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  }