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  }