github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/circonus/resource_circonus_check_icmp_ping.go (about)

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