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

Add support for Automation Actions' Action association to a Team #600

Merged
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.16
require (
cloud.google.com/go v0.71.0 // indirect
github.com/hashicorp/terraform-plugin-sdk/v2 v2.10.1
github.com/heimweh/go-pagerduty v0.0.0-20221215133901-7c3850d0bcf4
github.com/heimweh/go-pagerduty v0.0.0-20221219143240-8b7c456b23c6
github.com/klauspost/compress v1.15.9 // indirect
github.com/montanaflynn/stats v0.6.6 // indirect
go.mongodb.org/mongo-driver v1.10.2 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,8 @@ github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734/go.mod
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ=
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/heimweh/go-pagerduty v0.0.0-20221215133901-7c3850d0bcf4 h1:lM8slTKIJNiHnSo+him7GC3mOSSlz3Fbs4mqx2FfMpI=
github.com/heimweh/go-pagerduty v0.0.0-20221215133901-7c3850d0bcf4/go.mod h1:t9vftsO1IjYHGdgJXeemZtomCWnxi2SRgu0PRcRb2oY=
github.com/heimweh/go-pagerduty v0.0.0-20221219143240-8b7c456b23c6 h1:aK7yqQASNtcxrTy4L3Gidh0EUBoDLjDVWTcZ7bzcXJY=
github.com/heimweh/go-pagerduty v0.0.0-20221219143240-8b7c456b23c6/go.mod h1:t9vftsO1IjYHGdgJXeemZtomCWnxi2SRgu0PRcRb2oY=
github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package pagerduty

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func TestAccPagerDutyAutomationActionsActionTeamAssociation_import(t *testing.T) {
actionName := fmt.Sprintf("tf-%s", acctest.RandString(5))
teamName := fmt.Sprintf("tf-%s", acctest.RandString(5))

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckPagerDutyAutomationActionsActionTeamAssociationDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckPagerDutyAutomationActionsActionTeamAssociationConfig(actionName, teamName),
},
{
ResourceName: "pagerduty_automation_actions_action_team_association.foo",
ImportState: true,
ImportStateVerify: true,
},
},
})
}
63 changes: 32 additions & 31 deletions pagerduty/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,37 +65,38 @@ func Provider() *schema.Provider {
},

