From 3dba4e6fe9b59a973a450c1c5b7017e864e40358 Mon Sep 17 00:00:00 2001 From: Iurii Tatishchev Date: Thu, 23 Nov 2023 00:30:03 -0800 Subject: [PATCH] authentik, monitoring: add uptime-kuma with authentik proxy blueprint --- .../templates/blueprints/apps-proxy.yaml.j2 | 115 ++++++++++++++++++ .../templates/blueprints/arrstack.yaml.j2 | 72 ----------- .../templates/docker-compose.yml.j2 | 9 ++ 3 files changed, 124 insertions(+), 72 deletions(-) create mode 100644 roles/alpina/collections/services/authentik/templates/blueprints/apps-proxy.yaml.j2 delete mode 100644 roles/alpina/collections/services/authentik/templates/blueprints/arrstack.yaml.j2 diff --git a/roles/alpina/collections/services/authentik/templates/blueprints/apps-proxy.yaml.j2 b/roles/alpina/collections/services/authentik/templates/blueprints/apps-proxy.yaml.j2 new file mode 100644 index 0000000..a807fda --- /dev/null +++ b/roles/alpina/collections/services/authentik/templates/blueprints/apps-proxy.yaml.j2 @@ -0,0 +1,115 @@ +version: 1 +metadata: + labels: + blueprints.goauthentik.io/instantiate: "true" + name: Alpina - Proxied Apps +entries: + - identifiers: + name: arrstack + model: authentik_core.group + id: arrstack + attrs: + arrstack_username: "arr" + arrstack_password: "{{ arrstack_password }}" + + # TODO: Probably refactor this into a jinja macro + {% set apps = { + "uptime-kuma": { + "host": "uptime", + "name": "Uptime Kuma", + "icon": "https://uptime."~ domain ~"/icon.svg", + "unauthenticated_paths": "^/icon.svg$", + "group": "Services", + "create_admin_group": true, + }, + "qbit": { + "host": "qbit", + "name": "qBit", + "icon": "https://qbit."~ domain ~"/images/qbittorrent-tray.svg", + "unauthenticated_paths": "^/images/qbittorrent-tray.svg$", + "group": "Arrstack", + "create_admin_group": false, + }, + "prowlarr": { + "host": "prowlarr", + "name": "Prowlarr", + "icon": "https://prowlarr."~ domain ~"/Content/Images/logo.svg", + "unauthenticated_paths": "^/Content/Images/logo.svg$", + "group": "Arrstack", + "create_admin_group": false, + }, + "sonarr": { + "host": "sonarr", + "name": "Sonarr", + "icon": "https://sonarr."~ domain ~"/Content/Images/logo.svg", + "unauthenticated_paths": "^/Content/Images/logo.svg$", + "group": "Arrstack", + "create_admin_group": false, + }, + "radarr": { + "host": "radarr", + "name": "Radarr", + "icon": "https://radarr."~ domain ~"/Content/Images/logo.svg", + "unauthenticated_paths": "^/Content/Images/logo.svg$", + "group": "Arrstack", + "create_admin_group": false, + }, + } -%} + + {% for app in apps.keys() -%} + - identifiers: + name: {{ apps[app]["name"] }} + model: authentik_providers_proxy.proxyprovider + id: {{ app }} + attrs: + authorization_flow: !Find [authentik_flows.flow, [ slug, default-provider-authorization-implicit-consent ] ] + mode: forward_single + external_host: "https://{{ apps[app]["host"] }}.{{ domain }}/" + skip_path_regex: "{{ apps[app]["unauthenticated_paths"] }}" + + - identifiers: + slug: {{ app }} + model: authentik_core.application + attrs: + name: {{ apps[app]["name"] }} + group: {{ apps[app]["group"] }} + meta_description: "Hello, I'm {{ apps[app]["name"] }}!" + meta_publisher: Alpina + icon: "{{ apps[app]["icon"] }}" + open_in_new_tab: true + provider: !KeyOf {{ app }} + + {% if apps[app]["create_admin_group"] -%} + - identifiers: + name: "{{ apps[app]["name"] }} Admins" + model: authentik_core.group + id: "{{ app }} Admins" + + - identifiers: + group: !KeyOf "{{ app }} Admins" + target: !Find [authentik_core.application, [ slug, {{ app }}] ] + model: authentik_policies.policybinding + attrs: + order: 0 + {% endif %} + + {% if apps[app]["group"] == "Arrstack" -%} + - identifiers: + group: !KeyOf arrstack + target: !Find [authentik_core.application, [slug, {{ app }}]] + model: authentik_policies.policybinding + attrs: + order: 0 + {% endif %} + + {% endfor %} + + - identifiers: + managed: goauthentik.io/outposts/embedded + name: authentik Embedded Outpost + model: authentik_outposts.outpost + attrs: + providers: + {% for app in apps.keys() -%} + - !KeyOf {{ app }} + {% endfor %} diff --git a/roles/alpina/collections/services/authentik/templates/blueprints/arrstack.yaml.j2 b/roles/alpina/collections/services/authentik/templates/blueprints/arrstack.yaml.j2 deleted file mode 100644 index 43a76a4..0000000 --- a/roles/alpina/collections/services/authentik/templates/blueprints/arrstack.yaml.j2 +++ /dev/null @@ -1,72 +0,0 @@ -version: 1 -metadata: - labels: - blueprints.goauthentik.io/instantiate: "true" - name: Alpina - Arrstack Proxy -entries: - - identifiers: - name: arrstack - model: authentik_core.group - id: arrstack - attrs: - arrstack_username: "arr" - arrstack_password: "{{ arrstack_password }}" - - {% for service in ["qBit", "Prowlarr", "Sonarr", "Radarr"] -%} - - identifiers: - name: {{ service }} - model: authentik_providers_proxy.proxyprovider - id: {{ service | lower }} - attrs: - access_token_validity: hours=24 - authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]] - certificate: !Find [authentik_crypto.certificatekeypair, [name, "authentik Self-signed Certificate"]] - {% if service != 'qBit' -%} - basic_auth_enabled: true - basic_auth_user_attribute: arrstack_username - basic_auth_password_attribute: arrstack_password - {% endif -%} - intercept_header_auth: true - external_host: https://{{ service | lower }}.{{ domain }}/ - mode: forward_single - property_mappings: - - !Find [authentik_providers_oauth2.scopemapping, [scope_name, openid]] - - !Find [authentik_providers_oauth2.scopemapping, [scope_name, email]] - - !Find [authentik_providers_oauth2.scopemapping, [scope_name, profile]] - - !Find [authentik_providers_oauth2.scopemapping, [scope_name, ak_proxy]] - refresh_token_validity: days=30 - skip_path_regex: {{ "/images/qbittorrent-tray.svg" if service == "qBit" else "/Content/Images/logo.svg" }} - - - identifiers: - slug: {{ service | lower }} - model: authentik_core.application - id: {{ service | lower }} - attrs: - name: {{ service }} - group: "Arrstack" - meta_description: "Hello, I'm {{ service }}!" - meta_publisher: Alpina - icon: "https://{{ service }}.{{ domain }}/{{ "images/qbittorrent-tray.svg" if service == "qBit" else "Content/Images/logo.svg" }}" - open_in_new_tab: true - policy_engine_mode: any - provider: !KeyOf {{ service | lower }} - - - identifiers: - group: !KeyOf arrstack - target: !Find [authentik_core.application, [slug, {{ service | lower }}]] - model: authentik_policies.policybinding - attrs: - enabled: true - order: 0 - timeout: 30 - {% endfor %} - - - identifiers: - managed: goauthentik.io/outposts/embedded - name: authentik Embedded Outpost - model: authentik_outposts.outpost - attrs: - providers: - {% for service in ["qBit", "Prowlarr", "Sonarr", "Radarr"] -%} - - !KeyOf {{ service | lower }} - {% endfor %} diff --git a/roles/alpina/collections/services/monitoring/templates/docker-compose.yml.j2 b/roles/alpina/collections/services/monitoring/templates/docker-compose.yml.j2 index db2ef96..61fdf1c 100644 --- a/roles/alpina/collections/services/monitoring/templates/docker-compose.yml.j2 +++ b/roles/alpina/collections/services/monitoring/templates/docker-compose.yml.j2 @@ -88,3 +88,12 @@ services: - 6831:6831/udp volumes: - {{ base_volume_path }}/monitoring/jaeger:/jaeger + + uptime-kuma: + image: louislam/uptime-kuma:1 + container_name: uptime-kuma + labels: + - {{ helpers.traefik_labels('uptime', port='3001', auth=true) | indent(6) }} + restart: unless-stopped + volumes: + - {{ base_volume_path }}/monitoring/uptime-kuma:/app/data