Commit Graph
2780 Commits
Author SHA1 Message Date
kevinveenbirkenbach aedce7a9cd feat(tls): make global self-signed SANs strictly driven by CURRENT_PLAY_DOMAINS_ALL
cert_plan now requires CURRENT_PLAY_DOMAINS_ALL to be a non-empty list of strings when TLS_SELFSIGNED_SCOPE=global and uses it directly for SAN generation. Update unit tests to cover the strict contract and validation errors.

https://chatgpt.com/share/697bc866-0558-800f-8f2c-08ec84190a68
2026-01-29 21:51:23 +01:00
kevinveenbirkenbach fb53387384 feat(docker-compose-ca): inject CA trust for all compose services incl. profile-only ones
compose_ca_inject now discovers profiles from compose files, merges services from default + each profile config, and ensures missing images are built/pulled before inspecting entrypoint/cmd. Tests were updated to cover entrypoint normalization and the new profile-scan behavior.
2026-01-29 20:37:18 +01:00
kevinveenbirkenbach 06b9ccdc8e test(integration): require image tag for buildable docker-compose templates
Adds an integration test that fails when a service defines `build:` without an `image:` on the same indentation level. This enforces stable image names for tooling like CA-injection and makes compose behavior more predictable.

https://chatgpt.com/share/697bb4af-0d58-800f-8edd-aaef4c224319
2026-01-29 20:27:32 +01:00
kevinveenbirkenbach e9a6a952c5 refactor(compose): move compose_f_args lookup to top-level and update usages
- Relocate compose_f_args lookup plugin to lookup_plugins/
- Update docker compose commands to use canonical -f argument resolver
- Fix unit test import path after lookup relocation

https://chatgpt.com/share/697ba25e-b038-800f-9419-84cd575c8c0a
2026-01-29 19:09:23 +01:00
kevinveenbirkenbach b97cbef03f refactor(compose): derive project from application_id and unify compose -f resolution
Remove project kwarg from compose_ca_inject_cmd, derive entity name internally,
and reuse compose_f_args with include_ca=false for bootstrap consistency.
Add include_ca flag to compose_f_args and update unit tests accordingly.

https://chatgpt.com/share/697b9d97-0cf0-800f-805d-7e8308b6f832
2026-01-29 18:48:53 +01:00
kevinveenbirkenbach 4a5736615f Solved falsy file paths 2026-01-29 17:43:22 +01:00
kevinveenbirkenbach 8bff1b984d refactor(jinja): add strict recursive renderer and use in tls/compose lookups
Introduce module_utils/jinja_strict.py to render nested Jinja-in-vars with hard-fail semantics. Refactor cert_plan, compose_f_args, and compose_ca_inject_cmd to use render_strict so no "{{ ... }}" leaks into generated paths/commands, and add unit tests.

https://chatgpt.com/share/697b8e1b-54fc-800f-b895-7161f00ebd51
2026-01-29 17:42:28 +01:00
kevinveenbirkenbach b2fb72d112 feat(tls): split TLS settings to 02_tls and add self-signed root CA role
Move TLS/ACME/CA vars out of 00_general into group_vars/all/02_tls.yml and renumber subsequent group_vars files. Add sys-ca-selfsigned to generate /etc/<software>/ca/root-ca.crt and make docker-compose-ca depend on it. Update setup script, templates, and tests to use the new applications/users file numbering.

https://chatgpt.com/share/697b8150-22ac-800f-98b1-e063a659b684
2026-01-29 16:48:03 +01:00
kevinveenbirkenbach a354578844 feat(tls): expand Jinja paths inside cert_plan lookup
cert_plan now strictly renders Jinja-containing path variables (e.g. TLS_SELFSIGNED_BASE_PATH / LETSENCRYPT_LIVE_PATH) using hostvars context and fails fast if markers remain. Add unit tests covering successful expansion, hostvars precedence, and hard-fail behavior when variables are missing or Jinja leaks through. Include SOFTWARE_NAME in constructor debug output for easier runtime inspection.

