github.com/richardbowden/terraform@v0.6.12-0.20160901200758-30ea22c25211/builtin/providers/datadog/resource_datadog_timeboard.go (about) 1 package datadog 2 3 import ( 4 "fmt" 5 "log" 6 "strconv" 7 "strings" 8 9 "github.com/hashicorp/terraform/helper/schema" 10 "github.com/zorkian/go-datadog-api" 11 ) 12 13 func resourceDatadogTimeboard() *schema.Resource { 14 15 request := &schema.Schema{ 16 Type: schema.TypeList, 17 Required: true, 18 Elem: &schema.Resource{ 19 Schema: map[string]*schema.Schema{ 20 "q": &schema.Schema{ 21 Type: schema.TypeString, 22 Required: true, 23 }, 24 "stacked": &schema.Schema{ 25 Type: schema.TypeBool, 26 Optional: true, 27 Default: false, 28 }, 29 }, 30 }, 31 } 32 33 graph := &schema.Schema{ 34 Type: schema.TypeList, 35 Required: true, 36 Description: "A list of graph definitions.", 37 Elem: &schema.Resource{ 38 Schema: map[string]*schema.Schema{ 39 "title": &schema.Schema{ 40 Type: schema.TypeString, 41 Required: true, 42 Description: "The name of the graph.", 43 }, 44 "viz": &schema.Schema{ 45 Type: schema.TypeString, 46 Required: true, 47 }, 48 "request": request, 49 }, 50 }, 51 } 52 53 template_variable := &schema.Schema{ 54 Type: schema.TypeList, 55 Optional: true, 56 Description: "A list of template variables for using Dashboard templating.", 57 Elem: &schema.Resource{ 58 Schema: map[string]*schema.Schema{ 59 "name": &schema.Schema{ 60 Type: schema.TypeString, 61 Required: true, 62 Description: "The name of the variable.", 63 }, 64 "prefix": &schema.Schema{ 65 Type: schema.TypeString, 66 Optional: true, 67 Description: "The tag prefix associated with the variable. Only tags with this prefix will appear in the variable dropdown.", 68 }, 69 "default": &schema.Schema{ 70 Type: schema.TypeString, 71 Optional: true, 72 Description: "The default value for the template variable on dashboard load.", 73 }, 74 }, 75 }, 76 } 77 78 return &schema.Resource{ 79 Create: resourceDatadogTimeboardCreate, 80 Update: resourceDatadogTimeboardUpdate, 81 Read: resourceDatadogTimeboardRead, 82 Delete: resourceDatadogTimeboardDelete, 83 Exists: resourceDatadogTimeboardExists, 84 85 Schema: map[string]*schema.Schema{ 86 "title": &schema.Schema{ 87 Type: schema.TypeString, 88 Required: true, 89 Description: "The name of the dashboard.", 90 }, 91 "description": &schema.Schema{ 92 Type: schema.TypeString, 93 Required: true, 94 Description: "A description of the dashboard's content.", 95 }, 96 "read_only": &schema.Schema{ 97 Type: schema.TypeBool, 98 Optional: true, 99 Default: false, 100 }, 101 "graph": graph, 102 "template_variable": template_variable, 103 }, 104 } 105 } 106 107 func buildTemplateVariables(terraformTemplateVariables *[]interface{}) *[]datadog.TemplateVariable { 108 datadogTemplateVariables := make([]datadog.TemplateVariable, len(*terraformTemplateVariables)) 109 for i, t_ := range *terraformTemplateVariables { 110 t := t_.(map[string]interface{}) 111 datadogTemplateVariables[i] = datadog.TemplateVariable{ 112 Name: t["name"].(string), 113 Prefix: t["prefix"].(string), 114 Default: t["default"].(string)} 115 } 116 return &datadogTemplateVariables 117 } 118 119 func appendRequests(datadogGraph *datadog.Graph, terraformRequests *[]interface{}) { 120 for _, t_ := range *terraformRequests { 121 t := t_.(map[string]interface{}) 122 d := struct { 123 Query string `json:"q"` 124 Stacked bool `json:"stacked"` 125 Aggregator string 126 ConditionalFormats []datadog.DashboardConditionalFormat `json:"conditional_formats,omitempty"` 127 }{Query: t["q"].(string)} 128 if stacked, ok := t["stacked"]; ok { 129 d.Stacked = stacked.(bool) 130 } 131 datadogGraph.Definition.Requests = append(datadogGraph.Definition.Requests, d) 132 } 133 } 134 135 func buildGraphs(terraformGraphs *[]interface{}) *[]datadog.Graph { 136 datadogGraphs := make([]datadog.Graph, len(*terraformGraphs)) 137 for i, t_ := range *terraformGraphs { 138 t := t_.(map[string]interface{}) 139 datadogGraphs[i] = datadog.Graph{Title: t["title"].(string)} 140 d := &datadogGraphs[i] 141 d.Definition.Viz = t["viz"].(string) 142 terraformRequests := t["request"].([]interface{}) 143 appendRequests(d, &terraformRequests) 144 } 145 return &datadogGraphs 146 } 147 148 func buildTimeboard(d *schema.ResourceData) (*datadog.Dashboard, error) { 149 var id int 150 if d.Id() != "" { 151 var err error 152 id, err = strconv.Atoi(d.Id()) 153 if err != nil { 154 return nil, err 155 } 156 } 157 terraformGraphs := d.Get("graph").([]interface{}) 158 terraformTemplateVariables := d.Get("template_variable").([]interface{}) 159 return &datadog.Dashboard{ 160 Id: id, 161 Title: d.Get("title").(string), 162 Description: d.Get("description").(string), 163 ReadOnly: d.Get("read_only").(bool), 164 Graphs: *buildGraphs(&terraformGraphs), 165 TemplateVariables: *buildTemplateVariables(&terraformTemplateVariables), 166 }, nil 167 } 168 169 func resourceDatadogTimeboardCreate(d *schema.ResourceData, meta interface{}) error { 170 timeboard, err := buildTimeboard(d) 171 if err != nil { 172 return fmt.Errorf("Failed to parse resource configuration: %s", err.Error()) 173 } 174 timeboard, err = meta.(*datadog.Client).CreateDashboard(timeboard) 175 if err != nil { 176 return fmt.Errorf("Failed to create timeboard using Datadog API: %s", err.Error()) 177 } 178 d.SetId(strconv.Itoa(timeboard.Id)) 179 return nil 180 } 181 182 func resourceDatadogTimeboardUpdate(d *schema.ResourceData, meta interface{}) error { 183 timeboard, err := buildTimeboard(d) 184 if err != nil { 185 return fmt.Errorf("Failed to parse resource configuration: %s", err.Error()) 186 } 187 if err = meta.(*datadog.Client).UpdateDashboard(timeboard); err != nil { 188 return fmt.Errorf("Failed to update timeboard using Datadog API: %s", err.Error()) 189 } 190 return resourceDatadogTimeboardRead(d, meta) 191 } 192 193 func resourceDatadogTimeboardRead(d *schema.ResourceData, meta interface{}) error { 194 id, err := strconv.Atoi(d.Id()) 195 if err != nil { 196 return err 197 } 198 timeboard, err := meta.(*datadog.Client).GetDashboard(id) 199 if err != nil { 200 return err 201 } 202 log.Printf("[DEBUG] timeboard: %v", timeboard) 203 d.Set("title", timeboard.Title) 204 d.Set("description", timeboard.Description) 205 d.Set("graphs", timeboard.Graphs) 206 d.Set("template_variables", timeboard.TemplateVariables) 207 return nil 208 } 209 210 func resourceDatadogTimeboardDelete(d *schema.ResourceData, meta interface{}) error { 211 id, err := strconv.Atoi(d.Id()) 212 if err != nil { 213 return err 214 } 215 if err = meta.(*datadog.Client).DeleteDashboard(id); err != nil { 216 return err 217 } 218 return nil 219 } 220 221 func resourceDatadogTimeboardExists(d *schema.ResourceData, meta interface{}) (b bool, e error) { 222 id, err := strconv.Atoi(d.Id()) 223 if err != nil { 224 return false, err 225 } 226 if _, err = meta.(*datadog.Client).GetDashboard(id); err != nil { 227 if strings.Contains(err.Error(), "404 Not Found") { 228 return false, nil 229 } 230 return false, err 231 } 232 return true, nil 233 }