Add deregister critical service field and refactor duration parsing

This commit is contained in:
Kyle Havlovitz 2017-10-25 19:17:41 -07:00
parent ab3dac2379
commit 16908be034
No known key found for this signature in database
GPG Key ID: 8A5E6B173056AD6C
6 changed files with 75 additions and 42 deletions

View File

@ -1407,7 +1407,7 @@ func (a *Agent) reapServicesInternal() {
}
// reapServices is a long running goroutine that looks for checks that have been
// critical too long and dregisters their associated services.
// critical too long and deregisters their associated services.
func (a *Agent) reapServices() {
for {
select {

View File

@ -8,13 +8,15 @@ import (
"github.com/hashicorp/consul/agent/structs"
)
var durations = NewDurationFixer("interval", "timeout", "deregistercriticalserviceafter")
func (s *HTTPServer) CatalogRegister(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
if req.Method != "PUT" {
return nil, MethodNotAllowedError{req.Method, []string{"PUT"}}
}
var args structs.RegisterRequest
if err := decodeBody(req, &args, nil); err != nil {
if err := decodeBody(req, &args, durations.FixupDurations); err != nil {
resp.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(resp, "Request decode failed: %v", err)
return nil, nil

View File

@ -220,7 +220,8 @@ func (s *HTTPServer) OperatorAutopilotConfiguration(resp http.ResponseWriter, re
s.parseToken(req, &args.Token)
var conf api.AutopilotConfiguration
if err := decodeBody(req, &conf, FixupConfigDurations); err != nil {
durations := NewDurationFixer("lastcontactthreshold", "serverstabilizationtime")
if err := decodeBody(req, &conf, durations.FixupDurations); err != nil {
resp.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(resp, "Error parsing autopilot config: %v", err)
return nil, nil
@ -265,23 +266,50 @@ func (s *HTTPServer) OperatorAutopilotConfiguration(resp http.ResponseWriter, re
}
}
// FixupConfigDurations is used to handle parsing the duration fields in
// the Autopilot config struct
func FixupConfigDurations(raw interface{}) error {
type durationFixer map[string]struct{}
func NewDurationFixer(fields ...string) durationFixer {
d := make(map[string]struct{})
for _, field := range fields {
d[field] = struct{}{}
}
return d
}
// FixupDurations is used to handle parsing any field names in the map to time.Durations
func (d durationFixer) FixupDurations(raw interface{}) error {
rawMap, ok := raw.(map[string]interface{})
if !ok {
return nil
}
for key, val := range rawMap {
if strings.ToLower(key) == "lastcontactthreshold" ||
strings.ToLower(key) == "serverstabilizationtime" {
// Convert a string value into an integer
if vStr, ok := val.(string); ok {
dur, err := time.ParseDuration(vStr)
if err != nil {
if key == "NodeMeta" {
continue
}
switch val.(type) {
case map[string]interface{}:
if err := d.FixupDurations(val); err != nil {
return err
}
case []interface{}:
for _, v := range val.([]interface{}) {
if err := d.FixupDurations(v); err != nil {
return err
}
rawMap[key] = dur
}
default:
if _, ok := d[strings.ToLower(key)]; ok {
// Convert a string value into an integer
if vStr, ok := val.(string); ok {
dur, err := time.ParseDuration(vStr)
if err != nil {
return err
}
rawMap[key] = dur
}
}
}
}

View File

@ -482,13 +482,14 @@ type HealthCheck struct {
ServiceName string // optional service name
ServiceTags []string // optional service tags
HTTP string `json:",omitempty"`
TLSSkipVerify bool `json:",omitempty"`
Header map[string][]string `json:",omitempty"`
Method string `json:",omitempty"`
TCP string `json:",omitempty"`
Interval string `json:",omitempty"`
Timeout string `json:",omitempty"`
HTTP string `json:",omitempty"`
TLSSkipVerify bool `json:",omitempty"`
Header map[string][]string `json:",omitempty"`
Method string `json:",omitempty"`
TCP string `json:",omitempty"`
Interval api.ReadableDuration `json:",omitempty"`
Timeout api.ReadableDuration `json:",omitempty"`
DeregisterCriticalServiceAfter api.ReadableDuration `json:",omitempty"`
RaftIndex
}

View File

@ -7,21 +7,22 @@ import (
// AgentCheck represents a check known to the agent
type AgentCheck struct {
Node string
CheckID string
Name string
Status string
Notes string
Output string
ServiceID string
ServiceName string
HTTP string
Header map[string][]string
Method string
TLSSkipVerify bool
TCP string
Interval string
Timeout string
Node string
CheckID string
Name string
Status string
Notes string
Output string
ServiceID string
ServiceName string
HTTP string
Header map[string][]string
Method string
TLSSkipVerify bool
TCP string
Interval ReadableDuration
Timeout ReadableDuration
DeregisterCriticalServiceAfter ReadableDuration
}
// AgentService represents a service known to the agent

View File

@ -35,13 +35,14 @@ type HealthCheck struct {
ServiceName string
ServiceTags []string
HTTP string
Header map[string][]string
Method string
TLSSkipVerify bool
TCP string
Interval string
Timeout string
HTTP string
Header map[string][]string
Method string
TLSSkipVerify bool
TCP string
Interval ReadableDuration
Timeout ReadableDuration
DeregisterCriticalServiceAfter ReadableDuration
}
// HealthChecks is a collection of HealthCheck structs.