https://chatgpt.com/share/697b73c6-f5f8-800f-96cc-e360a137e7a7
2026-01-29 15:50:32 +01:00
kevinveenbirkenbach 5ca6ecd3d7 fix(dotenv): escape $ for docker compose env interpolation
Ensure dotenv_quote escapes `$` as `$$` so secrets are not
expanded by docker compose when rendered into .env files.

Add unit tests covering $, quotes, backslashes, unicode and
edge cases to prevent regressions.

https://chatgpt.com/share/6977825f-d8f8-800f-bafb-aae3b3704945
2026-01-26 16:03:36 +01:00
kevinveenbirkenbach 7a590a3ae5 set hunspell to pre-alpha 2026-01-25 14:51:27 +01:00
kevinveenbirkenbachandCopilot Autofix powered by AI 5e2b697fe1 Potential fix for code scanning alert no. 174: Jinja2 templating with autoescape=False
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-01-25 14:41:18 +01:00
kevinveenbirkenbachandCopilot Autofix powered by AI 620ec7e1c0 Potential fix for code scanning alert no. 136: Empty except
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-01-25 11:28:43 +01:00
kevinveenbirkenbach 84397d01c3 feat(sys-ctl-hlth-csp)!: build URL targets from nginx listen directives
Switch CSP health crawler to URL-only mode by deriving http/https from each
nginx .conf (listen 80/443/ssl) and passing full URLs to csp-checker.
Update unit tests accordingly.

BREAKING CHANGE: sys-ctl-hlth-csp now passes full URLs instead of domains.

https://chatgpt.com/share/69756136-e658-800f-9e52-7d9c4a79d026
2026-01-25 01:42:44 +01:00
kevinveenbirkenbach 3b1032895a feat(security): introduce sed_escape filter and enforce safe sed replacements
- add sed_escape Jinja filter for sed replacement safety
  - escapes \, &, and the active sed delimiter
  - designed explicitly for sed s/// replacement context

