Skip to content

feat(tenants): opt-in nachtelijke demo-reset per tenant - #147

Draft
rubenvdlinde wants to merge 4 commits into
mainfrom
feat/tenant-demo-reset
Draft

rubenvdlinde wants to merge 4 commits into
mainfrom
feat/tenant-demo-reset

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Collaborator

Wat

Een openbare demo-tenant vult zich met wat bezoekers maken. Nieuwe opt-in
component tenant.components.demoReset zet zo'n tenant elke nacht terug naar
een gouden momentopname en laadt daarna de voorbeeldsets opnieuw. Aanleiding:
de demogemeente Zuiddrecht (zuiddrecht-prod).

Nieuwe lokale chart charts/tenant-demo-reset en een aparte ApplicationSet
nextcloud-tenant-demo-reset met een post-selector op
tenant.components.demoReset.enabled. Zelfde afweging als
nextcloud-tenant-routes: geen vierde source in nextcloud-tenants, dus de
bestaande tenant-Applications veranderen niet.

De chart levert een ServiceAccount met alleen pods get/list en pods/exec,
het script als ConfigMap, een nachtelijke CronJob en een CronJob
demo-reset-golden die een mens afvuurt. Alles loopt via kubectl exec in de
bestaande pods. De momentopname is een template-database in de eigen Postgres
plus een kopie van de datamap op dezelfde PVC.

Veiligheid: confirmWipe moet de tenantnaam herhalen (validator, chart en
script). De reset stopt voordat er iets gewist is bij een S3 primary
objectstore, een andere instanceid, of een database en map van verschillende
momenten. Faalt hij daarna, dan blijft de onderhoudsmodus aan. Redis wordt
alleen voor deze instantie geleegd (occ memcache:distributed:clear).

Validator: vijftien nieuwe cases. Nieuwe suite
nextcloud-platform/tests/run-demo-reset-tests.sh, gedraaid door
scripts/verify.sh. Docs: docs/DEMO-RESET.md.

Openstaand: de ApplicationSet komt pas na een handmatige sync van
nextcloud-platform-bootstrap. Het image alpine/k8s:1.29.2 is op tag
gepind, niet op digest. Nooit op een cluster gedraaid.

Gecontroleerd

Lokaal: scripts/verify.sh, nextcloud-platform/tests/run-tests.sh en pre-commit run --all-files --hook-stage pre-push geven exit 0. Alle 89 bestaande tenants renderen byte-identiek (values en manifests). Niet gedraaid: niets tegen een cluster.

