alibabacloudstack/resource_apsarastack_ack_cluster.go (1,117 lines of code) (raw):
package alibabacloudstack
import (
// "encoding/base64"
"encoding/json"
"fmt"
"log"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
// "github.com/aliyun/alibaba-cloud-sdk-go/services/cs"
"regexp"
"time"
"github.com/aliyun/terraform-provider-alibabacloudstack/alibabacloudstack/connectivity"
"github.com/aliyun/terraform-provider-alibabacloudstack/alibabacloudstack/errmsgs"
"github.com/denverdino/aliyungo/cs"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)
const (
KubernetesClusterNetworkTypeFlannel = "flannel"
KubernetesClusterNetworkTypeTerway = "terway"
KubernetesClusterLoggingTypeSLS = "SLS"
ClusterType = "Kubernetes"
OsType = "Linux"
Platform = "CentOS"
RuntimeName = "docker"
RuntimeVersion = "19.03.5"
PortRange = "30000-32767"
)
var (
KubernetesClusterNodeCIDRMasksByDefault = 24
)
func resourceAlibabacloudStackCSKubernetes() *schema.Resource {
resource := &schema.Resource{
Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(90 * time.Minute),
Update: schema.DefaultTimeout(60 * time.Minute),
Delete: schema.DefaultTimeout(60 * time.Minute),
},
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ValidateFunc: validation.StringLenBetween(1, 63),
},
"master_disk_size": {
Type: schema.TypeInt,
Optional: true,
Default: 40,
ValidateFunc: validation.IntBetween(40, 500),
DiffSuppressFunc: csForceUpdateSuppressFunc,
},
"master_disk_category": {
Type: schema.TypeString,
Optional: true,
Default: DiskCloudSSD,
ValidateFunc: validation.StringInSlice([]string{
string(DiskCloudEfficiency), string(DiskCloudSSD), string(DiskCloudPPERF), string(DiskCloudSPERF)}, false),
DiffSuppressFunc: csForceUpdateSuppressFunc,
},
"delete_protection": {
Type: schema.TypeBool,
Default: false,
Optional: true,
},
"num_of_nodes": {
Type: schema.TypeInt,
Required: true,
},
"worker_disk_size": {
Type: schema.TypeInt,
Optional: true,
Default: 40,
ValidateFunc: validation.IntBetween(20, 32768),
DiffSuppressFunc: csForceUpdateSuppressFunc,
},
"worker_disk_category": {
Type: schema.TypeString,
Optional: true,
Default: DiskCloudSSD,
ValidateFunc: validation.StringInSlice([]string{
string(DiskCloudEfficiency), string(DiskCloudSSD), string(DiskCloudPPERF), string(DiskCloudSPERF)}, false),
DiffSuppressFunc: csForceUpdateSuppressFunc,
},
// "worker_data_disk_size": {
// Type: schema.TypeInt,
// Optional: true,
// Default: 40,
// ValidateFunc: validation.IntBetween(20, 32768),
// DiffSuppressFunc: workerDataDiskSizeSuppressFunc,
// },
// "worker_data_disk_category": {
// Type: schema.TypeString,
// Optional: true,
// ValidateFunc: validation.StringInSlice([]string{
// string(DiskCloudEfficiency), string(DiskCloudSSD), string(DiskCloudPPERF), string(DiskCloudSPERF)}, false),
// DiffSuppressFunc: csForceUpdateSuppressFunc,
// },
"worker_data_disks": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"size": {
Type: schema.TypeInt,
Default: "flannel",
Optional: true,
},
"encrypted": {
Type: schema.TypeBool,
Optional: true,
},
"auto_snapshot_policy_id": {
Type: schema.TypeString,
Optional: true,
},
"performance_level": {
Type: schema.TypeString,
Optional: true,
},
"category": {
Type: schema.TypeString,
Optional: true,
},
},
},
},
"master_storage_set_id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"master_storage_set_partition_number": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
ForceNew: true,
ValidateFunc: validation.IntBetween(1, 2000),
},
"worker_storage_set_id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"worker_storage_set_partition_number": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
ForceNew: true,
ValidateFunc: validation.IntBetween(1, 2000),
},
// "exclude_autoscaler_nodes": {
// Type: schema.TypeBool,
// Default: false,
// Optional: true,
// },
//"worker_data_disk": {
// Type: schema.TypeBool,
// Default: false,
// Optional: true,
//},
// global configurations
// Terway network
"pod_vswitch_ids": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: validation.StringMatch(regexp.MustCompile(`^vsw-[a-z0-9]*$`), "should start with 'vsw-'."),
},
MaxItems: 10,
DiffSuppressFunc: csForceUpdateSuppressFunc,
ConflictsWith: []string{"pod_cidr"},
},
// Flannel network
"pod_cidr": {
Type: schema.TypeString,
Optional: true,
DiffSuppressFunc: csForceUpdateSuppressFunc,
},
"service_cidr": {
Type: schema.TypeString,
Optional: true,
DiffSuppressFunc: csForceUpdateSuppressFunc,
},
"node_cidr_mask": {
Type: schema.TypeString,
Optional: true,
DiffSuppressFunc: csForceUpdateSuppressFunc,
},
"new_nat_gateway": {
Type: schema.TypeBool,
Optional: true,
Default: true,
},
"password": {
Type: schema.TypeString,
Optional: true,
Sensitive: true,
ConflictsWith: []string{"kms_encrypted_password"},
DiffSuppressFunc: csForceUpdateSuppressFunc,
},
// "key_name": {
// Type: schema.TypeString,
// Optional: true,
// ConflictsWith: []string{"password", "kms_encrypted_password"},
// DiffSuppressFunc: csForceUpdateSuppressFunc,
// },
"kms_encrypted_password": {
Type: schema.TypeString,
Optional: true,
ConflictsWith: []string{"password"},
},
"kms_encryption_context": {
Type: schema.TypeMap,
Optional: true,
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
return d.Get("kms_encrypted_password").(string) == ""
},
Elem: schema.TypeString,
},
// "user_ca": {
// Type: schema.TypeString,
// Optional: true,
// DiffSuppressFunc: csForceUpdateSuppressFunc,
// },
"enable_ssh": {
Type: schema.TypeBool,
Optional: true,
Default: false,
DiffSuppressFunc: csForceUpdateSuppressFunc,
},
"node_port_range": {
Type: schema.TypeString,
Optional: true,
Default: PortRange,
},
"image_id": {
Type: schema.TypeString,
Optional: true,
DiffSuppressFunc: imageIdSuppressFunc,
},
// "install_cloud_monitor": {
// Type: schema.TypeBool,
// Optional: true,
// Default: true,
// DiffSuppressFunc: csForceUpdateSuppressFunc,
// },
"version": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"cluster_type": {
Type: schema.TypeString,
Optional: true,
Default: ClusterType,
},
"os_type": {
Type: schema.TypeString,
Optional: true,
Default: OsType,
},
"platform": {
Type: schema.TypeString,
Optional: true,
Default: Platform,
},
// cpu policy options of kubelet
"cpu_policy": {
Type: schema.TypeString,
Optional: true,
Default: "none",
ValidateFunc: validation.StringInSlice([]string{"none", "static"}, false),
},
"proxy_mode": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{"iptables", "ipvs"}, false),
},
"addons": {
Type: schema.TypeList,
Optional: true,
MinItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Default: "flannel",
Optional: true,
},
"config": {
Type: schema.TypeString,
Optional: true,
},
//"disabled": {
// Type: schema.TypeBool,
// Optional: true,
// Default: false,
//},
},
},
},
"slb_internet_enabled": {
Type: schema.TypeBool,
Optional: true,
Default: true,
DiffSuppressFunc: csForceUpdateSuppressFunc,
},
// computed parameters
"kube_config": {
Type: schema.TypeString,
Optional: true,
},
"client_cert": {
Type: schema.TypeString,
Optional: true,
},
"client_key": {
Type: schema.TypeString,
Optional: true,
},
"cluster_ca_cert": {
Type: schema.TypeString,
Optional: true,
},
// "connections": {
// Type: schema.TypeList,
// Computed: true,
// Elem: &schema.Resource{
// Schema: map[string]*schema.Schema{
// "api_server_internet": {
// Type: schema.TypeString,
// Computed: true,
// },
// "api_server_intranet": {
// Type: schema.TypeString,
// Computed: true,
// },
// "master_public_ip": {
// Type: schema.TypeString,
// Computed: true,
// },
// "service_domain": {
// Type: schema.TypeString,
// Computed: true,
// },
// },
// },
// },
// "slb_id": {
// Type: schema.TypeString,
// Computed: true,
// Deprecated: "Field 'slb_id' has been deprecated from provider version 1.9.2. New field 'slb_internet' replaces it.",
// },
// "slb_internet": {
// Type: schema.TypeString,
// Computed: true,
// },
"slb_intranet": {
Type: schema.TypeString,
Computed: true,
},
"security_group_id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"master_system_disk_performance_level": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"worker_system_disk_performance_level": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"is_enterprise_security_group": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
},
"cloud_monitor_flags": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
},
"nat_gateway_id": {
Type: schema.TypeString,
Computed: true,
},
"vpc_id": {
Type: schema.TypeString,
Required: true,
},
"runtime": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Optional: true,
Default: RuntimeName,
},
"version": {
Type: schema.TypeString,
Optional: true,
Default: RuntimeVersion,
},
},
},
},
"master_nodes": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"private_ip": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"worker_nodes": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"private_ip": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
// remove parameters below
// mix vswitch_ids between master and worker is not a good guidance to create cluster
// "worker_instance_type": {
// Type: schema.TypeString,
// Optional: true,
// },
"master_instance_types": {
Type: schema.TypeList,
Elem: &schema.Schema{Type: schema.TypeString},
Required: true,
},
"master_vswitch_ids": {
Type: schema.TypeList,
Elem: &schema.Schema{Type: schema.TypeString},
Required: true,
},
"worker_instance_types": {
Type: schema.TypeList,
Elem: &schema.Schema{Type: schema.TypeString},
ConflictsWith: []string{"instances"},
Optional: true,
},
"worker_vswitch_ids": {
Type: schema.TypeList,
Elem: &schema.Schema{Type: schema.TypeString},
ConflictsWith: []string{"instances"},
Optional: true,
},
"instances": {
Type: schema.TypeSet,
Elem: &schema.Schema{Type: schema.TypeString},
ConflictsWith: []string{"worker_instance_types", "worker_vswitch_ids", "worker_disk_category"},
Optional: true,
},
"format_disk": {
Type: schema.TypeBool,
Optional: true,
},
"keep_instance_name": {
Type: schema.TypeBool,
Optional: true,
},
// "vswitch_ids": {
// Type: schema.TypeList,
// Optional: true,
// Elem: &schema.Schema{
// Type: schema.TypeString,
// ValidateFunc: validation.StringMatch(regexp.MustCompile(`^vsw-[a-z0-9]*$`), "should start with 'vsw-'."),
// },
// MinItems: 3,
// MaxItems: 5,
// DiffSuppressFunc: csForceUpdateSuppressFunc,
// //Removed: "Field 'vswitch_ids' has been removed from provider version 1.75.0. New field 'master_vswitch_ids' and 'worker_vswitch_ids' replace it.",
// },
"master_count": {
Type: schema.TypeInt,
Optional: true,
Default: 3,
},
// single instance type would cause extra troubles
// "master_instance_type": {
// Type: schema.TypeString,
// Optional: true,
// },
// force update is a high risk operation
// "force_update": {
// Type: schema.TypeBool,
// Optional: true,
// Default: false,
// //Removed: "Field 'force_update' has been removed from provider version 1.75.0.",
// },
"availability_zone": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
// single az would be never supported.
//"vswitch_id": {
// Type: schema.TypeString,
// Required: true,
// //Removed: "Field 'vswitch_id' has been removed from provider version 1.75.0. New field 'master_vswitch_ids' and 'worker_vswitch_ids' replaces it.",
//},
"timeout_mins": {
Type: schema.TypeInt,
Optional: true,
Default: 60,
},
"nodes": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
// too hard to use this config
// "log_config": {
// Type: schema.TypeList,
// Optional: true,
// MaxItems: 1,
// Elem: &schema.Resource{
// Schema: map[string]*schema.Schema{
// "type": {
// Type: schema.TypeString,
// ValidateFunc: validation.StringInSlice([]string{KubernetesClusterLoggingTypeSLS}, false),
// Required: true,
// },
// "project": {
// Type: schema.TypeString,
// Optional: true,
// },
// },
// },
// DiffSuppressFunc: csForceUpdateSuppressFunc,
// //Removed: "Field 'log_config' has been removed from provider version 1.75.0. New field 'addons' replaces it.",
// },
"user_data": {
Type: schema.TypeString,
Optional: true,
},
// "node_name_mode": {
// Type: schema.TypeString,
// Optional: true,
// ValidateFunc: validation.StringMatch(regexp.MustCompile(`^customized,[a-z0-9]([-a-z0-9\.])*,([5-9]|[1][0-2]),([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$`), "Each node name consists of a prefix, an IP substring, and a suffix. For example, if the node IP address is 192.168.0.55, the prefix is aliyun.com, IP substring length is 5, and the suffix is test, the node name will be aliyun.com00055test."),
// },
"worker_ram_role_name": {
Type: schema.TypeString,
Computed: true,
},
// "service_account_issuer": {
// Type: schema.TypeString,
// Optional: true,
// ForceNew: true,
// },
// "api_audiences": {
// Type: schema.TypeList,
// Optional: true,
// Elem: &schema.Schema{
// Type: schema.TypeString,
// },
// ForceNew: true,
// },
"nodepool_id": {
Type: schema.TypeString,
Computed: true,
},
"tags": tagsSchema(),
},
}
setResourceFunc(resource, resourceAlibabacloudStackCSKubernetesCreate,
resourceAlibabacloudStackCSKubernetesRead, resourceAlibabacloudStackCSKubernetesUpdate,
resourceAlibabacloudStackCSKubernetesDelete)
return resource
}
type Response struct {
RequestId string `json:"request_id"`
}
type ClusterCommonResponse struct {
Response
ClusterID string `json:"cluster_id"`
Token string `json:"token,omitempty"`
TaskId string `json:"task_id,omitempty"`
InstanceId string `json:"instanceId"`
}
func resourceAlibabacloudStackCSKubernetesCreate(d *schema.ResourceData, meta interface{}) error {
log.Printf("check meta %v", meta)
client := meta.(*connectivity.AlibabacloudStackClient)
csService := CsService{client}
invoker := NewInvoker()
timeout := d.Get("timeout_mins").(int)
Name := d.Get("name").(string)
OsType := d.Get("os_type").(string)
Platform := d.Get("platform").(string)
mastercount := d.Get("master_count").(int)
msysdiskcat := d.Get("master_disk_category").(string)
msysdisksize := d.Get("master_disk_size").(int)
wsysdisksize := d.Get("worker_disk_size").(int)
wsysdiskcat := d.Get("worker_disk_category").(string)
masterstoragesetid := d.Get("master_storage_set_id").(string)
masterstoragesetnumber := d.Get("master_storage_set_partition_number").(int)
workerstoragesetid := d.Get("worker_storage_set_id").(string)
workerstoragesetnumber := d.Get("worker_storage_set_partition_number").(int)
delete_pro := d.Get("delete_protection").(bool)
KubernetesVersion := d.Get("version").(string)
addons := make([]cs.Addon, 0)
type WorkerData struct {
Size int
Encrypted bool
AutoSnapshotPolicyId string
PerformanceLevel string
Category string
}
var req, workerdisks string
var pod, attachinst int
if v, ok := d.GetOk("addons"); ok {
all, ok := v.([]interface{})
if ok {
for i, a := range all {
addon, _ := a.(map[string]interface{})
log.Printf("check addon %v", addon)
if addon["name"] == "terway-eniip" {
pod = 1
}
log.Printf("check req id %v", i)
if i == 0 {
req = fmt.Sprintf("{\"name\" : \"%s\",\"config\": \"%s\"}", addon["name"].(string), addon["config"].(string))
} else {
req = fmt.Sprintf("%s,{\"name\" : \"%s\",\"config\": %q}", req, addon["name"].(string), addon["config"].(string))
}
}
}
}
if v, ok := d.GetOk("worker_data_disks"); ok {
all, ok := v.([]interface{})
if ok {
for i, a := range all {
disk, _ := a.(map[string]interface{})
if i == 0 {
workerdisks = fmt.Sprintf("{\"size\" : \"%d\",\"encrypted\": \"%t\",\"performance_level\": \"%s\",\"auto_snapshot_policy_id\": \"%s\",\"category\": \"%s\"}", disk["size"].(int), disk["encrypted"].(bool), disk["performance_level"].(string), disk["auto_snapshot_policy_id"].(string), disk["category"].(string))
} else {
workerdisks = fmt.Sprintf("%s,{\"size\" : \"%d\",\"encrypted\": \"%t\",\"performance_level\": \"%s\",\"auto_snapshot_policy_id\": \"%s\",\"category\": \"%s\"}", workerdisks, disk["size"].(int), disk["encrypted"].(bool), disk["performance_level"].(string), disk["auto_snapshot_policy_id"].(string), disk["category"].(string))
}
log.Printf("checking workerdatadisks %v", workerdisks)
}
}
}
udata := d.Get("user_data").(string)
log.Printf("checking addons %v", addons)
log.Printf("check req final %s", req)
var runtime string
if v, ok := d.GetOk("runtime"); ok {
all, _ := v.([]interface{})
for _, a := range all {
run, _ := a.(map[string]interface{})
runtime = fmt.Sprintf("\"name\": \"%s\", \"version\": \"%s\"", run["name"].(string), run["version"].(string))
}
}
log.Printf("checking runtime %v", runtime)
var tags string
// if v, ok := d.GetOk("tags"); ok && len(v.(map[string]interface{})) > 0 {
// index := 0
// for key, value := range v.(map[string]interface{}) {
// if index == 0 {
// tags = fmt.Sprintf("{\"key\": \"%s\",\"value\": \"%s\"}", key, value.(string))
// } else {
// tags = fmt.Sprintf("%s,{\"key\": \"%s\",\"value\":\"%s\"}", tags, key, value.(string))
// }
// index += 1
// }
// // tags = fmt.Sprintf("[%s]", tags)
// }
// // tagsBytes, _ := json.Marshal(tagss)
// tags = fmt.Sprintf("[%s]", tags)
tagss := make([]interface{}, 0)
if v, ok := d.GetOk("tags"); ok && len(v.(map[string]interface{})) > 0 {
for key, value := range v.(map[string]interface{}) {
tagss = append(tagss, cs.Tag{
Key: key,
Value: value.(string),
})
}
}
tagsBytes, _ := json.Marshal(tagss)
tags = string(tagsBytes)
log.Printf("checking tags %v", tags)
proxy_mode := d.Get("proxy_mode").(string)
VpcId := d.Get("vpc_id").(string)
ImageId := d.Get("image_id").(string)
var LoginPassword string
if password := d.Get("password").(string); password == "" {
if v := d.Get("kms_encrypted_password").(string); v != "" {
kmsService := KmsService{client}
decryptResp, err := kmsService.Decrypt(v, d.Get("kms_encryption_context").(map[string]interface{}))
if err != nil {
return errmsgs.WrapError(err)
}
password = decryptResp.Plaintext
}
LoginPassword = password
} else {
LoginPassword = password
}
nodecidr := d.Get("node_cidr_mask").(string)
enabSsh := d.Get("enable_ssh").(bool)
end := d.Get("slb_internet_enabled").(bool)
SnatEntry := d.Get("new_nat_gateway").(bool)
scdir := d.Get("service_cidr").(string)
pcidr := d.Get("pod_cidr").(string)
NumOfNodes := int64(d.Get("num_of_nodes").(int))
MasterSystemDiskPerformanceLevel := d.Get("master_system_disk_performance_level").(string)
WorkerSystemDiskPerformanceLevel := d.Get("worker_system_disk_performance_level").(string)
CloudMonitorFlags := d.Get("cloud_monitor_flags").(bool)
var secgroup string
var SecurityGroup string
if v, ok := d.GetOk("is_enterprise_security_group"); ok && v.(bool) {
if v, ok := d.GetOk("security_group_id"); ok && v.(string) != "" {
return fmt.Errorf("security_group_id must be `` or nil when is_enterprise_security_group is `true`")
}
secgroup = "is_enterprise_security_group"
is_enterprise_security_group := v.(bool)
SecurityGroup = fmt.Sprintf("%t", is_enterprise_security_group)
} else {
if v, ok := d.GetOk("security_group_id"); ok && v.(string) != "" {
secgroup = "security_group_id"
SecurityGroup = fmt.Sprintf("\"%s\"", d.Get("security_group_id").(string))
} else {
return fmt.Errorf("security_group_id must be set when is_enterprise_security_group is `false` or not set")
}
}
request := client.NewCommonRequest("POST", "CS", "2015-12-15", "CreateCluster", "/clusters")
request.SetContentType("application/json")
request.SetContent([]byte("{}")) // 必须指定,否则SDK会将类型修改为www-form,最终导致cr有一定的随机概率失败
var wvid, mvid, winst, minst, podid, inst string
var formatDisk, retainIname bool
wvids := d.Get("worker_vswitch_ids").([]interface{})
for i, k := range wvids {
if i == 0 {
wvid = fmt.Sprintf("%s", k)
} else {
wvid = fmt.Sprintf("%s\",\"%s", wvid, k)
}
}
log.Printf("new worker vids %v ", wvid)
mvids := d.Get("master_vswitch_ids").([]interface{})
for i, k := range mvids {
if i == 0 {
mvid = fmt.Sprintf("%s", k)
} else {
mvid = fmt.Sprintf("%s\",\"%s", mvid, k)
}
}
log.Printf("master vswids %v", mvid)
winsts := d.Get("worker_instance_types").([]interface{})
for i, k := range winsts {
if i == 0 {
winst = fmt.Sprintf("%s", k)
} else {
winst = fmt.Sprintf("%s\",\"%s", winst, k)
}
}
log.Printf("new worker inst %v ", winst)
insrsas := d.Get("master_instance_types").([]interface{})
for i, k := range insrsas {
if i == 0 {
minst = fmt.Sprintf("%s", k)
} else {
minst = fmt.Sprintf("%s\",\"%s", minst, k)
}
log.Printf("instances %d %v", i, k)
//minst = fmt.Sprintf("%s\",\"%s", minst, k)
}
//log.Printf("new master inst %v ",insrsas)
log.Printf("new master inst %v ", minst)
var insts, podids []string
if v, ok := d.GetOk("instances"); ok {
attachinst = 1
formatDisk = d.Get("format_disk").(bool)
retainIname = d.Get("keep_instance_name").(bool)
insts = expandStringList(v.(*schema.Set).List())
fmt.Print("checking instances attached: ", insts)
for i, k := range insts {
if i != 0 {
inst = fmt.Sprintf("%s\",\"%s", inst, k)
} else {
inst = k
}
}
}
log.Printf("pod request %d", pod)
clustertype := d.Get("cluster_type").(string)
log.Printf("pod is %d", pod)
if pod == 1 {
if v, ok := d.GetOk("pod_vswitch_ids"); ok {
log.Printf("123123podid is %v\n", podid)
podids = expandStringList(v.(*schema.Set).List())
log.Print("checking pod vsw ids: ", podids)
for i, k := range podids {
if i != 0 {
podid = fmt.Sprintf("%s\",\"%s", podid, k)
//minst=strings.Join(minsts,",")
} else {
podid = k
}
}
}
}
nodeportrange := d.Get("node_port_range").(string)
cpuPolicy := d.Get("cpu_policy").(string)
log.Printf("wswitchids %v mswitchids %v", wvid, mvid)
log.Printf("winsts %v minsts %v", winst, minst)
request.QueryParams = map[string]string{
"Action": "CreateCluster",
"SNatEntry": "false",
}
var body string
if attachinst == 1 {
if pod == 0 {
body = fmt.Sprintf("{\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":%d,\"%s\":%t,\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":[\"%s\"],\"%s\":[\"%s\"],\"%s\":\"%s\",\"%s\":%d,\"%s\":%d,\"%s\":%t,\"%s\":%t,\"%s\":%t,\"%s\":\"%s\",\"%s\":%d,\"%s\":%t,\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":[%s],\"%s\":\"%s\",\"%s\":[\"%s\"],\"%s\":%t,\"%s\":%t,\"%s\":\"%s\",\"%s\":{%s},\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":[%s],\"%s\":%s,\"%s\":%t,\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":%s}",
"Product", "Cs",
"os_type", OsType,
"platform", Platform,
"cluster_type", clustertype,
"region_id", client.RegionId,
"timeout_mins", timeout,
"disable_rollback", true,
"kubernetes_version", KubernetesVersion,
"container_cidr", pcidr,
"service_cidr", scdir,
"name", Name,
"master_instance_types", minst,
"master_vswitch_ids", mvid,
"login_Password", LoginPassword,
"num_of_nodes", NumOfNodes,
"master_count", mastercount,
"snat_entry", SnatEntry,
"endpoint_public_access", end,
"ssh_flags", enabSsh,
"master_system_disk_category", msysdiskcat,
"master_system_disk_size", msysdisksize,
"deletion_protection", delete_pro,
"node_cidr_mask", nodecidr,
"vpcid", VpcId,
"addons", req,
"proxy_mode", proxy_mode,
"instances", inst,
"format_disk", formatDisk,
"keep_instance_name", retainIname,
"user_data", udata,
"runtime", runtime,
"node_port_range", nodeportrange,
"cpu_policy", cpuPolicy,
"worker_data_disks", workerdisks,
secgroup, SecurityGroup,
"cloud_monitor_flags", CloudMonitorFlags,
"master_system_disk_performance_level", MasterSystemDiskPerformanceLevel,
"worker_system_disk_performance_level", WorkerSystemDiskPerformanceLevel,
"image_id", ImageId,
"tags", tags,
)
} else {
body = fmt.Sprintf("{\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":%d,\"%s\":%t,\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":[\"%s\"],\"%s\":[\"%s\"],\"%s\":\"%s\",\"%s\":%d,\"%s\":%d,\"%s\":%t,\"%s\":%t,\"%s\":%t,\"%s\":\"%s\",\"%s\":%d,\"%s\":%t,\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":[%s],\"%s\":[\"%s\"],\"%s\":\"%s\",\"%s\":[\"%s\"],\"%s\":%t,\"%s\":%t,\"%s\":\"%s\",\"%s\":{%s},\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":[%s],\"%s\":%s,\"%s\":%t,\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":%s}",
"Product", "Cs",
"os_type", OsType,
"platform", Platform,
"cluster_type", clustertype,
"region_id", client.RegionId,
"timeout_mins", timeout,
"disable_rollback", true,
"kubernetes_version", KubernetesVersion,
"container_cidr", pcidr,
"service_cidr", scdir,
"name", Name,
"master_instance_types", minst,
"master_vswitch_ids", mvid,
"login_Password", LoginPassword,
"num_of_nodes", NumOfNodes,
"master_count", mastercount,
"snat_entry", SnatEntry,
"endpoint_public_access", end,
"ssh_flags", enabSsh,
"master_system_disk_category", msysdiskcat,
"master_system_disk_size", msysdisksize,
"deletion_protection", delete_pro,
"node_cidr_mask", nodecidr,
"vpcid", VpcId,
"addons", req,
"pod_vswitch_ids", podid,
"proxy_mode", proxy_mode,
"instances", inst,
"format_disk", formatDisk,
"keep_instance_name", retainIname,
"user_data", udata,
"runtime", runtime,
"node_port_range", nodeportrange,
"cpu_policy", cpuPolicy,
"worker_data_disks", workerdisks,
secgroup, SecurityGroup,
"cloud_monitor_flags", CloudMonitorFlags,
"master_system_disk_performance_level", MasterSystemDiskPerformanceLevel,
"worker_system_disk_performance_level", WorkerSystemDiskPerformanceLevel,
"image_id", ImageId,
"tags", tags,
)
}
} else {
if pod == 0 {
body = fmt.Sprintf("{\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":%d,\"%s\":%t,\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":[\"%s\"],\"%s\":[\"%s\"],\"%s\":[\"%s\"],\"%s\":[\"%s\"],\"%s\":\"%s\",\"%s\":%d,\"%s\":%d,\"%s\":%t,\"%s\":%t,\"%s\":%t,\"%s\":\"%s\",\"%s\":%d,\"%s\":\"%s\",\"%s\":%d,\"%s\":%t,\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":[%s],\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":{%s},\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":%s,\"%s\":%t,\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":[%s],\"%s\":\"%s\",\"%s\":%s,\"%s\":\"%s\",\"%s\":%d,\"%s\":\"%s\",\"%s\":%d}",
"Product", "Cs",
"os_type", OsType,
"platform", Platform,
"cluster_type", clustertype,
"region_id", client.RegionId,
"timeout_mins", timeout,
"disable_rollback", true,
"kubernetes_version", KubernetesVersion,
"container_cidr", pcidr,
"service_cidr", scdir,
"name", Name,
"master_instance_types", minst,
"worker_instance_types", winst,
"master_vswitch_ids", mvid,
"worker_vswitch_ids", wvid,
"login_Password", LoginPassword,
"num_of_nodes", NumOfNodes,
"master_count", mastercount,
"snat_entry", SnatEntry,
"endpoint_public_access", end,
"ssh_flags", enabSsh,
"master_system_disk_category", msysdiskcat,
"master_system_disk_size", msysdisksize,
"worker_system_disk_category", wsysdiskcat,
"worker_system_disk_size", wsysdisksize,
"deletion_protection", delete_pro,
"node_cidr_mask", nodecidr,
"vpcid", VpcId,
"addons", req,
"proxy_mode", proxy_mode,
"user_data", udata,
"runtime", runtime,
"node_port_range", nodeportrange,
"cpu_policy", cpuPolicy,
secgroup, SecurityGroup,
"cloud_monitor_flags", CloudMonitorFlags,
"master_system_disk_performance_level", MasterSystemDiskPerformanceLevel,
"worker_system_disk_performance_level", WorkerSystemDiskPerformanceLevel,
"worker_data_disks", workerdisks,
"image_id", ImageId,
"tags", tags,
"master_storage_set_id", masterstoragesetid,
"master_storage_set_partition_number", masterstoragesetnumber,
"worker_storage_set_id", workerstoragesetid,
"worker_storage_set_partition_number", workerstoragesetnumber,
)
} else {
body = fmt.Sprintf("{\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":%d,\"%s\":%t,\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":[\"%s\"],\"%s\":[\"%s\"],\"%s\":[\"%s\"],\"%s\":[\"%s\"],\"%s\":\"%s\",\"%s\":%d,\"%s\":%d,\"%s\":%t,\"%s\":%t,\"%s\":%t,\"%s\":\"%s\",\"%s\":%d,\"%s\":\"%s\",\"%s\":%d,\"%s\":%t,\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":[%s],\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":{%s},\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":%s,\"%s\":%t,\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":[%s],\"%s\":[\"%s\"],\"%s\":\"%s\",\"%s\":%s,\"%s\":\"%s\",\"%s\":%d,\"%s\":\"%s\",\"%s\":%d}",
"Product", "Cs",
"os_type", OsType,
"platform", Platform,
"cluster_type", clustertype,
"region_id", client.RegionId,
"timeout_mins", timeout,
"disable_rollback", true,
"kubernetes_version", KubernetesVersion,
"container_cidr", pcidr,
"service_cidr", scdir,
"name", Name,
"master_instance_types", minst,
"worker_instance_types", winst,
"master_vswitch_ids", mvid,
"worker_vswitch_ids", wvid,
"login_Password", LoginPassword,
"num_of_nodes", NumOfNodes,
"master_count", mastercount,
"snat_entry", SnatEntry,
"endpoint_public_access", end,
"ssh_flags", enabSsh,
"master_system_disk_category", msysdiskcat,
"master_system_disk_size", msysdisksize,
"worker_system_disk_category", wsysdiskcat,
"worker_system_disk_size", wsysdisksize,
"deletion_protection", delete_pro,
"node_cidr_mask", nodecidr,
"vpcid", VpcId,
"addons", req,
"proxy_mode", proxy_mode,
"user_data", udata,
"runtime", runtime,
"node_port_range", nodeportrange,
"cpu_policy", cpuPolicy,
secgroup, SecurityGroup,
"cloud_monitor_flags", CloudMonitorFlags,
"master_system_disk_performance_level", MasterSystemDiskPerformanceLevel,
"worker_system_disk_performance_level", WorkerSystemDiskPerformanceLevel,
"worker_data_disks", workerdisks,
"pod_vswitch_ids", podid,
"image_id", ImageId,
"tags", tags,
"master_storage_set_id", masterstoragesetid,
"master_storage_set_partition_number", masterstoragesetnumber,
"worker_storage_set_id", workerstoragesetid,
"worker_storage_set_partition_number", workerstoragesetnumber,
)
}
}
request.SetContent([]byte(body))
var err error
err = nil
var cluster *responses.CommonResponse
if err = invoker.Run(func() error {
cluster, err = client.ProcessCommonRequest(request)
addDebug("CreateKubernetesCluster", cluster, request, request.QueryParams)
return err
}); err != nil {
//return errmsgs.WrapErrorf(err, errmsgs.DefaultErrorMsg, "alibabacloudstack_cs_kubernetes", "CreateKubernetesCluster", raw)
return err
}
clusterresponse := ClusterCommonResponse{}
if cluster.IsSuccess() == false {
//return errmsgs.WrapErrorf(err, errmsgs.DefaultErrorMsg, "alibabacloudstack_ascm", "API Action", cluster.GetHttpContentString())
return err
}
ok := json.Unmarshal(cluster.GetHttpContentBytes(), &clusterresponse)
if ok != nil {
return errmsgs.WrapErrorf(err, errmsgs.DefaultErrorMsg, "alibabacloudstack_cs_kubernetes", "ParseKubernetesClusterResponse", cluster)
}
d.SetId(clusterresponse.ClusterID)
stateConf := BuildStateConf([]string{"initial", " "}, []string{"running"}, d.Timeout(schema.TimeoutCreate), 15*time.Minute, csService.CsKubernetesInstanceStateRefreshFunc(d.Id(), []string{"deleting", "failed"}))
if _, err := stateConf.WaitForState(); err != nil {
return errmsgs.WrapErrorf(err, errmsgs.IdMsg, d.Id())
}
return nil
}
func resourceAlibabacloudStackCSKubernetesUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*connectivity.AlibabacloudStackClient)
csService := CsService{client}
d.Partial(true)
invoker := NewInvoker()
nodepool, err := csService.DescribeClusterNodePools(d.Id())
if err != nil {
return errmsgs.WrapError(err)
}
var nodepoolid string
for _, k := range nodepool.Nodepools {
//Considering multiple nodepools
if k.NodepoolInfo.IsDefault {
nodepoolid = k.NodepoolInfo.NodepoolID
}
}
if nodepoolid == "" {
if len(nodepool.Nodepools) == 1 && nodepool.Nodepools[0].NodepoolInfo.Name == "default-nodepool" {
nodepoolid = nodepool.Nodepools[0].NodepoolInfo.NodepoolID
} else {
return errmsgs.WrapErrorf(fmt.Errorf("can not found default node_pool"), "DescribeClusterNodePools", nodepool.Nodepools)
}
}
d.Set("nodepool_id", nodepoolid)
if d.HasChange("num_of_nodes") && !d.IsNewResource() {
password := d.Get("password").(string)
if password == "" {
if v := d.Get("kms_encrypted_password").(string); v != "" {
kmsService := KmsService{client}
decryptResp, err := kmsService.Decrypt(v, d.Get("kms_encryption_context").(map[string]interface{}))
if err != nil {
return errmsgs.WrapError(err)
}
password = decryptResp.Plaintext
}
}
oldV, newV := d.GetChange("num_of_nodes")
oldValue, ok := oldV.(int)
if ok != true {
return errmsgs.WrapErrorf(fmt.Errorf("num_of_nodes old value can not be parsed"), "parseError %d", oldValue)
}
newValue, ok := newV.(int)
if ok != true {
return errmsgs.WrapErrorf(fmt.Errorf("num_of_nodes new value can not be parsed"), "parseError %d", newValue)
}
if newValue < oldValue {
//return errmsgs.WrapErrorf(fmt.Errorf("num_of_nodes can not be less than before"), "scaleOutFailed %d:%d", newValue, oldValue)
object, err := csService.DescribeClusterNodes(d.Id(), nodepoolid)
if err != nil {
if errmsgs.NotFoundError(err) {
d.SetId("")
return nil
}
return errmsgs.WrapError(err)
}
var allNodeName []string
for _, value := range object.Nodes {
allNodeName = append(allNodeName, value.NodeName)
}
count := oldValue - newValue
removeNodesName := allNodeName[:count]
if len(removeNodesName) > 0 {
}
req := client.NewCommonRequest("POST", "CS", "2015-12-15", "RemoveClusterNodes", fmt.Sprintf("/api/v2/clusters/%s/nodes/remove", d.Id()))
body := fmt.Sprintf("{\"%s\":%t,\"%s\":%t,\"%s\":%q,\"%s\":\"%s\"}",
"release_node", true,
"drain_node", true,
"nodes", removeNodesName,
"ClusterId", d.Id(),
)
req.SetContent([]byte(body))
req.Headers["x-acs-content-type"] = "application/json"
var resp *responses.CommonResponse
if err := invoker.Run(func() error {
resp, err = client.ProcessCommonRequest(req)
return err
}); err != nil {
return errmsgs.WrapErrorf(err, errmsgs.DefaultErrorMsg, nodepoolid, "DeleteKubernetesClusterNodes", errmsgs.DenverdinoAliyungo)
}
if resp.IsSuccess() == false {
//return errmsgs.WrapErrorf(err, errmsgs.DefaultErrorMsg, "alibabacloudstack_ascm", "API Action", cluster.GetHttpContentString())
return err
}
stateConf := BuildStateConf([]string{"removing"}, []string{"active"}, d.Timeout(schema.TimeoutUpdate), 60*time.Second, csService.CsKubernetesNodePoolStateRefreshFunc(nodepoolid, d.Id(), []string{"deleting", "failed"}))
if _, err := stateConf.WaitForState(); err != nil {
return errmsgs.WrapErrorf(err, errmsgs.IdMsg, d.Id())
}
}
if newValue > oldValue {
request := client.NewCommonRequest("POST", "CS", "2015-12-15", "ScaleClusterNodePool", fmt.Sprintf("/clusters/%s/nodepools/%s", d.Id(), nodepoolid))
body := fmt.Sprintf("{\"%s\":%d}",
"count", int64(newValue)-int64(oldValue),
)
request.QueryParams["NodepoolId"] = nodepoolid
request.QueryParams["ClusterId"] = d.Id()
request.SetContent([]byte(body))
request.Headers["x-acs-content-type"] = "application/json"
//var err error
err = nil
var resp *responses.CommonResponse
if err = invoker.Run(func() error {
resp, err = client.ProcessCommonRequest(request)
return err
}); err != nil {
return errmsgs.WrapErrorf(err, errmsgs.DefaultErrorMsg, "alibabacloudstack_cs_kubernetes", "CreateKubernetesCluster", resp)
}
if debugOn() {
resizeRequestMap := make(map[string]interface{})
resizeRequestMap["ClusterId"] = d.Id()
resizeRequestMap["Args"] = request.GetQueryParams()
addDebug("ResizeKubernetesCluster", resp, resizeRequestMap)
}
stateConf := BuildStateConf([]string{"scaling"}, []string{"running"}, d.Timeout(schema.TimeoutUpdate), 10*time.Second, csService.CsKubernetesInstanceStateRefreshFunc(d.Id(), []string{"deleting", "failed"}))
if _, err := stateConf.WaitForState(); err != nil {
return errmsgs.WrapErrorf(err, errmsgs.IdMsg, d.Id())
}
//d.SetPartial("num_of_nodes")
}
}
d.Partial(false)
return nil
}
func resourceAlibabacloudStackCSKubernetesRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*connectivity.AlibabacloudStackClient)
csService := CsService{client}
object, err := csService.DescribeCsKubernetes(d.Id())
if err != nil {
if errmsgs.NotFoundError(err) {
d.SetId("")
return nil
}
return errmsgs.WrapError(err)
}
nodepoolid := d.Get("nodepool_id").(string)
clusternode, err := csService.DescribeClusterNodes(d.Id(), nodepoolid)
if err != nil {
return errmsgs.WrapError(err)
}
d.Set("name", object.Name)
//d.Set("id", object.ClusterId)
//d.Set("state", object.State)
d.Set("vpc_id", object.VpcId)
//d.Set("resource_group_id", object.ResourceGroupId)
d.Set("pod_cidr", object.ContainerCIDR)
d.Set("version", object.CurrentVersion)
d.Set("delete_protection", object.DeletionProtection)
d.Set("version", object.InitVersion)
var smaster, sworker []map[string]interface{}
//var MasterNodes, WorkerNodes map[string]interface{}
for _, k := range clusternode.Nodes {
if k.InstanceRole == "Master" {
MasterNodes := map[string]interface{}{
"id": k.InstanceID,
"name": k.InstanceName,
"private_ip": fmt.Sprintf("%s", k.IPAddress),
}
smaster = append(smaster, MasterNodes)
} else {
WorkerNodes := map[string]interface{}{
"id": k.InstanceID,
"name": k.InstanceName,
"private_ip": fmt.Sprintf("%s", k.IPAddress),
}
sworker = append(sworker, WorkerNodes)
}
}
d.Set("master_nodes", smaster)
d.Set("worker_nodes", sworker)
if err := d.Set("tags", flattenTagsConfig(object.Tags)); err != nil {
return errmsgs.WrapError(err)
}
return nil
}
func resourceAlibabacloudStackCSKubernetesDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*connectivity.AlibabacloudStackClient)
csService := CsService{client}
invoker := NewInvoker()
body := fmt.Sprintf("{\"%s\":\"%t\",\"%s\":\"%s\"}", "keep_slb", false, "ClusterId", d.Id())
request := client.NewCommonRequest("DELETE", "CS", "2015-12-15", "DeleteCluster", fmt.Sprintf("/clusters/%s", d.Id()))
request.QueryParams["ClusterId"] = d.Id()
request.SetContent([]byte(body))
request.Headers["x-acs-content-type"] = "application/json"
var response *responses.CommonResponse
err := resource.Retry(30*time.Minute, func() *resource.RetryError {
if err := invoker.Run(func() error {
var err error
response, err = client.ProcessCommonRequest(request)
addDebug("DeleteCluster", response, request, request.QueryParams)
return err
}); err != nil {
return resource.RetryableError(err)
}
return nil
})
if err != nil {
if errmsgs.IsExpectedErrors(err, []string{"ErrorClusterNotFound"}) {
return nil
}
return errmsgs.WrapErrorf(err, errmsgs.DefaultErrorMsg, d.Id(), "DeleteCluster", errmsgs.AlibabacloudStackLogGoSdkERROR)
}
stateConf := BuildStateConf([]string{"running", "deleting", "initial"}, []string{}, d.Timeout(schema.TimeoutDelete), 10*time.Minute, csService.CsKubernetesInstanceStateRefreshFunc(d.Id(), []string{"delete_failed"}))
if _, err := stateConf.WaitForState(); err != nil {
return errmsgs.WrapErrorf(err, errmsgs.IdMsg, d.Id())
}
return nil
}
func updateKubernetesClusterTag(d *schema.ResourceData, meta interface{}) error {
client := meta.(*connectivity.AlibabacloudStackClient)
csService := CsService{client}
d.Partial(true)
invoker := NewInvoker()
request := client.NewCommonRequest("POST", "CS", "2015-12-15", "ModifyClusterTags", fmt.Sprintf("/clusters/%s/tags", d.Id()))
tagss := make([]interface{}, 0)
if v, ok := d.GetOk("tags"); ok && len(v.(map[string]interface{})) > 0 {
for key, value := range v.(map[string]interface{}) {
tagss = append(tagss, cs.Tag{
Key: key,
Value: value.(string),
})
}
}
tagsBytes, _ := json.Marshal(map[string]interface{}{"tags": tagss})
request.SetContent([]byte(tagsBytes))
request.QueryParams["ClusterId"] = d.Id()
request.QueryParams["ProductName"] = "cs"
request.QueryParams["SignatureVersion"] = "1.0"
var err error
var raw *responses.CommonResponse
if err = invoker.Run(func() error {
raw, err = client.ProcessCommonRequest(request)
addDebug("ModifyClusterTags", raw, request, request.QueryParams)
return err
}); err != nil {
return errmsgs.WrapErrorf(err, errmsgs.DefaultErrorMsg, "alibabacloudstack_cs_kubernetes", "ModifyClusterTags", raw)
}
stateConf := BuildStateConf([]string{"scaling"}, []string{"running"}, d.Timeout(schema.TimeoutUpdate), 10*time.Second, csService.CsKubernetesInstanceStateRefreshFunc(d.Id(), []string{"deleting", "failed"}))
if _, err := stateConf.WaitForState(); err != nil {
return errmsgs.WrapErrorf(err, errmsgs.IdMsg, d.Id())
}
return nil
}