From 603a3e2809794da88483b7d6cb9b75ec7b71cace Mon Sep 17 00:00:00 2001 From: nickyinluo Date: Fri, 28 Apr 2023 15:33:06 +0800 Subject: [PATCH 1/6] support resource: tencentcloud_tcr_customized_domain --- tencentcloud/basic_test.go | 2 + tencentcloud/provider.go | 2 + .../resource_tc_tcr_customized_domain.go | 215 ++++++++++++++++++ .../resource_tc_tcr_customized_domain_test.go | 90 ++++++++ tencentcloud/service_tencentcloud_tcr.go | 78 +++++++ .../r/tcr_customized_domain.html.markdown | 51 +++++ website/tencentcloud.erb | 3 + 7 files changed, 441 insertions(+) create mode 100644 tencentcloud/resource_tc_tcr_customized_domain.go create mode 100644 tencentcloud/resource_tc_tcr_customized_domain_test.go create mode 100644 website/docs/r/tcr_customized_domain.html.markdown diff --git a/tencentcloud/basic_test.go b/tencentcloud/basic_test.go index 2ce5c68620..1cb93f0dc9 100644 --- a/tencentcloud/basic_test.go +++ b/tencentcloud/basic_test.go @@ -546,8 +546,10 @@ variable "cam_user_basic" { // TCR Service const defaultTCRInstanceName = "keep-tcr-instance" +const defaultTCRInstanceId = "tcr-e79o580i" const defaultTCRNamespace = "keep-tcr-namespace" const defaultTCRRepoName = "keep-tcr-repo" +const defaultTCRSSL = "0a5zD3cN" const defaultTCRInstanceVar = ` variable "tcr_name" { diff --git a/tencentcloud/provider.go b/tencentcloud/provider.go index 4d1e7504d2..646d7a0920 100644 --- a/tencentcloud/provider.go +++ b/tencentcloud/provider.go @@ -635,6 +635,7 @@ Tencent Container Registry(TCR) tencentcloud_tcr_tag_retention_rule tencentcloud_tcr_webhook_trigger tencentcloud_tcr_manage_replication_operation + tencentcloud_tcr_customized_domain Video on Demand(VOD) Data Source @@ -1725,6 +1726,7 @@ func Provider() terraform.ResourceProvider { "tencentcloud_tcr_tag_retention_rule": resourceTencentCloudTcrTagRetentionRule(), "tencentcloud_tcr_webhook_trigger": resourceTencentCloudTcrWebhookTrigger(), "tencentcloud_tcr_manage_replication_operation": resourceTencentCloudTcrManageReplicationOperation(), + "tencentcloud_tcr_customized_domain": resourceTencentCloudTcrCustomizedDomain(), "tencentcloud_tdmq_instance": resourceTencentCloudTdmqInstance(), "tencentcloud_tdmq_namespace": resourceTencentCloudTdmqNamespace(), "tencentcloud_tdmq_topic": resourceTencentCloudTdmqTopic(), diff --git a/tencentcloud/resource_tc_tcr_customized_domain.go b/tencentcloud/resource_tc_tcr_customized_domain.go new file mode 100644 index 0000000000..c9daaadde1 --- /dev/null +++ b/tencentcloud/resource_tc_tcr_customized_domain.go @@ -0,0 +1,215 @@ +/* +Provides a resource to create a tcr customized_domain + +Example Usage + +```hcl +resource "tencentcloud_tcr_customized_domain" "my_domain" { + registry_id = local.tcr_id + domain_name = "www.test.com" + certificate_id = "%s" + tags = { + "createdBy" = "terraform" + } +} +``` + +Import + +tcr customized_domain can be imported using the id, e.g. + +``` +terraform import tencentcloud_tcr_customized_domain.customized_domain customized_domain_id +``` +*/ +package tencentcloud + +import ( + "context" + "fmt" + "log" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + tcr "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tcr/v20190924" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" +) + +func resourceTencentCloudTcrCustomizedDomain() *schema.Resource { + return &schema.Resource{ + Create: resourceTencentCloudTcrCustomizedDomainCreate, + Read: resourceTencentCloudTcrCustomizedDomainRead, + Delete: resourceTencentCloudTcrCustomizedDomainDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ + "registry_id": { + Required: true, + ForceNew: true, + Type: schema.TypeString, + Description: "instance id.", + }, + + "domain_name": { + Required: true, + ForceNew: true, + Type: schema.TypeString, + Description: "custom domain name.", + }, + + "certificate_id": { + Required: true, + ForceNew: true, + Type: schema.TypeString, + Description: "certificate id.", + }, + + "tags": { + Optional: true, + ForceNew: true, + Type: schema.TypeMap, + Description: "Tag description list.", + }, + }, + } +} + +func resourceTencentCloudTcrCustomizedDomainCreate(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_tcr_customized_domain.create")() + defer inconsistentCheck(d, meta)() + + logId := getLogId(contextNil) + + var ( + request = tcr.NewCreateInstanceCustomizedDomainRequest() + registryId string + domainName string + ) + if v, ok := d.GetOk("registry_id"); ok { + registryId = v.(string) + request.RegistryId = helper.String(v.(string)) + } + + if v, ok := d.GetOk("domain_name"); ok { + domainName = v.(string) + request.DomainName = helper.String(v.(string)) + } + + if v, ok := d.GetOk("certificate_id"); ok { + request.CertificateId = helper.String(v.(string)) + } + + err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + result, e := meta.(*TencentCloudClient).apiV3Conn.UseTCRClient().CreateInstanceCustomizedDomain(request) + if e != nil { + return 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 create tcr CustomizedDomain failed, reason:%+v", logId, err) + return err + } + + d.SetId(strings.Join([]string{registryId, domainName}, FILED_SP)) + + service := TCRService{client: meta.(*TencentCloudClient).apiV3Conn} + + conf := BuildStateChangeConf([]string{}, []string{"SUCCESS"}, 2*readRetryTimeout, time.Second, service.TcrCustomizedDomainStateRefreshFunc(registryId, domainName, []string{})) + + if _, e := conf.WaitForState(); e != nil { + return e + } + + ctx := context.WithValue(context.TODO(), logIdKey, logId) + if tags := helper.GetTags(d, "tags"); len(tags) > 0 { + tagService := TagService{client: meta.(*TencentCloudClient).apiV3Conn} + region := meta.(*TencentCloudClient).apiV3Conn.Region + resourceName := fmt.Sprintf("qcs::tcr:%s:uin/:instance/%s", region, d.Id()) + if err := tagService.ModifyTags(ctx, resourceName, tags, nil); err != nil { + return err + } + } + + return resourceTencentCloudTcrCustomizedDomainRead(d, meta) +} + +func resourceTencentCloudTcrCustomizedDomainRead(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_tcr_customized_domain.read")() + defer inconsistentCheck(d, meta)() + + logId := getLogId(contextNil) + + ctx := context.WithValue(context.TODO(), logIdKey, logId) + + service := TCRService{client: meta.(*TencentCloudClient).apiV3Conn} + + idSplit := strings.Split(d.Id(), FILED_SP) + if len(idSplit) != 2 { + return fmt.Errorf("id is broken,%s", d.Id()) + } + registryId := idSplit[0] + domainName := idSplit[1] + + domains, err := service.DescribeTcrCustomizedDomainById(ctx, registryId, &domainName) + if err != nil { + return err + } + + if len(domains) == 0 { + d.SetId("") + log.Printf("[WARN]%s resource `TcrCustomizedDomain` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) + return nil + } + + CustomizedDomain := domains[0] + + if CustomizedDomain.RegistryId != nil { + _ = d.Set("registry_id", CustomizedDomain.RegistryId) + } + + if CustomizedDomain.DomainName != nil { + _ = d.Set("domain_name", CustomizedDomain.DomainName) + } + + if CustomizedDomain.CertId != nil { + _ = d.Set("certificate_id", CustomizedDomain.CertId) + } + + tcClient := meta.(*TencentCloudClient).apiV3Conn + tagService := &TagService{client: tcClient} + tags, err := tagService.DescribeResourceTags(ctx, "tcr", "instance", tcClient.Region, d.Id()) + if err != nil { + return err + } + _ = d.Set("tags", tags) + + return nil +} + +func resourceTencentCloudTcrCustomizedDomainDelete(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_tcr_customized_domain.delete")() + defer inconsistentCheck(d, meta)() + + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), logIdKey, logId) + + service := TCRService{client: meta.(*TencentCloudClient).apiV3Conn} + idSplit := strings.Split(d.Id(), FILED_SP) + if len(idSplit) != 2 { + return fmt.Errorf("id is broken,%s", d.Id()) + } + registryId := idSplit[0] + domainName := idSplit[1] + + if err := service.DeleteTcrCustomizedDomainById(ctx, registryId, domainName); err != nil { + return err + } + + return nil +} diff --git a/tencentcloud/resource_tc_tcr_customized_domain_test.go b/tencentcloud/resource_tc_tcr_customized_domain_test.go new file mode 100644 index 0000000000..6f16ce647e --- /dev/null +++ b/tencentcloud/resource_tc_tcr_customized_domain_test.go @@ -0,0 +1,90 @@ +package tencentcloud + +import ( + "context" + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +func init() { + resource.AddTestSweepers("tencentcloud_tcr_customized_domain", &resource.Sweeper{ + Name: "tencentcloud_tcr_customized_domain", + F: testSweepTcrCustomizedDomain, + }) +} + +// go test -v ./tencentcloud -sweep=ap-guangzhou -sweep-run=tencentcloud_tcr_customized_domain +func testSweepTcrCustomizedDomain(r string) error { + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), logIdKey, logId) + cli, _ := sharedClientForRegion(r) + tcrService := TCRService{client: cli.(*TencentCloudClient).apiV3Conn} + + domains, err := tcrService.DescribeTcrCustomizedDomainById(ctx, defaultTCRInstanceId, nil) + if err != nil { + return err + } + if domains == nil { + return fmt.Errorf("tcr customize domain instance not exists.") + } + + for _, v := range domains { + delName := *v.DomainName + + if strings.HasPrefix(delName, "test") { + err := resource.Retry(readRetryTimeout, func() *resource.RetryError { + err := tcrService.DeleteTcrCustomizedDomainById(ctx, defaultTCRInstanceId, delName) + if err != nil { + return retryError(err) + } + return nil + }) + if err != nil { + return fmt.Errorf("[ERROR] delete tcr customize domain instance %s failed! reason:[%s]", delName, err.Error()) + } + } + } + return nil +} + +func TestAccTencentCloudTcrCustomizedDomainResource_basic(t *testing.T) { + t.Parallel() + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: fmt.Sprintf(testAccTcrCustomizedDomain, defaultTCRSSL), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("tencentcloud_tcr_customized_domain.my_domain", "id"), + resource.TestCheckResourceAttrSet("tencentcloud_tcr_customized_domain.my_domain", "registry_id"), + resource.TestCheckResourceAttr("tencentcloud_tcr_customized_domain.my_domain", "domain_name", "www.test.com"), + resource.TestCheckResourceAttr("tencentcloud_tcr_customized_domain.my_domain", "certificate_id", defaultTCRSSL), + ), + }, + { + ResourceName: "tencentcloud_tcr_customized_domain.my_domain", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +const testAccTcrCustomizedDomain = defaultTCRInstanceData + ` + +resource "tencentcloud_tcr_customized_domain" "my_domain" { + registry_id = local.tcr_id + domain_name = "www.test.com" + certificate_id = "%s" + tags = { + "createdBy" = "terraform" + } +} + +` diff --git a/tencentcloud/service_tencentcloud_tcr.go b/tencentcloud/service_tencentcloud_tcr.go index bb0ce0ac03..264bb186ba 100644 --- a/tencentcloud/service_tencentcloud_tcr.go +++ b/tencentcloud/service_tencentcloud_tcr.go @@ -1214,3 +1214,81 @@ func (me *TCRService) DescribeTcrWebhookTriggerLogByFilter(ctx context.Context, return } + +func (me *TCRService) DescribeTcrCustomizedDomainById(ctx context.Context, registryId string, domainName *string) (CustomizedDomain []*tcr.CustomizedDomainInfo, errRet error) { + logId := getLogId(ctx) + + request := tcr.NewDescribeInstanceCustomizedDomainRequest() + request.RegistryId = ®istryId + + defer func() { + if errRet != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), errRet.Error()) + } + }() + + ratelimit.Check(request.GetAction()) + + response, err := me.client.UseTCRClient().DescribeInstanceCustomizedDomain(request) + if err != nil { + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + if len(response.Response.DomainInfoList) < 1 { + return + } + + if domainName != nil { + for _, domain := range response.Response.DomainInfoList { + if *domain.DomainName == *domainName { + CustomizedDomain = []*tcr.CustomizedDomainInfo{domain} + return + } + } + } else { + CustomizedDomain = response.Response.DomainInfoList + } + + return +} + +func (me *TCRService) DeleteTcrCustomizedDomainById(ctx context.Context, registryId string, domainName string) (errRet error) { + logId := getLogId(ctx) + + request := tcr.NewDeleteInstanceCustomizedDomainRequest() + request.RegistryId = ®istryId + request.DomainName = &domainName + + defer func() { + if errRet != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), errRet.Error()) + } + }() + + ratelimit.Check(request.GetAction()) + + response, err := me.client.UseTCRClient().DeleteInstanceCustomizedDomain(request) + if err != nil { + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + return +} + +func (me *TCRService) TcrCustomizedDomainStateRefreshFunc(registryId, domainName string, failStates []string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + ctx := contextNil + + object, err := me.DescribeTcrCustomizedDomainById(ctx, registryId, &domainName) + + if err != nil { + return nil, "", err + } + + return object, helper.PString(object[0].Status), nil + } +} diff --git a/website/docs/r/tcr_customized_domain.html.markdown b/website/docs/r/tcr_customized_domain.html.markdown new file mode 100644 index 0000000000..ea59dceecf --- /dev/null +++ b/website/docs/r/tcr_customized_domain.html.markdown @@ -0,0 +1,51 @@ +--- +subcategory: "Tencent Container Registry(TCR)" +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_tcr_customized_domain" +sidebar_current: "docs-tencentcloud-resource-tcr_customized_domain" +description: |- + Provides a resource to create a tcr customized_domain +--- + +# tencentcloud_tcr_customized_domain + +Provides a resource to create a tcr customized_domain + +## Example Usage + +```hcl +resource "tencentcloud_tcr_customized_domain" "my_domain" { + registry_id = local.tcr_id + domain_name = "www.test.com" + certificate_id = "%s" + tags = { + "createdBy" = "terraform" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `certificate_id` - (Required, String, ForceNew) certificate id. +* `domain_name` - (Required, String, ForceNew) custom domain name. +* `registry_id` - (Required, String, ForceNew) instance id. +* `tags` - (Optional, Map, ForceNew) Tag description list. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - ID of the resource. + + + +## Import + +tcr customized_domain can be imported using the id, e.g. + +``` +terraform import tencentcloud_tcr_customized_domain.customized_domain customized_domain_id +``` + diff --git a/website/tencentcloud.erb b/website/tencentcloud.erb index 2fc9a9848f..c95d482c2f 100644 --- a/website/tencentcloud.erb +++ b/website/tencentcloud.erb @@ -2208,6 +2208,9 @@
  • Resources