mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-11-20 12:06:25 +00:00
Compare commits
81 Commits
189aaaa9ec
...
feature/ke
| Author | SHA1 | Date | |
|---|---|---|---|
| 6fcf6a1ab6 | |||
| 4d9890406e | |||
| 59b652958f | |||
| a327adf8db | |||
| 7a38cb90fb | |||
| 9d6cf03f5b | |||
| 9439ac7f76 | |||
| 23353ac878 | |||
| 8beda2d45d | |||
| 5773409bd7 | |||
| b3ea962338 | |||
| b9fbf92461 | |||
| 6824e444b0 | |||
| 5cdcc18a99 | |||
| e7702948b8 | |||
| 09a4c243d7 | |||
| 1d5a50abf2 | |||
| 0d99c7f297 | |||
| 0a17e54d8c | |||
| bf94338845 | |||
| 5d42b78b3d | |||
| 26a1992d84 | |||
| 2439beb95a | |||
| 251f7b227d | |||
| 3fbb9c38a8 | |||
| 29e8b3a590 | |||
| 27b89d8fb6 | |||
| 55f2d15e93 | |||
| aa19a97ed6 | |||
| c06d1c4d17 | |||
| 66f294537d | |||
| a9097a3ec3 | |||
| fc59c64273 | |||
| dbbb3510f3 | |||
| eb3bf543a4 | |||
| 4f5602c791 | |||
| 75d476267e | |||
| c3e5db7f2e | |||
| dfd2d243b7 | |||
| 78ad2ea4b6 | |||
| c362e160fc | |||
| a044028e03 | |||
| 7405883b48 | |||
| 85db0a40db | |||
| 8af39c32ec | |||
| 31e86ac0fc | |||
| 4d223f1784 | |||
| 926def3d01 | |||
| 083b7d2914 | |||
| 73a38e0b2b | |||
| e3c0880e98 | |||
| a817d964e4 | |||
| 7572134e9d | |||
| 97af4990aa | |||
| b6d0535173 | |||
| 27d33435f8 | |||
| 3cc4014edf | |||
| 63da669c33 | |||
| fb04a4c7a0 | |||
| 2968ac7f0a | |||
| 1daa53017e | |||
| 9082443753 | |||
| bcee1fecdf | |||
| 0602148caa | |||
| cbfb991e79 | |||
| fa7b1400bd | |||
| c7cae93597 | |||
| 6ea0d09f14 | |||
| 5e4cda0ac9 | |||
| 1d29617f85 | |||
| 7c5ad8e6a1 | |||
| a26538d1b3 | |||
| f55b0ca797 | |||
| 6f3522dc28 | |||
| 5186eb5714 | |||
| 73bcdcaf45 | |||
| 9e402c863f | |||
| 84865d61b8 | |||
| 423850d3e6 | |||
| 598f4e854a | |||
| 1f99a6b84b |
@@ -158,26 +158,31 @@ class FilterModule(object):
|
||||
for directive in directives:
|
||||
tokens = ["'self'"]
|
||||
|
||||
# 1) Load flags (includes defaults from get_csp_flags)
|
||||
# Load flags (includes defaults from get_csp_flags)
|
||||
flags = self.get_csp_flags(applications, application_id, directive)
|
||||
tokens += flags
|
||||
|
||||
# 2) Allow fetching from internal CDN by default for selected directives
|
||||
# Allow fetching from internal CDN by default for selected directives
|
||||
if directive in ['script-src-elem', 'connect-src', 'style-src-elem']:
|
||||
tokens.append(get_url(domains, 'web-svc-cdn', web_protocol))
|
||||
|
||||
# 3) Matomo integration if feature is enabled
|
||||
# Matomo integration if feature is enabled
|
||||
if directive in ['script-src-elem', 'connect-src']:
|
||||
if self.is_feature_enabled(applications, matomo_feature_name, application_id):
|
||||
tokens.append(get_url(domains, 'web-app-matomo', web_protocol))
|
||||
|
||||
# 4) ReCaptcha integration (scripts + frames) if feature is enabled
|
||||
# Simpleicons integration if feature is enabled
|
||||
if directive in ['connect-src']:
|
||||
if self.is_feature_enabled(applications, 'simpleicons', application_id):
|
||||
tokens.append(get_url(domains, 'web-svc-simpleicons', web_protocol))
|
||||
|
||||
# ReCaptcha integration (scripts + frames) if feature is enabled
|
||||
if self.is_feature_enabled(applications, 'recaptcha', application_id):
|
||||
if directive in ['script-src-elem', 'frame-src']:
|
||||
tokens.append('https://www.gstatic.com')
|
||||
tokens.append('https://www.google.com')
|
||||
|
||||
# 5) Frame ancestors handling (desktop + logout support)
|
||||
# Frame ancestors handling (desktop + logout support)
|
||||
if directive == 'frame-ancestors':
|
||||
if self.is_feature_enabled(applications, 'desktop', application_id):
|
||||
# Allow being embedded by the desktop app domain (and potentially its parent)
|
||||
@@ -189,10 +194,10 @@ class FilterModule(object):
|
||||
tokens.append(get_url(domains, 'web-svc-logout', web_protocol))
|
||||
tokens.append(get_url(domains, 'web-app-keycloak', web_protocol))
|
||||
|
||||
# 6) Custom whitelist entries
|
||||
# Custom whitelist entries
|
||||
tokens += self.get_csp_whitelist(applications, application_id, directive)
|
||||
|
||||
# 7) Add inline content hashes ONLY if final tokens do NOT include 'unsafe-inline'
|
||||
# Add inline content hashes ONLY if final tokens do NOT include 'unsafe-inline'
|
||||
# (Check tokens, not flags, to include defaults and later modifications.)
|
||||
if "'unsafe-inline'" not in tokens:
|
||||
for snippet in self.get_csp_inline_content(applications, application_id, directive):
|
||||
@@ -201,7 +206,7 @@ class FilterModule(object):
|
||||
# Append directive
|
||||
parts.append(f"{directive} {' '.join(tokens)};")
|
||||
|
||||
# 8) Static img-src directive (kept permissive for data/blob and any host)
|
||||
# Static img-src directive (kept permissive for data/blob and any host)
|
||||
parts.append("img-src * data: blob:;")
|
||||
|
||||
return ' '.join(parts)
|
||||
|
||||
@@ -20,9 +20,10 @@ def get_docker_paths(application_id: str, path_docker_compose_instances: str) ->
|
||||
'config': f"{base}config/",
|
||||
},
|
||||
'files': {
|
||||
'env': f"{base}.env/env",
|
||||
'docker_compose': f"{base}docker-compose.yml",
|
||||
'dockerfile': f"{base}Dockerfile",
|
||||
'env': f"{base}.env/env",
|
||||
'docker_compose': f"{base}docker-compose.yml",
|
||||
'docker_compose_override': f"{base}docker-compose.override.yml",
|
||||
'dockerfile': f"{base}Dockerfile",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,3 +7,4 @@ MODE_DEBUG: false # This enables debugging in ansible an
|
||||
MODE_RESET: false # Cleans up all Infinito.Nexus files. It's necessary to run to whole playbook and not particial roles when using this function.
|
||||
MODE_CLEANUP: "{{ MODE_DEBUG | bool }}" # Cleanup unused files and configurations
|
||||
MODE_ASSERT: "{{ MODE_DEBUG | bool }}" # Executes validation tasks during the run.
|
||||
MODE_BACKUP: true # Executes the Backup before the deployment
|
||||
|
||||
@@ -6,12 +6,12 @@ SYS_TIMER_ALL_ENABLED: "{{ MODE_DEBUG }}" # Runtime Var
|
||||
|
||||
## Server Tact Variables
|
||||
|
||||
HOURS_SERVER_AWAKE: "0..23" # Ours in which the server is "awake" (100% working). Rest of the time is reserved for maintanance
|
||||
HOURS_SERVER_AWAKE: "6..23" # Ours in which the server is "awake" (100% working). Rest of the time is reserved for maintanance
|
||||
RANDOMIZED_DELAY_SEC: "5min" # Random delay for systemd timers to avoid peak loads.
|
||||
|
||||
## Timeouts for all services
|
||||
SYS_TIMEOUT_DOCKER_RPR_HARD: "10min"
|
||||
SYS_TIMEOUT_DOCKER_RPR_SOFT: "{{ SYS_TIMEOUT_DOCKER_RPR_HARD }}"
|
||||
SYS_TIMEOUT_DOCKER_RPR_SOFT: "{{ SYS_TIMEOUT_DOCKER_RPR_HARD }}"
|
||||
SYS_TIMEOUT_CLEANUP_SERVICES: "15min"
|
||||
SYS_TIMEOUT_DOCKER_UPDATE: "20min"
|
||||
SYS_TIMEOUT_STORAGE_OPTIMIZER: "{{ SYS_TIMEOUT_DOCKER_UPDATE }}"
|
||||
|
||||
@@ -110,6 +110,8 @@ defaults_networks:
|
||||
subnet: 192.168.104.16/28
|
||||
web-app-minio:
|
||||
subnet: 192.168.104.32/28
|
||||
web-svc-coturn:
|
||||
subnet: 192.168.104.48/28
|
||||
|
||||
# /24 Networks / 254 Usable Clients
|
||||
web-app-bigbluebutton:
|
||||
|
||||
@@ -84,16 +84,25 @@ ports:
|
||||
public:
|
||||
# The following ports should be changed to 22 on the subdomain via stream mapping
|
||||
ssh:
|
||||
web-app-gitea: 2201
|
||||
web-app-gitlab: 2202
|
||||
web-app-gitea: 2201
|
||||
web-app-gitlab: 2202
|
||||
ldaps:
|
||||
svc-db-openldap: 636
|
||||
stun:
|
||||
web-app-bigbluebutton: 3478 # Not sure if it's right placed here or if it should be moved to localhost section
|
||||
# Occupied by BBB: 3479
|
||||
web-app-nextcloud: 3480
|
||||
turn:
|
||||
web-app-bigbluebutton: 5349 # Not sure if it's right placed here or if it should be moved to localhost section
|
||||
web-app-nextcloud: 5350 # Not used yet
|
||||
svc-db-openldap: 636
|
||||
stun_turn:
|
||||
web-app-bigbluebutton: 3478 # Not sure if it's right placed here or if it should be moved to localhost section
|
||||
# Occupied by BBB: 3479
|
||||
web-app-nextcloud: 3480
|
||||
web-svc-coturn: 3481
|
||||
stun_turn_tls:
|
||||
web-app-bigbluebutton: 5349 # Not sure if it's right placed here or if it should be moved to localhost section
|
||||
web-app-nextcloud: 5350 # Not used yet
|
||||
web-svc-coturn: 5351
|
||||
federation:
|
||||
web-app-matrix_synapse: 8448
|
||||
relay_port_ranges:
|
||||
web-svc-coturn_start: 20000
|
||||
web-svc-coturn_end: 39999
|
||||
web-app-bigbluebutton_start: 40000
|
||||
web-app-bigbluebutton_end: 49999
|
||||
web-app-nextcloud_start: 50000
|
||||
web-app-nextcloud_end: 59999
|
||||
|
||||
@@ -142,7 +142,8 @@ class InventoryManager:
|
||||
"""
|
||||
if algorithm == "random_hex":
|
||||
return secrets.token_hex(64)
|
||||
|
||||
if algorithm == "random_hex_32":
|
||||
return secrets.token_hex(32)
|
||||
if algorithm == "sha256":
|
||||
return hashlib.sha256(secrets.token_bytes(32)).hexdigest()
|
||||
if algorithm == "sha1":
|
||||
|
||||
4
roles/dev-yay/defaults/main.yml
Normal file
4
roles/dev-yay/defaults/main.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
AUR_HELPER: yay
|
||||
AUR_BUILDER_USER: aur_builder
|
||||
AUR_BUILDER_GROUP: wheel
|
||||
AUR_BUILDER_SUDOERS_PATH: /etc/sudoers.d/11-install-aur_builder
|
||||
@@ -6,42 +6,53 @@
|
||||
- dev-git
|
||||
- dev-base-devel
|
||||
|
||||
- name: install yay
|
||||
- name: Install yay build prerequisites
|
||||
community.general.pacman:
|
||||
name:
|
||||
- base-devel
|
||||
- patch
|
||||
state: present
|
||||
|
||||
- name: Create the `aur_builder` user
|
||||
- name: Create the AUR builder user
|
||||
become: true
|
||||
ansible.builtin.user:
|
||||
name: aur_builder
|
||||
name: "{{ AUR_BUILDER_USER }}"
|
||||
create_home: yes
|
||||
group: wheel
|
||||
group: "{{ AUR_BUILDER_GROUP }}"
|
||||
|
||||
- name: Allow the `aur_builder` user to run `sudo pacman` without a password
|
||||
- name: Allow AUR builder to run pacman without password
|
||||
become: true
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/sudoers.d/11-install-aur_builder
|
||||
line: 'aur_builder ALL=(ALL) NOPASSWD: /usr/bin/pacman'
|
||||
path: "{{ AUR_BUILDER_SUDOERS_PATH }}"
|
||||
line: '{{ AUR_BUILDER_USER }} ALL=(ALL) NOPASSWD: /usr/bin/pacman'
|
||||
create: yes
|
||||
validate: 'visudo -cf %s'
|
||||
|
||||
- name: Clone yay from AUR
|
||||
become: true
|
||||
become_user: aur_builder
|
||||
become_user: "{{ AUR_BUILDER_USER }}"
|
||||
git:
|
||||
repo: https://aur.archlinux.org/yay.git
|
||||
dest: /home/aur_builder/yay
|
||||
dest: "/home/{{ AUR_BUILDER_USER }}/yay"
|
||||
clone: yes
|
||||
update: yes
|
||||
|
||||
- name: Build and install yay
|
||||
become: true
|
||||
become_user: aur_builder
|
||||
become_user: "{{ AUR_BUILDER_USER }}"
|
||||
shell: |
|
||||
cd /home/aur_builder/yay
|
||||
cd /home/{{ AUR_BUILDER_USER }}/yay
|
||||
makepkg -si --noconfirm
|
||||
args:
|
||||
creates: /usr/bin/yay
|
||||
|
||||
- name: upgrade the system using yay, only act on AUR packages.
|
||||
become: true
|
||||
become_user: "{{ AUR_BUILDER_USER }}"
|
||||
kewlfft.aur.aur:
|
||||
upgrade: yes
|
||||
use: "{{ AUR_HELPER }}"
|
||||
aur_only: yes
|
||||
when: MODE_UPDATE | bool
|
||||
|
||||
- include_tasks: utils/run_once.yml
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
- block:
|
||||
- include_tasks: 01_core.yml
|
||||
- set_fact:
|
||||
run_once_dev_yay: true
|
||||
when: run_once_dev_yay is not defined
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
- name: Set default docker_repository_path
|
||||
set_fact:
|
||||
docker_repository_path: "{{docker_compose.directories.services}}repository/"
|
||||
docker_repository_path: "{{ [ docker_compose.directories.services, 'repository/' ] | path_join }}"
|
||||
|
||||
- name: pull docker repository
|
||||
git:
|
||||
repo: "{{ docker_repository_address }}"
|
||||
dest: "{{ docker_repository_path }}"
|
||||
version: "{{ docker_repository_branch | default('main') }}"
|
||||
depth: 1
|
||||
update: yes
|
||||
recursive: yes
|
||||
repo: "{{ docker_repository_address }}"
|
||||
dest: "{{ docker_repository_path }}"
|
||||
version: "{{ docker_repository_branch | default('main') }}"
|
||||
single_branch: yes
|
||||
depth: 1
|
||||
update: yes
|
||||
recursive: yes
|
||||
force: yes
|
||||
accept_hostkey: yes
|
||||
notify:
|
||||
- docker compose build
|
||||
- docker compose up
|
||||
|
||||
@@ -28,6 +28,21 @@
|
||||
- env_template is failed
|
||||
- "'Could not find or access' not in env_template.msg"
|
||||
|
||||
- name: "Create (optional) '{{ docker_compose.files.docker_compose_override }}'"
|
||||
template:
|
||||
src: "{{ item }}"
|
||||
dest: "{{ docker_compose.files.docker_compose_override }}"
|
||||
mode: '770'
|
||||
force: yes
|
||||
notify: docker compose up
|
||||
register: docker_compose_override_template
|
||||
loop:
|
||||
- "{{ application_id | abs_role_path_by_application_id }}/templates/docker-compose.override.yml.j2"
|
||||
- "{{ application_id | abs_role_path_by_application_id }}/files/docker-compose.override.yml"
|
||||
failed_when:
|
||||
- docker_compose_override_template is failed
|
||||
- "'Could not find or access' not in docker_compose_override_template.msg"
|
||||
|
||||
- name: "Create (obligatoric) '{{ docker_compose.files.docker_compose }}'"
|
||||
template:
|
||||
src: "docker-compose.yml.j2"
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
users:
|
||||
blackhole:
|
||||
description: "Everything what will be send to this user will disapear"
|
||||
username: "blackhole"
|
||||
username: "blackhole"
|
||||
roles:
|
||||
- mail-bot
|
||||
@@ -1,2 +1,4 @@
|
||||
# @See https://chatgpt.com/share/67a23d18-fb54-800f-983c-d6d00752b0b4
|
||||
docker_compose: "{{ application_id | get_docker_paths(PATH_DOCKER_COMPOSE_INSTANCES) }}"
|
||||
docker_compose: "{{ application_id | get_docker_paths(PATH_DOCKER_COMPOSE_INSTANCES) }}"
|
||||
docker_compose_command_base: "docker compose --env-file {{ docker_compose.files.env }}"
|
||||
docker_compose_command_exec: "{{ docker_compose_command_base }} exec"
|
||||
@@ -4,7 +4,7 @@
|
||||
run_once_pkgmgr_install: true
|
||||
when: run_once_pkgmgr_install is not defined
|
||||
|
||||
- name: update {{ package_name }}
|
||||
- name: "update {{ package_name }}"
|
||||
ansible.builtin.shell: |
|
||||
source ~/.venvs/pkgmgr/bin/activate
|
||||
pkgmgr update {{ package_name }} --dependencies --clone-mode https
|
||||
|
||||
@@ -5,7 +5,7 @@ network:
|
||||
docker:
|
||||
services:
|
||||
openldap:
|
||||
image: "bitnami/openldap"
|
||||
image: "bitnamilegacy/openldap"
|
||||
name: "openldap"
|
||||
version: "latest"
|
||||
network: "openldap"
|
||||
|
||||
@@ -6,7 +6,7 @@ docker:
|
||||
name: postgres
|
||||
# Please set an version in your inventory file!
|
||||
# Rolling release isn't recommended
|
||||
version: "latest"
|
||||
version: "17-3.5"
|
||||
backup:
|
||||
database_routine: true
|
||||
cpus: "2.0"
|
||||
@@ -14,5 +14,5 @@ docker:
|
||||
mem_limit: "6g"
|
||||
pids_limit: 1024
|
||||
volumes:
|
||||
data: "postgres_data"
|
||||
network: "postgres"
|
||||
data: "postgres_data"
|
||||
network: "postgres"
|
||||
@@ -5,7 +5,7 @@ RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
git \
|
||||
postgresql-server-dev-all \
|
||||
postgresql-server-dev-{{ POSTGRES_VERSION_MAJOR | default('all', true) }} \
|
||||
&& git clone https://github.com/pgvector/pgvector.git /tmp/pgvector \
|
||||
&& cd /tmp/pgvector \
|
||||
&& make \
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# General
|
||||
application_id: svc-db-postgres
|
||||
entity_name: "{{ application_id | get_entity_name }}"
|
||||
|
||||
# Docker
|
||||
docker_compose_flush_handlers: true
|
||||
@@ -9,11 +10,12 @@ database_type: "{{ application_id | get_entity_name }
|
||||
|
||||
## Postgres
|
||||
POSTGRES_VOLUME: "{{ applications | get_app_conf(application_id, 'docker.volumes.data') }}"
|
||||
POSTGRES_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.postgres.name') }}"
|
||||
POSTGRES_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.postgres.image') }}"
|
||||
POSTGRES_SUBNET: "{{ networks.local['svc-db-postgres'].subnet }}"
|
||||
POSTGRES_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.' ~ entity_name ~ '.name') }}"
|
||||
POSTGRES_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.' ~ entity_name ~ '.image') }}"
|
||||
POSTGRES_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.' ~ entity_name ~ '.version') }}"
|
||||
POSTGRES_VERSION_MAJOR: "{{ POSTGRES_VERSION | regex_replace('^([0-9]+).*', '\\1') }}"
|
||||
POSTGRES_NETWORK_NAME: "{{ applications | get_app_conf(application_id, 'docker.network') }}"
|
||||
POSTGRES_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.postgres.version') }}"
|
||||
POSTGRES_SUBNET: "{{ networks.local['svc-db-postgres'].subnet }}"
|
||||
POSTGRES_PASSWORD: "{{ applications | get_app_conf(application_id, 'credentials.POSTGRES_PASSWORD') }}"
|
||||
POSTGRES_PORT: "{{ database_port | default(ports.localhost.database[ application_id ]) }}"
|
||||
POSTGRES_INIT: "{{ database_username is defined and database_password is defined and database_name is defined }}"
|
||||
|
||||
14
roles/svc-opt-swapfile/tasks/01_core.yml
Normal file
14
roles/svc-opt-swapfile/tasks/01_core.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
- name: Install '
|
||||
include_role:
|
||||
name: pkgmgr-install
|
||||
vars:
|
||||
package_name: "{{ SWAPFILE_PKG }}"
|
||||
when: run_once_pkgmgr_install is not defined
|
||||
|
||||
- name: Execute create swapfile script
|
||||
shell: "{{ SWAPFILE_PKG }} '{{ SWAPFILE_SIZE }}'"
|
||||
become: true
|
||||
async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}"
|
||||
poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}"
|
||||
|
||||
- include_tasks: utils/run_once.yml
|
||||
@@ -1,19 +1,3 @@
|
||||
- block:
|
||||
- name: Include dependency 'pkgmgr-install'
|
||||
include_role:
|
||||
name: pkgmgr-install
|
||||
when: run_once_pkgmgr_install is not defined
|
||||
- include_tasks: utils/run_once.yml
|
||||
- include_tasks: 01_core.yml
|
||||
when: run_once_svc_opt_swapfile is not defined
|
||||
|
||||
- name: "pkgmgr install"
|
||||
include_role:
|
||||
name: pkgmgr-install
|
||||
vars:
|
||||
package_name: swap-forge
|
||||
|
||||
- name: Execute create swapfile script
|
||||
shell: swap-forge "{{ SWAPFILE_SIZE }}"
|
||||
become: true
|
||||
async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}"
|
||||
poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}"
|
||||
@@ -1,3 +1,4 @@
|
||||
application_id: "svc-opt-swapfile"
|
||||
|
||||
SWAPFILE_SIZE: "{{ applications | get_app_conf(application_id, 'swapfile_size') }}"
|
||||
SWAPFILE_SIZE: "{{ applications | get_app_conf(application_id, 'swapfile_size') }}"
|
||||
SWAPFILE_PKG: "swap-forge"
|
||||
@@ -5,21 +5,23 @@
|
||||
- sys-ctl-alm-telegram
|
||||
- sys-ctl-alm-email
|
||||
vars:
|
||||
flush_handlers: true
|
||||
system_service_timer_enabled: false
|
||||
system_service_copy_files: true
|
||||
system_service_tpl_exec_start: "{{ system_service_script_exec }} %I"
|
||||
system_service_tpl_on_failure: ""
|
||||
flush_handlers: true
|
||||
system_service_timer_enabled: false
|
||||
system_service_copy_files: true
|
||||
system_service_tpl_exec_start: "{{ system_service_script_exec }} %I"
|
||||
system_service_tpl_on_failure: ""
|
||||
system_service_force_linear_sync: false
|
||||
|
||||
- name: "Include core service for '{{ system_service_id }}'"
|
||||
include_role:
|
||||
name: sys-service
|
||||
vars:
|
||||
flush_handlers: true
|
||||
system_service_timer_enabled: false
|
||||
system_service_copy_files: true
|
||||
system_service_tpl_exec_start: "{{ system_service_script_exec }} %I"
|
||||
system_service_tpl_on_failure: "" # No on failure needed, because it's anyhow the default on failure procedure
|
||||
flush_handlers: true
|
||||
system_service_timer_enabled: false
|
||||
system_service_copy_files: true
|
||||
system_service_tpl_exec_start: "{{ system_service_script_exec }} %I"
|
||||
system_service_tpl_on_failure: "" # No on failure needed, because it's anyhow the default on failure procedure
|
||||
system_service_force_linear_sync: false
|
||||
|
||||
- name: Assert '{{ system_service_id }}'
|
||||
block:
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
vars:
|
||||
system_service_copy_files: false
|
||||
system_service_timer_enabled: true
|
||||
system_service_force_linear_sync: true
|
||||
system_service_force_flush: "{{ MODE_BACKUP | bool }}"
|
||||
system_service_on_calendar: "{{ SYS_SCHEDULE_BACKUP_DOCKER_TO_LOCAL }}"
|
||||
system_service_tpl_exec_start_pre: '/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ SYS_SERVICE_GROUP_MANIPULATION | join(" ") }} --ignore {{ SYS_SERVICE_BACKUP_DOCKER_2_LOC }} --timeout "{{ SYS_TIMEOUT_BACKUP_SERVICES }}"'
|
||||
system_service_tpl_exec_start: "/bin/sh -c '{{ BKP_DOCKER_2_LOC_EXEC }}'"
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
system_service_tpl_exec_start: dockreap --no-confirmation
|
||||
system_service_tpl_exec_start_pre: "" # Anonymous volumes can allways be removed. It isn't necessary to wait for any service to stop.
|
||||
system_service_copy_files: false
|
||||
system_service_force_linear_sync: false
|
||||
|
||||
- include_tasks: utils/run_once.yml
|
||||
when:
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
system_service_tpl_exec_start: "{{ system_service_script_exec }} --backups-folder-path {{ BACKUPS_FOLDER_PATH }} --maximum-backup-size-percent {{SIZE_PERCENT_MAXIMUM_BACKUP}}"
|
||||
system_service_tpl_exec_start_pre: '/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ SYS_SERVICE_GROUP_MANIPULATION | join(" ") }} --ignore {{ SYS_SERVICE_GROUP_CLEANUP | join(" ") }} --timeout "{{ SYS_TIMEOUT_BACKUP_SERVICES }}"'
|
||||
system_service_copy_files: true
|
||||
system_service_force_linear_sync: false
|
||||
|
||||
- include_tasks: utils/run_once.yml
|
||||
vars:
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
- include_role:
|
||||
name: sys-service
|
||||
vars:
|
||||
system_service_timer_enabled: true
|
||||
system_service_on_calendar: "{{ SYS_SCHEDULE_CLEANUP_CERTS }}"
|
||||
system_service_copy_files: false
|
||||
system_service_timer_enabled: true
|
||||
system_service_on_calendar: "{{ SYS_SCHEDULE_CLEANUP_CERTS }}"
|
||||
system_service_copy_files: false
|
||||
system_service_force_linear_sync: false
|
||||
@@ -14,3 +14,4 @@
|
||||
system_service_tpl_on_failure: "{{ SYS_SERVICE_ON_FAILURE_COMPOSE }}"
|
||||
system_service_tpl_exec_start: "{{ system_service_script_exec }} {{ SIZE_PERCENT_CLEANUP_DISC_SPACE }}"
|
||||
system_service_tpl_exec_start_pre: '/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ SYS_SERVICE_GROUP_MANIPULATION | join(" ") }} --ignore {{ SYS_SERVICE_GROUP_CLEANUP | join(" ") }} --timeout "{{ SYS_TIMEOUT_BACKUP_SERVICES }}"'
|
||||
system_service_force_linear_sync: false
|
||||
|
||||
@@ -21,5 +21,5 @@
|
||||
system_service_tpl_on_failure: "{{ SYS_SERVICE_ON_FAILURE_COMPOSE }}"
|
||||
system_service_tpl_exec_start_pre: '/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ SYS_SERVICE_GROUP_MANIPULATION | join(" ") }} --ignore {{ SYS_SERVICE_GROUP_CLEANUP| join(" ") }} --timeout "{{ SYS_TIMEOUT_CLEANUP_SERVICES }}"'
|
||||
system_service_tpl_exec_start: '/bin/sh -c "{{ CLEANUP_FAILED_BACKUPS_PKG }} --all --workers {{ CLEANUP_FAILED_BACKUPS_WORKERS }} --yes"'
|
||||
|
||||
system_service_force_linear_sync: false
|
||||
- include_tasks: utils/run_once.yml
|
||||
|
||||
@@ -14,6 +14,32 @@ Designed for Archlinux systems, this role periodically checks whether web resour
|
||||
- **Domain Extraction:** Parses all `.conf` files in the NGINX config folder to determine the list of domains to check.
|
||||
- **Automated Execution:** Registers a systemd service and timer for recurring health checks.
|
||||
- **Error Notification:** Integrates with `sys-ctl-alm-compose` for alerting on failure.
|
||||
- **Ignore List Support:** Optional variable to suppress network block reports from specific external domains.
|
||||
|
||||
## Configuration
|
||||
|
||||
### Variables
|
||||
|
||||
- **`HEALTH_CSP_IGNORE_NETWORK_BLOCKS_FROM`** (list, default: `[]`)
|
||||
Optional list of domains whose network block failures (e.g., ORB) should be ignored during CSP checks.
|
||||
|
||||
Example:
|
||||
|
||||
```yaml
|
||||
HEALTH_CSP_IGNORE_NETWORK_BLOCKS_FROM:
|
||||
- pxscdn.com
|
||||
- cdn.example.org
|
||||
```
|
||||
|
||||
This will run the CSP checker with:
|
||||
|
||||
```bash
|
||||
checkcsp start --short --ignore-network-blocks-from pxscdn.com -- cdn.example.org <domains...>
|
||||
```
|
||||
|
||||
### Systemd Integration
|
||||
|
||||
The role configures a systemd service and timer which executes the CSP crawler periodically against all NGINX domains.
|
||||
|
||||
## License
|
||||
|
||||
@@ -24,4 +50,4 @@ Infinito.Nexus NonCommercial License
|
||||
|
||||
Kevin Veen-Birkenbach
|
||||
Consulting & Coaching Solutions
|
||||
[https://www.veen.world](https://www.veen.world)
|
||||
[https://www.veen.world](https://www.veen.world)
|
||||
|
||||
5
roles/sys-ctl-hlth-csp/defaults/main.yml
Normal file
5
roles/sys-ctl-hlth-csp/defaults/main.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
# List of domains whose network block failures (e.g., ORB) should be ignored
|
||||
# during CSP checks. This is useful for suppressing known external resources
|
||||
# (e.g., third-party CDNs) that cannot be influenced but otherwise cause
|
||||
# unnecessary alerts in the crawler reports.
|
||||
HEALTH_CSP_IGNORE_NETWORK_BLOCKS_FROM: []
|
||||
@@ -21,11 +21,20 @@ def extract_domains(config_path):
|
||||
print(f"Directory {config_path} not found.", file=sys.stderr)
|
||||
return None
|
||||
|
||||
def run_checkcsp(domains):
|
||||
def run_checkcsp(domains, ignore_network_blocks_from):
|
||||
"""
|
||||
Executes the 'checkcsp' command with the given domains.
|
||||
Executes the 'checkcsp' command with the given domains and optional ignores.
|
||||
"""
|
||||
cmd = ["checkcsp", "start", "--short"] + domains
|
||||
cmd = ["checkcsp", "start", "--short"]
|
||||
|
||||
# pass through ignore list only if not empty
|
||||
if ignore_network_blocks_from:
|
||||
cmd.append("--ignore-network-blocks-from")
|
||||
cmd.extend(ignore_network_blocks_from)
|
||||
cmd.append("--")
|
||||
|
||||
cmd += domains
|
||||
|
||||
try:
|
||||
result = subprocess.run(cmd, check=True)
|
||||
return result.returncode
|
||||
@@ -45,6 +54,12 @@ def main():
|
||||
required=True,
|
||||
help="Directory containing NGINX .conf files"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--ignore-network-blocks-from",
|
||||
nargs="*",
|
||||
default=[],
|
||||
help="Optional: one or more domains whose network block failures should be ignored"
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
domains = extract_domains(args.nginx_config_dir)
|
||||
@@ -55,7 +70,7 @@ def main():
|
||||
print("No domains found to check.")
|
||||
sys.exit(0)
|
||||
|
||||
rc = run_checkcsp(domains)
|
||||
rc = run_checkcsp(domains, args.ignore_network_blocks_from)
|
||||
sys.exit(rc)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
system_service_timer_enabled: true
|
||||
system_service_tpl_on_failure: "{{ SYS_SERVICE_ON_FAILURE_COMPOSE }}"
|
||||
system_service_tpl_timeout_start_sec: "{{ CURRENT_PLAY_DOMAINS_ALL | timeout_start_sec_for_domains }}"
|
||||
system_service_tpl_exec_start: "{{ system_service_script_exec }} --nginx-config-dir={{ NGINX.DIRECTORIES.HTTP.SERVERS }}"
|
||||
system_service_tpl_exec_start: >-
|
||||
{{ system_service_script_exec }}
|
||||
--nginx-config-dir={{ NGINX.DIRECTORIES.HTTP.SERVERS }}
|
||||
--ignore-network-blocks-from {{ HEALTH_CSP_IGNORE_NETWORK_BLOCKS_FROM | join(' ') }}
|
||||
|
||||
- include_tasks: utils/run_once.yml
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# roles/sys-ctl-hlth-webserver/filter_plugins/web_health_expectations.py
|
||||
import os
|
||||
import sys
|
||||
from collections.abc import Mapping
|
||||
@@ -94,6 +93,26 @@ def _normalize_selection(group_names):
|
||||
raise ValueError("web_health_expectations: 'group_names' must be provided and non-empty")
|
||||
return sel
|
||||
|
||||
def _normalize_codes(x):
|
||||
"""
|
||||
Accepts:
|
||||
- single code (int or str)
|
||||
- list/tuple/set of codes
|
||||
Returns a de-duplicated list of valid ints (100..599) in original order.
|
||||
"""
|
||||
if x is None:
|
||||
return []
|
||||
if isinstance(x, (list, tuple, set)):
|
||||
out = []
|
||||
seen = set()
|
||||
for v in x:
|
||||
c = _valid_http_code(v)
|
||||
if c is not None and c not in seen:
|
||||
seen.add(c)
|
||||
out.append(c)
|
||||
return out
|
||||
c = _valid_http_code(x)
|
||||
return [c] if c is not None else []
|
||||
|
||||
def web_health_expectations(applications, www_enabled: bool = False, group_names=None, redirect_maps=None):
|
||||
"""Produce a **flat mapping**: domain -> [expected_status_codes].
|
||||
@@ -138,17 +157,15 @@ def web_health_expectations(applications, www_enabled: bool = False, group_names
|
||||
sc_map = {}
|
||||
if isinstance(sc_raw, Mapping):
|
||||
for k, v in sc_raw.items():
|
||||
code = _valid_http_code(v)
|
||||
if code is not None:
|
||||
sc_map[str(k)] = code
|
||||
codes = _normalize_codes(v)
|
||||
if codes:
|
||||
sc_map[str(k)] = codes
|
||||
|
||||
if isinstance(canonical_raw, Mapping) and canonical_raw:
|
||||
for key, domains in canonical_raw.items():
|
||||
domains_list = _to_list(domains, allow_mapping=False)
|
||||
code = _valid_http_code(sc_map.get(key))
|
||||
if code is None:
|
||||
code = _valid_http_code(sc_map.get("default"))
|
||||
expected = [code] if code is not None else list(DEFAULT_OK)
|
||||
codes = sc_map.get(key) or sc_map.get("default")
|
||||
expected = list(codes) if codes else list(DEFAULT_OK)
|
||||
for d in domains_list:
|
||||
if d:
|
||||
expectations[d] = expected
|
||||
@@ -156,8 +173,8 @@ def web_health_expectations(applications, www_enabled: bool = False, group_names
|
||||
for d in _to_list(canonical_raw, allow_mapping=True):
|
||||
if not d:
|
||||
continue
|
||||
code = _valid_http_code(sc_map.get("default"))
|
||||
expectations[d] = [code] if code is not None else list(DEFAULT_OK)
|
||||
codes = sc_map.get("default")
|
||||
expectations[d] = list(codes) if codes else list(DEFAULT_OK)
|
||||
|
||||
for d in aliases:
|
||||
if d:
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
- include_role:
|
||||
name: sys-service
|
||||
vars:
|
||||
system_service_state: restarted
|
||||
system_service_on_calendar: "{{ SYS_SCHEDULE_MAINTANANCE_LETSENCRYPT_DEPLOY }}"
|
||||
persistent: "true"
|
||||
system_service_timer_enabled: true
|
||||
system_service_tpl_on_failure: "{{ SYS_SERVICE_ON_FAILURE_COMPOSE }}"
|
||||
system_service_state: restarted
|
||||
system_service_on_calendar: "{{ SYS_SCHEDULE_MAINTANANCE_LETSENCRYPT_DEPLOY }}"
|
||||
persistent: "true"
|
||||
system_service_timer_enabled: true
|
||||
system_service_tpl_on_failure: "{{ SYS_SERVICE_ON_FAILURE_COMPOSE }}"
|
||||
system_service_force_linear_sync: false
|
||||
@@ -3,7 +3,7 @@
|
||||
name: '{{ item }}'
|
||||
loop:
|
||||
- sys-svc-certbot
|
||||
- sys-svc-webserver
|
||||
- sys-svc-webserver-core
|
||||
- sys-ctl-alm-compose
|
||||
|
||||
- name: install certbot
|
||||
@@ -15,8 +15,9 @@
|
||||
- include_role:
|
||||
name: sys-service
|
||||
vars:
|
||||
system_service_copy_files: false
|
||||
system_service_on_calendar: "{{ SYS_SCHEDULE_MAINTANANCE_LETSENCRYPT_RENEW }}"
|
||||
persistent: true
|
||||
system_service_timer_enabled: true
|
||||
system_service_tpl_on_failure: "{{ SYS_SERVICE_ON_FAILURE_COMPOSE }}"
|
||||
system_service_copy_files: false
|
||||
system_service_on_calendar: "{{ SYS_SCHEDULE_MAINTANANCE_LETSENCRYPT_RENEW }}"
|
||||
persistent: true
|
||||
system_service_timer_enabled: true
|
||||
system_service_tpl_on_failure: "{{ SYS_SERVICE_ON_FAILURE_COMPOSE }}"
|
||||
system_service_force_linear_sync: false
|
||||
|
||||
@@ -12,9 +12,10 @@
|
||||
- include_role:
|
||||
name: sys-service
|
||||
vars:
|
||||
system_service_suppress_flush: true # It takes a super long time - Better wait for failure of timed service instead of executing it on every play
|
||||
system_service_copy_files: false
|
||||
system_service_on_calendar: "{{ SYS_SCHEDULE_REPAIR_BTRFS_AUTO_BALANCER }}"
|
||||
system_service_timer_enabled: true
|
||||
system_service_tpl_on_failure: "{{ SYS_SERVICE_ON_FAILURE_COMPOSE }}"
|
||||
system_service_tpl_exec_start: "/bin/sh -c 'btrfs-auto-balancer 90 10'"
|
||||
system_service_suppress_flush: true # It takes a super long time - Better wait for failure of timed service instead of executing it on every play
|
||||
system_service_copy_files: false
|
||||
system_service_on_calendar: "{{ SYS_SCHEDULE_REPAIR_BTRFS_AUTO_BALANCER }}"
|
||||
system_service_timer_enabled: true
|
||||
system_service_tpl_on_failure: "{{ SYS_SERVICE_ON_FAILURE_COMPOSE }}"
|
||||
system_service_tpl_exec_start: "/bin/sh -c 'btrfs-auto-balancer 90 10'"
|
||||
system_service_force_linear_sync: true
|
||||
@@ -12,5 +12,6 @@
|
||||
system_service_tpl_exec_start: '{{ system_service_script_exec }} {{ PATH_DOCKER_COMPOSE_INSTANCES }}'
|
||||
system_service_tpl_exec_start_post: "/usr/bin/systemctl start {{ SYS_SERVICE_CLEANUP_ANONYMOUS_VOLUMES }}"
|
||||
system_service_tpl_on_failure: "{{ SYS_SERVICE_ON_FAILURE_COMPOSE }}"
|
||||
system_service_force_linear_sync: true
|
||||
|
||||
- include_tasks: utils/run_once.yml
|
||||
|
||||
@@ -10,5 +10,6 @@
|
||||
system_service_tpl_exec_start_pre: "/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ SYS_SERVICE_GROUP_MANIPULATION | join(' ') }} --ignore {{ SYS_SERVICE_GROUP_CLEANUP| join(' ') }} {{ SYS_SERVICE_REPAIR_DOCKER_SOFT }} --timeout '{{ SYS_TIMEOUT_DOCKER_RPR_SOFT }}'"
|
||||
system_service_tpl_exec_start: >
|
||||
/bin/sh -c '{{ system_service_script_exec }} --manipulation-string "{{ SYS_SERVICE_GROUP_MANIPULATION | join(" ") }}" {{ PATH_DOCKER_COMPOSE_INSTANCES }}'
|
||||
system_service_force_linear_sync: true
|
||||
|
||||
- include_tasks: utils/run_once.yml
|
||||
|
||||
@@ -41,9 +41,9 @@
|
||||
when: inj_enabled.logout
|
||||
|
||||
- block:
|
||||
- name: Include dependency 'sys-svc-webserver'
|
||||
- name: Include dependency 'sys-svc-webserver-core'
|
||||
include_role:
|
||||
name: sys-svc-webserver
|
||||
when: run_once_sys_svc_webserver is not defined
|
||||
name: sys-svc-webserver-core
|
||||
when: run_once_sys_svc_webserver_core is not defined
|
||||
- include_tasks: utils/run_once.yml
|
||||
when: run_once_sys_front_inj_all is not defined
|
||||
@@ -1,7 +1,7 @@
|
||||
- name: Include dependency 'sys-svc-webserver'
|
||||
- name: Include dependency 'sys-svc-webserver-core'
|
||||
include_role:
|
||||
name: sys-svc-webserver
|
||||
when: run_once_sys_svc_webserver is not defined
|
||||
name: sys-svc-webserver-core
|
||||
when: run_once_sys_svc_webserver_core is not defined
|
||||
|
||||
- name: Generate color palette with colorscheme-generator
|
||||
set_fact:
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
- block:
|
||||
- name: Include dependency 'sys-svc-webserver'
|
||||
- name: Include dependency 'sys-svc-webserver-core'
|
||||
include_role:
|
||||
name: sys-svc-webserver
|
||||
when: run_once_sys_svc_webserver is not defined
|
||||
name: sys-svc-webserver-core
|
||||
when: run_once_sys_svc_webserver_core is not defined
|
||||
- include_tasks: 01_deploy.yml
|
||||
- include_tasks: utils/run_once.yml
|
||||
when: run_once_sys_front_inj_desktop is not defined
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
- block:
|
||||
|
||||
- name: Include dependency 'sys-svc-webserver'
|
||||
- name: Include dependency 'sys-svc-webserver-core'
|
||||
include_role:
|
||||
name: sys-svc-webserver
|
||||
when: run_once_sys_svc_webserver is not defined
|
||||
name: sys-svc-webserver-core
|
||||
when: run_once_sys_svc_webserver_core is not defined
|
||||
- include_tasks: utils/run_once.yml
|
||||
when: run_once_sys_front_inj_javascript is not defined
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
- name: Include dependency 'sys-svc-webserver'
|
||||
- name: Include dependency 'sys-svc-webserver-core'
|
||||
include_role:
|
||||
name: sys-svc-webserver
|
||||
name: sys-svc-webserver-core
|
||||
when:
|
||||
- run_once_sys_svc_webserver is not defined
|
||||
- run_once_sys_svc_webserver_core is not defined
|
||||
|
||||
- name: "deploy the logout.js"
|
||||
include_tasks: "02_deploy.yml"
|
||||
@@ -1,8 +1,8 @@
|
||||
- block:
|
||||
- name: Include dependency 'sys-svc-webserver'
|
||||
- name: Include dependency 'sys-svc-webserver-core'
|
||||
include_role:
|
||||
name: sys-svc-webserver
|
||||
when: run_once_sys_svc_webserver is not defined
|
||||
name: sys-svc-webserver-core
|
||||
when: run_once_sys_svc_webserver_core is not defined
|
||||
- include_tasks: utils/run_once.yml
|
||||
when: run_once_sys_front_inj_matomo is not defined
|
||||
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
- name: "Enable systemctl service"
|
||||
systemd:
|
||||
name: "{{ system_service_id | get_service_name(SOFTWARE_NAME) }}"
|
||||
name: "{{ system_service_name }}"
|
||||
enabled: yes
|
||||
daemon_reload: true
|
||||
become: true
|
||||
async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}"
|
||||
poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}"
|
||||
async: "{{ system_service_async }}"
|
||||
poll: "{{ system_service_poll }}"
|
||||
listen: refresh systemctl service
|
||||
|
||||
- name: "Set systemctl service state"
|
||||
systemd:
|
||||
name: "{{ system_service_id | get_service_name(SOFTWARE_NAME) }}"
|
||||
name: "{{ system_service_name }}"
|
||||
state: "{{ system_service_state }}"
|
||||
become: true
|
||||
async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}"
|
||||
poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}"
|
||||
async: "{{ system_service_async }}"
|
||||
poll: "{{ system_service_poll }}"
|
||||
when: not (system_service_suppress_flush | bool)
|
||||
listen: refresh systemctl service
|
||||
@@ -31,7 +31,7 @@
|
||||
- name: "setup systemctl '{{ system_service_id }}'"
|
||||
template:
|
||||
src: "{{ system_service_template_src }}"
|
||||
dest: "{{ [ PATH_SYSTEM_SERVICE_DIR, system_service_id | get_service_name(SOFTWARE_NAME) ] | path_join }}"
|
||||
dest: "{{ [ PATH_SYSTEM_SERVICE_DIR, system_service_name ] | path_join }}"
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
@@ -46,5 +46,5 @@
|
||||
command: /bin/true
|
||||
notify: refresh systemctl service
|
||||
when: not system_service_uses_at
|
||||
when: system_force_flush | bool
|
||||
when: system_service_force_flush | bool
|
||||
|
||||
|
||||
@@ -1,22 +1,28 @@
|
||||
UNIT_SUFFIX_REMOVER_PACKAGE: "unsure"
|
||||
UNIT_SUFFIX_REMOVER_PACKAGE: "unsure"
|
||||
system_service_name: "{{ system_service_id | get_service_name(SOFTWARE_NAME) }}"
|
||||
|
||||
## Paths
|
||||
system_service_role_name: "{{ system_service_id | regex_replace('@','') }}"
|
||||
system_service_role_dir: "{{ [ playbook_dir, 'roles', system_service_role_name ] | path_join }}"
|
||||
system_service_script_dir: "{{ [ PATH_SYSTEMCTL_SCRIPTS, system_service_id ] | path_join }}"
|
||||
system_service_role_name: "{{ system_service_id | regex_replace('@','') }}"
|
||||
system_service_role_dir: "{{ [ playbook_dir, 'roles', system_service_role_name ] | path_join }}"
|
||||
system_service_script_dir: "{{ [ PATH_SYSTEMCTL_SCRIPTS, system_service_id ] | path_join }}"
|
||||
|
||||
## Settings
|
||||
system_force_flush: "{{ SYS_SERVICE_ALL_ENABLED | bool }}" # When set to true it activates the flushing of services. defaults to SYS_SERVICE_ALL_ENABLED
|
||||
system_service_suppress_flush: "{{ (system_service_id in SYS_SERVICE_SUPPRESS_FLUSH) | bool }}" # When set to true it suppresses the flushing of services
|
||||
system_service_copy_files: true # When set to false file copying will be skipped
|
||||
system_service_timer_enabled: false # When set to true timer will be loaded
|
||||
system_service_state: "{{ SYS_SERVICE_DEFAULT_STATE }}"
|
||||
system_service_force_linear_sync: "{{ system_service_name in SYS_SERVICE_GROUP_MANIPULATION }}" # Disables automatic async
|
||||
system_service_force_flush: "{{ SYS_SERVICE_ALL_ENABLED | bool }}" # When set to true it activates the flushing of services. defaults to SYS_SERVICE_ALL_ENABLED
|
||||
system_service_suppress_flush: "{{ (system_service_id in SYS_SERVICE_SUPPRESS_FLUSH) | bool }}" # When set to true it suppresses the flushing of services
|
||||
system_service_copy_files: true # When set to false file copying will be skipped
|
||||
system_service_timer_enabled: false # When set to true timer will be loaded
|
||||
system_service_state: "{{ SYS_SERVICE_DEFAULT_STATE }}"
|
||||
|
||||
## ASYNC Settings
|
||||
system_service_async: "{{ omit if (system_service_force_linear_sync | bool or not ASYNC_ENABLED | bool) else ASYNC_TIME }}"
|
||||
system_service_poll: "{{ omit if (system_service_force_linear_sync | bool or not ASYNC_ENABLED | bool) else ASYNC_POLL }}"
|
||||
|
||||
# Dynamic Loaded ( Just available when dependencies are loaded )
|
||||
system_service_script_base: "{{ system_service_script_src | basename | regex_replace('\\.j2$', '') }}"
|
||||
system_service_script_type: "{{ system_service_script_base | filetype }}"
|
||||
system_service_script_inter: "/bin/{{ 'bash' if system_service_script_type == 'sh' else 'python3'}}"
|
||||
system_service_script_exec: "{{ system_service_script_inter }} {{ system_service_id | get_service_script_path( system_service_script_type ) }}"
|
||||
system_service_script_base: "{{ system_service_script_src | basename | regex_replace('\\.j2$', '') }}"
|
||||
system_service_script_type: "{{ system_service_script_base | filetype }}"
|
||||
system_service_script_inter: "/bin/{{ 'bash' if system_service_script_type == 'sh' else 'python3'}}"
|
||||
system_service_script_exec: "{{ system_service_script_inter }} {{ system_service_id | get_service_script_path( system_service_script_type ) }}"
|
||||
|
||||
# Service template
|
||||
system_service_tpl_on_failure: "{{ SYS_SERVICE_ON_FAILURE_COMPOSE }}"
|
||||
|
||||
21
roles/sys-stk-front-base/README.md
Normal file
21
roles/sys-stk-front-base/README.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# Front Base (HTTPS + Cloudflare + Handlers) 🚀
|
||||
|
||||
## Description
|
||||
**sys-stk-front-base** bootstraps the front layer that most web-facing apps need:
|
||||
- Ensures the HTTPS base via `sys-svc-webserver-https`
|
||||
- (Optional) Cloudflare bootstrap (zone lookup, dev mode, purge)
|
||||
- Wires OpenResty/Nginx handlers
|
||||
- Leaves per-domain certificate issuance to consumer roles (or pass-through vars to `sys-util-csp-cert` if needed)
|
||||
|
||||
> This role is intentionally small and reusable. It prepares the ground so app roles can just render their vHost.
|
||||
|
||||
## Responsibilities
|
||||
- Include `sys-svc-webserver-https` (once per host)
|
||||
- Include Cloudflare tasks when `DNS_PROVIDER == "cloudflare"`
|
||||
- Load handler utilities (e.g., `svc-prx-openresty`)
|
||||
- Stay domain-agnostic: expect `domain` to be provided by the consumer
|
||||
|
||||
## Outputs
|
||||
- Handler wiring completed
|
||||
- HTTPS base ready (Nginx, ACME webroot)
|
||||
- Cloudflare prepared (optional)
|
||||
@@ -1,6 +1,6 @@
|
||||
galaxy_info:
|
||||
author: "Kevin Veen-Birkenbach"
|
||||
description: "Updates AUR packages on Arch Linux systems using yay. This role automates the upgrade process for AUR packages, ensuring that the system remains up-to-date with the latest versions available in the Arch User Repository."
|
||||
description: "Front bootstrap for web apps: HTTPS base, optional Cloudflare setup, and handler wiring."
|
||||
license: "Infinito.Nexus NonCommercial License"
|
||||
license_url: "https://s.infinito.nexus/license"
|
||||
company: |
|
||||
@@ -9,16 +9,16 @@ galaxy_info:
|
||||
https://www.veen.world
|
||||
min_ansible_version: "2.9"
|
||||
platforms:
|
||||
- name: Archlinux
|
||||
versions:
|
||||
- rolling
|
||||
- name: Archlinux
|
||||
versions:
|
||||
- rolling
|
||||
galaxy_tags:
|
||||
- aur
|
||||
- update
|
||||
- archlinux
|
||||
- yay
|
||||
- system
|
||||
- maintenance
|
||||
- nginx
|
||||
- https
|
||||
- cloudflare
|
||||
- automation
|
||||
- web
|
||||
repository: "https://s.infinito.nexus/code"
|
||||
issue_tracker_url: "https://s.infinito.nexus/issues"
|
||||
documentation: "https://docs.infinito.nexus"
|
||||
documentation: "https://docs.infinito.nexus/"
|
||||
dependencies: []
|
||||
14
roles/sys-stk-front-base/tasks/main.yml
Normal file
14
roles/sys-stk-front-base/tasks/main.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
- block:
|
||||
- name: Include dependency 'sys-svc-webserver-https'
|
||||
include_role:
|
||||
name: sys-svc-webserver-https
|
||||
when: run_once_sys_svc_webserver_https is not defined
|
||||
- include_tasks: utils/run_once.yml
|
||||
when: run_once_sys_stk_front_base is not defined
|
||||
|
||||
- include_tasks: "01_cloudflare.yml"
|
||||
when: DNS_PROVIDER == "cloudflare"
|
||||
|
||||
- include_tasks: "{{ [ playbook_dir, 'tasks/utils/load_handlers.yml' ] | path_join }}"
|
||||
vars:
|
||||
handler_role_name: "svc-prx-openresty"
|
||||
@@ -1,8 +1,5 @@
|
||||
# default vhost flavour
|
||||
vhost_flavour: "basic" # valid: basic, ws_generic
|
||||
|
||||
# build the full template path from the flavour
|
||||
vhost_template_src: "roles/sys-svc-proxy/templates/vhost/{{ vhost_flavour }}.conf.j2"
|
||||
vhost_flavour: "basic" # valid: basic, ws_generic
|
||||
|
||||
# Enable / Disable Proxy during development, for faster Debugging
|
||||
SYS_STK_FRONT_PROXY_ENABLED: true
|
||||
@@ -1,26 +1,15 @@
|
||||
- block:
|
||||
- name: Include dependency 'sys-svc-proxy'
|
||||
include_role:
|
||||
name: sys-svc-proxy
|
||||
when: run_once_sys_svc_proxy is not defined
|
||||
- include_tasks: utils/run_once.yml
|
||||
when: run_once_sys_stk_front_proxy is not defined
|
||||
- name: Front bootstrap
|
||||
include_role:
|
||||
name: sys-stk-front-base
|
||||
|
||||
- include_tasks: "02_cloudflare.yml"
|
||||
when: DNS_PROVIDER == "cloudflare"
|
||||
|
||||
- include_tasks: "{{ [ playbook_dir, 'tasks/utils/load_handlers.yml' ] | path_join }}"
|
||||
vars:
|
||||
handler_role_name: "svc-prx-openresty"
|
||||
|
||||
- name: "include role for {{ domain }} to receive certificates and do the modification routines"
|
||||
- name: "include role for '{{ domain }}' to receive certificates and do the modification routines"
|
||||
include_role:
|
||||
name: sys-util-csp-cert
|
||||
|
||||
- name: "Copy nginx config to {{ configuration_destination }}"
|
||||
- name: "Copy nginx config to '{{ front_proxy_domain_conf_dst }}'"
|
||||
template:
|
||||
src: "{{ vhost_template_src }}"
|
||||
dest: "{{ configuration_destination }}"
|
||||
src: "{{ front_proxy_domain_conf_src }}"
|
||||
dest: "{{ front_proxy_domain_conf_dst }}"
|
||||
register: nginx_conf
|
||||
notify: restart openresty
|
||||
|
||||
@@ -39,4 +28,7 @@
|
||||
when:
|
||||
- site_check.status is defined
|
||||
- not site_check.status in [200,301,302]
|
||||
when: not nginx_conf.changed
|
||||
when: not nginx_conf.changed
|
||||
|
||||
- name: "Restart Webserver for '{{ front_proxy_domain_conf_dst }}'"
|
||||
meta: flush_handlers
|
||||
@@ -1 +1,2 @@
|
||||
configuration_destination: "{{ [ NGINX.DIRECTORIES.HTTP.SERVERS, domain ~ '.conf'] | path_join }}"
|
||||
front_proxy_domain_conf_dst: "{{ [ NGINX.DIRECTORIES.HTTP.SERVERS, domain ~ '.conf'] | path_join }}"
|
||||
front_proxy_domain_conf_src: "roles/sys-svc-proxy/templates/vhost/{{ vhost_flavour }}.conf.j2"
|
||||
|
||||
13
roles/sys-stk-semi-stateless/README.md
Normal file
13
roles/sys-stk-semi-stateless/README.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Semi-Stateless Stack (Front + Back) ⚡
|
||||
|
||||
## Description
|
||||
**sys-stk-semi-stateless** combines the front and back layer into a lightweight, mostly stateless web service stack:
|
||||
- Front bootstrap via `sys-stk-front-base` (HTTPS base, optional Cloudflare, handlers)
|
||||
- Backend via `sys-stk-back-stateless` (no persistent volumes/DB)
|
||||
|
||||
Ideal for services that need TLS/front glue but no database (e.g., TURN/STUN, gateways, simple APIs).
|
||||
|
||||
## Responsibilities
|
||||
- Prepare the front layer (HTTPS / handlers / optional Cloudflare)
|
||||
- Deploy the stateless backend (typically via Docker Compose)
|
||||
- Keep domain variables (`domain`) and app-scoped variables (`application_id`) clearly separated
|
||||
24
roles/sys-stk-semi-stateless/meta/main.yml
Normal file
24
roles/sys-stk-semi-stateless/meta/main.yml
Normal file
@@ -0,0 +1,24 @@
|
||||
galaxy_info:
|
||||
author: "Kevin Veen-Birkenbach"
|
||||
description: "Combined semi-stateless app stack: front bootstrap + stateless backend."
|
||||
license: "Infinito.Nexus NonCommercial License"
|
||||
license_url: "https://s.infinito.nexus/license"
|
||||
company: |
|
||||
Kevin Veen-Birkenbach
|
||||
Consulting & Coaching Solutions
|
||||
https://www.veen.world
|
||||
min_ansible_version: "2.9"
|
||||
platforms:
|
||||
- name: Archlinux
|
||||
versions:
|
||||
- rolling
|
||||
galaxy_tags:
|
||||
- nginx
|
||||
- https
|
||||
- stateless
|
||||
- backend
|
||||
- cloudflare
|
||||
- automation
|
||||
repository: "https://s.infinito.nexus/code"
|
||||
issue_tracker_url: "https://s.infinito.nexus/issues"
|
||||
documentation: "https://docs.infinito.nexus/"
|
||||
11
roles/sys-stk-semi-stateless/tasks/main.yml
Normal file
11
roles/sys-stk-semi-stateless/tasks/main.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
# run_once_sys_stk_semi_stateless: deactivated
|
||||
|
||||
- name: "sys-stk-front-base"
|
||||
include_role:
|
||||
name: sys-stk-front-base
|
||||
vars:
|
||||
domain: "{{ domains | get_domain(application_id) }}"
|
||||
|
||||
- name: "For '{{ application_id }}': Load sys-stk-back-stateless"
|
||||
include_role:
|
||||
name: sys-stk-back-stateless
|
||||
@@ -1,8 +1,8 @@
|
||||
- block:
|
||||
- name: Include dependency 'sys-stk-front-pure'
|
||||
- name: Include dependency 'sys-svc-webserver-https'
|
||||
include_role:
|
||||
name: sys-stk-front-pure
|
||||
when: run_once_sys_stk_front_pure is not defined
|
||||
name: sys-svc-webserver-https
|
||||
when: run_once_sys_svc_webserver_https is not defined
|
||||
- include_tasks: utils/run_once.yml
|
||||
when: run_once_sys_svc_certs is not defined
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
include_role:
|
||||
name: '{{ item }}'
|
||||
loop:
|
||||
- sys-svc-webserver
|
||||
- sys-svc-webserver-core
|
||||
|
||||
- name: Include task to remove deprecated nginx configs
|
||||
include_tasks: remove_deprecated_nginx_configs.yml
|
||||
|
||||
@@ -6,6 +6,12 @@
|
||||
state: present
|
||||
notify: docker restart
|
||||
|
||||
- name: Setup Swapfile to prevent OOM Failures
|
||||
# @ See https://en.wikipedia.org/wiki/Out_of_memory
|
||||
include_role:
|
||||
name: "svc-opt-swapfile"
|
||||
when: run_once_svc_opt_swapfile is not defined
|
||||
|
||||
- name: "Load reset tasks when MODE_RESET is enabled"
|
||||
include_tasks: "02_reset.yml"
|
||||
when: MODE_RESET | bool
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
include_role:
|
||||
name: sys-ctl-cln-anon-volumes
|
||||
vars:
|
||||
system_force_flush: true
|
||||
system_service_force_flush: true
|
||||
- include_tasks: utils/run_once.yml
|
||||
when: run_once_sys_ctl_cln_anon_volumes is not defined
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ The goal of this role is to deliver a **hassle-free, production-ready reverse pr
|
||||
|
||||
## Features
|
||||
|
||||
- **Automatic TLS & HSTS** — integrates with the *sys-stk-front-pure* role for certificate management.
|
||||
- **Automatic TLS & HSTS** — integrates with the *sys-svc-webserver-https* role for certificate management.
|
||||
- **Flexible vHost templates** — *basic* and *ws_generic* flavours cover standard HTTP and WebSocket applications.
|
||||
- **Security headers** — sensible defaults plus optional X-Frame-Options / CSP based on application settings.
|
||||
- **WebSocket & HTTP/2 aware** — upgrades, keep-alive tuning, and gzip already configured.
|
||||
|
||||
@@ -2,3 +2,4 @@
|
||||
- Optimize buffering
|
||||
- Optimize caching
|
||||
- Make 'proxy_hide_header Content-Security-Policy' optional by using more_header option. See [ChatGPT Conversation](https://chatgpt.com/share/6825cb39-8db8-800f-8886-0cebdfad575a)
|
||||
- Refactor this role - It seems like it's just an wrapper for 'sys-svc-webserver-https' which doesn't add any additional logic
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
- block:
|
||||
- name: Include dependencies
|
||||
include_role:
|
||||
name: '{{ item }}'
|
||||
loop:
|
||||
- sys-stk-front-pure
|
||||
- sys-svc-webserver
|
||||
- include_tasks: utils/run_once.yml
|
||||
when: run_once_sys_svc_proxy is not defined
|
||||
@@ -0,0 +1,23 @@
|
||||
{# Configure CORS headers dynamically based on role variables.
|
||||
If no variable is defined, defaults are applied (e.g. same-origin).
|
||||
Discussion: https://chat.openai.com/share/2671b961-c1b0-472d-bae2-2804d0455e8a #}
|
||||
|
||||
{# Access-Control-Allow-Origin #}
|
||||
{% if aca_origin is defined %}
|
||||
add_header 'Access-Control-Allow-Origin' {{ aca_origin }};
|
||||
{% endif %}
|
||||
|
||||
{# Access-Control-Allow-Credentials #}
|
||||
{% if aca_credentials is defined %}
|
||||
add_header 'Access-Control-Allow-Credentials' {{ aca_credentials }};
|
||||
{% endif %}
|
||||
|
||||
{# Access-Control-Allow-Methods #}
|
||||
{% if aca_methods is defined %}
|
||||
add_header 'Access-Control-Allow-Methods' {{ aca_methods }};
|
||||
{% endif %}
|
||||
|
||||
{# Access-Control-Allow-Headers #}
|
||||
{% if aca_headers is defined %}
|
||||
add_header 'Access-Control-Allow-Headers' {{ aca_headers }};
|
||||
{% endif %}
|
||||
@@ -19,6 +19,8 @@ location {{location}}
|
||||
|
||||
{% include 'roles/sys-svc-proxy/templates/headers/content_security_policy.conf.j2' %}
|
||||
|
||||
{% include 'roles/sys-svc-proxy/templates/headers/access_control_allow.conf.j2' %}
|
||||
|
||||
# WebSocket specific header
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
location {{ location_ws }} {
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_pass http://127.0.0.1:{{ ws_port }};
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_pass http://127.0.0.1:{{ ws_port }};
|
||||
|
||||
# Proxy buffering needs to be disabled for websockets.
|
||||
proxy_buffering off;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
tcp_nodelay on;
|
||||
}
|
||||
@@ -58,5 +58,3 @@ server
|
||||
{% endif %}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' close;
|
||||
}
|
||||
|
||||
server {
|
||||
server_name {{ domain }};
|
||||
|
||||
|
||||
@@ -18,4 +18,4 @@ galaxy_info:
|
||||
- performance
|
||||
repository: "https://s.infinito.nexus/code"
|
||||
issue_tracker_url: "https://s.infinito.nexus/issues"
|
||||
documentation: "https://s.infinito.nexus/code/roles/sys-svc-webserver"
|
||||
documentation: "https://s.infinito.nexus/code/roles/sys-svc-webserver-core"
|
||||
@@ -11,10 +11,13 @@
|
||||
- name: "Load variables from {{ DOCKER_VARS_FILE }} for {{ role_name }}/{{ application_id }}"
|
||||
include_vars: "{{ DOCKER_VARS_FILE }}"
|
||||
|
||||
- name: "Load docker compose handlers"
|
||||
- name: "Load docker compose & openresty handlers"
|
||||
include_tasks: "{{ [ playbook_dir, 'tasks/utils/load_handlers.yml' ] | path_join }}"
|
||||
vars:
|
||||
handler_role_name: "docker-compose"
|
||||
loop:
|
||||
- docker-compose
|
||||
- svc-prx-openresty
|
||||
loop_control:
|
||||
loop_var: handler_role_name
|
||||
|
||||
- name: "Include tasks to create directories"
|
||||
include_tasks: 04_directories.yml
|
||||
@@ -23,7 +26,7 @@
|
||||
template:
|
||||
src: nginx.conf.j2
|
||||
dest: "{{ NGINX.FILES.CONFIGURATION }}"
|
||||
notify: docker compose up
|
||||
notify: restart openresty
|
||||
|
||||
- name: Include openresty
|
||||
# Outside of run_once block is necessary for handler loading
|
||||
4
roles/sys-svc-webserver-core/tasks/main.yml
Normal file
4
roles/sys-svc-webserver-core/tasks/main.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
- block:
|
||||
- include_tasks: 01_core.yml
|
||||
when: run_once_sys_svc_webserver_core is not defined
|
||||
@@ -7,12 +7,26 @@ events
|
||||
|
||||
http
|
||||
{
|
||||
{#
|
||||
Map the client's Upgrade header to the proper Connection value for WebSocket proxying:
|
||||
use "upgrade" when an Upgrade is requested, otherwise "close". Define once in http{} and use $connection_upgrade.
|
||||
#}
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' close;
|
||||
}
|
||||
|
||||
include mime.types;
|
||||
|
||||
{# default_type application/octet-stream; If html filter does not work, this one needs to be used#}
|
||||
|
||||
default_type text/html;
|
||||
|
||||
{# Ensure caches (browsers, proxies, CDNs) treat responses as dependent on the Origin header
|
||||
to prevent cross-domain cache poisoning issues.
|
||||
Discussion: https://chat.openai.com/share/2671b961-c1b0-472d-bae2-2804d0455e8a #}
|
||||
add_header 'Vary' 'Origin' always;
|
||||
|
||||
{# caching #}
|
||||
proxy_cache_path {{ NGINX.DIRECTORIES.CACHE.GENERAL }} levels=1:2 keys_zone=cache:20m max_size=20g inactive=14d use_temp_path=off;
|
||||
proxy_cache_path {{ NGINX.DIRECTORIES.CACHE.IMAGE }} levels=1:2 keys_zone=imgcache:10m inactive=60m use_temp_path=off;
|
||||
@@ -1,21 +1,21 @@
|
||||
# Webserver HTTPS Provisioning 🚀
|
||||
|
||||
## Description
|
||||
The **sys-stk-front-pure** role extends a basic Nginx installation by wiring in everything you need to serve content over HTTPS:
|
||||
The **sys-svc-webserver-https** role extends a basic Nginx installation by wiring in everything you need to serve content over HTTPS:
|
||||
|
||||
1. Ensures your Nginx server is configured for SSL/TLS.
|
||||
2. Pulls in Let’s Encrypt ACME challenge handling.
|
||||
3. Applies global cleanup of unused domain configs.
|
||||
|
||||
This role is built on top of your existing `sys-svc-webserver` role, and it automates the end-to-end process of turning HTTP sites into secure HTTPS sites.
|
||||
This role is built on top of your existing `sys-svc-webserver-core` role, and it automates the end-to-end process of turning HTTP sites into secure HTTPS sites.
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
When you apply **sys-stk-front-pure**, it will:
|
||||
When you apply **sys-svc-webserver-https**, it will:
|
||||
|
||||
1. **Include** the `sys-svc-webserver` role to install and configure Nginx.
|
||||
1. **Include** the `sys-svc-webserver-core` role to install and configure Nginx.
|
||||
2. **Clean up** any stale vHost files under `sys-svc-cln-domains`.
|
||||
3. **Deploy** the Let’s Encrypt challenge-and-redirect snippet from `sys-svc-letsencrypt`.
|
||||
4. **Reload** Nginx automatically when any template changes.
|
||||
@@ -40,17 +40,6 @@ All tasks are idempotent—once your certificates are in place and your configur
|
||||
|
||||
---
|
||||
|
||||
## Requirements
|
||||
|
||||
- A working `sys-svc-webserver` setup.
|
||||
- DNS managed via Cloudflare (for CAA record tasks) or equivalent ACME DNS flow.
|
||||
- Variables:
|
||||
- `LETSENCRYPT_WEBROOT_PATH`
|
||||
- `LETSENCRYPT_LIVE_PATH`
|
||||
- `on_calendar_renew_lets_encrypt_certificates`
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
This role is released under the **Infinito.Nexus NonCommercial License**.
|
||||
@@ -3,9 +3,9 @@
|
||||
include_role:
|
||||
name: '{{ item }}'
|
||||
loop:
|
||||
- sys-svc-webserver
|
||||
- sys-svc-webserver-core
|
||||
- sys-svc-cln-domains
|
||||
- sys-svc-letsencrypt
|
||||
- sys-svc-dns
|
||||
- include_tasks: utils/run_once.yml
|
||||
when: run_once_sys_stk_front_pure is not defined
|
||||
when: run_once_sys_svc_webserver_https is not defined
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
- block:
|
||||
- include_tasks: 01_core.yml
|
||||
when: run_once_sys_svc_webserver is not defined
|
||||
@@ -1,4 +1,4 @@
|
||||
# Role: sys-util-csp-cert
|
||||
# sys-util-csp-cert
|
||||
|
||||
This Ansible role composes and orchestrates all necessary HTTPS-layer tasks and HTML-content injections for your webserver domains. It integrates two key sub-roles into a unified workflow:
|
||||
|
||||
|
||||
@@ -13,22 +13,3 @@
|
||||
include_role:
|
||||
name: update-apt
|
||||
when: ansible_distribution == "Debian"
|
||||
|
||||
- name: "Check if yay is installed"
|
||||
command: which yay
|
||||
register: yay_installed
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
||||
- name: "Update with yay"
|
||||
include_role:
|
||||
name: update-yay
|
||||
when:
|
||||
- yay_installed.rc == 0
|
||||
- run_once_update_yay is not defined
|
||||
|
||||
- name: "Check if pkgmgr command is available"
|
||||
command: "which pkgmgr"
|
||||
register: pkgmgr_available
|
||||
failed_when: false
|
||||
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
# Update yay
|
||||
|
||||
## Description
|
||||
|
||||
This role updates AUR packages on Arch Linux systems using [yay](https://wiki.archlinux.org/title/Yay). It automates the process of upgrading AUR packages, ensuring that your system stays current with the latest software available in the Arch User Repository.
|
||||
|
||||
## Overview
|
||||
|
||||
The role performs the following:
|
||||
- Checks if the [yay](https://wiki.archlinux.org/title/Yay) AUR helper is installed.
|
||||
- Upgrades AUR packages using the `kewlfft.aur.aur` module with yay.
|
||||
- Works exclusively on Arch Linux systems.
|
||||
|
||||
## Purpose
|
||||
|
||||
The primary purpose of this role is to ensure that AUR packages on Arch Linux are updated automatically. This helps maintain system stability and ensures that the latest features and fixes from the AUR are applied.
|
||||
|
||||
## Features
|
||||
|
||||
- **AUR Package Upgrades:** Uses yay to upgrade AUR packages.
|
||||
- **Conditional Execution:** Only runs if yay is installed on the system.
|
||||
- **Arch Linux Focused:** Specifically designed for Arch Linux systems.
|
||||
@@ -1,14 +0,0 @@
|
||||
- block:
|
||||
- name: Include dependency 'dev-yay'
|
||||
include_role:
|
||||
name: dev-yay
|
||||
when: run_once_dev_yay is not defined
|
||||
|
||||
- name: upgrade the system using yay, only act on AUR packages.
|
||||
become: false
|
||||
kewlfft.aur.aur:
|
||||
upgrade: yes
|
||||
use: yay
|
||||
aur_only: yes
|
||||
- include_tasks: utils/run_once.yml
|
||||
when: run_once_update_yay is not defined
|
||||
@@ -1 +0,0 @@
|
||||
application_id: update-yay
|
||||
@@ -17,6 +17,10 @@ docker:
|
||||
image: "baserow/baserow"
|
||||
version: "latest"
|
||||
name: "baserow"
|
||||
cpus: 1.0
|
||||
mem_reservation: 0.5g
|
||||
mem_limit: 1g
|
||||
pids_limit: 512
|
||||
volumes:
|
||||
data: "baserow_data"
|
||||
server:
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
# Setup
|
||||
|
||||
## Passwords
|
||||
```bash
|
||||
docker run --rm ruby:latest ruby -rsecurerandom -e 'puts SecureRandom.hex(64)'
|
||||
```
|
||||
@@ -1,3 +1,3 @@
|
||||
# Todo
|
||||
- Propper implement and test the LDAP integration, the configuration values just had been set during refactoring
|
||||
- Move this whole overcomplicated handlers to the copying of a docker-compose.yml file. This is just legacy stuff
|
||||
- Implement that BBB can be opened in web-app-desktop app
|
||||
@@ -1,15 +1,14 @@
|
||||
enable_greenlight: "true"
|
||||
api_suffix: "/bigbluebutton/"
|
||||
api_suffix: "/bigbluebutton/"
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
desktop: false # Videos can't open in frame due to iframe restrictions
|
||||
# @todo fix this
|
||||
ldap: false
|
||||
oidc: true
|
||||
central_database: false # Propably required for backup routines
|
||||
logout: true
|
||||
matomo: true
|
||||
css: true
|
||||
desktop: false # Videos can't open in frame due to iframe restrictions
|
||||
ldap: false
|
||||
oidc: true
|
||||
central_database: false # Propably required for backup routines
|
||||
logout: true
|
||||
server:
|
||||
ip6_enabled: false
|
||||
csp:
|
||||
flags:
|
||||
script-src-elem:
|
||||
@@ -25,8 +24,18 @@ credentials: {}
|
||||
docker:
|
||||
services:
|
||||
bigbluebutton:
|
||||
repository: "https://github.com/bigbluebutton/docker.git"
|
||||
version: "main"
|
||||
repository: "https://github.com/kevinveenbirkenbach/bigbluebutton-docker.git"
|
||||
version: "bbb3.0"
|
||||
recording:
|
||||
enabled: false # Enable recordings of sessions (deactivated by default because it crashed, also check GDPR comnpliance)
|
||||
cleanup: true # Auto-Cleanup Recordings
|
||||
max_age_days: 30 # Cleanup recording after this amount of days
|
||||
database:
|
||||
# This is set to true to pass integration test, doesn't have any other function
|
||||
enabled: true
|
||||
enabled: true
|
||||
greenlight:
|
||||
enabled: true
|
||||
coturn:
|
||||
internal: false
|
||||
collabora:
|
||||
internal: false
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
credentials:
|
||||
shared_secret:
|
||||
description: "Shared secret for BigBlueButton API authentication"
|
||||
algorithm: "sha256"
|
||||
validation: "^[a-f0-9]{64}$"
|
||||
description: "Shared secret for BigBlueButton API authentication"
|
||||
algorithm: "sha256"
|
||||
validation: "^[a-f0-9]{64}$"
|
||||
etherpad_api_key:
|
||||
description: "API key for Etherpad integration"
|
||||
algorithm: "plain"
|
||||
validation: "^[a-zA-Z0-9]{32}$"
|
||||
description: "API key for Etherpad integration"
|
||||
algorithm: "random_hex_32"
|
||||
validation: "^[a-zA-Z0-9]{32}$"
|
||||
rails_secret:
|
||||
description: "Secret key for Rails backend"
|
||||
algorithm: "random_hex"
|
||||
validation: "^[a-f0-9]{128}$"
|
||||
description: "Secret key for Rails backend"
|
||||
algorithm: "random_hex"
|
||||
validation: "^[a-f0-9]{128}$"
|
||||
postgresql_secret:
|
||||
description: "Password for PostgreSQL user"
|
||||
algorithm: "bcrypt"
|
||||
validation: "^\\$2[aby]\\$.{56}$"
|
||||
description: "Password for PostgreSQL user"
|
||||
algorithm: "random_hex_32"
|
||||
validation: "^[a-zA-Z0-9]{32}$"
|
||||
fsesl_password:
|
||||
description: "Password for FreeSWITCH ESL connection"
|
||||
algorithm: "plain"
|
||||
validation: "^.{8,}$"
|
||||
description: "Password for FreeSWITCH ESL connection"
|
||||
algorithm: "random_hex"
|
||||
validation: "^.{8,}$"
|
||||
turn_secret:
|
||||
description: "TURN server shared secret"
|
||||
algorithm: "sha1"
|
||||
validation: "^[a-f0-9]{40}$"
|
||||
description: "TURN server shared secret"
|
||||
algorithm: "sha1"
|
||||
validation: "^[a-f0-9]{40}$"
|
||||
@@ -8,12 +8,12 @@
|
||||
|
||||
- name: Slurp docker-compose.yml from remote host
|
||||
slurp:
|
||||
src: "{{ docker_compose_file_origine }}"
|
||||
src: "{{ BBB_DOCKER_COMPOSE_FILE_ORIGINE }}"
|
||||
register: compose_slurp
|
||||
|
||||
- name: Transform docker-compose.yml with compose_mods
|
||||
copy:
|
||||
content: "{{ compose_slurp.content | b64decode | compose_mods(docker_repository_path, docker_compose.files.env) }}"
|
||||
dest: "{{ docker_compose_file_final }}"
|
||||
dest: "{{ BBB_DOCKER_COMPOSE_FILE_FINAL }}"
|
||||
notify:
|
||||
- docker compose up
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
---
|
||||
- name: "Wait until Greenlight is reachable via Nginx"
|
||||
uri:
|
||||
url: "{{ domains | get_url(application_id, WEB_PROTOCOL) }}"
|
||||
@@ -13,19 +14,35 @@
|
||||
changed_when: false
|
||||
|
||||
- block:
|
||||
- name: "Create default admin"
|
||||
- name: "Create admin with primary password"
|
||||
command:
|
||||
cmd: >
|
||||
docker compose exec greenlight
|
||||
bundle exec rake admin:create['{{ users.administrator.username | upper }}','{{ users.administrator.email }}','{{ users.administrator.password }}']
|
||||
{{ docker_compose_command_exec }}
|
||||
greenlight
|
||||
bundle exec rake
|
||||
admin:create['{{ users.administrator.username | upper }}','{{ users.administrator.email }}','{{ users.administrator.password }}']
|
||||
chdir: "{{ docker_compose.directories.instance }}"
|
||||
register: admin_creation_result
|
||||
# Treat exit codes 0 (created) and 2 (already exists) as success
|
||||
failed_when: admin_creation_result.rc not in [0,2]
|
||||
rescue:
|
||||
- name: "Make existing user administrator"
|
||||
register: admin_create_primary
|
||||
when: not BBB_OIDC_ENABLED | bool
|
||||
|
||||
- name: "Retry with starred password when invalid and OIDC enabled"
|
||||
when: BBB_OIDC_ENABLED | bool
|
||||
command:
|
||||
cmd: >
|
||||
docker compose exec greenlight
|
||||
bundle exec rake user:set_admin_role['{{ users.administrator.email }}']
|
||||
chdir: "{{ docker_compose.directories.instance }}"
|
||||
{{ docker_compose_command_exec }}
|
||||
greenlight
|
||||
bundle exec rake
|
||||
admin:create['{{ users.administrator.username | upper }}','{{ users.administrator.email }}','{{ users.administrator.password ~ '*' }}']
|
||||
chdir: "{{ docker_compose.directories.instance }}"
|
||||
register: admin_create_retry
|
||||
failed_when: admin_create_retry.rc not in [0, 2]
|
||||
|
||||
rescue:
|
||||
- name: "Make existing user administrator (fallback)"
|
||||
command:
|
||||
cmd: >
|
||||
{{ docker_compose_command_exec }}
|
||||
greenlight
|
||||
bundle exec rake
|
||||
user:set_admin_role['{{ users.administrator.email }}']
|
||||
chdir: "{{ docker_compose.directories.instance }}"
|
||||
|
||||
17
roles/web-app-bigbluebutton/tasks/03_dependencies.yml
Normal file
17
roles/web-app-bigbluebutton/tasks/03_dependencies.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
- name: "Load Coturn Role for '{{ application_id }}'"
|
||||
include_role:
|
||||
name: web-svc-coturn
|
||||
vars:
|
||||
flush_handlers: true
|
||||
when:
|
||||
- run_once_web_svc_coturn is not defined
|
||||
- not BBB_COTURN_ENABLED
|
||||
|
||||
- name: "Install Collabora Dependency"
|
||||
include_role:
|
||||
name: web-svc-collabora
|
||||
vars:
|
||||
flush_handlers: true
|
||||
when:
|
||||
- run_once_web_svc_collabora is not defined
|
||||
- not BBB_COLLABORA_ENABLED
|
||||
@@ -15,7 +15,7 @@
|
||||
vars:
|
||||
docker_compose_flush_handlers: false
|
||||
- name: "include 04_seed-database-to-backup.yml"
|
||||
include_tasks: "{{ playbook_dir }}/roles/sys-ctl-bkp-docker-2-loc/tasks/04_seed-database-to-backup.yml"
|
||||
include_tasks: "{{ [ playbook_dir, 'roles/sys-ctl-bkp-docker-2-loc/tasks/04_seed-database-to-backup.yml' ] | path_join }}"
|
||||
|
||||
- name: "Unset 'proxy_extra_configuration'"
|
||||
set_fact:
|
||||
@@ -24,33 +24,42 @@
|
||||
- name: configure websocket_upgrade.conf
|
||||
copy:
|
||||
src: "websocket_upgrade.conf"
|
||||
dest: "{{NGINX.DIRECTORIES.HTTP.MAPS}}websocket_upgrade.conf"
|
||||
dest: "{{ [ NGINX.DIRECTORIES.HTTP.MAPS, 'websocket_upgrade.conf' ] | path_join }}"
|
||||
notify: restart openresty
|
||||
|
||||
- name: "Set BBB Facts"
|
||||
set_fact:
|
||||
bbb_env_file_link: "{{ docker_repository_path }}.env"
|
||||
bbb_env_file_origine: "{{ docker_compose.files.env }}"
|
||||
docker_compose_file_origine: "{{ docker_repository_path }}docker-compose.yml"
|
||||
docker_compose_file_final: "{{ docker_compose.directories.instance }}docker-compose.yml"
|
||||
BBB_ENV_FILE_LINK: "{{ [ docker_repository_path, '.env' ] | path_join }}"
|
||||
BBB_ENV_FILE_ORIGINE: "{{ docker_compose.files.env }}"
|
||||
BBB_DOCKER_COMPOSE_FILE_ORIGINE: "{{ [ docker_repository_path, 'docker-compose.yml' ] | path_join }}"
|
||||
BBB_DOCKER_COMPOSE_FILE_FINAL: "{{ [ docker_compose.directories.instance, 'docker-compose.yml' ] | path_join }}"
|
||||
|
||||
- name: Write docker-compose.override.yml for BigBlueButton
|
||||
template:
|
||||
src: docker-compose.override.yml.j2
|
||||
dest: "{{ [ docker_compose.directories.instance, 'docker-compose.override.yml' ] | path_join }}"
|
||||
notify:
|
||||
- docker compose up
|
||||
|
||||
- name: deploy .env
|
||||
# This seems redundant @todo Checkout if this is true and if so, delete it
|
||||
template:
|
||||
src: env.j2
|
||||
dest: "{{ bbb_env_file_origine }}"
|
||||
dest: "{{ BBB_ENV_FILE_ORIGINE }}"
|
||||
notify:
|
||||
- docker compose up
|
||||
|
||||
- name: Create symbolic link from .env file to target location
|
||||
file:
|
||||
src: "{{ bbb_env_file_origine }}"
|
||||
dest: "{{ bbb_env_file_link }}"
|
||||
src: "{{ BBB_ENV_FILE_ORIGINE }}"
|
||||
dest: "{{ BBB_ENV_FILE_LINK }}"
|
||||
state: link
|
||||
|
||||
- name: "Setup docker-compose.yml file"
|
||||
include_tasks: "01_docker-compose.yml"
|
||||
|
||||
- name: Ensure all containers in instance are running
|
||||
include_tasks: "{{ playbook_dir }}/roles/docker-compose/tasks/05_ensure_up.yml"
|
||||
include_tasks: "{{ [ playbook_dir , 'roles/docker-compose/tasks/05_ensure_up.yml' ] | path_join }}"
|
||||
|
||||
- name: flush docker service
|
||||
meta: flush_handlers
|
||||
@@ -58,4 +67,5 @@
|
||||
- name: "Setup administrator"
|
||||
include_tasks: "02_administrator.yml"
|
||||
|
||||
|
||||
- name: "Load '{{ application_id }}' dependencies"
|
||||
include_tasks: "03_dependencies.yml"
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
services:
|
||||
webrtc-sfu:
|
||||
environment:
|
||||
MS_WORKERS: "1"
|
||||
MS_ENABLE_IPV6: "false"
|
||||
MS_WEBRTC_LISTEN_IPS: >-
|
||||
[{"ip":"0.0.0.0","announcedIp":"${EXTERNAL_IPv4}"}]
|
||||
{% if BBB_COTURN_ENABLED | bool %}
|
||||
coturn:
|
||||
ports:
|
||||
- "{{ BBB_TURN_PORT }}:{{ BBB_TURN_PORT }}/udp"
|
||||
- "{{ BBB_TURN_PORT }}:{{ BBB_TURN_PORT }}/tcp"
|
||||
- "{{ BBB_STUN_PORT }}:{{ BBB_STUN_PORT }}/udp"
|
||||
- "{{ BBB_STUN_PORT }}:{{ BBB_STUN_PORT }}/tcp"
|
||||
- "{{ BBB_RELAY_PORT_RANGE }}/udp"
|
||||
command: >-
|
||||
--use-auth-secret
|
||||
--static-auth-secret=${TURN_SECRET}
|
||||
--lt-cred-mech
|
||||
--realm=${DOMAIN}
|
||||
--fingerprint
|
||||
--no-multicast-peers
|
||||
--no-cli
|
||||
--min-port={{ BBB_RELAY_PORT_START }}
|
||||
--max-port={{ BBB_RELAY_PORT_END }}
|
||||
--external-ip=${EXTERNAL_IPv4}
|
||||
{% if BBB_IP6_ENABLED %}--external-ip=${EXTERNAL_IPv6}{% endif %}
|
||||
--cert=${COTURN_TLS_CERT_PATH}
|
||||
--pkey=${COTURN_TLS_KEY_PATH}
|
||||
{% endif %}
|
||||
{% if BBB_COLLABORA_ENABLED | bool %}
|
||||
bbb-web:
|
||||
depends_on:
|
||||
- redis
|
||||
- etherpad
|
||||
- bbb-pads
|
||||
etherpad:
|
||||
depends_on:
|
||||
- redis
|
||||
{% endif %}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user