mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
Implements requirement docs/requirements/024-web-app-erpnext.md. Stack (per frappe_docker v15 single-image multi-role pattern): - configurator (one-shot bench set-config: db_host/port, three redis URLs split by DB number 0/1/2 for cache/queue/socketio, socketio_port, host_name HTTPS) - backend (gunicorn), frontend (nginx-entrypoint.sh), websocket (socketio), scheduler, queue-short (--queue short,default), queue-long (--queue long,default,short) Central-service consumer pattern (Decision #7): - ERPNEXT_DB_ROOT_PASSWORD branches on services.mariadb.shared: central svc-db-mariadb root pw when true, per-role MariaDB consumer pw when false - Redis via in-compose `redis` alias, 3-DB-number split for Frappe's logical buses - Explicit erpnext_assets volume mount on every container (image's VOLUME ['sites/assets'] otherwise creates anonymous volumes that fail the hlth-volumes check) Bench bootstrap (Decision #9): - bench new-site --install-app erpnext with 30-min hard timeout - Post-install restart of all long-lived Frappe containers (otherwise the cached app set serves HTTP 500 on /login) - TCP-port readiness probe (HTTP would 404 pre-site) - API-bot user seed + setup_complete=1 via apply_api_bot.py OIDC (Decisions #4 + #5): - redirect_uris filter auto-includes ERPNext in the shared Keycloak client - Social Login Key wired via apply_oidc_settings.py with social_login_provider=Keycloak (delete+recreate due to set_only_once), custom_base_url=1, relative authorize/token/userinfo paths, auth_url_data={response_type:code,scope:openid}, login_via_keycloak redirect path - Group-to-Frappe-role mapping persisted as a frappe.db default; per-login reconciliation hook deferred to follow-up (documented in README) LDAP (V3): LDAP Settings doctype applied via apply_ldap_source.py. End-to-end LDAP login (auto-create Frappe user from LDAP bind) deferred to follow-up; LDAP-login Playwright specs intentionally absent in v1 (documented). Email (Decision #8, outbound only): outbound Email Account applied via apply_email_account.py using db_insert/db_update to bypass Frappe's deploy-time SMTP socket validation. IMAP inbound deferred to follow-up. Variant matrix (Decision #11): V1 sso+ldap, V2 all-false, V3 ldap-only. Three variants verified end-to-end via `make compose-deploy mode=reinstall apps=web-app-erpnext full_cycle=true purge=true` — 6 PLAY RECAPs, all failed=0, all Playwright runs passed-or-skipped with no failures. Playwright specs: test-landing, test-csp-headers, test-login-administrator (OIDC), test-login-biber (OIDC), test-login-native-administrator (break-glass local login, always runs), test-guest-persona. _shared.js exposes signInViaErpnextOidc + signInViaErpnextLocal. Repo-wide lint addition: tests/lint/ansible/modules/test_task_name_length.py caps Ansible task `name:` strings at 120 chars (opt-out via `# nocheck: name-length`). Fixed two pre-existing violations in web-app-keycloak/tasks/update/ldap/per_app_mapper_one.yml. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
34 lines
1.7 KiB
Bash
34 lines
1.7 KiB
Bash
ADMIN_EMAIL={{ lookup('users', 'administrator').email | dotenv_quote }}
|
|
|
|
ADMIN_NATIVE_PASSWORD={{ ERPNEXT_INITIAL_ADMIN_PASSWORD | dotenv_quote }}
|
|
|
|
ADMIN_PASSWORD={{ lookup('users', 'administrator').password | dotenv_quote }}
|
|
|
|
ADMIN_USERNAME={{ lookup('users', 'administrator').username | dotenv_quote }}
|
|
|
|
BIBER_PASSWORD={{ lookup('users', 'biber').password | dotenv_quote }}
|
|
|
|
BIBER_USERNAME={{ lookup('users', 'biber').username | dotenv_quote }}
|
|
|
|
CANONICAL_DOMAIN={{ lookup('domain', application_id) | dotenv_quote }}
|
|
|
|
# nocheck: playwright-service-gate — covered by sys-svc-mail integration tests, not the persona surface
|
|
EMAIL_SERVICE_ENABLED={{ lookup('config', application_id, 'services.email.enabled') | string | lower }}
|
|
|
|
ERPNEXT_BASE_URL={{ lookup('tls', application_id, 'url.base') | dotenv_quote }}
|
|
|
|
# nocheck: playwright-service-gate — persona drives OIDC path; LDAP federation exercised in LDAP-only matrix variant
|
|
LDAP_SERVICE_ENABLED={{ lookup('config', application_id, 'services.ldap.enabled') | string | lower }}
|
|
|
|
# nocheck: playwright-service-gate — Frappe lacks a SLO/back-channel logout surface that an unauthenticated test can probe; covered by Keycloak-side integration tests
|
|
LOGOUT_SERVICE_ENABLED={{ lookup('config', application_id, 'services.logout.enabled') | string | lower }}
|
|
|
|
MATOMO_BASE_URL={{ lookup('tls', 'web-app-matomo', 'url.base') | dotenv_quote }}
|
|
|
|
# nocheck: playwright-service-gate — Matomo tracking is an injected snippet, not a per-persona surface; covered by Matomo integration tests
|
|
MATOMO_SERVICE_ENABLED={{ lookup('config', application_id, 'services.matomo.enabled') | string | lower }}
|
|
|
|
OIDC_ISSUER_URL={{ OIDC.CLIENT.ISSUER_URL | dotenv_quote }}
|
|
|
|
SSO_SERVICE_ENABLED={{ ERPNEXT_OIDC_ENABLED | string | lower }}
|