- patch all sed-based config updates across roles
  - espocrm, friendica, gitea, matomo, moodle, wordpress
  - ensure every Jinja value in sed replacements uses sed_escape
  - use correct delimiter-specific escaping (/, |, #)

- add robust integration test to enforce sed_escape usage
  - scans all roles/*/tasks/**/*.yml
  - detects sed substitutions with Jinja in replacement part
  - ignores delimiters inside {{ ... }} blocks
  - fails CI if sed_escape is missing

- harden repository against sed injection, delimiter breakage,
  and credential corruption in config patching tasks

https://chatgpt.com/share/6974fb45-1ee8-800f-80bd-c71122e4ac02
2026-01-24 18:02:37 +01:00
kevinveenbirkenbach 8b1ae03e77 fix(env): prevent dotenv_quote double-quoting in env.j2 templates
- Replace `"{{ ... | dotenv_quote }}"` with `{{ ... | dotenv_quote }}` across roles
- Update integration test to enforce pure Jinja + dotenv_quote and forbid wrapped quotes

https://chatgpt.com/share/6974e6c6-51b8-800f-80a1-a76f885cf57e
2026-01-24 16:35:27 +01:00
kevinveenbirkenbach d4ecd331a5 test(integration): fail on double-quoted | quote in shell password expressions
Extend password-quoting integration test to:
- fail when password variables in shell tasks miss the `| quote` filter
- fail when `| quote` is used but the Jinja expression is wrapped in quotes
  (double-quoting)

This ensures shell-safe password handling and prevents quoted secrets
from being passed literally to CLI tools.

https://chatgpt.com/share/6974dd33-9470-800f-b469-d31fabcd59e1
2026-01-24 16:03:09 +01:00
kevinveenbirkenbach dcb33e089d test(integration): enforce password quoting rules for definitions and shell tasks
- add integration test to ensure password variable definitions never use '| quote'
- add integration test to ensure password usage in shell tasks always uses '| quote'
- scope checks to roles/**.yml using regex-based best-effort parsing

https://chatgpt.com/share/6974da97-e6dc-800f-8acc-43aa45e6cf8f
2026-01-24 15:43:29 +01:00
kevinveenbirkenbach aa7d0c642c feat(dotenv): add dotenv_quote filter and enforce quoted password vars in env.j2
https://chatgpt.com/share/6974cbac-023c-800f-8198-fd85df2aa7bc
2026-01-24 15:22:19 +01:00
kevinveenbirkenbach 33a4b2a430 **feat(web-app-keycloak): add kcadm noisy-JSON helper and remove jq/--query usage**
Introduces role-local `kcadm_json` filter + `module_utils/kcadm_json.py` to reliably parse kcadm output with JVM noise, and reuses it in `keycloak_kcadm_update` and LDAP/RBAC/recaptcha tasks to eliminate jq/`--query`. Also refactors LDAP groups.path handling via `include_tasks` to avoid repeated `when` conditions and adds unit tests for filter/module utils/library behavior.

https://chatgpt.com/share/69743d89-b1c0-800f-b571-90f64605dfe4
2026-01-24 04:33:14 +01:00
kevinveenbirkenbach 35c1d29a88 fix(docker-compose): remove has_domain filter dependency from compose_f_args
Make has_domain filter self-contained (no module_utils/sys.path hacks) and let compose_f_args detect domains internally to avoid missing-filter failures. Adjust unit tests accordingly and increase Mailu user creation retry delay.

https://chatgpt.com/share/6973e02e-f22c-800f-aae3-1f57637a746c
2026-01-23 21:54:55 +01:00
kevinveenbirkenbach d971fd0fd6 fix(docker-compose): make compose_f_args role-aware for override + domain-aware for TLS
https://chatgpt.com/share/6973d900-93f4-800f-8d54-08c21f4a8f58
2026-01-23 21:24:27 +01:00
kevinveenbirkenbach 204c028d6a feat(domains): add has_domain filter and guard self-signed CA handling
- introduce has_domain filter reusing get_domain logic
- prevent self-signed CA role execution if no domain is defined
- add unit tests for has_domain filter

https://chatgpt.com/share/6973cdf7-f7fc-800f-901b-4de186a3637c
2026-01-23 20:37:22 +01:00
kevinveenbirkenbach 8e68dd5c1b feat(docker-compose): add infinito-compose wrapper and switch repair scripts to it
Deploy /usr/local/bin/infinito-compose to auto-detect .env and compose override files.
Refactor sys-ctl-rpr-docker-{hard,soft} to use the wrapper consistently.
Update unit tests to match wrapper-based command building.

https://chatgpt.com/share/6973c64c-b560-800f-8915-cbb786c51714
2026-01-23 20:04:38 +01:00
kevinveenbirkenbach 4dbbcec106 feat(docker-compose): add dynamic CA trust injection for self-signed TLS
Introduce docker-compose-ca role with CA wrapper and inject script, add CA-aware compose override handling, and refactor compose pull/run logic to support multi-file projects. Update handlers, lookups, paths, and unit tests to consistently resolve TLS-driven CA injection without implicit defaults.

https://chatgpt.com/share/6973c00c-139c-800f-8ddb-e7d0cf5043fc
2026-01-23 19:36:55 +01:00
kevinveenbirkenbach c3c54ce043 refactor(tls): split resolution and certificate planning, add global self-signed SAN support
- Extract shared TLS logic into module_utils/tls_common
- Introduce cert_plan lookup for certificate paths and SAN computation
- Simplify tls_resolve to strict protocol/port/domain resolution only
- Add global self-signed certificate scope covering all domains
- Mount self-signed cert base into OpenResty container
- Update Nginx templates to use cert_plan for ssl_certificate paths
- Add comprehensive unit tests for tls_common, tls_resolve, and cert_plan

https://chatgpt.com/share/6972c568-9e8c-800f-b89a-a0061966f9a8
2026-01-23 01:48:31 +01:00
kevinveenbirkenbach 5e25e5859c refactor(web-app-desktop): derive card URLs via tls_resolve instead of WEB_PROTOCOL
- Remove legacy WEB_PROTOCOL dependency from docker_cards lookup
- Build application URLs using strict tls_resolve lookup
- Align desktop card URL generation with new TLS layer
- Update unit tests to stub tls_resolve and validate TLS-based behavior
- Drop WEB_PROTOCOL-related test cases

https://chatgpt.com/share/6972b832-8284-800f-8b86-f1a32061c09f
2026-01-23 00:52:14 +01:00
kevinveenbirkenbach 0b9f71463c refactor(tls): replace legacy tls filters with strict tls_resolve lookup
- Remove deprecated filter_plugins/tls.py and all dependent filters
- Introduce strict lookup plugin lookup_plugins/tls_resolve.py as single TLS authority
- Migrate all roles, templates, vars, and tasks to use tls_resolve (protocols, ports, URLs, cert paths)
- Enforce explicit TLS context (domains, applications, TLS_ENABLED, TLS_MODE)
- Support letsencrypt and self_signed with SAN handling and per-app overrides
- Update TLS provider roles to assert resolver state instead of setting facts
- Add comprehensive unit tests for tls_resolve lookup

https://chatgpt.com/share/6972b49b-b074-800f-a323-dd9fe69d02eb
2026-01-23 00:36:46 +01:00
kevinveenbirkenbach fae7b82243 feat(security): introduce strong_password filter backed by ValueGenerator
- add strong_password Jinja2 filter as thin wrapper around ValueGenerator
- enforce password policy (upper, lower, digit, special, min length)
- replace insecure ascii-only password lookup with strong_password filter
- update CLI setup users and unit tests accordingly
- harden inventory sample password example

https://chatgpt.com/share/69722c7e-ebe0-800f-a9ab-a3e21b43269c
2026-01-22 14:56:05 +01:00
kevinveenbirkenbach bac0393a3e test(integration): fix false positives for applications.<attr>() and add exact error location
- Skip Python attribute matches that are used as method calls (e.g. applications.setdefault(...))
- Add line and column information to assertion errors
- Print the exact source line for faster debugging of invalid application references

https://chatgpt.com/share/697215ce-df3c-800f-b81f-641c75939e7f
2026-01-22 13:19:19 +01:00
kevinveenbirkenbach a565344ed5 Solved shellcheck 2026-01-21 00:25:35 +01:00
kevinveenbirkenbach ea78ff376f test(container): adapt CLI tests for required INVENTORY_DIR and forwarding
- add --inventory-dir to container CLI test invocations
- assert inventory_dir is forwarded to run_in_container()
- add tests for required INVENTORY_DIR when env is missing
- add test for INVENTORY_DIR env fallback

https://chatgpt.com/share/69700d69-b270-800f-ad50-d9ff486378b9
2026-01-21 00:23:54 +01:00
kevinveenbirkenbach d35e932e0c refactor(cli): switch development CLI to dynamic dispatcher and fix test paths
- Replace static argparse-based CLI in cli.deploy.development with dynamic
  module dispatcher compatible with nested command discovery.
- Ensure cli.deploy.development is executable via python -m and root dispatcher.
- Fix unit test path resolution to work locally and in CI.
- Make docker-* Makefile targets depend on install.
- Simplify test runner script and keep Nix flake config compatibility.

This aligns the CLI architecture with integration test discovery
(cli/**/__main__.py) and removes the need for manual subcommand registration.

