From 9f963ba3a9ae7a85795200e5973d86da54a0c2ca Mon Sep 17 00:00:00 2001 From: tongyiming <1290863722@qq.com> Date: Fri, 5 Jul 2024 20:32:17 +0800 Subject: [PATCH] feat(es): [118247615]support es kibana switch (#2708) * support es kibana switch * add changelog * update * update * update --------- Co-authored-by: mikatong --- .changelog/2708.txt | 3 + tencentcloud/acctest/basic.go | 14 +++ .../services/es/extension_elasticsearch.go | 8 ++ .../es/resource_tc_elasticsearch_instance.go | 85 +++++++++++++++---- ...resource_tc_elasticsearch_instance_test.go | 74 ++++++++++++++-- .../es/service_tencentcloud_elasticsearch.go | 5 +- .../r/elasticsearch_instance.html.markdown | 1 + 7 files changed, 169 insertions(+), 21 deletions(-) create mode 100644 .changelog/2708.txt diff --git a/.changelog/2708.txt b/.changelog/2708.txt new file mode 100644 index 0000000000..44937d8c69 --- /dev/null +++ b/.changelog/2708.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/tencentcloud_elasticsearch_instance: support es kibana switch +``` diff --git a/tencentcloud/acctest/basic.go b/tencentcloud/acctest/basic.go index 5eb5cce9b3..2313184478 100644 --- a/tencentcloud/acctest/basic.go +++ b/tencentcloud/acctest/basic.go @@ -1148,6 +1148,8 @@ const ( DefaultEsInstanceId = "es-5wn36he6" DefaultEsSecurityGroup = "sg-edmur627" DefaultEsLogstash = "ls-kru90fkz" + DefaultEsVpcId = "vpc-lrj71tt3" + DefaultEsSubnetId = "subnet-kggvos8o" ) const DefaultEsVariables = ` @@ -1162,6 +1164,18 @@ variable "security_group_id" { variable "logstash_id" { default = "` + DefaultEsLogstash + `" } + +variable "availability_zone" { + default = "ap-guangzhou-3" +} + +variable "vpc_id" { + default = "` + DefaultEsVpcId + `" +} + +variable "subnet_id" { + default = "` + DefaultEsSubnetId + `" +} ` // End of TSE diff --git a/tencentcloud/services/es/extension_elasticsearch.go b/tencentcloud/services/es/extension_elasticsearch.go index a7832e65e6..0ac8c49dde 100644 --- a/tencentcloud/services/es/extension_elasticsearch.go +++ b/tencentcloud/services/es/extension_elasticsearch.go @@ -31,6 +31,9 @@ const ( ES_INSTANCE_STATUS_STOP = -1 ES_INSTANCE_STATUS_DESTROYING = -2 ES_INSTANCE_STATUS_DESTROYED = -3 + + ES_KIBANA_PUBLIC_ACCESS_OPEN = "OPEN" + ES_KIBANA_PUBLIC_ACCESS_CLOSE = "CLOSE" ) var ES_CHARGE_TYPE = []string{ @@ -70,3 +73,8 @@ var ES_RENEW_FLAG = []string{ ES_RENEW_FLAG_AUTO, ES_RENEW_FLAG_MANUAL, } + +var ES_KIBANA_PUBLIC_ACCESS = []string{ + ES_KIBANA_PUBLIC_ACCESS_OPEN, + ES_KIBANA_PUBLIC_ACCESS_CLOSE, +} diff --git a/tencentcloud/services/es/resource_tc_elasticsearch_instance.go b/tencentcloud/services/es/resource_tc_elasticsearch_instance.go index 62f464591c..4e27f2ee99 100644 --- a/tencentcloud/services/es/resource_tc_elasticsearch_instance.go +++ b/tencentcloud/services/es/resource_tc_elasticsearch_instance.go @@ -126,6 +126,7 @@ func ResourceTencentCloudElasticsearchInstance() *schema.Resource { "web_node_type_info": { Type: schema.TypeList, Optional: true, + Computed: true, Description: "Visual node configuration.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -234,7 +235,13 @@ func ResourceTencentCloudElasticsearchInstance() *schema.Resource { Optional: true, Description: "A mapping of tags to assign to the instance. For tag limits, please refer to [Use Limits](https://intl.cloud.tencent.com/document/product/651/13354).", }, - + "kibana_public_access": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: tccommon.ValidateAllowedStringValue(ES_KIBANA_PUBLIC_ACCESS), + Description: "Kibana public network access status. Valid values are `OPEN` and `CLOSE`.", + }, // computed "elasticsearch_domain": { Type: schema.TypeString, @@ -412,6 +419,7 @@ func resourceTencentCloudElasticsearchInstanceCreate(d *schema.ResourceData, met return err } + var isUpdate bool // es acl esAcl := es.EsAcl{} if aclMap, ok := helper.InterfacesHeadMap(d, "es_acl"); ok { @@ -427,17 +435,31 @@ func resourceTencentCloudElasticsearchInstanceCreate(d *schema.ResourceData, met esAcl.WhiteIpList = append(esAcl.WhiteIpList, helper.String(d.(string))) } } + isUpdate = true } - err = resource.Retry(tccommon.WriteRetryTimeout*2, func() *resource.RetryError { - errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", 0, nil, nil, &esAcl) - if errRet != nil { - return tccommon.RetryError(errRet) + // KibanaPublicAccess + var kibanaPublicAccess string + if v, ok := d.GetOk("kibana_public_access"); ok { + kibanaPublicAccess = v.(string) + isUpdate = true + } + if isUpdate { + err = resource.Retry(tccommon.WriteRetryTimeout*2, func() *resource.RetryError { + errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", kibanaPublicAccess, 0, nil, nil, &esAcl) + if errRet != nil { + return tccommon.RetryError(errRet) + } + return nil + }) + if err != nil { + return err + } + + err = tencentCloudElasticsearchInstanceUpgradeWaiting(ctx, &elasticsearchService, instanceId) + if err != nil { + return err } - return nil - }) - if err != nil { - return err } // tags @@ -501,6 +523,7 @@ func resourceTencentCloudElasticsearchInstanceRead(d *schema.ResourceData, meta _ = d.Set("elasticsearch_port", instance.EsPort) _ = d.Set("kibana_url", instance.KibanaUrl) _ = d.Set("create_time", instance.CreateTime) + _ = d.Set("kibana_public_access", instance.KibanaPublicAccess) multiZoneInfos := make([]map[string]interface{}, 0, len(instance.MultiZoneInfo)) for _, item := range instance.MultiZoneInfo { @@ -572,7 +595,7 @@ func resourceTencentCloudElasticsearchInstanceUpdate(d *schema.ResourceData, met instanceName := d.Get("instance_name").(string) // Update operation support at most one item at the same time err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - errRet := elasticsearchService.UpdateInstance(ctx, instanceId, instanceName, "", 0, nil, nil, nil) + errRet := elasticsearchService.UpdateInstance(ctx, instanceId, instanceName, "", "", 0, nil, nil, nil) if errRet != nil { return tccommon.RetryError(errRet) } @@ -581,11 +604,15 @@ func resourceTencentCloudElasticsearchInstanceUpdate(d *schema.ResourceData, met if err != nil { return err } + err = tencentCloudElasticsearchInstanceUpgradeWaiting(ctx, &elasticsearchService, instanceId) + if err != nil { + return err + } } if d.HasChange("password") { password := d.Get("password").(string) err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", password, 0, nil, nil, nil) + errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", password, "", 0, nil, nil, nil) if errRet != nil { return tccommon.RetryError(errRet) } @@ -594,8 +621,32 @@ func resourceTencentCloudElasticsearchInstanceUpdate(d *schema.ResourceData, met if err != nil { return err } + err = tencentCloudElasticsearchInstanceUpgradeWaiting(ctx, &elasticsearchService, instanceId) + if err != nil { + return err + } } + // KibanaPublicAccess + if d.HasChange("kibana_public_access") { + if v, ok := d.GetOk("kibana_public_access"); ok { + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", v.(string), 0, nil, nil, nil) + if errRet != nil { + return tccommon.RetryError(errRet) + } + return nil + }) + if err != nil { + return err + } + err = tencentCloudElasticsearchInstanceUpgradeWaiting(ctx, &elasticsearchService, instanceId) + if err != nil { + return err + } + } + + } if d.HasChange("version") { version := d.Get("version").(string) err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { @@ -639,7 +690,7 @@ func resourceTencentCloudElasticsearchInstanceUpdate(d *schema.ResourceData, met licenseType := d.Get("license_type").(string) licenseTypeUpgrading := licenseType != "oss" err := resource.Retry(tccommon.WriteRetryTimeout*2, func() *resource.RetryError { - errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", int64(basicSecurityType), nil, nil, nil) + errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", "", int64(basicSecurityType), nil, nil, nil) if errRet != nil { err := errRet.(*sdkErrors.TencentCloudSDKError) if err.Code == es.INVALIDPARAMETER && licenseTypeUpgrading { @@ -670,7 +721,7 @@ func resourceTencentCloudElasticsearchInstanceUpdate(d *schema.ResourceData, met NodeType: helper.String(value["node_type"].(string)), } err = resource.Retry(tccommon.WriteRetryTimeout*2, func() *resource.RetryError { - errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", 0, nil, info, nil) + errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", "", 0, nil, info, nil) if errRet != nil { return tccommon.RetryError(errRet) } @@ -709,7 +760,7 @@ func resourceTencentCloudElasticsearchInstanceUpdate(d *schema.ResourceData, met nodeInfoList = append(nodeInfoList, &dataDisk) } err := resource.Retry(tccommon.WriteRetryTimeout*2, func() *resource.RetryError { - errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", 0, nodeInfoList, nil, nil) + errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", "", 0, nodeInfoList, nil, nil) if errRet != nil { return tccommon.RetryError(errRet) } @@ -760,7 +811,7 @@ func resourceTencentCloudElasticsearchInstanceUpdate(d *schema.ResourceData, met } err := resource.Retry(tccommon.WriteRetryTimeout*2, func() *resource.RetryError { - errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", 0, nil, nil, &esAcl) + errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", "", 0, nil, nil, &esAcl) if errRet != nil { return tccommon.RetryError(errRet) } @@ -769,6 +820,10 @@ func resourceTencentCloudElasticsearchInstanceUpdate(d *schema.ResourceData, met if err != nil { return err } + err = tencentCloudElasticsearchInstanceUpgradeWaiting(ctx, &elasticsearchService, instanceId) + if err != nil { + return err + } } d.Partial(false) diff --git a/tencentcloud/services/es/resource_tc_elasticsearch_instance_test.go b/tencentcloud/services/es/resource_tc_elasticsearch_instance_test.go index 6fda3a54df..188d476734 100644 --- a/tencentcloud/services/es/resource_tc_elasticsearch_instance_test.go +++ b/tencentcloud/services/es/resource_tc_elasticsearch_instance_test.go @@ -80,10 +80,10 @@ func TestAccTencentCloudElasticsearchInstanceResource_basic(t *testing.T) { resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.foo", "instance_name", "tf-ci-test"), resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.foo", "availability_zone", tcacctest.DefaultAZone), resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.foo", "version", "7.10.1"), - resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.foo", "vpc_id", tcacctest.DefaultVpcId), - resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.foo", "subnet_id", tcacctest.DefaultSubnetId), + resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.foo", "vpc_id", tcacctest.DefaultEsVpcId), + resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.foo", "subnet_id", tcacctest.DefaultEsSubnetId), resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.foo", "license_type", "basic"), - resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.foo", "basic_security_type", "1"), + resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.foo", "basic_security_type", "2"), resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.foo", "web_node_type_info.#", "1"), resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.foo", "web_node_type_info.0.node_num", "1"), resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.foo", "web_node_type_info.0.node_type", "ES.S1.MEDIUM4"), @@ -92,6 +92,7 @@ func TestAccTencentCloudElasticsearchInstanceResource_basic(t *testing.T) { resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.foo", "node_info_list.0.type", "hotData"), resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.foo", "node_info_list.0.encrypt", "false"), resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.foo", "tags.test", "terraform"), + resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.foo", "kibana_public_access", "OPEN"), ), }, { @@ -119,6 +120,31 @@ func TestAccTencentCloudElasticsearchInstanceResource_basic(t *testing.T) { }, }) } +func TestAccTencentCloudElasticsearchInstanceResource_kibanaPublicAccess(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { tcacctest.AccPreCheck(t) }, + Providers: tcacctest.AccProviders, + CheckDestroy: testAccCheckElasticsearchInstanceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccElasticsearchInstanceKibanaPublicAccessClose, + Check: resource.ComposeTestCheckFunc( + testAccCheckElasticsearchInstanceExists("tencentcloud_elasticsearch_instance.es_kibana"), + resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.es_kibana", "kibana_public_access", "CLOSE"), + ), + }, + { + Config: testAccElasticsearchInstanceKibanaPublicAccessOpen, + Check: resource.ComposeTestCheckFunc( + testAccCheckElasticsearchInstanceExists("tencentcloud_elasticsearch_instance.es_kibana"), + resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.es_kibana", "kibana_public_access", "OPEN"), + ), + }, + }, + }) +} func testAccCheckElasticsearchInstanceDestroy(s *terraform.State) error { logId := tccommon.GetLogId(tccommon.ContextNil) @@ -182,7 +208,7 @@ func testAccCheckElasticsearchInstanceExists(n string) resource.TestCheckFunc { } } -const testAccElasticsearchInstance = tcacctest.DefaultVpcVariable + ` +const testAccElasticsearchInstance = tcacctest.DefaultEsVariables + ` resource "tencentcloud_elasticsearch_instance" "foo" { instance_name = "tf-ci-test" availability_zone = var.availability_zone @@ -218,7 +244,7 @@ resource "tencentcloud_elasticsearch_instance" "foo" { } ` -const testAccElasticsearchInstanceUpdate = tcacctest.DefaultVpcVariable + ` +const testAccElasticsearchInstanceUpdate = tcacctest.DefaultEsVariables + ` resource "tencentcloud_elasticsearch_instance" "foo" { instance_name = "tf-ci-test-update" availability_zone = var.availability_zone @@ -253,3 +279,41 @@ resource "tencentcloud_elasticsearch_instance" "foo" { } } ` + +const testAccElasticsearchInstanceKibanaPublicAccessClose = tcacctest.DefaultEsVariables + ` +resource "tencentcloud_elasticsearch_instance" "es_kibana" { + instance_name = "tf-ci-test-kibana" + availability_zone = var.availability_zone + version = "7.10.1" + vpc_id = var.vpc_id + subnet_id = var.subnet_id + password = "Test1234" + license_type = "basic" + basic_security_type = 2 + kibana_public_access = "CLOSE" + + node_info_list { + node_num = 2 + node_type = "ES.S1.MEDIUM4" + } + } +` + +const testAccElasticsearchInstanceKibanaPublicAccessOpen = tcacctest.DefaultEsVariables + ` +resource "tencentcloud_elasticsearch_instance" "es_kibana" { + instance_name = "tf-ci-test-kibana" + availability_zone = var.availability_zone + version = "7.10.1" + vpc_id = var.vpc_id + subnet_id = var.subnet_id + password = "Test1234" + license_type = "basic" + basic_security_type = 2 + kibana_public_access = "OPEN" + + node_info_list { + node_num = 2 + node_type = "ES.S1.MEDIUM4" + } + } +` diff --git a/tencentcloud/services/es/service_tencentcloud_elasticsearch.go b/tencentcloud/services/es/service_tencentcloud_elasticsearch.go index cd06efca8a..1b2a75d8b2 100644 --- a/tencentcloud/services/es/service_tencentcloud_elasticsearch.go +++ b/tencentcloud/services/es/service_tencentcloud_elasticsearch.go @@ -107,7 +107,7 @@ func (me *ElasticsearchService) DeleteInstance(ctx context.Context, instanceId s } // UpdateInstance FIXME: use *Request instead of these suck params -func (me *ElasticsearchService) UpdateInstance(ctx context.Context, instanceId, instanceName, password string, basicSecurityType int64, nodeList []*es.NodeInfo, nodeTypeInfo *es.WebNodeTypeInfo, esAcl *es.EsAcl) error { +func (me *ElasticsearchService) UpdateInstance(ctx context.Context, instanceId, instanceName, password, kibanaPublicAccess string, basicSecurityType int64, nodeList []*es.NodeInfo, nodeTypeInfo *es.WebNodeTypeInfo, esAcl *es.EsAcl) error { logId := tccommon.GetLogId(ctx) request := es.NewUpdateInstanceRequest() request.InstanceId = &instanceId @@ -117,6 +117,9 @@ func (me *ElasticsearchService) UpdateInstance(ctx context.Context, instanceId, if password != "" { request.Password = &password } + if kibanaPublicAccess != "" { + request.KibanaPublicAccess = &kibanaPublicAccess + } if basicSecurityType > 0 { request.BasicSecurityType = &basicSecurityType } diff --git a/website/docs/r/elasticsearch_instance.html.markdown b/website/docs/r/elasticsearch_instance.html.markdown index dabb9fe193..9ad32b9b7e 100644 --- a/website/docs/r/elasticsearch_instance.html.markdown +++ b/website/docs/r/elasticsearch_instance.html.markdown @@ -166,6 +166,7 @@ The following arguments are supported: * `deploy_mode` - (Optional, Int, ForceNew) Cluster deployment mode. Valid values are `0` and `1`. `0` is single-AZ deployment, and `1` is multi-AZ deployment. Default value is `0`. * `es_acl` - (Optional, List) Kibana Access Control Configuration. * `instance_name` - (Optional, String) Name of the instance, which can contain 1 to 50 English letters, Chinese characters, digits, dashes(-), or underscores(_). +* `kibana_public_access` - (Optional, String) Kibana public network access status. Valid values are `OPEN` and `CLOSE`. * `license_type` - (Optional, String) License type. Valid values are `oss`, `basic` and `platinum`. The default value is `platinum`. * `multi_zone_infos` - (Optional, List, ForceNew) Details of AZs in multi-AZ deployment mode (which is required when deploy_mode is `1`). * `renew_flag` - (Optional, String, ForceNew) When enabled, the instance will be renew automatically when it reach the end of the prepaid tenancy. Valid values are `RENEW_FLAG_AUTO` and `RENEW_FLAG_MANUAL`. NOTE: it only works when charge_type is set to `PREPAID`.