Skip to content

Commit 1e4a043

Browse files
committed
SUMO-226102:added TF support for muting schedule
1 parent 88b6805 commit 1e4a043

6 files changed

+968
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
## 2.25.1 (Unreleased)
2+
FEATURES:
3+
* **New Resource:** sumologic_muting_schedule
24
* resource/sumologic_monitor: Added support for associating tags with a Monitor.
35

46
## 2.25.0 (August 8, 2023)

sumologic/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ func Provider() terraform.ResourceProvider {
9494
"sumologic_connection": resourceSumologicConnection(),
9595
"sumologic_monitor": resourceSumologicMonitorsLibraryMonitor(),
9696
"sumologic_monitor_folder": resourceSumologicMonitorsLibraryFolder(),
97+
"sumologic_muting_schedule": resourceSumologicMutingSchedulesLibraryMutingSchedule(),
9798
"sumologic_slo": resourceSumologicSLO(),
9899
"sumologic_slo_folder": resourceSumologicSLOLibraryFolder(),
99100
"sumologic_ingest_budget_v2": resourceSumologicIngestBudgetV2(),
Lines changed: 361 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,361 @@
1+
package sumologic
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"regexp"
7+
"time"
8+
9+
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
10+
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
11+
)
12+
13+
func resourceSumologicMutingSchedulesLibraryMutingSchedule() *schema.Resource {
14+
return &schema.Resource{
15+
Create: resourceSumologicMutingSchedulesLibraryMutingScheduleCreate,
16+
Read: resourceSumologicMutingSchedulesLibraryMutingScheduleRead,
17+
Update: resourceSumologicMutingSchedulesLibraryMutingScheduleUpdate,
18+
Delete: resourceSumologicMutingSchedulesLibraryMutingScheduleDelete,
19+
Importer: &schema.ResourceImporter{
20+
State: schema.ImportStatePassthrough,
21+
},
22+
23+
Schema: getMutingScheduleSchema(),
24+
}
25+
}
26+
27+
func getMutingScheduleBaseSchema() map[string]*schema.Schema {
28+
return map[string]*schema.Schema{
29+
30+
"name": {
31+
Type: schema.TypeString,
32+
Required: true,
33+
ValidateFunc: validation.All(
34+
validation.StringDoesNotContainAny("/"),
35+
validation.StringLenBetween(1, 255),
36+
validation.StringMatch(regexp.MustCompile(`(?s)^[^\ ].*[^\ ]$`),
37+
"name must not contain leading or trailing spaces"),
38+
),
39+
},
40+
41+
"description": {
42+
Type: schema.TypeString,
43+
Optional: true,
44+
ValidateFunc: validation.All(
45+
validation.StringLenBetween(0, 4096),
46+
validation.StringMatch(regexp.MustCompile(`(?s)^[^\ ].*[^\ ]$`),
47+
"description must not contain leading or trailing spaces"),
48+
),
49+
},
50+
51+
"parent_id": {
52+
Type: schema.TypeString,
53+
Optional: true,
54+
Computed: true,
55+
},
56+
57+
"monitor": {
58+
Type: schema.TypeList,
59+
Optional: true,
60+
MaxItems: 1,
61+
Elem: &schema.Resource{
62+
Schema: getMonitorScopeSchema(),
63+
},
64+
AtLeastOneOf: monitorAtleastOneKey,
65+
},
66+
67+
"schedule": {
68+
Type: schema.TypeList,
69+
Required: true,
70+
MaxItems: 1,
71+
Elem: &schema.Resource{
72+
Schema: getScheduleDefinitionSchemma(),
73+
},
74+
},
75+
76+
"version": {
77+
Type: schema.TypeInt,
78+
Optional: true,
79+
Computed: true,
80+
},
81+
}
82+
}
83+
84+
func getMonitorScopeSchema() map[string]*schema.Schema {
85+
return map[string]*schema.Schema{
86+
"ids": {
87+
Type: schema.TypeList,
88+
Optional: true,
89+
Elem: &schema.Schema{
90+
Type: schema.TypeString,
91+
ValidateFunc: validation.StringIsNotEmpty,
92+
},
93+
},
94+
"all": {
95+
Type: schema.TypeBool,
96+
Optional: true,
97+
},
98+
}
99+
}
100+
101+
func getScheduleDefinitionSchemma() map[string]*schema.Schema {
102+
return map[string]*schema.Schema{
103+
"timezone": {
104+
Type: schema.TypeString,
105+
Required: true,
106+
ForceNew: false,
107+
},
108+
"start_date": {
109+
Type: schema.TypeString,
110+
ForceNew: false,
111+
Required: true,
112+
ValidateFunc: validation.All(
113+
validation.StringMatch(regexp.MustCompile(`^\d{4}-\d{2}-\d{2}$`),
114+
"start date in format of yyyy-mm-dd"),
115+
StartDateIsAfterYesterday(),
116+
),
117+
},
118+
"start_time": {
119+
Type: schema.TypeString,
120+
Required: true,
121+
ForceNew: false,
122+
ValidateFunc: validation.All(
123+
validation.StringMatch(regexp.MustCompile(`^(?:[01]\d|2[0-3]):[0-5]\d$`),
124+
"start time in format of 00:00"),
125+
),
126+
},
127+
"duration": {
128+
Type: schema.TypeInt,
129+
Required: true,
130+
ForceNew: false,
131+
ValidateFunc: validation.IntAtLeast(15),
132+
},
133+
"rrule": {
134+
Type: schema.TypeString,
135+
Optional: true,
136+
},
137+
"is_form": {
138+
Type: schema.TypeBool,
139+
Optional: true,
140+
},
141+
}
142+
}
143+
144+
func getMutingScheduleSchema() map[string]*schema.Schema {
145+
tfSchema := getMutingScheduleBaseSchema()
146+
147+
additionalAttributes := map[string]*schema.Schema{
148+
149+
"type": {
150+
Type: schema.TypeString,
151+
Optional: true,
152+
Default: "MutingSchedulesLibraryMutingSchedule",
153+
ValidateFunc: validation.StringInSlice([]string{"MutingSchedulesLibraryMutingSchedule", "MutingSchedulesLibraryFolder"}, false),
154+
},
155+
156+
"content_type": {
157+
Type: schema.TypeString,
158+
Optional: true,
159+
Default: "MutingSchedule",
160+
},
161+
162+
"is_system": {
163+
Type: schema.TypeBool,
164+
Optional: true,
165+
Computed: true,
166+
},
167+
168+
"is_mutable": {
169+
Type: schema.TypeBool,
170+
Optional: true,
171+
Computed: true,
172+
},
173+
174+
"created_by": {
175+
Type: schema.TypeString,
176+
Optional: true,
177+
Computed: true,
178+
},
179+
180+
"created_at": {
181+
Type: schema.TypeString,
182+
Optional: true,
183+
Computed: true,
184+
},
185+
186+
"modified_by": {
187+
Type: schema.TypeString,
188+
Optional: true,
189+
Computed: true,
190+
},
191+
192+
"modified_at": {
193+
Type: schema.TypeString,
194+
Optional: true,
195+
Computed: true,
196+
},
197+
}
198+
199+
for k, v := range additionalAttributes {
200+
tfSchema[k] = v
201+
}
202+
203+
return tfSchema
204+
}
205+
206+
func resourceSumologicMutingSchedulesLibraryMutingScheduleCreate(d *schema.ResourceData, meta interface{}) error {
207+
c := meta.(*Client)
208+
209+
if d.Id() == "" {
210+
mutingSchedule := resourceToMutingSchedulesLibraryMutingSchedule(d)
211+
if mutingSchedule.ParentID == "" {
212+
rootFolder, err := c.GetMutingSchedulesLibraryFolder("root")
213+
if err != nil {
214+
return err
215+
}
216+
217+
mutingSchedule.ParentID = rootFolder.ID
218+
}
219+
paramMap := map[string]string{
220+
"parentId": mutingSchedule.ParentID,
221+
}
222+
mutingScheduleDefinitionID, err := c.CreateMutingSchedulesLibraryMutingSchedule(mutingSchedule, paramMap)
223+
if err != nil {
224+
return err
225+
}
226+
d.SetId(mutingScheduleDefinitionID)
227+
}
228+
return resourceSumologicMutingSchedulesLibraryMutingScheduleRead(d, meta)
229+
}
230+
231+
func resourceSumologicMutingSchedulesLibraryMutingScheduleRead(d *schema.ResourceData, meta interface{}) error {
232+
c := meta.(*Client)
233+
234+
mutingSchedule, err := c.MutingSchedulesRead(d.Id())
235+
if err != nil {
236+
return err
237+
}
238+
239+
if mutingSchedule == nil {
240+
log.Printf("[WARN] MutingSchedule not found, removing from state: %v - %v", d.Id(), err)
241+
d.SetId("")
242+
return nil
243+
}
244+
245+
d.Set("created_by", mutingSchedule.CreatedBy)
246+
d.Set("created_at", mutingSchedule.CreatedAt)
247+
d.Set("modified_by", mutingSchedule.ModifiedBy)
248+
d.Set("is_mutable", mutingSchedule.IsMutable)
249+
d.Set("version", mutingSchedule.Version)
250+
d.Set("description", mutingSchedule.Description)
251+
d.Set("name", mutingSchedule.Name)
252+
d.Set("parent_id", mutingSchedule.ParentID)
253+
d.Set("modified_at", mutingSchedule.ModifiedAt)
254+
d.Set("content_type", mutingSchedule.ContentType)
255+
d.Set("is_system", mutingSchedule.IsSystem)
256+
d.Set("monitor", mutingSchedule.Monitor)
257+
d.Set("schedule", mutingSchedule.Schedule)
258+
259+
return nil
260+
}
261+
262+
func resourceSumologicMutingSchedulesLibraryMutingScheduleUpdate(d *schema.ResourceData, meta interface{}) error {
263+
c := meta.(*Client)
264+
mutingSchedule := resourceToMutingSchedulesLibraryMutingSchedule(d)
265+
266+
mutingSchedule.Type = "MutingSchedulesLibraryMutingScheduleUpdate"
267+
err := c.UpdateMutingSchedulesLibraryMutingSchedule(mutingSchedule)
268+
if err != nil {
269+
return err
270+
}
271+
updatedMutingSchedule := resourceSumologicMutingSchedulesLibraryMutingScheduleRead(d, meta)
272+
return updatedMutingSchedule
273+
}
274+
275+
func resourceSumologicMutingSchedulesLibraryMutingScheduleDelete(d *schema.ResourceData, meta interface{}) error {
276+
c := meta.(*Client)
277+
mutingSchedule := resourceToMutingSchedulesLibraryMutingSchedule(d)
278+
err := c.DeleteMutingSchedulesLibraryMutingSchedule(mutingSchedule.ID)
279+
if err != nil {
280+
return err
281+
}
282+
return nil
283+
}
284+
285+
func getMonitorScope(d *schema.ResourceData) *MonitorScope {
286+
monitorMap := d.Get("monitor").([]interface{})
287+
if len(monitorMap) == 0 {
288+
return nil
289+
} else {
290+
monitorScopeDict := monitorMap[0].(map[string]interface{})
291+
monitorScope := MonitorScope{
292+
Ids: fieldsToStringArray(monitorScopeDict["ids"].([]interface{})),
293+
All: monitorScopeDict["all"].(bool),
294+
}
295+
return &monitorScope
296+
}
297+
}
298+
299+
func getScheduleDefinition(d *schema.ResourceData) ScheduleDefinition {
300+
scheduleDefinitionMap := d.Get("schedule").([]interface{})
301+
scheduleDefinitionDict := scheduleDefinitionMap[0].(map[string]interface{})
302+
scheduleDefinition := ScheduleDefinition{
303+
TimeZone: scheduleDefinitionDict["timezone"].(string),
304+
StartDate: scheduleDefinitionDict["start_date"].(string),
305+
StartTime: scheduleDefinitionDict["start_time"].(string),
306+
Duration: scheduleDefinitionDict["duration"].(int),
307+
RRule: scheduleDefinitionDict["rrule"].(string),
308+
IsForm: scheduleDefinitionDict["is_form"].(bool),
309+
}
310+
return scheduleDefinition
311+
}
312+
313+
func StartDateIsAfterYesterday() schema.SchemaValidateFunc {
314+
return func(i interface{}, k string) (warnings []string, errors []error) {
315+
v, ok := i.(string)
316+
if !ok {
317+
return warnings, []error{fmt.Errorf("expected type of %q to be string", k)}
318+
}
319+
320+
date, err := time.Parse("2006-01-02", v)
321+
322+
if err != nil {
323+
return warnings, []error{fmt.Errorf("expected %q to be an valid start date yyyy-mm-dd : got %v", k, v)}
324+
}
325+
326+
yesterday := time.Now().AddDate(0, 0, -1).Truncate(24 * time.Hour)
327+
328+
if date.Before(yesterday) {
329+
return warnings, []error{fmt.Errorf("expected %q to be an valid start date : got %v", k, v)}
330+
}
331+
return warnings, errors
332+
}
333+
}
334+
335+
var monitorAtleastOneKey = []string{
336+
"monitor.0.ids",
337+
"monitor.0.all",
338+
}
339+
340+
func resourceToMutingSchedulesLibraryMutingSchedule(d *schema.ResourceData) MutingSchedulesLibraryMutingSchedule {
341+
monitorScope := getMonitorScope(d)
342+
scheduleDefinition := getScheduleDefinition(d)
343+
344+
return MutingSchedulesLibraryMutingSchedule{
345+
CreatedBy: d.Get("created_by").(string),
346+
Name: d.Get("name").(string),
347+
ID: d.Id(),
348+
CreatedAt: d.Get("created_at").(string),
349+
Description: d.Get("description").(string),
350+
ModifiedBy: d.Get("modified_by").(string),
351+
IsMutable: d.Get("is_mutable").(bool),
352+
Version: d.Get("version").(int),
353+
Type: d.Get("type").(string),
354+
ParentID: d.Get("parent_id").(string),
355+
ModifiedAt: d.Get("modified_at").(string),
356+
ContentType: d.Get("content_type").(string),
357+
IsSystem: d.Get("is_system").(bool),
358+
Schedule: scheduleDefinition,
359+
Monitor: monitorScope,
360+
}
361+
}

0 commit comments

Comments
 (0)