Skip to content

Commit ed2ae9e

Browse files
committed
SUMO-260843: Terraform support for macros
1 parent 8b61fec commit ed2ae9e

File tree

3 files changed

+349
-0
lines changed

3 files changed

+349
-0
lines changed

sumologic/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ func Provider() *schema.Provider {
104104
"sumologic_lookup_table": resourceSumologicLookupTable(),
105105
"sumologic_subdomain": resourceSumologicSubdomain(),
106106
"sumologic_dashboard": resourceSumologicDashboard(),
107+
"sumologic_macro": resourceSumologicMacro(),
107108
"sumologic_password_policy": resourceSumologicPasswordPolicy(),
108109
"sumologic_saml_configuration": resourceSumologicSamlConfiguration(),
109110
"sumologic_kinesis_metrics_source": resourceSumologicKinesisMetricsSource(),
Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
package sumologic
2+
3+
import (
4+
"log"
5+
6+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
8+
)
9+
10+
var (
11+
validArgumentTypes = []string{
12+
"String",
13+
"Any",
14+
"Number",
15+
"Keyword",
16+
}
17+
)
18+
19+
func resourceSumologicMacro() *schema.Resource {
20+
return &schema.Resource{
21+
Create: resourceSumologicMacroCreate,
22+
Read: resourceSumologicMacroRead,
23+
Delete: resourceSumologicMacroDelete,
24+
Update: resourceSumologicMacroUpdate,
25+
Importer: &schema.ResourceImporter{
26+
State: schema.ImportStatePassthrough,
27+
},
28+
29+
Schema: map[string]*schema.Schema{
30+
"name": {
31+
Type: schema.TypeString,
32+
Required: true,
33+
ForceNew: true,
34+
ValidateFunc: validation.StringLenBetween(1, 128),
35+
},
36+
"description": {
37+
Type: schema.TypeString,
38+
Optional: true,
39+
},
40+
"definition": {
41+
Type: schema.TypeString,
42+
Required: true,
43+
},
44+
"enabled": {
45+
Type: schema.TypeBool,
46+
Optional: true,
47+
Default: true,
48+
},
49+
"argument": {
50+
Type: schema.TypeList,
51+
Optional: true,
52+
Elem: &schema.Resource{
53+
Schema: getArgumentsSchema(),
54+
},
55+
},
56+
"argument_validation": {
57+
Type: schema.TypeList,
58+
Optional: true,
59+
Elem: &schema.Resource{
60+
Schema: getArgumentValidationsSchema(),
61+
},
62+
},
63+
},
64+
}
65+
}
66+
67+
func getArgumentsSchema() map[string]*schema.Schema {
68+
return map[string]*schema.Schema{
69+
"name": {
70+
Type: schema.TypeString,
71+
Required: true,
72+
},
73+
"type": {
74+
Type: schema.TypeString,
75+
Optional: true,
76+
ValidateFunc: validation.StringInSlice(validArgumentTypes, false),
77+
},
78+
}
79+
}
80+
81+
func getArgumentValidationsSchema() map[string]*schema.Schema {
82+
return map[string]*schema.Schema{
83+
"eval_expression": {
84+
Type: schema.TypeString,
85+
Required: true,
86+
},
87+
"error_message": {
88+
Type: schema.TypeString,
89+
Optional: true,
90+
},
91+
}
92+
}
93+
94+
func resourceToMacro(d *schema.ResourceData) Macro {
95+
var arguments []Argument
96+
if val, ok := d.GetOk("argument"); ok {
97+
tfArguments := val.([]interface{})
98+
for _, tfArgument := range tfArguments {
99+
argument := getArgument(tfArgument.(map[string]interface{}))
100+
arguments = append(arguments, argument)
101+
}
102+
}
103+
104+
var argumentValidations []Argumentvalidation
105+
if val, ok := d.GetOk("argument_validation"); ok {
106+
tfArgumentValidations := val.([]interface{})
107+
for _, tfArgumentValidation := range tfArgumentValidations {
108+
argumentValidation := getArgumentValidation(tfArgumentValidation.(map[string]interface{}))
109+
argumentValidations = append(argumentValidations, argumentValidation)
110+
}
111+
}
112+
113+
return Macro{
114+
ID: d.Id(),
115+
Name: d.Get("name").(string),
116+
Description: d.Get("description").(string),
117+
Definition: d.Get("definition").(string),
118+
Enabled: d.Get("enabled").(bool),
119+
Arguments: arguments,
120+
ArgumentValidations: argumentValidations,
121+
}
122+
}
123+
124+
func getArgument(tfArgument map[string]interface{}) Argument {
125+
var argument Argument
126+
127+
if val, ok := tfArgument["name"]; ok {
128+
argument.Name = val.(string)
129+
}
130+
131+
if val, ok := tfArgument["type"]; ok {
132+
argument.Type = val.(string)
133+
}
134+
return argument
135+
}
136+
137+
func getArgumentValidation(tfArgumentValidation map[string]interface{}) Argumentvalidation {
138+
var argumentValidation Argumentvalidation
139+
140+
if val, ok := tfArgumentValidation["eval_expression"]; ok {
141+
argumentValidation.EvalExpression = val.(string)
142+
}
143+
144+
if val, ok := tfArgumentValidation["error_message"]; ok {
145+
argumentValidation.ErrorMessage = val.(string)
146+
}
147+
return argumentValidation
148+
}
149+
150+
func setMacro(d *schema.ResourceData, macro *Macro) error {
151+
if err := d.Set("name", macro.Name); err != nil {
152+
return err
153+
}
154+
if err := d.Set("description", macro.Description); err != nil {
155+
return err
156+
}
157+
158+
if err := d.Set("definition", macro.Definition); err != nil {
159+
return err
160+
}
161+
162+
if err := d.Set("enabled", macro.Enabled); err != nil {
163+
return err
164+
}
165+
166+
arguments := getTerraformArguments(macro.Arguments)
167+
if err := d.Set("argument", arguments); err != nil {
168+
return err
169+
}
170+
171+
argumentValidations := getTerraformArgumentValidations(macro.ArgumentValidations)
172+
if err := d.Set("argument_validation", argumentValidations); err != nil {
173+
return err
174+
}
175+
176+
log.Println("=====================================================================")
177+
log.Printf("name: %s\n", d.Get("name"))
178+
log.Printf("description: %s\n", d.Get("description"))
179+
log.Printf("definition: %s\n", d.Get("definition"))
180+
log.Printf("enabled: %s\n", d.Get("enabled"))
181+
log.Printf("arguments: %+v\n", d.Get("arguments"))
182+
log.Printf("argumentValidations: %+v\n", d.Get("argument_validation"))
183+
log.Println("=====================================================================")
184+
return nil
185+
}
186+
187+
func getTerraformArguments(arguments []Argument) []map[string]interface{} {
188+
tfArguments := make([]map[string]interface{}, len(arguments))
189+
190+
for i, argument := range arguments {
191+
tfArguments[i] = make(map[string]interface{})
192+
tfArguments[i]["name"] = argument.Name
193+
tfArguments[i]["type"] = argument.Type
194+
}
195+
return tfArguments
196+
}
197+
198+
func getTerraformArgumentValidations(argumentValidations []Argumentvalidation) []map[string]interface{} {
199+
tfArgumentValidations := make([]map[string]interface{}, len(argumentValidations))
200+
201+
for i, argumentValidation := range argumentValidations {
202+
tfArgumentValidations[i] = make(map[string]interface{})
203+
tfArgumentValidations[i]["eval_expression"] = argumentValidation.EvalExpression
204+
tfArgumentValidations[i]["error_message"] = argumentValidation.ErrorMessage
205+
}
206+
return tfArgumentValidations
207+
}
208+
209+
func resourceSumologicMacroCreate(d *schema.ResourceData, meta interface{}) error {
210+
c := meta.(*Client)
211+
if d.Id() == "" {
212+
macro := resourceToMacro(d)
213+
log.Println("=====================================================================")
214+
log.Printf("Creating macro: %+v\n", macro)
215+
log.Println("=====================================================================")
216+
217+
createdMacro, err := c.CreateMacro(macro)
218+
if err != nil {
219+
return err
220+
}
221+
d.SetId(createdMacro.ID)
222+
}
223+
224+
return resourceSumologicMacroRead(d, meta)
225+
}
226+
227+
func resourceSumologicMacroRead(d *schema.ResourceData, meta interface{}) error {
228+
c := meta.(*Client)
229+
230+
id := d.Id()
231+
macro, err := c.GetMacro(id)
232+
log.Println("=====================================================================")
233+
log.Printf("Read macro: %+v\n", macro)
234+
log.Println("=====================================================================")
235+
if err != nil {
236+
return err
237+
}
238+
239+
if macro == nil {
240+
log.Printf("[WARN] Macro not found, removing from state: %v - %v", id, err)
241+
d.SetId("")
242+
return nil
243+
}
244+
245+
err = setMacro(d, macro)
246+
return err
247+
}
248+
249+
func resourceSumologicMacroDelete(d *schema.ResourceData, meta interface{}) error {
250+
c := meta.(*Client)
251+
log.Printf("Deleting macro: %+v\n", d.Id())
252+
return c.DeleteMacro(d.Id())
253+
}
254+
255+
func resourceSumologicMacroUpdate(d *schema.ResourceData, meta interface{}) error {
256+
macro := resourceToMacro(d)
257+
log.Println("=====================================================================")
258+
log.Printf("Updating macro: %+v\n", macro)
259+
log.Println("=====================================================================")
260+
261+
c := meta.(*Client)
262+
err := c.UpdateMacro(macro)
263+
264+
if err != nil {
265+
return err
266+
}
267+
268+
return resourceSumologicMacroRead(d, meta)
269+
}

sumologic/sumologic_macro.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package sumologic
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"log"
7+
)
8+
9+
// ---------- ENDPOINTS ----------
10+
11+
func (s *Client) CreateMacro(macroReq Macro) (*Macro, error) {
12+
responseBody, err := s.Post("v2/macros", macroReq)
13+
if err != nil {
14+
return nil, err
15+
}
16+
17+
var macro Macro
18+
err = json.Unmarshal(responseBody, &macro)
19+
if err != nil {
20+
return nil, err
21+
}
22+
log.Printf("[CreateMacro] response: %+v\n", macro)
23+
return &macro, nil
24+
25+
}
26+
27+
func (s *Client) GetMacro(id string) (*Macro, error) {
28+
url := fmt.Sprintf("v2/macros/%s", id)
29+
data, err := s.Get(url)
30+
if err != nil {
31+
return nil, err
32+
}
33+
if data == nil {
34+
return nil, nil
35+
}
36+
37+
var macro Macro
38+
err = json.Unmarshal(data, &macro)
39+
if err != nil {
40+
return nil, err
41+
}
42+
log.Printf("[GetMacro] response: %+v\n", macro)
43+
return &macro, nil
44+
}
45+
46+
func (s *Client) DeleteMacro(id string) error {
47+
url := fmt.Sprintf("v2/macros/%s", id)
48+
_, err := s.Delete(url)
49+
return err
50+
}
51+
52+
func (s *Client) UpdateMacro(macro Macro) error {
53+
url := fmt.Sprintf("v2/macros/%s", macro.ID)
54+
_, err := s.Put(url, macro)
55+
return err
56+
}
57+
58+
// ---------- TYPES ----------
59+
type Macro struct {
60+
ID string `json:"id,omitempty"`
61+
Name string `json:"name"`
62+
Description string `json:"description"`
63+
Definition string `json:"definition"`
64+
Enabled bool `json:"enabled"`
65+
Arguments []Argument `json:"arguments"`
66+
ArgumentValidations []Argumentvalidation `json:"argumentValidations"`
67+
}
68+
69+
type Argument struct {
70+
Name string `json:"name"`
71+
Type string `json:"type"`
72+
}
73+
74+
type Argumentvalidation struct {
75+
EvalExpression string `json:"evalExpression"`
76+
ErrorMessage string `json:"errorMessage"`
77+
}
78+
79+
// ---------- END ----------

0 commit comments

Comments
 (0)