alibabacloudstack/service_apsarastack_cs.go (566 lines of code) (raw):

package alibabacloudstack import ( "encoding/json" "fmt" "log" "time" "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" "github.com/aliyun/terraform-provider-alibabacloudstack/alibabacloudstack/connectivity" "github.com/aliyun/terraform-provider-alibabacloudstack/alibabacloudstack/errmsgs" "github.com/denverdino/aliyungo/common" "github.com/denverdino/aliyungo/cs" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) type CsService struct { client *connectivity.AlibabacloudStackClient } const ( COMPONENT_AUTO_SCALER = "cluster-autoscaler" COMPONENT_DEFAULT_VRESION = "v1.0.0" SCALING_CONFIGURATION_NAME = "kubernetes_autoscaler_autogen" DefaultECSTag = "k8s.aliyun.com" DefaultClusterTag = "ack.aliyun.com" RECYCLE_MODE_LABEL = "k8s.io/cluster-autoscaler/node-template/label/policy" DefaultAutoscalerTag = "k8s.io/cluster-autoscaler" SCALING_GROUP_NAME = "sg-%s-%s" DEFAULT_COOL_DOWN_TIME = 300 RELEASE_MODE = "release" RECYCLE_MODE = "recycle" PRIORITY_POLICY = "PRIORITY" COST_OPTIMIZED_POLICY = "COST_OPTIMIZED" BALANCE_POLICY = "BALANCE" UpgradeClusterTimeout = 30 * time.Minute ) func (s *CsService) DoCsDescribeclusterdetailRequest(id string) (cl *cs.KubernetesClusterDetail, err error) { return s.DescribeCsKubernetes(id) } func (s *CsService) DescribeCsKubernetes(id string) (cl *cs.KubernetesClusterDetail, err error) { cluster := &cs.KubernetesClusterDetail{} cluster.ClusterId = "" request := s.client.NewCommonRequest("GET", "CS", "2015-12-15", "DescribeClustersV1", "/api/v1/clusters") request.QueryParams["SignatureVersion"] = "1.0" request.QueryParams["ProductName"] = "CS" clusterdetails, err := s.client.ProcessCommonRequest(request) addDebug("DescribeClustersV1", clusterdetails, request, request.QueryParams) if err != nil { if clusterdetails == nil { return nil, errmsgs.WrapErrorf(err, "Process Common Request Failed") } if errmsgs.IsExpectedErrors(err, []string{"ErrorClusterNotFound"}) { return cluster, errmsgs.WrapErrorf(err, errmsgs.NotFoundMsg, errmsgs.DenverdinoAlibabacloudStackgo) } errmsg := errmsgs.GetBaseResponseErrorMessage(clusterdetails.BaseResponse) return cluster, errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, id, "DescribeKubernetesCluster", errmsgs.DenverdinoAlibabacloudStackgo, errmsg) } if debugOn() { requestMap := make(map[string]interface{}) requestMap["ClusterId"] = id addDebug("DescribeKubernetesCluster", clusterdetails, request, requestMap) } Cdetails := ClustersV1{} _ = json.Unmarshal(clusterdetails.GetHttpContentBytes(), &Cdetails) cluster = &cs.KubernetesClusterDetail{} for _, k := range Cdetails.Clusters { if k.ClusterID == id { cluster.Tags = k.Tags cluster.Name = k.Name cluster.State = k.State cluster.ClusterId = k.ClusterID cluster.ClusterType = cs.KubernetesClusterType(k.ClusterType) cluster.VpcId = k.VpcID cluster.ResourceGroupId = k.ResourceGroupID cluster.ContainerCIDR = k.SubnetCidr cluster.CurrentVersion = k.CurrentVersion cluster.DeletionProtection = k.DeletionProtection cluster.RegionId = common.Region(k.RegionID) cluster.Size = int64(k.Size) cluster.IngressLoadbalancerId = k.ExternalLoadbalancerID cluster.InitVersion = k.InitVersion cluster.NetworkMode = k.NetworkMode cluster.PrivateZone = k.PrivateZone cluster.Profile = k.Profile cluster.VSwitchIds = k.VswitchID break } } if cluster.ClusterId != id { return cluster, errmsgs.WrapErrorf(errmsgs.Error(errmsgs.GetNotFoundMessage("CsKubernetes", id)), errmsgs.NotFoundMsg, errmsgs.ProviderERROR) } return cluster, nil } func (s *CsService) DescribeClusterNodes(id, nodepoolid string) (pools *NodePools, err error) { request := s.client.NewCommonRequest("GET", "CS", "2015-12-15", "DescribeClusterNodes", fmt.Sprintf("/clusters/%s/nodes", id)) mergeMaps(request.QueryParams, map[string]string{ "SignatureVersion": "1.0", "nodepool_id": nodepoolid, "ClusterId": id, }) response, err := s.client.ProcessCommonRequest(request) if err != nil { if response == nil { return nil, errmsgs.WrapErrorf(err, "Process Common Request Failed") } if errmsgs.IsExpectedErrors(err, []string{"ErrorClusterNodePoolNotFound"}) { return nil, errmsgs.WrapErrorf(err, errmsgs.NotFoundMsg, errmsgs.AlibabacloudStackSdkGoERROR) } errmsg := errmsgs.GetBaseResponseErrorMessage(response.BaseResponse) return nil, errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, id, "DescribeClusterNodes", errmsgs.AlibabacloudStackSdkGoERROR, errmsg) } if !response.IsSuccess() { return nil, errmsgs.WrapErrorf(err, errmsgs.DefaultErrorMsg, id, "DescribeClusterNodes", errmsgs.AlibabacloudStackSdkGoERROR) } var clusternodepools *NodePools _ = json.Unmarshal(response.GetHttpContentBytes(), &clusternodepools) return clusternodepools, nil } func (s *CsService) DescribeClusterNodePools(id string) (*NodePool, error) { req := s.client.NewCommonRequest("GET", "CS", "2015-12-15", "DescribeClusterNodePools", fmt.Sprintf("/clusters/%s/nodepools", id)) req.QueryParams["ProductName"] = "CS" req.QueryParams["ClusterId"] = id var nodePool *responses.CommonResponse nodePool, err := s.client.ProcessCommonRequest(req) if err != nil { errmsg := "" if nodePool != nil { errmsg = errmsgs.GetBaseResponseErrorMessage(nodePool.BaseResponse) } return nil, errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, "alibabacloudstack_cs_kubernetes", "DescribeClusterNodePools", nodePool, errmsg) } var node *NodePool if nodePool.IsSuccess() == false { return nil, errmsgs.WrapErrorf(err, errmsgs.DefaultErrorMsg, "alibabacloudstack_ascm", "API Action", nodePool.GetHttpContentString()) } err = json.Unmarshal(nodePool.GetHttpContentBytes(), &node) if err != nil { return nil, errmsgs.WrapErrorf(err, errmsgs.DefaultErrorMsg, "alibabacloudstack_cs_kubernetes", "DescribeClusterNodePools", nodePool) } return node, nil } func (s *CsService) CsKubernetesInstanceStateRefreshFunc(id string, failStates []string) resource.StateRefreshFunc { return func() (interface{}, string, error) { object, err := s.DescribeCsKubernetes(id) if err != nil { if errmsgs.NotFoundError(err) { // Set this to nil as if we didn't find anything. return nil, "", nil } return nil, "", errmsgs.WrapError(err) } for _, failState := range failStates { if object.State == failState { return object, object.State, errmsgs.WrapError(errmsgs.Error(errmsgs.FailedToReachTargetStatus, object.State)) } } return object, object.State, nil } } func (s *CsService) CsKubernetesNodePoolStateRefreshFunc(id, clusterid string, failStates []string) resource.StateRefreshFunc { return func() (interface{}, string, error) { object, err := s.DescribeCsKubernetesNodePool(id, clusterid) if err != nil { if errmsgs.NotFoundError(err) { // Set this to nil as if we didn't find anything. return nil, "", nil } return nil, "", errmsgs.WrapError(err) } for _, failState := range failStates { if string(object.Status.State) == failState { return object, string(object.Status.State), errmsgs.WrapError(errmsgs.Error(errmsgs.FailedToReachTargetStatus, string(object.Status.State))) } } return object, string(object.Status.State), nil } } func (s *CsService) DescribeCsKubernetesNodePool(id, clusterid string) (*NodePoolAlone, error) { req := s.client.NewCommonRequest("GET", "CS", "2015-12-15", "DescribeClusterNodePoolDetail", fmt.Sprintf("/clusters/%s/nodepools/%s", clusterid, id)) req.Headers["x-acs-asapi-gateway-version"] = "3.0" req.QueryParams["ClusterId"] = clusterid req.QueryParams["NodepoolId"] = id response, err := s.client.ProcessCommonRequest(req) if err != nil || !response.IsSuccess() { if response == nil { return nil, errmsgs.WrapErrorf(err, "Process Common Request Failed") } if errmsgs.IsExpectedErrors(err, []string{"<QuerySeter> no row found"}) { return nil, errmsgs.WrapErrorf(err, errmsgs.NotFoundMsg, errmsgs.DenverdinoAlibabacloudStackgo) } errmsg := errmsgs.GetBaseResponseErrorMessage(response.BaseResponse) return nil, errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, "alibabacloudstack_cs_nodepool", "DescribeNodePool", response, errmsg) } var node *NodePoolAlone err = json.Unmarshal(response.GetHttpContentBytes(), &node) if err != nil { return nil, errmsgs.WrapErrorf(err, errmsgs.DefaultErrorMsg, "alibabacloudstack_cs_nodepool", "ParsenodepoolResponse", response) } return node, nil } func (s *CsService) UpgradeCluster(clusterId string, args *cs.UpgradeClusterArgs) error { invoker := NewInvoker() err := invoker.Run(func() error { _, e := s.client.WithCsClient(func(csClient *cs.Client) (interface{}, error) { return nil, csClient.UpgradeCluster(clusterId, args) }) if e != nil { return e } return nil }) if err != nil { return errmsgs.WrapError(err) } state, upgradeError := s.WaitForUpgradeCluster(clusterId, "Upgrade") if state == cs.Task_Status_Success && upgradeError == nil { return nil } // if upgrade failed cancel the task err = invoker.Run(func() error { _, e := s.client.WithCsClient(func(csClient *cs.Client) (interface{}, error) { return nil, csClient.CancelUpgradeCluster(clusterId) }) if e != nil { return e } return nil }) if err != nil { return errmsgs.WrapError(upgradeError) } if state, err := s.WaitForUpgradeCluster(clusterId, "CancelUpgrade"); err != nil || state != cs.Task_Status_Success { log.Printf("[WARN] %s ACK Cluster cancel upgrade error: %#v", clusterId, err) } return errmsgs.WrapError(upgradeError) } func (s *CsService) WaitForUpgradeCluster(clusterId string, action string) (string, error) { err := resource.Retry(UpgradeClusterTimeout, func() *resource.RetryError { resp, err := s.client.WithCsClient(func(csClient *cs.Client) (interface{}, error) { return csClient.QueryUpgradeClusterResult(clusterId) }) if err != nil || resp == nil { return resource.RetryableError(err) } upgradeResult := resp.(*cs.UpgradeClusterResult) if upgradeResult.UpgradeStep == cs.UpgradeStep_Success { return nil } if upgradeResult.UpgradeStep == cs.UpgradeStep_Pause && upgradeResult.UpgradeStatus.Failed == "true" { msg := "" events := upgradeResult.UpgradeStatus.Events if len(events) > 0 { msg = events[len(events)-1].Message } return resource.NonRetryableError(fmt.Errorf("faild to %s cluster, error: %s", action, msg)) } return resource.RetryableError(fmt.Errorf("%s cluster state not matched", action)) }) if err == nil { log.Printf("[INFO] %s ACK Cluster %s successed", action, clusterId) return cs.Task_Status_Success, nil } return cs.Task_Status_Failed, errmsgs.WrapError(err) } type Cluster struct { _ string `json:"-"` Department int64 `json:"Department"` DepartmentName string `json:"DepartmentName"` ResourceGroup int64 `json:"ResourceGroup"` ResourceGroupName string `json:"ResourceGroupName"` ClusterHealthy string `json:"cluster_healthy"` ClusterID string `json:"cluster_id"` ClusterType string `json:"cluster_type"` Created string `json:"created"` CurrentVersion string `json:"current_version"` DataDiskCategory string `json:"data_disk_category"` DataDiskSize int64 `json:"data_disk_size"` DeletionProtection bool `json:"deletion_protection"` DockerVersion string `json:"docker_version"` EnabledMigration bool `json:"enabled_migration"` ErrMsg string `json:"err_msg"` ExternalLoadbalancerID string `json:"external_loadbalancer_id"` GwBridge string `json:"gw_bridge"` InitVersion string `json:"init_version"` InstanceType string `json:"instance_type"` MasterURL string `json:"master_url"` MetaData string `json:"meta_data"` Name string `json:"name"` NeedUpdateAgent bool `json:"need_update_agent"` NetworkMode string `json:"network_mode"` NodeStatus string `json:"node_status"` Outputs []struct { Description string `json:"Description"` OutputKey string `json:"OutputKey"` OutputValue interface{} `json:"OutputValue"` } `json:"outputs"` Parameters struct { ALIYUN__AccountID string `json:"ALIYUN::AccountId"` ALIYUN__NoValue string `json:"ALIYUN::NoValue"` ALIYUN__Region string `json:"ALIYUN::Region"` ALIYUN__StackID string `json:"ALIYUN::StackId"` ALIYUN__StackName string `json:"ALIYUN::StackName"` AdjustmentType string `json:"AdjustmentType"` AuditFlags string `json:"AuditFlags"` BetaVersion string `json:"BetaVersion"` Ca string `json:"CA"` ClientCA string `json:"ClientCA"` CloudMonitorFlags string `json:"CloudMonitorFlags"` CloudMonitorVersion string `json:"CloudMonitorVersion"` ContainerCIDR string `json:"ContainerCIDR"` DockerVersion string `json:"DockerVersion"` Eip string `json:"Eip"` EipAddress string `json:"EipAddress"` ElasticSearchHost string `json:"ElasticSearchHost"` ElasticSearchPass string `json:"ElasticSearchPass"` ElasticSearchPort string `json:"ElasticSearchPort"` ElasticSearchUser string `json:"ElasticSearchUser"` EtcdVersion string `json:"EtcdVersion"` ExecuteVersion string `json:"ExecuteVersion"` GPUFlags string `json:"GPUFlags"` HealthCheckType string `json:"HealthCheckType"` IPVSEnable string `json:"IPVSEnable"` ImageID string `json:"ImageId"` K8SMasterPolicyDocument string `json:"K8SMasterPolicyDocument"` K8sWorkerPolicyDocument string `json:"K8sWorkerPolicyDocument"` Key string `json:"Key"` KeyPair string `json:"KeyPair"` KubernetesVersion string `json:"KubernetesVersion"` LoggingType string `json:"LoggingType"` MasterAutoRenew string `json:"MasterAutoRenew"` MasterAutoRenewPeriod string `json:"MasterAutoRenewPeriod"` MasterDataDisk string `json:"MasterDataDisk"` MasterDataDiskCategory string `json:"MasterDataDiskCategory"` MasterDataDiskDevice string `json:"MasterDataDiskDevice"` MasterDataDiskSize string `json:"MasterDataDiskSize"` MasterImageID string `json:"MasterImageId"` MasterInstanceChargeType string `json:"MasterInstanceChargeType"` MasterInstanceType string `json:"MasterInstanceType"` MasterKeyPair string `json:"MasterKeyPair"` MasterLoginPassword string `json:"MasterLoginPassword"` MasterPeriod string `json:"MasterPeriod"` MasterPeriodUnit string `json:"MasterPeriodUnit"` MasterSystemDiskCategory string `json:"MasterSystemDiskCategory"` MasterSystemDiskSize string `json:"MasterSystemDiskSize"` NatGateway string `json:"NatGateway"` NatGatewayID string `json:"NatGatewayId"` Network string `json:"Network"` NodeCIDRMask string `json:"NodeCIDRMask"` NumOfNodes string `json:"NumOfNodes"` Password string `json:"Password"` ProtectedInstances string `json:"ProtectedInstances"` PublicSLB string `json:"PublicSLB"` RemoveInstanceIds string `json:"RemoveInstanceIds"` SLSProjectName string `json:"SLSProjectName"` SNatEntry string `json:"SNatEntry"` SSHFlags string `json:"SSHFlags"` ServiceCIDR string `json:"ServiceCIDR"` SnatTableID string `json:"SnatTableId"` UserCA string `json:"UserCA"` VSwitchID string `json:"VSwitchId"` VpcID string `json:"VpcId"` WillReplace string `json:"WillReplace"` WorkerAutoRenew string `json:"WorkerAutoRenew"` WorkerAutoRenewPeriod string `json:"WorkerAutoRenewPeriod"` WorkerDataDisk string `json:"WorkerDataDisk"` WorkerDataDiskCategory string `json:"WorkerDataDiskCategory"` WorkerDataDiskDevice string `json:"WorkerDataDiskDevice"` WorkerDataDiskSize string `json:"WorkerDataDiskSize"` WorkerImageID string `json:"WorkerImageId"` WorkerInstanceChargeType string `json:"WorkerInstanceChargeType"` WorkerInstanceType string `json:"WorkerInstanceType"` WorkerKeyPair string `json:"WorkerKeyPair"` WorkerLoginPassword string `json:"WorkerLoginPassword"` WorkerPeriod string `json:"WorkerPeriod"` WorkerPeriodUnit string `json:"WorkerPeriodUnit"` WorkerSystemDiskCategory string `json:"WorkerSystemDiskCategory"` WorkerSystemDiskSize string `json:"WorkerSystemDiskSize"` ZoneID string `json:"ZoneId"` } `json:"parameters"` Port int64 `json:"port"` PrivateZone bool `json:"private_zone"` Profile string `json:"profile"` RegionID string `json:"region_id"` ResourceGroupID string `json:"resource_group_id"` SecurityGroupID string `json:"security_group_id"` Size int64 `json:"size"` State string `json:"state"` SubnetCidr string `json:"subnet_cidr"` SwarmMode bool `json:"swarm_mode"` Updated string `json:"updated"` UpgradeComponents struct { Kubernetes struct { CanUpgrade bool `json:"can_upgrade"` Changed string `json:"changed"` ComponentName string `json:"component_name"` Exist bool `json:"exist"` Force bool `json:"force"` Message string `json:"message"` NextVersion string `json:"next_version"` Policy string `json:"policy"` ReadyToUpgrade string `json:"ready_to_upgrade"` Required bool `json:"required"` Version string `json:"version"` } `json:"Kubernetes"` } `json:"upgrade_components"` VpcID string `json:"vpc_id"` VswitchCidr string `json:"vswitch_cidr"` VswitchID string `json:"vswitch_id"` ZoneID string `json:"zone_id"` } type NodePools struct { Nodes []struct { CreationTime time.Time `json:"creation_time"` ErrorMessage string `json:"error_message"` InstanceName string `json:"instance_name"` NodeStatus string `json:"node_status"` IsAliyunNode bool `json:"is_aliyun_node"` NodeName string `json:"node_name"` ExpiredTime time.Time `json:"expired_time"` IPAddress []string `json:"ip_address"` Source string `json:"source"` InstanceTypeFamily string `json:"instance_type_family"` InstanceID string `json:"instance_id"` InstanceChargeType string `json:"instance_charge_type"` InstanceRole string `json:"instance_role"` State string `json:"state"` InstanceStatus string `json:"instance_status"` ImageID string `json:"image_id"` InstanceType string `json:"instance_type"` NodepoolID string `json:"nodepool_id"` HostName string `json:"host_name"` } `json:"nodes"` Page struct { PageNumber int `json:"page_number"` TotalCount int `json:"total_count"` PageSize int `json:"page_size"` } `json:"page"` } type NodePool struct { Nodepools []NodePoolAlone `json:"nodepools"` } type NodePoolAlone struct { TeeConfig struct { TeeEnable bool `json:"tee_enable"` TeeType string `json:"tee_type"` } `json:"tee_config"` ScalingGroup struct { InstanceTypes []string `json:"instance_types"` PeriodUnit string `json:"period_unit"` SecurityGroupID string `json:"security_group_id"` MultiAzPolicy string `json:"multi_az_policy"` Platform string `json:"platform"` WorkerHpcClusterID string `json:"worker_hpc_cluster_id"` DataDisks []cs.NodePoolDataDisk `json:"data_disks"` RAMPolicy string `json:"ram_policy"` LoginPassword string `json:"login_password"` InstanceChargeType string `json:"instance_charge_type"` VswitchIds []string `json:"vswitch_ids"` ScalingGroupID string `json:"scaling_group_id"` Period int `json:"period"` AutoRenewPeriod int `json:"auto_renew_period"` WorkerDeploymentsetID string `json:"worker_deploymentset_id"` KeyPair string `json:"key_pair"` SpotStrategy string `json:"spot_strategy"` SystemDiskSize int `json:"system_disk_size"` Tags []cs.Tag `json:"tags"` SpotPriceLimit []cs.SpotPrice `json:"spot_price_limit"` AutoRenew bool `json:"auto_renew"` SystemDiskCategory string `json:"system_disk_category"` RdsInstances []interface{} `json:"rds_instances"` WorkerSystemDiskSnapshotPolicyID string `json:"worker_system_disk_snapshot_policy_id"` ImageID string `json:"image_id"` ScalingPolicy string `json:"scaling_policy"` } `json:"scaling_group"` KubernetesConfig struct { RuntimeVersion string `json:"runtime_version"` CPUPolicy string `json:"cpu_policy"` CmsEnabled bool `json:"cms_enabled"` Runtime string `json:"runtime"` OverwriteHostname bool `json:"overwrite_hostname"` UserData string `json:"user_data"` NodeNameMode string `json:"node_name_mode"` Unschedulable bool `json:"unschedulable"` Taints []cs.Taint `json:"taints"` Labels []cs.Label `json:"labels"` } `json:"kubernetes_config"` AutoScaling cs.AutoScaling `json:"auto_scaling"` NodepoolInfo struct { ResourceGroupID string `json:"resource_group_id"` Created time.Time `json:"created"` RegionID string `json:"region_id"` Name string `json:"name"` IsDefault bool `json:"is_default"` Type string `json:"type"` NodepoolID string `json:"nodepool_id"` Updated time.Time `json:"updated"` } `json:"nodepool_info"` Status struct { ServingNodes int `json:"serving_nodes"` TotalNodes int `json:"total_nodes"` State string `json:"state"` OfflineNodes int `json:"offline_nodes"` RemovingNodes int `json:"removing_nodes"` InitialNodes int `json:"initial_nodes"` FailedNodes int `json:"failed_nodes"` HealthyNodes int `json:"healthy_nodes"` } `json:"status"` } type ClustersV1 struct { Redirect bool `json:"redirect"` EagleEyeTraceID string `json:"eagleEyeTraceId"` AsapiSuccess bool `json:"asapiSuccess"` Code string `json:"code"` Cost int `json:"cost"` Message string `json:"message"` ServerRole string `json:"serverRole"` AsapiRequestID string `json:"asapiRequestId"` Success bool `json:"success"` PageInfo struct { PageNumber int `json:"page_number"` TotalCount int `json:"total_count"` PageSize int `json:"page_size"` } `json:"page_info"` Domain string `json:"domain"` PureListData bool `json:"pureListData"` API string `json:"api"` Clusters []struct { Tags []cs.Tag `json:"tags"` ResourceGroupID string `json:"resource_group_id"` PrivateZone bool `json:"private_zone"` VpcID string `json:"vpc_id"` NetworkMode string `json:"network_mode"` SecurityGroupID string `json:"security_group_id"` ClusterType string `json:"cluster_type"` DockerVersion string `json:"docker_version"` DataDiskCategory string `json:"data_disk_category"` NextVersion string `json:"next_version"` ZoneID string `json:"zone_id"` ClusterID string `json:"cluster_id"` Department int `json:"Department"` ExternalLoadbalancerID string `json:"external_loadbalancer_id"` VswitchID string `json:"vswitch_id"` SwarmMode bool `json:"swarm_mode"` RMRegionID string `json:"RMRegionId"` State string `json:"state"` ResourceGroup int `json:"ResourceGroup"` InitVersion string `json:"init_version"` NodeStatus string `json:"node_status"` NeedUpdateAgent bool `json:"need_update_agent"` Created time.Time `json:"created"` DeletionProtection bool `json:"deletion_protection"` SubnetCidr string `json:"subnet_cidr"` Profile string `json:"profile"` RegionID string `json:"region_id"` MasterURL string `json:"master_url"` CurrentVersion string `json:"current_version"` NAMING_FAILED string `json:"-"` VswitchCidr string `json:"vswitch_cidr"` ClusterHealthy string `json:"cluster_healthy"` ClusterSpec string `json:"cluster_spec"` Size int `json:"size"` DataDiskSize int `json:"data_disk_size"` Port int `json:"port"` EnabledMigration bool `json:"enabled_migration"` Name string `json:"name"` DepartmentName string `json:"DepartmentName"` Updated time.Time `json:"updated"` InstanceType string `json:"instance_type"` WorkerRAMRoleName string `json:"worker_ram_role_name"` ResourceGroupName string `json:"ResourceGroupName"` } `json:"clusters"` }