Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Added organization role support #2487

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .markdownlint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
MD013: false
MD024:
siblings_only: true
MD028: false
3 changes: 2 additions & 1 deletion github/data_source_github_organization_custom_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ import (

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

Read: dataSourceGithubOrganizationCustomRoleRead,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Expand Down
95 changes: 95 additions & 0 deletions github/data_source_github_organization_repository_role.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package github

import (
"context"
"fmt"
"strconv"

"github.com/google/go-github/v66/github"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func dataSourceGithubOrganizationRepositoryRole() *schema.Resource {
return &schema.Resource{
Description: "Lookup a custom organization repository role.",

Read: dataSourceGithubOrganizationRepositoryRoleRead,

Schema: map[string]*schema.Schema{
"role_id": {
Description: "The ID of the organization repository role.",
Type: schema.TypeInt,
Required: true,
},
"name": {
Description: "The name of the organization repository role.",
Type: schema.TypeString,
Computed: true,
},
"description": {
Description: "The description of the organization repository role.",
Type: schema.TypeString,
Computed: true,
},
"base_role": {
Description: "The system role from which this role inherits permissions.",
Type: schema.TypeString,
Computed: true,
},
"permissions": {
Description: "The permissions included in this role.",
Type: schema.TypeSet,
Elem: &schema.Schema{Type: schema.TypeString},
Computed: true,
},
},
}
}

func dataSourceGithubOrganizationRepositoryRoleRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Owner).v3client
ctx := context.Background()
orgName := meta.(*Owner).name

roleId := int64(d.Get("role_id").(int))

// TODO: Use this code when go-github adds the functionality to get a custom repo role
// role, _, err := client.Organizations.GetCustomRepoRole(ctx, orgName, roleId)
// if err != nil {
// return err
// }

roles, _, err := client.Organizations.ListCustomRepoRoles(ctx, orgName)
if err != nil {
return err
}

var role *github.CustomRepoRoles
for _, r := range roles.CustomRepoRoles {
if r.GetID() == roleId {
role = r
break
}
}
if role == nil {
return fmt.Errorf("custom organization repo role with ID %d not found", roleId)
}

r := map[string]any{
"role_id": role.GetID(),
"name": role.GetName(),
"description": role.GetDescription(),
"base_role": role.GetBaseRole(),
"permissions": role.Permissions,
}

d.SetId(strconv.FormatInt(role.GetID(), 10))

for k, v := range r {
if err := d.Set(k, v); err != nil {
return err
}
}

return nil
}
50 changes: 50 additions & 0 deletions github/data_source_github_organization_repository_role_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package github

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func TestAccGithubOrganizationRepositoryRoleDataSource(t *testing.T) {
t.Run("queries an organization repository role", func(t *testing.T) {
randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum)
roleName := fmt.Sprintf(`tf-acc-test-%s`, randomID)

config := fmt.Sprintf(`
resource "github_organization_repository_role" "test" {
name = "%s"
description = "Test role description"
base_role = "read"
permissions = [
"reopen_issue",
"reopen_pull_request",
]
}

data "github_organization_repository_role" "test" {
role_id = github_organization_repository_role.test.role_id

depends_on = [ github_organization_repository_role.test ]
}
`, roleName)

resource.Test(t, resource.TestCase{
PreCheck: func() { skipUnlessMode(t, enterprise) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrPair("data.github_organization_repository_role.test", "name", "github_organization_repository_role.test", "name"),
resource.TestCheckResourceAttrPair("data.github_organization_repository_role.test", "description", "github_organization_repository_role.test", "description"),
resource.TestCheckResourceAttrPair("data.github_organization_repository_role.test", "base_role", "github_organization_repository_role.test", "base_role"),
resource.TestCheckResourceAttrPair("data.github_organization_repository_role.test", "permissions.#", "github_organization_repository_role.test", "permissions.#"),
),
},
},
})
})
}
84 changes: 84 additions & 0 deletions github/data_source_github_organization_repository_roles.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package github

import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func dataSourceGithubOrganizationRepositoryRoles() *schema.Resource {
return &schema.Resource{
Description: "Lookup all custom repository roles in an organization.",

Read: dataSourceGithubOrganizationRepositoryRolesRead,

Schema: map[string]*schema.Schema{
"roles": {
Description: "Available organization repository roles.",
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"role_id": {
Description: "The ID of the organization repository role.",
Type: schema.TypeInt,
Computed: true,
},
"name": {
Description: "The name of the organization repository role.",
Type: schema.TypeString,
Computed: true,
},
"description": {
Description: "The description of the organization repository role.",
Type: schema.TypeString,
Computed: true,
},
"base_role": {
Description: "The system role from which this role inherits permissions.",
Type: schema.TypeString,
Computed: true,
},
"permissions": {
Description: "The permissions included in this role.",
Type: schema.TypeSet,
Elem: &schema.Schema{Type: schema.TypeString},
Computed: true,
},
},
},
},
},
}
}

