Skip to content

Commit 9a38640

Browse files
authored
Merge pull request #353 from SumoLogic/INVS-11_match_list_match_items
INVS-11: CSE Matchlist/matchlist items support
2 parents 2819760 + 2fe64ca commit 9a38640

9 files changed

+828
-14
lines changed

.github/workflows/test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ jobs:
5454
name: Matrix Test
5555
needs: build
5656
runs-on: ubuntu-latest
57-
timeout-minutes: 25
57+
timeout-minutes: 35
5858
strategy:
5959
fail-fast: false
6060
matrix:
@@ -77,7 +77,7 @@ jobs:
7777
go mod download
7878
7979
- name: TF acceptance tests
80-
timeout-minutes: 20
80+
timeout-minutes: 30
8181
env:
8282
TF_ACC: "1"
8383
TF_ACC_TERRAFORM_VERSION: ${{ matrix.terraform }}

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
## 2.14.0 (Unreleased)
2+
* **New Resource:** sumologic_cse_match_list (GH-353)
23

34
## 2.13.0 (February 24, 2022)
45

sumologic/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ func Provider() terraform.ResourceProvider {
4343
},
4444
},
4545
ResourcesMap: map[string]*schema.Resource{
46+
"sumologic_cse_match_list": resourceSumologicCSEMatchList(),
4647
"sumologic_cse_log_mapping": resourceSumologicCSELogMapping(),
4748
"sumologic_cse_rule_tuning_expression": resourceSumologicCSERuleTuningExpression(),
4849
"sumologic_cse_network_block": resourceSumologicCSENetworkBlock(),

sumologic/resource_sumologic_cse_log_mapping.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -427,18 +427,18 @@ func setFields(d *schema.ResourceData, fields []CSELogMappingField) {
427427
mapping := map[string]interface{}{
428428
"name": t.Name,
429429
"value": t.Value,
430-
"value_type": t.Value,
431-
"skipped_values": t.Value,
432-
"default_value": t.Value,
433-
"format": t.Value,
434-
"case_insensitive": t.Value,
435-
"alternate_values": t.Value,
436-
"time_zone": t.Value,
437-
"split_delimiter": t.Value,
438-
"split_index": t.Value,
439-
"field_join": t.Value,
440-
"join_delimiter": t.Value,
441-
"format_parameters": t.Value,
430+
"value_type": t.ValueType,
431+
"skipped_values": t.SkippedValues,
432+
"default_value": t.DefaultValue,
433+
"format": t.Format,
434+
"case_insensitive": t.CaseInsensitive,
435+
"alternate_values": t.AlternateValues,
436+
"time_zone": t.TimeZone,
437+
"split_delimiter": t.SplitDelimiter,
438+
"split_index": t.SplitIndex,
439+
"field_join": t.FieldJoin,
440+
"join_delimiter": t.JoinDelimiter,
441+
"format_parameters": t.FormatParameters,
442442
"lookup": getLookUpResource(t.LookUp),
443443
}
444444
f = append(f, mapping)
Lines changed: 331 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,331 @@
1+
package sumologic
2+
3+
import (
4+
"fmt"
5+
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
6+
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
7+
"log"
8+
"time"
9+
)
10+
11+
func resourceSumologicCSEMatchList() *schema.Resource {
12+
return &schema.Resource{
13+
Create: resourceSumologicCSEMatchListCreate,
14+
Read: resourceSumologicCSEMatchListRead,
15+
Delete: resourceSumologicCSEMatchListDelete,
16+
Update: resourceSumologicCSEMatchListUpdate,
17+
Importer: &schema.ResourceImporter{
18+
State: schema.ImportStatePassthrough,
19+
},
20+
21+
Schema: map[string]*schema.Schema{
22+
"default_ttl": {
23+
Type: schema.TypeInt,
24+
Optional: true,
25+
ForceNew: false,
26+
},
27+
"description": {
28+
Type: schema.TypeString,
29+
Required: true,
30+
ForceNew: false,
31+
},
32+
"name": {
33+
Type: schema.TypeString,
34+
Required: true,
35+
ForceNew: false,
36+
},
37+
"target_column": {
38+
Type: schema.TypeString,
39+
Required: true,
40+
ForceNew: false,
41+
},
42+
"created": {
43+
Type: schema.TypeString,
44+
Computed: true,
45+
},
46+
"created_by": {
47+
Type: schema.TypeString,
48+
Computed: true,
49+
},
50+
"last_updated": {
51+
Type: schema.TypeString,
52+
Computed: true,
53+
},
54+
"last_updated_by": {
55+
Type: schema.TypeString,
56+
Computed: true,
57+
},
58+
"items": {
59+
Type: schema.TypeList,
60+
Optional: true,
61+
Elem: &schema.Resource{
62+
Schema: map[string]*schema.Schema{
63+
"id": {
64+
Type: schema.TypeString,
65+
Computed: true,
66+
},
67+
"description": {
68+
Type: schema.TypeString,
69+
Required: true,
70+
ForceNew: false,
71+
},
72+
"expiration": {
73+
Type: schema.TypeString,
74+
Optional: true,
75+
ForceNew: false,
76+
},
77+
"value": {
78+
Type: schema.TypeString,
79+
Required: true,
80+
ForceNew: false,
81+
},
82+
},
83+
},
84+
},
85+
},
86+
}
87+
}
88+
89+
func resourceSumologicCSEMatchListRead(d *schema.ResourceData, meta interface{}) error {
90+
c := meta.(*Client)
91+
92+
var CSEMatchList *CSEMatchListGet
93+
id := d.Id()
94+
95+
CSEMatchList, err := c.GetCSEMatchList(id)
96+
if err != nil {
97+
log.Printf("[WARN] CSE Match List not found when looking by id: %s, err: %v", id, err)
98+
99+
}
100+
101+
if CSEMatchList == nil {
102+
log.Printf("[WARN] CSE Match List not found, removing from state: %v - %v", id, err)
103+
d.SetId("")
104+
return nil
105+
}
106+
107+
d.Set("name", CSEMatchList.Name)
108+
d.Set("default_ttl", CSEMatchList.DefaultTtl)
109+
d.Set("description", CSEMatchList.Description)
110+
d.Set("name", CSEMatchList.Name)
111+
d.Set("target_column", CSEMatchList.TargetColumn)
112+
d.Set("created", CSEMatchList.Created)
113+
d.Set("created_by", CSEMatchList.CreatedBy)
114+
d.Set("last_updated", CSEMatchList.LastUpdated)
115+
d.Set("last_updated_by", CSEMatchList.LastUpdatedBy)
116+
117+
//items
118+
var CSEMatchListItems *CSEMatchListItemsInMatchListGet
119+
120+
CSEMatchListItems, err2 := c.GetCSEMatchListItemsInMatchList(id)
121+
if err2 != nil {
122+
log.Printf("[WARN] CSE Match List items not found when looking by match list id: %s, err: %v", id, err2)
123+
}
124+
if CSEMatchListItems == nil {
125+
d.Set("items", nil)
126+
} else {
127+
setItems(d, CSEMatchListItems.CSEMatchListItemsGetObjects)
128+
}
129+
130+
return nil
131+
}
132+
133+
func setItems(d *schema.ResourceData, items []CSEMatchListItemGet) {
134+
135+
var its []map[string]interface{}
136+
137+
for _, t := range items {
138+
item := map[string]interface{}{
139+
"id": t.ID,
140+
"description": t.Meta.Description,
141+
"expiration": t.Expiration,
142+
"value": t.Value,
143+
}
144+
its = append(its, item)
145+
}
146+
147+
d.Set("items", its)
148+
149+
}
150+
151+
func resourceSumologicCSEMatchListDelete(d *schema.ResourceData, meta interface{}) error {
152+
c := meta.(*Client)
153+
err := c.DeleteCSEMatchList(d.Id())
154+
return err
155+
156+
}
157+
158+
func resourceSumologicCSEMatchListCreate(d *schema.ResourceData, meta interface{}) error {
159+
c := meta.(*Client)
160+
161+
if d.Id() == "" {
162+
id, err := c.CreateCSEMatchList(CSEMatchListPost{
163+
Active: true,
164+
DefaultTtl: d.Get("default_ttl").(int),
165+
Description: d.Get("description").(string),
166+
Name: d.Get("name").(string),
167+
TargetColumn: d.Get("target_column").(string),
168+
})
169+
170+
if err != nil {
171+
return err
172+
}
173+
d.SetId(id)
174+
175+
//Match list items
176+
itemsData := d.Get("items").([]interface{})
177+
var items []CSEMatchListItemPost
178+
for _, data := range itemsData {
179+
item, _ := resourceToCSEMatchListItem([]interface{}{data})
180+
items = append(items, item)
181+
182+
}
183+
184+
if len(items) > 0 {
185+
err2 := c.CreateCSEMatchListItems(items, id)
186+
if err2 != nil {
187+
log.Printf("[WARN] An error occurred while adding match list items to match list id: %s, err: %v", id, err2)
188+
}
189+
190+
}
191+
192+
createStateConf := &resource.StateChangeConf{
193+
Target: []string{
194+
fmt.Sprint(len(items)),
195+
},
196+
Refresh: func() (interface{}, string, error) {
197+
resp, err := c.GetCSEMatchListItemsInMatchList(d.Id())
198+
if err != nil {
199+
return 0, "", err
200+
}
201+
return resp, fmt.Sprint(len(resp.CSEMatchListItemsGetObjects)), nil
202+
},
203+
Timeout: d.Timeout(schema.TimeoutCreate),
204+
Delay: 10 * time.Second,
205+
MinTimeout: 5 * time.Second,
206+
ContinuousTargetOccurence: 1,
207+
}
208+
209+
_, err = createStateConf.WaitForState()
210+
if err != nil {
211+
return fmt.Errorf("error waiting for match list (%s) to be created: %s", d.Id(), err)
212+
}
213+
214+
}
215+
216+
return resourceSumologicCSEMatchListRead(d, meta)
217+
}
218+
219+
func resourceToCSEMatchListItem(data interface{}) (CSEMatchListItemPost, string) {
220+
itemsSlice := data.([]interface{})
221+
item := CSEMatchListItemPost{}
222+
if len(itemsSlice) > 0 {
223+
itemObj := itemsSlice[0].(map[string]interface{})
224+
item.ID = itemObj["id"].(string)
225+
item.Description = itemObj["description"].(string)
226+
item.Active = true
227+
item.Expiration = itemObj["expiration"].(string)
228+
item.Value = itemObj["value"].(string)
229+
}
230+
return item, item.ID
231+
}
232+
233+
func resourceSumologicCSEMatchListUpdate(d *schema.ResourceData, meta interface{}) error {
234+
CSEMatchListPost, err := resourceToCSEMatchList(d)
235+
if err != nil {
236+
return err
237+
}
238+
239+
c := meta.(*Client)
240+
if err = c.UpdateCSEMatchList(CSEMatchListPost); err != nil {
241+
return err
242+
}
243+
244+
//Match list items
245+
itemsData := d.Get("items").([]interface{})
246+
var itemIds []string
247+
var items []CSEMatchListItemPost
248+
for _, data := range itemsData {
249+
item, id := resourceToCSEMatchListItem([]interface{}{data})
250+
item.ID = ""
251+
items = append(items, item)
252+
itemIds = append(itemIds, id)
253+
254+
}
255+
256+
if len(items) > 0 {
257+
err2 := c.CreateCSEMatchListItems(items, d.Id())
258+
if err2 != nil {
259+
log.Printf("[WARN] An error occurred while adding match list items to match list id: %s, err: %v", d.Id(), err2)
260+
}
261+
262+
}
263+
264+
var CSEMatchListItems *CSEMatchListItemsInMatchListGet
265+
266+
CSEMatchListItems, err2 := c.GetCSEMatchListItemsInMatchList(d.Id())
267+
if err2 != nil {
268+
log.Printf("[WARN] CSE Match List items not found when looking by match list id: %s, err: %v", d.Id(), err2)
269+
}
270+
if CSEMatchListItems != nil {
271+
272+
for _, t := range CSEMatchListItems.CSEMatchListItemsGetObjects {
273+
if !contains(itemIds, t.ID) {
274+
err3 := c.DeleteCSEMatchListItem(t.ID)
275+
if err3 != nil {
276+
log.Printf("[WARN] An error occurred deleting match list item with id: %s, err: %v", t.ID, err3)
277+
}
278+
}
279+
}
280+
}
281+
282+
createStateConf := &resource.StateChangeConf{
283+
Target: []string{
284+
fmt.Sprint(len(items)),
285+
},
286+
Refresh: func() (interface{}, string, error) {
287+
resp, err := c.GetCSEMatchListItemsInMatchList(d.Id())
288+
if err != nil {
289+
return 0, "", err
290+
}
291+
return resp, fmt.Sprint(len(resp.CSEMatchListItemsGetObjects)), nil
292+
},
293+
Timeout: d.Timeout(schema.TimeoutUpdate),
294+
Delay: 10 * time.Second,
295+
MinTimeout: 5 * time.Second,
296+
ContinuousTargetOccurence: 1,
297+
}
298+
299+
_, err = createStateConf.WaitForState()
300+
if err != nil {
301+
return fmt.Errorf("error waiting for match list (%s) to be updated: %s", d.Id(), err)
302+
}
303+
304+
return resourceSumologicCSEMatchListRead(d, meta)
305+
}
306+
307+
func contains(slice []string, item string) bool {
308+
set := make(map[string]struct{}, len(slice))
309+
for _, s := range slice {
310+
set[s] = struct{}{}
311+
}
312+
313+
_, ok := set[item]
314+
return ok
315+
}
316+
317+
func resourceToCSEMatchList(d *schema.ResourceData) (CSEMatchListPost, error) {
318+
id := d.Id()
319+
if id == "" {
320+
return CSEMatchListPost{}, nil
321+
}
322+
323+
return CSEMatchListPost{
324+
ID: id,
325+
Active: true,
326+
DefaultTtl: d.Get("default_ttl").(int),
327+
Description: d.Get("description").(string),
328+
Name: d.Get("name").(string),
329+
TargetColumn: d.Get("target_column").(string),
330+
}, nil
331+
}

0 commit comments

Comments
 (0)