Provision and provider users take the provisioner's client; mesh-vault writes its findings through the conditions client (K-4..K-20, K-21 part; ADR 0634 §4; issue 1966)

This commit is contained in:
2026-11-05 14:26:48 +01:00
parent 7c617bb085
commit e8f93d5db0
45 changed files with 264 additions and 244 deletions
@@ -14,7 +14,7 @@ import (
"sync"
"testing"
"git.novox.be/novox/mesh-sdk/go/provider"
"git.novox.be/novox/mesh-contracts/provisioning/go/clients/meshprovisionerclient/provider"
"gitea/internal/forgehttp"
)
@@ -29,8 +29,8 @@ import (
"github.com/nats-io/nats.go"
"github.com/nats-io/nats.go/jetstream"
"git.novox.be/novox/mesh-sdk/go/provider"
"git.novox.be/novox/mesh-sdk/go/provisions"
"git.novox.be/novox/mesh-contracts/provisioning/go/clients/meshprovisionerclient"
"git.novox.be/novox/mesh-contracts/provisioning/go/clients/meshprovisionerclient/provider"
)
const bundleVar = "MESH_FORGE_ACCOUNT_TEST_BUNDLE"
@@ -301,7 +301,7 @@ func TestTheProviderWholeAnswersAMachineThatReportedItsKey(t *testing.T) {
"plan": map[string]any{"provisions": []map[string]any{{"provision": "forge-account", "provider": "novox",
"provider-module": "gitea", "as": "mesh_g14_ssh_client"}}}})
rt.put("mesh-provisioner.provisions", "g14.ssh-client.forge-account",
json.RawMessage(provisionKey("g14", "ssh-client", provisions.Asked, nil)))
json.RawMessage(provisionKey("g14", "ssh-client", meshprovisionerclient.Asked, nil)))
rt.put("ssh-client.keys", "g14.nox", map[string]string{"node": "g14", "account": "nox", "kind": "machine",
"public": pubA + " nox@g14 (mesh)", "fingerprint": "SHA256:x", "at": "2026-10-16T10:00:00Z"})
rt.start([]string{"MESH_NODE=novox", "MESH_MODULE=gitea", "MESH_SERVED_MODULE=gitea",
@@ -22,8 +22,8 @@ import (
"sync"
"time"
"git.novox.be/novox/mesh-contracts/provisioning/go/clients/meshprovisionerclient/provider"
stdio "git.novox.be/novox/mesh-sdk/go"
"git.novox.be/novox/mesh-sdk/go/provider"
"gitea/internal/forgeaccount"
"gitea/internal/forgehttp"
@@ -12,7 +12,7 @@ import (
"sync"
"time"
"git.novox.be/novox/mesh-sdk/go/provider"
"git.novox.be/novox/mesh-contracts/provisioning/go/clients/meshprovisionerclient/provider"
"gitea/internal/forgeaccount"
"gitea/internal/forgehttp"
@@ -16,8 +16,8 @@ import (
"testing"
"time"
"git.novox.be/novox/mesh-sdk/go/provider"
"git.novox.be/novox/mesh-sdk/go/provisions"
"git.novox.be/novox/mesh-contracts/provisioning/go/clients/meshprovisionerclient"
"git.novox.be/novox/mesh-contracts/provisioning/go/clients/meshprovisionerclient/provider"
"gitea/internal/forgehttp"
)
@@ -84,7 +84,7 @@ func (b *fakeBus) entry(t *testing.T, key string) provider.Entry {
// values (ADR 0570 clause 3: an entry the provider could not make is kept, failed, serving nothing; one it is not
// ready to make waits and keeps serving).
func (b *fakeBus) serves(key string, state ...string) bool {
want := provisions.Provided
want := meshprovisionerclient.Provided
if len(state) > 0 {
want = state[0]
}
@@ -110,29 +110,29 @@ func (b *fakeBus) bindClient(node string) {
// bindPlan makes module on node bind gitea's forge-account as the seat mesh-provisioner keeps it: its plan, and the
// provision key asked of gitea on novox (novox/hq ADR 0570 clauses 1 to 3).
func (b *fakeBus) bindPlan(node, module, as string) {
b.set(provisions.PlansBucket, node+"."+module, []byte(fmt.Sprintf(
b.set(meshprovisionerclient.PlansBucket, node+"."+module, []byte(fmt.Sprintf(
`{"v":1,"node":%q,"module":%q,"plan":{"provisions":[{"provision":"forge-account","provider":"novox","provider-module":"gitea","as":%q}]}}`,
node, module, as)))
b.set(provisions.ProvisionsBucket, node+"."+module+".forge-account", provisionKey(node, module, provisions.Asked, nil))
b.set(meshprovisionerclient.ProvisionsBucket, node+"."+module+".forge-account", provisionKey(node, module, meshprovisionerclient.Asked, nil))
}
// retire is the operator's yes to the retiring of module's forge-account on node: its plan gone, its key retiring
// with the warrant (ADR 0570 clause 5), the only way the provider lets an entry go.
func (b *fakeBus) retire(node, module string) {
b.mu.Lock()
delete(b.buckets[provisions.PlansBucket], node+"."+module)
delete(b.buckets[meshprovisionerclient.PlansBucket], node+"."+module)
b.mu.Unlock()
b.set(provisions.ProvisionsBucket, node+"."+module+".forge-account", provisionKey(node, module, provisions.Retiring,
&provisions.Warrant{Ask: "ask-1", Option: "yes", By: "operator", At: time.Date(2026, 10, 29, 12, 0, 0, 0, time.UTC)}))
b.set(meshprovisionerclient.ProvisionsBucket, node+"."+module+".forge-account", provisionKey(node, module, meshprovisionerclient.Retiring,
&meshprovisionerclient.Warrant{Ask: "ask-1", Option: "yes", By: "operator", At: time.Date(2026, 10, 29, 12, 0, 0, 0, time.UTC)}))
}
func provisionKey(node, module, state string, w *provisions.Warrant) []byte {
pr := provisions.Provision{Provision: "forge-account", State: state, Warrant: w,
Consumer: provisions.End{Node: node, Module: module}, Provider: provisions.End{Node: "novox", Module: "gitea"}}
if state == provisions.Retiring {
func provisionKey(node, module, state string, w *meshprovisionerclient.Warrant) []byte {
pr := meshprovisionerclient.Provision{Provision: "forge-account", State: state, Warrant: w,
Consumer: meshprovisionerclient.End{Node: node, Module: module}, Provider: meshprovisionerclient.End{Node: "novox", Module: "gitea"}}
if state == meshprovisionerclient.Retiring {
pr.Why = "no want needs it"
}
raw, err := provisions.Encode(pr)
raw, err := meshprovisionerclient.Encode(pr)
if err != nil {
panic(err)
}
@@ -527,7 +527,7 @@ func TestAPassBeforeTheKeysAreLoadedRemovesAndDeletesNothing(t *testing.T) {
if got := strings.Join(r.forge.titles("nox-agent"), ","); got != "mesh:g14.nox,my own" {
t.Fatalf("keys = %s", got)
}
if !r.bus.serves("g14.ssh-client.forge-account", provisions.Waits) {
if !r.bus.serves("g14.ssh-client.forge-account", meshprovisionerclient.Waits) {
t.Fatal("the entry stopped serving before the keys were read; it waits and keeps serving")
}
if len(out) != 1 || !strings.Contains(out[0].Why, "not read yet") {