https://chatgpt.com/share/696fdbbc-b6d8-800f-a8b5-067aa7e38706
2026-01-20 20:46:20 +01:00
kevinveenbirkenbach ba4527a8db ruff 2026-01-19 21:17:56 +01:00
kevinveenbirkenbach ab7bb0b6fb feat(mastodon): add HTTP-only override and disable force_ssl via initializer
- Add optional HTTP-only mode for Mastodon deployments
- Inject override initializer to hard-disable force_ssl and ActionDispatch::SSL
- Mount override into Mastodon and Sidekiq containers
- Prevent automatic compose flush before migrations
- Apply overrides before setup phase

Also:
- Remove unconditional HSTS header from ws_generic proxy vhost
- Make OIDC optional for CI (docker-in-docker)
- Fix env.j2 quoting and formatting
- Gate HSTS in Nextcloud behind TLS_ENABLED

https://chatgpt.com/share/696e914c-c758-800f-b16e-6341873c0e0e
2026-01-19 21:17:04 +01:00
kevinveenbirkenbach f56cfa773e **test(unit): add full unittest coverage for sufficient_storage CLI and role_resource_validation**
https://chatgpt.com/share/696e3d20-276c-800f-87a7-a7052989ffe4
2026-01-19 19:29:08 +01:00
kevinveenbirkenbach c92aff464b feat(ci): add min_storage validation and CI filtering with warnings
- Add sufficient_storage CLI for validating docker.services.<entity>.min_storage
- Introduce role_resource_validation utility with human-friendly size parsing
- Filter CI app discovery by available runner storage (default: 12GB)
- Emit GitHub Actions warnings for:
  - missing min_storage metadata (treated as 0GB)
  - roles exceeding available runner storage
