forked from hashicorp/terraform
-
Notifications
You must be signed in to change notification settings - Fork 0
/
resource_circonus_check_icmp_ping.go
157 lines (133 loc) · 4.79 KB
/
resource_circonus_check_icmp_ping.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
package circonus
import (
"bytes"
"fmt"
"strconv"
"time"
"github.com/circonus-labs/circonus-gometrics/api/config"
"github.com/hashicorp/errwrap"
"github.com/hashicorp/terraform/helper/hashcode"
"github.com/hashicorp/terraform/helper/schema"
)
const (
// circonus_check.icmp_ping.* resource attribute names
checkICMPPingAvailabilityAttr = "availability"
checkICMPPingCountAttr = "count"
checkICMPPingIntervalAttr = "interval"
)
var checkICMPPingDescriptions = attrDescrs{
checkICMPPingAvailabilityAttr: `The percentage of ICMP available required for the check to be considered "good."`,
checkICMPPingCountAttr: "The number of ICMP requests to send during a single check.",
checkICMPPingIntervalAttr: "The number of milliseconds between ICMP requests.",
}
var schemaCheckICMPPing = &schema.Schema{
Type: schema.TypeSet,
Optional: true,
MaxItems: 1,
MinItems: 1,
Set: hashCheckICMPPing,
Elem: &schema.Resource{
Schema: convertToHelperSchema(checkICMPPingDescriptions, map[schemaAttr]*schema.Schema{
checkICMPPingAvailabilityAttr: &schema.Schema{
Type: schema.TypeFloat,
Optional: true,
Default: defaultCheckICMPPingAvailability,
ValidateFunc: validateFuncs(
validateFloatMin(checkICMPPingAvailabilityAttr, 0.0),
validateFloatMax(checkICMPPingAvailabilityAttr, 100.0),
),
},
checkICMPPingCountAttr: &schema.Schema{
Type: schema.TypeInt,
Optional: true,
Default: defaultCheckICMPPingCount,
ValidateFunc: validateFuncs(
validateIntMin(checkICMPPingCountAttr, 0),
validateIntMax(checkICMPPingCountAttr, 20),
),
},
checkICMPPingIntervalAttr: &schema.Schema{
Type: schema.TypeString,
Optional: true,
Default: defaultCheckICMPPingInterval,
ValidateFunc: validateFuncs(
validateDurationMin(checkICMPPingIntervalAttr, "100µs"),
validateDurationMax(checkICMPPingIntervalAttr, "5m"),
),
},
}),
},
}
// checkAPIToStateICMPPing reads the Config data out of circonusCheck.CheckBundle
// into the statefile.
func checkAPIToStateICMPPing(c *circonusCheck, d *schema.ResourceData) error {
icmpPingConfig := make(map[string]interface{}, len(c.Config))
availNeeded, err := strconv.ParseFloat(c.Config[config.AvailNeeded], 64)
if err != nil {
return errwrap.Wrapf(fmt.Sprintf("unable to parse %s: {{err}}", config.AvailNeeded), err)
}
count, err := strconv.ParseInt(c.Config[config.Count], 10, 64)
if err != nil {
return errwrap.Wrapf(fmt.Sprintf("unable to parse %s: {{err}}", config.Count), err)
}
interval, err := time.ParseDuration(fmt.Sprintf("%sms", c.Config[config.Interval]))
if err != nil {
return errwrap.Wrapf(fmt.Sprintf("unable to parse %s: {{err}}", config.Interval), err)
}
icmpPingConfig[string(checkICMPPingAvailabilityAttr)] = availNeeded
icmpPingConfig[string(checkICMPPingCountAttr)] = int(count)
icmpPingConfig[string(checkICMPPingIntervalAttr)] = interval.String()
if err := d.Set(checkICMPPingAttr, schema.NewSet(hashCheckICMPPing, []interface{}{icmpPingConfig})); err != nil {
return errwrap.Wrapf(fmt.Sprintf("Unable to store check %q attribute: {{err}}", checkICMPPingAttr), err)
}
return nil
}
// hashCheckICMPPing creates a stable hash of the normalized values
func hashCheckICMPPing(v interface{}) int {
m := v.(map[string]interface{})
b := &bytes.Buffer{}
b.Grow(defaultHashBufSize)
writeFloat64 := func(attrName schemaAttr) {
if v, ok := m[string(attrName)]; ok {
fmt.Fprintf(b, "%f", v.(float64))
}
}
writeInt := func(attrName schemaAttr) {
if v, ok := m[string(attrName)]; ok {
fmt.Fprintf(b, "%x", v.(int))
}
}
writeDuration := func(attrName schemaAttr) {
if v, ok := m[string(attrName)]; ok && v.(string) != "" {
d, _ := time.ParseDuration(v.(string))
fmt.Fprint(b, d.String())
}
}
// Order writes to the buffer using lexically sorted list for easy visual
// reconciliation with other lists.
writeFloat64(checkICMPPingAvailabilityAttr)
writeInt(checkICMPPingCountAttr)
writeDuration(checkICMPPingIntervalAttr)
s := b.String()
return hashcode.String(s)
}
func checkConfigToAPIICMPPing(c *circonusCheck, l interfaceList) error {
c.Type = string(apiCheckTypeICMPPing)
// Iterate over all `icmp_ping` attributes, even though we have a max of 1 in
// the schema.
for _, mapRaw := range l {
icmpPingConfig := newInterfaceMap(mapRaw)
if v, found := icmpPingConfig[checkICMPPingAvailabilityAttr]; found {
f := v.(float64)
c.Config[config.AvailNeeded] = fmt.Sprintf("%d", int(f))
}
if v, found := icmpPingConfig[checkICMPPingCountAttr]; found {
c.Config[config.Count] = fmt.Sprintf("%d", v.(int))
}
if v, found := icmpPingConfig[checkICMPPingIntervalAttr]; found {
d, _ := time.ParseDuration(v.(string))
c.Config[config.Interval] = fmt.Sprintf("%d", int64(d/time.Millisecond))
}
}
return nil
}