Skip to content
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
57 changes: 57 additions & 0 deletions docs/data-sources/identity_roles.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
subcategory: "Identity and Access Management (IAM)"
layout: "huaweicloud"
page_title: "HuaweiCloud: huaweicloud_identity_roles"
description: ""
---

# huaweicloud_identity_roles

Use this data source to get a list of IAM roles with optional filtering by name or display name.

-> **NOTE:** You *must* have IAM read privileges to use this data source.

The Roles in Terraform correspond to the IAM roles in HuaweiCloud. You can retrieve all **System-Defined Roles** and their details using this data source.

## Example Usage

### Retrieve Roles by Name
```hcl
data "huaweicloud_identity_roles" "roles" {
name = "system_all_64"
}
```

### Retrieve Roles by Display Name
```hcl
data "huaweicloud_identity_roles" "roles" {
display_name = "OBS ReadOnlyAccess"
}
```

### Retrieve All Roles (No Filtering)
```hcl
data "huaweicloud_identity_roles" "roles" {}
```

## Argument Reference

* `name` - (Optional, String) Specifies the internal name of the role. If provided, only roles matching this name will be returned.

* `display_name` - (Optional, String) Specifies the display name of the role as shown on the console. If provided, only roles matching this display name will be returned.

-> **NOTE:** At least one of `name` or `display_name` must be specified if you want to filter roles. If neither is specified, all roles will be returned.

## Attribute Reference

In addition to all arguments above, the following attributes are exported:

* `roles` - A list of roles matching the specified criteria. Each role contains the following attributes:
* `id` - The unique identifier of the role in UUID format.
* `name` - The internal name of the role.
* `display_name` - The display name of the role as shown on the console.
* `description` - The description of the role.
* `catalog` - The service catalog associated with the role.
* `type` - The type or display mode of the role.
* `policy` - The JSON content of the role's policy.
```
1 change: 1 addition & 0 deletions huaweicloud/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -948,6 +948,7 @@ func Provider() *schema.Provider {

"huaweicloud_identity_permissions": iam.DataSourceIdentityPermissions(),
"huaweicloud_identity_role": iam.DataSourceIdentityRole(),
"huaweicloud_identity_roles": iam.DataSourceIdentityRoles(),
"huaweicloud_identity_custom_role": iam.DataSourceIdentityCustomRole(),
"huaweicloud_identity_group": iam.DataSourceIdentityGroup(),
"huaweicloud_identity_projects": iam.DataSourceIdentityProjects(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package iam

import (
"testing"

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

"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance"
)

func TestAccIdentityRolesDataSource_basic(t *testing.T) {
dataSourceName := "data.huaweicloud_identity_roles.roles"
dc := acceptance.InitDataSourceCheck(dataSourceName)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
acceptance.TestAccPreCheck(t)
acceptance.TestAccPreCheckAdminOnly(t)
},
ProviderFactories: acceptance.TestAccProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccIdentityRolesDataSource_by_name,
Check: resource.ComposeTestCheckFunc(
dc.CheckResourceExists(),
resource.TestCheckResourceAttrSet(dataSourceName, "roles.#"),
resource.TestCheckResourceAttr(dataSourceName, "roles.0.name", "system_all_64"),
resource.TestCheckResourceAttr(dataSourceName, "roles.0.display_name", "OBS ReadOnlyAccess"),
),
},
{
Config: testAccIdentityRolesDataSource_by_displayname,
Check: resource.ComposeTestCheckFunc(
dc.CheckResourceExists(),
resource.TestCheckResourceAttrSet(dataSourceName, "roles.#"),
resource.TestCheckResourceAttr(dataSourceName, "roles.0.name", "kms_adm"),
resource.TestCheckResourceAttr(dataSourceName, "roles.0.display_name", "KMS Administrator"),
),
},
{
Config: testAccIdentityRolesDataSource_empty_filter,
Check: resource.ComposeTestCheckFunc(
dc.CheckResourceExists(),
resource.TestCheckResourceAttr(dataSourceName, "roles.#", "0"),
),
},
{
Config: testAccIdentityRolesDataSource_multiple_roles,
Check: resource.ComposeTestCheckFunc(
dc.CheckResourceExists(),
resource.TestCheckResourceAttrSet(dataSourceName, "roles.#"),
resource.TestCheckResourceAttr(dataSourceName, "roles.0.name", "system_all_64"),
resource.TestCheckResourceAttr(dataSourceName, "roles.1.name", "kms_adm"),
),
},
},
})
}

const testAccIdentityRolesDataSource_by_name = `
data "huaweicloud_identity_roles" "roles" {
name = "system_all_64"
}
`

const testAccIdentityRolesDataSource_by_displayname = `
data "huaweicloud_identity_roles" "roles" {
display_name = "KMS Administrator"
}
`

const testAccIdentityRolesDataSource_empty_filter = `
data "huaweicloud_identity_roles" "roles" {
name = "nonexistent_role"
}
`

const testAccIdentityRolesDataSource_multiple_roles = `
data "huaweicloud_identity_roles" "roles" {
}
`
132 changes: 132 additions & 0 deletions huaweicloud/services/iam/data_source_huaweicloud_identity_roles.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package iam

import (
"context"
"encoding/json"
"log"

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

"github.com/chnsz/golangsdk/openstack/identity/v3/roles"

"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config"
)

// @API IAM GET /v3/roles
func DataSourceIdentityRoles() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceIdentityRolesRead,

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Optional: true,
},
"display_name": {
Type: schema.TypeString,
Optional: true,
},
"roles": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"display_name": {
Type: schema.TypeString,
Computed: true,
},
"description": {
Type: schema.TypeString,
Computed: true,
},
"catalog": {
Type: schema.TypeString,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
"policy": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
},
}
}

// dataSourceIdentityRolesRead performs the role lookup.
func dataSourceIdentityRolesRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
cfg := meta.(*config.Config)
identityClient, err := cfg.IdentityV3Client(cfg.GetRegion(d))
if err != nil {
return diag.Errorf("error creating IAM client: %s", err)
}

listOpts := roles.ListOpts{
Name: d.Get("name").(string),
DisplayName: d.Get("display_name").(string),
}

log.Printf("[DEBUG] List Options: %#v", listOpts)
allPages, err := roles.ListWithPages(identityClient, listOpts).AllPages()
if err != nil {
return diag.Errorf("unable to query IAM roles: %s", err)
}

allRoles, err := roles.ExtractOffsetRoles(allPages)
if err != nil {
return diag.Errorf("unable to retrieve IAM roles: %s", err)
}

if len(allRoles) < 1 {
return diag.Errorf("your query returned no results. " +
"Please change your search criteria and try again.")
}

roleList := make([]map[string]interface{}, 0, len(allRoles))
for _, role := range allRoles {
roleMap, err := flattenIdentityRole(&role)
if err != nil {
return diag.FromErr(err)
}
roleList = append(roleList, roleMap)
}

d.SetId("identity_roles")
if err := d.Set("roles", roleList); err != nil {
return diag.Errorf("error setting roles: %s", err)
}

return nil
}

// flattenIdentityRole converts a Role struct into a map for Terraform state.
func flattenIdentityRole(role *roles.Role) (map[string]interface{}, error) {
policy, err := json.Marshal(role.Policy)
if err != nil {
return nil, err
}

return map[string]interface{}{
"id": role.ID,
"name": role.Name,
"display_name": role.DisplayName,
"description": role.Description,
"catalog": role.Catalog,
"type": role.Type,
"policy": string(policy),
}, nil
}
Loading