-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Add data source for retrieving project iam custom roles #13303
Merged
melinath
merged 1 commit into
GoogleCloudPlatform:main
from
bestefreund:feature/data_source_google_project_iam_custom_roles
Mar 11, 2025
+258
−0
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
146 changes: 146 additions & 0 deletions
146
...d_party/terraform/services/resourcemanager/data_source_google_project_iam_custom_roles.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
package resourcemanager | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"path" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
"github.com/hashicorp/terraform-provider-google/google/tpgresource" | ||
transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" | ||
"google.golang.org/api/iam/v1" | ||
) | ||
|
||
func DataSourceGoogleProjectIamCustomRoles() *schema.Resource { | ||
return &schema.Resource{ | ||
Read: dataSourceProjectIamCustomRoleRead, | ||
Schema: map[string]*schema.Schema{ | ||
"project": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
"show_deleted": { | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
Default: false, | ||
}, | ||
"view": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
Default: "BASIC", | ||
ValidateFunc: validateView, | ||
}, | ||
"roles": { | ||
Type: schema.TypeList, | ||
Computed: true, | ||
Elem: &schema.Resource{ | ||
Schema: map[string]*schema.Schema{ | ||
"deleted": { | ||
Type: schema.TypeBool, | ||
Computed: true, | ||
}, | ||
"description": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"id": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"name": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"permissions": { | ||
Type: schema.TypeList, | ||
Computed: true, | ||
Elem: &schema.Schema{Type: schema.TypeString}, | ||
}, | ||
"role_id": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"stage": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"title": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func validateView(val interface{}, key string) ([]string, []error) { | ||
v := val.(string) | ||
var errs []error | ||
|
||
if v != "BASIC" && v != "FULL" { | ||
errs = append(errs, fmt.Errorf("%q must be either 'BASIC' or 'FULL', got %q", key, v)) | ||
} | ||
|
||
return nil, errs | ||
} | ||
|
||
func dataSourceProjectIamCustomRoleRead(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*transport_tpg.Config) | ||
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
project, err := tpgresource.GetProject(d, config) | ||
if err != nil { | ||
return fmt.Errorf("Error fetching project for custom roles: %s", err) | ||
} | ||
|
||
roles := make([]map[string]interface{}, 0) | ||
|
||
showDeleted := d.Get("show_deleted").(bool) | ||
view := d.Get("view").(string) | ||
|
||
request := config.NewIamClient(userAgent).Projects.Roles.List("projects/" + project).ShowDeleted(showDeleted).View(view) | ||
|
||
err = request.Pages(context.Background(), func(roleList *iam.ListRolesResponse) error { | ||
for _, role := range roleList.Roles { | ||
var permissions []string | ||
|
||
switch view { | ||
case "BASIC": | ||
permissions = []string{} | ||
case "FULL": | ||
permissions = role.IncludedPermissions | ||
default: | ||
return fmt.Errorf("Unsupported view type: %s", view) | ||
} | ||
|
||
roles = append(roles, map[string]interface{}{ | ||
"deleted": role.Deleted, | ||
"description": role.Description, | ||
"id": role.Name, | ||
"name": role.Name, | ||
"permissions": permissions, | ||
"role_id": path.Base(role.Name), | ||
"stage": role.Stage, | ||
"title": role.Title, | ||
}) | ||
} | ||
return nil | ||
}) | ||
|
||
if err != nil { | ||
return fmt.Errorf("Error retrieving project custom roles: %s", err) | ||
} | ||
|
||
if err := d.Set("roles", roles); err != nil { | ||
return fmt.Errorf("Error setting project custom roles: %s", err) | ||
} | ||
|
||
d.SetId("projects/" + project) | ||
|
||
return nil | ||
} |
57 changes: 57 additions & 0 deletions
57
...ty/terraform/services/resourcemanager/data_source_google_project_iam_custom_roles_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package resourcemanager_test | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform-plugin-testing/helper/resource" | ||
"github.com/hashicorp/terraform-provider-google/google/acctest" | ||
"github.com/hashicorp/terraform-provider-google/google/envvar" | ||
) | ||
|
||
func TestAccDataSourceGoogleProjectIamCustomRoles_basic(t *testing.T) { | ||
t.Parallel() | ||
|
||
project := envvar.GetTestProjectFromEnv() | ||
roleId := "tfIamCustomRole" + acctest.RandString(t, 10) | ||
|
||
acctest.VcrTest(t, resource.TestCase{ | ||
PreCheck: func() { acctest.AccTestPreCheck(t) }, | ||
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccCheckGoogleProjectIamCustomRolesConfig(project, roleId), | ||
Check: resource.ComposeTestCheckFunc( | ||
// We can't guarantee no project won't have our custom role as first element, so we'll check set-ness rather than correctness | ||
resource.TestCheckResourceAttrSet("data.google_project_iam_custom_roles.this", "roles.0.id"), | ||
resource.TestCheckResourceAttrSet("data.google_project_iam_custom_roles.this", "roles.0.name"), | ||
resource.TestCheckResourceAttrSet("data.google_project_iam_custom_roles.this", "roles.0.role_id"), | ||
resource.TestCheckResourceAttrSet("data.google_project_iam_custom_roles.this", "roles.0.stage"), | ||
resource.TestCheckResourceAttrSet("data.google_project_iam_custom_roles.this", "roles.0.title"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccCheckGoogleProjectIamCustomRolesConfig(project string, roleId string) string { | ||
return fmt.Sprintf(` | ||
locals { | ||
project = "%s" | ||
role_id = "%s" | ||
} | ||
resource "google_project_iam_custom_role" "this" { | ||
project = local.project | ||
role_id = local.role_id | ||
title = "Terraform Test" | ||
permissions = [ | ||
"iam.roles.create", | ||
"iam.roles.delete", | ||
"iam.roles.list", | ||
] | ||
} | ||
data "google_project_iam_custom_roles" "this" { | ||
project = google_project_iam_custom_role.this.project | ||
} | ||
`, project, roleId) | ||
} |
54 changes: 54 additions & 0 deletions
54
mmv1/third_party/terraform/website/docs/d/project_iam_custom_roles.html.markdown
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
--- | ||
subcategory: "Cloud Platform" | ||
description: |- | ||
Get information about Google Cloud IAM Custom Roles from a project. | ||
--- | ||
|
||
# google_project_iam_custom_roles | ||
|
||
Get information about Google Cloud IAM Custom Roles from a project. | ||
Note that you must have the `roles/iam.roleViewer`. | ||
See [the official documentation](https://cloud.google.com/iam/docs/creating-custom-roles) | ||
and [API](https://cloud.google.com/iam/docs/reference/rest/v1/projects.roles/list). | ||
|
||
```hcl | ||
data "google_project_iam_custom_roles" "example" { | ||
project = "your-project-id" | ||
show_deleted = true | ||
view = "FULL" | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
* `project` - (Optional) The project were the custom role has been created in. Defaults to the provider project configuration. | ||
|
||
* `show_deleted` - (Optional) Include Roles that have been deleted. Defaults to `false`. | ||
|
||
* `view` - (Optional) When `"FULL"` is specified, the `permissions` field is returned, which includes a list of all permissions in the role. The default value is `"BASIC"`, which does not return the `permissions`. | ||
|
||
## Attributes Reference | ||
|
||
The following attributes are exported: | ||
|
||
* `roles` - A list of all retrieved custom roles roles. Structure is [defined below](#nested_roles). | ||
|
||
<a name="nested_roles"></a>The `roles` block supports: | ||
|
||
* `deleted` - The current deleted state of the role. | ||
|
||
* `description` - A human-readable description for the role. | ||
|
||
* `id` - an identifier for the resource with the format `projects/{{project}}/roles/{{role_id}}`. | ||
|
||
* `name` - The name of the role in the format `projects/{{project}}/roles/{{role_id}}`. Like `id`, this field can be used as a reference in other resources such as IAM role bindings. | ||
|
||
* `permissions` - The names of the permissions this role grants when bound in an IAM policy. | ||
|
||
* `role_id` - The camel case role id used for this role. | ||
|
||
* `stage` - The current launch stage of the role. List of possible stages is [here](https://cloud.google.com/iam/reference/rest/v1/organizations.roles#Role.RoleLaunchStage). | ||
|
||
* `title` - A human-readable title for the role. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: whitespace
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just merging anyway.