diff --git a/github/data_source_github_organization_repository_role.go b/github/data_source_github_organization_repository_role.go index 26aabb6d78..15c1afdf64 100644 --- a/github/data_source_github_organization_repository_role.go +++ b/github/data_source_github_organization_repository_role.go @@ -6,6 +6,7 @@ import ( "strconv" "github.com/google/go-github/v67/github" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -13,7 +14,7 @@ func dataSourceGithubOrganizationRepositoryRole() *schema.Resource { return &schema.Resource{ Description: "Lookup a custom organization repository role.", - Read: dataSourceGithubOrganizationRepositoryRoleRead, + ReadContext: dataSourceGithubOrganizationRepositoryRoleRead, Schema: map[string]*schema.Schema{ "role_id": { @@ -46,22 +47,21 @@ func dataSourceGithubOrganizationRepositoryRole() *schema.Resource { } } -func dataSourceGithubOrganizationRepositoryRoleRead(d *schema.ResourceData, meta any) error { +func dataSourceGithubOrganizationRepositoryRoleRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { 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 + // TODO: Use this code when go-github is at v68+ // role, _, err := client.Organizations.GetCustomRepoRole(ctx, orgName, roleId) // if err != nil { - // return err + // return diag.FromErr(err) // } roles, _, err := client.Organizations.ListCustomRepoRoles(ctx, orgName) if err != nil { - return err + return diag.FromErr(err) } var role *github.CustomRepoRoles @@ -72,7 +72,7 @@ func dataSourceGithubOrganizationRepositoryRoleRead(d *schema.ResourceData, meta } } if role == nil { - return fmt.Errorf("custom organization repo role with ID %d not found", roleId) + return diag.FromErr(fmt.Errorf("custom organization repo role with ID %d not found", roleId)) } r := map[string]any{ @@ -87,7 +87,7 @@ func dataSourceGithubOrganizationRepositoryRoleRead(d *schema.ResourceData, meta for k, v := range r { if err := d.Set(k, v); err != nil { - return err + return diag.FromErr(err) } } diff --git a/github/data_source_github_organization_repository_roles.go b/github/data_source_github_organization_repository_roles.go index e4ab6600fc..238c170398 100644 --- a/github/data_source_github_organization_repository_roles.go +++ b/github/data_source_github_organization_repository_roles.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -11,7 +12,7 @@ func dataSourceGithubOrganizationRepositoryRoles() *schema.Resource { return &schema.Resource{ Description: "Lookup all custom repository roles in an organization.", - Read: dataSourceGithubOrganizationRepositoryRolesRead, + ReadContext: dataSourceGithubOrganizationRepositoryRolesRead, Schema: map[string]*schema.Schema{ "roles": { @@ -53,14 +54,13 @@ func dataSourceGithubOrganizationRepositoryRoles() *schema.Resource { } } -func dataSourceGithubOrganizationRepositoryRolesRead(d *schema.ResourceData, meta any) error { +func dataSourceGithubOrganizationRepositoryRolesRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { client := meta.(*Owner).v3client - ctx := context.Background() orgName := meta.(*Owner).name ret, _, err := client.Organizations.ListCustomRepoRoles(ctx, orgName) if err != nil { - return err + return diag.FromErr(err) } allRoles := make([]any, ret.GetTotalCount()) @@ -77,7 +77,7 @@ func dataSourceGithubOrganizationRepositoryRolesRead(d *schema.ResourceData, met d.SetId(fmt.Sprintf("%s/github-org-repo-roles", orgName)) if err := d.Set("roles", allRoles); err != nil { - return fmt.Errorf("error setting roles: %w", err) + return diag.FromErr(fmt.Errorf("error setting roles: %w", err)) } return nil diff --git a/github/data_source_github_organization_role.go b/github/data_source_github_organization_role.go index 473766e100..02c681227d 100644 --- a/github/data_source_github_organization_role.go +++ b/github/data_source_github_organization_role.go @@ -4,6 +4,7 @@ import ( "context" "strconv" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -11,7 +12,7 @@ func dataSourceGithubOrganizationRole() *schema.Resource { return &schema.Resource{ Description: "Lookup a custom organization role.", - Read: dataSourceGithubOrganizationRoleRead, + ReadContext: dataSourceGithubOrganizationRoleRead, Schema: map[string]*schema.Schema{ "role_id": { @@ -49,16 +50,15 @@ func dataSourceGithubOrganizationRole() *schema.Resource { } } -func dataSourceGithubOrganizationRoleRead(d *schema.ResourceData, meta any) error { +func dataSourceGithubOrganizationRoleRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { 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 + return diag.FromErr(err) } r := map[string]any{ @@ -74,7 +74,7 @@ func dataSourceGithubOrganizationRoleRead(d *schema.ResourceData, meta any) erro for k, v := range r { if err := d.Set(k, v); err != nil { - return err + return diag.FromErr(err) } } diff --git a/github/data_source_github_organization_role_teams.go b/github/data_source_github_organization_role_teams.go index a781f7617a..f6f9c18073 100644 --- a/github/data_source_github_organization_role_teams.go +++ b/github/data_source_github_organization_role_teams.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/google/go-github/v67/github" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -12,7 +13,7 @@ func dataSourceGithubOrganizationRoleTeams() *schema.Resource { return &schema.Resource{ Description: "Lookup all teams assigned to a custom organization role.", - Read: dataSourceGithubOrganizationRoleTeamsRead, + ReadContext: dataSourceGithubOrganizationRoleTeamsRead, Schema: map[string]*schema.Schema{ "role_id": { @@ -47,7 +48,7 @@ func dataSourceGithubOrganizationRoleTeams() *schema.Resource { Type: schema.TypeString, Computed: true, }, - // TODO: Add these fields when go-github adds the functionality to get a custom org + // TODO: Add these fields when go-github is v68+ // See https://github.com/google/go-github/issues/3364 // "assignment": { // Description: "Determines if the team has a direct, indirect, or mixed relationship to a role.", @@ -71,9 +72,8 @@ func dataSourceGithubOrganizationRoleTeams() *schema.Resource { } } -func dataSourceGithubOrganizationRoleTeamsRead(d *schema.ResourceData, meta any) error { +func dataSourceGithubOrganizationRoleTeamsRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { client := meta.(*Owner).v3client - ctx := context.Background() orgName := meta.(*Owner).name roleId := int64(d.Get("role_id").(int)) @@ -87,7 +87,7 @@ func dataSourceGithubOrganizationRoleTeamsRead(d *schema.ResourceData, meta any) for { teams, resp, err := client.Organizations.ListTeamsAssignedToOrgRole(ctx, orgName, roleId, opts) if err != nil { - return err + return diag.FromErr(err) } for _, team := range teams { @@ -108,7 +108,7 @@ func dataSourceGithubOrganizationRoleTeamsRead(d *schema.ResourceData, meta any) d.SetId(fmt.Sprintf("%d", roleId)) if err := d.Set("teams", allTeams); err != nil { - return fmt.Errorf("error setting teams: %w", err) + return diag.FromErr(fmt.Errorf("error setting teams: %w", err)) } return nil diff --git a/github/data_source_github_organization_role_users.go b/github/data_source_github_organization_role_users.go index 543e02467f..2e2af025e9 100644 --- a/github/data_source_github_organization_role_users.go +++ b/github/data_source_github_organization_role_users.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/google/go-github/v67/github" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -12,7 +13,7 @@ func dataSourceGithubOrganizationRoleUsers() *schema.Resource { return &schema.Resource{ Description: "Lookup all users assigned to a custom organization role.", - Read: dataSourceGithubOrganizationRoleUsersRead, + ReadContext: dataSourceGithubOrganizationRoleUsersRead, Schema: map[string]*schema.Schema{ "role_id": { @@ -37,6 +38,7 @@ func dataSourceGithubOrganizationRoleUsers() *schema.Resource { Type: schema.TypeString, Computed: true, }, + // TODO: Add these fields when go-github is v68+ // See https://github.com/google/go-github/issues/3364 // "assignment": { // Description: "Determines if the team has a direct, indirect, or mixed relationship to a role.", @@ -60,9 +62,8 @@ func dataSourceGithubOrganizationRoleUsers() *schema.Resource { } } -func dataSourceGithubOrganizationRoleUsersRead(d *schema.ResourceData, meta any) error { +func dataSourceGithubOrganizationRoleUsersRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { client := meta.(*Owner).v3client - ctx := context.Background() orgName := meta.(*Owner).name roleId := int64(d.Get("role_id").(int)) @@ -76,7 +77,7 @@ func dataSourceGithubOrganizationRoleUsersRead(d *schema.ResourceData, meta any) for { users, resp, err := client.Organizations.ListUsersAssignedToOrgRole(ctx, orgName, roleId, opts) if err != nil { - return err + return diag.FromErr(err) } for _, user := range users { @@ -95,7 +96,7 @@ func dataSourceGithubOrganizationRoleUsersRead(d *schema.ResourceData, meta any) d.SetId(fmt.Sprintf("%d", roleId)) if err := d.Set("users", allUsers); err != nil { - return fmt.Errorf("error setting users: %w", err) + return diag.FromErr(fmt.Errorf("error setting users: %w", err)) } return nil diff --git a/github/data_source_github_organization_roles.go b/github/data_source_github_organization_roles.go index da23d2f666..2906b9ec86 100644 --- a/github/data_source_github_organization_roles.go +++ b/github/data_source_github_organization_roles.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -11,7 +12,7 @@ func dataSourceGithubOrganizationRoles() *schema.Resource { return &schema.Resource{ Description: "Lookup all custom roles in an organization.", - Read: dataSourceGithubOrganizationRolesRead, + ReadContext: dataSourceGithubOrganizationRolesRead, Schema: map[string]*schema.Schema{ "roles": { @@ -58,14 +59,13 @@ func dataSourceGithubOrganizationRoles() *schema.Resource { } } -func dataSourceGithubOrganizationRolesRead(d *schema.ResourceData, meta any) error { +func dataSourceGithubOrganizationRolesRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { client := meta.(*Owner).v3client - ctx := context.Background() orgName := meta.(*Owner).name ret, _, err := client.Organizations.ListRoles(ctx, orgName) if err != nil { - return err + return diag.FromErr(err) } allRoles := make([]any, ret.GetTotalCount()) @@ -83,7 +83,7 @@ func dataSourceGithubOrganizationRolesRead(d *schema.ResourceData, meta any) err d.SetId(fmt.Sprintf("%s/github-org-roles", orgName)) if err := d.Set("roles", allRoles); err != nil { - return fmt.Errorf("error setting roles: %w", err) + return diag.FromErr(fmt.Errorf("error setting roles: %w", err)) } return nil diff --git a/github/resource_github_organization_repository_role.go b/github/resource_github_organization_repository_role.go index 94922d0495..491be29605 100644 --- a/github/resource_github_organization_repository_role.go +++ b/github/resource_github_organization_repository_role.go @@ -7,16 +7,18 @@ import ( "strconv" "github.com/google/go-github/v67/github" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) func resourceGithubOrganizationRepositoryRole() *schema.Resource { return &schema.Resource{ Description: "Manage a custom organization repository role.", - Create: resourceGithubOrganizationRepositoryRoleCreate, - Read: resourceGithubOrganizationRepositoryRoleRead, - Update: resourceGithubOrganizationRepositoryRoleUpdate, - Delete: resourceGithubOrganizationRepositoryRoleDelete, + + CreateContext: resourceGithubOrganizationRepositoryRoleCreate, + ReadContext: resourceGithubOrganizationRepositoryRoleRead, + UpdateContext: resourceGithubOrganizationRepositoryRoleUpdate, + DeleteContext: resourceGithubOrganizationRepositoryRoleDelete, Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, @@ -54,15 +56,14 @@ func resourceGithubOrganizationRepositoryRole() *schema.Resource { } } -func resourceGithubOrganizationRepositoryRoleCreate(d *schema.ResourceData, meta any) error { +func resourceGithubOrganizationRepositoryRoleCreate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { err := checkOrganization(meta) if err != nil { - return err + return diag.FromErr(err) } client := meta.(*Owner).v3client orgName := meta.(*Owner).name - ctx := context.Background() permissions := d.Get("permissions").(*schema.Set).List() permissionsStr := make([]string, len(permissions)) @@ -77,29 +78,28 @@ func resourceGithubOrganizationRepositoryRoleCreate(d *schema.ResourceData, meta Permissions: permissionsStr, }) if err != nil { - return fmt.Errorf("error creating GitHub organization repository role (%s/%s): %w", orgName, d.Get("name").(string), err) + return diag.FromErr(fmt.Errorf("error creating GitHub organization repository role (%s/%s): %w", orgName, d.Get("name").(string), err)) } d.SetId(fmt.Sprint(role.GetID())) - return resourceGithubOrganizationRoleRead(d, meta) + return nil } -func resourceGithubOrganizationRepositoryRoleRead(d *schema.ResourceData, meta any) error { +func resourceGithubOrganizationRepositoryRoleRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { err := checkOrganization(meta) if err != nil { - return err + return diag.FromErr(err) } client := meta.(*Owner).v3client - ctx := context.Background() orgName := meta.(*Owner).name roleId, err := strconv.ParseInt(d.Id(), 10, 64) if err != nil { - return err + return diag.FromErr(err) } - // TODO: Use this code when go-github adds the functionality to get a custom repo role + // TODO: Use this code when go-github is v68+ // role, _, err := client.Organizations.GetCustomRepoRole(ctx, orgName, roleId) // if err != nil { // if ghErr, ok := err.(*github.ErrorResponse); ok { @@ -114,7 +114,7 @@ func resourceGithubOrganizationRepositoryRoleRead(d *schema.ResourceData, meta a roles, _, err := client.Organizations.ListCustomRepoRoles(ctx, orgName) if err != nil { - return err + return diag.FromErr(err) } var role *github.CustomRepoRoles @@ -132,37 +132,36 @@ func resourceGithubOrganizationRepositoryRoleRead(d *schema.ResourceData, meta a } if err = d.Set("role_id", role.GetID()); err != nil { - return err + return diag.FromErr(err) } if err = d.Set("name", role.Name); err != nil { - return err + return diag.FromErr(err) } if err = d.Set("description", role.Description); err != nil { - return err + return diag.FromErr(err) } if err = d.Set("base_role", role.BaseRole); err != nil { - return err + return diag.FromErr(err) } if err = d.Set("permissions", role.Permissions); err != nil { - return err + return diag.FromErr(err) } return nil } -func resourceGithubOrganizationRepositoryRoleUpdate(d *schema.ResourceData, meta any) error { +func resourceGithubOrganizationRepositoryRoleUpdate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { err := checkOrganization(meta) if err != nil { - return err + return diag.FromErr(err) } client := meta.(*Owner).v3client - ctx := context.Background() orgName := meta.(*Owner).name roleId, err := strconv.ParseInt(d.Id(), 10, 64) if err != nil { - return err + return diag.FromErr(err) } permissions := d.Get("permissions").(*schema.Set).List() @@ -180,30 +179,29 @@ func resourceGithubOrganizationRepositoryRoleUpdate(d *schema.ResourceData, meta _, _, err = client.Organizations.UpdateCustomRepoRole(ctx, orgName, roleId, update) if err != nil { - return fmt.Errorf("error updating GitHub organization repository role (%s/%s): %w", orgName, d.Get("name").(string), err) + return diag.FromErr(fmt.Errorf("error updating GitHub organization repository role (%s/%s): %w", orgName, d.Get("name").(string), err)) } - return resourceGithubOrganizationRoleRead(d, meta) + return nil } -func resourceGithubOrganizationRepositoryRoleDelete(d *schema.ResourceData, meta any) error { +func resourceGithubOrganizationRepositoryRoleDelete(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { err := checkOrganization(meta) if err != nil { - return err + return diag.FromErr(err) } client := meta.(*Owner).v3client - ctx := context.Background() orgName := meta.(*Owner).name roleId, err := strconv.ParseInt(d.Id(), 10, 64) if err != nil { - return err + return diag.FromErr(err) } _, err = client.Organizations.DeleteCustomRepoRole(ctx, orgName, roleId) if err != nil { - return fmt.Errorf("Error deleting GitHub organization repository role %s (%d): %w", orgName, roleId, err) + return diag.FromErr(fmt.Errorf("Error deleting organization repository role %d: %w", roleId, err)) } return nil diff --git a/github/resource_github_organization_role.go b/github/resource_github_organization_role.go index 104b49253f..d6da7fa746 100644 --- a/github/resource_github_organization_role.go +++ b/github/resource_github_organization_role.go @@ -9,6 +9,7 @@ import ( "strconv" "github.com/google/go-github/v67/github" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -16,10 +17,10 @@ func resourceGithubOrganizationRole() *schema.Resource { return &schema.Resource{ Description: "Manage a custom organization role.", - Create: resourceGithubOrganizationRoleCreate, - Read: resourceGithubOrganizationRoleRead, - Update: resourceGithubOrganizationRoleUpdate, - Delete: resourceGithubOrganizationRoleDelete, + CreateContext: resourceGithubOrganizationRoleCreate, + ReadContext: resourceGithubOrganizationRoleRead, + UpdateContext: resourceGithubOrganizationRoleUpdate, + DeleteContext: resourceGithubOrganizationRoleDelete, Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, @@ -41,32 +42,30 @@ func resourceGithubOrganizationRole() *schema.Resource { Optional: true, }, "base_role": { - Description: "The base role for the organization role.", + Description: "The system role from which this role inherits permissions.", Type: schema.TypeString, Optional: true, - Computed: true, - ValidateDiagFunc: validateValueFunc([]string{"read", "triage", "write", "maintain", "admin"}), + Default: "none", + ValidateDiagFunc: validateValueFunc([]string{"none", "read", "triage", "write", "maintain", "admin"}), }, "permissions": { Description: "The permissions for the organization role.", Type: schema.TypeSet, Required: true, Elem: &schema.Schema{Type: schema.TypeString}, - MinItems: 1, }, }, } } -func resourceGithubOrganizationRoleCreate(d *schema.ResourceData, meta any) error { +func resourceGithubOrganizationRoleCreate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { err := checkOrganization(meta) if err != nil { - return err + return diag.FromErr(err) } client := meta.(*Owner).v3client orgName := meta.(*Owner).name - ctx := context.Background() permissions := d.Get("permissions").(*schema.Set).List() permissionsStr := make([]string, len(permissions)) @@ -81,26 +80,25 @@ func resourceGithubOrganizationRoleCreate(d *schema.ResourceData, meta any) erro Permissions: permissionsStr, }) if err != nil { - return fmt.Errorf("error creating GitHub custom organization role (%s/%s): %w", orgName, d.Get("name").(string), err) + return diag.FromErr(fmt.Errorf("error creating organization role (%s/%s): %w", orgName, d.Get("name").(string), err)) } d.SetId(fmt.Sprint(role.GetID())) - return resourceGithubOrganizationRoleRead(d, meta) + return nil } -func resourceGithubOrganizationRoleRead(d *schema.ResourceData, meta any) error { +func resourceGithubOrganizationRoleRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { err := checkOrganization(meta) if err != nil { - return err + return diag.FromErr(err) } client := meta.(*Owner).v3client - ctx := context.Background() orgName := meta.(*Owner).name roleId, err := strconv.ParseInt(d.Id(), 10, 64) if err != nil { - return err + return diag.FromErr(err) } role, _, err := client.Organizations.GetOrgRole(ctx, orgName, roleId) @@ -108,46 +106,45 @@ func resourceGithubOrganizationRoleRead(d *schema.ResourceData, meta any) error ghErr := &github.ErrorResponse{} if errors.As(err, &ghErr) { if ghErr.Response.StatusCode == http.StatusNotFound { - log.Printf("[WARN] GitHub custom organization role (%s/%d) not found, removing from state", orgName, roleId) + log.Printf("[WARN] organization role (%s/%d) not found, removing from state", orgName, roleId) d.SetId("") return nil } } - return err + return diag.FromErr(err) } if err = d.Set("role_id", role.GetID()); err != nil { - return err + return diag.FromErr(err) } if err = d.Set("name", role.Name); err != nil { - return err + return diag.FromErr(err) } if err = d.Set("description", role.Description); err != nil { - return err + return diag.FromErr(err) } if err = d.Set("base_role", role.BaseRole); err != nil { - return err + return diag.FromErr(err) } if err = d.Set("permissions", role.Permissions); err != nil { - return err + return diag.FromErr(err) } return nil } -func resourceGithubOrganizationRoleUpdate(d *schema.ResourceData, meta any) error { +func resourceGithubOrganizationRoleUpdate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { err := checkOrganization(meta) if err != nil { - return err + return diag.FromErr(err) } client := meta.(*Owner).v3client - ctx := context.Background() orgName := meta.(*Owner).name roleId, err := strconv.ParseInt(d.Id(), 10, 64) if err != nil { - return err + return diag.FromErr(err) } permissions := d.Get("permissions").(*schema.Set).List() @@ -165,30 +162,29 @@ func resourceGithubOrganizationRoleUpdate(d *schema.ResourceData, meta any) erro _, _, err = client.Organizations.UpdateCustomOrgRole(ctx, orgName, roleId, update) if err != nil { - return fmt.Errorf("error updating GitHub custom organization role (%s/%s): %w", orgName, d.Get("name").(string), err) + return diag.FromErr(fmt.Errorf("error updating organization role (%s/%s): %w", orgName, d.Get("name").(string), err)) } - return resourceGithubOrganizationRoleRead(d, meta) + return nil } -func resourceGithubOrganizationRoleDelete(d *schema.ResourceData, meta any) error { +func resourceGithubOrganizationRoleDelete(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { err := checkOrganization(meta) if err != nil { - return err + return diag.FromErr(err) } client := meta.(*Owner).v3client - ctx := context.Background() orgName := meta.(*Owner).name roleId, err := strconv.ParseInt(d.Id(), 10, 64) if err != nil { - return err + return diag.FromErr(err) } _, err = client.Organizations.DeleteCustomOrgRole(ctx, orgName, roleId) if err != nil { - return fmt.Errorf("Error deleting GitHub custom organization role %s (%d): %w", orgName, roleId, err) + return diag.FromErr(fmt.Errorf("Error deleting organization role %d: %w", roleId, err)) } return nil diff --git a/github/resource_github_organization_role_team.go b/github/resource_github_organization_role_team.go index b1ea1601e3..727daa2697 100644 --- a/github/resource_github_organization_role_team.go +++ b/github/resource_github_organization_role_team.go @@ -2,10 +2,12 @@ package github import ( "context" + "fmt" "log" "strconv" "github.com/google/go-github/v67/github" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -13,9 +15,9 @@ func resourceGithubOrganizationRoleTeam() *schema.Resource { return &schema.Resource{ Description: "Manage an association between an organization role and a team.", - Create: resourceGithubOrganizationRoleTeamCreate, - Read: resourceGithubOrganizationRoleTeamRead, - Delete: resourceGithubOrganizationRoleTeamDelete, + CreateContext: resourceGithubOrganizationRoleTeamCreate, + ReadContext: resourceGithubOrganizationRoleTeamRead, + DeleteContext: resourceGithubOrganizationRoleTeamDelete, Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, @@ -37,14 +39,13 @@ func resourceGithubOrganizationRoleTeam() *schema.Resource { } } -func resourceGithubOrganizationRoleTeamCreate(d *schema.ResourceData, meta any) error { +func resourceGithubOrganizationRoleTeamCreate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { err := checkOrganization(meta) if err != nil { - return err + return diag.FromErr(err) } client := meta.(*Owner).v3client - ctx := context.Background() orgName := meta.(*Owner).name roleId := int64(d.Get("role_id").(int)) @@ -52,31 +53,30 @@ func resourceGithubOrganizationRoleTeamCreate(d *schema.ResourceData, meta any) _, err = client.Organizations.AssignOrgRoleToTeam(ctx, orgName, teamSlug, roleId) if err != nil { - return err + return diag.FromErr(err) } d.SetId(buildTwoPartID(strconv.FormatInt(roleId, 10), teamSlug)) - return resourceGithubOrganizationRoleTeamRead(d, meta) + return nil } -func resourceGithubOrganizationRoleTeamRead(d *schema.ResourceData, meta any) error { +func resourceGithubOrganizationRoleTeamRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { err := checkOrganization(meta) if err != nil { - return err + return diag.FromErr(err) } client := meta.(*Owner).v3client - ctx := context.Background() orgName := meta.(*Owner).name roleIdString, teamSlug, err := parseTwoPartID(d.Id(), "role_id", "team_slug") if err != nil { - return err + return diag.FromErr(err) } roleId, err := strconv.ParseInt(roleIdString, 10, 64) if err != nil { - return err + return diag.FromErr(err) } opts := &github.ListOptions{ @@ -87,7 +87,7 @@ func resourceGithubOrganizationRoleTeamRead(d *schema.ResourceData, meta any) er for { teams, resp, err := client.Organizations.ListTeamsAssignedToOrgRole(ctx, orgName, roleId, opts) if err != nil { - return err + return diag.FromErr(err) } for _, t := range teams { @@ -110,29 +110,32 @@ func resourceGithubOrganizationRoleTeamRead(d *schema.ResourceData, meta any) er } if err = d.Set("role_id", roleId); err != nil { - return err + return diag.FromErr(err) } if err = d.Set("team_slug", teamSlug); err != nil { - return err + return diag.FromErr(err) } return nil } -func resourceGithubOrganizationRoleTeamDelete(d *schema.ResourceData, meta any) error { +func resourceGithubOrganizationRoleTeamDelete(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { err := checkOrganization(meta) if err != nil { - return err + return diag.FromErr(err) } client := meta.(*Owner).v3client - ctx := context.Background() orgName := meta.(*Owner).name roleId := int64(d.Get("role_id").(int)) teamSlug := d.Get("team_slug").(string) _, err = client.Organizations.RemoveOrgRoleFromTeam(ctx, orgName, teamSlug, roleId) - return err + if err != nil { + return diag.FromErr(fmt.Errorf("Error deleting organization role team %d %s: %w", roleId, teamSlug, err)) + } + + return nil } diff --git a/github/resource_github_organization_role_test.go b/github/resource_github_organization_role_test.go index 55eac10c89..210a3f68b9 100644 --- a/github/resource_github_organization_role_test.go +++ b/github/resource_github_organization_role_test.go @@ -9,24 +9,117 @@ import ( ) func TestAccGithubOrganizationRole(t *testing.T) { - t.Run("can create an organization role without erroring", func(t *testing.T) { + t.Run("can create an empty organization role", func(t *testing.T) { + randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + name := fmt.Sprintf("tf-acc-org-role-%s", randomID) + config := fmt.Sprintf(` + resource "github_organization_role" "test" { + name = "%s" + permissions = [] + } + `, name) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { skipUnlessMode(t, enterprise) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("github_organization_role.test", "id"), + resource.TestCheckResourceAttrSet("github_organization_role.test", "role_id"), + resource.TestCheckResourceAttr("github_organization_role.test", "name", name), + resource.TestCheckResourceAttr("github_organization_role.test", "base_role", "none"), + resource.TestCheckResourceAttrSet("github_organization_role.test", "permissions.#"), + resource.TestCheckResourceAttr("github_organization_role.test", "permissions.#", "0"), + ), + }, + }, + }) + }) + + t.Run("can create an empty organization role with a base role", func(t *testing.T) { + randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + name := fmt.Sprintf("tf-acc-org-role-%s", randomID) + baseRole := "read" + + config := fmt.Sprintf(` + resource "github_organization_role" "test" { + name = "%s" + base_role = "%s" + permissions = [] + } + `, name, baseRole) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { skipUnlessMode(t, enterprise) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("github_organization_role.test", "id"), + resource.TestCheckResourceAttr("github_organization_role.test", "name", name), + resource.TestCheckResourceAttr("github_organization_role.test", "base_role", baseRole), + resource.TestCheckResourceAttrSet("github_organization_role.test", "permissions.#"), + resource.TestCheckResourceAttr("github_organization_role.test", "permissions.#", "0"), + ), + }, + }, + }) + }) + + t.Run("can create an organization role", func(t *testing.T) { + randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + name := fmt.Sprintf("tf-acc-org-role-%s", randomID) + baseRole := "none" + permission0 := "read_organization_actions_usage_metrics" + + config := fmt.Sprintf(` + resource "github_organization_role" "test" { + name = "%s" + base_role = "%s" + permissions = [ + "%s" + ] + } + `, name, baseRole, permission0) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { skipUnlessMode(t, enterprise) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("github_organization_role.test", "id"), + resource.TestCheckResourceAttr("github_organization_role.test", "name", name), + resource.TestCheckResourceAttr("github_organization_role.test", "base_role", baseRole), + resource.TestCheckResourceAttrSet("github_organization_role.test", "permissions.#"), + resource.TestCheckResourceAttr("github_organization_role.test", "permissions.#", "1"), + resource.TestCheckResourceAttr("github_organization_role.test", "permissions.0", permission0), + ), + }, + }, + }) + }) + + t.Run("can create an organization role with repo permissions", func(t *testing.T) { randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) name := fmt.Sprintf("tf-acc-org-role-%s", randomID) description := "This is a test org role." baseRole := "write" - permission0 := "read_organization_actions_usage_metrics" - permission1 := "read_audit_logs" + permission0 := "read_audit_logs" config := fmt.Sprintf(` resource "github_organization_role" "test" { name = "%s" description = "%s" base_role = "%s" permissions = [ - "%s", - %s + "%s" ] } - `, name, description, baseRole, permission0, permission1) + `, name, description, baseRole, permission0) resource.Test(t, resource.TestCase{ PreCheck: func() { skipUnlessMode(t, enterprise) }, @@ -41,28 +134,32 @@ func TestAccGithubOrganizationRole(t *testing.T) { resource.TestCheckResourceAttr("github_organization_role.test", "description", description), resource.TestCheckResourceAttr("github_organization_role.test", "base_role", baseRole), resource.TestCheckResourceAttrSet("github_organization_role.test", "permissions.#"), - resource.TestCheckResourceAttr("github_organization_role.test", "permissions.#", "2"), + resource.TestCheckResourceAttr("github_organization_role.test", "permissions.#", "1"), resource.TestCheckResourceAttr("github_organization_role.test", "permissions.0", permission0), - resource.TestCheckResourceAttr("github_organization_role.test", "permissions.1", permission1), ), }, }, }) }) - t.Run("can create an minimal organization role without erroring", func(t *testing.T) { + t.Run("can create an organization role with org and repo permissions", func(t *testing.T) { randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) name := fmt.Sprintf("tf-acc-org-role-%s", randomID) + description := "This is a test org role." + baseRole := "write" permission0 := "read_organization_actions_usage_metrics" - + permission1 := "read_audit_logs" config := fmt.Sprintf(` resource "github_organization_role" "test" { name = "%s" + description = "%s" + base_role = "%s" permissions = [ - "%s" + "%s", + "%s" ] } - `, name, permission0) + `, name, description, baseRole, permission0, permission1) resource.Test(t, resource.TestCase{ PreCheck: func() { skipUnlessMode(t, enterprise) }, @@ -72,11 +169,14 @@ func TestAccGithubOrganizationRole(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrSet("github_organization_role.test", "id"), + resource.TestCheckResourceAttrSet("github_organization_role.test", "role_id"), resource.TestCheckResourceAttr("github_organization_role.test", "name", name), - resource.TestCheckResourceAttrSet("github_organization_role.test", "base_role"), + resource.TestCheckResourceAttr("github_organization_role.test", "description", description), + resource.TestCheckResourceAttr("github_organization_role.test", "base_role", baseRole), resource.TestCheckResourceAttrSet("github_organization_role.test", "permissions.#"), - resource.TestCheckResourceAttr("github_organization_role.test", "permissions.#", "1"), + resource.TestCheckResourceAttr("github_organization_role.test", "permissions.#", "2"), resource.TestCheckResourceAttr("github_organization_role.test", "permissions.0", permission0), + resource.TestCheckResourceAttr("github_organization_role.test", "permissions.1", permission1), ), }, }, diff --git a/github/resource_github_organization_role_user.go b/github/resource_github_organization_role_user.go index 5ef9147619..483d97599b 100644 --- a/github/resource_github_organization_role_user.go +++ b/github/resource_github_organization_role_user.go @@ -2,10 +2,12 @@ package github import ( "context" + "fmt" "log" "strconv" "github.com/google/go-github/v67/github" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -13,9 +15,9 @@ func resourceGithubOrganizationRoleUser() *schema.Resource { return &schema.Resource{ Description: "Manage an association between an organization role and a user.", - Create: resourceGithubOrganizationRoleUserCreate, - Read: resourceGithubOrganizationRoleUserRead, - Delete: resourceGithubOrganizationRoleUserDelete, + CreateContext: resourceGithubOrganizationRoleUserCreate, + ReadContext: resourceGithubOrganizationRoleUserRead, + DeleteContext: resourceGithubOrganizationRoleUserDelete, Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, @@ -37,14 +39,13 @@ func resourceGithubOrganizationRoleUser() *schema.Resource { } } -func resourceGithubOrganizationRoleUserCreate(d *schema.ResourceData, meta any) error { +func resourceGithubOrganizationRoleUserCreate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { err := checkOrganization(meta) if err != nil { - return err + return diag.FromErr(err) } client := meta.(*Owner).v3client - ctx := context.Background() orgName := meta.(*Owner).name roleId := int64(d.Get("role_id").(int)) @@ -52,31 +53,30 @@ func resourceGithubOrganizationRoleUserCreate(d *schema.ResourceData, meta any) _, err = client.Organizations.AssignOrgRoleToUser(ctx, orgName, login, roleId) if err != nil { - return err + return diag.FromErr(err) } d.SetId(buildTwoPartID(strconv.FormatInt(roleId, 10), login)) - return resourceGithubOrganizationRoleUserRead(d, meta) + return nil } -func resourceGithubOrganizationRoleUserRead(d *schema.ResourceData, meta any) error { +func resourceGithubOrganizationRoleUserRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { err := checkOrganization(meta) if err != nil { - return err + return diag.FromErr(err) } client := meta.(*Owner).v3client - ctx := context.Background() orgName := meta.(*Owner).name roleIdString, login, err := parseTwoPartID(d.Id(), "role_id", "login") if err != nil { - return err + return diag.FromErr(err) } roleId, err := strconv.ParseInt(roleIdString, 10, 64) if err != nil { - return err + return diag.FromErr(err) } opts := &github.ListOptions{ @@ -87,7 +87,7 @@ func resourceGithubOrganizationRoleUserRead(d *schema.ResourceData, meta any) er for { users, resp, err := client.Organizations.ListUsersAssignedToOrgRole(ctx, orgName, roleId, opts) if err != nil { - return err + return diag.FromErr(err) } for _, u := range users { @@ -110,29 +110,32 @@ func resourceGithubOrganizationRoleUserRead(d *schema.ResourceData, meta any) er } if err = d.Set("role_id", roleId); err != nil { - return err + return diag.FromErr(err) } if err = d.Set("login", login); err != nil { - return err + return diag.FromErr(err) } return nil } -func resourceGithubOrganizationRoleUserDelete(d *schema.ResourceData, meta any) error { +func resourceGithubOrganizationRoleUserDelete(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { err := checkOrganization(meta) if err != nil { - return err + return diag.FromErr(err) } client := meta.(*Owner).v3client - ctx := context.Background() orgName := meta.(*Owner).name roleId := int64(d.Get("role_id").(int)) login := d.Get("login").(string) _, err = client.Organizations.RemoveOrgRoleFromUser(ctx, orgName, login, roleId) - return err + if err != nil { + return diag.FromErr(fmt.Errorf("Error deleting organization role user %d %s: %w", roleId, login, err)) + } + + return nil } diff --git a/website/docs/r/organization_role.html.markdown b/website/docs/r/organization_role.html.markdown index b28eb728a0..f57d9f776f 100644 --- a/website/docs/r/organization_role.html.markdown +++ b/website/docs/r/organization_role.html.markdown @@ -30,12 +30,12 @@ resource "github_organization_role" "example" { ### Required - `name` (String) The name of the organization role. -- `permissions` (Set of String, Min: 1) The permissions included in this role. +- `permissions` (Set of String) The permissions included in this role. Only organization permissions can be set if the `base_role` isn't set or is set to `none`. ### Optional - `description` (String) The description of the organization role. -- `base_role` (String) The system role from which this role inherits permissions. +- `base_role` (String) The system role from which this role inherits permissions; one of `none`, `read`, `triage`, `write`, `maintain`, or `admin`. Defaults to `none`. ### Read-Only