alicloud/resource_alicloud_ram_user.go (415 lines of code) (raw):

package alicloud import ( "time" "github.com/alibabacloud-go/tea/tea" util "github.com/alibabacloud-go/tea-utils/service" "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 resourceAlicloudRamUser() *schema.Resource { return &schema.Resource{ Create: resourceAlicloudRamUserCreate, Read: resourceAlicloudRamUserRead, Update: resourceAlicloudRamUserUpdate, Delete: resourceAlicloudRamUserDelete, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(3 * time.Minute), Update: schema.DefaultTimeout(3 * time.Minute), Delete: schema.DefaultTimeout(3 * time.Minute), }, Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, Required: true, }, "display_name": { Type: schema.TypeString, Optional: true, }, "mobile": { Type: schema.TypeString, Optional: true, }, "email": { Type: schema.TypeString, Optional: true, }, "comments": { Type: schema.TypeString, Optional: true, ValidateFunc: StringLenBetween(0, 128), }, "force": { Type: schema.TypeBool, Optional: true, }, }, } } func resourceAlicloudRamUserCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AliyunClient) ramService := RamService{client} request := ram.CreateCreateUserRequest() request.RegionId = client.RegionId request.UserName = d.Get("name").(string) if v, ok := d.GetOk("display_name"); ok { request.DisplayName = v.(string) } if v, ok := d.GetOk("mobile"); ok { request.MobilePhone = v.(string) } if v, ok := d.GetOk("email"); ok { request.Email = v.(string) } if v, ok := d.GetOk("comments"); ok { request.Comments = v.(string) } wait := incrementalWait(3*time.Second, 3*time.Second) var err error var raw interface{} err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutCreate)), func() *resource.RetryError { raw, err = client.WithRamClient(func(ramClient *ram.Client) (interface{}, error) { return ramClient.CreateUser(request) }) if err != nil { if NeedRetry(err) { wait() return resource.RetryableError(err) } return resource.NonRetryableError(err) } return nil }) addDebug(request.GetActionName(), raw, request.RpcRequest, request) if err != nil { return WrapErrorf(err, DefaultErrorMsg, "alicloud_ram_user", request.GetActionName(), AlibabaCloudSdkGoERROR) } response, _ := raw.(*ram.CreateUserResponse) d.SetId(response.User.UserId) err = ramService.WaitForRamUser(d.Id(), Normal, DefaultTimeout) if err != nil { return WrapError(err) } return resourceAlicloudRamUserRead(d, meta) } func resourceAlicloudRamUserUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AliyunClient) var response map[string]interface{} var err error update := false request := map[string]interface{}{ "UserName": d.Get("name"), "NewUserName": d.Get("name"), } if !d.IsNewResource() && d.HasChange("name") { update = true oldName, newName := d.GetChange("name") request["UserName"] = oldName.(string) request["NewUserName"] = newName.(string) } if d.HasChange("display_name") { update = true if v, ok := d.GetOk("display_name"); ok { request["NewDisplayName"] = v } else { request["NewDisplayName"] = tea.String("") } } if d.HasChange("mobile") { update = true if v, ok := d.GetOk("mobile"); ok { request["NewMobilePhone"] = v } else { request["NewMobilePhone"] = tea.String("") } } if d.HasChange("email") { update = true if v, ok := d.GetOk("email"); ok { request["NewEmail"] = v } else { request["NewEmail"] = tea.String("") } } if d.HasChange("comments") { update = true if v, ok := d.GetOk("comments"); ok { request["NewComments"] = v } else { request["NewComments"] = tea.String("") } } if update { action := "UpdateUser" wait := incrementalWait(3*time.Second, 5*time.Second) err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError { response, err = client.RpcPost("Ram", "2015-05-01", action, nil, request, false) if err != nil { if NeedRetry(err) { wait() return resource.RetryableError(err) } return resource.NonRetryableError(err) } return nil }) addDebug(action, response, request) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } } return resourceAlicloudRamUserRead(d, meta) } func resourceAlicloudRamUserRead(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AliyunClient) ramService := &RamService{client: client} object, err := ramService.DescribeRamUser(d.Id()) if err != nil { if NotFoundError(err) { d.SetId("") return nil } return WrapError(err) } d.SetId(object.UserId) d.Set("name", object.UserName) d.Set("display_name", object.DisplayName) d.Set("mobile", object.MobilePhone) d.Set("email", object.Email) d.Set("comments", object.Comments) return nil } func resourceAlicloudRamUserDelete(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AliyunClient) var raw interface{} var wait func() ramService := &RamService{client: client} object, err := ramService.DescribeRamUser(d.Id()) if err != nil { if NotFoundError(err) { return nil } return WrapError(err) } userName := object.UserName request := ram.CreateListAccessKeysRequest() request.RegionId = client.RegionId request.UserName = userName if d.Get("force").(bool) { // list and delete access keys for this user wait = incrementalWait(3*time.Second, 3*time.Second) err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutDelete)), func() *resource.RetryError { raw, err = client.WithRamClient(func(ramClient *ram.Client) (interface{}, error) { return ramClient.ListAccessKeys(request) }) if err != nil { if NeedRetry(err) { wait() return resource.RetryableError(err) } return resource.NonRetryableError(err) } return nil }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR) } addDebug(request.GetActionName(), raw, request.RpcRequest, request) listAccessKeysResponse, _ := raw.(*ram.ListAccessKeysResponse) if len(listAccessKeysResponse.AccessKeys.AccessKey) > 0 { for _, v := range listAccessKeysResponse.AccessKeys.AccessKey { request := ram.CreateDeleteAccessKeyRequest() request.RegionId = client.RegionId request.UserAccessKeyId = v.AccessKeyId request.UserName = userName runtime := util.RuntimeOptions{} runtime.SetAutoretry(true) wait = incrementalWait(3*time.Second, 3*time.Second) err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutDelete)), func() *resource.RetryError { raw, err = client.WithRamClient(func(ramClient *ram.Client) (interface{}, error) { return ramClient.DeleteAccessKey(request) }) if err != nil { if NeedRetry(err) { wait() return resource.RetryableError(err) } return resource.NonRetryableError(err) } return nil }) if err != nil && !IsExpectedErrors(err, []string{"EntityNotExist"}) { return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR) } addDebug(request.GetActionName(), raw, request.RpcRequest, request) } } // list and delete policies for this user request := ram.CreateListPoliciesForUserRequest() request.RegionId = client.RegionId request.UserName = userName wait = incrementalWait(3*time.Second, 3*time.Second) err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutDelete)), func() *resource.RetryError { raw, err = client.WithRamClient(func(ramClient *ram.Client) (interface{}, error) { return ramClient.ListPoliciesForUser(request) }) if err != nil { if NeedRetry(err) { wait() return resource.RetryableError(err) } return resource.NonRetryableError(err) } return nil }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR) } addDebug(request.GetActionName(), raw, request.RpcRequest, request) listPoliciesForUserResponse, _ := raw.(*ram.ListPoliciesForUserResponse) if len(listPoliciesForUserResponse.Policies.Policy) > 0 { for _, v := range listPoliciesForUserResponse.Policies.Policy { request := ram.CreateDetachPolicyFromUserRequest() request.RegionId = client.RegionId request.PolicyName = v.PolicyName request.PolicyType = v.PolicyType request.UserName = userName wait = incrementalWait(3*time.Second, 3*time.Second) err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutDelete)), func() *resource.RetryError { raw, err = client.WithRamClient(func(ramClient *ram.Client) (interface{}, error) { return ramClient.DetachPolicyFromUser(request) }) if err != nil { if NeedRetry(err) { wait() return resource.RetryableError(err) } return resource.NonRetryableError(err) } return nil }) if err != nil && !IsExpectedErrors(err, []string{"EntityNotExist"}) { return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR) } addDebug(request.GetActionName(), raw, request.RpcRequest, request) } } // list and delete groups for this user listGroupsForUserRequest := ram.CreateListGroupsForUserRequest() listGroupsForUserRequest.RegionId = client.RegionId listGroupsForUserRequest.UserName = userName wait = incrementalWait(3*time.Second, 3*time.Second) err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutDelete)), func() *resource.RetryError { raw, err = client.WithRamClient(func(ramClient *ram.Client) (interface{}, error) { return ramClient.ListGroupsForUser(listGroupsForUserRequest) }) if err != nil { if NeedRetry(err) { wait() return resource.RetryableError(err) } return resource.NonRetryableError(err) } return nil }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), listGroupsForUserRequest.GetActionName(), AlibabaCloudSdkGoERROR) } addDebug(listGroupsForUserRequest.GetActionName(), raw, listGroupsForUserRequest.RpcRequest, listGroupsForUserRequest) listGroupsForUserResponse, _ := raw.(*ram.ListGroupsForUserResponse) if len(listGroupsForUserResponse.Groups.Group) > 0 { for _, v := range listGroupsForUserResponse.Groups.Group { request := ram.CreateRemoveUserFromGroupRequest() request.RegionId = client.RegionId request.UserName = userName request.GroupName = v.GroupName wait = incrementalWait(3*time.Second, 3*time.Second) err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutDelete)), func() *resource.RetryError { raw, err = client.WithRamClient(func(ramClient *ram.Client) (interface{}, error) { return ramClient.RemoveUserFromGroup(request) }) if err != nil { if NeedRetry(err) { wait() return resource.RetryableError(err) } return resource.NonRetryableError(err) } return nil }) if err != nil && !IsExpectedErrors(err, []string{"EntityNotExist"}) { return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR) } addDebug(request.GetActionName(), raw, request.RpcRequest, request) } } // delete login profile for this user deleteLoginProfileRequest := ram.CreateDeleteLoginProfileRequest() deleteLoginProfileRequest.RegionId = client.RegionId deleteLoginProfileRequest.UserName = userName wait = incrementalWait(3*time.Second, 3*time.Second) err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutDelete)), func() *resource.RetryError { raw, err = client.WithRamClient(func(ramClient *ram.Client) (interface{}, error) { return ramClient.DeleteLoginProfile(deleteLoginProfileRequest) }) if err != nil { if NeedRetry(err) { wait() return resource.RetryableError(err) } return resource.NonRetryableError(err) } return nil }) if err != nil && !IsExpectedErrors(err, []string{"EntityNotExist.User.LoginProfile"}) { return WrapErrorf(err, DefaultErrorMsg, d.Id(), deleteLoginProfileRequest.GetActionName(), AlibabaCloudSdkGoERROR) } addDebug(deleteLoginProfileRequest.GetActionName(), raw) // unbind MFA device for this user unbindMFADeviceRequest := ram.CreateUnbindMFADeviceRequest() unbindMFADeviceRequest.UserName = userName wait = incrementalWait(3*time.Second, 3*time.Second) err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutDelete)), func() *resource.RetryError { raw, err = client.WithRamClient(func(ramClient *ram.Client) (interface{}, error) { return ramClient.UnbindMFADevice(unbindMFADeviceRequest) }) if err != nil { if NeedRetry(err) { wait() return resource.RetryableError(err) } return resource.NonRetryableError(err) } return nil }) if err != nil && !IsExpectedErrors(err, []string{"EntityNotExist", "EntityNotExist.User.MFADevice"}) { return WrapErrorf(err, DefaultErrorMsg, d.Id(), unbindMFADeviceRequest.GetActionName(), AlibabaCloudSdkGoERROR) } addDebug(unbindMFADeviceRequest.GetActionName(), raw, deleteLoginProfileRequest.RpcRequest, deleteLoginProfileRequest) } deleteUserRequest := ram.CreateDeleteUserRequest() deleteUserRequest.RegionId = client.RegionId wait = incrementalWait(3*time.Second, 3*time.Second) err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutDelete)), func() *resource.RetryError { raw, err = client.WithRamClient(func(ramClient *ram.Client) (interface{}, error) { deleteUserRequest.UserName = userName return ramClient.DeleteUser(deleteUserRequest) }) if err != nil { if NeedRetry(err) { wait() return resource.RetryableError(err) } return resource.NonRetryableError(err) } return nil }) if err != nil { if IsExpectedErrors(err, []string{"DeleteConflict.User.AccessKey", "DeleteConflict.User.Group", "DeleteConflict.User.Policy", "DeleteConflict.User.LoginProfile", "DeleteConflict.User.MFADevice"}) { return WrapError(Error("The user can not be deleted if he has any access keys, login profile, groups, policies, or MFA device attached. You can force the deletion of the user by setting force equals true.")) } return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR) } addDebug(deleteUserRequest.GetActionName(), raw, deleteUserRequest.RpcRequest, deleteUserRequest) return WrapError(ramService.WaitForRamUser(d.Id(), Deleted, DefaultTimeout)) }