Remove a machine's mesh keys and entry when its key is no longer reported (issue 955 F)
This commit is contained in:
@@ -66,6 +66,8 @@ type Service struct {
|
||||
keys map[string]machineKey
|
||||
known string // the forge's host key line, as the machines write it into known_hosts
|
||||
|
||||
bound provider.Bus // the bus the entries are written to (set by Provider)
|
||||
|
||||
making sync.Mutex // one Make at a time: they register keys, and two at once would race each other
|
||||
}
|
||||
|
||||
@@ -85,10 +87,12 @@ func NewService(cfg Config) *Service {
|
||||
// Provider is the provider helper answering the consumers over bus. Every consumer is made again every ten minutes,
|
||||
// which puts back an account, its team or a key changed by hand.
|
||||
func (s *Service) Provider(bus provider.Bus) *provider.Provider {
|
||||
vb := &valuesBus{Bus: bus, s: s, written: map[string][]byte{}}
|
||||
s.bound = vb
|
||||
return provider.New(provider.Options{
|
||||
Node: s.cfg.Node, Module: Module,
|
||||
Offers: map[string]provider.Offer{ProvisionName: {Credential: provider.NoCredential}},
|
||||
Bus: &valuesBus{Bus: bus, s: s, written: map[string][]byte{}},
|
||||
Bus: vb,
|
||||
Make: s.Make, Gone: s.Gone,
|
||||
Every: 10 * time.Minute,
|
||||
Logf: s.cfg.Log,
|
||||
@@ -115,6 +119,16 @@ func (s *Service) Make(ctx context.Context, c provider.Consumer) error {
|
||||
}
|
||||
have := s.keysOf(node)
|
||||
if len(have) == 0 {
|
||||
// A key the machine no longer reports is no longer wanted (ADR 0400 §2): the mesh's keys go, the operator's
|
||||
// stay, and the entry that served the machine goes with them.
|
||||
if err := s.accounts.RemoveKeysTitled(ctx, user, forgeaccount.TitlePrefix+node+"."); err != nil {
|
||||
return err
|
||||
}
|
||||
if s.bound != nil {
|
||||
if err := s.bound.Delete(ctx, provider.BucketOf(Module), c.Entry.Key()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return errNoKey{node}
|
||||
}
|
||||
if _, err := s.hostName(); err != nil {
|
||||
|
||||
@@ -415,3 +415,21 @@ func (f *fakeKeys) Watch(handle func(key, op string, value []byte, current bool)
|
||||
return nil
|
||||
}
|
||||
func (f *fakeKeys) send(key, op string, v []byte, current bool) { f.handle(key, op, v, current) }
|
||||
|
||||
func TestADeletedKeyEntryRemovesTheMeshKeyAndTheBoundEntryButNotTheOperatorsKey(t *testing.T) {
|
||||
r := newRig(t)
|
||||
r.bus.bindClient("g14")
|
||||
r.key("g14", "nox", pubA+" nox@g14 (mesh)")
|
||||
r.pass()
|
||||
r.forge.mu.Lock()
|
||||
r.forge.held["agent-g14"] = append(r.forge.held["agent-g14"], map[string]any{"id": int64(99), "title": "my own", "key": pubB})
|
||||
r.forge.mu.Unlock()
|
||||
r.svc.KeyGone("g14.nox")
|
||||
r.pass()
|
||||
if got := r.forge.titles("agent-g14"); len(got) != 1 || got[0] != "my own" {
|
||||
t.Fatalf("keys = %v", got)
|
||||
}
|
||||
if r.bus.has("g14.ssh-client.forge-account") {
|
||||
t.Fatal("the entry still serves a machine whose key is gone")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user