Adding option to brand across services where possible
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"permissions": {
|
"permissions": {
|
||||||
"allow": [
|
"allow": [
|
||||||
"Bash(ls -la /home/iroddis/dev/sovereign/.*)"
|
"Bash(ls -la /home/iroddis/dev/sovereign/.*)",
|
||||||
|
"Bash(ls -la /home/iroddis/dev/sovereign/roles/*/templates/)"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,25 @@
|
|||||||
# Base domain - all services are subdomains of this
|
# Base domain - all services are subdomains of this
|
||||||
base_domain: "example.com"
|
base_domain: "example.com"
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# BRANDING
|
||||||
|
# Applied across all services that support custom branding.
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Display name shown in service UIs and email subjects
|
||||||
|
tenant_name: "Example Corp"
|
||||||
|
|
||||||
|
# Path to a logo image on the Ansible control machine (PNG or SVG recommended).
|
||||||
|
# Leave empty to use each service's default logo.
|
||||||
|
# Example: "files/logo.png"
|
||||||
|
tenant_logo_local_path: ""
|
||||||
|
|
||||||
|
# Primary brand colour (hex). Used for backgrounds, buttons, and highlights.
|
||||||
|
tenant_primary_color: "#2563eb"
|
||||||
|
|
||||||
|
# Accent / secondary colour (hex).
|
||||||
|
tenant_accent_color: "#1e40af"
|
||||||
|
|
||||||
# Base directory for all service data
|
# Base directory for all service data
|
||||||
sovereign_base_dir: /opt/sovereign
|
sovereign_base_dir: /opt/sovereign
|
||||||
|
|
||||||
|
|||||||
@@ -7,10 +7,25 @@
|
|||||||
loop:
|
loop:
|
||||||
- "{{ authentik_data_dir }}"
|
- "{{ authentik_data_dir }}"
|
||||||
- "{{ authentik_data_dir }}/media"
|
- "{{ authentik_data_dir }}/media"
|
||||||
|
- "{{ authentik_data_dir }}/media/branding"
|
||||||
- "{{ authentik_data_dir }}/custom-templates"
|
- "{{ authentik_data_dir }}/custom-templates"
|
||||||
|
- "{{ authentik_data_dir }}/blueprints"
|
||||||
- "{{ authentik_data_dir }}/certs"
|
- "{{ authentik_data_dir }}/certs"
|
||||||
- "{{ authentik_data_dir }}/postgres"
|
- "{{ authentik_data_dir }}/postgres"
|
||||||
|
|
||||||
|
- name: Deploy Authentik branding blueprint
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: branding-blueprint.yaml.j2
|
||||||
|
dest: "{{ authentik_data_dir }}/blueprints/sovereign-branding.yaml"
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Copy tenant logo to Authentik media
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ tenant_logo_local_path }}"
|
||||||
|
dest: "{{ authentik_data_dir }}/media/branding/logo.png"
|
||||||
|
mode: '0644'
|
||||||
|
when: tenant_logo_local_path | default('') != ''
|
||||||
|
|
||||||
- name: Deploy Authentik docker-compose
|
- name: Deploy Authentik docker-compose
|
||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
src: docker-compose.yml.j2
|
src: docker-compose.yml.j2
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
# Sovereign branding blueprint — applied automatically by Authentik on startup.
|
||||||
|
# Customises the default brand with the tenant name, logo, and colour scheme.
|
||||||
|
version: 1
|
||||||
|
metadata:
|
||||||
|
name: Sovereign Tenant Branding
|
||||||
|
labels:
|
||||||
|
blueprints.goauthentik.io/description: Tenant branding configuration managed by Ansible
|
||||||
|
entries:
|
||||||
|
- model: authentik_brands.brand
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
domain: authentik-default
|
||||||
|
attrs:
|
||||||
|
branding_title: "{{ tenant_name }}"
|
||||||
|
{% if tenant_logo_local_path | default('') != '' %}
|
||||||
|
branding_logo: /media/branding/logo.png
|
||||||
|
branding_favicon: /media/branding/logo.png
|
||||||
|
{% endif %}
|
||||||
|
branding_custom_css: |
|
||||||
|
:root {
|
||||||
|
--ak-accent: {{ tenant_primary_color | default('#fd4b2d') }};
|
||||||
|
}
|
||||||
@@ -61,6 +61,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- {{ authentik_data_dir }}/media:/media
|
- {{ authentik_data_dir }}/media:/media
|
||||||
- {{ authentik_data_dir }}/custom-templates:/templates
|
- {{ authentik_data_dir }}/custom-templates:/templates
|
||||||
|
- {{ authentik_data_dir }}/blueprints:/blueprints/custom
|
||||||
- {{ authentik_data_dir }}/certs:/certs
|
- {{ authentik_data_dir }}/certs:/certs
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:9001:9000"
|
- "127.0.0.1:9001:9000"
|
||||||
|
|||||||
@@ -7,8 +7,16 @@
|
|||||||
loop:
|
loop:
|
||||||
- "{{ forgejo_data_dir }}"
|
- "{{ forgejo_data_dir }}"
|
||||||
- "{{ forgejo_data_dir }}/data"
|
- "{{ forgejo_data_dir }}/data"
|
||||||
|
- "{{ forgejo_data_dir }}/data/gitea/public/img"
|
||||||
- "{{ forgejo_data_dir }}/config"
|
- "{{ forgejo_data_dir }}/config"
|
||||||
|
|
||||||
|
- name: Copy tenant logo to Forgejo custom assets
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ tenant_logo_local_path }}"
|
||||||
|
dest: "{{ forgejo_data_dir }}/data/gitea/public/img/logo.png"
|
||||||
|
mode: '0644'
|
||||||
|
when: tenant_logo_local_path | default('') != ''
|
||||||
|
|
||||||
- name: Deploy Forgejo docker-compose
|
- name: Deploy Forgejo docker-compose
|
||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
src: docker-compose.yml.j2
|
src: docker-compose.yml.j2
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ services:
|
|||||||
FORGEJO__openid__ENABLE_OPENID_SIGNUP: "false"
|
FORGEJO__openid__ENABLE_OPENID_SIGNUP: "false"
|
||||||
FORGEJO__oauth2_client__REGISTER_EMAIL_CONFIRM: "false"
|
FORGEJO__oauth2_client__REGISTER_EMAIL_CONFIRM: "false"
|
||||||
FORGEJO__oauth2_client__ENABLE_AUTO_REGISTRATION: "true"
|
FORGEJO__oauth2_client__ENABLE_AUTO_REGISTRATION: "true"
|
||||||
|
FORGEJO____APP_NAME: "{{ tenant_name }}"
|
||||||
FORGEJO__log__LEVEL: warn
|
FORGEJO__log__LEVEL: warn
|
||||||
ports:
|
ports:
|
||||||
- "{{ forgejo_ssh_port }}:22"
|
- "{{ forgejo_ssh_port }}:22"
|
||||||
|
|||||||
@@ -11,6 +11,21 @@
|
|||||||
- "{{ jitsi_data_dir }}/jicofo"
|
- "{{ jitsi_data_dir }}/jicofo"
|
||||||
- "{{ jitsi_data_dir }}/jvb"
|
- "{{ jitsi_data_dir }}/jvb"
|
||||||
|
|
||||||
|
- name: Deploy Jitsi custom interface config
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: custom-interface-config.js.j2
|
||||||
|
dest: "{{ jitsi_data_dir }}/web/custom-interface-config.js"
|
||||||
|
mode: '0644'
|
||||||
|
notify: restart jitsi
|
||||||
|
|
||||||
|
- name: Copy tenant logo to Jitsi watermark
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ tenant_logo_local_path }}"
|
||||||
|
dest: "{{ jitsi_data_dir }}/web/watermark.png"
|
||||||
|
mode: '0644'
|
||||||
|
when: tenant_logo_local_path | default('') != ''
|
||||||
|
notify: restart jitsi
|
||||||
|
|
||||||
- name: Deploy Jitsi docker-compose
|
- name: Deploy Jitsi docker-compose
|
||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
src: docker-compose.yml.j2
|
src: docker-compose.yml.j2
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
// Sovereign tenant branding overrides for Jitsi Meet.
|
||||||
|
// This file is appended to interface_config.js by the Jitsi web container.
|
||||||
|
interfaceConfig.APP_NAME = '{{ tenant_name }}';
|
||||||
|
interfaceConfig.NATIVE_APP_NAME = '{{ tenant_name }}';
|
||||||
|
interfaceConfig.PROVIDER_NAME = '{{ tenant_name }}';
|
||||||
|
interfaceConfig.BRAND_WATERMARK_LINK = 'https://{{ base_domain }}';
|
||||||
@@ -5,6 +5,7 @@ services:
|
|||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
PUBLIC_URL: "https://{{ jitsi_domain }}"
|
PUBLIC_URL: "https://{{ jitsi_domain }}"
|
||||||
|
JITSI_WATERMARKLINK: "https://{{ base_domain }}"
|
||||||
XMPP_SERVER: jitsi-prosody
|
XMPP_SERVER: jitsi-prosody
|
||||||
XMPP_DOMAIN: meet.jitsi
|
XMPP_DOMAIN: meet.jitsi
|
||||||
XMPP_AUTH_DOMAIN: auth.meet.jitsi
|
XMPP_AUTH_DOMAIN: auth.meet.jitsi
|
||||||
|
|||||||
@@ -1,2 +1,4 @@
|
|||||||
---
|
---
|
||||||
matrix_data_dir: "{{ sovereign_base_dir }}/matrix"
|
matrix_data_dir: "{{ sovereign_base_dir }}/matrix"
|
||||||
|
# Element theme: "light" or "dark"
|
||||||
|
element_theme: "light"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
"server_name": "{{ matrix_domain }}"
|
"server_name": "{{ matrix_domain }}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"brand": "Element",
|
"brand": "{{ tenant_name }}",
|
||||||
"integrations_ui_url": "https://scalar.vector.im/",
|
"integrations_ui_url": "https://scalar.vector.im/",
|
||||||
"integrations_rest_url": "https://scalar.vector.im/api",
|
"integrations_rest_url": "https://scalar.vector.im/api",
|
||||||
"bug_report_endpoint_url": "",
|
"bug_report_endpoint_url": "",
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
"show_labs_settings": false,
|
"show_labs_settings": false,
|
||||||
"features": {},
|
"features": {},
|
||||||
"default_federate": true,
|
"default_federate": true,
|
||||||
"default_theme": "light",
|
"default_theme": "{{ element_theme | default('light') }}",
|
||||||
"room_directory": {
|
"room_directory": {
|
||||||
"servers": ["{{ matrix_domain }}"]
|
"servers": ["{{ matrix_domain }}"]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -19,3 +19,33 @@
|
|||||||
community.docker.docker_compose_v2:
|
community.docker.docker_compose_v2:
|
||||||
project_src: "{{ nextcloud_data_dir }}"
|
project_src: "{{ nextcloud_data_dir }}"
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
|
- name: Wait for Nextcloud to be ready
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: docker exec -u www-data nextcloud php occ status --output=json
|
||||||
|
register: nc_status
|
||||||
|
until: (nc_status.stdout | from_json).installed is defined and (nc_status.stdout | from_json).installed
|
||||||
|
retries: 30
|
||||||
|
delay: 10
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Copy tenant logo into Nextcloud container volume
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ tenant_logo_local_path }}"
|
||||||
|
dest: "{{ nextcloud_data_dir }}/data/sovereign-logo.png"
|
||||||
|
mode: '0644'
|
||||||
|
when: tenant_logo_local_path | default('') != ''
|
||||||
|
|
||||||
|
- name: Configure Nextcloud theming — name and colour
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: docker exec -u www-data nextcloud php occ theming:config {{ item.key }} "{{ item.value }}"
|
||||||
|
loop:
|
||||||
|
- { key: name, value: "{{ tenant_name }}" }
|
||||||
|
- { key: color, value: "{{ tenant_primary_color | default('#2563eb') }}" }
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Configure Nextcloud theming — logo
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: docker exec -u www-data nextcloud php occ theming:config logo /var/www/html/sovereign-logo.png
|
||||||
|
when: tenant_logo_local_path | default('') != ''
|
||||||
|
changed_when: false
|
||||||
|
|||||||
@@ -1,2 +1,4 @@
|
|||||||
---
|
---
|
||||||
roundcube_data_dir: "{{ sovereign_base_dir }}/roundcube"
|
roundcube_data_dir: "{{ sovereign_base_dir }}/roundcube"
|
||||||
|
# Roundcube UI skin. The official image ships "elastic" and "larry".
|
||||||
|
roundcube_skin: "elastic"
|
||||||
|
|||||||
@@ -6,6 +6,14 @@
|
|||||||
mode: '0755'
|
mode: '0755'
|
||||||
loop:
|
loop:
|
||||||
- "{{ roundcube_data_dir }}"
|
- "{{ roundcube_data_dir }}"
|
||||||
|
- "{{ roundcube_data_dir }}/config"
|
||||||
|
|
||||||
|
- name: Deploy Roundcube custom branding config
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: custom.inc.php.j2
|
||||||
|
dest: "{{ roundcube_data_dir }}/config/custom.inc.php"
|
||||||
|
mode: '0644'
|
||||||
|
notify: restart roundcube
|
||||||
|
|
||||||
- name: Deploy Roundcube docker-compose
|
- name: Deploy Roundcube docker-compose
|
||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
// Sovereign tenant branding for Roundcube.
|
||||||
|
// This file is merged with the auto-generated config by the container entrypoint.
|
||||||
|
|
||||||
|
$config['product_name'] = '{{ tenant_name }} Webmail';
|
||||||
@@ -35,7 +35,9 @@ services:
|
|||||||
ROUNDCUBEMAIL_SMTP_PORT: 587
|
ROUNDCUBEMAIL_SMTP_PORT: 587
|
||||||
ROUNDCUBEMAIL_DES_KEY: "{{ roundcube_des_key }}"
|
ROUNDCUBEMAIL_DES_KEY: "{{ roundcube_des_key }}"
|
||||||
ROUNDCUBEMAIL_PLUGINS: "archive,zipdownload,managesieve,jqueryui"
|
ROUNDCUBEMAIL_PLUGINS: "archive,zipdownload,managesieve,jqueryui"
|
||||||
ROUNDCUBEMAIL_SKIN: elastic
|
ROUNDCUBEMAIL_SKIN: "{{ roundcube_skin }}"
|
||||||
|
volumes:
|
||||||
|
- {{ roundcube_data_dir }}/config/custom.inc.php:/var/roundcube/config/custom.inc.php:ro
|
||||||
labels:
|
labels:
|
||||||
- "traefik.enable=true"
|
- "traefik.enable=true"
|
||||||
- "traefik.http.routers.roundcube.rule=Host(`{{ roundcube_domain }}`)"
|
- "traefik.http.routers.roundcube.rule=Host(`{{ roundcube_domain }}`)"
|
||||||
|
|||||||
@@ -7,6 +7,22 @@
|
|||||||
loop:
|
loop:
|
||||||
- "{{ wazuh_data_dir }}"
|
- "{{ wazuh_data_dir }}"
|
||||||
- "{{ wazuh_data_dir }}/config"
|
- "{{ wazuh_data_dir }}/config"
|
||||||
|
- "{{ wazuh_data_dir }}/dashboard-config"
|
||||||
|
|
||||||
|
- name: Deploy Wazuh dashboard branding config
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: opensearch_dashboards.yml.j2
|
||||||
|
dest: "{{ wazuh_data_dir }}/dashboard-config/opensearch_dashboards.yml"
|
||||||
|
mode: '0644'
|
||||||
|
notify: restart wazuh
|
||||||
|
|
||||||
|
- name: Copy tenant logo to Wazuh dashboard assets
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ tenant_logo_local_path }}"
|
||||||
|
dest: "{{ wazuh_data_dir }}/dashboard-config/branding-logo.png"
|
||||||
|
mode: '0644'
|
||||||
|
when: tenant_logo_local_path | default('') != ''
|
||||||
|
notify: restart wazuh
|
||||||
|
|
||||||
- name: Set vm.max_map_count for Wazuh indexer (OpenSearch)
|
- name: Set vm.max_map_count for Wazuh indexer (OpenSearch)
|
||||||
ansible.posix.sysctl:
|
ansible.posix.sysctl:
|
||||||
|
|||||||
@@ -84,6 +84,10 @@ services:
|
|||||||
- {{ wazuh_data_dir }}/wazuh-indexer-certs/wazuh.dashboard.pem:/usr/share/wazuh-dashboard/certs/wazuh-dashboard.pem
|
- {{ wazuh_data_dir }}/wazuh-indexer-certs/wazuh.dashboard.pem:/usr/share/wazuh-dashboard/certs/wazuh-dashboard.pem
|
||||||
- {{ wazuh_data_dir }}/wazuh-indexer-certs/wazuh.dashboard-key.pem:/usr/share/wazuh-dashboard/certs/wazuh-dashboard-key.pem
|
- {{ wazuh_data_dir }}/wazuh-indexer-certs/wazuh.dashboard-key.pem:/usr/share/wazuh-dashboard/certs/wazuh-dashboard-key.pem
|
||||||
- {{ wazuh_data_dir }}/wazuh-indexer-certs/root-ca.pem:/usr/share/wazuh-dashboard/certs/root-ca.pem
|
- {{ wazuh_data_dir }}/wazuh-indexer-certs/root-ca.pem:/usr/share/wazuh-dashboard/certs/root-ca.pem
|
||||||
|
- {{ wazuh_data_dir }}/dashboard-config/opensearch_dashboards.yml:/usr/share/wazuh-dashboard/config/opensearch_dashboards.yml:ro
|
||||||
|
{% if tenant_logo_local_path | default('') != '' %}
|
||||||
|
- {{ wazuh_data_dir }}/dashboard-config/branding-logo.png:/usr/share/wazuh-dashboard/plugins/wazuh/public/assets/custom/logos/branding-logo.png:ro
|
||||||
|
{% endif %}
|
||||||
labels:
|
labels:
|
||||||
- "traefik.enable=true"
|
- "traefik.enable=true"
|
||||||
- "traefik.http.routers.wazuh.rule=Host(`{{ wazuh_domain }}`)"
|
- "traefik.http.routers.wazuh.rule=Host(`{{ wazuh_domain }}`)"
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# Sovereign tenant branding for Wazuh Dashboard (OpenSearch Dashboards).
|
||||||
|
# Mounted over the default config — all required fields must be present.
|
||||||
|
|
||||||
|
server.host: "0.0.0.0"
|
||||||
|
server.port: 5601
|
||||||
|
opensearch.hosts: ["https://wazuh-indexer:9200"]
|
||||||
|
opensearch.ssl.verificationMode: certificate
|
||||||
|
opensearch.username: kibanaserver
|
||||||
|
opensearch.password: "{{ wazuh_admin_password }}"
|
||||||
|
opensearch.requestHeadersAllowlist: ["securitytenant","Authorization"]
|
||||||
|
opensearch_security.multitenancy.enabled: false
|
||||||
|
opensearch_security.readonly_mode.roles: ["kibana_read_only"]
|
||||||
|
server.ssl.enabled: true
|
||||||
|
server.ssl.key: /usr/share/wazuh-dashboard/certs/wazuh-dashboard-key.pem
|
||||||
|
server.ssl.certificate: /usr/share/wazuh-dashboard/certs/wazuh-dashboard.pem
|
||||||
|
opensearch.ssl.certificateAuthorities: ["/usr/share/wazuh-dashboard/certs/root-ca.pem"]
|
||||||
|
uiSettings.overrides.defaultRoute: /app/wazuh
|
||||||
|
|
||||||
|
opensearchDashboards.branding:
|
||||||
|
applicationTitle: "{{ tenant_name }} Security"
|
||||||
|
{% if tenant_logo_local_path | default('') != '' %}
|
||||||
|
logo:
|
||||||
|
defaultUrl: "/ui/logos/branding-logo.png"
|
||||||
|
darkModeUrl: "/ui/logos/branding-logo.png"
|
||||||
|
mark:
|
||||||
|
defaultUrl: "/ui/logos/branding-logo.png"
|
||||||
|
darkModeUrl: "/ui/logos/branding-logo.png"
|
||||||
|
{% endif %}
|
||||||
Reference in New Issue
Block a user