ResourcesMap: map[string]*schema.Resource{
"pagerduty_addon": resourcePagerDutyAddon(),
"pagerduty_escalation_policy": resourcePagerDutyEscalationPolicy(),
"pagerduty_maintenance_window": resourcePagerDutyMaintenanceWindow(),
"pagerduty_schedule": resourcePagerDutySchedule(),
"pagerduty_service": resourcePagerDutyService(),
"pagerduty_service_integration": resourcePagerDutyServiceIntegration(),
"pagerduty_team": resourcePagerDutyTeam(),
"pagerduty_team_membership": resourcePagerDutyTeamMembership(),
"pagerduty_user": resourcePagerDutyUser(),
"pagerduty_user_contact_method": resourcePagerDutyUserContactMethod(),
"pagerduty_user_notification_rule": resourcePagerDutyUserNotificationRule(),
"pagerduty_extension": resourcePagerDutyExtension(),
"pagerduty_extension_servicenow": resourcePagerDutyExtensionServiceNow(),
"pagerduty_event_rule": resourcePagerDutyEventRule(),
"pagerduty_ruleset": resourcePagerDutyRuleset(),
"pagerduty_ruleset_rule": resourcePagerDutyRulesetRule(),
"pagerduty_business_service": resourcePagerDutyBusinessService(),
"pagerduty_service_dependency": resourcePagerDutyServiceDependency(),
"pagerduty_response_play": resourcePagerDutyResponsePlay(),
"pagerduty_tag": resourcePagerDutyTag(),
"pagerduty_tag_assignment": resourcePagerDutyTagAssignment(),
"pagerduty_service_event_rule": resourcePagerDutyServiceEventRule(),
"pagerduty_slack_connection": resourcePagerDutySlackConnection(),
"pagerduty_business_service_subscriber": resourcePagerDutyBusinessServiceSubscriber(),
"pagerduty_webhook_subscription": resourcePagerDutyWebhookSubscription(),
"pagerduty_event_orchestration": resourcePagerDutyEventOrchestration(),
"pagerduty_event_orchestration_router": resourcePagerDutyEventOrchestrationPathRouter(),
"pagerduty_event_orchestration_unrouted": resourcePagerDutyEventOrchestrationPathUnrouted(),
"pagerduty_event_orchestration_service": resourcePagerDutyEventOrchestrationPathService(),
"pagerduty_automation_actions_runner": resourcePagerDutyAutomationActionsRunner(),
"pagerduty_automation_actions_action": resourcePagerDutyAutomationActionsAction(),
"pagerduty_addon": resourcePagerDutyAddon(),
"pagerduty_escalation_policy": resourcePagerDutyEscalationPolicy(),
"pagerduty_maintenance_window": resourcePagerDutyMaintenanceWindow(),
"pagerduty_schedule": resourcePagerDutySchedule(),
"pagerduty_service": resourcePagerDutyService(),
"pagerduty_service_integration": resourcePagerDutyServiceIntegration(),
"pagerduty_team": resourcePagerDutyTeam(),
"pagerduty_team_membership": resourcePagerDutyTeamMembership(),
"pagerduty_user": resourcePagerDutyUser(),
"pagerduty_user_contact_method": resourcePagerDutyUserContactMethod(),
"pagerduty_user_notification_rule": resourcePagerDutyUserNotificationRule(),
"pagerduty_extension": resourcePagerDutyExtension(),
"pagerduty_extension_servicenow": resourcePagerDutyExtensionServiceNow(),
"pagerduty_event_rule": resourcePagerDutyEventRule(),
"pagerduty_ruleset": resourcePagerDutyRuleset(),
"pagerduty_ruleset_rule": resourcePagerDutyRulesetRule(),
"pagerduty_business_service": resourcePagerDutyBusinessService(),
"pagerduty_service_dependency": resourcePagerDutyServiceDependency(),
"pagerduty_response_play": resourcePagerDutyResponsePlay(),
"pagerduty_tag": resourcePagerDutyTag(),
"pagerduty_tag_assignment": resourcePagerDutyTagAssignment(),
"pagerduty_service_event_rule": resourcePagerDutyServiceEventRule(),
"pagerduty_slack_connection": resourcePagerDutySlackConnection(),
"pagerduty_business_service_subscriber": resourcePagerDutyBusinessServiceSubscriber(),
"pagerduty_webhook_subscription": resourcePagerDutyWebhookSubscription(),
"pagerduty_event_orchestration": resourcePagerDutyEventOrchestration(),
"pagerduty_event_orchestration_router": resourcePagerDutyEventOrchestrationPathRouter(),
"pagerduty_event_orchestration_unrouted": resourcePagerDutyEventOrchestrationPathUnrouted(),
"pagerduty_event_orchestration_service": resourcePagerDutyEventOrchestrationPathService(),
"pagerduty_automation_actions_runner": resourcePagerDutyAutomationActionsRunner(),
"pagerduty_automation_actions_action": resourcePagerDutyAutomationActionsAction(),
"pagerduty_automation_actions_action_team_association": resourcePagerDutyAutomationActionsActionTeamAssociation(),
},
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package pagerduty

import (
"fmt"
"log"
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func resourcePagerDutyAutomationActionsActionTeamAssociation() *schema.Resource {
return &schema.Resource{
Create: resourcePagerDutyAutomationActionsActionTeamAssociationCreate,
Read: resourcePagerDutyAutomationActionsActionTeamAssociationRead,
Delete: resourcePagerDutyAutomationActionsActionTeamAssociationDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"action_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"team_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
},
}
}

