Skip to content

Commit

Permalink
Merge pull request #545 from imjaroiswebdev/issue-345-data-team-members
Browse files Browse the repository at this point in the history
Add `pagerduty_users` data source
  • Loading branch information
Scott McAllister authored Jul 21, 2022
2 parents ad92df5 + a41b13d commit e251ef8
Show file tree
Hide file tree
Showing 4 changed files with 289 additions and 0 deletions.
93 changes: 93 additions & 0 deletions pagerduty/data_source_pagerduty_users.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package pagerduty

import (
"log"
"strconv"
"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 dataSourcePagerDutyUsers() *schema.Resource {
return &schema.Resource{
Read: dataSourcePagerDutyUsersRead,

Schema: map[string]*schema.Schema{
"team_ids": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"users": {
Type: schema.TypeList,
Computed: true,
Description: "List of users who are members of the team",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"email": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
},
}
}

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

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

pre := d.Get("team_ids").([]interface{})
var teamIds []string
for _, ti := range pre {
teamIds = append(teamIds, ti.(string))
}

o := &pagerduty.ListUsersOptions{
TeamIDs: teamIds,
}

return resource.Retry(5*time.Minute, func() *resource.RetryError {
resp, err := client.Users.ListAll(o)
if err != nil {
// 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)
}

var users []map[string]interface{}
for _, user := range resp {
users = append(users, map[string]interface{}{
"id": user.ID,
"name": user.Name,
"email": user.Email,
})
}

// Since this data doesn't have an unique ID, this force this data to be
// refreshed in every Terraform apply
d.SetId(strconv.FormatInt(time.Now().Unix(), 10))
d.Set("users", users)

return nil
})
}
137 changes: 137 additions & 0 deletions pagerduty/data_source_pagerduty_users_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
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 TestAccDataSourcePagerDutyUsers_Basic(t *testing.T) {
teamname1 := fmt.Sprintf("tf-team-%s", acctest.RandString(5))
teamname2 := fmt.Sprintf("tf-team-%s", acctest.RandString(5))
username1 := fmt.Sprintf("tf-user1-%s", acctest.RandString(5))
email1 := fmt.Sprintf("%s@foo.test", username1)
username2 := fmt.Sprintf("tf-user2-%s", acctest.RandString(5))
email2 := fmt.Sprintf("%s@foo.test", username2)
username3 := fmt.Sprintf("tf-user3-%s", acctest.RandString(5))
email3 := fmt.Sprintf("%s@foo.test", username3)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourcePagerDutyUsersConfig(teamname1, teamname2, username1, email1, username2, email2, username3, email3),
Check: resource.ComposeTestCheckFunc(
testAccDataSourcePagerDutyUsersExists("data.pagerduty_users.test_all_users"),
testAccDataSourcePagerDutyUsersExists("data.pagerduty_users.test_by_1_team"),
testAccDataSourcePagerDutyUsersExists("data.pagerduty_users.test_by_2_team"),
resource.TestCheckResourceAttrSet(
"data.pagerduty_users.test_all_users", "users.#"),
resource.TestCheckTypeSetElemNestedAttrs(
"data.pagerduty_users.test_all_users",
"users.*",
map[string]string{
"name": username1,
}),
resource.TestCheckTypeSetElemNestedAttrs(
"data.pagerduty_users.test_all_users",
"users.*",
map[string]string{
"name": username2,
}),
resource.TestCheckTypeSetElemNestedAttrs(
"data.pagerduty_users.test_all_users",
"users.*",
map[string]string{
"name": username3,
}),
resource.TestCheckResourceAttr(
"data.pagerduty_users.test_by_1_team", "users.#", "1"),
resource.TestCheckResourceAttrSet(
"data.pagerduty_users.test_by_1_team", "users.0.id"),
resource.TestCheckResourceAttr(
"data.pagerduty_users.test_by_1_team", "users.0.name", username2),
resource.TestCheckResourceAttr(
"data.pagerduty_users.test_by_1_team", "users.0.email", email2),
resource.TestCheckResourceAttr(
"data.pagerduty_users.test_by_2_team", "users.#", "2"),
resource.TestCheckResourceAttrSet(
"data.pagerduty_users.test_by_2_team", "users.0.id"),
resource.TestCheckResourceAttr(
"data.pagerduty_users.test_by_2_team", "users.0.name", username2),
resource.TestCheckResourceAttr(
"data.pagerduty_users.test_by_2_team", "users.0.email", email2),
resource.TestCheckResourceAttr(
"data.pagerduty_users.test_by_2_team", "users.1.name", username3),
resource.TestCheckResourceAttr(
"data.pagerduty_users.test_by_2_team", "users.1.email", email3),
),
},
},
})
}

