yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/aws/zone.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 aws 16 17 import ( 18 "fmt" 19 20 "yunion.io/x/log" 21 "yunion.io/x/pkg/errors" 22 "yunion.io/x/pkg/utils" 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 var StorageTypes = []string{ 30 api.STORAGE_GP2_SSD, 31 api.STORAGE_GP3_SSD, 32 api.STORAGE_IO1_SSD, 33 api.STORAGE_IO2_SSD, 34 api.STORAGE_ST1_HDD, 35 api.STORAGE_SC1_HDD, 36 api.STORAGE_STANDARD_HDD, 37 } 38 39 type SZone struct { 40 multicloud.SResourceBase 41 AwsTags 42 region *SRegion 43 host *SHost 44 45 iwires []cloudprovider.ICloudWire 46 47 ZoneId string // 沿用阿里云ZoneId,对应Aws ZoneName 48 LocalName string 49 State string 50 } 51 52 func (self *SZone) addWire(wire *SWire) { 53 if self.iwires == nil { 54 self.iwires = make([]cloudprovider.ICloudWire, 0) 55 } 56 self.iwires = append(self.iwires, wire) 57 } 58 59 func (self *SZone) getHost() *SHost { 60 if self.host == nil { 61 self.host = &SHost{zone: self} 62 } 63 return self.host 64 } 65 66 func (self *SZone) GetIWires() ([]cloudprovider.ICloudWire, error) { 67 return self.iwires, nil 68 } 69 70 func (self *SZone) getNetworkById(networkId string) *SNetwork { 71 log.Debugf("Search in wires %d", len(self.iwires)) 72 for i := 0; i < len(self.iwires); i += 1 { 73 log.Debugf("Search in wire %s", self.iwires[i].GetName()) 74 wire := self.iwires[i].(*SWire) 75 net := wire.getNetworkById(networkId) 76 if net != nil { 77 return net 78 } 79 } 80 return nil 81 } 82 83 func (self *SZone) GetId() string { 84 return self.ZoneId 85 } 86 87 func (self *SZone) GetName() string { 88 return fmt.Sprintf("%s %s", CLOUD_PROVIDER_AWS_CN, self.LocalName) 89 } 90 91 func (self *SZone) GetI18n() cloudprovider.SModelI18nTable { 92 en := fmt.Sprintf("%s %s", CLOUD_PROVIDER_AWS_EN, self.LocalName) 93 table := cloudprovider.SModelI18nTable{} 94 table["name"] = cloudprovider.NewSModelI18nEntry(self.GetName()).CN(self.GetName()).EN(en) 95 return table 96 } 97 98 func (self *SZone) GetGlobalId() string { 99 return fmt.Sprintf("%s/%s", self.region.GetGlobalId(), self.ZoneId) 100 } 101 102 func (self *SZone) GetStatus() string { 103 if self.State == "unavailable" { 104 return api.ZONE_SOLDOUT 105 } else { 106 return api.ZONE_ENABLE 107 } 108 } 109 110 func (self *SZone) Refresh() error { 111 return nil 112 } 113 114 func (self *SZone) IsEmulated() bool { 115 return false 116 } 117 118 func (self *SZone) GetIRegion() cloudprovider.ICloudRegion { 119 return self.region 120 } 121 122 func (self *SZone) GetIHosts() ([]cloudprovider.ICloudHost, error) { 123 return []cloudprovider.ICloudHost{self.getHost()}, nil 124 } 125 126 func (self *SZone) GetIHostById(id string) (cloudprovider.ICloudHost, error) { 127 host := self.getHost() 128 if host.GetGlobalId() == id { 129 return host, nil 130 } 131 return nil, errors.Wrap(cloudprovider.ErrNotFound, "GetIHostById") 132 } 133 134 func (self *SZone) GetIStorages() ([]cloudprovider.ICloudStorage, error) { 135 ret := []cloudprovider.ICloudStorage{} 136 for i := range StorageTypes { 137 storage := &SStorage{zone: self, storageType: StorageTypes[i]} 138 ret = append(ret, storage) 139 } 140 return ret, nil 141 } 142 143 func (self *SZone) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) { 144 storages, err := self.GetIStorages() 145 if err != nil { 146 return nil, err 147 } 148 for i := 0; i < len(storages); i += 1 { 149 if storages[i].GetGlobalId() == id { 150 return storages[i], nil 151 } 152 } 153 return nil, errors.Wrapf(cloudprovider.ErrNotFound, "not found %s", id) 154 } 155 156 func (self *SZone) getStorageByCategory(category string) (*SStorage, error) { 157 storages, err := self.GetIStorages() 158 if err != nil { 159 return nil, errors.Wrap(err, "GetIStorages") 160 } 161 for i := 0; i < len(storages); i += 1 { 162 storage := storages[i].(*SStorage) 163 if storage.storageType == category { 164 return storage, nil 165 } 166 } 167 return nil, fmt.Errorf("No such storage %s", category) 168 } 169 170 func (self *SRegion) getZoneById(id string) (*SZone, error) { 171 izones, err := self.GetIZones() 172 if err != nil { 173 return nil, errors.Wrap(err, "GetIZones") 174 } 175 for i := 0; i < len(izones); i += 1 { 176 zone := izones[i].(*SZone) 177 if zone.ZoneId == id { 178 return zone, nil 179 } 180 } 181 return nil, fmt.Errorf("no such zone %s", id) 182 } 183 184 func (self *SRegion) TestStorageAvailable(zoneId, storageType string) (bool, error) { 185 params := map[string]string{ 186 "AvailabilityZone": zoneId, 187 "ClientToken": utils.GenRequestId(20), 188 "DryRun": "true", 189 "Size": "125", 190 "VolumeType": storageType, 191 } 192 iops, ok := map[string]string{ 193 api.STORAGE_GP3_SSD: "3000", 194 api.STORAGE_IO1_SSD: "100", 195 api.STORAGE_IO2_SSD: "100", 196 }[storageType] 197 if ok { 198 params["Iops"] = iops 199 } 200 ret := struct{}{} 201 err := self.ec2Request("CreateVolume", params, &ret) 202 if err != nil { 203 if e, ok := err.(*sAwsError); ok && e.Errors.Code == "DryRunOperation" { 204 return true, nil 205 } 206 return false, errors.Wrapf(err, "CreateVolume") 207 } 208 return true, nil 209 }