157 lines
4.2 KiB
Go
157 lines
4.2 KiB
Go
package circonus
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"log"
|
|
"strings"
|
|
|
|
"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.httptrap.* resource attribute names
|
|
checkHTTPTrapAsyncMetricsAttr = "async_metrics"
|
|
checkHTTPTrapSecretAttr = "secret"
|
|
)
|
|
|
|
var checkHTTPTrapDescriptions = attrDescrs{
|
|
checkHTTPTrapAsyncMetricsAttr: "Specify whether httptrap metrics are logged immediately or held until the status message is emitted",
|
|
checkHTTPTrapSecretAttr: "",
|
|
}
|
|
|
|
var schemaCheckHTTPTrap = &schema.Schema{
|
|
Type: schema.TypeSet,
|
|
Optional: true,
|
|
MaxItems: 1,
|
|
MinItems: 1,
|
|
Set: hashCheckHTTPTrap,
|
|
Elem: &schema.Resource{
|
|
Schema: convertToHelperSchema(checkHTTPTrapDescriptions, map[schemaAttr]*schema.Schema{
|
|
checkHTTPTrapAsyncMetricsAttr: &schema.Schema{
|
|
Type: schema.TypeBool,
|
|
Optional: true,
|
|
Default: defaultCheckHTTPTrapAsync,
|
|
},
|
|
checkHTTPTrapSecretAttr: &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Optional: true,
|
|
Sensitive: true,
|
|
ValidateFunc: validateRegexp(checkHTTPTrapSecretAttr, `^[a-zA-Z0-9_]+$`),
|
|
},
|
|
}),
|
|
},
|
|
}
|
|
|
|
// checkAPIToStateHTTPTrap reads the Config data out of circonusCheck.CheckBundle into
|
|
// the statefile.
|
|
func checkAPIToStateHTTPTrap(c *circonusCheck, d *schema.ResourceData) error {
|
|
httpTrapConfig := make(map[string]interface{}, len(c.Config))
|
|
|
|
// swamp is a sanity check: it must be empty by the time this method returns
|
|
swamp := make(map[config.Key]string, len(c.Config))
|
|
for k, v := range c.Config {
|
|
swamp[k] = v
|
|
}
|
|
|
|
saveBoolConfigToState := func(apiKey config.Key, attrName schemaAttr) {
|
|
if s, ok := c.Config[apiKey]; ok {
|
|
switch s {
|
|
case "true", "on":
|
|
httpTrapConfig[string(attrName)] = true
|
|
case "false", "off":
|
|
httpTrapConfig[string(attrName)] = false
|
|
default:
|
|
log.Printf("PROVIDER BUG: unsupported value %q returned in key %q", s, apiKey)
|
|
}
|
|
}
|
|
|
|
delete(swamp, apiKey)
|
|
}
|
|
|
|
saveStringConfigToState := func(apiKey config.Key, attrName schemaAttr) {
|
|
if s, ok := c.Config[apiKey]; ok {
|
|
httpTrapConfig[string(attrName)] = s
|
|
}
|
|
|
|
delete(swamp, apiKey)
|
|
}
|
|
|
|
saveBoolConfigToState(config.AsyncMetrics, checkHTTPTrapAsyncMetricsAttr)
|
|
saveStringConfigToState(config.Secret, checkHTTPTrapSecretAttr)
|
|
|
|
whitelistedConfigKeys := map[config.Key]struct{}{
|
|
config.ReverseSecretKey: struct{}{},
|
|
config.SubmissionURL: struct{}{},
|
|
}
|
|
|
|
for k := range swamp {
|
|
if _, ok := whitelistedConfigKeys[k]; ok {
|
|
delete(c.Config, k)
|
|
}
|
|
|
|
if _, ok := whitelistedConfigKeys[k]; !ok {
|
|
log.Printf("[ERROR]: PROVIDER BUG: API Config not empty: %#v", swamp)
|
|
}
|
|
}
|
|
|
|
if err := d.Set(checkHTTPTrapAttr, schema.NewSet(hashCheckHTTPTrap, []interface{}{httpTrapConfig})); err != nil {
|
|
return errwrap.Wrapf(fmt.Sprintf("Unable to store check %q attribute: {{err}}", checkHTTPTrapAttr), err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// hashCheckHTTPTrap creates a stable hash of the normalized values
|
|
func hashCheckHTTPTrap(v interface{}) int {
|
|
m := v.(map[string]interface{})
|
|
b := &bytes.Buffer{}
|
|
b.Grow(defaultHashBufSize)
|
|
|
|
writeBool := func(attrName schemaAttr) {
|
|
if v, ok := m[string(attrName)]; ok {
|
|
fmt.Fprintf(b, "%t", v.(bool))
|
|
}
|
|
}
|
|
|
|
writeString := func(attrName schemaAttr) {
|
|
if v, ok := m[string(attrName)]; ok && v.(string) != "" {
|
|
fmt.Fprint(b, strings.TrimSpace(v.(string)))
|
|
}
|
|
}
|
|
|
|
// Order writes to the buffer using lexically sorted list for easy visual
|
|
// reconciliation with other lists.
|
|
writeBool(checkHTTPTrapAsyncMetricsAttr)
|
|
writeString(checkHTTPTrapSecretAttr)
|
|
|
|
s := b.String()
|
|
return hashcode.String(s)
|
|
}
|
|
|
|
func checkConfigToAPIHTTPTrap(c *circonusCheck, l interfaceList) error {
|
|
c.Type = string(apiCheckTypeHTTPTrapAttr)
|
|
|
|
// Iterate over all `httptrap` attributes, even though we have a max of 1 in the
|
|
// schema.
|
|
for _, mapRaw := range l {
|
|
httpTrapConfig := newInterfaceMap(mapRaw)
|
|
|
|
if v, found := httpTrapConfig[checkHTTPTrapAsyncMetricsAttr]; found {
|
|
b := v.(bool)
|
|
if b {
|
|
c.Config[config.AsyncMetrics] = fmt.Sprintf("%t", b)
|
|
}
|
|
}
|
|
|
|
if v, found := httpTrapConfig[checkHTTPTrapSecretAttr]; found {
|
|
c.Config[config.Secret] = v.(string)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|