Autoformat (mbake/yamllint) re-indented sequence items under their mapping key
across the regenerated meta files and wrapped one long URL scalar in the matomo
inject task. Whitespace/formatting only, no semantic change.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract the csp, domains, and networks blocks out of roles/*/meta/server.yml
into dedicated meta files, each mapping to its own top-level applications key
via the recursive meta-walk:
csp: -> meta/csp.yml -> applications.<app>.csp
domains: -> meta/domains.yml -> applications.<app>.domains
networks: -> meta/networks.yml -> applications.<app>.networks
Residual nginx/proxy keys (status_codes, client_max_body_size, locations,
ip6_enabled, config_upstream_url) stay in server.yml; an emptied server.yml is
deleted. 98 server.yml -> 249 new files, 74 deleted.
- Consumers repointed applications.<app>.server.{csp,domains,networks} ->
applications.<app>.{csp,domains,networks} across templates, vars, tasks,
lookups and filters.
- Infra readers migrated: canonical_domains_map, application_domain_index,
build_ldap_role_entries, service-registry overlay discovery,
roles_with_service, and the file-based readers utils/domains/list.py +
utils/meta/scan.py (read the now-deleted server.yml directly).
- Detection + mapping: _META_TOPICS gains csp/domains/networks;
ROLE_FILE_META_{CSP,DOMAINS,NETWORKS} constants + ROLE_FILES entries.
- New self-expiring lint guard (test_server_meta_no_split_fields) fails if a
server.yml still carries a split field; auto-fails from 2026-12-28 as a
delete reminder.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The per-role swarm overlay local subnet was a /28 (14 usable IPs). A role's swarm stack plus its sidecars and per-task network attachments can need more than that, which surfaces as 'node is missing network attachments, ip addresses may be exhausted' and leaves services (sso-proxy, app frontends) unresolvable mid-deploy. Re-allocate all 74 /28 roles to a unique /24 (254 usable) inside 192.168.0.0/16, chosen via the network address suggester so the assignments stay non-overlapping. Validated by tests/integration/infrastructure/networks/test_unique_valid_and_mapped.py and a full make test.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add the document-start marker and indent the canonical-domains list entry to
match the project's yamllint profile.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Pi-hole v6 returns 308 (HTTP→HTTPS redirect) in addition to the
platform's DEFAULT_OK codes (200, 301, 302). Without 308 in the
accepted status_codes, the webserver health checker would flag
pihole.infinito.example as unhealthy.
- Change subnet from 192.168.102.240/28 to 192.168.103.80/28 (overlap with web-app-fediwall)
- Change local.oauth2 port from 16493 to 16500 (collision with web-svc-libretranslate)
- Extend PORT_BANDS.local.oauth2 band from 16499 to 16514 (band exhausted)
- Add missing resource limits to meta/services.yml (cpus, mem_reservation, mem_limit, min_storage, pids_limit)
- Deploy Pi-hole as web app with NGINX proxy and OAuth2 protection
- Only web-app-pihole-administrators group can access the dashboard
- DNS port 53 (TCP/UDP) exposed for network-wide ad blocking
- Upstream DNS configurable per inventory (default: Cloudflare 1.1.1.1)
- Redis session store for OAuth2 proxy
- Timezone from HOST_TIMEZONE platform variable
- Port bindings use DOCKER_BIND_HOST platform variable
- Register subnet 192.168.102.240/28 in networks
- Register ports 8070 (http) and 16493 (oauth2) in ports
- Playwright tests: oauth2 protection, admin login, biber denied (3/3 passing)
Known limitations:
- Pi-hole v6 gravity blocklist requires manual setup via admin UI
- Internal *.infinito.example DNS forwarding to CoreDNS planned as follow-up