func resourcePagerDutyAutomationActionsActionTeamAssociationCreate(d *schema.ResourceData, meta interface{}) error {
client, err := meta.(*Config).Client()
if err != nil {
return err
}

actionID := d.Get("action_id").(string)
teamID := d.Get("team_id").(string)

log.Printf("[INFO] Creating PagerDuty AutomationActionsActionTeamAssociation %s:%s", d.Get("action_id").(string), d.Get("team_id").(string))

retryErr := resource.Retry(10*time.Second, func() *resource.RetryError {
if teamRef, _, err := client.AutomationActionsAction.AssociateToTeam(actionID, teamID); err != nil {
if isErrCode(err, 429) {
time.Sleep(2 * time.Second)
return resource.RetryableError(err)
}

return resource.NonRetryableError(err)
} else if teamRef != nil {
d.SetId(fmt.Sprintf("%s:%s", actionID, teamID))
}
return nil
})

if retryErr != nil {
return retryErr
}

return fetchPagerDutyAutomationActionsActionTeamAssociation(d, meta, handleNotFoundError)
}

func fetchPagerDutyAutomationActionsActionTeamAssociation(d *schema.ResourceData, meta interface{}, errCallback func(error, *schema.ResourceData) error) error {
client, err := meta.(*Config).Client()
if err != nil {
return err
}

actionID, teamID := resourcePagerDutyParseColonCompoundID(d.Id())
return resource.Retry(30*time.Second, func() *resource.RetryError {
resp, _, err := client.AutomationActionsAction.GetAssociationToTeam(actionID, teamID)
if err != nil {
errResp := errCallback(err, d)
if errResp != nil {
time.Sleep(2 * time.Second)
return resource.RetryableError(errResp)
}

return nil
}

if resp.Team.ID != teamID {
log.Printf("[WARN] Removing %s since the user: %s is not a member of: %s", d.Id(), actionID, teamID)
d.SetId("")
return nil
}

d.Set("action_id", actionID)
d.Set("team_id", resp.Team.ID)

return nil
})
}

func resourcePagerDutyAutomationActionsActionTeamAssociationRead(d *schema.ResourceData, meta interface{}) error {
return fetchPagerDutyAutomationActionsActionTeamAssociation(d, meta, handleNotFoundError)
}

func resourcePagerDutyAutomationActionsActionTeamAssociationDelete(d *schema.ResourceData, meta interface{}) error {
client, err := meta.(*Config).Client()
if err != nil {
return err
}

actionID, teamID := resourcePagerDutyParseColonCompoundID(d.Id())
log.Printf("[INFO] Deleting PagerDuty AutomationActionsActionTeamAssociation %s", d.Id())

retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError {
if _, err := client.AutomationActionsAction.DissociateToTeam(actionID, teamID); err != nil {
return resource.RetryableError(err)
}
return nil
})
if retryErr != nil {
time.Sleep(2 * time.Second)
return retryErr
}
d.SetId("")

// giving the API time to catchup
time.Sleep(time.Second)
return nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package pagerduty

import (
"fmt"
"testing"

"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"
)

func init() {
resource.AddTestSweepers("pagerduty_automation_actions_action_team_association", &resource.Sweeper{
Name: "pagerduty_automation_actions_action_team_association",
F: testSweepAutomationActionsActionTeamAssociation,
})
}

func testSweepAutomationActionsActionTeamAssociation(region string) error {
return nil
}

func TestAccPagerDutyAutomationActionsActionTeamAssociation_Basic(t *testing.T) {
actionName := fmt.Sprintf("tf-%s", acctest.RandString(5))
teamName := fmt.Sprintf("tf-%s", acctest.RandString(5))

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckPagerDutyAutomationActionsActionTeamAssociationDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckPagerDutyAutomationActionsActionTeamAssociationConfig(actionName, teamName),
Check: resource.ComposeTestCheckFunc(
testAccCheckPagerDutyAutomationActionsActionTeamAssociationExists("pagerduty_automation_actions_action_team_association.foo"),
resource.TestCheckResourceAttrSet("pagerduty_automation_actions_action_team_association.foo", "action_id"),
resource.TestCheckResourceAttrSet("pagerduty_automation_actions_action_team_association.foo", "team_id"),
),
},
},
})
}

