diff --git a/.changelog/2859.txt b/.changelog/2859.txt new file mode 100644 index 0000000000..201eb3593c --- /dev/null +++ b/.changelog/2859.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/tencentcloud_kubernetes_scale_worker: support `taints` parameter +``` diff --git a/tencentcloud/services/tke/resource_tc_kubernetes_scale_worker.go b/tencentcloud/services/tke/resource_tc_kubernetes_scale_worker.go index 2478b632bd..02c2f066b9 100644 --- a/tencentcloud/services/tke/resource_tc_kubernetes_scale_worker.go +++ b/tencentcloud/services/tke/resource_tc_kubernetes_scale_worker.go @@ -9,7 +9,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - tke "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tke/v20180525" + tkev20180525 "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tke/v20180525" tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" @@ -435,6 +435,35 @@ func ResourceTencentCloudKubernetesScaleWorker() *schema.Resource { Description: "Base64-encoded user script, executed before initializing the node, currently only effective for adding existing nodes.", }, + "taints": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Description: "Node taint.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "key": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: "Key of the taint.", + }, + "value": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: "Value of the taint.", + }, + "effect": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: "Effect of the taint.", + }, + }, + }, + }, + "user_script": { Type: schema.TypeString, Optional: true, @@ -525,7 +554,7 @@ func resourceTencentCloudKubernetesScaleWorkerRead(d *schema.ResourceData, meta log.Printf("[WARN]%s resource `kubernetes_scale_worker` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) return nil } - respData1, err := service.DescribeKubernetesScaleWorkerById1(ctx, clusterId) + respData1, err := service.DescribeKubernetesScaleWorkerById1(ctx) if err != nil { return err } @@ -535,16 +564,6 @@ func resourceTencentCloudKubernetesScaleWorkerRead(d *schema.ResourceData, meta log.Printf("[WARN]%s resource `kubernetes_scale_worker` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) return nil } - respData2, err := service.DescribeKubernetesScaleWorkerById2(ctx) - if err != nil { - return err - } - - if respData2 == nil { - d.SetId("") - log.Printf("[WARN]%s resource `kubernetes_scale_worker` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) - return nil - } _ = instanceIdSet return nil } @@ -564,14 +583,14 @@ func resourceTencentCloudKubernetesScaleWorkerDelete(d *schema.ResourceData, met instanceIdSet := idSplit[1] var ( - request = tke.NewDescribeClustersRequest() - response = tke.NewDescribeClustersResponse() + request = tkev20180525.NewDescribeClustersRequest() + response = tkev20180525.NewDescribeClustersResponse() ) request.ClusterIds = []*string{helper.String(clusterId)} err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseTkeClient().DescribeClustersWithContext(ctx, request) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseTkeV20180525Client().DescribeClustersWithContext(ctx, request) if e != nil { return tccommon.RetryError(e) } else { diff --git a/tencentcloud/services/tke/resource_tc_kubernetes_scale_worker_extension.go b/tencentcloud/services/tke/resource_tc_kubernetes_scale_worker_extension.go index f788b3b242..fb542fcbc2 100644 --- a/tencentcloud/services/tke/resource_tc_kubernetes_scale_worker_extension.go +++ b/tencentcloud/services/tke/resource_tc_kubernetes_scale_worker_extension.go @@ -46,7 +46,90 @@ func customScaleWorkerResourceImporter(ctx context.Context, d *schema.ResourceDa return []*schema.ResourceData{d}, nil } -func resourceTencentCloudKubernetesScaleWorkerReadPostRequest1(ctx context.Context, req *tke.DescribeClusterInstancesRequest, resp *tke.DescribeClusterInstancesResponse) error { +func resourceTencentCloudKubernetesScaleWorkerReadPostRequest1(ctx context.Context, req *cvm.DescribeInstancesRequest, resp *cvm.DescribeInstancesResponse) error { + d := tccommon.ResourceDataFromContext(ctx) + + instances := make([]*cvm.Instance, 0) + instances = append(instances, resp.Response.InstanceSet...) + + instanceList := make([]interface{}, 0, len(instances)) + for _, instance := range instances { + mapping := map[string]interface{}{ + "count": 1, + "instance_charge_type_prepaid_period": 1, + "instance_type": helper.PString(instance.InstanceType), + "subnet_id": helper.PString(instance.VirtualPrivateCloud.SubnetId), + "availability_zone": helper.PString(instance.Placement.Zone), + "instance_name": helper.PString(instance.InstanceName), + "instance_charge_type": helper.PString(instance.InstanceChargeType), + "system_disk_type": helper.PString(instance.SystemDisk.DiskType), + "system_disk_size": helper.PInt64(instance.SystemDisk.DiskSize), + "internet_charge_type": helper.PString(instance.InternetAccessible.InternetChargeType), + "bandwidth_package_id": helper.PString(instance.InternetAccessible.BandwidthPackageId), + "internet_max_bandwidth_out": helper.PInt64(instance.InternetAccessible.InternetMaxBandwidthOut), + "security_group_ids": helper.StringsInterfaces(instance.SecurityGroupIds), + "img_id": helper.PString(instance.ImageId), + } + + if instance.RenewFlag != nil && helper.PString(instance.InstanceChargeType) == "PREPAID" { + mapping["instance_charge_type_prepaid_renew_flag"] = helper.PString(instance.RenewFlag) + } else { + mapping["instance_charge_type_prepaid_renew_flag"] = "" + } + if helper.PInt64(instance.InternetAccessible.InternetMaxBandwidthOut) > 0 { + mapping["public_ip_assigned"] = true + } + + if instance.CamRoleName != nil { + mapping["cam_role_name"] = instance.CamRoleName + } + if instance.LoginSettings != nil { + if instance.LoginSettings.KeyIds != nil && len(instance.LoginSettings.KeyIds) > 0 { + mapping["key_ids"] = helper.StringsInterfaces(instance.LoginSettings.KeyIds) + } + if instance.LoginSettings.Password != nil { + mapping["password"] = helper.PString(instance.LoginSettings.Password) + } + } + if instance.DisasterRecoverGroupId != nil && helper.PString(instance.DisasterRecoverGroupId) != "" { + mapping["disaster_recover_group_ids"] = []string{helper.PString(instance.DisasterRecoverGroupId)} + } + if instance.HpcClusterId != nil { + mapping["hpc_cluster_id"] = helper.PString(instance.HpcClusterId) + } + + dataDisks := make([]interface{}, 0, len(instance.DataDisks)) + for _, v := range instance.DataDisks { + dataDisk := map[string]interface{}{ + "disk_type": helper.PString(v.DiskType), + "disk_size": helper.PInt64(v.DiskSize), + "snapshot_id": helper.PString(v.DiskId), + "encrypt": helper.PBool(v.Encrypt), + "kms_key_id": helper.PString(v.KmsKeyId), + } + dataDisks = append(dataDisks, dataDisk) + } + + mapping["data_disk"] = dataDisks // worker_config.data_disk + instanceList = append(instanceList, mapping) + } + if importFlag1 { + _ = d.Set("worker_config", instanceList) + } + + // The machines I generated was deleted by others. + if len(WorkersNewWorkerInstancesList) == 0 { + d.SetId("") + return nil + } + + _ = d.Set("cluster_id", GlobalClusterId) + _ = d.Set("labels", WorkersLabelsMap) + _ = d.Set("worker_instances_list", WorkersNewWorkerInstancesList) + + return nil +} +func clusterInstanceParamHandle(ctx context.Context, req *tke.DescribeClusterInstancesRequest, resp *tke.DescribeClusterInstancesResponse) error { d := tccommon.ResourceDataFromContext(ctx) var has = map[string]bool{} @@ -198,90 +281,6 @@ func resourceTencentCloudKubernetesScaleWorkerReadPostRequest1(ctx context.Conte return nil } -func resourceTencentCloudKubernetesScaleWorkerReadPostRequest2(ctx context.Context, req *cvm.DescribeInstancesRequest, resp *cvm.DescribeInstancesResponse) error { - d := tccommon.ResourceDataFromContext(ctx) - - instances := make([]*cvm.Instance, 0) - instances = append(instances, resp.Response.InstanceSet...) - - instanceList := make([]interface{}, 0, len(instances)) - for _, instance := range instances { - mapping := map[string]interface{}{ - "count": 1, - "instance_charge_type_prepaid_period": 1, - "instance_type": helper.PString(instance.InstanceType), - "subnet_id": helper.PString(instance.VirtualPrivateCloud.SubnetId), - "availability_zone": helper.PString(instance.Placement.Zone), - "instance_name": helper.PString(instance.InstanceName), - "instance_charge_type": helper.PString(instance.InstanceChargeType), - "system_disk_type": helper.PString(instance.SystemDisk.DiskType), - "system_disk_size": helper.PInt64(instance.SystemDisk.DiskSize), - "internet_charge_type": helper.PString(instance.InternetAccessible.InternetChargeType), - "bandwidth_package_id": helper.PString(instance.InternetAccessible.BandwidthPackageId), - "internet_max_bandwidth_out": helper.PInt64(instance.InternetAccessible.InternetMaxBandwidthOut), - "security_group_ids": helper.StringsInterfaces(instance.SecurityGroupIds), - "img_id": helper.PString(instance.ImageId), - } - - if instance.RenewFlag != nil && helper.PString(instance.InstanceChargeType) == "PREPAID" { - mapping["instance_charge_type_prepaid_renew_flag"] = helper.PString(instance.RenewFlag) - } else { - mapping["instance_charge_type_prepaid_renew_flag"] = "" - } - if helper.PInt64(instance.InternetAccessible.InternetMaxBandwidthOut) > 0 { - mapping["public_ip_assigned"] = true - } - - if instance.CamRoleName != nil { - mapping["cam_role_name"] = instance.CamRoleName - } - if instance.LoginSettings != nil { - if instance.LoginSettings.KeyIds != nil && len(instance.LoginSettings.KeyIds) > 0 { - mapping["key_ids"] = helper.StringsInterfaces(instance.LoginSettings.KeyIds) - } - if instance.LoginSettings.Password != nil { - mapping["password"] = helper.PString(instance.LoginSettings.Password) - } - } - if instance.DisasterRecoverGroupId != nil && helper.PString(instance.DisasterRecoverGroupId) != "" { - mapping["disaster_recover_group_ids"] = []string{helper.PString(instance.DisasterRecoverGroupId)} - } - if instance.HpcClusterId != nil { - mapping["hpc_cluster_id"] = helper.PString(instance.HpcClusterId) - } - - dataDisks := make([]interface{}, 0, len(instance.DataDisks)) - for _, v := range instance.DataDisks { - dataDisk := map[string]interface{}{ - "disk_type": helper.PString(v.DiskType), - "disk_size": helper.PInt64(v.DiskSize), - "snapshot_id": helper.PString(v.DiskId), - "encrypt": helper.PBool(v.Encrypt), - "kms_key_id": helper.PString(v.KmsKeyId), - } - dataDisks = append(dataDisks, dataDisk) - } - - mapping["data_disk"] = dataDisks // worker_config.data_disk - instanceList = append(instanceList, mapping) - } - if importFlag1 { - _ = d.Set("worker_config", instanceList) - } - - // The machines I generated was deleted by others. - if len(WorkersNewWorkerInstancesList) == 0 { - d.SetId("") - return nil - } - - _ = d.Set("cluster_id", GlobalClusterId) - _ = d.Set("labels", WorkersLabelsMap) - _ = d.Set("worker_instances_list", WorkersNewWorkerInstancesList) - - return nil -} - func resourceTencentCloudKubernetesScaleWorkerDeletePostRequest0(ctx context.Context, req *tke.DescribeClustersRequest, resp *tke.DescribeClustersResponse) *resource.RetryError { if len(resp.Response.Clusters) == 0 { return resource.NonRetryableError(fmt.Errorf("The cluster has been deleted")) @@ -379,7 +378,7 @@ func resourceTencentCloudKubernetesScaleWorkerCreateOnStart(ctx context.Context) dMap := make(map[string]interface{}, 5) //mount_target, docker_graph_path, data_disk, extra_args, desired_pod_num - iAdvancedParas := []string{"mount_target", "docker_graph_path", "extra_args", "data_disk", "desired_pod_num", "gpu_args"} + iAdvancedParas := []string{"mount_target", "docker_graph_path", "extra_args", "data_disk", "desired_pod_num", "gpu_args", "taints"} for _, k := range iAdvancedParas { if v, ok := d.GetOk(k); ok { dMap[k] = v @@ -396,6 +395,23 @@ func resourceTencentCloudKubernetesScaleWorkerCreateOnStart(ctx context.Context) iAdvanced.PreStartUserScript = helper.String(v.(string)) } + if v, ok := d.GetOk("taints"); ok { + for _, item := range v.([]interface{}) { + taintsMap := item.(map[string]interface{}) + taint := tke.Taint{} + if v, ok := taintsMap["key"]; ok { + taint.Key = helper.String(v.(string)) + } + if v, ok := taintsMap["value"]; ok { + taint.Value = helper.String(v.(string)) + } + if v, ok := taintsMap["effect"]; ok { + taint.Effect = helper.String(v.(string)) + } + iAdvanced.Taints = append(iAdvanced.Taints, &taint) + } + } + if v, ok := d.GetOk("user_script"); ok { iAdvanced.UserScript = helper.String(v.(string)) } @@ -609,3 +625,61 @@ func resourceTencentCloudKubernetesScaleWorkerDeleteOnExit(ctx context.Context) } return nil } + +func resourceTencentCloudKubernetesScaleWorkerReadPostFillRequest1(ctx context.Context, req *cvm.DescribeInstancesRequest) error { + d := tccommon.ResourceDataFromContext(ctx) + meta := tccommon.ProviderMetaFromContext(ctx) + logId := tccommon.GetLogId(ctx) + + idSplit := strings.Split(d.Id(), tccommon.FILED_SP) + if len(idSplit) != 2 { + return fmt.Errorf("id is broken,%s", d.Id()) + } + clusterId := idSplit[0] + + request := tke.NewDescribeClusterInstancesRequest() + request.ClusterId = helper.String(clusterId) + + instanceSet := make([]*tke.Instance, 0) + + var offset int64 = 0 + var pageSize int64 = 100 + for { + request.Offset = &offset + request.Limit = &pageSize + ratelimit.Check(request.GetAction()) + + response, err := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseTkeClient().DescribeClusterInstances(request) + if err != nil { + return err + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + if err := clusterInstanceParamHandle(ctx, request, response); err != nil { + return err + } + + if response == nil || len(response.Response.InstanceSet) < 1 { + break + } + count := len(response.Response.InstanceSet) + instanceSet = append(instanceSet, response.Response.InstanceSet...) + + if count < int(pageSize) { + break + } + offset += pageSize + } + if instanceSet == nil { + d.SetId("") + log.Printf("[WARN]%s resource `kubernetes_scale_worker` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) + return nil + } + return nil +} + +func resourceTencentCloudKubernetesScaleWorkerReadPreRequest1(ctx context.Context, req *cvm.DescribeInstancesRequest) error { + req.InstanceIds = WorkersInstanceIds + + return nil +} diff --git a/tencentcloud/services/tke/service_tencentcloud_tke.go b/tencentcloud/services/tke/service_tencentcloud_tke.go index 645b712458..3ec621af82 100644 --- a/tencentcloud/services/tke/service_tencentcloud_tke.go +++ b/tencentcloud/services/tke/service_tencentcloud_tke.go @@ -3406,7 +3406,7 @@ func (me *TkeService) DescribeKubernetesScaleWorkerById(ctx context.Context, clu ratelimit.Check(request.GetAction()) - response, err := me.client.UseTkeClient().DescribeClusters(request) + response, err := me.client.UseTkeV20180525Client().DescribeClusters(request) if err != nil { errRet = err return @@ -3421,62 +3421,12 @@ func (me *TkeService) DescribeKubernetesScaleWorkerById(ctx context.Context, clu return } -func (me *TkeService) DescribeKubernetesScaleWorkerById1(ctx context.Context, clusterId string) (ret *tke.DescribeClusterInstancesResponseParams, errRet error) { - logId := tccommon.GetLogId(ctx) - - request := tke.NewDescribeClusterInstancesRequest() - request.ClusterId = helper.String(clusterId) - - ret = &tke.DescribeClusterInstancesResponseParams{ - InstanceSet: make([]*tke.Instance, 0), - TotalCount: new(uint64), - } - - 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()) - } - }() - - var offset int64 = 0 - var pageSize int64 = 100 - for { - request.Offset = &offset - request.Limit = &pageSize - ratelimit.Check(request.GetAction()) - - response, err := me.client.UseTkeClient().DescribeClusterInstances(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 err := resourceTencentCloudKubernetesScaleWorkerReadPostRequest1(ctx, request, response); err != nil { - return nil, err - } - - if response == nil || len(response.Response.InstanceSet) < 1 { - break - } - count := len(response.Response.InstanceSet) - ret.InstanceSet = append(ret.InstanceSet, response.Response.InstanceSet...) - *ret.TotalCount += *helper.IntUint64(count) - - if count < int(pageSize) { - break - } - offset += pageSize - } - return -} - -func (me *TkeService) DescribeKubernetesScaleWorkerById2(ctx context.Context) (ret *cvm.DescribeInstancesResponseParams, errRet error) { +func (me *TkeService) DescribeKubernetesScaleWorkerById1(ctx context.Context) (ret *cvm.DescribeInstancesResponseParams, errRet error) { logId := tccommon.GetLogId(ctx) request := cvm.NewDescribeInstancesRequest() - if err := resourceTencentCloudKubernetesScaleWorkerReadPostFillRequest2(ctx, request); err != nil { + if err := resourceTencentCloudKubernetesScaleWorkerReadPostFillRequest1(ctx, request); err != nil { return nil, err } @@ -3488,14 +3438,18 @@ func (me *TkeService) DescribeKubernetesScaleWorkerById2(ctx context.Context) (r ratelimit.Check(request.GetAction()) - response, err := me.client.UseCvmClient().DescribeInstances(request) + if err := resourceTencentCloudKubernetesScaleWorkerReadPreRequest1(ctx, request); err != nil { + return nil, err + } + + response, err := me.client.UseCvmV20170312Client().DescribeInstances(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 err := resourceTencentCloudKubernetesScaleWorkerReadPostRequest2(ctx, request, response); err != nil { + if err := resourceTencentCloudKubernetesScaleWorkerReadPostRequest1(ctx, request, response); err != nil { return nil, err } diff --git a/website/docs/r/kubernetes_scale_worker.html.markdown b/website/docs/r/kubernetes_scale_worker.html.markdown index d69860d3a2..773ebabf66 100644 --- a/website/docs/r/kubernetes_scale_worker.html.markdown +++ b/website/docs/r/kubernetes_scale_worker.html.markdown @@ -128,6 +128,7 @@ The following arguments are supported: * `labels` - (Optional, Map, ForceNew) Labels of kubernetes scale worker created nodes. * `mount_target` - (Optional, String, ForceNew) Mount target. Default is not mounting. * `pre_start_user_script` - (Optional, String, ForceNew) Base64-encoded user script, executed before initializing the node, currently only effective for adding existing nodes. +* `taints` - (Optional, List, ForceNew) Node taint. * `unschedulable` - (Optional, Int, ForceNew) Set whether the added node participates in scheduling. The default value is 0, which means participating in scheduling; non-0 means not participating in scheduling. After the node initialization is completed, you can execute kubectl uncordon nodename to join the node in scheduling. * `user_script` - (Optional, String, ForceNew) Base64 encoded user script, this script will be executed after the k8s component is run. The user needs to ensure that the script is reentrant and retry logic. The script and its generated log files can be viewed in the /data/ccs_userscript/ path of the node, if required. The node needs to be initialized before it can be added to the schedule. It can be used with the unschedulable parameter. After the final initialization of userScript is completed, add the kubectl uncordon nodename --kubeconfig=/root/.kube/config command to add the node to the schedule. @@ -160,6 +161,12 @@ The `gpu_args` object supports the following: * `driver` - (Optional, Map) GPU driver version. Format like: `{ version: String, name: String }`. `version`: Version of GPU driver or CUDA; `name`: Name of GPU driver or CUDA. * `mig_enable` - (Optional, Bool) Whether to enable MIG. +The `taints` object supports the following: + +* `effect` - (Optional, String, ForceNew) Effect of the taint. +* `key` - (Optional, String, ForceNew) Key of the taint. +* `value` - (Optional, String, ForceNew) Value of the taint. + The `worker_config` object supports the following: * `instance_type` - (Required, String, ForceNew) Specified types of CVM instance.