func dataSourceGithubOrganizationRepositoryRolesRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Owner).v3client
ctx := context.Background()
orgName := meta.(*Owner).name

ret, _, err := client.Organizations.ListCustomRepoRoles(ctx, orgName)
if err != nil {
return err
}

allRoles := make([]any, ret.GetTotalCount())
for i, role := range ret.CustomRepoRoles {
r := map[string]any{
"role_id": role.GetID(),
"name": role.GetName(),
"description": role.GetDescription(),
"base_role": role.GetBaseRole(),
"permissions": role.Permissions,
}
allRoles[i] = r
}

d.SetId(fmt.Sprintf("%s/github-org-repo-roles", orgName))
if err := d.Set("roles", allRoles); err != nil {
return fmt.Errorf("error setting roles: %s", err)
}

return nil
}
65 changes: 65 additions & 0 deletions github/data_source_github_organization_repository_roles_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package github

import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func TestAccDataSourceGithubOrganizationRepositoryRoles(t *testing.T) {
t.Run("get empty organization roles without error", func(t *testing.T) {
config := `
data "github_organization_repository_roles" "test" {}
`

resource.Test(t, resource.TestCase{
PreCheck: func() { skipUnlessMode(t, organization) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("data.github_organization_repository_roles.test", "roles.#"),
resource.TestCheckResourceAttr("data.github_organization_repository_roles.test", "roles.#", "0"),
),
},
},
})
})

t.Run("get organization roles without error", func(t *testing.T) {
config := `
resource "github_organization_repository_role" "test" {
name = "%s"
description = "Test role description"
base_role = "read"
permissions = [
"reopen_issue",
"reopen_pull_request",
]
}

data "github_organization_repository_roles" "test" {
depends_on = [ github_organization_repository_role.test ]
}
`

resource.Test(t, resource.TestCase{
PreCheck: func() { skipUnlessMode(t, enterprise) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("data.github_organization_repository_roles.test", "roles.#"),
resource.TestCheckResourceAttr("data.github_organization_repository_roles.test", "roles.#", "1"),
resource.TestCheckResourceAttrPair("data.github_organization_repository_roles.test", "roles.0.name", "github_organization_repository_role.test", "name"),
resource.TestCheckResourceAttrPair("data.github_organization_repository_roles.test", "roles.0.description", "github_organization_repository_role.test", "description"),
resource.TestCheckResourceAttrPair("data.github_organization_repository_roles.test", "roles.0.base_role", "github_organization_repository_role.test", "base_role"),
resource.TestCheckResourceAttrPair("data.github_organization_repository_roles.test", "roles.0.permissions.#", "github_organization_repository_role.test", "permissions.#"),
),
},
},
})
})
}
82 changes: 82 additions & 0 deletions github/data_source_github_organization_role.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package github

import (
"context"
"strconv"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func dataSourceGithubOrganizationRole() *schema.Resource {
return &schema.Resource{
Description: "Lookup a custom organization role.",

Read: dataSourceGithubOrganizationRoleRead,

Schema: map[string]*schema.Schema{
"role_id": {
Description: "The ID of the organization role.",
Type: schema.TypeInt,
Required: true,
},
"name": {
Description: "The name of the organization role.",
Type: schema.TypeString,
Computed: true,
},
"description": {
Description: "The description of the organization role.",
Type: schema.TypeString,
Computed: true,
},
"source": {
Description: "The source of this role; one of `Predefined`, `Organization`, or `Enterprise`.",
Type: schema.TypeString,
Computed: true,
},
"base_role": {
Description: "The system role from which this role inherits permissions.",
Type: schema.TypeString,
Computed: true,
},
"permissions": {
Description: "A list of permissions included in this role.",
Type: schema.TypeSet,
Elem: &schema.Schema{Type: schema.TypeString},
Computed: true,
},
},
}
}

func dataSourceGithubOrganizationRoleRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Owner).v3client
ctx := context.Background()
orgName := meta.(*Owner).name

roleId := int64(d.Get("role_id").(int))

role, _, err := client.Organizations.GetOrgRole(ctx, orgName, roleId)
if err != nil {
return err
}

r := map[string]any{
"role_id": role.GetID(),
"name": role.GetName(),
"description": role.GetDescription(),
"source": role.GetSource(),
"base_role": role.GetBaseRole(),
"permissions": role.Permissions,
}

d.SetId(strconv.FormatInt(role.GetID(), 10))

for k, v := range r {
if err := d.Set(k, v); err != nil {
return err
}
}

return nil
}
Loading
Loading