- Add BigBlueButton min_storage metadata (50GB)
- Add unit tests for validation logic and CLI behavior
- Add humanfriendly dependency for size parsing

https://chatgpt.com/share/696e097b-1038-800f-b8fc-23e9dadfa021
2026-01-19 11:37:28 +01:00
kevinveenbirkenbach 7a1fb02554 test(cli): add unit tests for combined + services resolution (services edges, desktop, cycles)
- add role_config_path support and services edges in combined resolver/tree
- add services resolver mapping with desktop enabled rule (non-shared)
- add unittest coverage for repo_paths, yaml parsing, services mapping/BFS, and combined tree cycles
- update tests to reflect new stable path expectations and tree output

https://chatgpt.com/share/696cb80f-e8f4-800f-b062-e47985b4b074
2026-01-18 11:37:41 +01:00
kevinveenbirkenbach cf216014e3 refactor(cli): introduce combined role resolution and reorganize meta resolvers
- add cli.meta.applications.resolution.combined to resolve run_after + app-only dependencies
- add optional --tree output for combined resolution
- add cli.meta.applications.resolution.dependencies (app-only) resolver
- move run_after resolver to cli.meta.applications.resolution.run_after
- update test deploy dependency resolver to use combined module
- add unit tests for combined/dependencies/run_after resolvers
- minor cleanup: remove stray header comment, fix newline in vars, tidy YAML formatting

https://chatgpt.com/share/696ca531-9644-800f-98c0-bae58c0aff41
2026-01-18 10:17:26 +01:00
kevinveenbirkenbach 66aec3b577 refactor(docker-compose): generate volumes via compose_volumes filter
Replace legacy volumes*.yml.j2 includes with the new compose_volumes filter across roles.
Add YAML-safe serialization for Ansible/Jinja proxy types to avoid PyYAML representer errors.
Remove obsolete volumes templates and extend unit tests to enforce required database_volume behavior.

https://chatgpt.com/share/696c2722-fd30-800f-bf01-dfcd3cb7ba72
2026-01-18 01:19:31 +01:00
kevinveenbirkenbach 8059f51e33 feat(filter): add compose_volumes helper to replace volumes.yml.j2 logic
- Add compose_volumes filter to generate docker-compose volumes section dynamically
- Preserve exact logic from roles/docker-compose/templates/volumes.yml.j2
  - database volume only when database service enabled and not shared
  - redis volume when redis service enabled or oauth2 enabled
  - no fallback names, database_volume is required when database is needed
- Support manual volume injection via extra_volumes (YAML merge equivalent)
- Add strict input validation for applications and application_id
- Add full unit test coverage for all conditions and edge cases

https://chatgpt.com/share/696c1710-04c4-800f-a73f-de3d5ebd2902
2026-01-18 00:11:07 +01:00
kevinveenbirkenbach fa422ed7fe cli: allow comma-separated application IDs for --id flag
- Support space-separated, comma-separated and mixed --id values
- Normalize and deduplicate application IDs before validation
- Fix Makefile to pass APP without quoting
- Add unittest coverage for ID normalization

