github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/circonus/metric.go (about) 1 package circonus 2 3 // The circonusMetric type is the backing store of the `circonus_metric` resource. 4 5 import ( 6 "bytes" 7 "fmt" 8 9 "github.com/circonus-labs/circonus-gometrics/api" 10 "github.com/hashicorp/errwrap" 11 uuid "github.com/hashicorp/go-uuid" 12 "github.com/hashicorp/terraform/helper/hashcode" 13 "github.com/hashicorp/terraform/helper/schema" 14 ) 15 16 type circonusMetric struct { 17 ID metricID 18 api.CheckBundleMetric 19 } 20 21 func newMetric() circonusMetric { 22 return circonusMetric{} 23 } 24 25 func (m *circonusMetric) Create(d *schema.ResourceData) error { 26 return m.SaveState(d) 27 } 28 29 func (m *circonusMetric) ParseConfig(id string, d *schema.ResourceData) error { 30 m.ID = metricID(id) 31 32 if v, found := d.GetOk(metricNameAttr); found { 33 m.Name = v.(string) 34 } 35 36 if v, found := d.GetOk(metricActiveAttr); found { 37 m.Status = metricActiveToAPIStatus(v.(bool)) 38 } 39 40 if v, found := d.GetOk(metricTagsAttr); found { 41 m.Tags = derefStringList(flattenSet(v.(*schema.Set))) 42 } 43 44 if v, found := d.GetOk(metricTypeAttr); found { 45 m.Type = v.(string) 46 } 47 48 if v, found := d.GetOk(metricUnitAttr); found { 49 s := v.(string) 50 m.Units = &s 51 } 52 53 if m.Units != nil && *m.Units == "" { 54 m.Units = nil 55 } 56 57 return nil 58 } 59 60 func (m *circonusMetric) ParseConfigMap(id string, attrMap map[string]interface{}) error { 61 m.ID = metricID(id) 62 63 if v, found := attrMap[metricNameAttr]; found { 64 m.Name = v.(string) 65 } 66 67 if v, found := attrMap[metricActiveAttr]; found { 68 m.Status = metricActiveToAPIStatus(v.(bool)) 69 } 70 71 if v, found := attrMap[metricTagsAttr]; found { 72 m.Tags = derefStringList(flattenSet(v.(*schema.Set))) 73 } 74 75 if v, found := attrMap[metricTypeAttr]; found { 76 m.Type = v.(string) 77 } 78 79 if v, found := attrMap[metricUnitAttr]; found { 80 s := v.(string) 81 m.Units = &s 82 } 83 84 if m.Units != nil && *m.Units == "" { 85 m.Units = nil 86 } 87 88 return nil 89 } 90 91 func (m *circonusMetric) SaveState(d *schema.ResourceData) error { 92 d.SetId(string(m.ID)) 93 94 d.Set(metricActiveAttr, metricAPIStatusToBool(m.Status)) 95 d.Set(metricNameAttr, m.Name) 96 d.Set(metricTagsAttr, tagsToState(apiToTags(m.Tags))) 97 d.Set(metricTypeAttr, m.Type) 98 d.Set(metricUnitAttr, indirect(m.Units)) 99 100 return nil 101 } 102 103 func (m *circonusMetric) Update(d *schema.ResourceData) error { 104 // NOTE: there are no "updates" to be made against an API server, so we just 105 // pass through a call to SaveState. Keep this method around for API 106 // symmetry. 107 return m.SaveState(d) 108 } 109 110 func metricAPIStatusToBool(s string) bool { 111 switch s { 112 case metricStatusActive: 113 return true 114 case metricStatusAvailable: 115 return false 116 default: 117 // log.Printf("PROVIDER BUG: metric status %q unsupported", s) 118 return false 119 } 120 } 121 122 func metricActiveToAPIStatus(active bool) string { 123 if active { 124 return metricStatusActive 125 } 126 127 return metricStatusAvailable 128 } 129 130 func newMetricID() (string, error) { 131 id, err := uuid.GenerateUUID() 132 if err != nil { 133 return "", errwrap.Wrapf("metric ID creation failed: {{err}}", err) 134 } 135 136 return id, nil 137 } 138 139 func metricChecksum(m interfaceMap) int { 140 b := &bytes.Buffer{} 141 b.Grow(defaultHashBufSize) 142 143 // Order writes to the buffer using lexically sorted list for easy visual 144 // reconciliation with other lists. 145 if v, found := m[metricActiveAttr]; found { 146 fmt.Fprintf(b, "%t", v.(bool)) 147 } 148 149 if v, found := m[metricNameAttr]; found { 150 fmt.Fprint(b, v.(string)) 151 } 152 153 if v, found := m[metricTagsAttr]; found { 154 tags := derefStringList(flattenSet(v.(*schema.Set))) 155 for _, tag := range tags { 156 fmt.Fprint(b, tag) 157 } 158 } 159 160 if v, found := m[metricTypeAttr]; found { 161 fmt.Fprint(b, v.(string)) 162 } 163 164 if v, found := m[metricUnitAttr]; found { 165 if v != nil { 166 var s string 167 switch v.(type) { 168 case string: 169 s = v.(string) 170 case *string: 171 s = *v.(*string) 172 } 173 174 if s != "" { 175 fmt.Fprint(b, s) 176 } 177 } 178 } 179 180 s := b.String() 181 return hashcode.String(s) 182 }