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 }