Skip to content

Commit

Permalink
Fix deleting mute timings that are in use (#1608) (#1613)
Browse files Browse the repository at this point in the history
Closes #1601
When deleting a mute timing, the provider has to start with removing it from all notification policies where it's in-use
  • Loading branch information
julienduchesne authored Jun 5, 2024
1 parent 5b3d094 commit ccf90e3
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 2 deletions.
54 changes: 52 additions & 2 deletions internal/resources/grafana/resource_alerting_mute_timing.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ import (
"fmt"
"strconv"
"strings"
"time"

"github.com/go-openapi/runtime"
goapi "github.com/grafana/grafana-openapi-client-go/client"
"github.com/grafana/grafana-openapi-client-go/client/provisioning"
"github.com/grafana/grafana-openapi-client-go/models"
"github.com/grafana/terraform-provider-grafana/v2/internal/common"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

Expand Down Expand Up @@ -185,10 +188,24 @@ func createMuteTiming(ctx context.Context, data *schema.ResourceData, meta inter
params.SetXDisableProvenance(&provenanceDisabled)
}

resp, err := client.Provisioning.PostMuteTiming(params)
var resp *provisioning.PostMuteTimingCreated
err := retry.RetryContext(ctx, 2*time.Minute, func() *retry.RetryError {
var postErr error
resp, postErr = client.Provisioning.PostMuteTiming(params)
if orgID > 1 && postErr != nil {
if apiError, ok := postErr.(*runtime.APIError); ok && (apiError.IsCode(500) || apiError.IsCode(404)) {
return retry.RetryableError(postErr)
}
}
if postErr != nil {
return retry.NonRetryableError(postErr)
}
return nil
})
if err != nil {
return diag.FromErr(err)
}

data.SetId(MakeOrgResourceID(orgID, resp.Payload.Name))
return readMuteTiming(ctx, data, meta)
}
Expand Down Expand Up @@ -218,11 +235,44 @@ func updateMuteTiming(ctx context.Context, data *schema.ResourceData, meta inter
func deleteMuteTiming(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics {
client, _, name := OAPIClientFromExistingOrgResource(meta, data.Id())

_, err := client.Provisioning.DeleteMuteTiming(name)
// Remove the mute timing from all notification policies
policyResp, err := client.Provisioning.GetPolicyTree()
if err != nil {
return diag.FromErr(err)
}
policy := policyResp.Payload
modified := false
policy, modified = removeMuteTimingFromRoute(name, policy)
if modified {
_, err = client.Provisioning.PutPolicyTree(provisioning.NewPutPolicyTreeParams().WithBody(policy))
if err != nil {
return diag.FromErr(err)
}
}

_, err = client.Provisioning.DeleteMuteTiming(name)
diag, _ := common.CheckReadError("mute timing", data, err)
return diag
}

func removeMuteTimingFromRoute(name string, route *models.Route) (*models.Route, bool) {
modified := false
for i, m := range route.MuteTimeIntervals {
if m == name {
route.MuteTimeIntervals = append(route.MuteTimeIntervals[:i], route.MuteTimeIntervals[i+1:]...)
modified = true
break
}
}
for j, p := range route.Routes {
var subRouteModified bool
route.Routes[j], subRouteModified = removeMuteTimingFromRoute(name, p)
modified = modified || subRouteModified
}

return route, modified
}

func suppressMonthDiff(k, oldValue, newValue string, d *schema.ResourceData) bool {
monthNums := map[string]int{
"january": 1,
Expand Down
56 changes: 56 additions & 0 deletions internal/resources/grafana/resource_alerting_mute_timing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,59 @@ resource "grafana_mute_timing" "my_mute_timing" {
},
})
}

func TestAccMuteTiming_RemoveInUse(t *testing.T) {
testutils.CheckOSSTestsEnabled(t, ">9.0.0")

config := func(mute bool) string {
return fmt.Sprintf(`
locals {
use_mute = %t
}
resource "grafana_organization" "my_org" {
name = "mute-timing-test"
}
resource "grafana_contact_point" "default_policy" {
org_id = grafana_organization.my_org.id
name = "default-policy"
email {
addresses = ["[email protected]"]
}
}
resource "grafana_notification_policy" "org_policy" {
org_id = grafana_organization.my_org.id
group_by = ["..."]
group_wait = "45s"
group_interval = "6m"
repeat_interval = "3h"
contact_point = grafana_contact_point.default_policy.name
policy {
mute_timings = local.use_mute ? [grafana_mute_timing.test[0].name] : []
contact_point = grafana_contact_point.default_policy.name
}
}
resource "grafana_mute_timing" "test" {
count = local.use_mute ? 1 : 0
org_id = grafana_organization.my_org.id
name = "test-mute-timing"
intervals {}
}`, mute)
}

resource.ParallelTest(t, resource.TestCase{
ProtoV5ProviderFactories: testutils.ProtoV5ProviderFactories,
Steps: []resource.TestStep{
{
Config: config(true),
},
{
Config: config(false),
},
},
})
}

0 comments on commit ccf90e3

Please sign in to comment.