Restructured server config

This commit is contained in:
Kevin Veen-Birkenbach 2025-08-07 11:31:06 +02:00
parent 99c6c9ec92
commit 9228d51e86
No known key found for this signature in database
GPG Key ID: 44D8F11FD62F878E
69 changed files with 770 additions and 677 deletions

View File

@ -39,7 +39,7 @@ class FilterModule(object):
# 1) Precompute canonical domains per app (fallback to default)
canonical_map = {}
for app_id, cfg in apps.items():
domains_cfg = cfg.get('domains') or {}
domains_cfg = cfg.get('server',{}).get('domains',{})
entry = domains_cfg.get('canonical')
if entry is None:
canonical_map[app_id] = [default_domain(app_id, primary_domain)]
@ -49,13 +49,13 @@ class FilterModule(object):
canonical_map[app_id] = list(entry)
else:
raise AnsibleFilterError(
f"Unexpected type for 'domains.canonical' in application '{app_id}': {type(entry).__name__}"
f"Unexpected type for 'server.domains.canonical' in application '{app_id}': {type(entry).__name__}"
)
# 2) Build alias list per app
result = {}
for app_id, cfg in apps.items():
domains_cfg = cfg.get('domains')
domains_cfg = cfg.get('server',{}).get('domains')
# no domains key → no aliases
if domains_cfg is None:

View File

@ -28,7 +28,7 @@ class FilterModule(object):
f"expected a dict, got {cfg!r}"
)
domains_cfg = cfg.get('domains')
domains_cfg = cfg.get('server',{}).get('domains',{})
if not domains_cfg or 'canonical' not in domains_cfg:
self._add_default_domain(app_id, primary_domain, seen_domains, result)
continue
@ -64,7 +64,7 @@ class FilterModule(object):
self._process_canonical_domains_list(app_id, canonical_domains, seen_domains, result)
else:
raise AnsibleFilterError(
f"Unexpected type for 'domains.canonical' in application '{app_id}': "
f"Unexpected type for 'server.domains.canonical' in application '{app_id}': "
f"{type(canonical_domains).__name__}"
)

View File

@ -36,7 +36,7 @@ class FilterModule(object):
# 1) Compute canonical domains per app (always as a list)
canonical_map = {}
for app_id, cfg in apps.items():
domains_cfg = cfg.get('domains') or {}
domains_cfg = cfg.get('server',{}).get('domains',{})
entry = domains_cfg.get('canonical')
if entry is None:
canonical_map[app_id] = [default_domain(app_id, primary_domain)]
@ -46,13 +46,13 @@ class FilterModule(object):
canonical_map[app_id] = list(entry)
else:
raise AnsibleFilterError(
f"Unexpected type for 'domains.canonical' in application '{app_id}': {type(entry).__name__}"
f"Unexpected type for 'server.domains.canonical' in application '{app_id}': {type(entry).__name__}"
)
# 2) Compute alias domains per app
alias_map = {}
for app_id, cfg in apps.items():
domains_cfg = cfg.get('domains')
domains_cfg = cfg.get('server',{}).get('domains',{})
if domains_cfg is None:
alias_map[app_id] = []
continue

View File

@ -8,6 +8,7 @@ features:
port-ui-desktop: true
central_database: true
logout: true
server:
domains:
canonical:
- "accounting.{{ primary_domain }}"

View File

@ -13,6 +13,7 @@ docker:
enabled: true
database:
enabled: true
server:
domains:
canonical:
- "tickets.{{ primary_domain }}"

View File

@ -18,7 +18,7 @@ docker:
name: "baserow"
volumes:
data: "baserow_data"
server:
domains:
canonical:
- baserow.{{ primary_domain }}

View File

@ -12,13 +12,14 @@ features:
oidc: true
central_database: false
logout: true
domains:
canonical:
- "meet.{{ primary_domain }}"
server:
csp:
flags:
script-src-elem:
unsafe-inline: true
style-src:
unsafe-inline: true
domains:
canonical:
- "meet.{{ primary_domain }}"
credentials: {}

View File

@ -8,6 +8,7 @@ features:
port-ui-desktop: true
central_database: true
logout: true
server:
domains:
canonical:
web: "bskyweb.{{ primary_domain }}"

View File

