Skip to content

Commit c841d14

Browse files
committed
Manually merge PR249 to follow-up on PR244 and allow overriding non-essential GLOBAL and SITE conf options through include sections
git-svn-id: svn+ssh://svn.code.sf.net/p/migrid/code/trunk@6241 b75ad72c-e7d7-11dd-a971-7dbc132099af
1 parent 9760d45 commit c841d14

File tree

7 files changed

+342
-48
lines changed

7 files changed

+342
-48
lines changed

mig/shared/configuration.py

Lines changed: 92 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@
7474
print("could not import migrid modules")
7575

7676

77-
def include_section_contents(logger, config, section, load_path, verbose=False):
77+
def include_section_contents(logger, config, section, load_path, verbose=False,
78+
reject_overrides=[]):
7879
"""Include additional section contents from load_path in config."""
7980
if not os.path.exists(load_path):
8081
msg = "no such %r section config in %s" % (section, load_path)
@@ -102,6 +103,13 @@ def include_section_contents(logger, config, section, load_path, verbose=False):
102103
logger.debug("add %r section to main config" % section)
103104
config.add_section(section)
104105
for (key, val) in section_config.items(section):
106+
if key in reject_overrides:
107+
msg = "reject override core option %r in %r section" % (key,
108+
section)
109+
if verbose:
110+
print(msg)
111+
logger.warning(msg)
112+
continue
105113
logger.debug("add config key %r in %r section" % (key, section))
106114
config.set(section, key, val)
107115
logger.debug("done including %r section to main config" % section)
@@ -120,7 +128,7 @@ def expand_external_sources(logger, val):
120128
if val.find('::') == -1:
121129
# logger.debug("nothing to expand in %r" % val)
122130
return val
123-
#logger.debug("expand any ENV and FILE content in %r" % val)
131+
# logger.debug("expand any ENV and FILE content in %r" % val)
124132
env_pattern = "[a-zA-Z][a-zA-Z0-9_]+"
125133
cache_pattern = file_pattern = "[^ ]+"
126134
expanded = val
@@ -150,7 +158,7 @@ def expand_external_sources(logger, val):
150158
# "reading conf content from file in %r" % cache)
151159
content = read_file(path, logger)
152160
if cache and content:
153-
#logger.debug("caching conf content salt in %r" % cache)
161+
# logger.debug("caching conf content salt in %r" % cache)
154162
write_file(content, cache, logger)
155163
if not content:
156164
logger.warning("salt file not found or empty: %s" % path)
@@ -846,6 +854,85 @@ def reload_config(self, verbose, skip_log=False, disable_auth_log=False,
846854
# print "logger initialized (level " + logger_obj.loglevel() + ")"
847855
# logger.debug("logger initialized")
848856

857+
# Allow section confs included from file
858+
if config.has_option('GLOBAL', 'include_sections'):
859+
self.include_sections = config.get('GLOBAL', 'include_sections')
860+
else:
861+
# Fall back to config section dir along with actual conf
862+
if config.has_option('GLOBAL', 'mig_server_home'):
863+
_config_file_dir = config.get('GLOBAL', 'mig_server_home')
864+
else:
865+
_config_file_dir = os.path.dirname(_config_file)
866+
self.include_sections = os.path.join(_config_file_dir,
867+
mig_conf_section_dirname)
868+
869+
# NOTE: for simplicity we do NOT allow core overrides in GLOBAL and
870+
# SITE sections. Especially the options affecting base paths
871+
# and service daemons as that might interfere with external
872+
# dependencies e.g. in the apache web server.
873+
no_override_section_options = {
874+
'GLOBAL': ['include_sections', 'mig_path', 'mig_server_home',
875+
'state_path', 'certs_path',
876+
'logfile', 'loglevel',
877+
'server_fqdn',
878+
'migserver_public_url',
879+
'migserver_public_alias_url',
880+
'migserver_http_url',
881+
'migserver_https_url',
882+
'migserver_https_mig_oid_url',
883+
'migserver_https_ext_oid_url',
884+
'migserver_https_mig_oidc_url',
885+
'migserver_https_ext_oidc_url',
886+
'migserver_https_mig_cert_url',
887+
'migserver_https_ext_cert_url',
888+
'migserver_https_sid_url',
889+
'user_openid_address', 'user_openid_port',
890+
'user_openid_key', 'user_openid_log',
891+
'user_davs_address', 'user_davs_port',
892+
'user_davs_key', 'user_davs_log',
893+
'user_sftp_address', 'user_sftp_port',
894+
'user_sftp_key', 'user_sftp_log',
895+
'user_sftp_subsys_address', 'user_sftp_subsys_port',
896+
'user_sftp_subsys_log',
897+
'user_ftps_address', 'user_ftps_ctrl_port',
898+
'user_ftps_pasv_ports',
899+
'user_ftps_key', 'user_ftps_log'],
900+
'SITE': ['enable_openid', 'enable_davs', 'enable_ftps',
901+
'enable_sftp', 'enable_sftp_subsys', 'enable_crontab',
902+
'enable_events', 'enable_notify', 'enable_imnotify',
903+
'enable_transfers']
904+
}
905+
self.include_sections = os.path.normpath(self.include_sections)
906+
if os.path.isdir(self.include_sections):
907+
msg = "read extra config sections from %s" % self.include_sections
908+
if verbose:
909+
print(msg)
910+
logger.debug(msg)
911+
for section_filename in os.listdir(self.include_sections):
912+
# skip dotfiles and non-confs
913+
if section_filename.startswith('.'):
914+
continue
915+
if not section_filename.endswith('.conf'):
916+
msg = "%r is not on required sectionname.conf form" % \
917+
section_filename
918+
if verbose:
919+
print(msg)
920+
logger.warning(msg)
921+
continue
922+
section_path = os.path.join(self.include_sections,
923+
section_filename)
924+
section = section_filename.replace('.conf', '').upper()
925+
reject_overrides = []
926+
if section in no_override_section_options:
927+
reject_overrides = no_override_section_options[section]
928+
msg = "filter %r section override in %r for %s" % \
929+
(section, section_filename, reject_overrides)
930+
if verbose:
931+
print(msg)
932+
logger.debug(msg)
933+
include_section_contents(logger, config, section, section_path,
934+
verbose, reject_overrides)
935+
849936
# Mandatory options first
850937

851938
try:
@@ -958,45 +1045,6 @@ def reload_config(self, verbose, skip_log=False, disable_auth_log=False,
9581045
else:
9591046
self.user_db_home = os.path.join(self.state_path, 'user_db_home')
9601047

961-
# Allow section confs included from file
962-
if config.has_option('GLOBAL', 'include_sections'):
963-
self.include_sections = config.get('GLOBAL', 'include_sections')
964-
else:
965-
self.include_sections = os.path.join(self.mig_server_home,
966-
mig_conf_section_dirname)
967-
968-
# NOTE: for simplicity we do NOT allow overrides in GLOBAL section
969-
no_override_sections = ['GLOBAL']
970-
self.include_sections = os.path.normpath(self.include_sections)
971-
if os.path.isdir(self.include_sections):
972-
msg = "read extra config sections from %s" % self.include_sections
973-
if verbose:
974-
print(msg)
975-
logger.info(msg)
976-
for section_filename in os.listdir(self.include_sections):
977-
# skip dotfiles and non-confs
978-
if section_filename.startswith('.'):
979-
continue
980-
if not section_filename.endswith('.conf'):
981-
msg = "%r is not on required sectionname.conf form" % \
982-
section_filename
983-
if verbose:
984-
print(msg)
985-
logger.warning(msg)
986-
continue
987-
section_path = os.path.join(self.include_sections,
988-
section_filename)
989-
section = section_filename.replace('.conf', '').upper()
990-
if section in no_override_sections:
991-
msg = "skip unsupported %r section override in %r" % \
992-
(section, section_filename)
993-
if verbose:
994-
print(msg)
995-
logger.warning(msg)
996-
continue
997-
include_section_contents(logger, config, section, section_path,
998-
verbose)
999-
10001048
if config.has_option('GLOBAL', 'admin_list'):
10011049
# Parse semi-colon separated list of admins with optional spaces
10021050
admins = config.get('GLOBAL', 'admin_list')
@@ -1440,7 +1488,7 @@ def reload_config(self, verbose, skip_log=False, disable_auth_log=False,
14401488
protos = [i for i in plain_val.split() if i]
14411489
# Append missing supported protocols for AUTO and filter invalid
14421490
if keyword_auto in protos:
1443-
protos = [i for i in protos if i != keyword_auto] +\
1491+
protos = [i for i in protos if i != keyword_auto] + \
14441492
[i for i in allowed_protos if i not in protos]
14451493
valid_protos = [i for i in protos if i in allowed_protos]
14461494
if protos != valid_protos:
@@ -1719,7 +1767,7 @@ def reload_config(self, verbose, skip_log=False, disable_auth_log=False,
17191767
protos = [i for i in plain_val.split() if i]
17201768
# Append missing supported protocols for AUTO and filter invalid
17211769
if keyword_auto in protos:
1722-
protos = [i for i in protos if i != keyword_auto] +\
1770+
protos = [i for i in protos if i != keyword_auto] + \
17231771
[i for i in allowed_protos if i not in protos]
17241772
valid_protos = [i for i in protos if i in allowed_protos]
17251773
if protos != valid_protos:

tests/data/MiGserver.d/dummy

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Dummy conf section with missing conf extension
2+
[SETTINGS]
3+
language = Pig Latin

tests/data/MiGserver.d/global.conf

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Used to test that core GLOBAL section overrides are rejected by policy while
2+
# peripheral overrides are accepted.
3+
[GLOBAL]
4+
# These overrides are allowed
5+
admin_email = admin@somewhere.org
6+
vgrid_resources = resources.custom
7+
vgrid_triggers = triggers.custom
8+
vgrid_sharelinks = sharelinks.custom
9+
vgrid_monitor = monitor.custom
10+
# but these core ones aren't allowed
11+
include_sections = /tmp/MiGserver.d
12+
mig_path = /tmp/mig/mig
13+
logfile = /tmp/mig.log
14+
loglevel = warning
15+
server_fqdn = somewhere.org
16+
migserver_public_url = https://somewhere.org
17+
migserver_https_sid_url = https://somewhere.org
18+
user_openid_address = somewhere.org
19+
user_openid_port = 4242
20+
user_openid_key = /tmp/openid.key
21+
user_openid_log = /tmp/openid.log

tests/data/MiGserver.d/multi.conf

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Sample multi conf to test that superflous other sections in conf are ignored
2+
[MULTI]
3+
blabla = yes
4+
5+
# Other sections like SETTINGS must be in SECTIONAME.conf and are ignored here
6+
[SETTINGS]
7+
language = Spanglish
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Dummy section conf with wrong name
2+
[SETTINGS]
3+
language = Pig Latin

tests/data/MiGserver.d/site.conf

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Used to test that core SITE section overrides are rejected by policy while
2+
# peripheral overrides are accepted.
3+
[SITE]
4+
# These overrides are allowed
5+
short_title = ACME Site
6+
support_text = Custom support text
7+
privacy_text = Custom privacy text
8+
peers_notice = Custom peers notice
9+
peers_contact_hint = Custom peers contact hint
10+
new_user_default_ui = V3
11+
password_legacy_policy = MEDIUM
12+
freeze_admins = BOFH
13+
freeze_to_tape = Custom freeze to tape
14+
freeze_doi_text = Custom freeze doi text
15+
freeze_doi_url = https://somewhere.org/mint-doi
16+
freeze_doi_url_field = archiveurl
17+
# but these core ones aren't allowed
18+
enable_openid = True
19+
enable_davs = True
20+
enable_ftps = True
21+
enable_sftp = True
22+
enable_sftp_susbsys = True
23+
enable_crontab = True
24+
enable_events = True
25+
enable_notify = True
26+
enable_imnotify = True
27+
enable_transfers = True

0 commit comments

Comments
 (0)