Skip to content

Commit 468dc74

Browse files
committed
feat: Added organization role support
Signed-off-by: Steve Hipwell <[email protected]>
1 parent 1c11053 commit 468dc74

16 files changed

+1266
-2
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package github
2+
3+
import (
4+
"context"
5+
"strconv"
6+
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
8+
)
9+
10+
func dataSourceGithubOrganizationRole() *schema.Resource {
11+
return &schema.Resource{
12+
Read: dataSourceGithubOrganizationRoleRead,
13+
14+
Schema: map[string]*schema.Schema{
15+
"role_id": {
16+
Description: "The ID of the role.",
17+
Type: schema.TypeInt,
18+
Required: true,
19+
},
20+
"name": {
21+
Description: "The name of the role.",
22+
Type: schema.TypeString,
23+
Computed: true,
24+
},
25+
"description": {
26+
Description: "A short description about who this role is for or what permissions it grants.",
27+
Type: schema.TypeString,
28+
Computed: true,
29+
},
30+
"source": {
31+
Description: "Source answers the question, \"where did this role come from?\"",
32+
Type: schema.TypeString,
33+
Computed: true,
34+
},
35+
"base_role": {
36+
Description: "The system role from which this role inherits permissions.",
37+
Type: schema.TypeString,
38+
Computed: true,
39+
},
40+
"permissions": {
41+
Description: "A list of permissions included in this role.",
42+
Type: schema.TypeSet,
43+
Elem: &schema.Schema{Type: schema.TypeString},
44+
Computed: true,
45+
},
46+
},
47+
}
48+
}
49+
50+
func dataSourceGithubOrganizationRoleRead(d *schema.ResourceData, meta interface{}) error {
51+
client := meta.(*Owner).v3client
52+
ctx := context.Background()
53+
orgName := meta.(*Owner).name
54+
55+
roleId := int64(d.Get("role_id").(int))
56+
57+
role, _, err := client.Organizations.GetOrgRole(ctx, orgName, roleId)
58+
if err != nil {
59+
return err
60+
}
61+
62+
r := map[string]any{
63+
"role_id": role.GetID(),
64+
"name": role.GetName(),
65+
"description": role.GetDescription(),
66+
"source": role.GetSource(),
67+
"base_role": role.GetBaseRole(),
68+
"permissions": role.Permissions,
69+
}
70+
71+
d.SetId(strconv.FormatInt(role.GetID(), 10))
72+
73+
for k, v := range r {
74+
if err := d.Set(k, v); err != nil {
75+
return err
76+
}
77+
}
78+
79+
return nil
80+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package github
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/google/go-github/v66/github"
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
9+
)
10+
11+
func dataSourceGithubOrganizationRoleTeams() *schema.Resource {
12+
return &schema.Resource{
13+
Read: dataSourceGithubOrganizationRoleTeamsRead,
14+
15+
Schema: map[string]*schema.Schema{
16+
"role_id": {
17+
Description: "The unique identifier of the role to find teams for.",
18+
Type: schema.TypeInt,
19+
Required: true,
20+
ForceNew: true,
21+
},
22+
"teams": {
23+
Description: "List of teams assigned to the organization role.",
24+
Type: schema.TypeList,
25+
Computed: true,
26+
Elem: &schema.Resource{
27+
Schema: map[string]*schema.Schema{
28+
"id": {
29+
Description: "Unique identifier of the team.",
30+
Type: schema.TypeInt,
31+
Computed: true,
32+
},
33+
"slug": {
34+
Description: "Slug of the team name.",
35+
Type: schema.TypeString,
36+
Computed: true,
37+
},
38+
"name": {
39+
Description: "Name of the team.",
40+
Type: schema.TypeString,
41+
Computed: true,
42+
},
43+
"permission": {
44+
Description: "Permission that the team will have for its repositories.",
45+
Type: schema.TypeString,
46+
Computed: true,
47+
},
48+
// See https://github.com/google/go-github/issues/3364
49+
// "assignment": {
50+
// Description: "Determines if the team has a direct, indirect, or mixed relationship to a role.",
51+
// Type: schema.TypeString,
52+
// Computed: true,
53+
// },
54+
// "parent_team_id": {
55+
// Description: "The ID of the parent team if this is an indirect assignment.",
56+
// Type: schema.TypeString,
57+
// Computed: true,
58+
// },
59+
// "parent_team_slug": {
60+
// Description: "The slug of the parent team if this is an indirect assignment.",
61+
// Type: schema.TypeString,
62+
// Computed: true,
63+
// },
64+
},
65+
},
66+
},
67+
},
68+
}
69+
}
70+
71+
func dataSourceGithubOrganizationRoleTeamsRead(d *schema.ResourceData, meta interface{}) error {
72+
client := meta.(*Owner).v3client
73+
ctx := context.Background()
74+
orgName := meta.(*Owner).name
75+
76+
roleId := int64(d.Get("role_id").(int))
77+
78+
allTeams := make([]any, 0)
79+
80+
opts := &github.ListOptions{
81+
PerPage: maxPerPage,
82+
}
83+
84+
for {
85+
teams, resp, err := client.Organizations.ListTeamsAssignedToOrgRole(ctx, orgName, roleId, opts)
86+
if err != nil {
87+
return err
88+
}
89+
90+
for _, team := range teams {
91+
t := map[string]any{
92+
"id": team.GetID(),
93+
"slug": team.GetSlug(),
94+
"name": team.GetName(),
95+
"permission": team.GetPermission(),
96+
}
97+
allTeams = append(allTeams, t)
98+
}
99+
100+
if resp.NextPage == 0 {
101+
break
102+
}
103+
opts.Page = resp.NextPage
104+
}
105+
106+
d.SetId(fmt.Sprintf("%d", roleId))
107+
if err := d.Set("teams", allTeams); err != nil {
108+
return fmt.Errorf("error setting teams: %s", err)
109+
}
110+
111+
return nil
112+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package github
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
9+
)
10+
11+
func TestAccDataSourceGithubOrganizationRoleTeams(t *testing.T) {
12+
t.Run("get the organization role teams without error", func(t *testing.T) {
13+
randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum)
14+
teamName := fmt.Sprintf("tf-acc-team-%s", randomID)
15+
roleId := 8134
16+
config := fmt.Sprintf(`
17+
resource "github_team" "test" {
18+
name = "%s"
19+
}
20+
21+
resource "github_organization_role_team" "test" {
22+
role_id = %d
23+
team_slug = github_team.test.slug
24+
}
25+
26+
data "github_organization_role_teams" "test" {
27+
role_id = %[2]d
28+
29+
depends_on = [
30+
github_organization_role_team.test
31+
]
32+
}
33+
`, teamName, roleId)
34+
35+
resource.Test(t, resource.TestCase{
36+
PreCheck: func() { skipUnlessMode(t, organization) },
37+
Providers: testAccProviders,
38+
Steps: []resource.TestStep{
39+
{
40+
Config: config,
41+
Check: resource.ComposeTestCheckFunc(
42+
resource.TestCheckResourceAttrSet("data.github_organization_role_teams.test", "teams.#"),
43+
resource.TestCheckResourceAttr("data.github_organization_role_teams.test", "teams.#", "1"),
44+
resource.TestCheckResourceAttrPair("data.github_organization_role_teams.test", "teams.0.id", "github_team.test", "id"),
45+
resource.TestCheckResourceAttrPair("data.github_organization_role_teams.test", "teams.0.slug", "github_team.test", "slug"),
46+
resource.TestCheckResourceAttrPair("data.github_organization_role_teams.test", "teams.0.name", "github_team.test", "name"),
47+
),
48+
},
49+
},
50+
})
51+
})
52+
53+
t.Run("get indirect organization role teams without error", func(t *testing.T) {
54+
randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum)
55+
teamName1 := fmt.Sprintf("tf-acc-team-1-%s", randomID)
56+
teamName2 := fmt.Sprintf("tf-acc-team-2-%s", randomID)
57+
roleId := 8134
58+
config := fmt.Sprintf(`
59+
resource "github_team" "test_1" {
60+
name = "%s"
61+
privacy = "closed"
62+
}
63+
64+
resource "github_team" "test_2" {
65+
name = "%s"
66+
privacy = "closed"
67+
parent_team_id = github_team.test_1.id
68+
}
69+
70+
resource "github_organization_role_team" "test" {
71+
role_id = %d
72+
team_slug = github_team.test_1.slug
73+
}
74+
75+
data "github_organization_role_teams" "test" {
76+
role_id = %[3]d
77+
78+
depends_on = [
79+
github_organization_role_team.test
80+
]
81+
}
82+
`, teamName1, teamName2, roleId)
83+
84+
resource.Test(t, resource.TestCase{
85+
PreCheck: func() { skipUnlessMode(t, organization) },
86+
Providers: testAccProviders,
87+
Steps: []resource.TestStep{
88+
{
89+
Config: config,
90+
Check: resource.ComposeTestCheckFunc(
91+
resource.TestCheckResourceAttrSet("data.github_organization_role_teams.test", "teams.#"),
92+
resource.TestCheckResourceAttr("data.github_organization_role_teams.test", "teams.#", "2"),
93+
resource.TestCheckResourceAttrPair("data.github_organization_role_teams.test", "teams.0.id", "github_team.test_1", "id"),
94+
resource.TestCheckResourceAttrPair("data.github_organization_role_teams.test", "teams.0.slug", "github_team.test_1", "slug"),
95+
resource.TestCheckResourceAttrPair("data.github_organization_role_teams.test", "teams.0.name", "github_team.test_1", "name"),
96+
resource.TestCheckResourceAttrPair("data.github_organization_role_teams.test", "teams.1.id", "github_team.test_2", "id"),
97+
resource.TestCheckResourceAttrPair("data.github_organization_role_teams.test", "teams.1.slug", "github_team.test_2", "slug"),
98+
resource.TestCheckResourceAttrPair("data.github_organization_role_teams.test", "teams.1.name", "github_team.test_2", "name"),
99+
),
100+
},
101+
},
102+
})
103+
})
104+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package github
2+
3+
import (
4+
"fmt"
5+
"strconv"
6+
"testing"
7+
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
9+
)
10+
11+
func TestAccDataSourceGithubOrganizationRole(t *testing.T) {
12+
t.Run("get the organization role without error", func(t *testing.T) {
13+
roleId := 138
14+
config := fmt.Sprintf(`
15+
data "github_organization_role" "test" {
16+
role_id = %d
17+
}
18+
`, roleId)
19+
20+
resource.Test(t, resource.TestCase{
21+
PreCheck: func() { skipUnlessMode(t, organization) },
22+
Providers: testAccProviders,
23+
Steps: []resource.TestStep{
24+
{
25+
Config: config,
26+
Check: resource.ComposeTestCheckFunc(
27+
resource.TestCheckResourceAttr("data.github_organization_role.test", "role_id", strconv.Itoa(roleId)),
28+
resource.TestCheckResourceAttr("data.github_organization_role.test", "name", "security_manager"),
29+
resource.TestCheckResourceAttr("data.github_organization_role.test", "source", "Predefined"),
30+
resource.TestCheckResourceAttr("data.github_organization_role.test", "base_role", "read"),
31+
resource.TestCheckResourceAttrSet("data.github_organization_role.test", "description"),
32+
resource.TestCheckResourceAttrSet("data.github_organization_role.test", "permissions.#"),
33+
),
34+
},
35+
},
36+
})
37+
})
38+
}

0 commit comments

Comments
 (0)