https://chatgpt.com/share/696be0c2-816c-800f-8b07-3c5cd0304ac5
2026-01-17 20:19:13 +01:00
kevinveenbirkenbach 357a9bda83 fix(users): normalize reserved flag handling and align CLI/tests
- Always emit reserved flag in generated users (default: false)
- Do not override existing user definitions via --reserved-usernames
- Normalize description default to empty string
- Align unit tests with new reserved semantics
- Fix YAML quoting and trailing newline issues
- Clean up minor formatting and config inconsistencies

https://chatgpt.com/share/696bb761-0048-800f-9cf7-aebd3fda75be
2026-01-17 17:22:50 +01:00
kevinveenbirkenbach 97869523cb ruff 2026-01-17 02:56:22 +01:00
kevinveenbirkenbach c4bffe1ea1 test(lookup): add deterministic Jinja templating for docker_cards unit tests
- Render WEB_PROTOCOL and domain_url via templar in docker_cards lookup
- Add DummyTemplar with Ansible-like bool filter for stable unit testing
- Refactor tests to use templar injection via _run_lookup helper
- Add coverage for Jinja-based WEB_PROTOCOL and domain rendering

This ensures lookup behavior matches real Ansible runtime while keeping unit tests deterministic.

https://chatgpt.com/share/696ac8bf-8c0c-800f-a3e7-db4bfb2a8f3f
2026-01-17 00:24:41 +01:00
kevinveenbirkenbach ae7a1e258c feat(web-app-desktop): require WEB_PROTOCOL for docker_cards lookup URLs
- Enforce explicit WEB_PROTOCOL variable for URL generation
- Fail fast with AnsibleError when WEB_PROTOCOL is missing
- Add unit tests for http/https protocol handling
- Refactor test fixtures using shared base variables

This makes URL generation deterministic and proxy-agnostic and avoids
implicit defaults in desktop card rendering.

https://chatgpt.com/share/696a958b-eeec-800f-867b-842e0621b4bb
2026-01-16 20:46:15 +01:00
kevinveenbirkenbach 505af3e2ad cli: make --log require explicit directory and create parents automatically
- Change --log flag to require explicit log directory (--log <LOG_DIR>)
- Automatically create log directory with parents=True
- Harden permissions best-effort (0700)
- Update CLI help text accordingly
- Adjust Makefile test targets to pass explicit log directory
- Ignore logs/ via .gitignore and .dockerignore
- Refactor flag parsing to correctly detect deploy with --log
- Add dedicated logging unit tests
- Update existing tests for new log semantics
- Remove deprecated -i alias for --id in deploy command

https://chatgpt.com/share/6969680a-dbf8-800f-aafb-3d32d6212ba0
2026-01-15 23:19:31 +01:00
kevinveenbirkenbach ea63818216 refactor(cli): simplify dedicated deploy wrapper and add ansible passthrough support
- Remove unused cli_root and logs handling from dedicated deploy wrapper
- Add parse_known_args() to forward native ansible-playbook flags
- Append passthrough args at the end for proper override behavior
- Clean up MODE_LOGS usage
- Update runner signature and cleanup phase logic
- Adapt unit tests to new wrapper contract
- Add unit test for ansible flag passthrough in command.main()

https://chatgpt.com/share/69694ad5-453c-800f-8047-cf210f60460f
2026-01-15 21:15:06 +01:00
kevinveenbirkenbach 49df004a5f General py optimations 2026-01-15 05:02:55 +01:00
kevinveenbirkenbach 854f5501f7 test(filter): remove invalid applications type guard test for service_load_enabled
The applications parameter is guaranteed to always be a dict in the runtime
environment. The defensive test for non-mapping input was therefore removed
to avoid unrealistic failure scenarios and false negatives.

This keeps the unit tests aligned with the actual inventory and schema model.

https://chatgpt.com/share/6968551e-7b74-800f-8a5e-a2380c950d06
2026-01-15 03:46:47 +01:00