Opt-in per tenant; platformwijziging, dus mergen ma tot do na 17:00 en daarna nextcloud-platform-bootstrap syncen. Eerste gebruiker: tenant zuiddrecht-prod (#145).

🤖 Generated with Claude Code

…en momentopname

Nieuwe opt-in component tenant.components.demoReset. Een eigen
ApplicationSet (nextcloud-tenant-demo-reset) met een post-selector op
enabled: true rendert charts/tenant-demo-reset in de namespace van de
tenant; voor de rest van de vloot levert hij niets op en de bestaande
tenant-Applications veranderen niet.

De chart levert een ServiceAccount met alleen pods get/list en pods/exec,
een ConfigMap met het script, een nachtelijke CronJob (04:15
Europe/Amsterdam, paused zet hem stil) en een CronJob demo-reset-golden die
nooit vanzelf draait en die een mens afvuurt met kubectl create job --from.

De momentopname is een template-database binnen de eigen Postgres
(<db>_demo_golden) plus een kopie van de datamap naar /var/www/demo-reset
op dezelfde PVC. Terugzetten is CREATE DATABASE ... TEMPLATE en een
rename, daarna de datamap; logs, config/ en custom_apps blijven van de
draaiende tenant. Daarna occ upgrade als de app-code nieuwer is,
memcache:distributed:clear (alleen de sleutels van deze instantie in de
gedeelde Redis) en occ openregister:example-set:install per set.

confirmWipe moet de tenantnaam herhalen, anders rendert de chart niet en
wist het script niets. Een S3 primary objectstore, een andere instanceid of
een database en map van verschillende momenten stoppen de reset voordat er
iets gewist is. Faalt hij daarna, dan blijft de onderhoudsmodus aan.
…ectl

validate-values.sh kent tenant.components en weigert er onbekende
sleutels. Voor demoReset: enabled en paused zijn echte booleans,
confirmWipe is de tenantnaam, alleen dbType postgres, niet op een
canary-tenant (S3), schedule is een cron-schema met vijf velden,
exampleSets vraagt openregister. Vijftien nieuwe cases.

run-demo-reset-tests.sh rendert de chart (uit leeg, aan zes geldige
resources, verkeerde confirmWipe faalt), het values-blok van de
ApplicationSet via Helm, en draait demo-reset.sh tegen een nep-kubectl
met echte bestandsoperaties op een nep-boom: momentopname nemen,
terugzetten, falen voor en na de eerste onomkeerbare stap, een wissel
die halverwege stopte, het wachtwoord via stdin. verify.sh draait de
suite mee.
docs/DEMO-RESET.md beschrijft hoe de reset werkt, wat de momentopname is en
wat er niet wordt teruggezet, aanzetten, de momentopname nemen, controleren,
falen en herstarten, uitzetten en weghalen, de voorwaarden op het cluster en
waarom niet CNPG, pg_dump, VolumeSnapshots of S3.

docs/agents.md krijgt twee regels: demoReset aanzetten is voorstel-eerst,
een momentopname nemen of een reset met de hand starten is mensenwerk.
docs/index.md, docs/TENANT-OPERATIONS.md, CLAUDE.md en een changelog-
fragment verwijzen ernaar.
@rubenvdlinde rubenvdlinde added the change/platform Platform- of gemengde wijziging: raakt shared values, Argo-wiring, scripts of policy label Oct 14, 2026
…oor medewerkers

Een demo-tenant met inwoners-accounts toont anders elke werkplek-app aan
een inwoner. Nieuw optioneel blok tenant.components.demoReset.limitApps
(apps + exceptGroups): na de voorbeeldsets zet de reset elke app aan voor
alle groepen behalve exceptGroups, per app apart. Een app die Nextcloud
niet tot groepen laat beperken, gaat aan voor iedereen met een WARN.

Groeps- en app-namen gaan door occ in een sh -c-string, dus de validator
en het script accepteren alleen veilige namen. Validator: zes fixtures.
Suite: chart-env, appset-values en vijf scriptcases.

De openregister-check in de validator leest yq nu helemaal uit: onder
pipefail gaf grep -q af en toe een SIGPIPE-fout op een geldig bestand.
@rubenvdlinde

Copy link
Copy Markdown
Collaborator Author

Wat

Eén commit bovenop #147 (feat/tenant-demo-reset): de nachtelijke reset kan na de voorbeeldsets apps beperken tot medewerkers. Nieuw optioneel blok tenant.components.demoReset.limitApps:

tenant:
  components:
    demoReset:
      limitApps:
        apps: [dashboard, contacts, calendar, deck, mail, launchpad, dossiq, pipelinq, decidiq, shillinq, filinq, stackiq, buildiq, keepiq, hermiq, versioniq]
        exceptGroups: [inwoners]

Na occ openregister:example-set:install zet de reset elke app uit apps aan voor alle groepen behalve exceptGroups (occ app:enable --groups=<g> ... <app>), per app apart. Een app die Nextcloud niet tot groepen laat beperken, gaat aan voor iedereen met een WARN in de log. Een app die niet geïnstalleerd is, wordt overgeslagen.

Aanleiding: in de generale repetitie van Zuiddrecht zag een vers inwoners-account 17 apps in de navigatie en opende /apps/dossiq/ met 200. Het repetitiescript 15-staff-only-apps.sh loste dat met de hand op; dit is dezelfde stap, generiek en per tenant te configureren. Hij moet ná de sets draaien, want de voorbeeldset maakt de groepen van medewerkers aan, en hij moet elke nacht opnieuw, want de install-hook zet een app bij een pin-bump uit en weer aan, en dan vervalt een groepsbeperking.

Veiligheid

occ loopt in de Nextcloud-container als sh -c-string. Daarom:

  • validator en script accepteren alleen app-ids (^[a-z][a-z0-9_]{0,63}$) en groeps-ids (^[A-Za-z0-9._@-]{1,64}$);
  • een groep uit occ group:list met een andere naam stopt de stap met een fout, in plaats van hem door te geven;
  • apps zonder exceptGroups weigert de validator, en het script stopt dan vóór de eerste kubectl-aanroep: zonder uitzondering beperkt de stap niets;
  • blijft er geen groep over, dan faalt de Job zichtbaar. De tenant staat dan al op de momentopname en blijft in de lucht.

Ook in deze commit

De openregister-check van #147 in validate-values.sh (yq ... | grep -qx) gaf onder set -o pipefail af en toe een fout op een geldig bestand: grep -q stopt na de eerste match, yq krijgt SIGPIPE en de pipeline faalt. Eén van de nieuwe fixtures liep er bij de eerste run tegenaan; los gedraaid zes keer groen. Nu grep -x ... >/dev/null, dat de invoer helemaal leest.

Gedraaid

Commando Exit
nextcloud-platform/scripts/validate-values.sh 0
nextcloud-platform/tests/run-tests.sh (6 nieuwe fixtures voor limitApps) 0 (41 geslaagd)
nextcloud-platform/tests/run-demo-reset-tests.sh (chart-env, appset-values en 5 nieuwe scriptcases) 0 (32 geslaagd)
scripts/verify.sh 0
pre-commit run --all-files --hook-stage pre-push 0
shellcheck op demo-reset.sh, validate-values.sh, run-demo-reset-tests.sh 0
mutatie: aanroep van limit_apps_to_groups uitgezet 3 scriptcases falen, zoals bedoeld

Niet gedraaid: niets tegen een cluster. Een tenant zonder limitApps krijgt geen nieuwe env vars in de CronJob; geen tenant op main gebruikt de demo-reset.

Te beslissen

Platformwijziging (nieuwe ApplicationSet en chart via #147), label change/platform, mergen ma tot do na 17:00 en daarna nextcloud-platform-bootstrap syncen.

🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

change/platform Platform- of gemengde wijziging: raakt shared values, Argo-wiring, scripts of policy

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant