Skip to content

Commit

Permalink
Threshold alerts (#49)
Browse files Browse the repository at this point in the history
* first stab

* add support for threshold alerts

* move alert creation inside config, add severity checks

* break from loop
  • Loading branch information
louism517 authored Jul 3, 2019
1 parent 7218446 commit 98ccff1
Show file tree
Hide file tree
Showing 10 changed files with 326 additions and 24 deletions.
5 changes: 0 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@ Once you have the plugin you should remove the `_os_arch` from the end of the fi

Valid provider filenames are `terraform-provider-NAME_X.X.X` or `terraform-provider-NAME_vX.X.X`

## Known Issues

To ensure that applies of large batches of Alerts are successful you can use the `-parallelism` flag to prevent parallel resource creations
`terraform apply -parallelism=1`

## Building and Testing

### Build the plugin.
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ module github.com/spaceapegames/terraform-provider-wavefront
require (
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/terraform v0.12.0
github.com/spaceapegames/go-wavefront v0.0.0-20190424105721-72e8eb185145
github.com/spaceapegames/go-wavefront v1.6.2
)
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,12 @@ github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:Udh
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
github.com/spaceapegames/go-wavefront v0.0.0-20190424105721-72e8eb185145 h1:iN5Rc2gJLJFZ3Io4n5qxwe6uVKyHRfTGWc0yTauAH60=
github.com/spaceapegames/go-wavefront v0.0.0-20190424105721-72e8eb185145/go.mod h1:Q9wbY/SM99cOM4NvoJ2SN1bzcJUJOEzta5C7dhnT5IM=
github.com/spaceapegames/go-wavefront v0.0.0-20190627103934-9f0b48af3f8f h1:EG1F9wt5cMZ9az8TDMlMRD08HP8zdjn8f3fmsVBBhf4=
github.com/spaceapegames/go-wavefront v0.0.0-20190627103934-9f0b48af3f8f/go.mod h1:Q9wbY/SM99cOM4NvoJ2SN1bzcJUJOEzta5C7dhnT5IM=
github.com/spaceapegames/go-wavefront v1.6.1 h1:5ZezLy0NiiOFDhrgJA01c5/vZZbFcj2IL2ymdRXJzT8=
github.com/spaceapegames/go-wavefront v1.6.1/go.mod h1:Q9wbY/SM99cOM4NvoJ2SN1bzcJUJOEzta5C7dhnT5IM=
github.com/spaceapegames/go-wavefront v1.6.2 h1:5AHElze/Y6oi4DdpkYfksS4F0ItsBpV7WwuB3r159cY=
github.com/spaceapegames/go-wavefront v1.6.2/go.mod h1:Q9wbY/SM99cOM4NvoJ2SN1bzcJUJOEzta5C7dhnT5IM=
github.com/spf13/afero v1.2.1 h1:qgMbHoJbPbw579P+1zVY+6n4nIFuIchaIjzZ/I/Yq8M=
github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
Expand Down
34 changes: 31 additions & 3 deletions vendor/github.com/spaceapegames/go-wavefront/alert.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion vendor/github.com/spaceapegames/go-wavefront/event.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion vendor/github.com/spaceapegames/go-wavefront/target.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion vendor/github.com/spaceapegames/go-wavefront/version

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion vendor/modules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ github.com/posener/complete
github.com/posener/complete/cmd/install
github.com/posener/complete/cmd
github.com/posener/complete/match
# github.com/spaceapegames/go-wavefront v0.0.0-20190424105721-72e8eb185145
# github.com/spaceapegames/go-wavefront v1.6.2
github.com/spaceapegames/go-wavefront
# github.com/spf13/afero v1.2.1
github.com/spf13/afero
Expand Down
104 changes: 93 additions & 11 deletions wavefront/resource_alert.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,28 @@ func resourceAlert() *schema.Resource {
Type: schema.TypeString,
Required: true,
},
"alert_type": {
Type: schema.TypeString,
Optional: true,
Default: wavefront.AlertTypeClassic,
},
"target": {
Type: schema.TypeString,
Required: true,
Optional: true,
},
"condition": {
Type: schema.TypeString,
Required: true,
Optional: true,
StateFunc: trimSpaces,
},
"threshold_conditions": {
Type: schema.TypeMap,
Optional: true,
},
"threshold_targets": {
Type: schema.TypeMap,
Optional: true,
},
"additional_information": {
Type: schema.TypeString,
Optional: true,
Expand All @@ -56,7 +69,7 @@ func resourceAlert() *schema.Resource {
},
"severity": {
Type: schema.TypeString,
Required: true,
Optional: true,
},
"tags": {
Type: schema.TypeSet,
Expand All @@ -71,6 +84,14 @@ func trimSpaces(d interface{}) string {
return strings.TrimSpace(d.(string))
}

func trimSpacesMap(m map[string]interface{}) map[string]string {
trimmed := map[string]string{}
for key, v := range m {
trimmed[key] = trimSpaces(v)
}
return trimmed
}

func resourceAlertCreate(d *schema.ResourceData, m interface{}) error {
alerts := m.(*wavefrontClient).client.Alerts()

Expand All @@ -81,19 +102,21 @@ func resourceAlertCreate(d *schema.ResourceData, m interface{}) error {

a := &wavefront.Alert{
Name: d.Get("name").(string),
Target: d.Get("target").(string),
Condition: trimSpaces(d.Get("condition").(string)),
AdditionalInfo: trimSpaces(d.Get("additional_information").(string)),
DisplayExpression: trimSpaces(d.Get("display_expression").(string)),
Minutes: d.Get("minutes").(int),
ResolveAfterMinutes: d.Get("resolve_after_minutes").(int),
NotificationResendFrequencyMinutes: d.Get("notification_resend_frequency_minutes").(int),
Severity: d.Get("severity").(string),
Tags: tags,
Tags: tags,
}

err := validateAlertConditions(a, d)
if err != nil {
return err
}

// Create the alert on Wavefront
err := alerts.Create(a)
err = alerts.Create(a)
if err != nil {
return fmt.Errorf("error creating Alert %s. %s", d.Get("name"), err)
}
Expand Down Expand Up @@ -129,6 +152,9 @@ func resourceAlertRead(d *schema.ResourceData, m interface{}) error {
d.Set("notification_resend_frequency_minutes", tmpAlert.NotificationResendFrequencyMinutes)
d.Set("severity", tmpAlert.Severity)
d.Set("tags", tmpAlert.Tags)
d.Set("alert_type", tmpAlert.AlertType)
d.Set("threshold_conditions", tmpAlert.Conditions)
d.Set("threshold_targets", tmpAlert.Targets)

return nil
}
Expand All @@ -151,16 +177,18 @@ func resourceAlertUpdate(d *schema.ResourceData, m interface{}) error {

a := tmpAlert
a.Name = d.Get("name").(string)
a.Target = d.Get("target").(string)
a.Condition = trimSpaces(d.Get("condition").(string))
a.AdditionalInfo = trimSpaces(d.Get("additional_information").(string))
a.DisplayExpression = trimSpaces(d.Get("display_expression").(string))
a.Minutes = d.Get("minutes").(int)
a.ResolveAfterMinutes = d.Get("resolve_after_minutes").(int)
a.NotificationResendFrequencyMinutes = d.Get("notification_resend_frequency_minutes").(int)
a.Severity = d.Get("severity").(string)
a.Tags = tags

err = validateAlertConditions(&a, d)
if err != nil {
return err
}

// Update the alert on Wavefront
err = alerts.Update(&a)
if err != nil {
Expand Down Expand Up @@ -188,3 +216,57 @@ func resourceAlertDelete(d *schema.ResourceData, m interface{}) error {
d.SetId("")
return nil
}

func validateAlertConditions(a *wavefront.Alert, d *schema.ResourceData) error {
if d.Get("alert_type") == wavefront.AlertTypeThreshold {
a.AlertType = wavefront.AlertTypeThreshold
if conditions, ok := d.GetOk("threshold_conditions"); ok {
a.Conditions = trimSpacesMap(conditions.(map[string]interface{}))
err := validateThresholdLevels(a.Conditions)
if err != nil {
return err
}
} else {
return fmt.Errorf("threshold_conditions must be supplied for threshold alerts")
}

if targets, ok := d.GetOk("threshold_targets"); ok {
a.Targets = trimSpacesMap(targets.(map[string]interface{}))
return validateThresholdLevels(a.Targets)
}

} else if d.Get("alert_type") == wavefront.AlertTypeClassic {
a.AlertType = wavefront.AlertTypeClassic

if d.Get("condition") == "" {
return fmt.Errorf("condition must be supplied for classic alerts")
}
a.Condition = trimSpaces(d.Get("condition").(string))

if d.Get("severity") == "" {
return fmt.Errorf("severity must be supplied for classic alerts")
}
a.Severity = d.Get("severity").(string)
a.Target = d.Get("target").(string)
} else {
return fmt.Errorf("alert_type must be CLASSIC or THRESHOLD")
}

return nil
}

func validateThresholdLevels(m map[string]string) error {
for key := range m {
ok := false
for _, level := range []string{"severe", "warn", "info", "smoke"} {
if key == level {
ok = true
break
}
}
if !ok {
return fmt.Errorf("invalid severity: %s", key)
}
}
return nil
}
Loading

0 comments on commit 98ccff1

Please sign in to comment.