Ga naar inhoud

Provisioning a tenant

Any operator who can reach a tenant can run the target track — it is pure-stdlib Python over HTTPS, no repo-specific state. Supply the tenant URL and an admin / app-password credential (kept out of argv via env):

# one .env file per target (gitignored; see .env.canary.example)
#   CANARY_USER=...      CANARY_PASS=<app password>      OPENWOO_APIKEY=<source key>
set -a; . .env.<target>; set +a
python3 scripts/provision.py all \
    --base https://<tenant> --user "$CANARY_USER" \
    --password-env CANARY_PASS --apikey-env OPENWOO_APIKEY

Credentials can also come from interactive prompts — omit --user, --password and --apikey and, on a terminal, the tool asks for the admin user (default admin), the app password and the source API key (getpass, never stored or in argv). The minimal fully-interactive run:

python3 scripts/provision.py all --base https://<tenant>
#   Nextcloud admin user [admin]:
#   App password for admin @ https://<tenant>:
#   Source API key (blank = dummy test key):
#   Source URL (blank = keep config default):
#   API-Interface-ID (blank = keep config default):

The source URL, API-Interface-ID and API key are per-tenant (each client's source system differs), so they are supplied per run — not committed to the config. Provisioning is operator-driven: an operator runs the CLI/GUI against the tenant's public URL after a deployment (the public host is a trusted domain, so it just works — no in-cluster wiring).

For a form-based front-end, scripts/provision_gui.py opens a small Tkinter window with the same fields and runs provision.py all (secrets passed via env, never argv). With no Tkinter/display it prints the equivalent terminal command.

What all does

all is a convergence/repair run: it updates the existing tenant's objects to the config's desired state — it does not wipe, and does not prune entities that exist on the tenant but not in the config. It is idempotent: each step GET-checks first and skips the write when the tenant is already correct, so a re-run on a converged tenant is a near no-op. The config import is skipped when every slug is already present; pass --force-import (or the GUI "Force re-import" checkbox) to re-upload after a config content change. Run a single step (verify-import, sync-check, …) to validate an existing tenant without changing it — see the command reference. Credentials come from the operator's own env/secret, never from this repo.

Source credentials

The demo source authenticates with an API key sent as the API-KEY request header. The config ships an empty placeholder (configuration."headers.API-KEY": "") — the real key is never committed; it is injected at provision time from a secret (a K8s secret / ESO in prod, an env var locally):

# real provisioning against a tenant — password and key come from env vars
# (kept out of argv / logs); username is not a secret:
python3 scripts/provision.py credentials \
    --base https://<tenant> --user <admin> \
    --password-env CANARY_PASS --apikey-env OPENWOO_APIKEY

Real credentials for any source come from a secret store, never from the config JSON or git history.