diff --git a/agent/agent.go b/agent/agent.go index 13c55b1567..30203224dc 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -151,6 +151,9 @@ type Agent struct { // checkDockers maps the check ID to an associated Docker Exec based check checkDockers map[types.CheckID]*checks.CheckDocker + // checkAliases maps the check ID to an associated Alias checks + checkAliases map[types.CheckID]*checks.CheckAlias + // checkLock protects updates to the check* maps checkLock sync.Mutex @@ -232,6 +235,7 @@ func New(c *config.RuntimeConfig) (*Agent, error) { checkTCPs: make(map[types.CheckID]*checks.CheckTCP), checkGRPCs: make(map[types.CheckID]*checks.CheckGRPC), checkDockers: make(map[types.CheckID]*checks.CheckDocker), + checkAliases: make(map[types.CheckID]*checks.CheckAlias), eventCh: make(chan serf.UserEvent, 1024), eventBuf: make([]*UserEvent, 256), joinLANNotifier: &systemd.Notifier{}, @@ -1329,6 +1333,9 @@ func (a *Agent) ShutdownAgent() error { for _, chk := range a.checkDockers { chk.Stop() } + for _, chk := range a.checkAliases { + chk.Stop() + } // Stop the proxy manager if a.proxyManager != nil { @@ -2017,6 +2024,32 @@ func (a *Agent) AddCheck(check *structs.HealthCheck, chkType *structs.CheckType, monitor.Start() a.checkMonitors[check.CheckID] = monitor + case chkType.IsAlias(): + if existing, ok := a.checkAliases[check.CheckID]; ok { + existing.Stop() + delete(a.checkAliases, check.CheckID) + } + if chkType.Interval < checks.MinInterval { + a.logger.Printf("[WARN] agent: check '%s' has interval below minimum of %v", + check.CheckID, checks.MinInterval) + chkType.Interval = checks.MinInterval + } + + var rpcReq structs.NodeSpecificRequest + rpcReq.Datacenter = a.config.Datacenter + rpcReq.Token = a.tokens.AgentToken() + + chkImpl := &checks.CheckAlias{ + Notify: a.State, + RPC: a.delegate, + RPCReq: rpcReq, + CheckID: check.CheckID, + Node: chkType.AliasNode, + ServiceID: chkType.AliasService, + } + chkImpl.Start() + a.checkAliases[check.CheckID] = chkImpl + default: return fmt.Errorf("Check type is not valid") } diff --git a/agent/agent_test.go b/agent/agent_test.go index f22fc88ff7..702592eb44 100644 --- a/agent/agent_test.go +++ b/agent/agent_test.go @@ -935,6 +935,42 @@ func TestAgent_AddCheck_GRPC(t *testing.T) { } } +func TestAgent_AddCheck_Alias(t *testing.T) { + t.Parallel() + a := NewTestAgent(t.Name(), "") + defer a.Shutdown() + + health := &structs.HealthCheck{ + Node: "foo", + CheckID: "aliashealth", + Name: "Alias health check", + Status: api.HealthCritical, + } + chk := &structs.CheckType{ + AliasService: "foo", + } + err := a.AddCheck(health, chk, false, "") + if err != nil { + t.Fatalf("err: %v", err) + } + + // Ensure we have a check mapping + sChk, ok := a.State.Checks()["aliashealth"] + if !ok { + t.Fatalf("missing aliashealth check") + } + + // Ensure our check is in the right state + if sChk.Status != api.HealthCritical { + t.Fatalf("check not critical") + } + + // Ensure a check is setup + if _, ok := a.checkAliases["aliashealth"]; !ok { + t.Fatalf("missing aliashealth check") + } +} + func TestAgent_RemoveCheck(t *testing.T) { t.Parallel() a := NewTestAgent(t.Name(), `