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  }