yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/ctyun/region.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 ctyun 16 17 import ( 18 "fmt" 19 "strconv" 20 21 "yunion.io/x/jsonutils" 22 "yunion.io/x/pkg/errors" 23 24 api "yunion.io/x/cloudmux/pkg/apis/compute" 25 "yunion.io/x/cloudmux/pkg/cloudprovider" 26 "yunion.io/x/cloudmux/pkg/multicloud" 27 ) 28 29 type SRegion struct { 30 cloudprovider.SFakeOnPremiseRegion 31 multicloud.SRegion 32 multicloud.SNoObjectStorageRegion 33 34 client *SCtyunClient 35 storageCache *SStoragecache 36 37 // 38 initialled bool 39 40 RegionName string 41 Description string `json:"description"` 42 ID string `json:"id"` 43 ParentRegionID string `json:"parent_region_id"` 44 Type string `json:"type"` 45 46 izones []cloudprovider.ICloudZone 47 ivpcs []cloudprovider.ICloudVpc 48 } 49 50 func (self *SRegion) fetchIVpcs() error { 51 vpcs, err := self.GetVpcs() 52 if err != nil { 53 return errors.Wrap(err, "SRegion.fetchIVpcs") 54 } 55 56 self.ivpcs = make([]cloudprovider.ICloudVpc, 0) 57 for i := range vpcs { 58 vpc := vpcs[i] 59 vpc.region = self 60 self.ivpcs = append(self.ivpcs, &vpc) 61 } 62 63 return nil 64 } 65 66 func (self *SRegion) fetchInfrastructure() error { 67 if err := self.fetchIVpcs(); err != nil { 68 return err 69 } 70 71 for i := 0; i < len(self.ivpcs); i += 1 { 72 vpc := self.ivpcs[i].(*SVpc) 73 wire := SWire{region: self, vpc: vpc} 74 vpc.addWire(&wire) 75 76 for j := 0; j < len(self.izones); j += 1 { 77 zone := self.izones[j].(*SZone) 78 zone.addWire(&wire) 79 } 80 81 vpc.fetchNetworks() 82 } 83 return nil 84 } 85 86 func (self *SRegion) GetVpcs() ([]SVpc, error) { 87 vpcs := make([]SVpc, 0) 88 params := map[string]string{ 89 "regionId": self.GetId(), 90 } 91 92 resp, err := self.client.DoGet("/apiproxy/v3/getVpcs", params) 93 if err != nil { 94 return nil, err 95 } 96 97 err = resp.Unmarshal(&vpcs, "returnObj") 98 if err != nil { 99 return nil, err 100 } 101 102 return vpcs, nil 103 } 104 105 func (self *SRegion) CreateVpc(name, cidr string) (*SVpc, error) { 106 params := map[string]jsonutils.JSONObject{ 107 "regionId": jsonutils.NewString(self.GetId()), 108 "name": jsonutils.NewString(name), 109 "cidr": jsonutils.NewString(cidr), 110 } 111 resp, err := self.client.DoPost("/apiproxy/v3/createVPC", params) 112 if err != nil { 113 return nil, err 114 } 115 116 vpc := &SVpc{} 117 err = resp.Unmarshal(vpc, "returnObj") 118 if err != nil { 119 return nil, err 120 } 121 122 vpc.ResVpcID, _ = resp.GetString("returnObj", "id") 123 vpc.region = self 124 return vpc, nil 125 } 126 127 func (self *SRegion) GetClient() *SCtyunClient { 128 return self.client 129 } 130 131 func (self *SRegion) GetISecurityGroupById(secgroupId string) (cloudprovider.ICloudSecurityGroup, error) { 132 return self.GetSecurityGroupDetails(secgroupId) 133 } 134 135 func (self *SRegion) GetISecurityGroupByName(opts *cloudprovider.SecurityGroupFilterOptions) (cloudprovider.ICloudSecurityGroup, error) { 136 segroups, err := self.GetSecurityGroups(opts.VpcId) 137 if err != nil { 138 return nil, errors.Wrap(err, "SRegion.GetISecurityGroupByName.GetSecurityGroups") 139 } 140 141 for i := range segroups { 142 if segroups[i].Name == opts.Name { 143 return &segroups[i], nil 144 } 145 } 146 147 return nil, errors.Wrap(cloudprovider.ErrNotFound, "SRegion.GetISecurityGroupByName.GetSecurityGroups") 148 } 149 150 func (self *SRegion) CreateISecurityGroup(conf *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) { 151 secgroup, err := self.CreateSecurityGroup(conf.VpcId, conf.Name) 152 if err != nil { 153 return nil, errors.Wrap(err, "Region.CreateISecurityGroup") 154 } 155 156 return secgroup, nil 157 } 158 159 func (self *SRegion) GetId() string { 160 return self.ID 161 } 162 163 func (self *SRegion) GetName() string { 164 return fmt.Sprintf("%s %s", CLOUD_PROVIDER_CTYUN_CN, self.RegionName) 165 } 166 167 func (self *SRegion) GetI18n() cloudprovider.SModelI18nTable { 168 en := fmt.Sprintf("%s %s", CLOUD_PROVIDER_CTYUN_EN, self.RegionName) 169 table := cloudprovider.SModelI18nTable{} 170 table["name"] = cloudprovider.NewSModelI18nEntry(self.GetName()).CN(self.GetName()).EN(en) 171 return table 172 } 173 174 func (self *SRegion) GetGlobalId() string { 175 return fmt.Sprintf("%s/%s", self.client.GetAccessEnv(), self.ID) 176 } 177 178 func (self *SRegion) GetStatus() string { 179 return api.CLOUD_REGION_STATUS_INSERVER 180 } 181 182 func (self *SRegion) Refresh() error { 183 return nil 184 } 185 186 func (self *SRegion) IsEmulated() bool { 187 return false 188 } 189 190 func (self *SRegion) GetGeographicInfo() cloudprovider.SGeographicInfo { 191 if info, ok := LatitudeAndLongitude[self.ID]; ok { 192 return info 193 } 194 return cloudprovider.SGeographicInfo{} 195 } 196 197 // http://ctyun-api-url/apiproxy/v3/order/getZoneConfig 198 func (self *SRegion) GetIZones() ([]cloudprovider.ICloudZone, error) { 199 if self.izones == nil || self.initialled == false { 200 var err error 201 err = self.fetchInfrastructure() 202 if err != nil { 203 return nil, err 204 } 205 206 self.initialled = true 207 } 208 return self.izones, nil 209 } 210 211 // http://ctyun-api-url/apiproxy/v3/getVpcs 212 // http://ctyun-api-url/apiproxy/v3/getVpcs 213 func (self *SRegion) GetIVpcs() ([]cloudprovider.ICloudVpc, error) { 214 if self.ivpcs == nil || self.initialled == false { 215 err := self.fetchInfrastructure() 216 if err != nil { 217 return nil, err 218 } 219 220 self.initialled = true 221 } 222 return self.ivpcs, nil 223 } 224 225 // http://ctyun-api-url/apiproxy/v3/ondemand/queryIps 226 func (self *SRegion) GetIEips() ([]cloudprovider.ICloudEIP, error) { 227 eips, err := self.GetEips() 228 if err != nil { 229 return nil, errors.Wrap(err, "SRegion.GetIEips.GetEips") 230 } 231 232 ieips := make([]cloudprovider.ICloudEIP, len(eips)) 233 for i := range eips { 234 ieips[i] = &eips[i] 235 } 236 237 return ieips, nil 238 } 239 240 func (self *SRegion) GetIVpcById(id string) (cloudprovider.ICloudVpc, error) { 241 ivpcs, err := self.GetIVpcs() 242 if err != nil { 243 return nil, err 244 } 245 for i := 0; i < len(ivpcs); i += 1 { 246 if ivpcs[i].GetGlobalId() == id { 247 return ivpcs[i], nil 248 } 249 } 250 return nil, cloudprovider.ErrNotFound 251 } 252 253 func (self *SRegion) GetIZoneById(id string) (cloudprovider.ICloudZone, error) { 254 izones, err := self.GetIZones() 255 if err != nil { 256 return nil, err 257 } 258 for i := 0; i < len(izones); i += 1 { 259 if izones[i].GetGlobalId() == id { 260 return izones[i], nil 261 } 262 } 263 return nil, cloudprovider.ErrNotFound 264 } 265 266 func (self *SRegion) GetIEipById(id string) (cloudprovider.ICloudEIP, error) { 267 return self.GetEip(id) 268 } 269 270 func (self *SRegion) GetIVMById(id string) (cloudprovider.ICloudVM, error) { 271 return self.GetVMById(id) 272 } 273 274 func (self *SRegion) GetIDiskById(id string) (cloudprovider.ICloudDisk, error) { 275 return self.GetDisk(id) 276 } 277 278 func (self *SRegion) DeleteSecurityGroup(securityGroupId string) error { 279 params := map[string]jsonutils.JSONObject{ 280 "regionId": jsonutils.NewString(self.GetId()), 281 "securityGroupId": jsonutils.NewString(securityGroupId), 282 } 283 284 resp, err := self.client.DoPost("/apiproxy/v3/deleteSecurityGroup", params) 285 if err != nil { 286 return errors.Wrap(err, "SRegion.DeleteSecurityGroup.DoPost") 287 } 288 289 var statusCode int 290 err = resp.Unmarshal(&statusCode, "statusCode") 291 if statusCode != 800 { 292 return errors.Wrap(fmt.Errorf(strconv.Itoa(statusCode)), "SRegion.DeleteSecurityGroup.JobFailed") 293 } 294 295 return nil 296 } 297 298 func (self *SRegion) CreateIVpc(opts *cloudprovider.VpcCreateOptions) (cloudprovider.ICloudVpc, error) { 299 return self.CreateVpc(opts.NAME, opts.CIDR) 300 } 301 302 func (self *SRegion) CreateEIP(eip *cloudprovider.SEip) (cloudprovider.ICloudEIP, error) { 303 zones, err := self.GetIZones() 304 if err != nil { 305 return nil, errors.Wrap(err, "SRegion.CreateEIP.GetIZones") 306 } 307 308 if len(zones) == 0 { 309 return nil, errors.Wrap(errors.ErrNotFound, "SRegion.CreateEIP.GetIZones") 310 } 311 312 return self.CreateEip(zones[0].GetId(), eip.Name, strconv.Itoa(eip.BandwidthMbps), "PER", eip.ChargeType) 313 } 314 315 func (self *SRegion) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) { 316 return []cloudprovider.ICloudSnapshot{}, nil 317 } 318 319 func (self *SRegion) GetISnapshotById(snapshotId string) (cloudprovider.ICloudSnapshot, error) { 320 return nil, cloudprovider.ErrNotFound 321 } 322 323 func (self *SRegion) CreateSnapshotPolicy(*cloudprovider.SnapshotPolicyInput) (string, error) { 324 return "", cloudprovider.ErrNotImplemented 325 } 326 327 func (self *SRegion) UpdateSnapshotPolicy(*cloudprovider.SnapshotPolicyInput, string) error { 328 return cloudprovider.ErrNotImplemented 329 } 330 331 func (self *SRegion) DeleteSnapshotPolicy(policyId string) error { 332 return cloudprovider.ErrNotImplemented 333 } 334 335 func (self *SRegion) ApplySnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error { 336 return cloudprovider.ErrNotImplemented 337 } 338 339 func (self *SRegion) CancelSnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error { 340 return cloudprovider.ErrNotImplemented 341 } 342 343 func (self *SRegion) GetISnapshotPolicies() ([]cloudprovider.ICloudSnapshotPolicy, error) { 344 polices, err := self.GetDiskBackupPolices() 345 if err != nil { 346 return nil, errors.Wrap(err, "SRegion.GetISnapshotPolicies.GetDiskBackupPolices") 347 } 348 349 ipolices := make([]cloudprovider.ICloudSnapshotPolicy, len(polices)) 350 for i := range polices { 351 ipolices[i] = &polices[i] 352 } 353 354 return ipolices, nil 355 } 356 357 func (self *SRegion) GetISnapshotPolicyById(snapshotPolicyId string) (cloudprovider.ICloudSnapshotPolicy, error) { 358 return self.GetDiskBackupPolicy(snapshotPolicyId) 359 } 360 361 func (self *SRegion) GetIHosts() ([]cloudprovider.ICloudHost, error) { 362 iHosts := make([]cloudprovider.ICloudHost, 0) 363 364 izones, err := self.GetIZones() 365 if err != nil { 366 return nil, err 367 } 368 for i := 0; i < len(izones); i += 1 { 369 iZoneHost, err := izones[i].GetIHosts() 370 if err != nil { 371 return nil, err 372 } 373 iHosts = append(iHosts, iZoneHost...) 374 } 375 return iHosts, nil 376 } 377 378 func (self *SRegion) GetIHostById(id string) (cloudprovider.ICloudHost, error) { 379 izones, err := self.GetIZones() 380 if err != nil { 381 return nil, err 382 } 383 for i := 0; i < len(izones); i += 1 { 384 ihost, err := izones[i].GetIHostById(id) 385 if err == nil { 386 return ihost, nil 387 } else if errors.Cause(err) != cloudprovider.ErrNotFound { 388 return nil, err 389 } 390 } 391 return nil, cloudprovider.ErrNotFound 392 } 393 394 func (self *SRegion) GetIStorages() ([]cloudprovider.ICloudStorage, error) { 395 iStores := make([]cloudprovider.ICloudStorage, 0) 396 397 izones, err := self.GetIZones() 398 if err != nil { 399 return nil, err 400 } 401 for i := 0; i < len(izones); i += 1 { 402 iZoneStores, err := izones[i].GetIStorages() 403 if err != nil { 404 return nil, err 405 } 406 iStores = append(iStores, iZoneStores...) 407 } 408 return iStores, nil 409 } 410 411 func (self *SRegion) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) { 412 izones, err := self.GetIZones() 413 if err != nil { 414 return nil, err 415 } 416 for i := 0; i < len(izones); i += 1 { 417 istore, err := izones[i].GetIStorageById(id) 418 if err == nil { 419 return istore, nil 420 } else if errors.Cause(err) != cloudprovider.ErrNotFound { 421 return nil, err 422 } 423 } 424 return nil, cloudprovider.ErrNotFound 425 } 426 427 func (self *SRegion) GetIStoragecaches() ([]cloudprovider.ICloudStoragecache, error) { 428 storageCache := self.getStoragecache() 429 return []cloudprovider.ICloudStoragecache{storageCache}, nil 430 } 431 432 func (self *SRegion) GetIStoragecacheById(id string) (cloudprovider.ICloudStoragecache, error) { 433 storageCache := self.getStoragecache() 434 if storageCache.GetGlobalId() == id { 435 return storageCache, nil 436 } 437 return nil, cloudprovider.ErrNotFound 438 } 439 440 func (self *SRegion) GetProvider() string { 441 return api.CLOUD_PROVIDER_CTYUN 442 } 443 444 func (self *SRegion) GetInstances(instanceId string) ([]SInstance, error) { 445 params := map[string]string{ 446 "regionId": self.GetId(), 447 } 448 449 if len(instanceId) > 0 { 450 params["instanceId"] = instanceId 451 } 452 453 resp, err := self.client.DoGet("/apiproxy/v3/ondemand/queryVMs", params) 454 if err != nil { 455 return nil, errors.Wrap(err, "SRegion.GetInstances.DoGet") 456 } 457 458 ret := make([]SInstance, 0) 459 err = resp.Unmarshal(&ret, "returnObj", "servers") 460 if err != nil { 461 return nil, errors.Wrap(err, "SRegion.GetInstances.Unmarshal") 462 } 463 464 return ret, nil 465 } 466 467 func (self *SRegion) GetInstanceFlavors() ([]FlavorObj, error) { 468 params := map[string]string{ 469 "regionId": self.GetId(), 470 } 471 472 resp, err := self.client.DoGet("/apiproxy/v3/order/getFlavors", params) 473 if err != nil { 474 return nil, errors.Wrap(err, "SRegion.GetInstanceFlavors.DoGet") 475 } 476 477 ret := make([]FlavorObj, 0) 478 err = resp.Unmarshal(&ret, "returnObj") 479 if err != nil { 480 return nil, errors.Wrap(err, "SRegion.GetInstanceFlavors.Unmarshal") 481 } 482 483 return ret, nil 484 } 485 486 func (region *SRegion) GetCapabilities() []string { 487 return region.client.GetCapabilities() 488 }