Skip to content

Commit

Permalink
Merge pull request #402 from stmcallister/tags-resource
Browse files Browse the repository at this point in the history
Adding Tag and Tag Assignment resources. Also Tag Data Source.
  • Loading branch information
Scott McAllister authored Oct 11, 2021
2 parents 7b9df94 + 66f3716 commit 23ba885
Show file tree
Hide file tree
Showing 38 changed files with 1,490 additions and 193 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ go 1.16

require (
cloud.google.com/go v0.71.0 // indirect
github.com/heimweh/go-pagerduty v0.0.0-20210930203304-530eff2acdc6
github.com/google/go-querystring v1.0.0 // indirect
github.com/hashicorp/terraform-plugin-sdk/v2 v2.7.1
github.com/heimweh/go-pagerduty v0.0.0-20210831220234-54710c5e87d1
go.mongodb.org/mongo-driver v1.7.0 // indirect
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd // indirect
google.golang.org/api v0.35.0 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/heimweh/go-pagerduty v0.0.0-20210831220234-54710c5e87d1 h1:yBAqdyzvIpGktzh8EnWqaXAtwhdgWqrP2Zk53MDH89Y=
github.com/heimweh/go-pagerduty v0.0.0-20210831220234-54710c5e87d1/go.mod h1:6+bccpjQ/PM8uQY9m8avM4MJea+3vo3ta9r8kGQ4XFY=
github.com/heimweh/go-pagerduty v0.0.0-20210930203304-530eff2acdc6 h1:/D0VtHEOCdotE1vSB9XznceAjIGkUieZ4BF6VKUIqNU=
github.com/heimweh/go-pagerduty v0.0.0-20210930203304-530eff2acdc6/go.mod h1:JtJGtgN0y9KOCaqFMZFaBCWskpO/KK3Ro9TwjP9ss6w=
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 Expand Up @@ -376,6 +378,8 @@ github.com/zclconf/go-cty v1.8.4/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUA
github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8=
go.mongodb.org/mongo-driver v1.7.0 h1:hHrvOBWlWB2c7+8Gh/Xi5jj82AgidK/t7KVXBZ+IyUA=
go.mongodb.org/mongo-driver v1.7.0/go.mod h1:Q4oFMbo1+MSNqICAdYMlC/zSTrwCogR4R8NzkI+yfU8=
go.mongodb.org/mongo-driver v1.7.2 h1:pFttQyIiJUHEn50YfZgC9ECjITMT44oiN36uArf/OFg=
go.mongodb.org/mongo-driver v1.7.2/go.mod h1:Q4oFMbo1+MSNqICAdYMlC/zSTrwCogR4R8NzkI+yfU8=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
Expand Down
73 changes: 73 additions & 0 deletions pagerduty/data_source_pagerduty_tag.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package pagerduty

import (
"fmt"
"log"
"time"

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

func dataSourcePagerDutyTag() *schema.Resource {
return &schema.Resource{
Read: dataSourcePagerDutyTagRead,

Schema: map[string]*schema.Schema{
"label": {
Type: schema.TypeString,
Required: true,
Description: "The label of the tag to find in the PagerDuty API",
},
},
}
}

func dataSourcePagerDutyTagRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*pagerduty.Client)

log.Printf("[INFO] Reading PagerDuty tag")

searchTag := d.Get("label").(string)

o := &pagerduty.ListTagsOptions{
Query: searchTag,
}

return resource.Retry(2*time.Minute, func() *resource.RetryError {
resp, _, err := client.Tags.List(o)
if err != nil {
if isErrCode(err, 429) {
// Delaying retry by 30s as recommended by PagerDuty
// https://developer.pagerduty.com/docs/rest-api-v2/rate-limiting/#what-are-possible-workarounds-to-the-events-api-rate-limit
time.Sleep(30 * time.Second)
return resource.RetryableError(err)
}

return resource.NonRetryableError(err)
}

var found *pagerduty.Tag

for _, tag := range resp.Tags {
if tag.Label == searchTag {
found = tag
break
}
}

if found == nil {
return resource.NonRetryableError(
fmt.Errorf("Unable to locate any tag with label: %s", searchTag),
)
}

d.SetId(found.ID)
d.Set("label", found.Label)
d.Set("summary", found.Summary)
d.Set("html_url", found.HTMLURL)

return nil
})
}
64 changes: 64 additions & 0 deletions pagerduty/data_source_pagerduty_tag_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
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 TestAccDataSourcePagerDutyTag_Basic(t *testing.T) {
tag := fmt.Sprintf("tf-%s", acctest.RandString(5))

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourcePagerDutyTagConfig(tag),
Check: resource.ComposeTestCheckFunc(
testAccDataSourcePagerDutyTag("pagerduty_tag.test", "data.pagerduty_tag.by_label"),
),
},
},
})
}

