yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/aliyun/kube_cluster.go (about) 1 // Copyright 2019 Yunion 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package aliyun 16 17 import ( 18 "fmt" 19 "time" 20 21 "yunion.io/x/jsonutils" 22 "yunion.io/x/pkg/errors" 23 24 "yunion.io/x/cloudmux/pkg/apis" 25 "yunion.io/x/cloudmux/pkg/cloudprovider" 26 "yunion.io/x/cloudmux/pkg/multicloud" 27 ) 28 29 type SKubeCluster struct { 30 multicloud.SResourceBase 31 32 region *SRegion 33 34 Name string `json:"name"` 35 ClusterId string `json:"cluster_id"` 36 Size int `json:"size"` 37 RegionId string `json:"region_id"` 38 State string `json:"state"` 39 ClusterType string `json:"cluster_type"` 40 Created time.Time `json:"created"` 41 Updated time.Time `json:"updated"` 42 InitVersion string `json:"init_version"` 43 CurrentVersion string `json:"current_version"` 44 MetaData string `json:"meta_data"` 45 ResourceGroupId string `json:"resource_group_id"` 46 InstanceType string `json:"instance_type"` 47 VpcId string `json:"vpc_id"` 48 VswitchId string `json:"vswitch_id"` 49 VswitchCidr string `json:"vswitch_cidr"` 50 DataDiskSize int `json:"data_disk_size"` 51 DataDiskCategory string `json:"data_disk_category"` 52 SecurityGroupId string `json:"security_group_id"` 53 Tags []struct { 54 Key string 55 Value string 56 } 57 ZoneId string `json:"zone_id"` 58 NetworkMode string `json:"network_mode"` 59 SubnetCidr string `json:"subnet_cidr"` 60 MasterURL string `json:"master_url"` 61 ExternalLoadbalancerId string `json:"external_loadbalancer_id"` 62 Port int `json:"port"` 63 NodeStatus string `json:"node_status"` 64 ClusterHealthy string `json:"cluster_healthy"` 65 DockerVersion string `json:"docker_version"` 66 SwarmMode bool `json:"swarm_mode"` 67 GwBridge string `json:"gw_bridge"` 68 UpgradeComponents string `json:"upgrade_components"` 69 NextVersion string `json:"next_version"` 70 PrivateZone bool `json:"private_zone"` 71 ServiceDiscoveryTypes string `json:"service_discovery_types"` 72 PrivateLink bool `json:"private_link"` 73 Profile string `json:"profile"` 74 DeletionProtection bool `json:"deletion_protection"` 75 ClusterSpec string `json:"cluster_spec"` 76 MaintenanceWindow struct { 77 Enable bool `json:"enable"` 78 MaintenanceTime string `json:"maintenance_time"` 79 Duration string `json:"duration"` 80 WeeklyPeriod string `json:"weekly_period"` 81 } `json:"maintenance_window"` 82 Capabilities string `json:"capabilities"` 83 EnabledMigration bool `json:"enabled_migration"` 84 NeedUpdateAgent bool `json:"need_update_agent"` 85 Outputs string `json:"outputs"` 86 Parameters string `json:"parameters"` 87 WorkerRAMRoleName string `json:"worker_ram_role_name"` 88 MaintenanceInfo string `json:"maintenance_info"` 89 } 90 91 func (self *SKubeCluster) GetName() string { 92 return self.Name 93 } 94 95 func (self *SKubeCluster) GetStatus() string { 96 switch self.State { 97 case "initial": 98 return apis.STATUS_CREATING 99 case "failed": 100 return apis.STATUS_CREATE_FAILED 101 case "deleting", "deleted": 102 return apis.STATUS_DELETING 103 case "delete_failed": 104 return apis.STATUS_DELETE_FAILED 105 default: 106 return self.State 107 } 108 } 109 110 func (self *SKubeCluster) GetId() string { 111 return self.ClusterId 112 } 113 114 func (self *SKubeCluster) GetGlobalId() string { 115 return self.ClusterId 116 } 117 118 func (self *SKubeCluster) GetEnabled() bool { 119 return true 120 } 121 122 func (self *SKubeCluster) Refresh() error { 123 cluster, err := self.region.GetKubeCluster(self.ClusterId) 124 if err != nil { 125 return errors.Wrapf(err, "GetKubeCluster(%s)", self.ClusterId) 126 } 127 return jsonutils.Update(self, cluster) 128 } 129 130 func (self *SKubeCluster) GetKubeConfig(private bool, expireMinutes int) (*cloudprovider.SKubeconfig, error) { 131 return self.region.GetKubeConfig(self.ClusterId, private, expireMinutes) 132 } 133 134 func (self *SKubeCluster) Delete(isRetain bool) error { 135 return self.region.DeleteKubeCluster(self.ClusterId, isRetain) 136 } 137 138 func (self *SKubeCluster) GetTags() (map[string]string, error) { 139 ret := map[string]string{} 140 for _, tag := range self.Tags { 141 ret[tag.Key] = tag.Value 142 } 143 return ret, nil 144 } 145 146 func (self *SKubeCluster) GetSysTags() map[string]string { 147 return nil 148 } 149 150 func (self *SKubeCluster) SetTags(tags map[string]string, replace bool) error { 151 return cloudprovider.ErrNotImplemented 152 } 153 154 func (self *SRegion) GetKubeConfig(clusterId string, private bool, minutes int) (*cloudprovider.SKubeconfig, error) { 155 params := map[string]string{ 156 "PathPattern": fmt.Sprintf("/k8s/%s/user_config", clusterId), 157 "PrivateIpAddress": fmt.Sprintf("%v", private), 158 } 159 if minutes >= 15 && minutes <= 4320 { 160 params["TemporaryDurationMinutes"] = fmt.Sprintf("%d", minutes) 161 } 162 resp, err := self.k8sRequest("DescribeClusterUserKubeconfig", params) 163 if err != nil { 164 return nil, errors.Wrapf(err, "DescribeClusterUserKubeconfig") 165 } 166 result := &cloudprovider.SKubeconfig{} 167 err = resp.Unmarshal(result) 168 if err != nil { 169 return nil, errors.Wrapf(err, "resp.Unmarshal") 170 } 171 return result, nil 172 } 173 174 func (self *SRegion) GetKubeClusters(pageSize, pageNumber int) ([]SKubeCluster, int, error) { 175 if pageSize < 1 || pageSize > 100 { 176 pageSize = 100 177 } 178 if pageNumber < 1 { 179 pageNumber = 1 180 } 181 params := map[string]string{ 182 "page_size": fmt.Sprintf("%d", pageSize), 183 "page_number": fmt.Sprintf("%d", pageNumber), 184 "PathPattern": "/api/v1/clusters", 185 } 186 resp, err := self.k8sRequest("DescribeClustersV1", params) 187 if err != nil { 188 return nil, 0, errors.Wrapf(err, "DescribeClustersV1") 189 } 190 clusters := []SKubeCluster{} 191 err = resp.Unmarshal(&clusters, "clusters") 192 if err != nil { 193 return nil, 0, errors.Wrapf(err, "resp.Unmarshal") 194 } 195 totalCnt, _ := resp.Int("page_info", "total_count") 196 return clusters, int(totalCnt), nil 197 } 198 199 func (self *SRegion) GetICloudKubeClusters() ([]cloudprovider.ICloudKubeCluster, error) { 200 clusters := []SKubeCluster{} 201 for { 202 part, total, err := self.GetKubeClusters(100, len(clusters)/100+1) 203 if err != nil { 204 return nil, errors.Wrapf(err, "GetKubeClusters") 205 } 206 clusters = append(clusters, part...) 207 if len(clusters) >= total || len(part) == 0 { 208 break 209 } 210 } 211 ret := []cloudprovider.ICloudKubeCluster{} 212 for i := range clusters { 213 if clusters[i].RegionId == self.RegionId { 214 clusters[i].region = self 215 ret = append(ret, &clusters[i]) 216 } 217 } 218 return ret, nil 219 } 220 221 func (self *SRegion) GetICloudKubeClusterById(id string) (cloudprovider.ICloudKubeCluster, error) { 222 cluster, err := self.GetKubeCluster(id) 223 if err != nil { 224 return nil, errors.Wrapf(err, "GetKubeCluster(%s)", id) 225 } 226 if cluster.RegionId != self.RegionId { 227 return nil, errors.Wrapf(cloudprovider.ErrNotFound, "%s at region %s", id, cluster.RegionId) 228 } 229 return cluster, nil 230 } 231 232 func (self *SRegion) GetKubeCluster(id string) (*SKubeCluster, error) { 233 params := map[string]string{ 234 "PathPattern": fmt.Sprintf("/clusters/%s", id), 235 } 236 resp, err := self.k8sRequest("DescribeClusterDetail", params) 237 if err != nil { 238 return nil, errors.Wrapf(err, "DescribeClusterDetail") 239 } 240 cluster := &SKubeCluster{region: self} 241 err = resp.Unmarshal(&cluster) 242 if err != nil { 243 return nil, errors.Wrapf(err, "resp.Unmarshal") 244 } 245 return cluster, nil 246 } 247 248 func (self *SRegion) DeleteKubeCluster(id string, isRetain bool) error { 249 params := map[string]string{ 250 "PathPattern": fmt.Sprintf("/clusters/%s", id), 251 } 252 if isRetain { 253 params["retain_all_resources"] = "true" 254 params["keep_slb"] = "true" 255 } 256 _, err := self.k8sRequest("DeleteCluster", params) 257 return errors.Wrapf(err, "DeleteCluster") 258 }