func testAccCheckPagerDutyAutomationActionsActionTeamAssociationDestroy(s *terraform.State) error {
client, _ := testAccProvider.Meta().(*Config).Client()
for _, r := range s.RootModule().Resources {
if r.Type != "pagerduty_automation_actions_action_team_association" {
continue
}
actionID, teamID := resourcePagerDutyParseColonCompoundID(r.Primary.ID)
if _, _, err := client.AutomationActionsAction.GetAssociationToTeam(actionID, teamID); err == nil {
return fmt.Errorf("Automation Actions Runner still exists")
}
}
return nil
}

func testAccCheckPagerDutyAutomationActionsActionTeamAssociationExists(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 Automation Actions Runner ID is set")
}

client, _ := testAccProvider.Meta().(*Config).Client()
actionID, teamID := resourcePagerDutyParseColonCompoundID(rs.Primary.ID)
found, _, err := client.AutomationActionsAction.GetAssociationToTeam(actionID, teamID)
if err != nil {
return err
}
if fmt.Sprintf("%s:%s", actionID, found.Team.ID) != rs.Primary.ID {
return fmt.Errorf("Automation Actions Action association to team not found: %v - %v", rs.Primary.ID, found)
}

return nil
}
}

func testAccCheckPagerDutyAutomationActionsActionTeamAssociationConfig(teamName, actionName string) string {
return fmt.Sprintf(`
resource "pagerduty_team" "foo" {
name = "%s"
description = "foo"
}

resource "pagerduty_automation_actions_action" "foo" {
name = "%s"
description = "PA Action created by TF"
action_type = "script"
action_data_reference {
script = "java --version"
invocation_command = "/bin/bash"
}
}

resource "pagerduty_automation_actions_action_team_association" "foo" {
action_id = pagerduty_automation_actions_action.foo.id
team_id = pagerduty_team.foo.id
}

`, teamName, actionName)
}
10 changes: 2 additions & 8 deletions pagerduty/resource_pagerduty_team_membership.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package pagerduty
import (
"fmt"
"log"
"strings"
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
Expand Down Expand Up @@ -51,7 +50,7 @@ func fetchPagerDutyTeamMembership(d *schema.ResourceData, meta interface{}, errC
return err
}

userID, teamID := resourcePagerDutyTeamMembershipParseID(d.Id())
userID, teamID := resourcePagerDutyParseColonCompoundID(d.Id())
log.Printf("[DEBUG] Reading user: %s from team: %s", userID, teamID)
return resource.Retry(2*time.Minute, func() *resource.RetryError {
resp, _, err := client.Teams.GetMembers(teamID, &pagerduty.GetMembersOptions{})
Expand Down Expand Up @@ -156,7 +155,7 @@ func resourcePagerDutyTeamMembershipDelete(d *schema.ResourceData, meta interfac
return err
}

userID, teamID := resourcePagerDutyTeamMembershipParseID(d.Id())
userID, teamID := resourcePagerDutyParseColonCompoundID(d.Id())

log.Printf("[DEBUG] Removing user: %s from team: %s", userID, teamID)

Expand Down Expand Up @@ -275,11 +274,6 @@ func associateEPsBackToTeam(c *pagerduty.Client, teamID string, eps []string) er
return nil
}

func resourcePagerDutyTeamMembershipParseID(id string) (string, string) {
parts := strings.Split(id, ":")
return parts[0], parts[1]
}

func isTeamMember(user *pagerduty.User, teamID string) bool {
var found bool

Expand Down
Loading