80 lines
2.8 KiB
Go
80 lines
2.8 KiB
Go
//go:build integration
|
|
|
|
package main
|
|
|
|
import (
|
|
"slices"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/novox/mesh-controller/internal/broker"
|
|
"github.com/novox/mesh-controller/internal/catalogue"
|
|
"github.com/novox/mesh-controller/internal/inventory"
|
|
)
|
|
|
|
func TestTheProvisionerClientsAccountIsIssuedForItsServiceAndNeverInvented(t *testing.T) {
|
|
open := aMesh(t)
|
|
ctx := t.Context()
|
|
inv := open.inventory
|
|
m := aProvisioner()
|
|
register(t, open, m)
|
|
if _, err := assign(ctx, open, "laptop", m.Module); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := busCredentialIssued(ctx, inv, "laptop", m.Module, broker.ProvisionerSecret); err == nil {
|
|
t.Fatal("a push would seal a placeholder for the client's account before it was issued")
|
|
}
|
|
|
|
if err := issueProvisionerClient(ctx, inv, m, "laptop", broker.Broker{Fingerprint: "ab"}, "10.0.0.1:4222"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, minted, err := inv.BusUserHash(ctx, "provisioner.laptop"); err != nil || !minted {
|
|
t.Fatalf("the client's account is not minted: %v %v", minted, err)
|
|
}
|
|
states, err := inv.SecretsOf(ctx, "laptop", m.Module)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !slices.ContainsFunc(states, func(s inventory.SecretState) bool { return s.Name == broker.ProvisionerSecret }) {
|
|
t.Fatalf("the client's account is not sealed to the machine for its service: %+v", states)
|
|
}
|
|
if err := busCredentialIssued(ctx, inv, "laptop", m.Module, broker.ProvisionerSecret); err != nil {
|
|
t.Fatalf("an issued client account is refused: %v", err)
|
|
}
|
|
if !runsTheProvisionerClient(m) {
|
|
t.Fatal("the module is not read as running the client")
|
|
}
|
|
unread := m
|
|
unread.OwnSecrets = catalogue.OwnSecrets{"broker": {Path: "/run/broker"}}
|
|
if runsTheProvisionerClient(unread) {
|
|
t.Fatal("a module with nowhere to read the client's account is read as running it")
|
|
}
|
|
}
|
|
|
|
func TestAssigningTheClientIssuesItsAccount(t *testing.T) {
|
|
open := aMesh(t)
|
|
ctx := t.Context()
|
|
client := aClientModule()
|
|
register(t, open, client)
|
|
out, err := assign(ctx, open, "laptop", client.Module)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !strings.Contains(out, "bus credential") {
|
|
t.Fatalf("assigning the client said nothing of its account:\n%s", out)
|
|
}
|
|
}
|
|
|
|
// A module that runs the client and declares no broker of its own, as the catalogue's mesh-provisioner-client does,
|
|
// may be issued: the client's account alone (issue 917). Before, `module issue` refused it for having no broker,
|
|
// while a push refused it for having no account, so no machine could run the client.
|
|
func TestAClientWithoutABrokerOfItsOwnMayBeIssued(t *testing.T) {
|
|
if err := mayIssue(aClientModule()); err != nil {
|
|
t.Fatalf("the client alone is refused an account: %v", err)
|
|
}
|
|
neither := aBot("bot", false)
|
|
if err := mayIssue(neither); err == nil {
|
|
t.Fatal("a module with nowhere to read any account may be issued one")
|
|
}
|
|
}
|