github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/newrelic/resource_newrelic_alert_condition.go (about)

     1  package newrelic
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"strconv"
     7  
     8  	"github.com/hashicorp/terraform/helper/schema"
     9  	"github.com/hashicorp/terraform/helper/validation"
    10  	newrelic "github.com/paultyng/go-newrelic/api"
    11  )
    12  
    13  var alertConditionTypes = map[string][]string{
    14  	"apm_app_metric": []string{
    15  		"apdex",
    16  		"error_percentage",
    17  		"response_time_background",
    18  		"response_time_web",
    19  		"throughput_background",
    20  		"throughput_web",
    21  		"user_defined",
    22  	},
    23  	"apm_kt_metric": []string{
    24  		"apdex",
    25  		"error_count",
    26  		"error_percentage",
    27  		"response_time",
    28  		"throughput",
    29  	},
    30  	"browser_metric": []string{
    31  		"ajax_response_time",
    32  		"ajax_throughput",
    33  		"dom_processing",
    34  		"end_user_apdex",
    35  		"network",
    36  		"page_rendering",
    37  		"page_view_throughput",
    38  		"page_views_with_js_errors",
    39  		"request_queuing",
    40  		"total_page_load",
    41  		"user_defined",
    42  		"web_application",
    43  	},
    44  	"mobile_metric": []string{
    45  		"database",
    46  		"images",
    47  		"json",
    48  		"mobile_crash_rate",
    49  		"network_error_percentage",
    50  		"network",
    51  		"status_error_percentage",
    52  		"user_defined",
    53  		"view_loading",
    54  	},
    55  	"servers_metric": []string{
    56  		"cpu_percentage",
    57  		"disk_io_percentage",
    58  		"fullest_disk_percentage",
    59  		"load_average_one_minute",
    60  		"memory_percentage",
    61  		"user_defined",
    62  	},
    63  }
    64  
    65  func resourceNewRelicAlertCondition() *schema.Resource {
    66  	validAlertConditionTypes := make([]string, 0, len(alertConditionTypes))
    67  	for k := range alertConditionTypes {
    68  		validAlertConditionTypes = append(validAlertConditionTypes, k)
    69  	}
    70  
    71  	return &schema.Resource{
    72  		Create: resourceNewRelicAlertConditionCreate,
    73  		Read:   resourceNewRelicAlertConditionRead,
    74  		Update: resourceNewRelicAlertConditionUpdate,
    75  		Delete: resourceNewRelicAlertConditionDelete,
    76  		Importer: &schema.ResourceImporter{
    77  			State: schema.ImportStatePassthrough,
    78  		},
    79  		Schema: map[string]*schema.Schema{
    80  			"policy_id": {
    81  				Type:     schema.TypeInt,
    82  				Required: true,
    83  				ForceNew: true,
    84  			},
    85  			"name": {
    86  				Type:     schema.TypeString,
    87  				Required: true,
    88  			},
    89  			"type": {
    90  				Type:         schema.TypeString,
    91  				Required:     true,
    92  				ValidateFunc: validation.StringInSlice(validAlertConditionTypes, false),
    93  			},
    94  			"entities": {
    95  				Type:     schema.TypeList,
    96  				Elem:     &schema.Schema{Type: schema.TypeInt},
    97  				Required: true,
    98  				MinItems: 1,
    99  			},
   100  			"metric": {
   101  				Type:     schema.TypeString,
   102  				Required: true,
   103  				//TODO: ValidateFunc from map
   104  			},
   105  			"runbook_url": {
   106  				Type:     schema.TypeString,
   107  				Optional: true,
   108  			},
   109  			"term": {
   110  				Type: schema.TypeList,
   111  				Elem: &schema.Resource{
   112  					Schema: map[string]*schema.Schema{
   113  						"duration": {
   114  							Type:         schema.TypeInt,
   115  							Required:     true,
   116  							ValidateFunc: intInSlice([]int{5, 10, 15, 30, 60, 120}),
   117  						},
   118  						"operator": {
   119  							Type:         schema.TypeString,
   120  							Optional:     true,
   121  							Default:      "equal",
   122  							ValidateFunc: validation.StringInSlice([]string{"above", "below", "equal"}, false),
   123  						},
   124  						"priority": {
   125  							Type:         schema.TypeString,
   126  							Optional:     true,
   127  							Default:      "critical",
   128  							ValidateFunc: validation.StringInSlice([]string{"critical", "warning"}, false),
   129  						},
   130  						"threshold": {
   131  							Type:         schema.TypeFloat,
   132  							Required:     true,
   133  							ValidateFunc: float64Gte(0.0),
   134  						},
   135  						"time_function": {
   136  							Type:         schema.TypeString,
   137  							Required:     true,
   138  							ValidateFunc: validation.StringInSlice([]string{"all", "any"}, false),
   139  						},
   140  					},
   141  				},
   142  				Required: true,
   143  				MinItems: 1,
   144  			},
   145  			"user_defined_metric": {
   146  				Type:     schema.TypeString,
   147  				Optional: true,
   148  			},
   149  			"user_defined_value_function": {
   150  				Type:         schema.TypeString,
   151  				Optional:     true,
   152  				ValidateFunc: validation.StringInSlice([]string{"average", "min", "max", "total", "sample_size"}, false),
   153  			},
   154  		},
   155  	}
   156  }
   157  
   158  func buildAlertConditionStruct(d *schema.ResourceData) *newrelic.AlertCondition {
   159  	entitySet := d.Get("entities").([]interface{})
   160  	entities := make([]string, len(entitySet))
   161  
   162  	for i, entity := range entitySet {
   163  		entities[i] = strconv.Itoa(entity.(int))
   164  	}
   165  
   166  	termSet := d.Get("term").([]interface{})
   167  	terms := make([]newrelic.AlertConditionTerm, len(termSet))
   168  
   169  	for i, termI := range termSet {
   170  		termM := termI.(map[string]interface{})
   171  
   172  		terms[i] = newrelic.AlertConditionTerm{
   173  			Duration:     termM["duration"].(int),
   174  			Operator:     termM["operator"].(string),
   175  			Priority:     termM["priority"].(string),
   176  			Threshold:    termM["threshold"].(float64),
   177  			TimeFunction: termM["time_function"].(string),
   178  		}
   179  	}
   180  
   181  	condition := newrelic.AlertCondition{
   182  		Type:     d.Get("type").(string),
   183  		Name:     d.Get("name").(string),
   184  		Enabled:  true,
   185  		Entities: entities,
   186  		Metric:   d.Get("metric").(string),
   187  		Terms:    terms,
   188  		PolicyID: d.Get("policy_id").(int),
   189  	}
   190  
   191  	if attr, ok := d.GetOk("runbook_url"); ok {
   192  		condition.RunbookURL = attr.(string)
   193  	}
   194  
   195  	if attrM, ok := d.GetOk("user_defined_metric"); ok {
   196  		if attrVF, ok := d.GetOk("user_defined_value_function"); ok {
   197  			condition.UserDefined = newrelic.AlertConditionUserDefined{
   198  				Metric:        attrM.(string),
   199  				ValueFunction: attrVF.(string),
   200  			}
   201  		}
   202  	}
   203  
   204  	return &condition
   205  }
   206  
   207  func readAlertConditionStruct(condition *newrelic.AlertCondition, d *schema.ResourceData) error {
   208  	ids, err := parseIDs(d.Id(), 2)
   209  	if err != nil {
   210  		return err
   211  	}
   212  
   213  	policyID := ids[0]
   214  
   215  	entities := make([]int, len(condition.Entities))
   216  	for i, entity := range condition.Entities {
   217  		v, err := strconv.ParseInt(entity, 10, 32)
   218  		if err != nil {
   219  			return err
   220  		}
   221  		entities[i] = int(v)
   222  	}
   223  
   224  	d.Set("policy_id", policyID)
   225  	d.Set("name", condition.Name)
   226  	d.Set("type", condition.Type)
   227  	d.Set("metric", condition.Metric)
   228  	d.Set("runbook_url", condition.RunbookURL)
   229  	d.Set("user_defined_metric", condition.UserDefined.Metric)
   230  	d.Set("user_defined_value_function", condition.UserDefined.ValueFunction)
   231  	if err := d.Set("entities", entities); err != nil {
   232  		return fmt.Errorf("[DEBUG] Error setting alert condition entities: %#v", err)
   233  	}
   234  
   235  	var terms []map[string]interface{}
   236  
   237  	for _, src := range condition.Terms {
   238  		dst := map[string]interface{}{
   239  			"duration":      src.Duration,
   240  			"operator":      src.Operator,
   241  			"priority":      src.Priority,
   242  			"threshold":     src.Threshold,
   243  			"time_function": src.TimeFunction,
   244  		}
   245  		terms = append(terms, dst)
   246  	}
   247  
   248  	if err := d.Set("term", terms); err != nil {
   249  		return fmt.Errorf("[DEBUG] Error setting alert condition terms: %#v", err)
   250  	}
   251  
   252  	return nil
   253  }
   254  
   255  func resourceNewRelicAlertConditionCreate(d *schema.ResourceData, meta interface{}) error {
   256  	client := meta.(*newrelic.Client)
   257  	condition := buildAlertConditionStruct(d)
   258  
   259  	log.Printf("[INFO] Creating New Relic alert condition %s", condition.Name)
   260  
   261  	condition, err := client.CreateAlertCondition(*condition)
   262  	if err != nil {
   263  		return err
   264  	}
   265  
   266  	d.SetId(serializeIDs([]int{condition.PolicyID, condition.ID}))
   267  
   268  	return nil
   269  }
   270  
   271  func resourceNewRelicAlertConditionRead(d *schema.ResourceData, meta interface{}) error {
   272  	client := meta.(*newrelic.Client)
   273  
   274  	log.Printf("[INFO] Reading New Relic alert condition %s", d.Id())
   275  
   276  	ids, err := parseIDs(d.Id(), 2)
   277  	if err != nil {
   278  		return err
   279  	}
   280  
   281  	policyID := ids[0]
   282  	id := ids[1]
   283  
   284  	condition, err := client.GetAlertCondition(policyID, id)
   285  	if err != nil {
   286  		if err == newrelic.ErrNotFound {
   287  			d.SetId("")
   288  			return nil
   289  		}
   290  
   291  		return err
   292  	}
   293  
   294  	return readAlertConditionStruct(condition, d)
   295  }
   296  
   297  func resourceNewRelicAlertConditionUpdate(d *schema.ResourceData, meta interface{}) error {
   298  	client := meta.(*newrelic.Client)
   299  	condition := buildAlertConditionStruct(d)
   300  
   301  	ids, err := parseIDs(d.Id(), 2)
   302  	if err != nil {
   303  		return err
   304  	}
   305  
   306  	policyID := ids[0]
   307  	id := ids[1]
   308  
   309  	condition.PolicyID = policyID
   310  	condition.ID = id
   311  
   312  	log.Printf("[INFO] Updating New Relic alert condition %d", id)
   313  
   314  	updatedCondition, err := client.UpdateAlertCondition(*condition)
   315  	if err != nil {
   316  		return err
   317  	}
   318  
   319  	return readAlertConditionStruct(updatedCondition, d)
   320  }
   321  
   322  func resourceNewRelicAlertConditionDelete(d *schema.ResourceData, meta interface{}) error {
   323  	client := meta.(*newrelic.Client)
   324  
   325  	ids, err := parseIDs(d.Id(), 2)
   326  	if err != nil {
   327  		return err
   328  	}
   329  
   330  	policyID := ids[0]
   331  	id := ids[1]
   332  
   333  	log.Printf("[INFO] Deleting New Relic alert condition %d", id)
   334  
   335  	if err := client.DeleteAlertCondition(policyID, id); err != nil {
   336  		return err
   337  	}
   338  
   339  	d.SetId("")
   340  
   341  	return nil
   342  }