Commit graph

7 commits

Author SHA1 Message Date
Simon Bärlocher
3ace667b6c
feat(services): refine split-horizon OIDC routing and harden nextcloud patch
- authentik: address the rewrite service by compose service name instead
  of a network alias on the public FQDN, which shadowed extra_hosts pins
  and broke OIDC discovery for c-ares-based (Node) resolvers
- homarr: add homarr_extra_hosts to pin the IdP FQDN to a LAN IP so OIDC
  discovery stays in-network while the issuer matches the browser-facing URL
- opnform: add opnform_oidc_sso_redirect_root to 302 the root URL to the
  SSO path (deep-links untouched, /login?bypass=1 break-glass); restart
  ingress via container restart so envsubst re-renders nginx.conf
- nextcloud: make the UserConfig sed workaround fail loud on upstream
  drift instead of silently skipping (nextcloud/server#59629)
- gitignore: exclude the local .ansible/ collection cache
2026-06-02 13:44:08 +02:00
Simon Bärlocher
3236ca332f
docs(collection): document all roles and fix metadata drift
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.
2026-05-27 23:12:24 +02:00
Simon Bärlocher
19864d79b2
feat(services): multi-domain routing, split-horizon and OIDC hardening
Bundle of cross-role changes for the gymb services deployment:

- Traefik routers: OR-combine opnform/homarr/bookstack Host rules with new
  *_extra_domains (internal *.int.* FQDNs for a DMZ reverseproxy), and emit
  tls.certresolver only when traefik_cert_mode == acme (drawio, homarr,
  opnform, send).
- Split-horizon: bookstack_extra_hosts / opnform_extra_hosts add container
  /etc/hosts overrides so containers reach the IdP public FQDN over the LAN.
- bookstack: assert the OIDC issuer resolves concretely (reject "//v2.0"),
  allowing non-Entra IdPs that override bookstack_oidc_issuer.
- homarr: derive the bcrypt salt from the password digest so the admin hash
  is idempotent — no spurious template changes / container restarts.
- opnform: PATCH an existing OIDC connection instead of skipping (applies
  corrected inventory on re-run); add OIDC_FORCE_LOGIN (enabled only after
  bootstrap) and an optional direct-SSO ingress entrypoint.

Docs: READMEs and meta/argument_specs.yml updated for all new variables.
2026-05-27 23:12:24 +02:00
Simon Bärlocher
30f3c16b59
docs(opnform): add meta/argument_specs.yml
50 typed options covering the full defaults file plus the OIDC subschema
(group_role_mappings with idp_group + role choices). Required secrets
(app_key, jwt_secret, front_api_secret, db_password) marked
required: true so ansible refuses the play with a clear error before
the validate task even runs.

Loads cleanly through ansible-core's ArgumentSpecValidator. Matches the
spec convention introduced for traefik, authentik, drawio, garage and
nextcloud.
2026-05-26 14:58:36 +02:00
Simon Bärlocher
fb81f60f9d
fix(opnform): drop production-looking secrets from defaults
opnform_app_key, opnform_jwt_secret, opnform_front_api_secret and
opnform_db_password shipped as real base64 strings in defaults — they
look like production secrets that just happen to be public. Set all
four to '' and rely on the existing Validate task (and the new
argument_specs marking them required) to fail fast when an inventory
forgets to override them.

Mirror the docstring comment to show how to generate each one with
openssl.
2026-05-26 14:58:18 +02:00
Simon Bärlocher
48d12a1b4a
fix(opnform): address review feedback on vars header and meta boilerplate
* vars/main.yml: header was 'vars file for homarr' (copy-paste from the
  homarr role). Fixed to 'vars file for opnform'. File body is empty.
* meta/main.yml: replace ansible-galaxy init boilerplate with real
  metadata — author, description, license (MIT-0), min_ansible_version
  set to '2.15' as a string (galaxy schema requires str), galaxy_tags
  for discovery, and an empty dependencies list.

The third inline finding (dead roles/opnform/templates/compose.yml.j2)
is resolved by dropping the WIP commit a6f301e during the rebase rather
than removing it in a separate commit — the file no longer exists in
the rebased history.
2026-05-26 14:58:10 +02:00
03af64ca2c
feat(opnform)!: add admin and OIDC bootstrap, rename role to lowercase
Rename roles/OpnForm → roles/opnform so the role resolves as
  digitalboard.core.opnform (Ansible collection convention is
  lowercase). Update tests/test.yml reference accordingly.

  Add automated admin user creation via POST /api/register, gated on
  opnform_admin_email + opnform_admin_password. Idempotent through a
  prior login probe. Without these vars the manual setup page flow is
  preserved.

  Add automated OIDC IdentityConnection setup via the per-workspace
  /api/open/workspaces/{id}/oidc-connections endpoint, gated on
  opnform_oidc_enabled. Hard-coupled to the admin bootstrap (the API
  requires an authenticated admin token); validation block fails fast
  if OIDC is enabled without admin credentials. Supports both an
  explicit opnform_oidc_group_role_mappings list and a fallback
  opnform_oidc_admin_group convenience var.

  Convert opnform_oidc_scopes from space-separated string to YAML list
  to match OpnForm's API expectation. Rewrite README "First login" and
  "OIDC setup" sections to reflect that self-hosted OpnForm does not
  ship a pre-seeded admin and to document the new bootstrap paths.
  BREAKING CHANGE: opnform_oidc_scopes changed from space-separated
  string to YAML list. Inventories that override it must update from
  "openid profile email" to [openid, profile, email].
2026-05-26 14:54:35 +02:00