func testAccDataSourcePagerDutyTag(src, n string) resource.TestCheckFunc {
return func(s *terraform.State) error {

srcR := s.RootModule().Resources[src]
srcA := srcR.Primary.Attributes

r := s.RootModule().Resources[n]
a := r.Primary.Attributes

if a["id"] == "" {
return fmt.Errorf("Expected to get a tag ID from PagerDuty")
}

testAtts := []string{"id", "label"}

for _, att := range testAtts {
if a[att] != srcA[att] {
return fmt.Errorf("Expected the tag %s to be: %s, but got: %s", att, srcA[att], a[att])
}
}

return nil
}
}

func testAccDataSourcePagerDutyTagConfig(tag string) string {
return fmt.Sprintf(`
resource "pagerduty_tag" "test" {
label = "%s"
}
data "pagerduty_tag" "by_label" {
label = pagerduty_tag.test.label
}
`, tag)
}
37 changes: 37 additions & 0 deletions pagerduty/import_pagerduty_tag_assignment_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
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 TestAccPagerDutyTagAssignment_import(t *testing.T) {
tag := fmt.Sprintf("tf-%s", acctest.RandString(5))
team := fmt.Sprintf("tf-%s", acctest.RandString(5))

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckPagerDutyTagAssignmentDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckPagerDutyTagAssignmentTeamConfig(tag, team),
},

{
ResourceName: "pagerduty_tag_assignment.foo",
ImportStateIdFunc: testAccCheckPagerDutyTagAssignmentID,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccCheckPagerDutyTagAssignmentID(s *terraform.State) (string, error) {
return fmt.Sprintf("%v.%v.%v", "teams", s.RootModule().Resources["pagerduty_team.foo"].Primary.ID, s.RootModule().Resources["pagerduty_tag.foo"].Primary.ID), nil
}
30 changes: 30 additions & 0 deletions pagerduty/import_pagerduty_tag_test.go
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 TestAccPagerDutyTag_import(t *testing.T) {
tag := fmt.Sprintf("tf-%s", acctest.RandString(5))

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckPagerDutyTagDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckPagerDutyTagConfig(tag),
},

{
ResourceName: "pagerduty_tag.foo",
ImportState: true,
ImportStateVerify: true,
},
},
})
}
3 changes: 3 additions & 0 deletions pagerduty/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ func Provider() *schema.Provider {
"pagerduty_business_service": dataSourcePagerDutyBusinessService(),
"pagerduty_priority": dataSourcePagerDutyPriority(),
"pagerduty_ruleset": dataSourcePagerDutyRuleset(),
"pagerduty_tag": dataSourcePagerDutyTag(),
},

ResourcesMap: map[string]*schema.Resource{
Expand All @@ -61,6 +62,8 @@ func Provider() *schema.Provider {
"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(),
},
Expand Down
118 changes: 118 additions & 0 deletions pagerduty/resource_pagerduty_tag.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package pagerduty

import (
"log"
"time"

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

func resourcePagerDutyTag() *schema.Resource {
return &schema.Resource{
Create: resourcePagerDutyTagCreate,
Read: resourcePagerDutyTagRead,
Delete: resourcePagerDutyTagDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"label": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"summary": {
Type: schema.TypeString,
Computed: true,
},
"html_url": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func buildTagStruct(d *schema.ResourceData) *pagerduty.Tag {
tag := &pagerduty.Tag{
Label: d.Get("label").(string),
Type: "tag",
}

if attr, ok := d.GetOk("summary"); ok {
tag.Summary = attr.(string)
}

return tag
}

func resourcePagerDutyTagCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*pagerduty.Client)

tag := buildTagStruct(d)

log.Printf("[INFO] Creating PagerDuty tag %s", tag.Label)

retryErr := resource.Retry(10*time.Second, func() *resource.RetryError {
if tag, _, err := client.Tags.Create(tag); err != nil {
if isErrCode(err, 400) || isErrCode(err, 429) {
return resource.RetryableError(err)
}

return resource.NonRetryableError(err)
} else if tag != nil {
d.SetId(tag.ID)
}
return nil
})

if retryErr != nil {
return retryErr
}

return resourcePagerDutyTagRead(d, meta)

}

func resourcePagerDutyTagRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*pagerduty.Client)

log.Printf("[INFO] Reading PagerDuty tag %s", d.Id())

return resource.Retry(30*time.Second, func() *resource.RetryError {
if tag, _, err := client.Tags.Get(d.Id()); err != nil {
time.Sleep(2 * time.Second)
return resource.RetryableError(err)
} else if tag != nil {
log.Printf("Tag Type: %v", tag.Type)
d.Set("label", tag.Label)
d.Set("summary", tag.Summary)
d.Set("html_url", tag.HTMLURL)
}
return nil
})
}

func resourcePagerDutyTagDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*pagerduty.Client)

log.Printf("[INFO] Deleting PagerDuty tag %s", d.Id())

retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError {
if _, err := client.Tags.Delete(d.Id()); 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
}
Loading

0 comments on commit 23ba885

Please sign in to comment.