mesh/merge-gate head d3e182503c19 merged into trunk c8b07242a009 — pass: [release feat/57-config-and-provisioning, judged by its controller fcdecb436117] t…
mesh/repo-check head d3e182503c19 merged into trunk c8b07242a009 — pass: [release feat/57-config-and-provisioning, judged by its controller fcdecb436117] i…
mesh/delivery delivered
Providers, the state bus, templates and the environment collection that the feature's modules build on (feature 57, config and provisioning).
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)
|
|
}
|
|
}
|