@ -1,3 +1,4 @@
server:
domains:
canonical:
- "collabora.{{ primary_domain }}"

View File

@ -7,6 +7,7 @@ features:
central_database: true
ldap: false # @todo implement and activate
logout: true
server:
csp:
flags:
style-src:

View File

@ -1,6 +1,6 @@
features:
logout: false # Just deactivated to oppress warnings, elk is anyhow not running
server:
domains:
canonical:
- elk.{{ primary_domain }}

View File

@ -6,6 +6,7 @@ features:
oidc: true
central_database: true
logout: true
server:
csp:
flags:
script-src-elem:

View File

@ -9,6 +9,7 @@ features:
ldap: true
oauth2: false # No special login side which could be protected, use 2FA of Friendica instead
logout: true
server:
domains:
canonical:
- "social.{{ primary_domain }}"

View File

@ -20,6 +20,7 @@ features:
central_database: true
oauth2: false # Doesn't make sense to activate it atm, because login is possible on homepage
logout: true
server:
domains:
canonical:
- "audio.{{ primary_domain }}"

View File

@ -19,6 +19,7 @@ oauth2_proxy:
acl:
blacklist:
- "/user/login"
server:
csp:
flags:
script-src-elem:

View File

@ -15,7 +15,7 @@ docker:
version: "latest"
credentials:
initial_root_password: "{{ users.administrator.password }}"
server:
domains:
canonical:
- gitlab.{{ primary_domain }}

View File

@ -1,6 +1,6 @@
features:
logout: true # Same like with elk, anyhow not active atm
server:
domains:
canonical:
- jenkins.{{ primary_domain }}

View File

@ -6,6 +6,7 @@ features:
port-ui-desktop: true
central_database: true
logout: true
server:
domains:
canonical:
- "cms.{{ primary_domain }}"

View File

@ -7,6 +7,7 @@ features:
central_database: true
recaptcha: true
logout: true
server:
csp:
flags:
script-src-elem:

View File

@ -13,6 +13,7 @@ features:
central_database: false
oauth2: true
logout: true
server:
csp:
flags:
style-src:

View File

@ -18,6 +18,7 @@ features:
oauth2: false # Enable the OAuth2-Proy
javascript: false # Enables the custom JS in the javascript.js.j2 file
logout: false # With this app I assume that it's a service, so should be renamed and logging is unneccessary
server:
csp:
whitelist: {} # URL's which should be whitelisted
flags: {} # Flags which should be set

View File

@ -6,6 +6,7 @@ features:
central_database: true
oidc: true
logout: true
server:
domains:
canonical:
- "newsletter.{{ primary_domain }}"

View File

@ -9,6 +9,7 @@ features:
oidc: true
central_database: false # Deactivate central database for mailu, I don't know why the database deactivation is necessary
logout: true
server:
domains:
canonical:
- "mail.{{ primary_domain }}"

View File

@ -7,6 +7,7 @@ features:
oidc: true
central_database: true
logout: true
server:
domains:
canonical:
- "microblog.{{ primary_domain }}"

View File

@ -9,6 +9,7 @@ features:
central_database: true
oauth2: false
logout: true
server:
csp:
whitelist:
script-src-elem:

View File

@ -24,6 +24,7 @@ features:
oidc: true # Deactivated OIDC due to this issue https://github.com/matrix-org/synapse/issues/10492
central_database: true
logout: true
server:
csp:
flags:
script-src:
@ -39,6 +40,11 @@ csp:
script-src-elem:
- "element.{{ primary_domain }}"
- "https://cdn.jsdelivr.net"
domains:
canonical:
synapse: "matrix.{{ primary_domain }}"
element: "element.{{ primary_domain }}"
client_max_body_size: "15M"
plugins:
# You need to enable them in the inventory file
@ -50,10 +56,3 @@ plugins:
slack: false
telegram: false
whatsapp: false
client_max_body_size: "15M"
domains:
canonical:
synapse: "matrix.{{ primary_domain }}"
element: "element.{{ primary_domain }}"

View File

@ -17,4 +17,4 @@ matrix_project: "{{ application_id | get_entity_name }}"
# Webserver
well_known_directory: "{{nginx.directories.data.well_known}}/matrix/"
location_upload: "~ ^/_matrix/media/v3/"
client_max_body_size: "{{ applications | get_app_conf(application_id, 'client_max_body_size') }}"
client_max_body_size: "{{ applications | get_app_conf(application_id, 'server.client_max_body_size') }}"

