Skip to content

Commit ff32898

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

26 files changed

+1884
-5
lines changed

github/data_source_github_organization_custom_role.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ import (
1212

1313
func dataSourceGithubOrganizationCustomRole() *schema.Resource {
1414
return &schema.Resource{
15-
Read: dataSourceGithubOrganizationCustomRoleRead,
15+
DeprecationMessage: "This data source is deprecated and will be removed in a future release. Use the github_organization_repository_role data source instead.",
1616

17+
Read: dataSourceGithubOrganizationCustomRoleRead,
1718
Schema: map[string]*schema.Schema{
1819
"name": {
1920
Type: schema.TypeString,
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package github
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"strconv"
7+
8+
"github.com/google/go-github/v66/github"
9+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
10+
)
11+
12+
func dataSourceGithubOrganizationRepositoryRole() *schema.Resource {
13+
return &schema.Resource{
14+
Read: dataSourceGithubOrganizationRepositoryRoleRead,
15+
16+
Schema: map[string]*schema.Schema{
17+
"role_id": {
18+
Description: "The ID of the organization repository role.",
19+
Type: schema.TypeInt,
20+
Required: true,
21+
},
22+
"name": {
23+
Description: "The name of the organization repository role.",
24+
Type: schema.TypeString,
25+
Computed: true,
26+
},
27+
"description": {
28+
Description: "A short description about who this role is for or what permissions it grants.",
29+
Type: schema.TypeString,
30+
Computed: true,
31+
},
32+
"base_role": {
33+
Description: "The system role from which this role inherits permissions.",
34+
Type: schema.TypeString,
35+
Computed: true,
36+
},
37+
"permissions": {
38+
Description: "A list of permissions included in this role.",
39+
Type: schema.TypeSet,
40+
Elem: &schema.Schema{Type: schema.TypeString},
41+
Computed: true,
42+
},
43+
},
44+
}
45+
}
46+
47+
func dataSourceGithubOrganizationRepositoryRoleRead(d *schema.ResourceData, meta interface{}) error {
48+
client := meta.(*Owner).v3client
49+
ctx := context.Background()
50+
orgName := meta.(*Owner).name
51+
52+
roleId := int64(d.Get("role_id").(int))
53+
54+
// TODO: Use this code when go-github adds the functionality to get a custom repo role
55+
// role, _, err := client.Organizations.GetCustomRepoRole(ctx, orgName, roleId)
56+
// if err != nil {
57+
// return err
58+
// }
59+
60+
roles, _, err := client.Organizations.ListCustomRepoRoles(ctx, orgName)
61+
if err != nil {
62+
return err
63+
}
64+
65+
var role *github.CustomRepoRoles
66+
for _, r := range roles.CustomRepoRoles {
67+
if r.GetID() == roleId {
68+
role = r
69+
break
70+
}
71+
}
72+
if role == nil {
73+
return fmt.Errorf("custom organization repo role with ID %d not found", roleId)
74+
}
75+
76+
r := map[string]any{
77+
"role_id": role.GetID(),
78+
"name": role.GetName(),
79+
"description": role.GetDescription(),
80+
"base_role": role.GetBaseRole(),
81+
"permissions": role.Permissions,
82+
}
83+
84+
d.SetId(strconv.FormatInt(role.GetID(), 10))
85+
86+
for k, v := range r {
87+
if err := d.Set(k, v); err != nil {
88+
return err
89+
}
90+
}
91+
92+
return nil
93+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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 TestAccGithubOrganizationRepositoryRoleDataSource(t *testing.T) {
12+
t.Run("queries an organization repository role", func(t *testing.T) {
13+
randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum)
14+
roleName := fmt.Sprintf(`tf-acc-test-%s`, randomID)
15+
16+
config := fmt.Sprintf(`
17+
resource "github_organization_repository_role" "test" {
18+
name = "%s"
19+
description = "Test role description"
20+
base_role = "read"
21+
permissions = [
22+
"reopen_issue",
23+
"reopen_pull_request",
24+
]
25+
}
26+
27+
data "github_organization_repository_role" "test" {
28+
role_id = github_organization_repository_role.test.role_id
29+
30+
depends_on = [ github_organization_repository_role.test ]
31+
}
32+
`, roleName)
33+
34+
resource.Test(t, resource.TestCase{
35+
PreCheck: func() { skipUnlessMode(t, enterprise) },
36+
Providers: testAccProviders,
37+
Steps: []resource.TestStep{
38+
{
39+
Config: config,
40+
Check: resource.ComposeTestCheckFunc(
41+
resource.TestCheckResourceAttrPair("data.github_organization_repository_role.test", "name", "github_organization_repository_role.test", "name"),
42+
resource.TestCheckResourceAttrPair("data.github_organization_repository_role.test", "description", "github_organization_repository_role.test", "description"),
43+
resource.TestCheckResourceAttrPair("data.github_organization_repository_role.test", "base_role", "github_organization_repository_role.test", "base_role"),
44+
resource.TestCheckResourceAttrPair("data.github_organization_repository_role.test", "permissions.#", "github_organization_repository_role.test", "permissions.#"),
45+
),
46+
},
47+
},
48+
})
49+
})
50+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package github
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
8+
)
9+
10+
func dataSourceGithubOrganizationRepositoryRoles() *schema.Resource {
11+
return &schema.Resource{
12+
Read: dataSourceGithubOrganizationRepositoryRolesRead,
13+
14+
Schema: map[string]*schema.Schema{
15+
"roles": {
16+
Description: "The list of organization repository roles available.",
17+
Type: schema.TypeList,
18+
Computed: true,
19+
Elem: &schema.Resource{
20+
Schema: map[string]*schema.Schema{
21+
"role_id": {
22+
Description: "The unique identifier of the organization repository role.",
23+
Type: schema.TypeInt,
24+
Computed: true,
25+
},
26+
"name": {
27+
Description: "The name of the organization repository role.",
28+
Type: schema.TypeString,
29+
Computed: true,
30+
},
31+
"description": {
32+
Description: "A short description about who this role is for or what permissions it grants.",
33+
Type: schema.TypeString,
34+
Computed: true,
35+
},
36+
"base_role": {
37+
Description: "The system role from which this role inherits permissions.",
38+
Type: schema.TypeString,
39+
Computed: true,
40+
},
41+
"permissions": {
42+
Description: "A list of permissions included in this role.",
43+
Type: schema.TypeSet,
44+
Elem: &schema.Schema{Type: schema.TypeString},
45+
Computed: true,
46+
},
47+
},
48+
},
49+
},
50+
},
51+
}
52+
}
53+
54+
func dataSourceGithubOrganizationRepositoryRolesRead(d *schema.ResourceData, meta interface{}) error {
55+
client := meta.(*Owner).v3client
56+
ctx := context.Background()
57+
orgName := meta.(*Owner).name
58+
59+
ret, _, err := client.Organizations.ListCustomRepoRoles(ctx, orgName)
60+
if err != nil {
61+
return err
62+
}
63+
64+
allRoles := make([]any, ret.GetTotalCount())
65+
for i, role := range ret.CustomRepoRoles {
66+
r := map[string]any{
67+
"role_id": role.GetID(),
68+
"name": role.GetName(),
69+
"description": role.GetDescription(),
70+
"base_role": role.GetBaseRole(),
71+
"permissions": role.Permissions,
72+
}
73+
allRoles[i] = r
74+
}
75+
76+
d.SetId(fmt.Sprintf("%s/github-org-repo-roles", orgName))
77+
if err := d.Set("roles", allRoles); err != nil {
78+
return fmt.Errorf("error setting roles: %s", err)
79+
}
80+
81+
return nil
82+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package github
2+
3+
import (
4+
"testing"
5+
6+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
7+
)
8+
9+
func TestAccDataSourceGithubOrganizationRepositoryRoles(t *testing.T) {
10+
t.Run("get empty organization roles without error", func(t *testing.T) {
11+
config := `
12+
data "github_organization_repository_roles" "test" {}
13+
`
14+
15+
resource.Test(t, resource.TestCase{
16+
PreCheck: func() { skipUnlessMode(t, organization) },
17+
Providers: testAccProviders,
18+
Steps: []resource.TestStep{
19+
{
20+
Config: config,
21+
Check: resource.ComposeTestCheckFunc(
22+
resource.TestCheckResourceAttrSet("data.github_organization_repository_roles.test", "roles.#"),
23+
resource.TestCheckResourceAttr("data.github_organization_repository_roles.test", "roles.#", "0"),
24+
),
25+
},
26+
},
27+
})
28+
})
29+
30+
t.Run("get organization roles without error", func(t *testing.T) {
31+
config := `
32+
resource "github_organization_repository_role" "test" {
33+
name = "%s"
34+
description = "Test role description"
35+
base_role = "read"
36+
permissions = [
37+
"reopen_issue",
38+
"reopen_pull_request",
39+
]
40+
}
41+
42+
data "github_organization_repository_roles" "test" {
43+
depends_on = [ github_organization_repository_role.test ]
44+
}
45+
`
46+
47+
resource.Test(t, resource.TestCase{
48+
PreCheck: func() { skipUnlessMode(t, enterprise) },
49+
Providers: testAccProviders,
50+
Steps: []resource.TestStep{
51+
{
52+
Config: config,
53+
Check: resource.ComposeTestCheckFunc(
54+
resource.TestCheckResourceAttrSet("data.github_organization_repository_roles.test", "roles.#"),
55+
resource.TestCheckResourceAttr("data.github_organization_repository_roles.test", "roles.#", "1"),
56+
resource.TestCheckResourceAttrPair("data.github_organization_repository_roles.test", "roles.0.name", "github_organization_repository_role.test", "name"),
57+
resource.TestCheckResourceAttrPair("data.github_organization_repository_roles.test", "roles.0.description", "github_organization_repository_role.test", "description"),
58+
resource.TestCheckResourceAttrPair("data.github_organization_repository_roles.test", "roles.0.base_role", "github_organization_repository_role.test", "base_role"),
59+
resource.TestCheckResourceAttrPair("data.github_organization_repository_roles.test", "roles.0.permissions.#", "github_organization_repository_role.test", "permissions.#"),
60+
),
61+
},
62+
},
63+
})
64+
})
65+
}
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 organization role.",
17+
Type: schema.TypeInt,
18+
Required: true,
19+
},
20+
"name": {
21+
Description: "The name of the organization 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+
}

0 commit comments

Comments
 (0)