1package structs
2
3import (
4	"fmt"
5	"reflect"
6	"time"
7
8	"github.com/hashicorp/consul/types"
9)
10
11// CheckType is used to create either the CheckMonitor or the CheckTTL.
12// The following types are supported: Script, HTTP, TCP, Docker, TTL, GRPC, Alias. Script,
13// HTTP, Docker, TCP and GRPC all require Interval. Only one of the types may
14// to be provided: TTL or Script/Interval or HTTP/Interval or TCP/Interval or
15// Docker/Interval or GRPC/Interval or AliasService.
16type CheckType struct {
17	// fields already embedded in CheckDefinition
18	// Note: CheckType.CheckID == CheckDefinition.ID
19
20	CheckID types.CheckID
21	Name    string
22	Status  string
23	Notes   string
24
25	// fields copied to CheckDefinition
26	// Update CheckDefinition when adding fields here
27
28	ScriptArgs        []string
29	HTTP              string
30	Header            map[string][]string
31	Method            string
32	TCP               string
33	Interval          time.Duration
34	AliasNode         string
35	AliasService      string
36	DockerContainerID string
37	Shell             string
38	GRPC              string
39	GRPCUseTLS        bool
40	TLSSkipVerify     bool
41	Timeout           time.Duration
42	TTL               time.Duration
43
44	// DeregisterCriticalServiceAfter, if >0, will cause the associated
45	// service, if any, to be deregistered if this check is critical for
46	// longer than this duration.
47	DeregisterCriticalServiceAfter time.Duration
48}
49type CheckTypes []*CheckType
50
51// Validate returns an error message if the check is invalid
52func (c *CheckType) Validate() error {
53	intervalCheck := c.IsScript() || c.HTTP != "" || c.TCP != "" || c.GRPC != ""
54
55	if c.Interval > 0 && c.TTL > 0 {
56		return fmt.Errorf("Interval and TTL cannot both be specified")
57	}
58	if intervalCheck && c.Interval <= 0 {
59		return fmt.Errorf("Interval must be > 0 for Script, HTTP, or TCP checks")
60	}
61	if intervalCheck && c.IsAlias() {
62		return fmt.Errorf("Interval cannot be set for Alias checks")
63	}
64	if c.IsAlias() && c.TTL > 0 {
65		return fmt.Errorf("TTL must be not be set for Alias checks")
66	}
67	if !intervalCheck && !c.IsAlias() && c.TTL <= 0 {
68		return fmt.Errorf("TTL must be > 0 for TTL checks")
69	}
70	return nil
71}
72
73// Empty checks if the CheckType has no fields defined. Empty checks parsed from json configs are filtered out
74func (c *CheckType) Empty() bool {
75	return reflect.DeepEqual(c, &CheckType{})
76}
77
78// IsAlias checks if this is an alias check.
79func (c *CheckType) IsAlias() bool {
80	return c.AliasNode != "" || c.AliasService != ""
81}
82
83// IsScript checks if this is a check that execs some kind of script.
84func (c *CheckType) IsScript() bool {
85	return len(c.ScriptArgs) > 0
86}
87
88// IsTTL checks if this is a TTL type
89func (c *CheckType) IsTTL() bool {
90	return c.TTL > 0
91}
92
93// IsMonitor checks if this is a Monitor type
94func (c *CheckType) IsMonitor() bool {
95	return c.IsScript() && c.DockerContainerID == "" && c.Interval > 0
96}
97
98// IsHTTP checks if this is a HTTP type
99func (c *CheckType) IsHTTP() bool {
100	return c.HTTP != "" && c.Interval > 0
101}
102
103// IsTCP checks if this is a TCP type
104func (c *CheckType) IsTCP() bool {
105	return c.TCP != "" && c.Interval > 0
106}
107
108// IsDocker returns true when checking a docker container.
109func (c *CheckType) IsDocker() bool {
110	return c.IsScript() && c.DockerContainerID != "" && c.Interval > 0
111}
112
113// IsGRPC checks if this is a GRPC type
114func (c *CheckType) IsGRPC() bool {
115	return c.GRPC != "" && c.Interval > 0
116}
117