View File

@ -1,3 +1,4 @@
server:
domains:
canonical:
- "wiki.{{ primary_domain }}"

View File

@ -9,6 +9,7 @@ features:
css: true # use custom infinito stile
port-ui-desktop: true # Enable in port-ui
logout: false
server:
csp:
whitelist:
script-src-elem:

View File

@ -5,6 +5,7 @@ features:
matomo: true
port-ui-desktop: true
logout: true
server:
csp:
flags:
script-src-elem:

View File

@ -6,6 +6,7 @@ features:
central_database: true
oidc: true
logout: true
server:
csp:
flags:
script-src-elem:

View File

@ -15,7 +15,7 @@ docker:
name: "mybb"
volumes:
data: "mybb_data"
server:
domains:
canonical:
- mybb.{{ primary_domain }}

View File

@ -3,6 +3,7 @@ features:
css: true
port-ui-desktop: true
logout: false
server:
csp:
whitelist:
script-src-elem:

View File

@ -1,4 +1,5 @@
version: "production" # @see https://nextcloud.com/blog/nextcloud-release-channels-and-how-to-track-them/
server:
csp:
flags:
style-src:

View File

@ -6,7 +6,7 @@ features:
css: true
port-ui-desktop: false
logout: true
server:
domains:
canonical:
- oauth2-proxy.{{ primary_domain }}

View File

@ -18,6 +18,7 @@ features:
central_database: true
oauth2: true
logout: true
server:
csp:
flags:
script-src-elem:

View File

@ -5,6 +5,7 @@ features:
central_database: true
oidc: true
logout: true
server:
csp:
flags:
script-src-elem:

View File

@ -13,6 +13,7 @@ features:
central_database: true
oauth2: true
logout: true
server:
csp:
flags:
style-src:
@ -22,11 +23,10 @@ csp:
whitelist:
font-src:
- "data:"
domains:
canonical:
- pgadmin.{{ primary_domain }}
docker:
services:
database:
enabled: true
domains:
canonical:
- pgadmin.{{ primary_domain }}

View File

@ -11,7 +11,7 @@ features:
ldap: true
oauth2: true
logout: true
server:
domains:
canonical:
- phpldapadmin.{{ primary_domain }}

View File

@ -12,6 +12,7 @@ features:
central_database: true
oauth2: true
logout: true
server:
csp:
flags:
style-src:

View File

@ -6,6 +6,7 @@ features:
central_database: true
oidc: true
logout: true
server:
csp:
flags:
script-src:

View File

@ -5,6 +5,7 @@ features:
simpleicons: true # Activate Brand Icons for your groups
javascript: true # Necessary for URL sync
logout: false # Doesn't have own user data. Just a frame.
server:
csp:
whitelist:
script-src-elem:

View File

@ -18,6 +18,7 @@ features:
oauth2: false # Enable the OAuth2-Proy
javascript: false # Enables the custom JS in the javascript.js.j2 file
logout: true
server:
csp:
whitelist: {} # URL's which should be whitelisted
flags: {} # Flags which should be set

View File

@ -1,5 +1,6 @@
features:
logout: false
server:
domains:
canonical:
- "wheel.{{ primary_domain }}"

View File

@ -6,6 +6,7 @@ features:
ldap: true
oauth2: true
logout: true
server:
domains:
canonical:
- "inventory.{{ primary_domain }}"

View File

@ -3,6 +3,7 @@ features:
css: true
port-ui-desktop: true
logout: false
server:
csp:
flags:
script-src:

View File

@ -13,7 +13,7 @@ features:
# users:
# administrator:
# username: "{{ users.administrator.username }}"
server:
domains:
canonical:
- syncope.{{ primary_domain }}

View File

@ -18,6 +18,7 @@ docker:
enabled: true
taiga:
version: "latest"
server:
csp:
flags:
script-src-elem:

View File

@ -14,6 +14,7 @@ features:
oidc: true
central_database: true
logout: true
server:
csp:
flags:
style-src:

View File

