Skip to content

Commit b04dee2

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

File tree

37 files changed

+2282
-5
lines changed

37 files changed

+2282
-5
lines changed

.markdownlint.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
MD013: false
2+
MD024:
3+
siblings_only: true
4+
MD028: false

github/data_source_github_organization_custom_role.go

+2-1
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,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
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+
Description: "Lookup a custom organization repository role.",
15+
16+
Read: dataSourceGithubOrganizationRepositoryRoleRead,
17+
18+
Schema: map[string]*schema.Schema{
19+
"role_id": {
20+
Description: "The ID of the organization repository role.",
21+
Type: schema.TypeInt,
22+
Required: true,
23+
},
24+
"name": {
25+
Description: "The name of the organization repository role.",
26+
Type: schema.TypeString,
27+
Computed: true,
28+
},
29+
"description": {
30+
Description: "The description of the organization repository role.",
31+
Type: schema.TypeString,
32+
Computed: true,
33+
},
34+
"base_role": {
35+
Description: "The system role from which this role inherits permissions.",
36+
Type: schema.TypeString,
37+
Computed: true,
38+
},
39+
"permissions": {
40+
Description: "The permissions included in this role.",
41+
Type: schema.TypeSet,
42+
Elem: &schema.Schema{Type: schema.TypeString},
43+
Computed: true,
44+
},
45+
},
46+
}
47+
}
48+
49+
func dataSourceGithubOrganizationRepositoryRoleRead(d *schema.ResourceData, meta interface{}) error {
50+
client := meta.(*Owner).v3client
51+
ctx := context.Background()
52+
orgName := meta.(*Owner).name
53+
54+
roleId := int64(d.Get("role_id").(int))
55+
56+
// TODO: Use this code when go-github adds the functionality to get a custom repo role
57+
// role, _, err := client.Organizations.GetCustomRepoRole(ctx, orgName, roleId)
58+
// if err != nil {
59+
// return err
60+
// }
61+
62+
roles, _, err := client.Organizations.ListCustomRepoRoles(ctx, orgName)
63+
if err != nil {
64+
return err
65+
}
66+
67+
var role *github.CustomRepoRoles
68+
for _, r := range roles.CustomRepoRoles {
69+
if r.GetID() == roleId {
70+
role = r
71+
break
72+
}
73+
}
74+
if role == nil {
75+
return fmt.Errorf("custom organization repo role with ID %d not found", roleId)
76+
}
77+
78+
r := map[string]any{
79+
"role_id": role.GetID(),
80+
"name": role.GetName(),
81+
"description": role.GetDescription(),
82+
"base_role": role.GetBaseRole(),
83+
"permissions": role.Permissions,
84+
}
85+
86+
d.SetId(strconv.FormatInt(role.GetID(), 10))
87+
88+
for k, v := range r {
89+
if err := d.Set(k, v); err != nil {
90+
return err
91+
}
92+
}
93+
94+
return nil
95+
}
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+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
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+
Description: "Lookup all custom repository roles in an organization.",
13+
14+
Read: dataSourceGithubOrganizationRepositoryRolesRead,
15+
16+
Schema: map[string]*schema.Schema{
17+
"roles": {
18+
Description: "Available organization repository roles.",
19+
Type: schema.TypeList,
20+
Computed: true,
21+
Elem: &schema.Resource{
22+
Schema: map[string]*schema.Schema{
23+
"role_id": {
24+
Description: "The ID of the organization repository role.",
25+
Type: schema.TypeInt,
26+
Computed: true,
27+
},
28+
"name": {
29+
Description: "The name of the organization repository role.",
30+
Type: schema.TypeString,
31+
Computed: true,
32+
},
33+
"description": {
34+
Description: "The description of the organization repository role.",
35+
Type: schema.TypeString,
36+
Computed: true,
37+
},
38+
"base_role": {
39+
Description: "The system role from which this role inherits permissions.",
40+
Type: schema.TypeString,
41+
Computed: true,
42+
},
43+
"permissions": {
44+
Description: "The permissions included in this role.",
45+
Type: schema.TypeSet,
46+
Elem: &schema.Schema{Type: schema.TypeString},
47+
Computed: true,
48+
},
49+
},
50+
},
51+
},
52+
},
53+
}
54+
}
55+
56+
func dataSourceGithubOrganizationRepositoryRolesRead(d *schema.ResourceData, meta interface{}) error {
57+
client := meta.(*Owner).v3client
58+
ctx := context.Background()
59+
orgName := meta.(*Owner).name
60+
61+
ret, _, err := client.Organizations.ListCustomRepoRoles(ctx, orgName)
62+
if err != nil {
63+
return err
64+
}
65+
66+
allRoles := make([]any, ret.GetTotalCount())
67+
for i, role := range ret.CustomRepoRoles {
68+
r := map[string]any{
69+
"role_id": role.GetID(),
70+
"name": role.GetName(),
71+
"description": role.GetDescription(),
72+
"base_role": role.GetBaseRole(),
73+
"permissions": role.Permissions,
74+
}
75+
allRoles[i] = r
76+
}
77+
78+
d.SetId(fmt.Sprintf("%s/github-org-repo-roles", orgName))
79+
if err := d.Set("roles", allRoles); err != nil {
80+
return fmt.Errorf("error setting roles: %s", err)
81+
}
82+
83+
return nil
84+
}
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+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
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+
Description: "Lookup a custom organization role.",
13+
14+
Read: dataSourceGithubOrganizationRoleRead,
15+
16+
Schema: map[string]*schema.Schema{
17+
"role_id": {
18+
Description: "The ID of the organization role.",
19+
Type: schema.TypeInt,
20+
Required: true,
21+
},
22+
"name": {
23+
Description: "The name of the organization role.",
24+
Type: schema.TypeString,
25+
Computed: true,
26+
},
27+
"description": {
28+
Description: "The description of the organization role.",
29+
Type: schema.TypeString,
30+
Computed: true,
31+
},
32+
"source": {
33+
Description: "The source of this role; one of `Predefined`, `Organization`, or `Enterprise`.",
34+
Type: schema.TypeString,
35+
Computed: true,
36+
},
37+
"base_role": {
38+
Description: "The system role from which this role inherits permissions.",
39+
Type: schema.TypeString,
40+
Computed: true,
41+
},
42+
"permissions": {
43+
Description: "A list of permissions included in this role.",
44+
Type: schema.TypeSet,
45+
Elem: &schema.Schema{Type: schema.TypeString},
46+
Computed: true,
47+
},
48+
},
49+
}
50+
}
51+
52+
func dataSourceGithubOrganizationRoleRead(d *schema.ResourceData, meta interface{}) error {
53+
client := meta.(*Owner).v3client
54+
ctx := context.Background()
55+
orgName := meta.(*Owner).name
56+
57+
roleId := int64(d.Get("role_id").(int))
58+
59+
role, _, err := client.Organizations.GetOrgRole(ctx, orgName, roleId)
60+
if err != nil {
61+
return err
62+
}
63+
64+
r := map[string]any{
65+
"role_id": role.GetID(),
66+
"name": role.GetName(),
67+
"description": role.GetDescription(),
68+
"source": role.GetSource(),
69+
"base_role": role.GetBaseRole(),
70+
"permissions": role.Permissions,
71+
}
72+
73+
d.SetId(strconv.FormatInt(role.GetID(), 10))
74+
75+
for k, v := range r {
76+
if err := d.Set(k, v); err != nil {
77+
return err
78+
}
79+
}
80+
81+
return nil
82+
}

0 commit comments

Comments
 (0)