yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/zstack/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 zstack 16 17 import ( 18 "fmt" 19 "net/url" 20 "strings" 21 22 "yunion.io/x/log" 23 "yunion.io/x/pkg/errors" 24 25 api "yunion.io/x/cloudmux/pkg/apis/compute" 26 "yunion.io/x/cloudmux/pkg/cloudprovider" 27 "yunion.io/x/cloudmux/pkg/multicloud" 28 ) 29 30 type SRegion struct { 31 multicloud.SRegion 32 multicloud.SNoObjectStorageRegion 33 34 client *SZStackClient 35 36 Name string 37 38 izones []cloudprovider.ICloudZone 39 ivpcs []cloudprovider.ICloudVpc 40 } 41 42 func (region *SRegion) GetILoadBalancerBackendGroups() ([]cloudprovider.ICloudLoadbalancerBackendGroup, error) { 43 return nil, cloudprovider.ErrNotImplemented 44 } 45 46 func (region *SRegion) GetClient() *SZStackClient { 47 return region.client 48 } 49 50 func (region *SRegion) GetId() string { 51 return region.Name 52 } 53 54 func (region *SRegion) GetName() string { 55 return region.client.cpcfg.Name 56 } 57 58 func (region *SRegion) GetI18n() cloudprovider.SModelI18nTable { 59 table := cloudprovider.SModelI18nTable{} 60 table["name"] = cloudprovider.NewSModelI18nEntry(region.GetName()).CN(region.GetName()) 61 return table 62 } 63 64 func (region *SRegion) GetGlobalId() string { 65 return fmt.Sprintf("%s/%s", CLOUD_PROVIDER_ZSTACK, region.client.cpcfg.Id) 66 } 67 68 func (region *SRegion) IsEmulated() bool { 69 return false 70 } 71 72 func (region *SRegion) GetProvider() string { 73 return CLOUD_PROVIDER_ZSTACK 74 } 75 76 func (region *SRegion) GetCloudEnv() string { 77 return "" 78 } 79 80 func (region *SRegion) GetGeographicInfo() cloudprovider.SGeographicInfo { 81 return cloudprovider.SGeographicInfo{} 82 } 83 84 func (region *SRegion) GetStatus() string { 85 return api.CLOUD_REGION_STATUS_INSERVER 86 } 87 88 func (region *SRegion) Refresh() error { 89 // do nothing 90 return nil 91 } 92 93 func (self *SRegion) GetIVMById(id string) (cloudprovider.ICloudVM, error) { 94 vm, err := self.GetInstance(id) 95 if err != nil { 96 return nil, err 97 } 98 return vm, nil 99 } 100 101 func (self *SRegion) GetIDiskById(id string) (cloudprovider.ICloudDisk, error) { 102 disk, err := self.GetDisk(id) 103 if err != nil { 104 return nil, err 105 } 106 return disk, nil 107 } 108 109 func (region *SRegion) GetIHostById(id string) (cloudprovider.ICloudHost, error) { 110 return region.GetHost(id) 111 } 112 113 func (region *SRegion) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) { 114 storages, err := region.getIStorages("") 115 if err != nil { 116 return nil, err 117 } 118 for i := 0; i < len(storages); i++ { 119 if storages[i].GetGlobalId() == id { 120 return storages[i], nil 121 } 122 } 123 return nil, cloudprovider.ErrNotFound 124 } 125 126 func (region *SRegion) GetIHosts() ([]cloudprovider.ICloudHost, error) { 127 hosts, err := region.GetHosts("", "") 128 if err != nil { 129 return nil, err 130 } 131 ihosts := []cloudprovider.ICloudHost{} 132 for i := 0; i < len(hosts); i++ { 133 ihosts = append(ihosts, &hosts[i]) 134 } 135 return ihosts, nil 136 } 137 138 func (region *SRegion) GetIStorages() ([]cloudprovider.ICloudStorage, error) { 139 return region.getIStorages("") 140 } 141 142 func (region *SRegion) GetIStoragecacheById(id string) (cloudprovider.ICloudStoragecache, error) { 143 caches, err := region.GetIStoragecaches() 144 if err != nil { 145 return nil, err 146 } 147 for i := 0; i < len(caches); i++ { 148 if caches[i].GetGlobalId() == id { 149 return caches[i], nil 150 } 151 } 152 return nil, cloudprovider.ErrNotFound 153 } 154 155 func (region *SRegion) GetIStoragecaches() ([]cloudprovider.ICloudStoragecache, error) { 156 zones, err := region.GetZones("") 157 if err != nil { 158 return nil, err 159 } 160 icaches := []cloudprovider.ICloudStoragecache{} 161 for i := 0; i < len(zones); i++ { 162 icaches = append(icaches, &SStoragecache{ZoneId: zones[i].UUID, region: region}) 163 } 164 return icaches, nil 165 } 166 167 func (region *SRegion) GetIVpcById(vpcId string) (cloudprovider.ICloudVpc, error) { 168 return &SVpc{region: region}, nil 169 } 170 171 func (region *SRegion) GetIZoneById(id string) (cloudprovider.ICloudZone, error) { 172 izones, err := region.GetIZones() 173 if err != nil { 174 return nil, err 175 } 176 for i := 0; i < len(izones); i++ { 177 if izones[i].GetGlobalId() == id { 178 return izones[i], nil 179 } 180 } 181 return nil, cloudprovider.ErrNotFound 182 } 183 184 func (region *SRegion) GetZone(zoneId string) (*SZone, error) { 185 zone := &SZone{region: region} 186 return zone, region.client.getResource("zones", zoneId, zone) 187 } 188 189 func (region *SRegion) GetZones(zoneId string) ([]SZone, error) { 190 zones := []SZone{} 191 params := url.Values{} 192 if len(zoneId) > 0 { 193 params.Add("q", "uuid="+zoneId) 194 } 195 err := region.client.listAll("zones", params, &zones) 196 if err != nil { 197 return nil, err 198 } 199 for i := 0; i < len(zones); i++ { 200 zones[i].region = region 201 } 202 return zones, nil 203 } 204 205 func (region *SRegion) fetchZones() { 206 if region.izones == nil || len(region.izones) == 0 { 207 zones, err := region.GetZones("") 208 if err != nil { 209 log.Errorf("failed to get zones error: %v", err) 210 return 211 } 212 region.izones = []cloudprovider.ICloudZone{} 213 for i := 0; i < len(zones); i++ { 214 region.izones = append(region.izones, &zones[i]) 215 } 216 } 217 } 218 219 func (region *SRegion) fetchInfrastructure() error { 220 region.fetchZones() 221 region.GetIVpcs() 222 return nil 223 } 224 225 func (region *SRegion) GetIZones() ([]cloudprovider.ICloudZone, error) { 226 if region.izones == nil { 227 if err := region.fetchInfrastructure(); err != nil { 228 return nil, err 229 } 230 } 231 return region.izones, nil 232 } 233 234 func (region *SRegion) GetVpc() *SVpc { 235 return &SVpc{region: region} 236 } 237 238 func (region *SRegion) GetIVpcs() ([]cloudprovider.ICloudVpc, error) { 239 region.ivpcs = []cloudprovider.ICloudVpc{region.GetVpc()} 240 return region.ivpcs, nil 241 } 242 243 func (region *SRegion) CreateIVpc(opts *cloudprovider.VpcCreateOptions) (cloudprovider.ICloudVpc, error) { 244 return nil, cloudprovider.ErrNotSupported 245 } 246 247 func (region *SRegion) CreateEIP(eip *cloudprovider.SEip) (cloudprovider.ICloudEIP, error) { 248 if len(eip.NetworkExternalId) == 0 { 249 return nil, fmt.Errorf("networkId cannot be empty") 250 } 251 networkInfo := strings.Split(eip.NetworkExternalId, "/") 252 if len(networkInfo) != 2 { 253 return nil, fmt.Errorf("invalid network externalId, it should be `l3networId/networkId` format") 254 } 255 _, err := region.GetL3Network(networkInfo[0]) 256 if err != nil { 257 return nil, err 258 } 259 vip, err := region.CreateVirtualIP(eip.Name, "", eip.IP, networkInfo[0]) 260 if err != nil { 261 return nil, err 262 } 263 return region.CreateEip(eip.Name, vip.UUID, "") 264 } 265 266 func (region *SRegion) GetIEipById(eipId string) (cloudprovider.ICloudEIP, error) { 267 return region.GetEip(eipId) 268 } 269 270 func (region *SRegion) GetILoadBalancers() ([]cloudprovider.ICloudLoadbalancer, error) { 271 return nil, cloudprovider.ErrNotImplemented 272 } 273 274 func (region *SRegion) GetILoadBalancerById(loadbalancerId string) (cloudprovider.ICloudLoadbalancer, error) { 275 return nil, cloudprovider.ErrNotImplemented 276 } 277 278 func (region *SRegion) GetILoadBalancerAclById(aclId string) (cloudprovider.ICloudLoadbalancerAcl, error) { 279 return nil, cloudprovider.ErrNotImplemented 280 } 281 282 func (region *SRegion) GetILoadBalancerCertificateById(certId string) (cloudprovider.ICloudLoadbalancerCertificate, error) { 283 return nil, cloudprovider.ErrNotImplemented 284 } 285 286 func (region *SRegion) CreateILoadBalancerCertificate(cert *cloudprovider.SLoadbalancerCertificate) (cloudprovider.ICloudLoadbalancerCertificate, error) { 287 return nil, cloudprovider.ErrNotImplemented 288 } 289 290 func (region *SRegion) GetILoadBalancerAcls() ([]cloudprovider.ICloudLoadbalancerAcl, error) { 291 return nil, cloudprovider.ErrNotImplemented 292 } 293 294 func (region *SRegion) GetILoadBalancerCertificates() ([]cloudprovider.ICloudLoadbalancerCertificate, error) { 295 return nil, cloudprovider.ErrNotImplemented 296 } 297 298 func (region *SRegion) CreateILoadBalancer(loadbalancer *cloudprovider.SLoadbalancer) (cloudprovider.ICloudLoadbalancer, error) { 299 return nil, cloudprovider.ErrNotImplemented 300 } 301 302 func (region *SRegion) CreateILoadBalancerAcl(acl *cloudprovider.SLoadbalancerAccessControlList) (cloudprovider.ICloudLoadbalancerAcl, error) { 303 return nil, cloudprovider.ErrNotImplemented 304 } 305 306 func (region *SRegion) GetIEips() ([]cloudprovider.ICloudEIP, error) { 307 eips, err := region.GetEips("", "") 308 if err != nil { 309 return nil, err 310 } 311 ieips := []cloudprovider.ICloudEIP{} 312 for i := 0; i < len(eips); i++ { 313 ieips = append(ieips, &eips[i]) 314 } 315 return ieips, nil 316 } 317 318 func (region *SRegion) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) { 319 snapshots, err := region.GetSnapshots("", "") 320 if err != nil { 321 return nil, err 322 } 323 isnapshots := []cloudprovider.ICloudSnapshot{} 324 for i := 0; i < len(snapshots); i++ { 325 snapshots[i].region = region 326 isnapshots = append(isnapshots, &snapshots[i]) 327 } 328 return isnapshots, nil 329 } 330 331 func (region *SRegion) GetISnapshotById(snapshotId string) (cloudprovider.ICloudSnapshot, error) { 332 return region.GetSnapshot(snapshotId) 333 } 334 335 func (region *SRegion) GetISkus() ([]cloudprovider.ICloudSku, error) { 336 offerings, err := region.GetInstanceOfferings("", "", 0, 0) 337 if err != nil { 338 return nil, err 339 } 340 iskus := []cloudprovider.ICloudSku{} 341 for i := 0; i < len(offerings); i++ { 342 offerings[i].region = region 343 iskus = append(iskus, &offerings[i]) 344 } 345 return iskus, nil 346 } 347 348 func (region *SRegion) DeleteISkuByName(name string) error { 349 offerings, err := region.GetInstanceOfferings("", name, 0, 0) 350 if err != nil { 351 return errors.Wrap(err, "region.GetInstanceOfferings") 352 } 353 for _, offering := range offerings { 354 err = offering.Delete() 355 if err != nil { 356 return err 357 } 358 } 359 return nil 360 } 361 362 func (region *SRegion) GetISecurityGroupById(secgroupId string) (cloudprovider.ICloudSecurityGroup, error) { 363 return region.GetSecurityGroup(secgroupId) 364 } 365 366 func (region *SRegion) GetISecurityGroupByName(opts *cloudprovider.SecurityGroupFilterOptions) (cloudprovider.ICloudSecurityGroup, error) { 367 secgroups, err := region.GetSecurityGroups("", "", opts.Name) 368 if err != nil { 369 return nil, err 370 } 371 if len(secgroups) == 0 { 372 return nil, cloudprovider.ErrNotFound 373 } 374 if len(secgroups) > 1 { 375 return nil, cloudprovider.ErrDuplicateId 376 } 377 return &secgroups[0], nil 378 } 379 380 func (region *SRegion) CreateISecurityGroup(conf *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) { 381 return region.CreateSecurityGroup(conf.Name, conf.Desc) 382 } 383 384 func (region *SRegion) GetCapabilities() []string { 385 return region.client.GetCapabilities() 386 }