Skip to content

Commit 70a9b9b

Browse files
authored
Merge pull request #480 from SumoLogic/pgupta-monitor-based-slo-support
SUMO-209281 Terraform support for monitor based SLOs
2 parents 6c40082 + 41f1802 commit 70a9b9b

File tree

3 files changed

+138
-8
lines changed

3 files changed

+138
-8
lines changed

sumologic/resource_sumologic_slo.go

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010

1111
const fieldNameWindowBasedEvaluation = `window_based_evaluation`
1212
const fieldNameRequestBasedEvaluation = `request_based_evaluation`
13+
const fieldNameMonitorBasedEvaluation = `monitor_based_evaluation`
1314
const sloContentTypeString = "Slo"
1415

1516
func resourceSumologicSLO() *schema.Resource {
@@ -116,6 +117,41 @@ func resourceSumologicSLO() *schema.Resource {
116117
},
117118
}
118119

120+
triggerTypeSchema := &schema.Schema{
121+
Type: schema.TypeString,
122+
ValidateFunc: validation.StringInSlice([]string{
123+
"Critical", "Warning", "MissingData",
124+
}, false),
125+
}
126+
127+
monitorTriggerSchema := &schema.Resource{
128+
Schema: map[string]*schema.Schema{
129+
"monitor_id": {
130+
Type: schema.TypeString,
131+
Required: true,
132+
},
133+
"trigger_types": {
134+
Type: schema.TypeList,
135+
MinItems: 1,
136+
MaxItems: 1,
137+
Elem: triggerTypeSchema,
138+
Required: true,
139+
},
140+
},
141+
}
142+
143+
monitorBasedIndicatorSchema := &schema.Resource{
144+
Schema: map[string]*schema.Schema{
145+
"monitor_triggers": {
146+
Type: schema.TypeList,
147+
MinItems: 1,
148+
MaxItems: 1,
149+
Required: true,
150+
Elem: monitorTriggerSchema,
151+
},
152+
},
153+
}
154+
119155
return &schema.Resource{
120156
Create: resourceSumologicSLOCreate,
121157
Read: resourceSLORead,
@@ -231,6 +267,12 @@ func resourceSumologicSLO() *schema.Resource {
231267
Optional: true,
232268
Elem: requestBasedIndicatorSchema,
233269
},
270+
fieldNameMonitorBasedEvaluation: {
271+
Type: schema.TypeList,
272+
MaxItems: 1,
273+
Optional: true,
274+
Elem: monitorBasedIndicatorSchema,
275+
},
234276
},
235277
},
236278
},
@@ -386,6 +428,8 @@ func flattenSLOIndicator(ind SLOIndicator) (map[string]interface{}, error) {
386428
return flattenRequestIndicator(ind)
387429
case "Window":
388430
return flattenWindowIndicator(ind)
431+
case "Monitor":
432+
return flattenMonitorIndicator(ind)
389433
default:
390434
return nil, fmt.Errorf("unhandled indicator type found : %s", ind.EvaluationType)
391435
}
@@ -410,6 +454,29 @@ func flattenRequestIndicator(ind SLOIndicator) (map[string]interface{}, error) {
410454
}, nil
411455
}
412456

457+
func flattenMonitorIndicator(ind SLOIndicator) (map[string]interface{}, error) {
458+
monitorIndicator := map[string]interface{}{}
459+
monitorTriggers, err := flattenMonitorTriggers(ind.MonitorTriggers)
460+
if err != nil {
461+
return nil, err
462+
}
463+
monitorIndicator["monitor_triggers"] = monitorTriggers
464+
return map[string]interface{}{
465+
fieldNameMonitorBasedEvaluation: []interface{}{monitorIndicator},
466+
}, nil
467+
}
468+
469+
func flattenMonitorTriggers(triggers []MonitorTrigger) ([]interface{}, error) {
470+
var triggerList []interface{}
471+
for _, trigger := range triggers {
472+
queryMap := map[string]interface{}{}
473+
queryMap["monitor_id"] = trigger.MonitorId
474+
queryMap["trigger_types"] = trigger.TriggerTypes
475+
triggerList = append(triggerList, queryMap)
476+
}
477+
return triggerList, nil
478+
}
479+
413480
func flattenWindowIndicator(ind SLOIndicator) (map[string]interface{}, error) {
414481
windowIndicator := map[string]interface{}{}
415482
windowIndicator["query_type"] = ind.QueryType
@@ -582,7 +649,34 @@ func getSLOIndicator(d *schema.ResourceData) (*SLOIndicator, error) {
582649
}, nil
583650
}
584651

