mesh/merge-gate head 1bc5719b8b85 merged into trunk a2d2af00dc5d beside mesh-host#116@bff1ac14 — pass, with a note: builds mesh-sdk (+40 dependent(s)) → ac…
mesh/repo-check head 1bc5719b8b85 merged into trunk a2d2af00dc5d beside mesh-host#116@bff1ac14 — pass: its merge-check.sh passed, each part in its toolchai…
mesh/delivery delivered
mesh/delivery-group group release/57-config-and-provisioning delivered: every member is delivered
70 lines
3.2 KiB
Go
70 lines
3.2 KiB
Go
package provider
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// The provider reads its consumers' credentials only from the file its machine's provisioner client fills (novox/hq
|
|
// ADR 0373 clause 3, issue 679): one entry per consumer, naming the consumer and the vault's name for its credential,
|
|
// and carrying the value. The helper is wired to it as its Vault and asks nothing of the vault itself.
|
|
func TestTheConsumersFileAnswersEachConsumersCredential(t *testing.T) {
|
|
dir := t.TempDir()
|
|
at := filepath.Join(dir, "consumers.json")
|
|
file := `[{"consumer":"ace","module":"letta","credential":"pair/novox/postgres-database/ace/letta","value":"s3cret"},
|
|
{"consumer":"g14","module":"gitea","local":"cache","credential":"pair/novox/postgres-database/g14/gitea/cache","value":"other"}]`
|
|
if err := os.WriteFile(at, []byte(file), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
v := ConsumersFile{Paths: []string{filepath.Join(dir, "absent.json"), at}}
|
|
got, err := v.Value(context.Background(), PairName("novox", "postgres-database", "ace", "letta", ""))
|
|
if err != nil || string(got) != "s3cret" {
|
|
t.Fatalf("ace's letta: %q, %v; want s3cret", got, err)
|
|
}
|
|
got, err = v.Value(context.Background(), PairName("novox", "postgres-database", "g14", "gitea", "cache"))
|
|
if err != nil || string(got) != "other" {
|
|
t.Fatalf("g14's gitea under cache: %q, %v; want other", got, err)
|
|
}
|
|
// A consumer the file does not carry is waited for, and never told of a login its provider has not made.
|
|
_, err = v.Value(context.Background(), PairName("novox", "postgres-database", "shanks", "photos", ""))
|
|
if err == nil || !strings.Contains(err.Error(), "pair/novox/postgres-database/shanks/photos") {
|
|
t.Fatalf("a consumer the file does not carry: %v", err)
|
|
}
|
|
if strings.Contains(err.Error(), "s3cret") || strings.Contains(err.Error(), "other") {
|
|
t.Fatalf("an error names a credential: %v", err)
|
|
}
|
|
|
|
// Wired as the helper's Vault, the file is what makes each consumer's login.
|
|
bus := newStandIn()
|
|
bus.Put(context.Background(), AssignmentsBucket, "ace.letta", []byte(`{"node":"ace","module":"letta",
|
|
"provisioning":{"provisions":[{"provision":"postgres-database","provider":"novox","provider-module":"postgres"}]}}`))
|
|
var made []string
|
|
p := New(Options{Node: "novox", Module: "postgres", Bus: bus, Vault: v,
|
|
Offers: map[string]Offer{"postgres-database": {Serves: map[string]any{"port": 5432}}},
|
|
Make: func(_ context.Context, c Consumer) error {
|
|
made = append(made, c.Entry.User+"="+string(c.Credential))
|
|
return nil
|
|
}, Logf: func(string, ...any) {}})
|
|
if _, err := p.Pass(context.Background()); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(made) != 1 || made[0] != "mesh_ace_letta=s3cret" {
|
|
t.Fatalf("made %v, want ace's letta under the file's credential", made)
|
|
}
|
|
}
|
|
|
|
// A file that is not the client's form is said, never read as no consumers.
|
|
func TestAConsumersFileNotInItsFormIsRefused(t *testing.T) {
|
|
at := filepath.Join(t.TempDir(), "consumers.json")
|
|
if err := os.WriteFile(at, []byte(`{"not": "a list"}`), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
_, err := ConsumersFile{Paths: []string{at}}.Value(context.Background(), "pair/novox/p/ace/m")
|
|
if err == nil || !strings.Contains(err.Error(), at) {
|
|
t.Fatalf("a file not in the client's form: %v", err)
|
|
}
|
|
}
|