diff --git a/.changelog/3604.txt b/.changelog/3604.txt new file mode 100644 index 0000000000..6f46fffca2 --- /dev/null +++ b/.changelog/3604.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/tencentcloud_tcr_service_account: optimiz custom password. +``` \ No newline at end of file diff --git a/tencentcloud/services/tcr/resource_tc_tcr_service_account.go b/tencentcloud/services/tcr/resource_tc_tcr_service_account.go index 80eb200dd9..b56c189775 100644 --- a/tencentcloud/services/tcr/resource_tc_tcr_service_account.go +++ b/tencentcloud/services/tcr/resource_tc_tcr_service_account.go @@ -107,14 +107,14 @@ func resourceTencentCloudTcrServiceAccountCreate(d *schema.ResourceData, meta in defer tccommon.LogElapsed("resource.tencentcloud_tcr_service_account.create")() defer tccommon.InconsistentCheck(d, meta)() - logId := tccommon.GetLogId(tccommon.ContextNil) - var ( + logId = tccommon.GetLogId(tccommon.ContextNil) request = tcr.NewCreateServiceAccountRequest() response = tcr.NewCreateServiceAccountResponse() registryId string name string ) + if v, ok := d.GetOk("registry_id"); ok { request.RegistryId = helper.String(v.(string)) registryId = v.(string) @@ -132,6 +132,7 @@ func resourceTencentCloudTcrServiceAccountCreate(d *schema.ResourceData, meta in if v, ok := dMap["resource"]; ok { permission.Resource = helper.String(v.(string)) } + if v, ok := dMap["actions"]; ok { actionsSet := v.(*schema.Set).List() for i := range actionsSet { @@ -141,6 +142,7 @@ func resourceTencentCloudTcrServiceAccountCreate(d *schema.ResourceData, meta in } } } + request.Permissions = append(request.Permissions, &permission) } } @@ -168,23 +170,33 @@ func resourceTencentCloudTcrServiceAccountCreate(d *schema.ResourceData, meta in } else { log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) } + + if result == nil || result.Response == nil { + return resource.NonRetryableError(fmt.Errorf("Create tcr ServiceAccount failed, Response is nil.")) + } + response = result return nil }) + if err != nil { log.Printf("[CRITAL]%s create tcr ServiceAccount failed, reason:%+v", logId, err) return err } + if response.Response.Name == nil { + return fmt.Errorf("Name is nil.") + } + if !strings.Contains(*response.Response.Name, name) { return fmt.Errorf("The name[%s] return from response is not equal to the name[%s] of tf code.", *response.Response.Name, name) } d.SetId(strings.Join([]string{registryId, name}, tccommon.FILED_SP)) - pw := response.Response.Password - if pw != nil { - _ = d.Set("password", *pw) + var deafultPwd string + if response.Response.Password != nil { + deafultPwd = *response.Response.Password } ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) @@ -197,13 +209,17 @@ func resourceTencentCloudTcrServiceAccountCreate(d *schema.ResourceData, meta in } } - service := TCRService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} - if v, ok := d.GetOk("password"); ok { + // set custom password OR set default password + if v, ok := d.GetOk("password"); ok && v.(string) != "" { + service := TCRService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} password, err := service.ModifyServiceAccountPassword(ctx, registryId, name, v.(string)) if err != nil { return err } + _ = d.Set("password", password) + } else { + _ = d.Set("password", deafultPwd) } return resourceTencentCloudTcrServiceAccountRead(d, meta) @@ -213,16 +229,17 @@ func resourceTencentCloudTcrServiceAccountRead(d *schema.ResourceData, meta inte defer tccommon.LogElapsed("resource.tencentcloud_tcr_service_account.read")() defer tccommon.InconsistentCheck(d, meta)() - logId := tccommon.GetLogId(tccommon.ContextNil) - - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - - service := TCRService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + var ( + logId = tccommon.GetLogId(tccommon.ContextNil) + ctx = context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + service = TCRService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + ) idSplit := strings.Split(d.Id(), tccommon.FILED_SP) if len(idSplit) != 2 { return fmt.Errorf("id is broken,%s", d.Id()) } + registryId := idSplit[0] name := idSplit[1] @@ -232,8 +249,8 @@ func resourceTencentCloudTcrServiceAccountRead(d *schema.ResourceData, meta inte } if ServiceAccount == nil { + log.Printf("[WARN]%s resource `tencentcloud_tcr_service_account` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) d.SetId("") - log.Printf("[WARN]%s resource `TcrServiceAccount` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) return nil } @@ -244,7 +261,6 @@ func resourceTencentCloudTcrServiceAccountRead(d *schema.ResourceData, meta inte permissionsList := []interface{}{} for _, permission := range ServiceAccount.Permissions { permissionsMap := map[string]interface{}{} - if permission.Resource != nil { permissionsMap["resource"] = permission.Resource } @@ -257,7 +273,6 @@ func resourceTencentCloudTcrServiceAccountRead(d *schema.ResourceData, meta inte } _ = d.Set("permissions", permissionsList) - } if ServiceAccount.Description != nil { @@ -287,31 +302,38 @@ func resourceTencentCloudTcrServiceAccountUpdate(d *schema.ResourceData, meta in defer tccommon.LogElapsed("resource.tencentcloud_tcr_service_account.update")() defer tccommon.InconsistentCheck(d, meta)() - logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - service := TCRService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} - - request := tcr.NewModifyServiceAccountRequest() + var ( + logId = tccommon.GetLogId(tccommon.ContextNil) + ctx = context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + service = TCRService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + ) idSplit := strings.Split(d.Id(), tccommon.FILED_SP) if len(idSplit) != 2 { return fmt.Errorf("id is broken,%s", d.Id()) } + registryId := idSplit[0] name := idSplit[1] - request.RegistryId = ®istryId - request.Name = helper.String(TCR_NAME_PREFIX + name) - immutableArgs := []string{"registry_id", "name"} - for _, v := range immutableArgs { if d.HasChange(v) { return fmt.Errorf("argument `%s` cannot be changed", v) } } - if d.HasChange("permissions") { + needChange := false + mutableArgs := []string{"permissions", "description", "duration", "expires_at", "disable"} + for _, v := range mutableArgs { + if d.HasChange(v) { + needChange = true + break + } + } + + if needChange { + request := tcr.NewModifyServiceAccountRequest() if v, ok := d.GetOk("permissions"); ok { for _, item := range v.([]interface{}) { permission := tcr.Permission{} @@ -319,6 +341,7 @@ func resourceTencentCloudTcrServiceAccountUpdate(d *schema.ResourceData, meta in if v, ok := dMap["resource"]; ok { permission.Resource = helper.String(v.(string)) } + if v, ok := dMap["actions"]; ok { actionsSet := v.(*schema.Set).List() for i := range actionsSet { @@ -331,44 +354,40 @@ func resourceTencentCloudTcrServiceAccountUpdate(d *schema.ResourceData, meta in request.Permissions = append(request.Permissions, &permission) } } - } - if d.HasChange("description") { if v, ok := d.GetOk("description"); ok { request.Description = helper.String(v.(string)) } - } - if d.HasChange("duration") { if v, ok := d.GetOkExists("duration"); ok { request.Duration = helper.IntInt64(v.(int)) } - } - if d.HasChange("expires_at") { if v, ok := d.GetOkExists("expires_at"); ok { request.ExpiresAt = helper.IntInt64(v.(int)) } - } - if d.HasChange("disable") { if v, ok := d.GetOkExists("disable"); ok { request.Disable = helper.Bool(v.(bool)) } - } - err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseTCRClient().ModifyServiceAccount(request) - if e != nil { - return tccommon.RetryError(e) - } else { - log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) + request.RegistryId = ®istryId + request.Name = helper.String(TCR_NAME_PREFIX + name) + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseTCRClient().ModifyServiceAccount(request) + if e != nil { + return tccommon.RetryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) + } + + return nil + }) + + if err != nil { + log.Printf("[CRITAL]%s update tcr ServiceAccount failed, reason:%+v", logId, err) + return err } - return nil - }) - if err != nil { - log.Printf("[CRITAL]%s update tcr ServiceAccount failed, reason:%+v", logId, err) - return err } if d.HasChange("tags") { @@ -389,9 +408,11 @@ func resourceTencentCloudTcrServiceAccountUpdate(d *schema.ResourceData, meta in if err != nil { return err } + _ = d.Set("password", password) } } + return resourceTencentCloudTcrServiceAccountRead(d, meta) } @@ -399,14 +420,17 @@ func resourceTencentCloudTcrServiceAccountDelete(d *schema.ResourceData, meta in defer tccommon.LogElapsed("resource.tencentcloud_tcr_service_account.delete")() defer tccommon.InconsistentCheck(d, meta)() - logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + var ( + logId = tccommon.GetLogId(tccommon.ContextNil) + ctx = context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + service = TCRService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + ) - service := TCRService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} idSplit := strings.Split(d.Id(), tccommon.FILED_SP) if len(idSplit) != 2 { return fmt.Errorf("id is broken,%s", d.Id()) } + registryId := idSplit[0] name := TCR_NAME_PREFIX + idSplit[1] diff --git a/tencentcloud/services/tcr/resource_tc_tcr_service_account.md b/tencentcloud/services/tcr/resource_tc_tcr_service_account.md index 6175702aed..735ec1076a 100644 --- a/tencentcloud/services/tcr/resource_tc_tcr_service_account.md +++ b/tencentcloud/services/tcr/resource_tc_tcr_service_account.md @@ -1,4 +1,4 @@ -Provides a resource to create a tcr service account. +Provides a resource to create a TCR service account. Example Usage @@ -6,29 +6,26 @@ Create custom account with specified duration days ```hcl resource "tencentcloud_tcr_instance" "example" { - name = "tf-example-tcr-instance" - instance_type = "basic" + name = "tf-example" + instance_type = "standard" delete_bucket = true tags = { - "createdBy" = "terraform" + createdBy = "Terraform" } } resource "tencentcloud_tcr_namespace" "example" { instance_id = tencentcloud_tcr_instance.example.id - name = "tf_test_tcr_namespace" + name = "tf-example" is_public = true is_auto_scan = true is_prevent_vul = true severity = "medium" - cve_whitelist_items { - cve_id = "tf_example_cve_id" - } } resource "tencentcloud_tcr_service_account" "example" { registry_id = tencentcloud_tcr_instance.example.id - name = "tf_example_account" + name = "tf-example" permissions { resource = tencentcloud_tcr_namespace.example.name actions = ["tcr:PushRepository", "tcr:PullRepository"] @@ -36,8 +33,9 @@ resource "tencentcloud_tcr_service_account" "example" { description = "tf example for tcr custom account" duration = 10 disable = false + password = "Password123" tags = { - "createdBy" = "terraform" + createdBy = "Terraform" } } ``` @@ -47,7 +45,7 @@ With specified expiration time ```hcl resource "tencentcloud_tcr_service_account" "example" { registry_id = tencentcloud_tcr_instance.example.id - name = "tf_example_account" + name = "tf-example" permissions { resource = tencentcloud_tcr_namespace.example.name actions = ["tcr:PushRepository", "tcr:PullRepository"] @@ -56,15 +54,15 @@ resource "tencentcloud_tcr_service_account" "example" { expires_at = 1676897989000 //time stamp disable = false tags = { - "createdBy" = "terraform" + createdBy = "Terraform" } } ``` Import -tcr service_account can be imported using the id, e.g. +TCR service account can be imported using the registryId#accountName, e.g. ``` -terraform import tencentcloud_tcr_service_account.service_account registry_id#account_name +terraform import tencentcloud_tcr_service_account.example tcr-ixgt2l0z#tf-example ``` \ No newline at end of file diff --git a/website/docs/r/tcr_service_account.html.markdown b/website/docs/r/tcr_service_account.html.markdown index 48edb208b4..4d5a84fa06 100644 --- a/website/docs/r/tcr_service_account.html.markdown +++ b/website/docs/r/tcr_service_account.html.markdown @@ -4,12 +4,12 @@ layout: "tencentcloud" page_title: "TencentCloud: tencentcloud_tcr_service_account" sidebar_current: "docs-tencentcloud-resource-tcr_service_account" description: |- - Provides a resource to create a tcr service account. + Provides a resource to create a TCR service account. --- # tencentcloud_tcr_service_account -Provides a resource to create a tcr service account. +Provides a resource to create a TCR service account. ## Example Usage @@ -17,29 +17,26 @@ Provides a resource to create a tcr service account. ```hcl resource "tencentcloud_tcr_instance" "example" { - name = "tf-example-tcr-instance" - instance_type = "basic" + name = "tf-example" + instance_type = "standard" delete_bucket = true tags = { - "createdBy" = "terraform" + createdBy = "Terraform" } } resource "tencentcloud_tcr_namespace" "example" { instance_id = tencentcloud_tcr_instance.example.id - name = "tf_test_tcr_namespace" + name = "tf-example" is_public = true is_auto_scan = true is_prevent_vul = true severity = "medium" - cve_whitelist_items { - cve_id = "tf_example_cve_id" - } } resource "tencentcloud_tcr_service_account" "example" { registry_id = tencentcloud_tcr_instance.example.id - name = "tf_example_account" + name = "tf-example" permissions { resource = tencentcloud_tcr_namespace.example.name actions = ["tcr:PushRepository", "tcr:PullRepository"] @@ -47,8 +44,9 @@ resource "tencentcloud_tcr_service_account" "example" { description = "tf example for tcr custom account" duration = 10 disable = false + password = "Password123" tags = { - "createdBy" = "terraform" + createdBy = "Terraform" } } ``` @@ -58,7 +56,7 @@ resource "tencentcloud_tcr_service_account" "example" { ```hcl resource "tencentcloud_tcr_service_account" "example" { registry_id = tencentcloud_tcr_instance.example.id - name = "tf_example_account" + name = "tf-example" permissions { resource = tencentcloud_tcr_namespace.example.name actions = ["tcr:PushRepository", "tcr:PullRepository"] @@ -67,7 +65,7 @@ resource "tencentcloud_tcr_service_account" "example" { expires_at = 1676897989000 //time stamp disable = false tags = { - "createdBy" = "terraform" + createdBy = "Terraform" } } ``` @@ -101,9 +99,9 @@ In addition to all arguments above, the following attributes are exported: ## Import -tcr service_account can be imported using the id, e.g. +TCR service account can be imported using the registryId#accountName, e.g. ``` -terraform import tencentcloud_tcr_service_account.service_account registry_id#account_name +terraform import tencentcloud_tcr_service_account.example tcr-ixgt2l0z#tf-example ```