From 06238343df2815b6c71d608e3931e754697906dc Mon Sep 17 00:00:00 2001 From: Kevin Veen-Birkenbach Date: Fri, 16 May 2025 17:03:44 +0200 Subject: [PATCH] Added 'group_domain_filters' draft(needs to be optimized to load dependencies) --- filter_plugins/group_domain_filters.py | 29 +++++ group_vars/all/03_domains.yml | 105 ++++++++---------- group_vars/all/15_about.yml | 4 +- roles/docker-bluesky/tasks/main.yml | 4 +- .../templates/docker-compose.yml.j2 | 4 +- roles/docker-bluesky/templates/env.j2 | 8 +- roles/docker-mastodon/tasks/main.yml | 2 +- roles/docker-mastodon/templates/env.j2 | 2 +- roles/docker-matrix/vars/configuration.yml | 4 +- roles/docker-peertube/tasks/main.yml | 2 +- tests/unit/test_group_domain_filters.py | 51 +++++++++ 11 files changed, 143 insertions(+), 72 deletions(-) create mode 100644 filter_plugins/group_domain_filters.py create mode 100644 tests/unit/test_group_domain_filters.py diff --git a/filter_plugins/group_domain_filters.py b/filter_plugins/group_domain_filters.py new file mode 100644 index 00000000..9b2f1a88 --- /dev/null +++ b/filter_plugins/group_domain_filters.py @@ -0,0 +1,29 @@ +from ansible.errors import AnsibleFilterError + +class FilterModule(object): + """ + Custom filters for conditional domain assignments + """ + + def filters(self): + return { + "add_domain_if_group": self.add_domain_if_group, + } + + @staticmethod + def add_domain_if_group(domains_dict, domain_key, domain_value, group_names): + """ + Add {domain_key: domain_value} to domains_dict + only if domain_key is in group_names. + + Usage in Jinja: + {{ {} + | add_domain_if_group('akaunting', 'akaunting.' ~ primary_domain, group_names) }} + """ + try: + result = dict(domains_dict) + if domain_key in group_names: + result[domain_key] = domain_value + return result + except Exception as exc: + raise AnsibleFilterError(f"add_domain_if_group failed: {exc}") diff --git a/group_vars/all/03_domains.yml b/group_vars/all/03_domains.yml index ef72d3a4..a43159e3 100644 --- a/group_vars/all/03_domains.yml +++ b/group_vars/all/03_domains.yml @@ -1,58 +1,48 @@ -# Domains +defaults_domains: >- + {{ {} + | add_domain_if_group('akaunting', 'accounting.' ~ primary_domain, group_names) + | add_domain_if_group('attendize', 'tickets.' ~ primary_domain, group_names) + | add_domain_if_group('baserow', 'baserow.' ~ primary_domain, group_names) + | add_domain_if_group('bigbluebutton', 'meet.' ~ primary_domain, group_names) + | add_domain_if_group('bluesky', {'web': 'bskyweb.' ~ primary_domain,'api':'bluesky.' ~ primary_domain}, group_names) + | add_domain_if_group('discourse', 'forum.' ~ primary_domain, group_names) + | add_domain_if_group('elk', 'elk.' ~ primary_domain, group_names) + | add_domain_if_group('espocrm', 'espocrm.' ~ primary_domain, group_names) + | add_domain_if_group('file_server', 'files.' ~ primary_domain, group_names) + | add_domain_if_group('friendica', 'friendica.' ~ primary_domain, group_names) + | add_domain_if_group('funkwhale', 'music.' ~ primary_domain, group_names) + | add_domain_if_group('gitea', 'git.' ~ primary_domain, group_names) + | add_domain_if_group('gitlab', 'gitlab.' ~ primary_domain, group_names) + | add_domain_if_group('html_server', 'html.' ~ primary_domain, group_names) + | add_domain_if_group('keycloak', 'auth.' ~ primary_domain, group_names) + | add_domain_if_group('lam', 'lam.' ~ primary_domain, group_names) + | add_domain_if_group('ldap', 'ldap.' ~ primary_domain, group_names) + | add_domain_if_group('listmonk', 'newsletter.' ~ primary_domain, group_names) + | add_domain_if_group('mailu', 'mail.' ~ primary_domain, group_names) + | add_domain_if_group('mastodon', ['microblog.' ~ primary_domain], group_names) + | add_domain_if_group('matomo', 'matomo.' ~ primary_domain, group_names) + | add_domain_if_group('matrix', 'matrix.' ~ primary_domain, group_names) + | add_domain_if_group('matrix', 'element.' ~ primary_domain, group_names) + | add_domain_if_group('moodle', 'academy.' ~ primary_domain, group_names) + | add_domain_if_group('mediawiki', 'wiki.' ~ primary_domain, group_names) + | add_domain_if_group('nextcloud', 'cloud.' ~ primary_domain, group_names) + | add_domain_if_group('openproject', 'project.' ~ primary_domain, group_names) + | add_domain_if_group('peertube', ['video.' ~ primary_domain], group_names) + | add_domain_if_group('pgadmin', 'pgadmin.' ~ primary_domain, group_names) + | add_domain_if_group('phpmyadmin', 'phpmyadmin.' ~ primary_domain, group_names) + | add_domain_if_group('phpmyldapadmin', 'phpmyldap.' ~ primary_domain, group_names) + | add_domain_if_group('pixelfed', 'picture.' ~ primary_domain, group_names) + | add_domain_if_group('portfolio', primary_domain, group_names) + | add_domain_if_group('presentation', 'slides.' ~ primary_domain, group_names) + | add_domain_if_group('roulette-wheel', 'roulette.' ~ primary_domain, group_names) + | add_domain_if_group('snipe_it', 'inventory.' ~ primary_domain, group_names) + | add_domain_if_group('sphinx', 'docs.' ~ primary_domain, group_names) + | add_domain_if_group('syncope', 'syncope.' ~ primary_domain, group_names) + | add_domain_if_group('taiga', 'kanban.' ~ primary_domain, group_names) + | add_domain_if_group('yourls', 's.' ~ primary_domain, group_names) + | add_domain_if_group('wordpress', ['blog.' ~ primary_domain], group_names) + }} -## Service Domains -defaults_domains: - akaunting: "accounting.{{primary_domain}}" - attendize: "tickets.{{primary_domain}}" - baserow: "baserow.{{primary_domain}}" - bigbluebutton: "meet.{{primary_domain}}" - bluesky_api: "bluesky.{{primary_domain}}" - bluesky_web: "bskyweb.{{primary_domain}}" - discourse: "forum.{{primary_domain}}" - elk: "elk.{{primary_domain}}" - espocrm: "espocrm.{{primary_domain}}" - file_server: "files.{{primary_domain}}" - friendica: "friendica.{{primary_domain}}" - funkwhale: "music.{{primary_domain}}" - gitea: "git.{{primary_domain}}" - gitlab: "gitlab.{{primary_domain}}" - html_server: "html.{{primary_domain}}" - keycloak: "auth.{{primary_domain}}" - lam: "lam.{{primary_domain}}" - ldap: "ldap.{{primary_domain}}" - listmonk: "newsletter.{{primary_domain}}" - mailu: "mail.{{primary_domain}}" - mastodon: "microblog.{{primary_domain}}" - # ATTENTION: Will be owerwritten by the values in domains. Not merged. - mastodon_alternates: - - "mastodon.{{primary_domain}}" - matomo: "matomo.{{primary_domain}}" - synapse: "matrix.{{primary_domain}}" - element: "element.{{primary_domain}}" - moodle: "academy.{{primary_domain}}" - mediawiki: "wiki.{{primary_domain}}" - nextcloud: "cloud.{{primary_domain}}" - openproject: "project.{{primary_domain}}" - peertube: "video.{{primary_domain}}" - # ATTENTION: Will be owerwritten by the values in domains. Not merged. - peertube_alternates: [] - pgadmin: "pgadmin.{{primary_domain}}" - phpmyadmin: "phpmyadmin.{{primary_domain}}" - phpmyldap: "phpmyldap.{{primary_domain}}" - pixelfed: "picture.{{primary_domain}}" - portfolio: "{{primary_domain}}" - presentation: "slides.{{primary_domain}}" - roulette-wheel: "roulette.{{primary_domain}}" - snipe_it: "inventory.{{primary_domain}}" - sphinx: "docs.{{primary_domain}}" - syncope: "syncope.{{primary_domain}}" - taiga: "kanban.{{primary_domain}}" - yourls: "s.{{primary_domain}}" - # ATTENTION: Will be owerwritten by the values in domains. Not merged. - wordpress: - - "blog.{{primary_domain}}" - -## Domain Redirects defaults_redirect_domain_mappings: >- {{ [] | add_redirect_if_group('akaunting', "akaunting." ~ primary_domain, domains.akaunting, group_names) @@ -63,19 +53,20 @@ defaults_redirect_domain_mappings: >- | add_redirect_if_group('gitea', "gitea." ~ primary_domain, domains.gitea, group_names) | add_redirect_if_group('keycloak', "keycloak." ~ primary_domain, domains.keycloak, group_names) | add_redirect_if_group('lam', domains.ldap, domains.lam, group_names) - | add_redirect_if_group('phpmyldapadmin', domains.ldap, domains.phpmyldap, group_names) + | add_redirect_if_group('phpmyldapadmin', domains.ldap, domains.phpmyldapadmin,group_names) | add_redirect_if_group('listmonk', "listmonk." ~ primary_domain, domains.listmonk, group_names) | add_redirect_if_group('mailu', "mailu." ~ primary_domain, domains.mailu, group_names) + | add_redirect_if_group('mastodon', "mastodon." ~ primary_domain, domains.mastodon[0], group_names) | add_redirect_if_group('moodle', "moodle." ~ primary_domain, domains.moodle, group_names) | add_redirect_if_group('nextcloud', "nextcloud." ~ primary_domain, domains.nextcloud, group_names) | add_redirect_if_group('openproject', "openproject." ~ primary_domain, domains.openproject, group_names) - | add_redirect_if_group('peertube', "peertube." ~ primary_domain, domains.peertube, group_names) + | add_redirect_if_group('peertube', "peertube." ~ primary_domain, domains.peertube[0], group_names) | add_redirect_if_group('pixelfed', "pictures." ~ primary_domain, domains.pixelfed, group_names) | add_redirect_if_group('pixelfed', "pixelfed." ~ primary_domain, domains.pixelfed, group_names) | add_redirect_if_group('yourls', "short." ~ primary_domain, domains.yourls, group_names) | add_redirect_if_group('snipe-it', "snipe-it." ~ primary_domain, domains.snipe_it, group_names) | add_redirect_if_group('taiga', "taiga." ~ primary_domain, domains.taiga, group_names) - | add_redirect_if_group('peertube', "videos." ~ primary_domain, domains.peertube, group_names) + | add_redirect_if_group('peertube', "videos." ~ primary_domain, domains.peertube[0], group_names) | add_redirect_if_group('wordpress', "wordpress." ~ primary_domain, domains.wordpress[0], group_names) }} diff --git a/group_vars/all/15_about.yml b/group_vars/all/15_about.yml index d8764748..45c62335 100644 --- a/group_vars/all/15_about.yml +++ b/group_vars/all/15_about.yml @@ -16,11 +16,11 @@ defaults_service_provider: logo: "{{applications.assets_server.url}}/img/logo.png" favicon: "{{applications.assets_server.url}}/img/favicon.ico" contact: - bluesky: "{{ '@' ~ users.administrator.username ~ '.' ~ domains.bluesky_api if 'bluesky' in group_names else '' }}" + bluesky: "{{ '@' ~ users.administrator.username ~ '.' ~ domains.[application_id]['api'] if 'bluesky' in group_names else '' }}" email: "contact@{{ primary_domain }}" mastodon: "{{ '@' ~ users.administrator.username ~ '@' ~ domains.mastodon if 'mastodon' in group_names else '' }}" matrix: "{{ '@' ~ users.administrator.username ~ ':' ~ domains.synapse if 'matrix' in group_names else '' }}" - peertube: "{{ '@' ~ users.administrator.username ~ '@' ~ domains.peertube if 'peertube' in group_names else '' }}" + peertube: "{{ '@' ~ users.administrator.username ~ '@' ~ domains.peertube[0] if 'peertube' in group_names else '' }}" pixelfed: "{{ '@' ~ users.administrator.username ~ '@' ~ domains.pixelfed if 'pixelfed' in group_names else '' }}" phone: "+0 000 000 404" wordpress: "{{ '@' ~ users.administrator.username ~ '@' ~ domains.wordpress[0] if 'wordpress' in group_names else '' }}" diff --git a/roles/docker-bluesky/tasks/main.yml b/roles/docker-bluesky/tasks/main.yml index c4f3899a..c465bb87 100644 --- a/roles/docker-bluesky/tasks/main.yml +++ b/roles/docker-bluesky/tasks/main.yml @@ -10,8 +10,8 @@ domain: "{{ item.domain }}" http_port: "{{ item.http_port }}" loop: - - { domain: domains.bluesky_api, http_port: ports.localhost.http.bluesky_api } - - { domain: domains.bluesky_web, http_port: ports.localhost.http.bluesky_web } + - { domain: domains.[application_id]['api'], http_port: ports.localhost.http.bluesky_api } + - { domain: domains.[application_id]['web'], http_port: ports.localhost.http.bluesky_web } # The following lines should be removed when the following issue is closed: # https://github.com/bluesky-social/pds/issues/52 diff --git a/roles/docker-bluesky/templates/docker-compose.yml.j2 b/roles/docker-bluesky/templates/docker-compose.yml.j2 index 0714a6e2..cb41b3ca 100644 --- a/roles/docker-bluesky/templates/docker-compose.yml.j2 +++ b/roles/docker-bluesky/templates/docker-compose.yml.j2 @@ -22,8 +22,8 @@ services: dockerfile: Dockerfile # It doesn't compile yet with this parameters. @todo Fix it args: - REACT_APP_PDS_URL: "{{ web_protocol }}://{{domains.bluesky_api}}" # URL des PDS - REACT_APP_API_URL: "{{ web_protocol }}://{{domains.bluesky_api}}" # API-URL des PDS + REACT_APP_PDS_URL: "{{ web_protocol }}://{{domains.[application_id]['api']}}" # URL des PDS + REACT_APP_API_URL: "{{ web_protocol }}://{{domains.[application_id]['api']}}" # API-URL des PDS REACT_APP_SITE_NAME: "{{primary_domain | upper}} - Bluesky" REACT_APP_SITE_DESCRIPTION: "Decentral Social " ports: diff --git a/roles/docker-bluesky/templates/env.j2 b/roles/docker-bluesky/templates/env.j2 index 433c3b55..187443b1 100644 --- a/roles/docker-bluesky/templates/env.j2 +++ b/roles/docker-bluesky/templates/env.j2 @@ -1,6 +1,6 @@ -PDS_HOSTNAME="{{domains.bluesky_api}}" +PDS_HOSTNAME="{{domains.[application_id]['api']}}" PDS_ADMIN_EMAIL="{{applications.bluesky.users.administrator.email}}" -PDS_SERVICE_DID="did:web:{{domains.bluesky_api}}" +PDS_SERVICE_DID="did:web:{{domains.[application_id]['api']}}" # See https://mattdyson.org/blog/2024/11/self-hosting-bluesky-pds/ PDS_SERVICE_HANDLE_DOMAINS=".{{primary_domain}}" @@ -15,7 +15,7 @@ PDS_BLOBSTORE_DISK_LOCATION=/opt/pds/blocks PDS_DATA_DIRECTORY: /opt/pds PDS_BLOB_UPLOAD_LIMIT: 52428800 PDS_DID_PLC_URL=https://plc.directory -PDS_BSKY_APP_VIEW_URL=https://{{domains.bluesky_web}} -PDS_BSKY_APP_VIEW_DID=did:web:{{domains.bluesky_web}} +PDS_BSKY_APP_VIEW_URL=https://{{domains.[application_id]['web']}} +PDS_BSKY_APP_VIEW_DID=did:web:{{domains.[application_id]['web']}} PDS_REPORT_SERVICE_URL=https://mod.bsky.app PDS_REPORT_SERVICE_DID=did:plc:ar7c4by46qjdydhdevvrndac diff --git a/roles/docker-mastodon/tasks/main.yml b/roles/docker-mastodon/tasks/main.yml index 249dc884..74c2d7d1 100644 --- a/roles/docker-mastodon/tasks/main.yml +++ b/roles/docker-mastodon/tasks/main.yml @@ -6,7 +6,7 @@ - name: "Include setup for domain '{{ domain }}'" include_role: name: nginx-domain-setup - loop: "{{ [domains.mastodon] + domains.mastodon_alternates }}" + loop: "{{ domains.mastodon }}" loop_control: loop_var: domain vars: diff --git a/roles/docker-mastodon/templates/env.j2 b/roles/docker-mastodon/templates/env.j2 index c07e2b93..33f6b38c 100644 --- a/roles/docker-mastodon/templates/env.j2 +++ b/roles/docker-mastodon/templates/env.j2 @@ -4,7 +4,7 @@ LOCAL_DOMAIN={{domains[application_id]}} -ALTERNATE_DOMAINS="{{ domains.mastodon_alternates | join(',') }}" +ALTERNATE_DOMAINS="{{ domains.mastodon[1:] | join(',') }}" SINGLE_USER_MODE={{applications.mastodon.single_user_mode}} # Credentials diff --git a/roles/docker-matrix/vars/configuration.yml b/roles/docker-matrix/vars/configuration.yml index ca9c2bc9..73641c94 100644 --- a/roles/docker-matrix/vars/configuration.yml +++ b/roles/docker-matrix/vars/configuration.yml @@ -25,9 +25,9 @@ csp: whitelist: connect-src: - "{{ primary_domain }}" - - "{{ domains.synapse }}" + - "{{ domains.matrix }}" script-src: - - "{{ domains.synapse }}" + - "{{ domains.matrix }}" - "https://cdn.jsdelivr.net" plugins: # You need to enable them in the inventory file diff --git a/roles/docker-peertube/tasks/main.yml b/roles/docker-peertube/tasks/main.yml index 1891ab29..589c027b 100644 --- a/roles/docker-peertube/tasks/main.yml +++ b/roles/docker-peertube/tasks/main.yml @@ -5,7 +5,7 @@ - name: "include create-domains.yml for peertube" include_tasks: create-domains.yml - loop: "{{ [domains.peertube] + domains.peertube_alternates }}" + loop: "{{ domains.peertube }}" loop_control: loop_var: domain vars: diff --git a/tests/unit/test_group_domain_filters.py b/tests/unit/test_group_domain_filters.py new file mode 100644 index 00000000..f35c9187 --- /dev/null +++ b/tests/unit/test_group_domain_filters.py @@ -0,0 +1,51 @@ +import unittest + +from filter_plugins.group_domain_filters import FilterModule + +class TestAddDomainIfGroup(unittest.TestCase): + def setUp(self): + self.filter = FilterModule().filters()["add_domain_if_group"] + + def test_add_string_value(self): + result = self.filter({}, "akaunting", "accounting.example.org", ["akaunting"]) + self.assertEqual(result, {"akaunting": "accounting.example.org"}) + + def test_add_list_value(self): + result = self.filter({}, "mastodon", ["microblog.example.org"], ["mastodon"]) + self.assertEqual(result, {"mastodon": ["microblog.example.org"]}) + + def test_add_dict_value(self): + result = self.filter({}, "bluesky", {"web": "bskyweb.example.org", "api": "bluesky.example.org"}, ["bluesky"]) + self.assertEqual(result, {"bluesky": {"web": "bskyweb.example.org", "api": "bluesky.example.org"}}) + + def test_ignore_if_not_in_group(self): + result = self.filter({}, "akaunting", "accounting.example.org", ["wordpress"]) + self.assertEqual(result, {}) + + def test_merge_with_existing(self): + initial = {"wordpress": ["blog.example.org"]} + result = self.filter(initial, "akaunting", "accounting.example.org", ["akaunting"]) + self.assertEqual(result, { + "wordpress": ["blog.example.org"], + "akaunting": "accounting.example.org" + }) + + def test_dict_is_not_mutated(self): + base = {"keycloak": "auth.example.org"} + copy = dict(base) # make a copy for comparison + _ = self.filter(base, "akaunting", "accounting.example.org", ["akaunting"]) + self.assertEqual(base, copy) # original must stay unchanged + + def test_multiple_adds_accumulate(self): + result = {} + result = self.filter(result, "akaunting", "accounting.example.org", ["akaunting", "wordpress"]) + result = self.filter(result, "wordpress", ["blog.example.org"], ["akaunting", "wordpress"]) + result = self.filter(result, "bluesky", {"web": "bskyweb.example.org", "api": "bluesky.example.org"}, ["bluesky"]) + self.assertEqual(result, { + "akaunting": "accounting.example.org", + "wordpress": ["blog.example.org"], + "bluesky": {"web": "bskyweb.example.org", "api": "bluesky.example.org"}, + }) + +if __name__ == "__main__": + unittest.main()