Skip to content

Commit

Permalink
feat: Added organization role support
Browse files Browse the repository at this point in the history
Signed-off-by: Steve Hipwell <[email protected]>
  • Loading branch information
stevehipwell committed Nov 29, 2024
1 parent 1c11053 commit 11cc1a6
Show file tree
Hide file tree
Showing 16 changed files with 945 additions and 2 deletions.
80 changes: 80 additions & 0 deletions github/data_source_github_organization_role.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package github

import (
"context"
"strconv"

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

func dataSourceGithubOrganizationRole() *schema.Resource {
return &schema.Resource{
Read: dataSourceGithubOrganizationRoleRead,

Schema: map[string]*schema.Schema{
"role_id": {
Description: "The ID of the role.",
Type: schema.TypeInt,
Required: true,
},
"name": {
Description: "The name of the role.",
Type: schema.TypeString,
Computed: true,
},
"description": {
Description: "A short description about who this role is for or what permissions it grants.",
Type: schema.TypeString,
Computed: true,
},
"source": {
Description: "Source answers the question, \"where did this role come from?\"",
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
}
90 changes: 90 additions & 0 deletions github/data_source_github_organization_role_teams.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package github

import (
"context"
"fmt"

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

func dataSourceGithubOrganizationRoleTeams() *schema.Resource {
return &schema.Resource{
Read: dataSourceGithubOrganizationRoleTeamsRead,

Schema: map[string]*schema.Schema{
"teams": {
Description: "List of teams assigned to the organization role.",
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Description: "Unique identifier of the team.",
Type: schema.TypeInt,
Computed: true,
},
"slug": {
Description: "Slug of the team name.",
Type: schema.TypeString,
Computed: true,
},
"name": {
Description: "Name of the team.",
Type: schema.TypeString,
Computed: true,
},
"permission": {
Description: "Permission that the team will have for its repositories.",
Type: schema.TypeString,
Computed: true,
},
},
},
},
},
}
}

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

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

allTeams := make([]any, 0)

opts := &github.ListOptions{
PerPage: maxPerPage,
}

for {
teams, resp, err := client.Organizations.ListTeamsAssignedToOrgRole(ctx, orgName, roleId, opts)
if err != nil {
return err
}

for _, team := range teams {
t := map[string]any{
"id": team.GetID(),
"slug": team.GetSlug(),
"name": team.GetName(),
"permission": team.GetPermission(),
}
allTeams = append(allTeams, t)
}

if resp.NextPage == 0 {
break
}
opts.Page = resp.NextPage
}

d.SetId(fmt.Sprintf("%d", roleId))
if err := d.Set("teams", allTeams); err != nil {
return fmt.Errorf("error setting teams: %s", err)
}

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

import (
"testing"

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

func TestAccDataSourceGithubOrganizationRole(t *testing.T) {
t.Run("get the organization role without error", func(t *testing.T) {
config := `
data "github_organization_role" "test" {
role_id = 138
}
`

resource.Test(t, resource.TestCase{
PreCheck: func() { skipUnlessMode(t, organization) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("data.github_organization_role.test", "role_id", "138"),
resource.TestCheckResourceAttr("data.github_organization_role.test", "name", "security_manager"),
resource.TestCheckResourceAttr("data.github_organization_role.test", "source", "Predefined"),
resource.TestCheckResourceAttr("data.github_organization_role.test", "base_role", "read"),
resource.TestCheckResourceAttrSet("data.github_organization_role.test", "description"),
resource.TestCheckResourceAttrSet("data.github_organization_role.test", "permissions.#"),
),
},
},
})
})
}
84 changes: 84 additions & 0 deletions github/data_source_github_organization_role_users.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package github

import (
"context"
"fmt"

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

func dataSourceGithubOrganizationRoleUsers() *schema.Resource {
return &schema.Resource{
Read: dataSourceGithubOrganizationRoleUsersRead,

Schema: map[string]*schema.Schema{
"users": {
Description: "List of users assigned to the organization role.",
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Description: "Unique identifier of the user.",
Type: schema.TypeInt,
Computed: true,
},
"login": {
Description: "Login for the user.",
Type: schema.TypeString,
Computed: true,
},
"type": {
Description: "Determines if the user has a direct, indirect, or mixed relationship to a role.",
Type: schema.TypeString,
Computed: true,
},
},
},
},
},
}
}

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

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

allUsers := make([]any, 0)

opts := &github.ListOptions{
PerPage: maxPerPage,
}

for {
users, resp, err := client.Organizations.ListUsersAssignedToOrgRole(ctx, orgName, roleId, opts)
if err != nil {
return err
}

for _, user := range users {
u := map[string]any{
"id": user.GetID(),
"login": user.GetLogin(),
"type": user.GetType(),
}
allUsers = append(allUsers, u)
}

if resp.NextPage == 0 {
break
}
opts.Page = resp.NextPage
}

d.SetId(fmt.Sprintf("%d", roleId))
if err := d.Set("users", allUsers); err != nil {
return fmt.Errorf("error setting users: %s", err)
}

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

import (
"context"
"fmt"

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

func dataSourceGithubOrganizationRoles() *schema.Resource {
return &schema.Resource{
Read: dataSourceGithubOrganizationRolesRead,

Schema: map[string]*schema.Schema{
"roles": {
Description: "The list of organization roles available to the organization.",
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Description: "The unique identifier of the role.",
Type: schema.TypeInt,
Computed: true,
},
"name": {
Description: "The name of the role.",
Type: schema.TypeString,
Computed: true,
},
"description": {
Description: "A short description about who this role is for or what permissions it grants.",
Type: schema.TypeString,
Computed: true,
},
"source": {
Description: "Source answers the question, \"where did this role come from?\"",
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 dataSourceGithubOrganizationRolesRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Owner).v3client
ctx := context.Background()
orgName := meta.(*Owner).name

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

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

Check failure on line 79 in github/data_source_github_organization_roles.go

View workflow job for this annotation

GitHub Actions / ci

append to slice `allRoles` with non-zero initialized length (makezero)
}

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

return nil
}
Loading

0 comments on commit 11cc1a6

Please sign in to comment.