Grant the provisioner client every machine's plans, as it watches them (issue 774) #137

Merged
jschoubben merged 1 commits from fix/provisioner-reads-every-plan into main 2026-10-30 15:53:31 +00:00
2 changed files with 12 additions and 7 deletions
+6 -4
View File
@@ -658,6 +658,9 @@ func healthChecks(t *testing.T) {
"a.disk-load": {"$KV.disk-load_readings.a.pg.data"},
"provisioner.a": {"$JS.API.DIRECT.GET.KV_mesh-provisioner_plans.$KV.mesh-provisioner_plans.a.keycloak",
"$JS.API.CONSUMER.CREATE.KV_mesh-provisioner_plans.c1.$KV.mesh-provisioner_plans.a.keycloak",
// Every machine's plans, as the client V3 watches them (issue 774, 2026-10-30).
"$JS.API.CONSUMER.CREATE.KV_mesh-provisioner_plans.c1.$KV.mesh-provisioner_plans.>",
"$JS.API.DIRECT.GET.KV_mesh-provisioner_plans.$KV.mesh-provisioner_plans.b.keycloak",
// The needs, for the client before V3, until the lease write (review round 3).
"$KV." + ProvisionerNeedsBucket + ".a.keycloak.db.x"},
// ADR 0571 clause 3: restic's bundle writes each item's last good night as its own state; the self-check reads it.
@@ -692,10 +695,9 @@ func healthChecks(t *testing.T) {
// Each writes its own state alone, and these users are composed.
"a.disk-load": {"$KV.restic_good.a.pg.data"},
"a.mesh-delivery-builder": {"$KV.disk-load_readings.a.pg.data"},
// Another machine's plans are not its to read, nor another machine's needs, which it keeps for the client before
// V3 until the lease write.
"provisioner.a": {"$JS.API.DIRECT.GET.KV_mesh-provisioner_plans.$KV.mesh-provisioner_plans.b.keycloak",
"$KV.mesh-provisioner_plans.a.keycloak", "$KV." + ProvisionerNeedsBucket + ".b.keycloak.db.x"},
// It reads every machine's plans (a provider's consumers are bound there, ADR 0373) but writes none, nor another
// machine's needs, which it keeps for the client before V3 until the lease write.
"provisioner.a": {"$KV.mesh-provisioner_plans.a.keycloak", "$KV." + ProvisionerNeedsBucket + ".b.keycloak.db.x"},
// Only the assigner writes seat-holders.
"a.artifact-store-tools": {"$KV.mesh-delivery-assigner_seat-holders.mesh-broker"},
// Only disk-load writes its readings.
+6 -3
View File
@@ -39,13 +39,16 @@ var ConfigResolvedBucket = BucketName("mesh-config", "resolved")
// mesh-config's resolved values; and the seat mesh-provisioner's plans of its machine, `<node>.<module>` (novox/hq ADR
// 0570 clause 2). **Named one by one**, as the controller's asks are: a domain that moves to the
// provisioner adds its bucket here, and a bucket not named is one the client cannot read.
var ProvisionerReads = []string{ConfigResolvedBucket, provisions.PlansBucket}
var ProvisionerReads = []string{ConfigResolvedBucket}
// ProvisionerReadsWhole are the buckets a provisioner client reads every key of: the controller's assignments mirror,
// where a provider's consumers are bound to it in their own machines' plans, which the provider machine's client
// reads to fill ${consumers:<provision>} with each one's credential (novox/hq ADR 0373, issue 679). It holds placement
// and plans, never a secret's value; the client writes none of it.
var ProvisionerReadsWhole = []string{AssignmentsBucket}
// and plans, never a secret's value; the client writes none of it. **The seat's plans are read whole for the same
// reason** (2026-10-30 recovery, issue 774): the client V3 watches every machine's plans to bind a provider's
// consumers, and granted only its own machine's keys it read none. ADR 0570 clause 3 has providers act on the seat's
// provision keys instead; once the client does, plans go back to its own machine's keys.
var ProvisionerReadsWhole = []string{AssignmentsBucket, provisions.PlansBucket}
// BoundState is a providing module's state of entries, one per consumer (mesh-sdk go/provider, issue 678): a
// consumer's machine's client reads its own keys of it, `<node>.<module>.<provision>[.<local>]`, to fill