Skip to content

Commit

Permalink
Merge pull request #519 from imjaroiswebdev/issue-456-slack-connectio…
Browse files Browse the repository at this point in the history
…n-priority

Addressing pagerduty_slack_connection unable to set "No Priority" vs "Any Priority" for priorities configuration
  • Loading branch information
Scott McAllister authored Jun 9, 2022
2 parents 2f40744 + 6eb3505 commit 09bfd7c
Show file tree
Hide file tree
Showing 3 changed files with 190 additions and 3 deletions.
30 changes: 27 additions & 3 deletions pagerduty/resource_pagerduty_slack_connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
)

const AppBaseUrl = "https://app.pagerduty.com"
const StarWildcardConfig = "*"

func resourcePagerDutySlackConnection() *schema.Resource {
return &schema.Resource{
Expand Down Expand Up @@ -215,7 +216,7 @@ func expandConnectionConfig(v interface{}) pagerduty.ConnectionConfig {

config = pagerduty.ConnectionConfig{
Events: expandConfigList(c["events"].([]interface{})),
Priorities: expandConfigList(c["priorities"].([]interface{})),
Priorities: expandStarWildcardConfig(expandConfigList(c["priorities"].([]interface{}))),
Urgency: nil,
}
if val, ok := c["urgency"]; ok {
Expand All @@ -228,18 +229,30 @@ func expandConnectionConfig(v interface{}) pagerduty.ConnectionConfig {
}

func expandConfigList(v interface{}) []string {
var items []string
items := []string{}
for _, i := range v.([]interface{}) {
items = append(items, i.(string))
}
return items
}

//Expands the use of star wildcard ("*") configuration for an attribute to its
//matching expected value by PagerDuty's API, which is nil. This is necessary
//when the API accepts and interprets nil and empty configurations as valid
//settings. The state produced by this kind of config can be reverted to the API
//expected values with sibbling function `flattenStarWildcardConfig`.
func expandStarWildcardConfig(c []string) []string {
if isUsingStarWildcardConfig := len(c) == 1 && c[0] == StarWildcardConfig; isUsingStarWildcardConfig {
c = nil
}
return c
}

func flattenConnectionConfig(config pagerduty.ConnectionConfig) []map[string]interface{} {
var configs []map[string]interface{}
configMap := map[string]interface{}{
"events": flattenConfigList(config.Events),
"priorities": flattenConfigList(config.Priorities),
"priorities": flattenConfigList(flattenStarWildcardConfig(config.Priorities)),
}
if config.Urgency != nil {
configMap["urgency"] = *config.Urgency
Expand All @@ -258,6 +271,17 @@ func flattenConfigList(list []string) interface{} {
return items
}

// Flattens a `nil` configuration to its corresponding star wildcard ("*")
// configuration value for an attribute which is meant to be accepting this kind
// of configuration, with the only purpose to match the config stored in the
// Terraform's state.
func flattenStarWildcardConfig(c []string) []string {
if hasStarWildcardConfigSet := c[:] == nil; hasStarWildcardConfigSet {
c = append(c, StarWildcardConfig)
}
return c
}

func resourcePagerDutySlackConnectionImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
client, err := meta.(*Config).SlackClient()
if err != nil {
Expand Down
161 changes: 161 additions & 0 deletions pagerduty/resource_pagerduty_slack_connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,41 @@ func TestAccPagerDutySlackConnection_Envar(t *testing.T) {
})
}

func TestAccPagerDutySlackConnection_NonAndAnyPriorities(t *testing.T) {
username := fmt.Sprintf("tf-%s", acctest.RandString(5))
email := fmt.Sprintf("%s@foo.test", username)
escalationPolicy := fmt.Sprintf("tf-%s", acctest.RandString(5))
service := fmt.Sprintf("tf-%s", acctest.RandString(5))

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckPagerDutySlackConnectionDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckPagerDutySlackConnectionConfigNonAndAnyPriorities(username, email, escalationPolicy, service, workspaceID, channelID),
Check: resource.ComposeTestCheckFunc(
testAccCheckPagerDutySlackConnectionExists("pagerduty_slack_connection.foo"),
resource.TestCheckResourceAttr(
"pagerduty_slack_connection.foo", "source_name", service),
resource.TestCheckResourceAttr(
"pagerduty_slack_connection.foo", "config.0.priorities.#", "0"),
),
},
{
Config: testAccCheckPagerDutySlackConnectionConfigNonAndAnyPrioritiesUpdated(username, email, escalationPolicy, service, workspaceID, channelID),
Check: resource.ComposeTestCheckFunc(
testAccCheckPagerDutySlackConnectionExists("pagerduty_slack_connection.foo"),
resource.TestCheckResourceAttr(
"pagerduty_slack_connection.foo", "config.0.priorities.#", "1"),
resource.TestCheckResourceAttr(
"pagerduty_slack_connection.foo", "config.0.priorities.0", "*"),
),
},
},
})
}

func testAccCheckPagerDutySlackConnectionDestroy(s *terraform.State) error {
config := &pagerduty.Config{
Token: os.Getenv("PAGERDUTY_USER_TOKEN"),
Expand Down Expand Up @@ -388,3 +423,129 @@ func testAccCheckPagerDutySlackConnectionConfigEnvar(team, channelID string) str
}
`, team, channelID)
}

func testAccCheckPagerDutySlackConnectionConfigNonAndAnyPriorities(username, useremail, escalationPolicy, service, workspaceID, channelID string) string {
return fmt.Sprintf(`
resource "pagerduty_user" "foo" {
name = "%s"
email = "%s"
}
resource "pagerduty_escalation_policy" "foo" {
name = "%s"
description = "foo"
num_loops = 1
rule {
escalation_delay_in_minutes = 10
target {
type = "user_reference"
id = pagerduty_user.foo.id
}
}
}
resource "pagerduty_service" "foo" {
name = "%s"
description = "foo"
auto_resolve_timeout = 1800
acknowledgement_timeout = 1800
escalation_policy = pagerduty_escalation_policy.foo.id
incident_urgency_rule {
type = "constant"
urgency = "high"
}
}
resource "pagerduty_slack_connection" "foo" {
source_id = pagerduty_service.foo.id
source_type = "service_reference"
workspace_id = "%s"
channel_id = "%s"
notification_type = "responder"
config {
events = [
"incident.triggered",
"incident.acknowledged",
"incident.escalated",
"incident.resolved",
"incident.reassigned",
"incident.annotated",
"incident.unacknowledged",
"incident.delegated",
"incident.priority_updated",
"incident.responder.added",
"incident.responder.replied",
"incident.status_update_published",
"incident.reopened"
]
priorities = []
urgency = "high"
}
}
`, username, useremail, escalationPolicy, service, workspaceID, channelID)
}

func testAccCheckPagerDutySlackConnectionConfigNonAndAnyPrioritiesUpdated(username, email, escalationPolicy, service, workspaceID, channelID string) string {
return fmt.Sprintf(`
resource "pagerduty_user" "foo" {
name = "%s"
email = "%s"
}
resource "pagerduty_escalation_policy" "foo" {
name = "%s"
description = "foo"
num_loops = 1
rule {
escalation_delay_in_minutes = 10
target {
type = "user_reference"
id = pagerduty_user.foo.id
}
}
}
resource "pagerduty_service" "foo" {
name = "%s"
description = "foo"
auto_resolve_timeout = 1800
acknowledgement_timeout = 1800
escalation_policy = pagerduty_escalation_policy.foo.id
incident_urgency_rule {
type = "constant"
urgency = "high"
}
}
resource "pagerduty_slack_connection" "foo" {
source_id = pagerduty_service.foo.id
source_type = "service_reference"
workspace_id = "%s"
channel_id = "%s"
notification_type = "responder"
config {
events = [
"incident.triggered",
"incident.acknowledged",
"incident.escalated",
"incident.resolved",
"incident.reassigned",
"incident.annotated",
"incident.unacknowledged",
"incident.delegated",
"incident.priority_updated",
"incident.responder.added",
"incident.responder.replied",
"incident.status_update_published",
"incident.reopened"
]
priorities = ["*"]
urgency = "high"
}
}
`, username, email, escalationPolicy, service, workspaceID, channelID)
}
2 changes: 2 additions & 0 deletions website/docs/r/slack_connection.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ The following arguments are supported:
- `incident.status_update_published`
- `incident.reopened`
* `priorities` - (Optional) Allows you to filter events by priority. Needs to be an array of PagerDuty priority IDs. Available through [pagerduty_priority](https://registry.terraform.io/providers/PagerDuty/pagerduty/latest/docs/data-sources/priority) data source.
- When omitted or set to an empty array (`[]`) in the configuration for a Slack Connection, its default behaviour is to set `priorities` to `No Priority` value.
- When set to `["*"]` its corresponding value for `priorities` in Slack Connection's configuration will be `Any Priority`.
* `urgency` - (Optional) Allows you to filter events by urgency. Either `high` or `low`.

## Attributes Reference
Expand Down

0 comments on commit 09bfd7c

Please sign in to comment.