diff --git a/tencentcloud/resource_tc_elasticsearch_instance.go b/tencentcloud/resource_tc_elasticsearch_instance.go index fff218c513..6b78fc383a 100755 --- a/tencentcloud/resource_tc_elasticsearch_instance.go +++ b/tencentcloud/resource_tc_elasticsearch_instance.go @@ -21,7 +21,17 @@ resource "tencentcloud_elasticsearch_instance" "foo" { node_info_list { node_num = 2 node_type = "ES.S1.MEDIUM4" - encrypt = false + encrypt = false + } + + es_acl { + black_list = [ + "9.9.9.9", + "8.8.8.8", + ] + white_list = [ + "0.0.0.0", + ] } tags = { @@ -171,6 +181,33 @@ func resourceTencentCloudElasticsearchInstance() *schema.Resource { }, }, }, + "es_acl": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Description: "Kibana Access Control Configuration.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "black_list": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Description: "Blacklist of kibana access.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "white_list": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Description: "Whitelist of kibana access.", + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + }, "license_type": { Type: schema.TypeString, Optional: true, @@ -385,7 +422,7 @@ func resourceTencentCloudElasticsearchInstanceCreate(d *schema.ResourceData, met return retryError(errRet, InternalError) } if instance == nil || *instance.Status == ES_INSTANCE_STATUS_PROCESSING { - return resource.RetryableError(errors.New("elasticsearch instance status is processing, retry...")) + return resource.RetryableError(fmt.Errorf("elasticsearch instance status is processing, retry... status:%v", *instance.Status)) } return nil }) @@ -478,6 +515,16 @@ func resourceTencentCloudElasticsearchInstanceRead(d *schema.ResourceData, meta } _ = d.Set("node_info_list", nodeInfoList) + if instance.EsAcl != nil { + esAcls := make([]map[string]interface{}, 0, 1) + esAcl := map[string]interface{}{ + "black_list": instance.EsAcl.BlackIpList, + "white_list": instance.EsAcl.WhiteIpList, + } + esAcls = append(esAcls, esAcl) + _ = d.Set("es_acl", esAcls) + } + if len(instance.TagList) > 0 { tags := make(map[string]string) for _, tag := range instance.TagList { @@ -505,7 +552,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(writeRetryTimeout, func() *resource.RetryError { - errRet := elasticsearchService.UpdateInstance(ctx, instanceId, instanceName, "", 0, nil, nil) + errRet := elasticsearchService.UpdateInstance(ctx, instanceId, instanceName, "", 0, nil, nil, nil) if errRet != nil { return retryError(errRet) } @@ -519,7 +566,7 @@ func resourceTencentCloudElasticsearchInstanceUpdate(d *schema.ResourceData, met if d.HasChange("password") { password := d.Get("password").(string) err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { - errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", password, 0, nil, nil) + errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", password, 0, nil, nil, nil) if errRet != nil { return retryError(errRet) } @@ -592,7 +639,7 @@ func resourceTencentCloudElasticsearchInstanceUpdate(d *schema.ResourceData, met if d.HasChange("basic_security_type") { basicSecurityType := d.Get("basic_security_type").(int) err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { - errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", int64(basicSecurityType), nil, nil) + errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", int64(basicSecurityType), nil, nil, nil) if errRet != nil { return retryError(errRet) } @@ -614,7 +661,7 @@ func resourceTencentCloudElasticsearchInstanceUpdate(d *schema.ResourceData, met NodeType: helper.String(value["node_type"].(string)), } err = resource.Retry(writeRetryTimeout, func() *resource.RetryError { - errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", 0, nil, info) + errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", 0, nil, info, nil) if errRet != nil { return retryError(errRet) } @@ -649,7 +696,7 @@ func resourceTencentCloudElasticsearchInstanceUpdate(d *schema.ResourceData, met nodeInfoList = append(nodeInfoList, &dataDisk) } err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { - errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", 0, nodeInfoList, nil) + errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", 0, nodeInfoList, nil, nil) if errRet != nil { return retryError(errRet) } @@ -687,6 +734,35 @@ func resourceTencentCloudElasticsearchInstanceUpdate(d *schema.ResourceData, met } d.SetPartial("tags") } + if d.HasChange("es_acl") { + esAcl := es.EsAcl{} + if aclMap, ok := helper.InterfacesHeadMap(d, "es_acl"); ok { + if v, ok := aclMap["black_list"]; ok { + blist := v.(*schema.Set).List() + for _, d := range blist { + esAcl.BlackIpList = append(esAcl.BlackIpList, helper.String(d.(string))) + } + } + if v, ok := aclMap["white_list"]; ok { + wlist := v.(*schema.Set).List() + for _, d := range wlist { + esAcl.WhiteIpList = append(esAcl.WhiteIpList, helper.String(d.(string))) + } + } + } + + err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + errRet := elasticsearchService.UpdateInstance(ctx, instanceId, "", "", 0, nil, nil, &esAcl) + if errRet != nil { + return retryError(errRet) + } + return nil + }) + if err != nil { + return err + } + d.SetPartial("es_acl") + } d.Partial(false) diff --git a/tencentcloud/resource_tc_elasticsearch_instance_test.go b/tencentcloud/resource_tc_elasticsearch_instance_test.go index a2df211b4b..a4c2f56e24 100755 --- a/tencentcloud/resource_tc_elasticsearch_instance_test.go +++ b/tencentcloud/resource_tc_elasticsearch_instance_test.go @@ -83,6 +83,9 @@ func TestAccTencentCloudNeedFixElasticsearchInstance_basic(t *testing.T) { resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.foo", "web_node_type_info.0.node_type", "ES.S1.MEDIUM8"), resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.foo", "node_info_list.0.node_type", "ES.S1.MEDIUM8"), resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.foo", "node_info_list.0.disk_size", "200"), + resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.foo", "es_public_acl.#", "1"), + resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.foo", "es_public_acl.0.white_list.#", "1"), + resource.TestCheckResourceAttr("tencentcloud_elasticsearch_instance.foo", "es_public_acl.0.black_list.#", "1"), ), }, { @@ -208,6 +211,15 @@ resource "tencentcloud_elasticsearch_instance" "foo" { node_type = "ES.S1.MEDIUM8" disk_size = 200 } + + es_public_acl { + white_list { + "0.0.0.0" + } + black_list { + "1.1.1.1" + } + } tags = { test = "test" diff --git a/tencentcloud/service_tencentcloud_elasticsearch.go b/tencentcloud/service_tencentcloud_elasticsearch.go index 3373037663..e0c8269d92 100755 --- a/tencentcloud/service_tencentcloud_elasticsearch.go +++ b/tencentcloud/service_tencentcloud_elasticsearch.go @@ -95,7 +95,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) error { +func (me *ElasticsearchService) UpdateInstance(ctx context.Context, instanceId, instanceName, password string, basicSecurityType int64, nodeList []*es.NodeInfo, nodeTypeInfo *es.WebNodeTypeInfo, esAcl *es.EsAcl) error { logId := getLogId(ctx) request := es.NewUpdateInstanceRequest() request.InstanceId = &instanceId @@ -114,6 +114,9 @@ func (me *ElasticsearchService) UpdateInstance(ctx context.Context, instanceId, if nodeTypeInfo != nil { request.WebNodeTypeInfo = nodeTypeInfo } + if esAcl != nil { + request.EsAcl = esAcl + } ratelimit.Check(request.GetAction()) _, err := me.client.UseEsClient().UpdateInstance(request) if err != nil { diff --git a/website/docs/r/elasticsearch_instance.html.markdown b/website/docs/r/elasticsearch_instance.html.markdown index df0f127f6f..e24a6879cd 100644 --- a/website/docs/r/elasticsearch_instance.html.markdown +++ b/website/docs/r/elasticsearch_instance.html.markdown @@ -34,6 +34,16 @@ resource "tencentcloud_elasticsearch_instance" "foo" { encrypt = false } + es_acl { + black_list = [ + "9.9.9.9", + "8.8.8.8", + ] + white_list = [ + "0.0.0.0", + ] + } + tags = { test = "test" } @@ -53,6 +63,7 @@ The following arguments are supported: * `charge_period` - (Optional, Int, ForceNew) The tenancy of the prepaid instance, and uint is month. NOTE: it only works when charge_type is set to `PREPAID`. * `charge_type` - (Optional, String, ForceNew) The charge type of instance. Valid values are `PREPAID` and `POSTPAID_BY_HOUR`. * `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(_). * `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`). @@ -61,6 +72,11 @@ The following arguments are supported: * `tags` - (Optional, Map) 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). * `web_node_type_info` - (Optional, List) Visual node configuration. +The `es_acl` object supports the following: + +* `black_list` - (Optional, Set) Blacklist of kibana access. +* `white_list` - (Optional, Set) Whitelist of kibana access. + The `multi_zone_infos` object supports the following: * `availability_zone` - (Required, String) Availability zone.