Replace ansible-galaxy init placeholders across the collection and
correct documentation that drifted from the code, after a multi-agent
review of every role README against its defaults, tasks and templates.
Collection level:
- README: role table for all 16 roles, requirements and role-ordering
- galaxy.yml: declare community.docker and community.general deps,
real description/tags/urls; normalize license to MIT-0
- meta/runtime.yml: requires_ansible '>=2.15.0'
- plugins/README: document the homarr_layout filter and
garage_credentials lookup instead of scaffold boilerplate
Per-role meta/main.yml and README for the placeholder roles
(389ds, authentik, authentik_outpost_ldap, base, collabora, drawio,
garage, homarr, httpbin, keycloak, nextcloud, opencloud, traefik).
Correctness fixes found during review:
- keycloak: wrong domain default, drop invented keycloak_cert_resolver,
document the provisioning feature
- garage: root_domain is .s3.<first-entry>, not the bare domain
- opnform: jwt/front_api secrets use `openssl rand -hex 32`; align the
validation fail_msg in tasks/main.yml accordingly
- send: S3 example references garage_s3_domains[0] (was singular)
- opencloud: document required opencloud_wopi_domain
License normalized to MIT-0 across galaxy.yml, role meta and READMEs to
match the SPDX headers.
Each of the five roles touched in this branch now ships:
* meta/argument_specs.yml: typed schema for every variable in
defaults/main.yml plus the optional inputs surfaced via this
branch (traefik_extra_hosts, authentik_host_rewrite_domains,
authentik_proxy_apps.mode / .allowed_groups, drawio_extra_domains,
drawio_authentik_forward_auth*, garage_webui_authentik_forward_auth*).
All five specs load cleanly through ansible-core's
ArgumentSpecValidator.
* README.md: replaces the ansible-galaxy boilerplate (where it was
still in place) with a focused write-up — service vars, required
secrets, ForwardAuth/idempotency notes, dependencies, and a working
example playbook. authentik and garage READMEs are rewritten to cover
the new knobs while preserving their existing content.
nextcloud/server#59629: under PHP 8.x with OPcache,
UserConfig::getValueBool() passes a non-string from getTypedValue()
straight into strtolower(), throwing a TypeError on every authenticated
request once user_ldap is involved. Fix landed in master (PR #59646)
but no stable33 backport made it into 33.0.4.
Discover all compose-managed nextcloud containers, check whether the
`strtolower((string)` cast is already present, and `sed` it into
`lib/private/Config/UserConfig.php` on the ones that still ship the
broken version. Idempotent via grep guard so re-runs are no-ops.
Remove this block once the deployed image >= 33.0.4 ships the upstream fix.
Every `occ config:app:set` / `ldap:set-config` / `notify_push:setup`
call previously fired on every play, marking changed even when the
stored value already matched. Now we read the current value first and
only invoke the setter when it differs:
* richdocuments (collabora): pre-read wopi_url, public_wopi_url,
disable_certificate_verification, wopi_allowlist into a fact map;
guard each `config:app:set` and tag `richdocuments:activate-config`
with `changed_when: false` since it's a discovery refresh.
* drawio: same pattern for DrawioUrl, DrawioTheme, DrawioOffline,
comparing as strings (occ stores booleans as "1"/"0").
* user_ldap: pre-read `ldap:show-config s01 --output=json`, parse JSON
defensively (occ logs interleave on stderr), and skip per-key
`ldap:set-config` calls when the stored value already equals the
desired one.
* notify_push: skip `notify_push:setup` when the stored base_endpoint
already matches the computed URL.
* plugins: `app:install`/`app:enable` were treating "already installed/
enabled" output as a change. Add the negative match to `changed_when`
so re-runs of a fully-provisioned site report ok rather than changed.
- Drop `recreate: always` from collabora/drawio/homarr/opencloud/traefik
handlers and the authentik_outpost_ldap start task. `up -d` with
`state: present` already recreates exactly the services whose
compose definition changed; the blanket recreate was forcing
restarts even when nothing relevant moved.
- Rewrite the `*_domains` Traefik Host loop to the `Host(\`a\`) ||
Host(\`b\`)` form across authentik/collabora/garage/nextcloud so the
rule still matches when traefik can't normalize the comma-form into
the same canonical shape.
- Traefik: add `traefik_acme_tcp_only` (sets LEGO_EXPERIMENTAL_DNS_TCP_ONLY)
and `traefik_acme_disable_ans_checks` (disables lego's authoritative-NS
propagation check) for environments where the DNS path between the
traefik container and the zone's nameservers is constrained.
- Traefik DMZ collector: two-step merge so a `traefik_dmz_exposed_services`
entry that sets its own `backend_host` wins over the host fallback;
lets a route target an internal FQDN covered by the backend cert's
SANs instead of the raw IP.
- Nextcloud: add `nextcloud_notify_push_domain` override for the
`occ notify_push:setup` call so the setup check can hit an internal
FQDN instead of hairpinning through the DMZ. Push router now matches
every entry in `nextcloud_domains`.
- Nextcloud: also %2F-escape slashes in the postgres user/password
inside the notify_push DATABASE_URL.
- Refactor: collapse `*_domain` + `*_extra_domains` into a single
`*_domains` list across authentik, collabora, garage and nextcloud
roles. First entry is the canonical FQDN (used for OVERWRITEHOST,
BASE_URL, notify_push setup and garage root_domain).
- Authentik blueprint: guard the OAuth sources block so an empty
`authentik_login_sources` no longer renders an invalid YAML key.
- Nextcloud: introduce `nextcloud_collabora_public_domain` and set
Collabora's `public_wopi_url` separately from the server-to-server
`wopi_url` so browsers can reach Collabora via the public name while
Nextcloud still talks to it on the internal one.
- Nextcloud: URL-encode the postgres user/password in DATABASE_URL.