Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plan recreation of tag assignments and teams on external to Terraform deletion #686

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions pagerduty/resource_pagerduty_tag_assignment.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package pagerduty
import (
"fmt"
"log"
"net/http"
"strings"
"time"

Expand Down Expand Up @@ -106,6 +107,15 @@ func resourcePagerDutyTagAssignmentRead(d *schema.ResourceData, meta interface{}

log.Printf("[INFO] Reading PagerDuty tag assignment with tagID %s for %s entity with ID %s", assignment.TagID, assignment.EntityType, assignment.EntityID)

ok, err := isFoundTagAssignmentEntity(d.Get("entity_id").(string), d.Get("entity_type").(string), meta)
if err != nil {
return err
}
if !ok {
d.SetId("")
return nil
}

return resource.Retry(30*time.Second, func() *resource.RetryError {
if tagResponse, _, err := client.Tags.ListTagsForEntity(assignment.EntityType, assignment.EntityID); err != nil {
time.Sleep(2 * time.Second)
Expand Down Expand Up @@ -202,6 +212,50 @@ func resourcePagerDutyTagAssignmentImport(d *schema.ResourceData, meta interface
return []*schema.ResourceData{d}, err
}

func isFoundTagAssignmentEntity(entityID, entityType string, meta interface{}) (bool, error) {
var isFound bool
client, err := meta.(*Config).Client()
if err != nil {
return isFound, err
}

fetchUser := func(id string) (*pagerduty.User, *pagerduty.Response, error) {
return client.Users.Get(id, &pagerduty.GetUserOptions{})
}
fetchTeam := func(id string) (*pagerduty.Team, *pagerduty.Response, error) {
return client.Teams.Get(id)
}
fetchEscalationPolicy := func(id string) (*pagerduty.EscalationPolicy, *pagerduty.Response, error) {
return client.EscalationPolicies.Get(id, &pagerduty.GetEscalationPolicyOptions{})
}
retryErr := resource.Retry(30*time.Second, func() *resource.RetryError {
var err error
if entityType == "users" {
_, _, err = fetchUser(entityID)
}
if entityType == "teams" {
_, _, err = fetchTeam(entityID)
}
if entityType == "escalation_policies" {
_, _, err = fetchEscalationPolicy(entityID)
}

if err != nil && isErrCode(err, http.StatusNotFound) {
return nil
}
if err != nil {
return resource.RetryableError(err)
}
isFound = true

return nil
})
if retryErr != nil {
return isFound, retryErr
}
return isFound, nil
}

func createAssignmentID(entityID, tagID string) string {
return fmt.Sprintf("%v.%v", entityID, tagID)
}
97 changes: 95 additions & 2 deletions pagerduty/resource_pagerduty_tag_assignment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/heimweh/go-pagerduty/pagerduty"
)

func TestAccPagerDutyTagAssignment_User(t *testing.T) {
Expand All @@ -32,6 +33,24 @@ func TestAccPagerDutyTagAssignment_User(t *testing.T) {
"pagerduty_user.foo", "email", email),
),
},
// Validating that externally removed users with tag assigments are
// detected and tag assignment is planed for re-creation
{
Config: testAccCheckPagerDutyTagAssignmentConfig(tagLabel, username, email),
Check: resource.ComposeTestCheckFunc(
testAccExternallyDestroyTagAssignment("pagerduty_user.foo", "users"),
),
ExpectNonEmptyPlan: true,
},
{
Config: testAccCheckPagerDutyTagAssignmentConfig(tagLabel, username, email),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckNoResourceAttr(
"pagerduty_tag_assignment.foo", "id"),
),
PlanOnly: true,
ExpectNonEmptyPlan: true,
},
},
})
}
Expand All @@ -54,6 +73,24 @@ func TestAccPagerDutyTagAssignment_Team(t *testing.T) {
"pagerduty_team.foo", "name", team),
),
},
// Validating that externally removed teams with tag assigments are
// detected and tag assignment is planed for re-creation
{
Config: testAccCheckPagerDutyTagAssignmentTeamConfig(tagLabel, team),
Check: resource.ComposeTestCheckFunc(
testAccExternallyDestroyTagAssignment("pagerduty_team.foo", "teams"),
),
ExpectNonEmptyPlan: true,
},
{
Config: testAccCheckPagerDutyTagAssignmentTeamConfig(tagLabel, team),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckNoResourceAttr(
"pagerduty_tag_assignment.foo", "id"),
),
PlanOnly: true,
ExpectNonEmptyPlan: true,
},
},
})
}
Expand All @@ -71,13 +108,31 @@ func TestAccPagerDutyTagAssignment_EP(t *testing.T) {
{
Config: testAccCheckPagerDutyTagAssignmentEPConfig(tagLabel, username, email, ep),
Check: resource.ComposeTestCheckFunc(
testAccCheckPagerDutyTagAssignmentExists("pagerduty_tag_assignment.foo", "teams"),
testAccCheckPagerDutyTagAssignmentExists("pagerduty_tag_assignment.foo", "escalation_policies"),
resource.TestCheckResourceAttr(
"pagerduty_tag.foo", "label", tagLabel),
resource.TestCheckResourceAttr(
"pagerduty_escalation_policy.foo", "name", ep),
),
},
// Validating that externally removed escalation policies with tag
// assigments are detected and tag assignment is planed for re-creation
{
Config: testAccCheckPagerDutyTagAssignmentEPConfig(tagLabel, username, email, ep),
Check: resource.ComposeTestCheckFunc(
testAccExternallyDestroyTagAssignment("pagerduty_escalation_policy.foo", "escalation_policies"),
),
ExpectNonEmptyPlan: true,
},
{
Config: testAccCheckPagerDutyTagAssignmentEPConfig(tagLabel, username, email, ep),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckNoResourceAttr(
"pagerduty_tag_assignment.foo", "id"),
),
PlanOnly: true,
ExpectNonEmptyPlan: true,
},
},
})
}
Expand Down Expand Up @@ -200,9 +255,47 @@ resource "pagerduty_escalation_policy" "foo" {
}
}
resource "pagerduty_tag_assignment" "foo" {
entity_type = "teams"
entity_type = "escalation_policies"
entity_id = pagerduty_escalation_policy.foo.id
tag_id = pagerduty_tag.foo.id
}
`, tagLabel, username, email, ep)
}

func testAccExternallyDestroyTagAssignment(n, entityType string) resource.TestCheckFunc {
deleteUser := func(id string, client *pagerduty.Client) (*pagerduty.Response, error) {
return client.Users.Delete(id)
}
deleteTeam := func(id string, client *pagerduty.Client) (*pagerduty.Response, error) {
return client.Teams.Delete(id)
}
deleteEscalationPolicy := func(id string, client *pagerduty.Client) (*pagerduty.Response, error) {
return client.EscalationPolicies.Delete(id)
}
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No Tag Assignment ID is set")
}

client, _ := testAccProvider.Meta().(*Config).Client()
var err error
if entityType == "users" {
_, err = deleteUser(rs.Primary.ID, client)
}
if entityType == "teams" {
_, err = deleteTeam(rs.Primary.ID, client)
}
if entityType == "escalation_policies" {
_, err = deleteEscalationPolicy(rs.Primary.ID, client)
}
if err != nil {
return err
}

return nil
}
}
7 changes: 5 additions & 2 deletions pagerduty/resource_pagerduty_team.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,11 @@ func resourcePagerDutyTeamRead(d *schema.ResourceData, meta interface{}) error {

return resource.Retry(30*time.Second, func() *resource.RetryError {
if team, _, err := client.Teams.Get(d.Id()); err != nil {
time.Sleep(2 * time.Second)
return resource.RetryableError(err)
errResp := handleNotFoundError(err, d)
if errResp != nil {
time.Sleep(2 * time.Second)
return resource.RetryableError(errResp)
}
} else if team != nil {
d.Set("name", team.Name)
d.Set("description", team.Description)
Expand Down
38 changes: 38 additions & 0 deletions pagerduty/resource_pagerduty_team_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,24 @@ func TestAccPagerDutyTeam_Basic(t *testing.T) {
"pagerduty_team.foo", "description", "bar"),
),
},
// Validating that externally removed teams are detected and planed for
// re-creation
{
Config: testAccCheckPagerDutyTeamConfigUpdated(teamUpdated),
Check: resource.ComposeTestCheckFunc(
testAccExternallyDestroyTeam("pagerduty_team.foo"),
),
ExpectNonEmptyPlan: true,
},
{
Config: testAccCheckPagerDutyTeamConfigUpdated(teamUpdated),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckNoResourceAttr(
"pagerduty_team.foo", "id"),
),
PlanOnly: true,
ExpectNonEmptyPlan: true,
},
},
})
}
Expand Down Expand Up @@ -173,3 +191,23 @@ resource "pagerduty_team" "foo" {
parent = pagerduty_team.parent.id
}`, parent, team)
}

func testAccExternallyDestroyTeam(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No Team ID is set")
}

client, _ := testAccProvider.Meta().(*Config).Client()
_, err := client.Teams.Delete(rs.Primary.ID)
if err != nil {
return err
}

return nil
}
}