yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/azure/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 azure 16 17 import ( 18 "fmt" 19 "net/url" 20 "strconv" 21 "strings" 22 23 "yunion.io/x/jsonutils" 24 "yunion.io/x/log" 25 "yunion.io/x/pkg/errors" 26 "yunion.io/x/pkg/util/netutils" 27 28 api "yunion.io/x/cloudmux/pkg/apis/compute" 29 "yunion.io/x/cloudmux/pkg/cloudprovider" 30 "yunion.io/x/cloudmux/pkg/multicloud" 31 ) 32 33 type SVMSize struct { 34 //MaxDataDiskCount int32 `json:"maxDataDiskCount,omitempty"` //Unmarshal会出错 35 MemoryInMB int32 `json:"memoryInMB,omitempty"` 36 NumberOfCores int `json:"numberOfCores,omitempty"` 37 Name string 38 OsDiskSizeInMB int32 `json:"osDiskSizeInMB,omitempty"` 39 ResourceDiskSizeInMB int32 `json:"resourceDiskSizeInMB,omitempty"` 40 } 41 42 type SRegion struct { 43 multicloud.SRegion 44 client *SAzureClient 45 46 storageCache *SStoragecache 47 appServicePlans map[string]*SAppServicePlan 48 49 ID string 50 Name string 51 DisplayName string 52 Latitude string 53 Longitude string 54 } 55 56 func (self *SRegion) GetILoadBalancerBackendGroups() ([]cloudprovider.ICloudLoadbalancerBackendGroup, error) { 57 return nil, cloudprovider.ErrNotImplemented 58 } 59 60 ///////////////////////////////////////////////////////////////////////////// 61 func (self *SRegion) Refresh() error { 62 // do nothing 63 return nil 64 } 65 66 func (self *SRegion) GetClient() *SAzureClient { 67 return self.client 68 } 69 70 func (self *SRegion) ListVmSizes() ([]SVMSize, error) { 71 result := []SVMSize{} 72 resource := fmt.Sprintf("Microsoft.Compute/locations/%s/vmSizes", self.Name) 73 return result, self.client.list(resource, url.Values{}, &result) 74 } 75 76 func (self *SRegion) getHardwareProfile(cpu, memMB int) []string { 77 vmSizes, err := self.ListVmSizes() 78 if err != nil { 79 return []string{} 80 } 81 result := []string{} 82 for i := range vmSizes { 83 if vmSizes[i].MemoryInMB == int32(memMB) && vmSizes[i].NumberOfCores == cpu { 84 result = append(result, vmSizes[i].Name) 85 } 86 } 87 return result 88 } 89 90 func (self *SRegion) getVMSize(name string) (*SVMSize, error) { 91 vmSizes, err := self.ListVmSizes() 92 if err != nil { 93 return nil, errors.Wrapf(err, "ListVmSizes") 94 } 95 for i := range vmSizes { 96 if vmSizes[i].Name == name { 97 return &vmSizes[i], nil 98 } 99 } 100 return nil, errors.Wrapf(cloudprovider.ErrNotFound, name) 101 } 102 103 func (self *SRegion) GetId() string { 104 return self.Name 105 } 106 107 func (self *SRegion) GetName() string { 108 return fmt.Sprintf("%s %s", CLOUD_PROVIDER_AZURE_CN, self.DisplayName) 109 } 110 111 func (self *SRegion) GetI18n() cloudprovider.SModelI18nTable { 112 en := fmt.Sprintf("%s %s", CLOUD_PROVIDER_AZURE_EN, self.DisplayName) 113 table := cloudprovider.SModelI18nTable{} 114 table["name"] = cloudprovider.NewSModelI18nEntry(self.GetName()).CN(self.GetName()).EN(en) 115 return table 116 } 117 118 func (self *SRegion) GetGlobalId() string { 119 return fmt.Sprintf("%s/%s", self.client.GetAccessEnv(), self.Name) 120 } 121 122 func (self *SRegion) IsEmulated() bool { 123 return false 124 } 125 126 func (self *SRegion) GetProvider() string { 127 return CLOUD_PROVIDER_AZURE 128 } 129 130 func (self *SRegion) GetCloudEnv() string { 131 return self.client.envName 132 } 133 134 func (self *SRegion) trimGeographicString(geographic string) string { 135 return strings.TrimFunc(geographic, func(r rune) bool { 136 return !((r >= '0' && r <= '9') || r == '.' || r == '-') 137 }) 138 } 139 140 func (self *SRegion) GetGeographicInfo() cloudprovider.SGeographicInfo { 141 info := cloudprovider.SGeographicInfo{} 142 if geographicInfo, ok := AzureGeographicInfo[self.Name]; ok { 143 info = geographicInfo 144 } 145 146 self.Latitude = self.trimGeographicString(self.Latitude) 147 self.Longitude = self.trimGeographicString(self.Longitude) 148 149 latitude, err := strconv.ParseFloat(self.Latitude, 32) 150 if err != nil { 151 log.Errorf("Parse azure region %s latitude %s error: %v", self.Name, self.Latitude, err) 152 } else { 153 info.Latitude = float32(latitude) 154 } 155 156 longitude, err := strconv.ParseFloat(self.Longitude, 32) 157 if err != nil { 158 log.Errorf("Parse azure region %s longitude %s error: %v", self.Name, self.Longitude, err) 159 } else { 160 info.Longitude = float32(longitude) 161 } 162 return info 163 } 164 165 func (self *SRegion) GetStatus() string { 166 return api.CLOUD_REGION_STATUS_INSERVER 167 } 168 169 func (self *SRegion) CreateIVpc(opts *cloudprovider.VpcCreateOptions) (cloudprovider.ICloudVpc, error) { 170 vpc := SVpc{ 171 region: self, 172 Name: opts.NAME, 173 Location: self.Name, 174 Properties: VirtualNetworkPropertiesFormat{ 175 AddressSpace: AddressSpace{ 176 AddressPrefixes: []string{opts.CIDR}, 177 }, 178 }, 179 Type: "Microsoft.Network/virtualNetworks", 180 } 181 return &vpc, self.create("", jsonutils.Marshal(vpc), &vpc) 182 } 183 184 func (self *SRegion) GetIHostById(id string) (cloudprovider.ICloudHost, error) { 185 izones, err := self.GetIZones() 186 if err != nil { 187 return nil, err 188 } 189 for i := 0; i < len(izones); i += 1 { 190 ihost, err := izones[i].GetIHostById(id) 191 if err == nil { 192 return ihost, nil 193 } else if err != cloudprovider.ErrNotFound { 194 return nil, err 195 } 196 } 197 return nil, cloudprovider.ErrNotFound 198 } 199 200 func (self *SRegion) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) { 201 izones, err := self.GetIZones() 202 if err != nil { 203 return nil, err 204 } 205 for i := 0; i < len(izones); i += 1 { 206 istore, err := izones[i].GetIStorageById(id) 207 if err == nil { 208 return istore, nil 209 } else if err != cloudprovider.ErrNotFound { 210 return nil, err 211 } 212 } 213 return nil, cloudprovider.ErrNotFound 214 } 215 216 func (self *SRegion) GetIVMById(id string) (cloudprovider.ICloudVM, error) { 217 return self.GetInstance(id) 218 } 219 220 func (self *SRegion) GetIDiskById(id string) (cloudprovider.ICloudDisk, error) { 221 return self.GetDisk(id) 222 } 223 224 func (self *SRegion) GetIHosts() ([]cloudprovider.ICloudHost, error) { 225 iHosts := make([]cloudprovider.ICloudHost, 0) 226 227 izones, err := self.GetIZones() 228 if err != nil { 229 return nil, err 230 } 231 for i := 0; i < len(izones); i += 1 { 232 iZoneHost, err := izones[i].GetIHosts() 233 if err != nil { 234 return nil, err 235 } 236 iHosts = append(iHosts, iZoneHost...) 237 } 238 return iHosts, nil 239 } 240 241 func (self *SRegion) GetIStorages() ([]cloudprovider.ICloudStorage, error) { 242 iStores := make([]cloudprovider.ICloudStorage, 0) 243 244 izones, err := self.GetIZones() 245 if err != nil { 246 return nil, err 247 } 248 for i := 0; i < len(izones); i += 1 { 249 iZoneStores, err := izones[i].GetIStorages() 250 if err != nil { 251 return nil, err 252 } 253 iStores = append(iStores, iZoneStores...) 254 } 255 return iStores, nil 256 } 257 258 func (self *SRegion) GetIStoragecacheById(id string) (cloudprovider.ICloudStoragecache, error) { 259 storageCache := self.getStoragecache() 260 if storageCache.GetGlobalId() == id { 261 return self.storageCache, nil 262 } 263 return nil, cloudprovider.ErrNotFound 264 } 265 266 func (self *SRegion) GetIVpcById(id string) (cloudprovider.ICloudVpc, error) { 267 ivpcs, err := self.GetIVpcs() 268 if err != nil { 269 return nil, err 270 } 271 for i := 0; i < len(ivpcs); i++ { 272 if ivpcs[i].GetGlobalId() == id { 273 return ivpcs[i], nil 274 } 275 } 276 return nil, cloudprovider.ErrNotFound 277 } 278 279 func (self *SRegion) GetIZoneById(id string) (cloudprovider.ICloudZone, error) { 280 if izones, err := self.GetIZones(); err != nil { 281 return nil, err 282 } else { 283 for i := 0; i < len(izones); i += 1 { 284 if izones[i].GetGlobalId() == id { 285 return izones[i], nil 286 } 287 } 288 } 289 return nil, cloudprovider.ErrNotFound 290 } 291 292 func (self *SRegion) getZone() *SZone { 293 return &SZone{region: self, Name: self.Name} 294 } 295 296 func (self *SRegion) GetIZones() ([]cloudprovider.ICloudZone, error) { 297 return []cloudprovider.ICloudZone{self.getZone()}, nil 298 } 299 300 func (self *SRegion) getStoragecache() *SStoragecache { 301 if self.storageCache == nil { 302 self.storageCache = &SStoragecache{region: self} 303 } 304 return self.storageCache 305 } 306 307 func (self *SRegion) ListVpcs() ([]SVpc, error) { 308 result := []SVpc{} 309 err := self.list("Microsoft.Network/virtualNetworks", url.Values{}, &result) 310 if err != nil { 311 return nil, errors.Wrapf(err, "list") 312 } 313 return result, nil 314 } 315 316 func (self *SRegion) ListClassicVpcs() ([]SClassicVpc, error) { 317 result := []SClassicVpc{} 318 err := self.list("Microsoft.ClassicNetwork/virtualNetworks", url.Values{}, &result) 319 if err != nil { 320 return nil, errors.Wrapf(err, "ListClassicVpcs") 321 } 322 return result, nil 323 } 324 325 func (self *SRegion) GetIVpcs() ([]cloudprovider.ICloudVpc, error) { 326 vpcs, err := self.ListVpcs() 327 if err != nil { 328 return nil, errors.Wrapf(err, "ListVpcs") 329 } 330 classicVpcs, err := self.ListClassicVpcs() 331 if err != nil { 332 return nil, errors.Wrapf(err, "ListClassicVpcs") 333 } 334 ret := []cloudprovider.ICloudVpc{} 335 for i := range vpcs { 336 vpcs[i].region = self 337 ret = append(ret, &vpcs[i]) 338 } 339 for i := range classicVpcs { 340 classicVpcs[i].region = self 341 ret = append(ret, &classicVpcs[i]) 342 } 343 return ret, nil 344 } 345 346 func (self *SRegion) CreateInstanceSimple(name string, imgId, osType string, cpu int, memMb int, sysDiskSizeGB int, storageType string, dataDiskSizesGB []int, nicId string, passwd string, publicKey string) (*SInstance, error) { 347 desc := &cloudprovider.SManagedVMCreateConfig{ 348 Name: name, 349 ExternalImageId: imgId, 350 SysDisk: cloudprovider.SDiskInfo{SizeGB: sysDiskSizeGB, StorageType: storageType}, 351 Cpu: cpu, 352 MemoryMB: memMb, 353 Password: passwd, 354 DataDisks: []cloudprovider.SDiskInfo{}, 355 PublicKey: publicKey, 356 OsType: osType, 357 } 358 if len(passwd) > 0 { 359 desc.Password = passwd 360 } 361 for _, sizeGB := range dataDiskSizesGB { 362 desc.DataDisks = append(desc.DataDisks, cloudprovider.SDiskInfo{SizeGB: sizeGB, StorageType: storageType}) 363 } 364 return self._createVM(desc, nicId) 365 } 366 367 func (region *SRegion) GetEips() ([]SEipAddress, error) { 368 eips := []SEipAddress{} 369 err := region.client.list("Microsoft.Network/publicIPAddresses", url.Values{}, &eips) 370 if err != nil { 371 return nil, err 372 } 373 result := []SEipAddress{} 374 for i := 0; i < len(eips); i++ { 375 if eips[i].Location == region.Name { 376 eips[i].region = region 377 result = append(result, eips[i]) 378 } 379 } 380 return result, nil 381 } 382 383 func (region *SRegion) GetIEips() ([]cloudprovider.ICloudEIP, error) { 384 eips, err := region.GetEips() 385 if err != nil { 386 return nil, errors.Wrapf(err, "GetEips") 387 } 388 classicEips, err := region.GetClassicEips() 389 if err != nil { 390 return nil, errors.Wrapf(err, "GetClassicEips") 391 } 392 ieips := []cloudprovider.ICloudEIP{} 393 for i := 0; i < len(eips); i++ { 394 if len(eips[i].GetIpAddr()) == 0 { 395 continue 396 } 397 _, err := netutils.NewIPV4Addr(eips[i].GetIpAddr()) 398 if err != nil { 399 continue 400 } 401 eips[i].region = region 402 ieips = append(ieips, &eips[i]) 403 } 404 for i := 0; i < len(classicEips); i++ { 405 if len(classicEips[i].GetIpAddr()) == 0 { 406 continue 407 } 408 _, err := netutils.NewIPV4Addr(eips[i].GetIpAddr()) 409 if err != nil { 410 continue 411 } 412 classicEips[i].region = region 413 ieips = append(ieips, &classicEips[i]) 414 } 415 return ieips, nil 416 } 417 418 func (region *SRegion) GetISecurityGroupById(secgroupId string) (cloudprovider.ICloudSecurityGroup, error) { 419 if strings.Contains(strings.ToLower(secgroupId), "microsoft.classicnetwork") { 420 return region.GetClassicSecurityGroupDetails(secgroupId) 421 } 422 return region.GetSecurityGroupDetails(secgroupId) 423 } 424 425 func (region *SRegion) GetISecurityGroupByName(opts *cloudprovider.SecurityGroupFilterOptions) (cloudprovider.ICloudSecurityGroup, error) { 426 if strings.Contains(strings.ToLower(opts.VpcId), "microsoft.classicnetwork") { 427 return nil, errors.Wrapf(cloudprovider.ErrNotSupported, "not support classic secgroup") 428 } 429 resource := fmt.Sprintf("subscriptions/%s/resourcegroups/%s/providers/microsoft.network/networksecuritygroups/%s", region.client.subscriptionId, opts.ProjectId, opts.Name) 430 secgroup := &SSecurityGroup{region: region} 431 err := region.get(resource, url.Values{}, secgroup) 432 if err != nil { 433 return nil, errors.Wrapf(err, "get(%s)", resource) 434 } 435 return secgroup, nil 436 } 437 438 func (region *SRegion) CreateISecurityGroup(conf *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) { 439 if conf.VpcId == "classic" { 440 return region.CreateClassicSecurityGroup(conf.Name) 441 } 442 return region.CreateSecurityGroup(conf.Name) 443 } 444 445 func (region *SRegion) getIAppLBs() ([]cloudprovider.ICloudLoadbalancer, error) { 446 lbs := []SLoadbalancer{} 447 params := url.Values{} 448 params.Set("api-version", "2021-02-01") 449 err := region.list("Microsoft.Network/applicationGateways", params, &lbs) 450 if err != nil { 451 return nil, errors.Wrapf(err, "list") 452 } 453 454 ilbs := make([]cloudprovider.ICloudLoadbalancer, len(lbs)) 455 for i := range lbs { 456 lbs[i].region = region 457 ilbs[i] = &lbs[i] 458 } 459 460 return ilbs, nil 461 } 462 463 func (region *SRegion) getINetworkLBs() ([]cloudprovider.ICloudLoadbalancer, error) { 464 lbs := []SLoadbalancer{} 465 params := url.Values{} 466 params.Set("api-version", "2021-02-01") 467 err := region.list("Microsoft.Network/loadBalancers", params, &lbs) 468 if err != nil { 469 return nil, errors.Wrapf(err, "list") 470 } 471 472 ilbs := make([]cloudprovider.ICloudLoadbalancer, len(lbs)) 473 for i := range lbs { 474 lbs[i].region = region 475 ilbs[i] = &lbs[i] 476 } 477 478 return ilbs, nil 479 } 480 481 func (region *SRegion) GetILoadBalancers() ([]cloudprovider.ICloudLoadbalancer, error) { 482 appLbs, err := region.getIAppLBs() 483 if err != nil { 484 return nil, errors.Wrap(err, "GetIAppLBs") 485 } 486 487 netLbs, err := region.getINetworkLBs() 488 if err != nil { 489 return nil, errors.Wrap(err, "GetINetworkLBs") 490 } 491 492 lbs := []cloudprovider.ICloudLoadbalancer{} 493 lbs = append(lbs, appLbs...) 494 lbs = append(lbs, netLbs...) 495 return lbs, nil 496 } 497 498 func (region *SRegion) GetILoadBalancerById(loadbalancerId string) (cloudprovider.ICloudLoadbalancer, error) { 499 lb := SLoadbalancer{} 500 params := url.Values{} 501 params.Set("api-version", "2021-02-01") 502 err := region.get(loadbalancerId, params, &lb) 503 if err != nil { 504 return nil, errors.Wrapf(err, "get") 505 } 506 507 lb.region = region 508 return &lb, nil 509 } 510 511 func (region *SRegion) GetILoadBalancerAclById(aclId string) (cloudprovider.ICloudLoadbalancerAcl, error) { 512 return nil, errors.Wrap(cloudprovider.ErrNotSupported, "GetILoadBalancerAclById") 513 } 514 515 func (region *SRegion) GetILoadBalancerCertificateById(certId string) (cloudprovider.ICloudLoadbalancerCertificate, error) { 516 segs := strings.Split(certId, "/sslCertificates") 517 if len(segs[0]) > 0 { 518 lb, err := region.GetILoadBalancerById(segs[0]) 519 if err != nil { 520 return nil, errors.Wrap(err, "GetILoadBalancerById") 521 } 522 523 return lb.(*SLoadbalancer).GetILoadBalancerCertificateById(certId) 524 } 525 526 return nil, errors.Wrap(cloudprovider.ErrNotFound, "GetILoadBalancerCertificateById") 527 } 528 529 func (region *SRegion) GetILoadBalancerCertificates() ([]cloudprovider.ICloudLoadbalancerCertificate, error) { 530 lbs, err := region.GetILoadBalancers() 531 if err != nil { 532 return nil, errors.Wrap(err, "GetILoadBalancers") 533 } 534 535 certs := []cloudprovider.ICloudLoadbalancerCertificate{} 536 for i := range lbs { 537 _certs, err := lbs[i].(*SLoadbalancer).GetILoadBalancerCertificates() 538 if err != nil { 539 return nil, errors.Wrap(err, "GetILoadBalancerCertificates") 540 } 541 certs = append(certs, _certs...) 542 } 543 544 return certs, nil 545 } 546 547 func (region *SRegion) CreateILoadBalancerCertificate(cert *cloudprovider.SLoadbalancerCertificate) (cloudprovider.ICloudLoadbalancerCertificate, error) { 548 return nil, errors.Wrap(cloudprovider.ErrNotImplemented, "CreateILoadBalancerCertificate") 549 } 550 551 func (region *SRegion) GetILoadBalancerAcls() ([]cloudprovider.ICloudLoadbalancerAcl, error) { 552 return nil, errors.Wrap(cloudprovider.ErrNotSupported, "GetILoadBalancerAcls") 553 } 554 555 func (region *SRegion) CreateILoadBalancer(loadbalancer *cloudprovider.SLoadbalancer) (cloudprovider.ICloudLoadbalancer, error) { 556 return nil, errors.Wrap(cloudprovider.ErrNotImplemented, "GetILoadBalancerCertificates") 557 } 558 559 func (region *SRegion) CreateILoadBalancerAcl(acl *cloudprovider.SLoadbalancerAccessControlList) (cloudprovider.ICloudLoadbalancerAcl, error) { 560 return nil, errors.Wrap(cloudprovider.ErrNotImplemented, "CreateILoadBalancerAcl") 561 } 562 563 func (region *SRegion) GetIBuckets() ([]cloudprovider.ICloudBucket, error) { 564 accounts, err := region.ListStorageAccounts() 565 if err != nil { 566 return nil, errors.Wrapf(err, "ListStorageAccounts") 567 } 568 ret := make([]cloudprovider.ICloudBucket, 0) 569 for i := range accounts { 570 ret = append(ret, &accounts[i]) 571 } 572 return ret, nil 573 } 574 575 func (region *SRegion) CreateIBucket(name string, storageClassStr string, acl string) error { 576 _, err := region.createStorageAccount(name, storageClassStr) 577 if err != nil { 578 return errors.Wrapf(err, "region.createStorageAccount name=%s storageClass=%s acl=%s", name, storageClassStr, acl) 579 } 580 return nil 581 } 582 583 func (region *SRegion) DeleteIBucket(name string) error { 584 accounts, err := region.listStorageAccounts() 585 if err != nil { 586 return errors.Wrap(err, "ListStorageAccounts") 587 } 588 for i := range accounts { 589 if accounts[i].Name == name { 590 err = region.del(accounts[i].ID) 591 if err != nil { 592 return errors.Wrapf(err, "region.del") 593 } 594 return nil 595 } 596 } 597 return nil 598 } 599 600 func (region *SRegion) IBucketExist(name string) (bool, error) { 601 return region.checkStorageAccountNameExist(name) 602 } 603 604 func (region *SRegion) GetIBucketById(name string) (cloudprovider.ICloudBucket, error) { 605 return cloudprovider.GetIBucketById(region, name) 606 } 607 608 func (region *SRegion) GetIBucketByName(name string) (cloudprovider.ICloudBucket, error) { 609 return region.GetIBucketById(name) 610 } 611 612 func (region *SRegion) GetCapabilities() []string { 613 return region.client.GetCapabilities() 614 } 615 616 func (self *SRegion) get(resource string, params url.Values, retVal interface{}) error { 617 return self.client.get(resource, params, retVal) 618 } 619 620 func (self *SRegion) Show(resource string) (jsonutils.JSONObject, error) { 621 ret := jsonutils.NewDict() 622 err := self.get(resource, url.Values{}, ret) 623 if err != nil { 624 return nil, err 625 } 626 return ret, nil 627 } 628 629 func (self *SRegion) del(resource string) error { 630 return self.client.del(resource) 631 } 632 633 func (self *SRegion) Delete(resource string) error { 634 return self.del(resource) 635 } 636 637 func (self *SRegion) checkResourceGroup(resourceGroup string) (string, error) { 638 if len(resourceGroup) == 0 { 639 resourceGroup = "Default" 640 } 641 resourceGroups, err := self.client.ListResourceGroups() 642 if err != nil { 643 return "", errors.Wrapf(err, "ListResourceGroups") 644 } 645 646 for i := range resourceGroups { 647 proj := resourceGroups[i] 648 if strings.ToLower(proj.GetName()) == strings.ToLower(resourceGroup) || 649 proj.GetGlobalId() == resourceGroup || 650 (strings.Contains(resourceGroup, "/") && strings.HasSuffix(proj.GetGlobalId(), resourceGroup)) { 651 return resourceGroup, nil 652 } 653 } 654 _, err = self.CreateResourceGroup(resourceGroup) 655 return resourceGroup, err 656 } 657 658 type sInfo struct { 659 Location string `json:"Location"` 660 Name string `json:"Name"` 661 Type string `json:"Type"` 662 } 663 664 func (self *SRegion) createInfo(body jsonutils.JSONObject) (sInfo, error) { 665 info := sInfo{} 666 err := body.Unmarshal(&info) 667 if err != nil { 668 return info, errors.Wrapf(err, "body.Unmarshal") 669 } 670 if len(info.Name) == 0 { 671 return info, fmt.Errorf("Missing name params") 672 } 673 if len(info.Type) == 0 { 674 return info, fmt.Errorf("Missing type params") 675 } 676 return info, nil 677 } 678 679 func (self *SRegion) create(resourceGroup string, _body jsonutils.JSONObject, retVal interface{}) error { 680 body := _body.(*jsonutils.JSONDict) 681 info, err := self.createInfo(_body) 682 if err != nil { 683 return errors.Wrapf(err, "createInfo") 684 } 685 resourceGroup, err = self.checkResourceGroup(resourceGroup) 686 if err != nil { 687 return errors.Wrapf(err, "checkResourceGroup(%s)", resourceGroup) 688 } 689 info.Name, err = self.client.getUniqName(resourceGroup, info.Type, info.Name) 690 if err != nil { 691 return errors.Wrapf(err, "getUniqName") 692 } 693 info.Location = self.Name 694 body.Update(jsonutils.Marshal(info)) 695 body.Remove("location") 696 body.Remove("name") 697 body.Remove("type") 698 return self.client.create(resourceGroup, info.Type, info.Name, body, retVal) 699 } 700 701 func (self *SRegion) update(body jsonutils.JSONObject, retVal interface{}) error { 702 return self.client.update(body, retVal) 703 } 704 705 func (self *SRegion) perform(id, action string, body jsonutils.JSONObject) (jsonutils.JSONObject, error) { 706 return self.client.perform(id, action, body) 707 } 708 709 func (self *SRegion) put(resource string, body jsonutils.JSONObject) (jsonutils.JSONObject, error) { 710 return self.client.put(resource, body) 711 } 712 713 func (self *SRegion) patch(resource string, body jsonutils.JSONObject) (jsonutils.JSONObject, error) { 714 return self.client.patch(resource, body) 715 } 716 717 func (self *SRegion) list(resource string, params url.Values, retVal interface{}) error { 718 result := []jsonutils.JSONObject{} 719 err := self.client.list(resource, params, &result) 720 if err != nil { 721 return errors.Wrapf(err, "client.list") 722 } 723 ret := []jsonutils.JSONObject{} 724 for i := range result { 725 location, _ := result[i].GetString("location") 726 if len(location) == 0 || strings.ToLower(self.Name) == strings.ToLower(strings.Replace(location, " ", "", -1)) { 727 ret = append(ret, result[i]) 728 } 729 } 730 return jsonutils.Update(retVal, ret) 731 }