agent: move structs into consul/structs pkg

* CheckDefinition
 * ServiceDefinition
 * CheckType
This commit is contained in:
Frank Schroeder 2017-06-15 18:46:06 +02:00 committed by Frank Schröder
parent 4273fb8444
commit c49a15d0f3
12 changed files with 241 additions and 227 deletions

View File

@ -1342,6 +1342,13 @@ func (a *Agent) reapServices() {
} }
// persistedService is used to wrap a service definition and bundle it
// with an ACL token so we can restore both at a later agent start.
type persistedService struct {
Token string
Service *structs.NodeService
}
// persistService saves a service definition to a JSON file in the data dir // persistService saves a service definition to a JSON file in the data dir
func (a *Agent) persistService(service *structs.NodeService) error { func (a *Agent) persistService(service *structs.NodeService) error {
svcPath := filepath.Join(a.config.DataDir, servicesDir, stringHash(service.ID)) svcPath := filepath.Join(a.config.DataDir, servicesDir, stringHash(service.ID))
@ -1368,7 +1375,7 @@ func (a *Agent) purgeService(serviceID string) error {
} }
// persistCheck saves a check definition to the local agent's state directory // persistCheck saves a check definition to the local agent's state directory
func (a *Agent) persistCheck(check *structs.HealthCheck, chkType *CheckType) error { func (a *Agent) persistCheck(check *structs.HealthCheck, chkType *structs.CheckType) error {
checkPath := filepath.Join(a.config.DataDir, checksDir, checkIDHash(check.CheckID)) checkPath := filepath.Join(a.config.DataDir, checksDir, checkIDHash(check.CheckID))
// Create the persisted check // Create the persisted check
@ -1426,7 +1433,7 @@ func writeFileAtomic(path string, contents []byte) error {
// AddService is used to add a service entry. // AddService is used to add a service entry.
// This entry is persistent and the agent will make a best effort to // This entry is persistent and the agent will make a best effort to
// ensure it is registered // ensure it is registered
func (a *Agent) AddService(service *structs.NodeService, chkTypes CheckTypes, persist bool, token string) error { func (a *Agent) AddService(service *structs.NodeService, chkTypes []*structs.CheckType, persist bool, token string) error {
if service.Service == "" { if service.Service == "" {
return fmt.Errorf("Service name missing") return fmt.Errorf("Service name missing")
} }
@ -1552,7 +1559,7 @@ func (a *Agent) RemoveService(serviceID string, persist bool) error {
// This entry is persistent and the agent will make a best effort to // This entry is persistent and the agent will make a best effort to
// ensure it is registered. The Check may include a CheckType which // ensure it is registered. The Check may include a CheckType which
// is used to automatically update the check status // is used to automatically update the check status
func (a *Agent) AddCheck(check *structs.HealthCheck, chkType *CheckType, persist bool, token string) error { func (a *Agent) AddCheck(check *structs.HealthCheck, chkType *structs.CheckType, persist bool, token string) error {
if check.CheckID == "" { if check.CheckID == "" {
return fmt.Errorf("CheckID missing") return fmt.Errorf("CheckID missing")
} }

View File

@ -230,7 +230,7 @@ func (s *HTTPServer) syncChanges() {
const invalidCheckMessage = "Must provide TTL or Script/DockerContainerID/HTTP/TCP and Interval" const invalidCheckMessage = "Must provide TTL or Script/DockerContainerID/HTTP/TCP and Interval"
func (s *HTTPServer) AgentRegisterCheck(resp http.ResponseWriter, req *http.Request) (interface{}, error) { func (s *HTTPServer) AgentRegisterCheck(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
var args CheckDefinition var args structs.CheckDefinition
// Fixup the type decode of TTL or Interval. // Fixup the type decode of TTL or Interval.
decodeCB := func(raw interface{}) error { decodeCB := func(raw interface{}) error {
return FixupCheckType(raw) return FixupCheckType(raw)
@ -412,7 +412,7 @@ func (s *HTTPServer) AgentCheckUpdate(resp http.ResponseWriter, req *http.Reques
} }
func (s *HTTPServer) AgentRegisterService(resp http.ResponseWriter, req *http.Request) (interface{}, error) { func (s *HTTPServer) AgentRegisterService(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
var args ServiceDefinition var args structs.ServiceDefinition
// Fixup the type decode of TTL or Interval if a check if provided. // Fixup the type decode of TTL or Interval if a check if provided.
decodeCB := func(raw interface{}) error { decodeCB := func(raw interface{}) error {
rawMap, ok := raw.(map[string]interface{}) rawMap, ok := raw.(map[string]interface{})

View File

@ -234,8 +234,8 @@ func TestAgent_Reload(t *testing.T) {
t.Parallel() t.Parallel()
cfg := TestConfig() cfg := TestConfig()
cfg.ACLEnforceVersion8 = Bool(false) cfg.ACLEnforceVersion8 = Bool(false)
cfg.Services = []*ServiceDefinition{ cfg.Services = []*structs.ServiceDefinition{
&ServiceDefinition{Name: "redis"}, &structs.ServiceDefinition{Name: "redis"},
} }
a := NewTestAgent(t.Name(), cfg) a := NewTestAgent(t.Name(), cfg)
defer a.Shutdown() defer a.Shutdown()
@ -246,8 +246,8 @@ func TestAgent_Reload(t *testing.T) {
cfg2 := TestConfig() cfg2 := TestConfig()
cfg2.ACLEnforceVersion8 = Bool(false) cfg2.ACLEnforceVersion8 = Bool(false)
cfg2.Services = []*ServiceDefinition{ cfg2.Services = []*structs.ServiceDefinition{
&ServiceDefinition{Name: "redis-reloaded"}, &structs.ServiceDefinition{Name: "redis-reloaded"},
} }
ok, err := a.ReloadConfig(cfg2) ok, err := a.ReloadConfig(cfg2)
@ -580,7 +580,7 @@ func TestAgent_RegisterCheck(t *testing.T) {
defer a.Shutdown() defer a.Shutdown()
// Register node // Register node
args := &CheckDefinition{ args := &structs.CheckDefinition{
Name: "test", Name: "test",
TTL: 15 * time.Second, TTL: 15 * time.Second,
} }
@ -621,7 +621,7 @@ func TestAgent_RegisterCheck_Passing(t *testing.T) {
defer a.Shutdown() defer a.Shutdown()
// Register node // Register node
args := &CheckDefinition{ args := &structs.CheckDefinition{
Name: "test", Name: "test",
TTL: 15 * time.Second, TTL: 15 * time.Second,
Status: api.HealthPassing, Status: api.HealthPassing,
@ -657,7 +657,7 @@ func TestAgent_RegisterCheck_BadStatus(t *testing.T) {
defer a.Shutdown() defer a.Shutdown()
// Register node // Register node
args := &CheckDefinition{ args := &structs.CheckDefinition{
Name: "test", Name: "test",
TTL: 15 * time.Second, TTL: 15 * time.Second,
Status: "fluffy", Status: "fluffy",
@ -677,7 +677,7 @@ func TestAgent_RegisterCheck_ACLDeny(t *testing.T) {
a := NewTestAgent(t.Name(), TestACLConfig()) a := NewTestAgent(t.Name(), TestACLConfig())
defer a.Shutdown() defer a.Shutdown()
args := &CheckDefinition{ args := &structs.CheckDefinition{
Name: "test", Name: "test",
TTL: 15 * time.Second, TTL: 15 * time.Second,
} }
@ -754,7 +754,7 @@ func TestAgent_PassCheck(t *testing.T) {
defer a.Shutdown() defer a.Shutdown()
chk := &structs.HealthCheck{Name: "test", CheckID: "test"} chk := &structs.HealthCheck{Name: "test", CheckID: "test"}
chkType := &CheckType{TTL: 15 * time.Second} chkType := &structs.CheckType{TTL: 15 * time.Second}
if err := a.AddCheck(chk, chkType, false, ""); err != nil { if err := a.AddCheck(chk, chkType, false, ""); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -781,7 +781,7 @@ func TestAgent_PassCheck_ACLDeny(t *testing.T) {
defer a.Shutdown() defer a.Shutdown()
chk := &structs.HealthCheck{Name: "test", CheckID: "test"} chk := &structs.HealthCheck{Name: "test", CheckID: "test"}
chkType := &CheckType{TTL: 15 * time.Second} chkType := &structs.CheckType{TTL: 15 * time.Second}
if err := a.AddCheck(chk, chkType, false, ""); err != nil { if err := a.AddCheck(chk, chkType, false, ""); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -807,7 +807,7 @@ func TestAgent_WarnCheck(t *testing.T) {
defer a.Shutdown() defer a.Shutdown()
chk := &structs.HealthCheck{Name: "test", CheckID: "test"} chk := &structs.HealthCheck{Name: "test", CheckID: "test"}
chkType := &CheckType{TTL: 15 * time.Second} chkType := &structs.CheckType{TTL: 15 * time.Second}
if err := a.AddCheck(chk, chkType, false, ""); err != nil { if err := a.AddCheck(chk, chkType, false, ""); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -834,7 +834,7 @@ func TestAgent_WarnCheck_ACLDeny(t *testing.T) {
defer a.Shutdown() defer a.Shutdown()
chk := &structs.HealthCheck{Name: "test", CheckID: "test"} chk := &structs.HealthCheck{Name: "test", CheckID: "test"}
chkType := &CheckType{TTL: 15 * time.Second} chkType := &structs.CheckType{TTL: 15 * time.Second}
if err := a.AddCheck(chk, chkType, false, ""); err != nil { if err := a.AddCheck(chk, chkType, false, ""); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -860,7 +860,7 @@ func TestAgent_FailCheck(t *testing.T) {
defer a.Shutdown() defer a.Shutdown()
chk := &structs.HealthCheck{Name: "test", CheckID: "test"} chk := &structs.HealthCheck{Name: "test", CheckID: "test"}
chkType := &CheckType{TTL: 15 * time.Second} chkType := &structs.CheckType{TTL: 15 * time.Second}
if err := a.AddCheck(chk, chkType, false, ""); err != nil { if err := a.AddCheck(chk, chkType, false, ""); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -887,7 +887,7 @@ func TestAgent_FailCheck_ACLDeny(t *testing.T) {
defer a.Shutdown() defer a.Shutdown()
chk := &structs.HealthCheck{Name: "test", CheckID: "test"} chk := &structs.HealthCheck{Name: "test", CheckID: "test"}
chkType := &CheckType{TTL: 15 * time.Second} chkType := &structs.CheckType{TTL: 15 * time.Second}
if err := a.AddCheck(chk, chkType, false, ""); err != nil { if err := a.AddCheck(chk, chkType, false, ""); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -913,7 +913,7 @@ func TestAgent_UpdateCheck(t *testing.T) {
defer a.Shutdown() defer a.Shutdown()
chk := &structs.HealthCheck{Name: "test", CheckID: "test"} chk := &structs.HealthCheck{Name: "test", CheckID: "test"}
chkType := &CheckType{TTL: 15 * time.Second} chkType := &structs.CheckType{TTL: 15 * time.Second}
if err := a.AddCheck(chk, chkType, false, ""); err != nil { if err := a.AddCheck(chk, chkType, false, ""); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -1012,7 +1012,7 @@ func TestAgent_UpdateCheck_ACLDeny(t *testing.T) {
defer a.Shutdown() defer a.Shutdown()
chk := &structs.HealthCheck{Name: "test", CheckID: "test"} chk := &structs.HealthCheck{Name: "test", CheckID: "test"}
chkType := &CheckType{TTL: 15 * time.Second} chkType := &structs.CheckType{TTL: 15 * time.Second}
if err := a.AddCheck(chk, chkType, false, ""); err != nil { if err := a.AddCheck(chk, chkType, false, ""); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -1039,18 +1039,18 @@ func TestAgent_RegisterService(t *testing.T) {
a := NewTestAgent(t.Name(), nil) a := NewTestAgent(t.Name(), nil)
defer a.Shutdown() defer a.Shutdown()
args := &ServiceDefinition{ args := &structs.ServiceDefinition{
Name: "test", Name: "test",
Tags: []string{"master"}, Tags: []string{"master"},
Port: 8000, Port: 8000,
Check: CheckType{ Check: structs.CheckType{
TTL: 15 * time.Second, TTL: 15 * time.Second,
}, },
Checks: CheckTypes{ Checks: []*structs.CheckType{
&CheckType{ &structs.CheckType{
TTL: 20 * time.Second, TTL: 20 * time.Second,
}, },
&CheckType{ &structs.CheckType{
TTL: 30 * time.Second, TTL: 30 * time.Second,
}, },
}, },
@ -1091,18 +1091,18 @@ func TestAgent_RegisterService_ACLDeny(t *testing.T) {
a := NewTestAgent(t.Name(), TestACLConfig()) a := NewTestAgent(t.Name(), TestACLConfig())
defer a.Shutdown() defer a.Shutdown()
args := &ServiceDefinition{ args := &structs.ServiceDefinition{
Name: "test", Name: "test",
Tags: []string{"master"}, Tags: []string{"master"},
Port: 8000, Port: 8000,
Check: CheckType{ Check: structs.CheckType{
TTL: 15 * time.Second, TTL: 15 * time.Second,
}, },
Checks: CheckTypes{ Checks: []*structs.CheckType{
&CheckType{ &structs.CheckType{
TTL: 20 * time.Second, TTL: 20 * time.Second,
}, },
&CheckType{ &structs.CheckType{
TTL: 30 * time.Second, TTL: 30 * time.Second,
}, },
}, },
@ -1130,7 +1130,7 @@ func TestAgent_RegisterService_InvalidAddress(t *testing.T) {
for _, addr := range []string{"0.0.0.0", "::", "[::]"} { for _, addr := range []string{"0.0.0.0", "::", "[::]"} {
t.Run("addr "+addr, func(t *testing.T) { t.Run("addr "+addr, func(t *testing.T) {
args := &ServiceDefinition{ args := &structs.ServiceDefinition{
Name: "test", Name: "test",
Address: addr, Address: addr,
Port: 8000, Port: 8000,
@ -1475,10 +1475,10 @@ func TestAgent_RegisterCheck_Service(t *testing.T) {
a := NewTestAgent(t.Name(), nil) a := NewTestAgent(t.Name(), nil)
defer a.Shutdown() defer a.Shutdown()
args := &ServiceDefinition{ args := &structs.ServiceDefinition{
Name: "memcache", Name: "memcache",
Port: 8000, Port: 8000,
Check: CheckType{ Check: structs.CheckType{
TTL: 15 * time.Second, TTL: 15 * time.Second,
}, },
} }
@ -1490,7 +1490,7 @@ func TestAgent_RegisterCheck_Service(t *testing.T) {
} }
// Now register an additional check // Now register an additional check
checkArgs := &CheckDefinition{ checkArgs := &structs.CheckDefinition{
Name: "memcache_check2", Name: "memcache_check2",
ServiceID: "memcache", ServiceID: "memcache",
TTL: 15 * time.Second, TTL: 15 * time.Second,

View File

@ -336,7 +336,7 @@ func TestAgent_AddService(t *testing.T) {
tests := []struct { tests := []struct {
desc string desc string
srv *structs.NodeService srv *structs.NodeService
chkTypes CheckTypes chkTypes []*structs.CheckType
healthChks map[string]*structs.HealthCheck healthChks map[string]*structs.HealthCheck
}{ }{
{ {
@ -347,8 +347,8 @@ func TestAgent_AddService(t *testing.T) {
Tags: []string{"tag1"}, Tags: []string{"tag1"},
Port: 8100, Port: 8100,
}, },
CheckTypes{ []*structs.CheckType{
&CheckType{ &structs.CheckType{
CheckID: "check1", CheckID: "check1",
Name: "name1", Name: "name1",
TTL: time.Minute, TTL: time.Minute,
@ -375,22 +375,22 @@ func TestAgent_AddService(t *testing.T) {
Tags: []string{"tag2"}, Tags: []string{"tag2"},
Port: 8200, Port: 8200,
}, },
CheckTypes{ []*structs.CheckType{
&CheckType{ &structs.CheckType{
CheckID: "check1", CheckID: "check1",
Name: "name1", Name: "name1",
TTL: time.Minute, TTL: time.Minute,
Notes: "note1", Notes: "note1",
}, },
&CheckType{ &structs.CheckType{
CheckID: "check-noname", CheckID: "check-noname",
TTL: time.Minute, TTL: time.Minute,
}, },
&CheckType{ &structs.CheckType{
Name: "check-noid", Name: "check-noid",
TTL: time.Minute, TTL: time.Minute,
}, },
&CheckType{ &structs.CheckType{
TTL: time.Minute, TTL: time.Minute,
}, },
}, },
@ -499,14 +499,14 @@ func TestAgent_RemoveService(t *testing.T) {
Service: "memcache", Service: "memcache",
Port: 8000, Port: 8000,
} }
chkTypes := CheckTypes{&CheckType{TTL: time.Minute}} chkTypes := []*structs.CheckType{&structs.CheckType{TTL: time.Minute}}
if err := a.AddService(srv, chkTypes, false, ""); err != nil { if err := a.AddService(srv, chkTypes, false, ""); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
// Add a check after the fact with a specific check ID // Add a check after the fact with a specific check ID
check := &CheckDefinition{ check := &structs.CheckDefinition{
ID: "check2", ID: "check2",
Name: "check2", Name: "check2",
ServiceID: "memcache", ServiceID: "memcache",
@ -535,9 +535,9 @@ func TestAgent_RemoveService(t *testing.T) {
Service: "redis", Service: "redis",
Port: 8000, Port: 8000,
} }
chkTypes := CheckTypes{ chkTypes := []*structs.CheckType{
&CheckType{TTL: time.Minute}, &structs.CheckType{TTL: time.Minute},
&CheckType{TTL: 30 * time.Second}, &structs.CheckType{TTL: 30 * time.Second},
} }
if err := a.AddService(srv, chkTypes, false, ""); err != nil { if err := a.AddService(srv, chkTypes, false, ""); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
@ -579,13 +579,13 @@ func TestAgent_RemoveServiceRemovesAllChecks(t *testing.T) {
defer a.Shutdown() defer a.Shutdown()
svc := &structs.NodeService{ID: "redis", Service: "redis", Port: 8000} svc := &structs.NodeService{ID: "redis", Service: "redis", Port: 8000}
chk1 := &CheckType{CheckID: "chk1", Name: "chk1", TTL: time.Minute} chk1 := &structs.CheckType{CheckID: "chk1", Name: "chk1", TTL: time.Minute}
chk2 := &CheckType{CheckID: "chk2", Name: "chk2", TTL: 2 * time.Minute} chk2 := &structs.CheckType{CheckID: "chk2", Name: "chk2", TTL: 2 * time.Minute}
hchk1 := &structs.HealthCheck{Node: "node1", CheckID: "chk1", Name: "chk1", Status: "critical", ServiceID: "redis", ServiceName: "redis"} hchk1 := &structs.HealthCheck{Node: "node1", CheckID: "chk1", Name: "chk1", Status: "critical", ServiceID: "redis", ServiceName: "redis"}
hchk2 := &structs.HealthCheck{Node: "node1", CheckID: "chk2", Name: "chk2", Status: "critical", ServiceID: "redis", ServiceName: "redis"} hchk2 := &structs.HealthCheck{Node: "node1", CheckID: "chk2", Name: "chk2", Status: "critical", ServiceID: "redis", ServiceName: "redis"}
// register service with chk1 // register service with chk1
if err := a.AddService(svc, CheckTypes{chk1}, false, ""); err != nil { if err := a.AddService(svc, []*structs.CheckType{chk1}, false, ""); err != nil {
t.Fatal("Failed to register service", err) t.Fatal("Failed to register service", err)
} }
@ -595,7 +595,7 @@ func TestAgent_RemoveServiceRemovesAllChecks(t *testing.T) {
} }
// update the service with chk2 // update the service with chk2
if err := a.AddService(svc, CheckTypes{chk2}, false, ""); err != nil { if err := a.AddService(svc, []*structs.CheckType{chk2}, false, ""); err != nil {
t.Fatal("Failed to update service", err) t.Fatal("Failed to update service", err)
} }
@ -632,7 +632,7 @@ func TestAgent_AddCheck(t *testing.T) {
Name: "memory util", Name: "memory util",
Status: api.HealthCritical, Status: api.HealthCritical,
} }
chk := &CheckType{ chk := &structs.CheckType{
Script: "exit 0", Script: "exit 0",
Interval: 15 * time.Second, Interval: 15 * time.Second,
} }
@ -669,7 +669,7 @@ func TestAgent_AddCheck_StartPassing(t *testing.T) {
Name: "memory util", Name: "memory util",
Status: api.HealthPassing, Status: api.HealthPassing,
} }
chk := &CheckType{ chk := &structs.CheckType{
Script: "exit 0", Script: "exit 0",
Interval: 15 * time.Second, Interval: 15 * time.Second,
} }
@ -706,7 +706,7 @@ func TestAgent_AddCheck_MinInterval(t *testing.T) {
Name: "memory util", Name: "memory util",
Status: api.HealthCritical, Status: api.HealthCritical,
} }
chk := &CheckType{ chk := &structs.CheckType{
Script: "exit 0", Script: "exit 0",
Interval: time.Microsecond, Interval: time.Microsecond,
} }
@ -739,7 +739,7 @@ func TestAgent_AddCheck_MissingService(t *testing.T) {
Name: "baz check 1", Name: "baz check 1",
ServiceID: "baz", ServiceID: "baz",
} }
chk := &CheckType{ chk := &structs.CheckType{
Script: "exit 0", Script: "exit 0",
Interval: time.Microsecond, Interval: time.Microsecond,
} }
@ -770,7 +770,7 @@ func TestAgent_AddCheck_RestoreState(t *testing.T) {
CheckID: "baz", CheckID: "baz",
Name: "baz check 1", Name: "baz check 1",
} }
chk := &CheckType{ chk := &structs.CheckType{
TTL: time.Minute, TTL: time.Minute,
} }
err = a.AddCheck(health, chk, false, "") err = a.AddCheck(health, chk, false, "")
@ -813,7 +813,7 @@ func TestAgent_RemoveCheck(t *testing.T) {
Name: "memory util", Name: "memory util",
Status: api.HealthCritical, Status: api.HealthCritical,
} }
chk := &CheckType{ chk := &structs.CheckType{
Script: "exit 0", Script: "exit 0",
Interval: 15 * time.Second, Interval: 15 * time.Second,
} }
@ -849,7 +849,7 @@ func TestAgent_updateTTLCheck(t *testing.T) {
Name: "memory util", Name: "memory util",
Status: api.HealthCritical, Status: api.HealthCritical,
} }
chk := &CheckType{ chk := &structs.CheckType{
TTL: 15 * time.Second, TTL: 15 * time.Second,
} }
@ -1085,14 +1085,14 @@ func TestAgent_PurgeServiceOnDuplicate(t *testing.T) {
// Try bringing the agent back up with the service already // Try bringing the agent back up with the service already
// existing in the config // existing in the config
svc2 := &ServiceDefinition{ svc2 := &structs.ServiceDefinition{
ID: "redis", ID: "redis",
Name: "redis", Name: "redis",
Tags: []string{"bar"}, Tags: []string{"bar"},
Port: 9000, Port: 9000,
} }
cfg.Services = []*ServiceDefinition{svc2} cfg.Services = []*structs.ServiceDefinition{svc2}
a2 := NewTestAgent(t.Name()+"-a2", cfg) a2 := NewTestAgent(t.Name()+"-a2", cfg)
defer a2.Shutdown() defer a2.Shutdown()
@ -1124,7 +1124,7 @@ func TestAgent_PersistCheck(t *testing.T) {
Name: "memory check", Name: "memory check",
Status: api.HealthPassing, Status: api.HealthPassing,
} }
chkType := &CheckType{ chkType := &structs.CheckType{
Script: "/bin/true", Script: "/bin/true",
Interval: 10 * time.Second, Interval: 10 * time.Second,
} }
@ -1265,7 +1265,7 @@ func TestAgent_PurgeCheckOnDuplicate(t *testing.T) {
a.Shutdown() a.Shutdown()
// Start again with the check registered in config // Start again with the check registered in config
check2 := &CheckDefinition{ check2 := &structs.CheckDefinition{
ID: "mem", ID: "mem",
Name: "memory check", Name: "memory check",
Notes: "my cool notes", Notes: "my cool notes",
@ -1273,7 +1273,7 @@ func TestAgent_PurgeCheckOnDuplicate(t *testing.T) {
Interval: 30 * time.Second, Interval: 30 * time.Second,
} }
cfg.Checks = []*CheckDefinition{check2} cfg.Checks = []*structs.CheckDefinition{check2}
a2 := NewTestAgent(t.Name()+"-a2", cfg) a2 := NewTestAgent(t.Name()+"-a2", cfg)
defer a2.Shutdown() defer a2.Shutdown()
@ -1294,7 +1294,7 @@ func TestAgent_PurgeCheckOnDuplicate(t *testing.T) {
func TestAgent_loadChecks_token(t *testing.T) { func TestAgent_loadChecks_token(t *testing.T) {
t.Parallel() t.Parallel()
cfg := TestConfig() cfg := TestConfig()
cfg.Checks = append(cfg.Checks, &CheckDefinition{ cfg.Checks = append(cfg.Checks, &structs.CheckDefinition{
ID: "rabbitmq", ID: "rabbitmq",
Name: "rabbitmq", Name: "rabbitmq",
Token: "abc123", Token: "abc123",
@ -1367,7 +1367,7 @@ func TestAgent_unloadChecks(t *testing.T) {
func TestAgent_loadServices_token(t *testing.T) { func TestAgent_loadServices_token(t *testing.T) {
t.Parallel() t.Parallel()
cfg := TestConfig() cfg := TestConfig()
cfg.Services = append(cfg.Services, &ServiceDefinition{ cfg.Services = append(cfg.Services, &structs.ServiceDefinition{
ID: "rabbitmq", ID: "rabbitmq",
Name: "rabbitmq", Name: "rabbitmq",
Port: 5672, Port: 5672,
@ -1510,8 +1510,8 @@ func TestAgent_Service_Reap(t *testing.T) {
Tags: []string{"foo"}, Tags: []string{"foo"},
Port: 8000, Port: 8000,
} }
chkTypes := CheckTypes{ chkTypes := []*structs.CheckType{
&CheckType{ &structs.CheckType{
Status: api.HealthPassing, Status: api.HealthPassing,
TTL: 10 * time.Millisecond, TTL: 10 * time.Millisecond,
DeregisterCriticalServiceAfter: 100 * time.Millisecond, DeregisterCriticalServiceAfter: 100 * time.Millisecond,
@ -1584,8 +1584,8 @@ func TestAgent_Service_NoReap(t *testing.T) {
Tags: []string{"foo"}, Tags: []string{"foo"},
Port: 8000, Port: 8000,
} }
chkTypes := CheckTypes{ chkTypes := []*structs.CheckType{
&CheckType{ &structs.CheckType{
Status: api.HealthPassing, Status: api.HealthPassing,
TTL: 10 * time.Millisecond, TTL: 10 * time.Millisecond,
}, },
@ -1653,7 +1653,7 @@ func TestAgent_addCheck_restoresSnapshot(t *testing.T) {
} }
// Re-registering the service preserves the state of the check // Re-registering the service preserves the state of the check
chkTypes := CheckTypes{&CheckType{TTL: 30 * time.Second}} chkTypes := []*structs.CheckType{&structs.CheckType{TTL: 30 * time.Second}}
if err := a.AddService(svc, chkTypes, false, ""); err != nil { if err := a.AddService(svc, chkTypes, false, ""); err != nil {
t.Fatalf("err: %s", err) t.Fatalf("err: %s", err)
} }

View File

@ -38,72 +38,6 @@ const (
UserAgent = "Consul Health Check" UserAgent = "Consul Health Check"
) )
// CheckType is used to create either the CheckMonitor or the CheckTTL.
// Five types are supported: Script, HTTP, TCP, Docker and TTL. Script, HTTP,
// Docker and TCP all require Interval. Only one of the types may to be
// provided: TTL or Script/Interval or HTTP/Interval or TCP/Interval or
// Docker/Interval.
type CheckType struct {
// fields already embedded in CheckDefinition
// Note: CheckType.CheckID == CheckDefinition.ID
CheckID types.CheckID
Name string
Status string
Notes string
// fields copied to CheckDefinition
// Update CheckDefinition when adding fields here
Script string
HTTP string
Header map[string][]string
Method string
TCP string
Interval time.Duration
DockerContainerID string
Shell string
TLSSkipVerify bool
Timeout time.Duration
TTL time.Duration
// DeregisterCriticalServiceAfter, if >0, will cause the associated
// service, if any, to be deregistered if this check is critical for
// longer than this duration.
DeregisterCriticalServiceAfter time.Duration
}
type CheckTypes []*CheckType
// Valid checks if the CheckType is valid
func (c *CheckType) Valid() bool {
return c.IsTTL() || c.IsMonitor() || c.IsHTTP() || c.IsTCP() || c.IsDocker()
}
// IsTTL checks if this is a TTL type
func (c *CheckType) IsTTL() bool {
return c.TTL != 0
}
// IsMonitor checks if this is a Monitor type
func (c *CheckType) IsMonitor() bool {
return c.Script != "" && c.DockerContainerID == "" && c.Interval != 0
}
// IsHTTP checks if this is a HTTP type
func (c *CheckType) IsHTTP() bool {
return c.HTTP != "" && c.Interval != 0
}
// IsTCP checks if this is a TCP type
func (c *CheckType) IsTCP() bool {
return c.TCP != "" && c.Interval != 0
}
// IsDocker returns true when checking a docker container.
func (c *CheckType) IsDocker() bool {
return c.DockerContainerID != "" && c.Script != "" && c.Interval != 0
}
// CheckNotifier interface is used by the CheckMonitor // CheckNotifier interface is used by the CheckMonitor
// to notify when a check has a status update. The update // to notify when a check has a status update. The update
// should take care to be idempotent. // should take care to be idempotent.
@ -324,7 +258,7 @@ func (c *CheckTTL) SetStatus(status, output string) {
// so that it may be restored later on. // so that it may be restored later on.
type persistedCheck struct { type persistedCheck struct {
Check *structs.HealthCheck Check *structs.HealthCheck
ChkType *CheckType ChkType *structs.CheckType
Token string Token string
} }

View File

@ -15,6 +15,7 @@ import (
"time" "time"
"github.com/hashicorp/consul/agent/consul" "github.com/hashicorp/consul/agent/consul"
"github.com/hashicorp/consul/agent/consul/structs"
"github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/lib"
"github.com/hashicorp/consul/tlsutil" "github.com/hashicorp/consul/tlsutil"
"github.com/hashicorp/consul/types" "github.com/hashicorp/consul/types"
@ -729,10 +730,10 @@ type Config struct {
SyncCoordinateIntervalMin time.Duration `mapstructure:"-" json:"-"` SyncCoordinateIntervalMin time.Duration `mapstructure:"-" json:"-"`
// Checks holds the provided check definitions // Checks holds the provided check definitions
Checks []*CheckDefinition `mapstructure:"-" json:"-"` Checks []*structs.CheckDefinition `mapstructure:"-" json:"-"`
// Services holds the provided service definitions // Services holds the provided service definitions
Services []*ServiceDefinition `mapstructure:"-" json:"-"` Services []*structs.ServiceDefinition `mapstructure:"-" json:"-"`
// ConsulConfig can either be provided or a default one created // ConsulConfig can either be provided or a default one created
ConsulConfig *consul.Config `mapstructure:"-" json:"-"` ConsulConfig *consul.Config `mapstructure:"-" json:"-"`
@ -1371,7 +1372,7 @@ func DecodeConfig(r io.Reader) (*Config, error) {
} }
// DecodeServiceDefinition is used to decode a service definition // DecodeServiceDefinition is used to decode a service definition
func DecodeServiceDefinition(raw interface{}) (*ServiceDefinition, error) { func DecodeServiceDefinition(raw interface{}) (*structs.ServiceDefinition, error) {
rawMap, ok := raw.(map[string]interface{}) rawMap, ok := raw.(map[string]interface{})
if !ok { if !ok {
goto AFTER_FIX goto AFTER_FIX
@ -1404,7 +1405,7 @@ func DecodeServiceDefinition(raw interface{}) (*ServiceDefinition, error) {
} }
AFTER_FIX: AFTER_FIX:
var md mapstructure.Metadata var md mapstructure.Metadata
var result ServiceDefinition var result structs.ServiceDefinition
msdec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ msdec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
Metadata: &md, Metadata: &md,
Result: &result, Result: &result,
@ -1511,12 +1512,12 @@ func FixupCheckType(raw interface{}) error {
} }
// DecodeCheckDefinition is used to decode a check definition // DecodeCheckDefinition is used to decode a check definition
func DecodeCheckDefinition(raw interface{}) (*CheckDefinition, error) { func DecodeCheckDefinition(raw interface{}) (*structs.CheckDefinition, error) {
if err := FixupCheckType(raw); err != nil { if err := FixupCheckType(raw); err != nil {
return nil, err return nil, err
} }
var md mapstructure.Metadata var md mapstructure.Metadata
var result CheckDefinition var result structs.CheckDefinition
msdec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ msdec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
Metadata: &md, Metadata: &md,
Result: &result, Result: &result,

View File

@ -14,6 +14,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/hashicorp/consul/agent/consul/structs"
"github.com/hashicorp/consul/testutil" "github.com/hashicorp/consul/testutil"
"github.com/pascaldekloe/goe/verify" "github.com/pascaldekloe/goe/verify"
) )
@ -742,8 +743,8 @@ func TestDecodeConfig(t *testing.T) {
} }
}`, }`,
c: &Config{ c: &Config{
Services: []*ServiceDefinition{ Services: []*structs.ServiceDefinition{
&ServiceDefinition{ &structs.ServiceDefinition{
ID: "a", ID: "a",
Name: "b", Name: "b",
Tags: []string{"c", "d"}, Tags: []string{"c", "d"},
@ -751,7 +752,7 @@ func TestDecodeConfig(t *testing.T) {
Port: 123, Port: 123,
Token: "f", Token: "f",
EnableTagOverride: true, EnableTagOverride: true,
Check: CheckType{ Check: structs.CheckType{
CheckID: "g", CheckID: "g",
Name: "h", Name: "h",
Status: "i", Status: "i",
@ -825,8 +826,8 @@ func TestDecodeConfig(t *testing.T) {
} }
}`, }`,
c: &Config{ c: &Config{
Services: []*ServiceDefinition{ Services: []*structs.ServiceDefinition{
&ServiceDefinition{ &structs.ServiceDefinition{
ID: "a", ID: "a",
Name: "b", Name: "b",
Tags: []string{"c", "d"}, Tags: []string{"c", "d"},
@ -834,7 +835,7 @@ func TestDecodeConfig(t *testing.T) {
Port: 123, Port: 123,
Token: "f", Token: "f",
EnableTagOverride: true, EnableTagOverride: true,
Checks: CheckTypes{ Checks: []*structs.CheckType{
{ {
CheckID: "g", CheckID: "g",
Name: "h", Name: "h",
@ -937,8 +938,8 @@ func TestDecodeConfig(t *testing.T) {
] ]
}`, }`,
c: &Config{ c: &Config{
Services: []*ServiceDefinition{ Services: []*structs.ServiceDefinition{
&ServiceDefinition{ &structs.ServiceDefinition{
ID: "a", ID: "a",
Name: "b", Name: "b",
Tags: []string{"c", "d"}, Tags: []string{"c", "d"},
@ -946,7 +947,7 @@ func TestDecodeConfig(t *testing.T) {
Port: 123, Port: 123,
Token: "f", Token: "f",
EnableTagOverride: true, EnableTagOverride: true,
Check: CheckType{ Check: structs.CheckType{
CheckID: "g", CheckID: "g",
Name: "h", Name: "h",
Status: "i", Status: "i",
@ -965,7 +966,7 @@ func TestDecodeConfig(t *testing.T) {
DeregisterCriticalServiceAfter: 5 * time.Second, DeregisterCriticalServiceAfter: 5 * time.Second,
}, },
}, },
&ServiceDefinition{ &structs.ServiceDefinition{
ID: "aa", ID: "aa",
Name: "bb", Name: "bb",
Tags: []string{"cc", "dd"}, Tags: []string{"cc", "dd"},
@ -973,7 +974,7 @@ func TestDecodeConfig(t *testing.T) {
Port: 246, Port: 246,
Token: "ff", Token: "ff",
EnableTagOverride: false, EnableTagOverride: false,
Check: CheckType{ Check: structs.CheckType{
CheckID: "gg", CheckID: "gg",
Name: "hh", Name: "hh",
Status: "ii", Status: "ii",
@ -1021,8 +1022,8 @@ func TestDecodeConfig(t *testing.T) {
} }
}`, }`,
c: &Config{ c: &Config{
Checks: []*CheckDefinition{ Checks: []*structs.CheckDefinition{
&CheckDefinition{ &structs.CheckDefinition{
ID: "a", ID: "a",
Name: "b", Name: "b",
Notes: "c", Notes: "c",
@ -1092,8 +1093,8 @@ func TestDecodeConfig(t *testing.T) {
] ]
}`, }`,
c: &Config{ c: &Config{
Checks: []*CheckDefinition{ Checks: []*structs.CheckDefinition{
&CheckDefinition{ &structs.CheckDefinition{
ID: "a", ID: "a",
Name: "b", Name: "b",
Notes: "c", Notes: "c",
@ -1113,7 +1114,7 @@ func TestDecodeConfig(t *testing.T) {
TTL: 4 * time.Second, TTL: 4 * time.Second,
DeregisterCriticalServiceAfter: 5 * time.Second, DeregisterCriticalServiceAfter: 5 * time.Second,
}, },
&CheckDefinition{ &structs.CheckDefinition{
ID: "aa", ID: "aa",
Name: "bb", Name: "bb",
Notes: "cc", Notes: "cc",
@ -1336,8 +1337,8 @@ func TestMergeConfig(t *testing.T) {
CertFile: "test/cert.pem", CertFile: "test/cert.pem",
KeyFile: "test/key.pem", KeyFile: "test/key.pem",
TLSMinVersion: "tls12", TLSMinVersion: "tls12",
Checks: []*CheckDefinition{nil}, Checks: []*structs.CheckDefinition{nil},
Services: []*ServiceDefinition{nil}, Services: []*structs.ServiceDefinition{nil},
StartJoin: []string{"1.1.1.1"}, StartJoin: []string{"1.1.1.1"},
StartJoinWan: []string{"1.1.1.1"}, StartJoinWan: []string{"1.1.1.1"},
EnableUI: true, EnableUI: true,
@ -1502,7 +1503,7 @@ func TestUnixSockets(t *testing.T) {
func TestCheckDefinitionToCheckType(t *testing.T) { func TestCheckDefinitionToCheckType(t *testing.T) {
t.Parallel() t.Parallel()
got := &CheckDefinition{ got := &structs.CheckDefinition{
ID: "id", ID: "id",
Name: "name", Name: "name",
Status: "green", Status: "green",
@ -1521,7 +1522,7 @@ func TestCheckDefinitionToCheckType(t *testing.T) {
TTL: 3 * time.Second, TTL: 3 * time.Second,
DeregisterCriticalServiceAfter: 4 * time.Second, DeregisterCriticalServiceAfter: 4 * time.Second,
} }
want := &CheckType{ want := &structs.CheckType{
CheckID: "id", CheckID: "id",
Name: "name", Name: "name",
Status: "green", Status: "green",

View File

@ -1,51 +1,12 @@
package agent package structs
import ( import (
"time" "time"
"github.com/hashicorp/consul/agent/consul/structs"
"github.com/hashicorp/consul/api" "github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/types" "github.com/hashicorp/consul/types"
) )
// ServiceDefinition is used to JSON decode the Service definitions
type ServiceDefinition struct {
ID string
Name string
Tags []string
Address string
Port int
Check CheckType
Checks CheckTypes
Token string
EnableTagOverride bool
}
func (s *ServiceDefinition) NodeService() *structs.NodeService {
ns := &structs.NodeService{
ID: s.ID,
Service: s.Name,
Tags: s.Tags,
Address: s.Address,
Port: s.Port,
EnableTagOverride: s.EnableTagOverride,
}
if ns.ID == "" && ns.Service != "" {
ns.ID = ns.Service
}
return ns
}
func (s *ServiceDefinition) CheckTypes() (checks CheckTypes) {
s.Checks = append(s.Checks, &s.Check)
for _, check := range s.Checks {
if check.Valid() {
checks = append(checks, check)
}
}
return
}
// CheckDefinition is used to JSON decode the Check definitions // CheckDefinition is used to JSON decode the Check definitions
type CheckDefinition struct { type CheckDefinition struct {
ID types.CheckID ID types.CheckID
@ -74,8 +35,8 @@ type CheckDefinition struct {
DeregisterCriticalServiceAfter time.Duration DeregisterCriticalServiceAfter time.Duration
} }
func (c *CheckDefinition) HealthCheck(node string) *structs.HealthCheck { func (c *CheckDefinition) HealthCheck(node string) *HealthCheck {
health := &structs.HealthCheck{ health := &HealthCheck{
Node: node, Node: node,
CheckID: c.ID, CheckID: c.ID,
Name: c.Name, Name: c.Name,
@ -110,10 +71,3 @@ func (c *CheckDefinition) CheckType() *CheckType {
Notes: c.Notes, Notes: c.Notes,
} }
} }
// persistedService is used to wrap a service definition and bundle it
// with an ACL token so we can restore both at a later agent start.
type persistedService struct {
Token string
Service *structs.NodeService
}

View File

@ -0,0 +1,18 @@
package structs
import (
"testing"
"github.com/hashicorp/consul/api"
)
func TestAgentStructs_HealthCheck(t *testing.T) {
t.Parallel()
def := CheckDefinition{}
check := def.HealthCheck("node1")
// Health checks default to critical state
if check.Status != api.HealthCritical {
t.Fatalf("bad: %v", check.Status)
}
}

View File

@ -0,0 +1,73 @@
package structs
import (
"time"
"github.com/hashicorp/consul/types"
)
// CheckType is used to create either the CheckMonitor or the CheckTTL.
// Five types are supported: Script, HTTP, TCP, Docker and TTL. Script, HTTP,
// Docker and TCP all require Interval. Only one of the types may to be
// provided: TTL or Script/Interval or HTTP/Interval or TCP/Interval or
// Docker/Interval.
type CheckType struct {
// fields already embedded in CheckDefinition
// Note: CheckType.CheckID == CheckDefinition.ID
CheckID types.CheckID
Name string
Status string
Notes string
// fields copied to CheckDefinition
// Update CheckDefinition when adding fields here
Script string
HTTP string
Header map[string][]string
Method string
TCP string
Interval time.Duration
DockerContainerID string
Shell string
TLSSkipVerify bool
Timeout time.Duration
TTL time.Duration
// DeregisterCriticalServiceAfter, if >0, will cause the associated
// service, if any, to be deregistered if this check is critical for
// longer than this duration.
DeregisterCriticalServiceAfter time.Duration
}
type CheckTypes []*CheckType
// Valid checks if the CheckType is valid
func (c *CheckType) Valid() bool {
return c.IsTTL() || c.IsMonitor() || c.IsHTTP() || c.IsTCP() || c.IsDocker()
}
// IsTTL checks if this is a TTL type
func (c *CheckType) IsTTL() bool {
return c.TTL != 0
}
// IsMonitor checks if this is a Monitor type
func (c *CheckType) IsMonitor() bool {
return c.Script != "" && c.DockerContainerID == "" && c.Interval != 0
}
// IsHTTP checks if this is a HTTP type
func (c *CheckType) IsHTTP() bool {
return c.HTTP != "" && c.Interval != 0
}
// IsTCP checks if this is a TCP type
func (c *CheckType) IsTCP() bool {
return c.TCP != "" && c.Interval != 0
}
// IsDocker returns true when checking a docker container.
func (c *CheckType) IsDocker() bool {
return c.DockerContainerID != "" && c.Script != "" && c.Interval != 0
}

View File

@ -0,0 +1,39 @@
package structs
// ServiceDefinition is used to JSON decode the Service definitions
type ServiceDefinition struct {
ID string
Name string
Tags []string
Address string
Port int
Check CheckType
Checks CheckTypes
Token string
EnableTagOverride bool
}
func (s *ServiceDefinition) NodeService() *NodeService {
ns := &NodeService{
ID: s.ID,
Service: s.Name,
Tags: s.Tags,
Address: s.Address,
Port: s.Port,
EnableTagOverride: s.EnableTagOverride,
}
if ns.ID == "" && ns.Service != "" {
ns.ID = ns.Service
}
return ns
}
func (s *ServiceDefinition) CheckTypes() (checks CheckTypes) {
s.Checks = append(s.Checks, &s.Check)
for _, check := range s.Checks {
if check.Valid() {
checks = append(checks, check)
}
}
return
}

View File

@ -1,23 +1,10 @@
package agent package structs
import ( import (
"testing" "testing"
"time" "time"
"github.com/hashicorp/consul/api"
) )
func TestAgentStructs_HealthCheck(t *testing.T) {
t.Parallel()
def := CheckDefinition{}
check := def.HealthCheck("node1")
// Health checks default to critical state
if check.Status != api.HealthCritical {
t.Fatalf("bad: %v", check.Status)
}
}
func TestAgentStructs_CheckTypes(t *testing.T) { func TestAgentStructs_CheckTypes(t *testing.T) {
t.Parallel() t.Parallel()
svc := new(ServiceDefinition) svc := new(ServiceDefinition)