diff --git a/docs/data-sources/identity_custom_role.md b/docs/data-sources/identity_custom_role.md new file mode 100644 index 0000000000..d4b350c09e --- /dev/null +++ b/docs/data-sources/identity_custom_role.md @@ -0,0 +1,40 @@ +--- +subcategory: "Identity and Access Management (IAM)" +--- + +# huaweicloud\_identity\_custom\_role + +Use this data source to get the ID of an HuaweiCloud custom role. + +The Role in Terraform is the same as Policy on console. however, +The policy name is the display name of Role, the Role name cannot +be found on Console. + +```hcl +data "huaweicloud_identity_custom_role" "role" { + name = "custom_role" +} +``` + +## Argument Reference + +* `name` - (Optional, String) Name of the custom policy. + +* `id` - (Optional, String) ID of the custom policy. + +* `domain_id` - (Optional, String) The domain the policy belongs to. + +* `references` - (Optional, Int) The number of citations for the custom policy. + +* `description` - (Optional, String) Description of the custom policy. + +* `type` - (Optional, String) Display mode. Valid options are AX: Account level and XA: Project level. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `policy` - Document of the custom policy. + +* `catalog` - The catalog of the custom policy. + diff --git a/go.mod b/go.mod index 32b6dc2200..7d5ad454d8 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/hashicorp/errwrap v1.0.0 github.com/hashicorp/go-cleanhttp v0.5.1 github.com/hashicorp/terraform-plugin-sdk v1.13.0 - github.com/huaweicloud/golangsdk v0.0.0-20201228013212-d10065a3dc7f + github.com/huaweicloud/golangsdk v0.0.0-20210116064800-601b4de34229 github.com/jen20/awspolicyequivalence v0.0.0-20170831201602-3d48364a137a github.com/mitchellh/go-homedir v1.1.0 github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa // indirect diff --git a/go.sum b/go.sum index c2165c671a..959bb39278 100644 --- a/go.sum +++ b/go.sum @@ -129,16 +129,8 @@ github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= -github.com/huaweicloud/golangsdk v0.0.0-20201222025841-5312fcc13866 h1:CN12N3XOkiMzsyNhdjABKhXlbRIZKu1YJMcEPJs6hZE= -github.com/huaweicloud/golangsdk v0.0.0-20201222025841-5312fcc13866/go.mod h1:fcOI5u+0f62JtJd7zkCch/Z57BNC6bhqb32TKuiF4r0= -github.com/huaweicloud/golangsdk v0.0.0-20201223081519-cedf29b4891c h1:Wn/clEpob9fqlwbRIvuKM1UpQJcyObse8uav4NyglIc= -github.com/huaweicloud/golangsdk v0.0.0-20201223081519-cedf29b4891c/go.mod h1:fcOI5u+0f62JtJd7zkCch/Z57BNC6bhqb32TKuiF4r0= -github.com/huaweicloud/golangsdk v0.0.0-20201224083252-010617edf28c h1:Igfi5l8W6r8NGUVOZyaIt1m6JZQqo9Lx5bOXbx53qyE= -github.com/huaweicloud/golangsdk v0.0.0-20201224083252-010617edf28c/go.mod h1:fcOI5u+0f62JtJd7zkCch/Z57BNC6bhqb32TKuiF4r0= -github.com/huaweicloud/golangsdk v0.0.0-20201225034918-fe22e43ed768 h1:v+5rLipFpQ99TnlPneFWn28mw6koeLtXgplfDdpDWag= -github.com/huaweicloud/golangsdk v0.0.0-20201225034918-fe22e43ed768/go.mod h1:fcOI5u+0f62JtJd7zkCch/Z57BNC6bhqb32TKuiF4r0= -github.com/huaweicloud/golangsdk v0.0.0-20201228013212-d10065a3dc7f h1:5gf/WhTTYklU59Ah+hcnCkQAyQzlylglysX6E8I82f8= -github.com/huaweicloud/golangsdk v0.0.0-20201228013212-d10065a3dc7f/go.mod h1:fcOI5u+0f62JtJd7zkCch/Z57BNC6bhqb32TKuiF4r0= +github.com/huaweicloud/golangsdk v0.0.0-20210116064800-601b4de34229 h1:tbgMbWp2CbIxSb6/YVXLjSnliKDzz5luUjEavpD1jZE= +github.com/huaweicloud/golangsdk v0.0.0-20210116064800-601b4de34229/go.mod h1:fcOI5u+0f62JtJd7zkCch/Z57BNC6bhqb32TKuiF4r0= github.com/jen20/awspolicyequivalence v0.0.0-20170831201602-3d48364a137a h1:FyS/ubzBR5xJlnJGRTwe7GUHpJOR4ukYK3y+LFNffuA= github.com/jen20/awspolicyequivalence v0.0.0-20170831201602-3d48364a137a/go.mod h1:uoIMjNxUfXi48Ci40IXkPRbghZ1vbti6v9LCbNqRgHY= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= diff --git a/huaweicloud/data_source_huaweicloud_identity_custom_role.go b/huaweicloud/data_source_huaweicloud_identity_custom_role.go new file mode 100644 index 0000000000..b1b04c7d93 --- /dev/null +++ b/huaweicloud/data_source_huaweicloud_identity_custom_role.go @@ -0,0 +1,155 @@ +package huaweicloud + +import ( + "encoding/json" + "fmt" + "log" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/huaweicloud/golangsdk/openstack/identity/v3.0/policies" +) + +func DataSourceIdentityCustomRole() *schema.Resource { + return &schema.Resource{ + Read: dataSourceIdentityCustomRoleRead, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Optional: true, + AtLeastOneOf: []string{"name", "id"}, + }, + "id": { + Type: schema.TypeString, + Optional: true, + AtLeastOneOf: []string{"name", "id"}, + }, + "domain_id": { + Type: schema.TypeString, + Optional: true, + }, + "references": { + Type: schema.TypeInt, + Optional: true, + }, + "description": { + Type: schema.TypeString, + Optional: true, + }, + "type": { + Type: schema.TypeString, + Optional: true, + }, + "catalog": { + Type: schema.TypeString, + Computed: true, + }, + "policy": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func dataSourceIdentityCustomRoleRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + identityClient, err := config.IAMV3Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating HuaweiCloud identity client: %s", err) + } + + allPages, err := policies.List(identityClient).AllPages() + if err != nil { + return fmt.Errorf("Unable to query roles: %s", err) + } + + roles, err := policies.ExtractPageRoles(allPages) + + conditions := map[string]interface{}{} + + if v, ok := d.GetOk("name"); ok { + conditions["name"] = v.(string) + } + if v, ok := d.GetOk("id"); ok { + conditions["id"] = v.(string) + } + if v, ok := d.GetOk("domain_id"); ok { + conditions["domain_id"] = v.(string) + } + if v, ok := d.GetOk("references"); ok { + conditions["references"] = v.(int) + } + if v, ok := d.GetOk("description"); ok { + conditions["description"] = v.(string) + } + if v, ok := d.GetOk("type"); ok { + conditions["type"] = v.(string) + } + + var allRoles []policies.Role + + for _, role := range roles { + if rolesFilter(role, conditions) { + allRoles = append(allRoles, role) + } + } + + if len(allRoles) < 1 { + return fmt.Errorf("Your query returned no results. " + + "Please change your search criteria and try again.") + } + + if len(allRoles) > 1 { + log.Printf("[DEBUG] Multiple results found: %#v", allRoles) + return fmt.Errorf("Your query returned more than one result. Please try a more " + + "specific search criteria.") + } + role := allRoles[0] + + return dataSourceIdentityCustomRoleAttributes(d, config, &role) +} + +// dataSourceIdentityRoleV3Attributes populates the fields of an Role resource. +func dataSourceIdentityCustomRoleAttributes(d *schema.ResourceData, config *Config, role *policies.Role) error { + log.Printf("[DEBUG] huaweicloud_identity_role details: %#v", role) + + d.SetId(role.ID) + d.Set("name", role.Name) + d.Set("domain_id", role.DomainId) + d.Set("references", role.References) + d.Set("catalog", role.Catalog) + d.Set("description", role.Description) + d.Set("type", role.Type) + + policy, err := json.Marshal(role.Policy) + if err != nil { + return fmt.Errorf("Error marshalling policy: %s", err) + } + + d.Set("policy", string(policy)) + + return nil +} + +func rolesFilter(role policies.Role, conditions map[string]interface{}) bool { + if v, ok := conditions["name"]; ok && v != role.Name { + return false + } + if v, ok := conditions["id"]; ok && v != role.ID { + return false + } + if v, ok := conditions["domain_id"]; ok && v != role.DomainId { + return false + } + if v, ok := conditions["references"]; ok && v != role.References { + return false + } + if v, ok := conditions["description"]; ok && v != role.Description { + return false + } + if v, ok := conditions["type"]; ok && v != role.Type { + return false + } + return true +} diff --git a/huaweicloud/data_source_huaweicloud_identity_custom_role_test.go b/huaweicloud/data_source_huaweicloud_identity_custom_role_test.go new file mode 100644 index 0000000000..39743dfa72 --- /dev/null +++ b/huaweicloud/data_source_huaweicloud_identity_custom_role_test.go @@ -0,0 +1,77 @@ +package huaweicloud + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" +) + +func TestAccHuaweiCloudIdentityCustomRoleDataSource_basic(t *testing.T) { + var rName = fmt.Sprintf("ACCPTTEST-%s", acctest.RandString(5)) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccPreCheckAdminOnly(t) + }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccHuaweiCloudIdentityCustomRoleDataSource_basic(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckIdentityCustomDataSourceID("data.huaweicloud_identity_custom_role.role_1"), + resource.TestCheckResourceAttr( + "data.huaweicloud_identity_custom_role.role_1", "name", rName), + ), + }, + }, + }) +} + +func testAccCheckIdentityCustomDataSourceID(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Can't find role data source: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("Role data source ID not set") + } + + return nil + } +} + +func testAccHuaweiCloudIdentityCustomRoleDataSource_basic(rName string) string { + return fmt.Sprintf(` +resource "huaweicloud_identity_role" test { + name = "%s" + description = "created by terraform" + type = "AX" + policy = <