@ -6,7 +6,7 @@
- name: "Include role srv-proxy-6-6-domain for {{ application_id }}"
include_role:
name: srv-proxy-6-6-domain
loop: "{{ applications | get_app_conf(application_id, 'domains.canonical', True) }}"
loop: "{{ applications | get_app_conf(application_id, 'server.domains.canonical', True) }}"
loop_control:
loop_var: domain
vars:

View File

@ -1,7 +1,7 @@
# xmpp is more a service then a app with ui interface. @todo Rename it
features:
logout: false # Reactivated as soon as xmpp is fully implemented
server:
domains:
canonical:
- xmpp.{{ primary_domain }}

View File

@ -13,19 +13,12 @@ features:
central_database: true
oauth2: true
logout: true
server:
domains:
canonical:
- "s.{{ primary_domain }}"
aliases:
- "short.{{ primary_domain }}"
docker:
services:
database:
enabled: true
yourls:
version: "latest"
name: "yourls"
image: "yourls"
csp:
flags:
style-src:
@ -34,3 +27,11 @@ csp:
unsafe-inline: true
script-src:
unsafe-inline: true
docker:
services:
database:
enabled: true
yourls:
version: "latest"
name: "yourls"
image: "yourls"

View File

@ -1,6 +1,6 @@
source_directory: "{{ playbook_dir }}/assets"
url: "{{ web_protocol }}://<< defaults_applications['web-svc-file']domains.canonical[0] >>/assets"
url: "{{ web_protocol }}://<< defaults_applications['web-svc-file']server.domains.canonical[0] >>/assets"
server:
domains:
canonical:
- asset.{{ primary_domain }}

View File

@ -2,6 +2,7 @@ features:
matomo: true
css: true
port-ui-desktop: true
server:
domains:
canonical:
- "cdn.{{ primary_domain }}"

View File

@ -2,6 +2,7 @@ features:
matomo: true
css: true
port-ui-desktop: true
server:
domains:
canonical:
- "file.{{ primary_domain }}"

View File

@ -2,6 +2,7 @@ features:
matomo: true
css: true
port-ui-desktop: true
server:
domains:
canonical:
- "html.{{ primary_domain }}"

View File

@ -4,6 +4,7 @@ features:
port-ui-desktop: true
javascript: false
logout: false
server:
domains:
canonical:
- "logout.{{ primary_domain }}"
@ -22,5 +23,5 @@ csp:
style-src:
- https://cdn.jsdelivr.net
frame-ancestors:
- "{{ web_protocol }}://<< defaults_applications[web-app-keycloak].domains.canonical[0] >>"
- "{{ web_protocol }}://<< defaults_applications[web-app-keycloak].server.domains.canonical[0] >>"

View File

@ -31,7 +31,7 @@ class FilterModule(object):
continue
# use canonical domains list if present
domains_entry = config.get('domains', {}).get('canonical', [])
domains_entry = config.get('server', {}).get('domains', {}).get('canonical', [])
# normalize to a list of strings
if isinstance(domains_entry, dict):

View File

@ -16,6 +16,7 @@ features:
central_database: false # Enable Central Database Network
recaptcha: false # Enable ReCaptcha
oauth2: false # Enable the OAuth2-Proy
server:
csp: {}
domains:
canonical:

View File

@ -25,6 +25,7 @@ features:
oauth2: false # Enable the OAuth2-Proy
javascript: false # Enable the custom JS in the javascript.js.j2 file
logout: true # Enable the logout via the central logout mechanism (deleting all cookies)
server:
csp:
whitelist: # URL's which should be whitelisted
script-src-elem: []
@ -39,7 +40,6 @@ csp:
unsafe-inline: false
script-src-elem:
unsafe-inline: false
domains:
domains:
canonical: {} # Urls under which the domain should be directly accessible
aliases: [] # Alias redirections to the first element of the canonical domains

View File

@ -25,7 +25,7 @@ class TestDomainUniqueness(unittest.TestCase):
domain_to_apps = defaultdict(set)
for app_name, app_cfg in apps.items():
domains_cfg = app_cfg.get('domains', {})
domains_cfg = app_cfg.get('server',{}).get('domains',{})
# canonical entries may be a list or a mapping
canonical = domains_cfg.get('canonical', [])

View File