585-
return nil, fmt.Errorf("can't find indicator in resource, valid types are '%s' and '%s'", fieldNameRequestBasedEvaluation, fieldNameWindowBasedEvaluation)
652+
if indicatorWrapperDict[fieldNameMonitorBasedEvaluation] != nil &&
653+
len(indicatorWrapperDict[fieldNameMonitorBasedEvaluation].([]interface{})) > 0 {
654+
indicatorDictList := indicatorWrapperDict[fieldNameMonitorBasedEvaluation].([]interface{})
655+
var monitorTriggers []MonitorTrigger
656+
for _, indicatorDictElem := range indicatorDictList {
657+
indicatorDictElemMapped := indicatorDictElem.(map[string]interface{})
658+
monitorTriggersMappedArray := indicatorDictElemMapped["monitor_triggers"].([]interface{})
659+
for _, monitorTriggersElem := range monitorTriggersMappedArray {
660+
monitorIdResult := monitorTriggersElem.(map[string]interface{})["monitor_id"].(string)
661+
triggerTypes := monitorTriggersElem.(map[string]interface{})["trigger_types"].([]interface{})
662+
var triggerTypesResult []string
663+
for _, triggerType := range triggerTypes {
664+
triggerTypesResult = append(triggerTypesResult, triggerType.(string))
665+
}
666+
monitorTriggers = append(monitorTriggers, MonitorTrigger{
667+
MonitorId: monitorIdResult,
668+
TriggerTypes: triggerTypesResult,
669+
})
670+
}
671+
}
672+
673+
return &SLOIndicator{
674+
EvaluationType: "Monitor",
675+
MonitorTriggers: monitorTriggers,
676+
}, nil
677+
}
678+
679+
return nil, fmt.Errorf("can't find indicator in resource, valid types are '%s', '%s' and '%s'", fieldNameRequestBasedEvaluation, fieldNameWindowBasedEvaluation, fieldNameMonitorBasedEvaluation)
586680
}
587681

588682
func GetSLOIndicatorQueries(queriesRaw []interface{}) []SLIQueryGroup {

sumologic/sumologic_slo_library_slo.go

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,14 +143,20 @@ type SLOCompliance struct {
143143
StartFrom string `json:"startFrom,omitempty"`
144144
}
145145

146+
type MonitorTrigger struct {
147+
MonitorId string `json:"monitorId"`
148+
TriggerTypes []string `json:"triggerTypes"`
149+
}
150+
146151
type SLOIndicator struct {
147-
EvaluationType string `json:"evaluationType"` // string^(Window|Request)$
148-
QueryType string `json:"queryType"` // string^(Logs|Metrics)$
149-
Queries []SLIQueryGroup `json:"queries"`
150-
Threshold float64 `json:"threshold"`
151-
Op string `json:"op,omitempty"`
152-
Aggregation string `json:"aggregation,omitempty"`
153-
Size string `json:"size,omitempty"`
152+
EvaluationType string `json:"evaluationType"` // string^(Window|Request|Monitor)$
153+
QueryType string `json:"queryType"` // string^(Logs|Metrics)$
154+
Queries []SLIQueryGroup `json:"queries"`
155+
Threshold float64 `json:"threshold"`
156+
Op string `json:"op,omitempty"`
157+
Aggregation string `json:"aggregation,omitempty"`
158+
Size string `json:"size,omitempty"`
159+
MonitorTriggers []MonitorTrigger `json:"monitorTriggers"`
154160
}
155161

156162
type SLI struct {

website/docs/r/slo.html.markdown

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,29 @@ QUERY
117117
}
118118
}
119119
}
120+
121+
resource "sumologic_slo" "slo_tf_monitor_based" {
122+
name = "slo-tf-monitor-based"
123+
description = "example of monitor based SLO created with terraform"
124+
parent_id = "0000000000000001"
125+
signal_type = "Error"
126+
service = "auth"
127+
application = "login"
128+
compliance {
129+
compliance_type = "Rolling"
130+
size = "7d"
131+
target = 99
132+
timezone = "Asia/Kolkata"
133+
}
134+
indicator {
135+
monitor_based_evaluation {
136+
monitor_triggers {
137+
monitor_id = "0000000000BCB3A4"
138+
trigger_types = ["Critical"]
139+
}
140+
}
141+
}
142+
}
120143
```
121144

122145
## Argument reference
@@ -186,6 +209,13 @@ The following arguments are supported:
186209
- `field` - (Optional) Field of log query output to compare against. To be used only for logs based data
187210
type when `use_row_count` is false.
188211

212+
#### monitor_based_evaluation
213+
214+
- `monitor_triggers` - (Required) Monitor details on which SLO will be based. Only single monitor is supported here.
215+
- `monitor_id` - (Required) ID of the monitor. Ex: `0000000000BCB3A4`
216+
- `trigger_types` - (Required) Type of monitor trigger which will attribute towards a successful or unsuccessful SLO
217+
window. Valid values are `Critical`, `Warning`, `MissingData`. Only one trigger type is supported.
218+
189219
[1]: https://help.sumologic.com/Beta/SLO_Reliability_Management
190220

191221
[2]: slo_folder.html.markdown

0 commit comments

Comments
 (0)