github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/apiserver/facades/controller/firewaller/modelfirewallruleswatcher.go (about) 1 // Copyright 2023 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package firewaller 5 6 import ( 7 "github.com/juju/collections/set" 8 "github.com/juju/errors" 9 "github.com/juju/worker/v3/catacomb" 10 ) 11 12 type modelFirewallRulesWatcher struct { 13 catacomb catacomb.Catacomb 14 backend State 15 16 out chan struct{} 17 18 sshAllowCache set.Strings 19 } 20 21 // NewModelFirewallRulesWatcher returns a worker that notifies when a change to something 22 // determining the model firewall rules takes place 23 // 24 // NOTE: At this time, ssh-allow model config item is the only thing that needs to be watched 25 func NewModelFirewallRulesWatcher(st State) (*modelFirewallRulesWatcher, error) { 26 w := &modelFirewallRulesWatcher{ 27 backend: st, 28 out: make(chan struct{}), 29 } 30 31 err := catacomb.Invoke(catacomb.Plan{ 32 Site: &w.catacomb, 33 Work: w.loop, 34 }) 35 return w, err 36 } 37 38 func (w *modelFirewallRulesWatcher) loop() error { 39 defer close(w.out) 40 41 configWatcher := w.backend.WatchForModelConfigChanges() 42 if err := w.catacomb.Add(configWatcher); err != nil { 43 return errors.Trace(err) 44 } 45 46 var out chan struct{} 47 48 for { 49 select { 50 case <-w.catacomb.Dying(): 51 return w.catacomb.ErrDying() 52 case out <- struct{}{}: 53 out = nil 54 case _, ok := <-configWatcher.Changes(): 55 if !ok { 56 return w.catacomb.ErrDying() 57 } 58 cfg, err := w.backend.ModelConfig() 59 if err != nil { 60 return errors.Trace(err) 61 } 62 sshAllow := set.NewStrings(cfg.SSHAllow()...) 63 if !setEquals(sshAllow, w.sshAllowCache) { 64 out = w.out 65 w.sshAllowCache = sshAllow 66 } 67 } 68 } 69 } 70 71 func (w *modelFirewallRulesWatcher) Changes() <-chan struct{} { 72 return w.out 73 } 74 75 func (w *modelFirewallRulesWatcher) Kill() { 76 w.catacomb.Kill(nil) 77 } 78 79 func (w *modelFirewallRulesWatcher) Wait() error { 80 return w.catacomb.Wait() 81 } 82 83 func (w *modelFirewallRulesWatcher) Stop() error { 84 w.Kill() 85 return w.Wait() 86 } 87 88 func (w *modelFirewallRulesWatcher) Err() error { 89 return w.catacomb.Err() 90 }