@ -20,17 +20,17 @@ class TestWebRolesDomains(unittest.TestCase):
self.assertIsInstance(data, dict, f"YAML root is not a dict in {path}")
domains = data.get("domains")
domains = data.get('server',{}).get('domains',{})
self.assertIsNotNone(domains, f"'domains' section missing in {path}")
self.assertIsInstance(domains, dict, f"'domains' must be a dict in {path}")
canonical = domains.get("canonical")
self.assertIsNotNone(canonical, f"'domains.canonical' missing in {path}")
self.assertIsNotNone(canonical, f"'server.domains.canonical' missing in {path}")
# Check for emptiness
empty_values = [{}, [], ""]
self.assertNotIn(canonical, empty_values,
f"'domains.canonical' in {path} must not be empty dict, list, or empty string")
f"'server.domains.canonical' in {path} must not be empty dict, list, or empty string")
if __name__ == "__main__":
unittest.main()

View File

@ -33,7 +33,7 @@ class TestDomainsStructure(unittest.TestCase):
if 'domains' not in data:
continue
domains = data['domains']
domains = data.get('server',{}).get('domains')
if not isinstance(domains, dict):
failed_roles.append((role_path.name, vars_file.name, "'domains' should be a dict"))
continue

View File

@ -33,9 +33,11 @@ class TestDomainFilters(unittest.TestCase):
def test_alias_with_explicit_aliases(self):
apps = {
'app1': {
'server':{
'domains': {'aliases': ['alias.com']}
}
}
}
# canonical defaults to ['app1.example.com'], so alias should include alias.com and default
expected = {'app1': ['alias.com', 'app1.example.com']}
result = self.filter_module.alias_domains_map(apps, self.primary)
@ -44,7 +46,7 @@ class TestDomainFilters(unittest.TestCase):
def test_alias_with_canonical_not_default(self):
apps = {
'app1': {
'domains': {'canonical': ['foo.com']}
'server':{'domains': {'canonical': ['foo.com']}}
}
}
# foo.com is canonical, default not in canonical so added as alias
@ -55,12 +57,14 @@ class TestDomainFilters(unittest.TestCase):
def test_alias_with_existing_default(self):
apps = {
'app1': {
'server':{
'domains': {
'canonical': ['foo.com'],
'aliases': ['app1.example.com']
}
}
}
}
# default present in aliases, should not be duplicated
expected = {'app1': ['app1.example.com']}
result = self.filter_module.alias_domains_map(apps, self.primary)
@ -68,7 +72,7 @@ class TestDomainFilters(unittest.TestCase):
def test_invalid_aliases_type(self):
apps = {
'app1': {'domains': {'aliases': 123}}
'app1': {'server':{'domains': {'aliases': 123}}}
}
with self.assertRaises(AnsibleFilterError):
self.filter_module.alias_domains_map(apps, self.primary)
@ -76,9 +80,11 @@ class TestDomainFilters(unittest.TestCase):
def test_alias_with_empty_domains_cfg(self):
apps = {
'app1': {
'server':{
'domains': {}
}
}
}
expected = apps
result = self.filter_module.alias_domains_map(apps, self.primary)
self.assertEqual(result, expected)
@ -86,6 +92,7 @@ class TestDomainFilters(unittest.TestCase):
def test_alias_with_canonical_dict_not_default(self):
apps = {
'app1': {
'server':{
'domains': {
'canonical': {
'one': 'one.com',
@ -94,6 +101,7 @@ class TestDomainFilters(unittest.TestCase):
}
}
}
}
expected = {'app1': ['app1.example.com']}
result = self.filter_module.alias_domains_map(apps, self.primary)
self.assertEqual(result, expected)

View File

@ -32,9 +32,11 @@ class TestDomainFilters(unittest.TestCase):
def test_canonical_with_list(self):
apps = {
'web-app-app1': {
'server':{
'domains': {'canonical': ['foo.com', 'bar.com']}
}
}
}
result = self.filter_module.canonical_domains_map(apps, self.primary)
self.assertCountEqual(
result['web-app-app1'],
@ -44,9 +46,11 @@ class TestDomainFilters(unittest.TestCase):
def test_canonical_with_dict(self):
apps = {
'web-app-app1': {
'server':{
'domains': {'canonical': {'one': 'one.com', 'two': 'two.com'}}
}
}
}
result = self.filter_module.canonical_domains_map(apps, self.primary)
self.assertEqual(
result['web-app-app1'],
@ -55,8 +59,14 @@ class TestDomainFilters(unittest.TestCase):
def test_canonical_duplicate_raises(self):
apps = {
'web-app-app1': {'domains': {'canonical': ['dup.com']}},
'web-app-app2': {'domains': {'canonical': ['dup.com']}},
'web-app-app1':{
'server':{'domains': {'canonical': ['dup.com']}},
},
'web-app-app2':{
'server':{
'domains': {'canonical': ['dup.com']}
},
},
}
with self.assertRaises(AnsibleFilterError) as cm:
self.filter_module.canonical_domains_map(apps, self.primary)
@ -65,7 +75,7 @@ class TestDomainFilters(unittest.TestCase):
def test_invalid_canonical_type(self):
apps = {
'web-app-app1': {'domains': {'canonical': 123}}
'web-app-app1': {'server':{'domains': {'canonical': 123}}}
}
with self.assertRaises(AnsibleFilterError):
self.filter_module.canonical_domains_map(apps, self.primary)
@ -76,7 +86,7 @@ class TestDomainFilters(unittest.TestCase):
resulting in an empty mapping when only non-web apps are provided.
"""
apps = {
'db-app-app1': {'domains': {'canonical': ['db.example.com']}},
'db-app-app1': {'server':{'domains': {'canonical': ['db.example.com']}}},
'service-app-app2': {}
}
result = self.filter_module.canonical_domains_map(apps, self.primary)
@ -88,7 +98,7 @@ class TestDomainFilters(unittest.TestCase):
non-web apps should be ignored alongside valid web apps.
"""
apps = {
'db-app-app1': {'domains': {'canonical': ['db.example.com']}},
'db-app-app1': {'server':{'domains': {'canonical': ['db.example.com']}}},
'web-app-app1': {}
}
expected = {'web-app-app1': ['app1.example.com']}

View File

@ -37,9 +37,11 @@ class TestDomainMappings(unittest.TestCase):
def test_explicit_aliases(self):
apps = {
'app1': {
'server':{
'domains': {'aliases': ['alias.com']}
}
}
}
default = 'app1.example.com'
expected = [
{'source': 'alias.com', 'target': default},
@ -51,9 +53,11 @@ class TestDomainMappings(unittest.TestCase):
def test_canonical_not_default(self):
apps = {
'app1': {
'server':{
'domains': {'canonical': ['foo.com']}
}
}
}
expected = [
{'source': 'app1.example.com', 'target': 'foo.com'}
]
@ -63,11 +67,13 @@ class TestDomainMappings(unittest.TestCase):
def test_canonical_dict(self):
apps = {
'app1': {
'server':{
'domains': {
'canonical': {'one': 'one.com', 'two': 'two.com'}
}
}
}
}
# first canonical key 'one' → one.com
expected = [
{'source': 'app1.example.com', 'target': 'one.com'}
@ -77,8 +83,12 @@ class TestDomainMappings(unittest.TestCase):
def test_multiple_apps(self):
apps = {
'app1': {'domains': {'aliases': ['a1.com']}},
'app2': {'domains': {'canonical': ['c2.com']}},
'app1': {
'server':{'domains': {'aliases': ['a1.com']}}
},
'app2': {
'server':{'domains': {'canonical': ['c2.com']}}
},
}
expected = [
{'source': 'a1.com', 'target': 'app1.example.com'},
@ -89,7 +99,10 @@ class TestDomainMappings(unittest.TestCase):
def test_multiple_aliases(self):
apps = {
'app1': {'domains': {'aliases': ['a1.com','a2.com']}}
'app1': {
'server':{'domains': {'aliases': ['a1.com','a2.com']}
}
}
}
expected = [
{'source': 'a1.com', 'target': 'app1.example.com'},
@ -100,7 +113,7 @@ class TestDomainMappings(unittest.TestCase):
def test_invalid_aliases_type(self):
apps = {
'app1': {'domains': {'aliases': 123}}
'app1': {'server':{'domains': {'aliases': 123}}}
}
with self.assertRaises(AnsibleFilterError):
self.filter.domain_mappings(apps, self.primary)

View File

@ -19,12 +19,14 @@ class TestLoadConfigurationFilter(unittest.TestCase):
self.nested_cfg = {
'html': {
'features': {'matomo': True},
'server': {
'domains':{'canonical': ['html.example.com']}
}
}
}
self.flat_cfg = {
'features': {'matomo': False},
'domains': {'canonical': ['flat.example.com']}
'server': {'domains':{'canonical': ['flat.example.com']}}
}
def test_invalid_key(self):
@ -69,7 +71,7 @@ class TestLoadConfigurationFilter(unittest.TestCase):
self.assertIn(self.app, _cfg_cache)
mock_yaml.reset_mock()
# from cache
self.assertEqual(self.f(self.app, 'domains.canonical'),
self.assertEqual(self.f(self.app, 'server.domains.canonical'),
['html.example.com'])
mock_yaml.assert_not_called()
@ -92,7 +94,7 @@ class TestLoadConfigurationFilter(unittest.TestCase):
mock_yaml.return_value = self.nested_cfg
# nested fallback must work
self.assertTrue(self.f(self.app, 'features.matomo'))
self.assertEqual(self.f(self.app, 'domains.canonical'),
self.assertEqual(self.f(self.app, 'server.domains.canonical'),
['html.example.com'])
@patch('load_configuration.os.listdir', return_value=['r4'])
@ -105,13 +107,15 @@ class TestLoadConfigurationFilter(unittest.TestCase):
mock_exists.side_effect = lambda p: p.endswith('config/main.yml')
mock_yaml.return_value = {
'file': {
'server': {
'domains':{
'canonical': ['files.example.com', 'extra.example.com']
}
}
}
}
# should get the first element of the canonical domains list
self.assertEqual(self.f('file', 'domains.canonical[0]'),
self.assertEqual(self.f('file', 'server.domains.canonical[0]'),
'files.example.com')
if __name__ == '__main__':

View File

@ -33,23 +33,33 @@ class TestLogoutDomainsFilter(unittest.TestCase):
def test_flatten_and_feature_flag(self):
applications = {
"app1": {
"domains": {"canonical": "single.domain.com"},
'server':{
"domains": {"canonical": "single.domain.com"}
},
"features": {"logout": True},
},
"app2": {
"domains": {"canonical": ["list1.com", "list2.com"]},
'server':{
"domains": {"canonical": ["list1.com", "list2.com"]}
},
"features": {"logout": True},
},
"app3": {
"domains": {"canonical": {"k1": "dictA.com", "k2": "dictB.com"}},
'server':{
"domains": {"canonical": {"k1": "dictA.com", "k2": "dictB.com"}}
},
"features": {"logout": True},
},
"app4": {
"domains": {"canonical": "no-logout.com"},
'server':{
"domains": {"canonical": "no-logout.com"}
},
"features": {"logout": False},
},
"other": {
"domains": {"canonical": "ignored.com"},
'server':{
"domains": {"canonical": "ignored.com"}
},
"features": {"logout": True},
},
}
@ -67,7 +77,9 @@ class TestLogoutDomainsFilter(unittest.TestCase):
def test_missing_canonical_defaults_empty(self):
applications = {
"app1": {
"domains": {}, # no 'canonical' key
'server':{
"domains": {}
}, # no 'canonical' key
"features": {"logout": True},
}
}
@ -77,7 +89,9 @@ class TestLogoutDomainsFilter(unittest.TestCase):
def test_app_not_in_group(self):
applications = {
"app1": {
"domains": {"canonical": "domain.com"},
'server':{
"domains": {"canonical": "domain.com"}
},
"features": {"logout": True},
}
}
@ -87,7 +101,9 @@ class TestLogoutDomainsFilter(unittest.TestCase):
def test_invalid_domain_type(self):
applications = {
"app1": {
"domains": {"canonical": 123},
'server':{
"domains": {"canonical": 123}
},
"features": {"logout": True},
}
}

View File

@ -64,11 +64,13 @@ class TestDictRenderer(unittest.TestCase):
# Combine quoted key, dot access and numeric index
data = {
"web-svc-file": {
'server':{
"domains": {
"canonical": ["file.example.com"]
}
}
},
"url": '<<[\'web-svc-file\'].domains.canonical[0]>>'
"url": '<<[\'web-svc-file\'].server.domains.canonical[0]>>'
}
rendered = self.renderer.render(data)
self.assertEqual(rendered["url"], "file.example.com")