github.com/subuk/terraform@v0.6.14-0.20160317140351-de1567c2e732/builtin/providers/datadog/resource_datadog_monitor.go (about)

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