func testAccDataSourcePagerDutyUsersExists(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {

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

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

return nil
}
}

func testAccDataSourcePagerDutyUsersConfig(teamname1, teamname2, username1, email1, username2, email2, username3, email3 string) string {
return fmt.Sprintf(`
resource "pagerduty_team" "test1" {
name = "%s"
}
resource "pagerduty_team" "test2" {
name = "%s"
}
resource "pagerduty_user" "test_wo_team" {
name = "%s"
email = "%s"
}
resource "pagerduty_user" "test_w_team1" {
name = "%s"
email = "%s"
}
resource "pagerduty_user" "test_w_team2" {
name = "%s"
email = "%s"
}
resource "pagerduty_team_membership" "test1" {
team_id = pagerduty_team.test1.id
user_id = pagerduty_user.test_w_team1.id
}
resource "pagerduty_team_membership" "test2" {
depends_on = [pagerduty_team_membership.test1]
team_id = pagerduty_team.test2.id
user_id = pagerduty_user.test_w_team2.id
}
data "pagerduty_users" "test_all_users" {
depends_on = [pagerduty_user.test_w_team1, pagerduty_user.test_wo_team]
}
data "pagerduty_users" "test_by_1_team" {
depends_on = [pagerduty_team_membership.test1]
team_ids = [pagerduty_team.test1.id]
}
data "pagerduty_users" "test_by_2_team" {
depends_on = [pagerduty_team_membership.test2]
team_ids = [pagerduty_team.test1.id, pagerduty_team.test2.id]
}
`, teamname1, teamname2, username1, email1, username2, email2, username3, email3)
}
1 change: 1 addition & 0 deletions pagerduty/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func Provider() *schema.Provider {
"pagerduty_escalation_policy": dataSourcePagerDutyEscalationPolicy(),
"pagerduty_schedule": dataSourcePagerDutySchedule(),
"pagerduty_user": dataSourcePagerDutyUser(),
"pagerduty_users": dataSourcePagerDutyUsers(),
"pagerduty_user_contact_method": dataSourcePagerDutyUserContactMethod(),
"pagerduty_team": dataSourcePagerDutyTeam(),
"pagerduty_vendor": dataSourcePagerDutyVendor(),
Expand Down
58 changes: 58 additions & 0 deletions website/docs/d/users.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
layout: "pagerduty"
page_title: "PagerDuty: pagerduty_user"
sidebar_current: "docs-pagerduty-datasource-user"
description: |-
Get information about users of your PagerDuty account as a list, optionally filtered by team ids that you can use for a service integration (e.g Amazon Cloudwatch, Splunk, Datadog).
---

# pagerduty\_users

Use this data source to get information about [list of users][1] that you can use for other PagerDuty resources, optionally filtering by team ids.

## Example Usage

```hcl
data "pagerduty_team" "devops" {
name = "devops"
}
data "pagerduty_user" "me" {
email = "me@example.com"
}
resource "pagerduty_user" "example_w_team" {
name = "user-with-team"
email = "user-with-team@example.com"
}
resource "pagerduty_team_membership" "example" {
team_id = pagerduty_team.devops.id
user_id = pagerduty_user.example_w_team.id
}
data "pagerduty_users" "all_users" {}
data "pagerduty_users" "from_devops_team" {
depends_on = [pagerduty_team_membership.example]
team_ids = [pagerduty_team.devops.id]
}
```

## Argument Reference

The following arguments are supported:

* `team_ids` - (Optional) List of team IDs. Only results related to these teams will be returned. Account must have the `teams` ability to use this parameter.

## Attributes Reference
* `id` - The ID of queried list of users.
* `users` - List of users queried.

### Users (`users`) supports the following:

* `id` - The ID of the found user.
* `name` - The short name of the found user.
* `email` - The email to use to find a user in the PagerDuty API.

[1]: https://developer.pagerduty.com/api-reference/b3A6Mjc0ODIzMw-list-users

0 comments on commit e251ef8

Please sign in to comment.