alicloud/data_source_alicloud_ram_groups.go (216 lines of code) (raw):

package alicloud import ( "regexp" "time" "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" "github.com/aliyun/alibaba-cloud-sdk-go/services/ram" "github.com/aliyun/terraform-provider-alicloud/alicloud/connectivity" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" ) func dataSourceAlicloudRamGroups() *schema.Resource { return &schema.Resource{ Read: dataSourceAlicloudRamGroupsRead, Schema: map[string]*schema.Schema{ "name_regex": { Type: schema.TypeString, Optional: true, ForceNew: true, }, "user_name": { Type: schema.TypeString, Optional: true, ForceNew: true, ValidateFunc: StringLenBetween(0, 64), }, "policy_name": { Type: schema.TypeString, Optional: true, ForceNew: true, ValidateFunc: StringLenBetween(0, 128), }, "policy_type": { Type: schema.TypeString, Optional: true, ForceNew: true, // must be ram.System, ram.Custom ValidateFunc: StringInSlice([]string{"System", "Custom"}, false), }, "output_file": { Type: schema.TypeString, Optional: true, }, "names": { Type: schema.TypeList, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, // Computed values "groups": { Type: schema.TypeList, Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, Computed: true, }, "comments": { Type: schema.TypeString, Computed: true, }, }, }, }, }, } } func dataSourceAlicloudRamGroupsRead(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AliyunClient) ramService := RamService{client} var allGroups []interface{} allGroupsMap := make(map[string]interface{}) userFilterGroupsMap := make(map[string]interface{}) policyFilterGroupsMap := make(map[string]interface{}) var dataMap []map[string]interface{} userName, userNameOk := d.GetOk("user_name") policyName, policyNameOk := d.GetOk("policy_name") policyType, policyTypeOk := d.GetOk("policy_type") nameRegex, nameRegexOk := d.GetOk("name_regex") if policyTypeOk && !policyNameOk { return WrapError(Error("You must set 'policy_name' at one time when you set 'policy_type'.")) } // groups filtered by name_regex request := ram.CreateListGroupsRequest() request.RegionId = client.RegionId request.MaxItems = requests.NewInteger(1000) for { var raw interface{} var err error wait := incrementalWait(3*time.Second, 3*time.Second) err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutRead)), func() *resource.RetryError { raw, err = client.WithRamClient(func(ramClient *ram.Client) (interface{}, error) { return ramClient.ListGroups(request) }) if err != nil { if NeedRetry(err) { wait() return resource.RetryableError(err) } return resource.NonRetryableError(err) } addDebug(request.GetActionName(), raw, request.RpcRequest, request) return nil }) if err != nil { return WrapErrorf(err, DataDefaultErrorMsg, "alicloud_ram_groups", request.GetActionName(), AlibabaCloudSdkGoERROR) } response, _ := raw.(*ram.ListGroupsResponse) for _, v := range response.Groups.Group { if nameRegexOk { r, err := regexp.Compile(nameRegex.(string)) if err != nil { return WrapError(err) } if !r.MatchString(v.GroupName) { continue } } allGroupsMap[v.GroupName] = v } if !response.IsTruncated { break } request.Marker = response.Marker } // groups for user if userNameOk { request := ram.CreateListGroupsForUserRequest() request.UserName = userName.(string) var raw interface{} var err error wait := incrementalWait(3*time.Second, 3*time.Second) err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutRead)), func() *resource.RetryError { raw, err = client.WithRamClient(func(ramClient *ram.Client) (interface{}, error) { return ramClient.ListGroupsForUser(request) }) if err != nil { if NeedRetry(err) { wait() return resource.RetryableError(err) } return resource.NonRetryableError(err) } addDebug(request.GetActionName(), raw, request.RpcRequest, request) return nil }) if err != nil { return WrapErrorf(err, DataDefaultErrorMsg, "alicloud_ram_groups", request.GetActionName(), AlibabaCloudSdkGoERROR) } response, _ := raw.(*ram.ListGroupsForUserResponse) for _, v := range response.Groups.Group { userFilterGroupsMap[v.GroupName] = v } if len(userFilterGroupsMap) > 0 { dataMap = append(dataMap, userFilterGroupsMap) } } // groups which attach with this policy if policyNameOk { pType := "System" if policyTypeOk { pType = policyType.(string) } request := ram.CreateListEntitiesForPolicyRequest() request.PolicyType = pType request.PolicyName = policyName.(string) var raw interface{} var err error wait := incrementalWait(3*time.Second, 3*time.Second) err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutRead)), func() *resource.RetryError { raw, err = client.WithRamClient(func(ramClient *ram.Client) (interface{}, error) { return ramClient.ListEntitiesForPolicy(request) }) if err != nil { if NeedRetry(err) { wait() return resource.RetryableError(err) } return resource.NonRetryableError(err) } addDebug(request.GetActionName(), raw, request.RpcRequest, request) return nil }) if err != nil { return WrapErrorf(err, DataDefaultErrorMsg, "alicloud_ram_groups", request.GetActionName(), AlibabaCloudSdkGoERROR) } response, _ := raw.(*ram.ListEntitiesForPolicyResponse) for _, v := range response.Groups.Group { policyFilterGroupsMap[v.GroupName] = v } if len(policyFilterGroupsMap) > 0 { dataMap = append(dataMap, policyFilterGroupsMap) } } // GetIntersection of each map allGroups = ramService.GetIntersection(dataMap, allGroupsMap, userNameOk, policyNameOk) return ramGroupsDescriptionAttributes(d, allGroups) } func ramGroupsDescriptionAttributes(d *schema.ResourceData, groups []interface{}) error { var ids []string var s []map[string]interface{} for _, v := range groups { group := v.(ram.Group) mapping := map[string]interface{}{ "name": group.GroupName, "comments": group.Comments, } ids = append(ids, v.(ram.Group).GroupName) s = append(s, mapping) } d.SetId(dataResourceIdHash(ids)) if err := d.Set("names", ids); err != nil { return WrapError(err) } if err := d.Set("groups", s); err != nil { return WrapError(err) } // create a json file in current directory and write data source to it. if output, ok := d.GetOk("output_file"); ok && output.(string) != "" { writeToFile(output.(string), s) } return nil }