github.com/jdextraze/terraform@v0.6.17-0.20160511153921-e33847c8a8af/builtin/providers/datadog/resource_datadog_monitor.go (about)

     1  package datadog
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"log"
     7  	"strconv"
     8  	"strings"
     9  
    10  	"github.com/hashicorp/terraform/helper/schema"
    11  	"github.com/zorkian/go-datadog-api"
    12  )
    13  
    14  func resourceDatadogMonitor() *schema.Resource {
    15  	return &schema.Resource{
    16  		Create: resourceDatadogMonitorCreate,
    17  		Read:   resourceDatadogMonitorRead,
    18  		Update: resourceDatadogMonitorUpdate,
    19  		Delete: resourceDatadogMonitorDelete,
    20  		Exists: resourceDatadogMonitorExists,
    21  
    22  		Schema: map[string]*schema.Schema{
    23  			"name": &schema.Schema{
    24  				Type:     schema.TypeString,
    25  				Required: true,
    26  			},
    27  			"message": &schema.Schema{
    28  				Type:     schema.TypeString,
    29  				Required: true,
    30  				StateFunc: func(val interface{}) string {
    31  					return strings.TrimSpace(val.(string))
    32  				},
    33  			},
    34  			"escalation_message": &schema.Schema{
    35  				Type:     schema.TypeString,
    36  				Optional: true,
    37  				StateFunc: func(val interface{}) string {
    38  					return strings.TrimSpace(val.(string))
    39  				},
    40  			},
    41  			"query": &schema.Schema{
    42  				Type:     schema.TypeString,
    43  				Required: true,
    44  				StateFunc: func(val interface{}) string {
    45  					return strings.TrimSpace(val.(string))
    46  				},
    47  			},
    48  			"type": &schema.Schema{
    49  				Type:     schema.TypeString,
    50  				Required: true,
    51  			},
    52  
    53  			// Options
    54  			"thresholds": &schema.Schema{
    55  				Type:     schema.TypeMap,
    56  				Required: true,
    57  				Elem: &schema.Resource{
    58  					Schema: map[string]*schema.Schema{
    59  						"ok": &schema.Schema{
    60  							Type:     schema.TypeFloat,
    61  							Optional: true,
    62  						},
    63  						"warning": &schema.Schema{
    64  							Type:     schema.TypeFloat,
    65  							Optional: true,
    66  						},
    67  						"critical": &schema.Schema{
    68  							Type:     schema.TypeFloat,
    69  							Required: true,
    70  						},
    71  					},
    72  				},
    73  			},
    74  			"notify_no_data": &schema.Schema{
    75  				Type:     schema.TypeBool,
    76  				Optional: true,
    77  				Default:  true,
    78  			},
    79  			"no_data_timeframe": &schema.Schema{
    80  				Type:     schema.TypeInt,
    81  				Optional: true,
    82  			},
    83  			"renotify_interval": &schema.Schema{
    84  				Type:     schema.TypeInt,
    85  				Optional: true,
    86  			},
    87  			"notify_audit": &schema.Schema{
    88  				Type:     schema.TypeBool,
    89  				Optional: true,
    90  			},
    91  			"timeout_h": &schema.Schema{
    92  				Type:     schema.TypeInt,
    93  				Optional: true,
    94  			},
    95  			// TODO should actually be map[string]int
    96  			"silenced": &schema.Schema{
    97  				Type:     schema.TypeMap,
    98  				Optional: true,
    99  				Elem: &schema.Schema{
   100  					Type: schema.TypeString,
   101  					Elem: &schema.Schema{
   102  						Type: schema.TypeInt},
   103  				},
   104  			},
   105  			"include_tags": &schema.Schema{
   106  				Type:     schema.TypeBool,
   107  				Optional: true,
   108  			},
   109  		},
   110  	}
   111  }
   112  
   113  func buildMonitorStruct(d *schema.ResourceData) *datadog.Monitor {
   114  
   115  	var thresholds datadog.ThresholdCount
   116  
   117  	if r, ok := d.GetOk("thresholds.ok"); ok {
   118  		thresholds.Ok = json.Number(r.(string))
   119  	}
   120  	if r, ok := d.GetOk("thresholds.warning"); ok {
   121  		thresholds.Warning = json.Number(r.(string))
   122  	}
   123  	if r, ok := d.GetOk("thresholds.critical"); ok {
   124  		thresholds.Critical = json.Number(r.(string))
   125  	}
   126  
   127  	o := datadog.Options{
   128  		Thresholds: thresholds,
   129  	}
   130  	if attr, ok := d.GetOk("silenced"); ok {
   131  		s := make(map[string]int)
   132  		// TODO: this is not very defensive, test if we can fail on non int input
   133  		for k, v := range attr.(map[string]interface{}) {
   134  			s[k], _ = strconv.Atoi(v.(string))
   135  		}
   136  		o.Silenced = s
   137  	}
   138  	if attr, ok := d.GetOk("notify_no_data"); ok {
   139  		o.NotifyNoData = attr.(bool)
   140  	}
   141  	if attr, ok := d.GetOk("no_data_timeframe"); ok {
   142  		o.NoDataTimeframe = attr.(int)
   143  	}
   144  	if attr, ok := d.GetOk("renotify_interval"); ok {
   145  		o.RenotifyInterval = attr.(int)
   146  	}
   147  	if attr, ok := d.GetOk("notify_audit"); ok {
   148  		o.NotifyAudit = attr.(bool)
   149  	}
   150  	if attr, ok := d.GetOk("timeout_h"); ok {
   151  		o.TimeoutH = attr.(int)
   152  	}
   153  	if attr, ok := d.GetOk("escalation_message"); ok {
   154  		o.EscalationMessage = attr.(string)
   155  	}
   156  	if attr, ok := d.GetOk("include_tags"); ok {
   157  		o.IncludeTags = attr.(bool)
   158  	}
   159  
   160  	m := datadog.Monitor{
   161  		Type:    d.Get("type").(string),
   162  		Query:   d.Get("query").(string),
   163  		Name:    d.Get("name").(string),
   164  		Message: d.Get("message").(string),
   165  		Options: o,
   166  	}
   167  
   168  	return &m
   169  }
   170  
   171  func resourceDatadogMonitorExists(d *schema.ResourceData, meta interface{}) (b bool, e error) {
   172  	// Exists - This is called to verify a resource still exists. It is called prior to Read,
   173  	// and lowers the burden of Read to be able to assume the resource exists.
   174  	client := meta.(*datadog.Client)
   175  
   176  	i, err := strconv.Atoi(d.Id())
   177  	if err != nil {
   178  		return false, err
   179  	}
   180  
   181  	if _, err = client.GetMonitor(i); err != nil {
   182  		if strings.Contains(err.Error(), "404 Not Found") {
   183  			return false, nil
   184  		}
   185  		return false, err
   186  	}
   187  
   188  	return true, nil
   189  }
   190  
   191  func resourceDatadogMonitorCreate(d *schema.ResourceData, meta interface{}) error {
   192  
   193  	client := meta.(*datadog.Client)
   194  
   195  	m := buildMonitorStruct(d)
   196  	m, err := client.CreateMonitor(m)
   197  	if err != nil {
   198  		return fmt.Errorf("error updating montor: %s", err.Error())
   199  	}
   200  
   201  	d.SetId(strconv.Itoa(m.Id))
   202  
   203  	return nil
   204  }
   205  
   206  func resourceDatadogMonitorRead(d *schema.ResourceData, meta interface{}) error {
   207  	client := meta.(*datadog.Client)
   208  
   209  	i, err := strconv.Atoi(d.Id())
   210  	if err != nil {
   211  		return err
   212  	}
   213  
   214  	m, err := client.GetMonitor(i)
   215  	if err != nil {
   216  		return err
   217  	}
   218  
   219  	log.Printf("[DEBUG] monitor: %v", m)
   220  	d.Set("name", m.Name)
   221  	d.Set("message", m.Message)
   222  	d.Set("query", m.Query)
   223  	d.Set("type", m.Type)
   224  	d.Set("thresholds", m.Options.Thresholds)
   225  	d.Set("notify_no_data", m.Options.NotifyNoData)
   226  	d.Set("no_data_timeframe", m.Options.NoDataTimeframe)
   227  	d.Set("renotify_interval", m.Options.RenotifyInterval)
   228  	d.Set("notify_audit", m.Options.NotifyAudit)
   229  	d.Set("timeout_h", m.Options.TimeoutH)
   230  	d.Set("escalation_message", m.Options.EscalationMessage)
   231  	d.Set("silenced", m.Options.Silenced)
   232  	d.Set("include_tags", m.Options.IncludeTags)
   233  
   234  	return nil
   235  }
   236  
   237  func resourceDatadogMonitorUpdate(d *schema.ResourceData, meta interface{}) error {
   238  	client := meta.(*datadog.Client)
   239  
   240  	m := &datadog.Monitor{}
   241  
   242  	i, err := strconv.Atoi(d.Id())
   243  	if err != nil {
   244  		return err
   245  	}
   246  
   247  	m.Id = i
   248  	if attr, ok := d.GetOk("name"); ok {
   249  		m.Name = attr.(string)
   250  	}
   251  	if attr, ok := d.GetOk("message"); ok {
   252  		m.Message = attr.(string)
   253  	}
   254  	if attr, ok := d.GetOk("query"); ok {
   255  		m.Query = attr.(string)
   256  	}
   257  
   258  	o := datadog.Options{}
   259  	if attr, ok := d.GetOk("thresholds"); ok {
   260  		thresholds := attr.(map[string]interface{})
   261  		if thresholds["ok"] != nil {
   262  			o.Thresholds.Ok = json.Number(thresholds["ok"].(string))
   263  		}
   264  		if thresholds["warning"] != nil {
   265  			o.Thresholds.Warning = json.Number(thresholds["warning"].(string))
   266  		}
   267  		if thresholds["critical"] != nil {
   268  			o.Thresholds.Critical = json.Number(thresholds["critical"].(string))
   269  		}
   270  	}
   271  
   272  	if attr, ok := d.GetOk("notify_no_data"); ok {
   273  		o.NotifyNoData = attr.(bool)
   274  	}
   275  	if attr, ok := d.GetOk("no_data_timeframe"); ok {
   276  		o.NoDataTimeframe = attr.(int)
   277  	}
   278  	if attr, ok := d.GetOk("renotify_interval"); ok {
   279  		o.RenotifyInterval = attr.(int)
   280  	}
   281  	if attr, ok := d.GetOk("notify_audit"); ok {
   282  		o.NotifyAudit = attr.(bool)
   283  	}
   284  	if attr, ok := d.GetOk("timeout_h"); ok {
   285  		o.TimeoutH = attr.(int)
   286  	}
   287  	if attr, ok := d.GetOk("escalation_message"); ok {
   288  		o.EscalationMessage = attr.(string)
   289  	}
   290  	if attr, ok := d.GetOk("silenced"); ok {
   291  		// TODO: this is not very defensive, test if we can fail non int input
   292  		s := make(map[string]int)
   293  		for k, v := range attr.(map[string]interface{}) {
   294  			s[k], _ = strconv.Atoi(v.(string))
   295  		}
   296  		o.Silenced = s
   297  	}
   298  	if attr, ok := d.GetOk("include_tags"); ok {
   299  		o.IncludeTags = attr.(bool)
   300  	}
   301  
   302  	m.Options = o
   303  
   304  	if err = client.UpdateMonitor(m); err != nil {
   305  		return fmt.Errorf("error updating monitor: %s", err.Error())
   306  	}
   307  
   308  	return resourceDatadogMonitorRead(d, meta)
   309  }
   310  
   311  func resourceDatadogMonitorDelete(d *schema.ResourceData, meta interface{}) error {
   312  	client := meta.(*datadog.Client)
   313  
   314  	i, err := strconv.Atoi(d.Id())
   315  	if err != nil {
   316  		return err
   317  	}
   318  
   319  	if err = client.DeleteMonitor(i); err != nil {
   320  		return err
   321  	}
   322  
   323  	return nil
   324  }