github.com/nevins-b/terraform@v0.3.8-0.20170215184714-bbae22007d5a/builtin/providers/librato/resource_librato_space_chart.go (about) 1 package librato 2 3 import ( 4 "bytes" 5 "fmt" 6 "log" 7 "math" 8 "strconv" 9 "time" 10 11 "github.com/hashicorp/terraform/helper/hashcode" 12 "github.com/hashicorp/terraform/helper/resource" 13 "github.com/hashicorp/terraform/helper/schema" 14 "github.com/henrikhodne/go-librato/librato" 15 ) 16 17 func resourceLibratoSpaceChart() *schema.Resource { 18 return &schema.Resource{ 19 Create: resourceLibratoSpaceChartCreate, 20 Read: resourceLibratoSpaceChartRead, 21 Update: resourceLibratoSpaceChartUpdate, 22 Delete: resourceLibratoSpaceChartDelete, 23 24 Schema: map[string]*schema.Schema{ 25 "space_id": &schema.Schema{ 26 Type: schema.TypeInt, 27 Required: true, 28 ForceNew: true, 29 }, 30 "name": &schema.Schema{ 31 Type: schema.TypeString, 32 Required: true, 33 }, 34 "type": &schema.Schema{ 35 Type: schema.TypeString, 36 Required: true, 37 ForceNew: true, 38 }, 39 "min": &schema.Schema{ 40 Type: schema.TypeFloat, 41 Default: math.NaN(), 42 Optional: true, 43 }, 44 "max": &schema.Schema{ 45 Type: schema.TypeFloat, 46 Default: math.NaN(), 47 Optional: true, 48 }, 49 "label": &schema.Schema{ 50 Type: schema.TypeString, 51 Optional: true, 52 }, 53 "related_space": &schema.Schema{ 54 Type: schema.TypeInt, 55 Optional: true, 56 }, 57 "stream": &schema.Schema{ 58 Type: schema.TypeSet, 59 Optional: true, 60 Elem: &schema.Resource{ 61 Schema: map[string]*schema.Schema{ 62 "metric": &schema.Schema{ 63 Type: schema.TypeString, 64 Optional: true, 65 ConflictsWith: []string{"stream.composite"}, 66 }, 67 "source": &schema.Schema{ 68 Type: schema.TypeString, 69 Optional: true, 70 ConflictsWith: []string{"stream.composite"}, 71 }, 72 "group_function": &schema.Schema{ 73 Type: schema.TypeString, 74 Optional: true, 75 ConflictsWith: []string{"stream.composite"}, 76 }, 77 "composite": &schema.Schema{ 78 Type: schema.TypeString, 79 Optional: true, 80 ConflictsWith: []string{"stream.metric", "stream.source", "stream.group_function"}, 81 }, 82 "summary_function": &schema.Schema{ 83 Type: schema.TypeString, 84 Optional: true, 85 }, 86 "name": &schema.Schema{ 87 Type: schema.TypeString, 88 Optional: true, 89 }, 90 "color": &schema.Schema{ 91 Type: schema.TypeString, 92 Optional: true, 93 }, 94 "units_short": &schema.Schema{ 95 Type: schema.TypeString, 96 Optional: true, 97 }, 98 "units_long": &schema.Schema{ 99 Type: schema.TypeString, 100 Optional: true, 101 }, 102 "min": &schema.Schema{ 103 Type: schema.TypeFloat, 104 Default: math.NaN(), 105 Optional: true, 106 }, 107 "max": &schema.Schema{ 108 Type: schema.TypeFloat, 109 Default: math.NaN(), 110 Optional: true, 111 }, 112 "transform_function": &schema.Schema{ 113 Type: schema.TypeString, 114 Optional: true, 115 }, 116 "period": &schema.Schema{ 117 Type: schema.TypeInt, 118 Optional: true, 119 }, 120 }, 121 }, 122 Set: resourceLibratoSpaceChartHash, 123 }, 124 }, 125 } 126 } 127 128 func resourceLibratoSpaceChartHash(v interface{}) int { 129 var buf bytes.Buffer 130 m := v.(map[string]interface{}) 131 buf.WriteString(fmt.Sprintf("%s-", m["metric"].(string))) 132 buf.WriteString(fmt.Sprintf("%s-", m["source"].(string))) 133 buf.WriteString(fmt.Sprintf("%s-", m["composite"].(string))) 134 135 return hashcode.String(buf.String()) 136 } 137 138 func resourceLibratoSpaceChartCreate(d *schema.ResourceData, meta interface{}) error { 139 client := meta.(*librato.Client) 140 141 spaceID := uint(d.Get("space_id").(int)) 142 143 spaceChart := new(librato.SpaceChart) 144 if v, ok := d.GetOk("name"); ok { 145 spaceChart.Name = librato.String(v.(string)) 146 } 147 if v, ok := d.GetOk("type"); ok { 148 spaceChart.Type = librato.String(v.(string)) 149 } 150 if v, ok := d.GetOk("min"); ok { 151 if math.IsNaN(v.(float64)) { 152 spaceChart.Min = nil 153 } else { 154 spaceChart.Min = librato.Float(v.(float64)) 155 } 156 } 157 if v, ok := d.GetOk("max"); ok { 158 if math.IsNaN(v.(float64)) { 159 spaceChart.Max = nil 160 } else { 161 spaceChart.Max = librato.Float(v.(float64)) 162 } 163 } 164 if v, ok := d.GetOk("label"); ok { 165 spaceChart.Label = librato.String(v.(string)) 166 } 167 if v, ok := d.GetOk("related_space"); ok { 168 spaceChart.RelatedSpace = librato.Uint(uint(v.(int))) 169 } 170 if v, ok := d.GetOk("stream"); ok { 171 vs := v.(*schema.Set) 172 streams := make([]librato.SpaceChartStream, vs.Len()) 173 for i, streamDataM := range vs.List() { 174 streamData := streamDataM.(map[string]interface{}) 175 var stream librato.SpaceChartStream 176 if v, ok := streamData["metric"].(string); ok && v != "" { 177 stream.Metric = librato.String(v) 178 } 179 if v, ok := streamData["source"].(string); ok && v != "" { 180 stream.Source = librato.String(v) 181 } 182 if v, ok := streamData["composite"].(string); ok && v != "" { 183 stream.Composite = librato.String(v) 184 } 185 if v, ok := streamData["group_function"].(string); ok && v != "" { 186 stream.GroupFunction = librato.String(v) 187 } 188 if v, ok := streamData["summary_function"].(string); ok && v != "" { 189 stream.SummaryFunction = librato.String(v) 190 } 191 if v, ok := streamData["transform_function"].(string); ok && v != "" { 192 stream.TransformFunction = librato.String(v) 193 } 194 if v, ok := streamData["color"].(string); ok && v != "" { 195 stream.Color = librato.String(v) 196 } 197 if v, ok := streamData["units_short"].(string); ok && v != "" { 198 stream.UnitsShort = librato.String(v) 199 } 200 if v, ok := streamData["units_longs"].(string); ok && v != "" { 201 stream.UnitsLong = librato.String(v) 202 } 203 if v, ok := streamData["min"].(float64); ok && !math.IsNaN(v) { 204 stream.Min = librato.Float(v) 205 } 206 if v, ok := streamData["max"].(float64); ok && !math.IsNaN(v) { 207 stream.Max = librato.Float(v) 208 } 209 streams[i] = stream 210 } 211 spaceChart.Streams = streams 212 } 213 214 spaceChartResult, _, err := client.Spaces.CreateChart(spaceID, spaceChart) 215 if err != nil { 216 return fmt.Errorf("Error creating Librato space chart %s: %s", *spaceChart.Name, err) 217 } 218 219 resource.Retry(1*time.Minute, func() *resource.RetryError { 220 _, _, err := client.Spaces.GetChart(spaceID, *spaceChartResult.ID) 221 if err != nil { 222 if errResp, ok := err.(*librato.ErrorResponse); ok && errResp.Response.StatusCode == 404 { 223 return resource.RetryableError(err) 224 } 225 return resource.NonRetryableError(err) 226 } 227 return nil 228 }) 229 230 return resourceLibratoSpaceChartReadResult(d, spaceChartResult) 231 } 232 233 func resourceLibratoSpaceChartRead(d *schema.ResourceData, meta interface{}) error { 234 client := meta.(*librato.Client) 235 236 spaceID := uint(d.Get("space_id").(int)) 237 238 id, err := strconv.ParseUint(d.Id(), 10, 0) 239 if err != nil { 240 return err 241 } 242 243 chart, _, err := client.Spaces.GetChart(spaceID, uint(id)) 244 if err != nil { 245 if errResp, ok := err.(*librato.ErrorResponse); ok && errResp.Response.StatusCode == 404 { 246 d.SetId("") 247 return nil 248 } 249 return fmt.Errorf("Error reading Librato Space chart %s: %s", d.Id(), err) 250 } 251 252 return resourceLibratoSpaceChartReadResult(d, chart) 253 } 254 255 func resourceLibratoSpaceChartReadResult(d *schema.ResourceData, chart *librato.SpaceChart) error { 256 d.SetId(strconv.FormatUint(uint64(*chart.ID), 10)) 257 if chart.Name != nil { 258 if err := d.Set("name", *chart.Name); err != nil { 259 return err 260 } 261 } 262 if chart.Type != nil { 263 if err := d.Set("type", *chart.Type); err != nil { 264 return err 265 } 266 } 267 if chart.Min != nil { 268 if err := d.Set("min", *chart.Min); err != nil { 269 return err 270 } 271 } 272 if chart.Max != nil { 273 if err := d.Set("max", *chart.Max); err != nil { 274 return err 275 } 276 } 277 if chart.Label != nil { 278 if err := d.Set("label", *chart.Label); err != nil { 279 return err 280 } 281 } 282 if chart.RelatedSpace != nil { 283 if err := d.Set("related_space", *chart.RelatedSpace); err != nil { 284 return err 285 } 286 } 287 288 streams := resourceLibratoSpaceChartStreamsGather(d, chart.Streams) 289 if err := d.Set("stream", streams); err != nil { 290 return err 291 } 292 293 return nil 294 } 295 296 func resourceLibratoSpaceChartStreamsGather(d *schema.ResourceData, streams []librato.SpaceChartStream) []map[string]interface{} { 297 retStreams := make([]map[string]interface{}, 0, len(streams)) 298 for _, s := range streams { 299 stream := make(map[string]interface{}) 300 if s.Metric != nil { 301 stream["metric"] = *s.Metric 302 } 303 if s.Source != nil { 304 stream["source"] = *s.Source 305 } 306 if s.Composite != nil { 307 stream["composite"] = *s.Composite 308 } 309 if s.GroupFunction != nil { 310 stream["group_function"] = *s.GroupFunction 311 } 312 if s.SummaryFunction != nil { 313 stream["summary_function"] = *s.SummaryFunction 314 } 315 if s.TransformFunction != nil { 316 stream["transform_function"] = *s.TransformFunction 317 } 318 if s.Color != nil { 319 stream["color"] = *s.Color 320 } 321 if s.UnitsShort != nil { 322 stream["units_short"] = *s.UnitsShort 323 } 324 if s.UnitsLong != nil { 325 stream["units_long"] = *s.UnitsLong 326 } 327 retStreams = append(retStreams, stream) 328 } 329 330 return retStreams 331 } 332 333 func resourceLibratoSpaceChartUpdate(d *schema.ResourceData, meta interface{}) error { 334 client := meta.(*librato.Client) 335 336 spaceID := uint(d.Get("space_id").(int)) 337 chartID, err := strconv.ParseUint(d.Id(), 10, 0) 338 if err != nil { 339 return err 340 } 341 342 spaceChart := new(librato.SpaceChart) 343 if d.HasChange("name") { 344 spaceChart.Name = librato.String(d.Get("name").(string)) 345 } 346 if d.HasChange("min") { 347 if math.IsNaN(d.Get("min").(float64)) { 348 spaceChart.Min = nil 349 } else { 350 spaceChart.Min = librato.Float(d.Get("min").(float64)) 351 } 352 } 353 if d.HasChange("max") { 354 if math.IsNaN(d.Get("max").(float64)) { 355 spaceChart.Max = nil 356 } else { 357 spaceChart.Max = librato.Float(d.Get("max").(float64)) 358 } 359 } 360 if d.HasChange("label") { 361 spaceChart.Label = librato.String(d.Get("label").(string)) 362 } 363 if d.HasChange("related_space") { 364 spaceChart.RelatedSpace = librato.Uint(d.Get("related_space").(uint)) 365 } 366 if d.HasChange("stream") { 367 vs := d.Get("stream").(*schema.Set) 368 streams := make([]librato.SpaceChartStream, vs.Len()) 369 for i, streamDataM := range vs.List() { 370 streamData := streamDataM.(map[string]interface{}) 371 var stream librato.SpaceChartStream 372 if v, ok := streamData["metric"].(string); ok && v != "" { 373 stream.Metric = librato.String(v) 374 } 375 if v, ok := streamData["source"].(string); ok && v != "" { 376 stream.Source = librato.String(v) 377 } 378 if v, ok := streamData["composite"].(string); ok && v != "" { 379 stream.Composite = librato.String(v) 380 } 381 if v, ok := streamData["group_function"].(string); ok && v != "" { 382 stream.GroupFunction = librato.String(v) 383 } 384 if v, ok := streamData["summary_function"].(string); ok && v != "" { 385 stream.SummaryFunction = librato.String(v) 386 } 387 if v, ok := streamData["transform_function"].(string); ok && v != "" { 388 stream.TransformFunction = librato.String(v) 389 } 390 if v, ok := streamData["color"].(string); ok && v != "" { 391 stream.Color = librato.String(v) 392 } 393 if v, ok := streamData["units_short"].(string); ok && v != "" { 394 stream.UnitsShort = librato.String(v) 395 } 396 if v, ok := streamData["units_longs"].(string); ok && v != "" { 397 stream.UnitsLong = librato.String(v) 398 } 399 if v, ok := streamData["min"].(float64); ok && !math.IsNaN(v) { 400 stream.Min = librato.Float(v) 401 } 402 if v, ok := streamData["max"].(float64); ok && !math.IsNaN(v) { 403 stream.Max = librato.Float(v) 404 } 405 streams[i] = stream 406 } 407 spaceChart.Streams = streams 408 } 409 410 _, err = client.Spaces.EditChart(spaceID, uint(chartID), spaceChart) 411 if err != nil { 412 return fmt.Errorf("Error updating Librato space chart %s: %s", *spaceChart.Name, err) 413 } 414 415 return resourceLibratoSpaceChartRead(d, meta) 416 } 417 418 func resourceLibratoSpaceChartDelete(d *schema.ResourceData, meta interface{}) error { 419 client := meta.(*librato.Client) 420 421 spaceID := uint(d.Get("space_id").(int)) 422 423 id, err := strconv.ParseUint(d.Id(), 10, 0) 424 if err != nil { 425 return err 426 } 427 428 log.Printf("[INFO] Deleting Chart: %d/%d", spaceID, uint(id)) 429 _, err = client.Spaces.DeleteChart(spaceID, uint(id)) 430 if err != nil { 431 return fmt.Errorf("Error deleting space: %s", err) 432 } 433 434 resource.Retry(1*time.Minute, func() *resource.RetryError { 435 _, _, err := client.Spaces.GetChart(spaceID, uint(id)) 436 if err != nil { 437 if errResp, ok := err.(*librato.ErrorResponse); ok && errResp.Response.StatusCode == 404 { 438 return nil 439 } 440 return resource.NonRetryableError(err) 441 } 442 return resource.RetryableError(fmt.Errorf("space chart still exists")) 443 }) 444 445 d.SetId("") 446 return nil 447 }