diff --git a/.changelog/3381.txt b/.changelog/3381.txt new file mode 100644 index 0000000000..981cae90e8 --- /dev/null +++ b/.changelog/3381.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/tencentcloud_elasticsearch_instance: support kibana_private_access +``` \ No newline at end of file diff --git a/tencentcloud/services/es/extension_elasticsearch.go b/tencentcloud/services/es/extension_elasticsearch.go index b1b50d9324..d47d97cb69 100644 --- a/tencentcloud/services/es/extension_elasticsearch.go +++ b/tencentcloud/services/es/extension_elasticsearch.go @@ -36,6 +36,8 @@ const ( ES_KIBANA_PUBLIC_ACCESS_CLOSE = "CLOSE" ES_PUBLIC_ACCESS_OPEN = "OPEN" ES_PUBLIC_ACCESS_CLOSE = "CLOSE" + ES_PRIVATE_ACCESS_OPEN = "OPEN" + ES_PRIVATE_ACCESS_CLOSE = "CLOSE" ) var ES_CHARGE_TYPE = []string{ @@ -88,3 +90,8 @@ var ES_PUBLIC_ACCESS = []string{ ES_PUBLIC_ACCESS_OPEN, ES_PUBLIC_ACCESS_CLOSE, } + +var ES_PRIVATE_ACCESS = []string{ + ES_PRIVATE_ACCESS_OPEN, + ES_PRIVATE_ACCESS_CLOSE, +} diff --git a/tencentcloud/services/es/resource_tc_elasticsearch_instance.go b/tencentcloud/services/es/resource_tc_elasticsearch_instance.go index 47a07a6f2d..ae8a3264fd 100644 --- a/tencentcloud/services/es/resource_tc_elasticsearch_instance.go +++ b/tencentcloud/services/es/resource_tc_elasticsearch_instance.go @@ -242,6 +242,13 @@ func ResourceTencentCloudElasticsearchInstance() *schema.Resource { ValidateFunc: tccommon.ValidateAllowedStringValue(ES_KIBANA_PUBLIC_ACCESS), Description: "Kibana public network access status. Valid values are `OPEN` and `CLOSE`.", }, + "kibana_private_access": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: tccommon.ValidateAllowedStringValue(ES_PRIVATE_ACCESS), + Description: "Kibana private network access status. Valid values are `OPEN` and `CLOSE`.", + }, "cos_backup": { Type: schema.TypeList, Optional: true, @@ -456,6 +463,7 @@ func resourceTencentCloudElasticsearchInstanceCreate(d *schema.ResourceData, met //internal version: replace setTag begin, please do not modify this annotation and refrain from inserting any code between the beginning and end lines of the annotation. //internal version: replace setTag end, please do not modify this annotation and refrain from inserting any code between the beginning and end lines of the annotation. + var actualKibanaPrivateAccess string instanceEmptyRetries := 5 err = resource.Retry(15*tccommon.ReadRetryTimeout, func() *resource.RetryError { instance, errRet := elasticsearchService.DescribeInstanceById(ctx, instanceId) @@ -472,13 +480,15 @@ func resourceTencentCloudElasticsearchInstanceCreate(d *schema.ResourceData, met if *instance.Status != ES_INSTANCE_STATUS_NORMAL { return resource.RetryableError(fmt.Errorf("elasticsearch instance status is %v, retrying", *instance.Status)) } + if instance.KibanaPrivateAccess != nil { + actualKibanaPrivateAccess = *instance.KibanaPrivateAccess + } return nil }) if err != nil { return err } - var isUpdate bool // es acl esAcl := es.EsAcl{} if aclMap, ok := helper.InterfacesHeadMap(d, "es_acl"); ok { @@ -494,9 +504,24 @@ 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, 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 + } } + var isUpdate bool + // KibanaPublicAccess var kibanaPublicAccess string if v, ok := d.GetOk("kibana_public_access"); ok { @@ -508,9 +533,18 @@ func resourceTencentCloudElasticsearchInstanceCreate(d *schema.ResourceData, met } } + var kibanaPrivateAccess string + if v, ok := d.GetOk("kibana_private_access"); ok { + if actualKibanaPrivateAccess != "" && actualKibanaPrivateAccess != v.(string) { + kibanaPrivateAccess = 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, nil, nil) + errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", kibanaPublicAccess, kibanaPrivateAccess, "", 0, nil, nil, nil, nil, nil) if errRet != nil { return tccommon.RetryError(errRet) } @@ -556,7 +590,7 @@ func resourceTencentCloudElasticsearchInstanceCreate(d *schema.ResourceData, met if isUpdate { err = resource.Retry(tccommon.WriteRetryTimeout*2, func() *resource.RetryError { - errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", "", publicAccess, 0, nil, nil, nil, nil, &esPublicAcl) + errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", "", "", publicAccess, 0, nil, nil, nil, nil, &esPublicAcl) if errRet != nil { return tccommon.RetryError(errRet) } @@ -586,7 +620,7 @@ func resourceTencentCloudElasticsearchInstanceCreate(d *schema.ResourceData, met } err = resource.Retry(tccommon.WriteRetryTimeout*2, func() *resource.RetryError { - errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", "", "", 0, nil, nil, nil, &cosBackup, nil) + errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", "", "", "", 0, nil, nil, nil, &cosBackup, nil) if errRet != nil { return tccommon.RetryError(errRet) } @@ -666,6 +700,7 @@ func resourceTencentCloudElasticsearchInstanceRead(d *schema.ResourceData, meta _ = d.Set("kibana_url", instance.KibanaUrl) _ = d.Set("create_time", instance.CreateTime) _ = d.Set("kibana_public_access", instance.KibanaPublicAccess) + _ = d.Set("kibana_private_access", instance.KibanaPrivateAccess) multiZoneInfos := make([]map[string]interface{}, 0, len(instance.MultiZoneInfo)) for _, item := range instance.MultiZoneInfo { @@ -770,7 +805,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, nil, nil) + errRet := elasticsearchService.UpdateInstance(ctx, instanceId, instanceName, "", "", "", "", 0, nil, nil, nil, nil, nil) if errRet != nil { return tccommon.RetryError(errRet) } @@ -787,7 +822,7 @@ func resourceTencentCloudElasticsearchInstanceUpdate(d *schema.ResourceData, met 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, nil, nil) + errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", password, "", "", "", 0, nil, nil, nil, nil, nil) if errRet != nil { return tccommon.RetryError(errRet) } @@ -806,7 +841,27 @@ func resourceTencentCloudElasticsearchInstanceUpdate(d *schema.ResourceData, met 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, nil, nil) + errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", v.(string), "", "", 0, nil, nil, 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 + } + } + + } + // KibanaPrivateAccess + if d.HasChange("kibana_private_access") { + if v, ok := d.GetOk("kibana_private_access"); ok { + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", "", v.(string), "", 0, nil, nil, nil, nil, nil) if errRet != nil { return tccommon.RetryError(errRet) } @@ -865,7 +920,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, nil, nil) + errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", "", "", "", int64(basicSecurityType), nil, nil, nil, nil, nil) if errRet != nil { err := errRet.(*sdkErrors.TencentCloudSDKError) if err.Code == es.INVALIDPARAMETER && licenseTypeUpgrading { @@ -896,7 +951,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, nil, nil) + errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", "", "", "", 0, nil, info, nil, nil, nil) if errRet != nil { return tccommon.RetryError(errRet) } @@ -935,7 +990,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, nil, nil) + errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", "", "", "", 0, nodeInfoList, nil, nil, nil, nil) if errRet != nil { return tccommon.RetryError(errRet) } @@ -972,7 +1027,7 @@ func resourceTencentCloudElasticsearchInstanceUpdate(d *schema.ResourceData, met } } err := resource.Retry(tccommon.WriteRetryTimeout*2, func() *resource.RetryError { - errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", "", publicAccess, 0, nil, nil, nil, nil, &esPublicAcl) + errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", "", "", publicAccess, 0, nil, nil, nil, nil, &esPublicAcl) if errRet != nil { return tccommon.RetryError(errRet) } @@ -1023,7 +1078,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, nil, nil) + errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", "", "", "", 0, nil, nil, &esAcl, nil, nil) if errRet != nil { return tccommon.RetryError(errRet) } @@ -1053,7 +1108,7 @@ func resourceTencentCloudElasticsearchInstanceUpdate(d *schema.ResourceData, met } err := resource.Retry(tccommon.WriteRetryTimeout*2, func() *resource.RetryError { - errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", "", "", 0, nil, nil, nil, &cosBackup, nil) + errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", "", "", "", 0, nil, nil, nil, &cosBackup, nil) if errRet != nil { return tccommon.RetryError(errRet) } diff --git a/tencentcloud/services/es/resource_tc_elasticsearch_instance_test.go b/tencentcloud/services/es/resource_tc_elasticsearch_instance_test.go index 09df23be3b..755fce2750 100644 --- a/tencentcloud/services/es/resource_tc_elasticsearch_instance_test.go +++ b/tencentcloud/services/es/resource_tc_elasticsearch_instance_test.go @@ -163,6 +163,39 @@ func TestAccTencentCloudElasticsearchInstanceResource_kibanaPublicAccess(t *test }) } +func TestAccTencentCloudElasticsearchInstanceResource_kibanaPrivateAccess(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { tcacctest.AccPreCheck(t) }, + Providers: tcacctest.AccProviders, + CheckDestroy: testAccCheckElasticsearchInstanceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccElasticsearchInstanceKibanaPrivateAccessOpen, + Check: resource.ComposeTestCheckFunc( + testAccCheckElasticsearchInstanceExists("tencentcloud_elasticsearch_instance.es_kibana"), + resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.es_kibana", "kibana_private_access", "OPEN"), + ), + }, + { + Config: testAccElasticsearchInstanceKibanaPrivateAccessClose, + Check: resource.ComposeTestCheckFunc( + testAccCheckElasticsearchInstanceExists("tencentcloud_elasticsearch_instance.es_kibana"), + resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.es_kibana", "kibana_private_access", "CLOSE"), + ), + }, + { + Config: testAccElasticsearchInstanceKibanaPrivateAccessOpen, + Check: resource.ComposeTestCheckFunc( + testAccCheckElasticsearchInstanceExists("tencentcloud_elasticsearch_instance.es_kibana"), + resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.es_kibana", "kibana_private_access", "OPEN"), + ), + }, + }, + }) +} + func testAccCheckElasticsearchInstanceDestroy(s *terraform.State) error { logId := tccommon.GetLogId(tccommon.ContextNil) ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) @@ -346,3 +379,53 @@ resource "tencentcloud_elasticsearch_instance" "es_kibana" { } } ` + +const testAccElasticsearchInstanceKibanaPrivateAccessClose = 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_private_access = "CLOSE" + public_access = "CLOSE" + es_public_acl { + white_ip_list = [ + "127.0.0.1" + ] + } + + node_info_list { + node_num = 2 + node_type = "ES.S1.MEDIUM4" + } + } +` + +const testAccElasticsearchInstanceKibanaPrivateAccessOpen = 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_private_access = "OPEN" + public_access = "OPEN" + es_public_acl { + white_ip_list = [ + "127.0.0.1" + ] + } + + 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 6a5a36458b..8302fc3c74 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, kibanaPublicAccess, publicAccess string, +func (me *ElasticsearchService) UpdateInstance(ctx context.Context, instanceId, instanceName, password, kibanaPublicAccess, kibanaPrivateAccess, publicAccess string, basicSecurityType int64, nodeList []*es.NodeInfo, nodeTypeInfo *es.WebNodeTypeInfo, esAcl *es.EsAcl, cosBackup *es.CosBackup, esPublicAcl *es.EsPublicAcl) error { logId := tccommon.GetLogId(ctx) request := es.NewUpdateInstanceRequest() @@ -121,6 +121,9 @@ func (me *ElasticsearchService) UpdateInstance(ctx context.Context, instanceId, if kibanaPublicAccess != "" { request.KibanaPublicAccess = &kibanaPublicAccess } + if kibanaPrivateAccess != "" { + request.KibanaPrivateAccess = &kibanaPrivateAccess + } 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 5ae4f8813d..bacebad93b 100644 --- a/website/docs/r/elasticsearch_instance.html.markdown +++ b/website/docs/r/elasticsearch_instance.html.markdown @@ -173,6 +173,7 @@ The following arguments are supported: * `es_acl` - (Optional, List) Kibana Access Control Configuration. * `es_public_acl` - (Optional, List) Public network access control list. * `instance_name` - (Optional, String) Name of the instance, which can contain 1 to 50 English letters, Chinese characters, digits, dashes(-), or underscores(_). +* `kibana_private_access` - (Optional, String) Kibana private network access status. Valid values are `OPEN` and `CLOSE`. * `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`).