yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/aws/provider/provider.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 provider
    16  
    17  import (
    18  	"context"
    19  	"strings"
    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/onecloud/pkg/httperrors"
    27  	"yunion.io/x/onecloud/pkg/mcclient"
    28  	"yunion.io/x/cloudmux/pkg/multicloud/aws"
    29  )
    30  
    31  type SAwsProviderFactory struct {
    32  	cloudprovider.SPublicCloudBaseProviderFactory
    33  }
    34  
    35  func (self *SAwsProviderFactory) GetId() string {
    36  	return aws.CLOUD_PROVIDER_AWS
    37  }
    38  
    39  func (self *SAwsProviderFactory) GetName() string {
    40  	return aws.CLOUD_PROVIDER_AWS_CN
    41  }
    42  
    43  func (self *SAwsProviderFactory) IsCloudeventRegional() bool {
    44  	return true
    45  }
    46  
    47  func (self *SAwsProviderFactory) GetMaxCloudEventSyncDays() int {
    48  	return 1
    49  }
    50  
    51  func (self *SAwsProviderFactory) GetMaxCloudEventKeepDays() int {
    52  	return 90
    53  }
    54  
    55  func (self *SAwsProviderFactory) IsSupportPrepaidResources() bool {
    56  	return false
    57  }
    58  
    59  func (self *SAwsProviderFactory) IsSupportCloudIdService() bool {
    60  	return true
    61  }
    62  
    63  func (self *SAwsProviderFactory) IsSupportCreateCloudgroup() bool {
    64  	return true
    65  }
    66  
    67  func (factory *SAwsProviderFactory) IsSystemCloudpolicyUnified() bool {
    68  	return false
    69  }
    70  
    71  func (factory *SAwsProviderFactory) IsSupportSAMLAuth() bool {
    72  	return true
    73  }
    74  
    75  func (self *SAwsProviderFactory) GetSupportedDnsZoneTypes() []cloudprovider.TDnsZoneType {
    76  	return []cloudprovider.TDnsZoneType{
    77  		cloudprovider.PublicZone,
    78  		cloudprovider.PrivateZone,
    79  	}
    80  }
    81  
    82  func (self *SAwsProviderFactory) GetSupportedDnsTypes() map[cloudprovider.TDnsZoneType][]cloudprovider.TDnsType {
    83  	return map[cloudprovider.TDnsZoneType][]cloudprovider.TDnsType{
    84  		cloudprovider.PublicZone: []cloudprovider.TDnsType{
    85  			cloudprovider.DnsTypeA,
    86  			cloudprovider.DnsTypeAAAA,
    87  			cloudprovider.DnsTypeCAA,
    88  			cloudprovider.DnsTypeCNAME,
    89  			cloudprovider.DnsTypeMX,
    90  			cloudprovider.DnsTypeNS,
    91  			cloudprovider.DnsTypeSRV,
    92  			cloudprovider.DnsTypeSOA,
    93  			cloudprovider.DnsTypeTXT,
    94  			cloudprovider.DnsTypePTR,
    95  			cloudprovider.DnsTypeNAPTR,
    96  			cloudprovider.DnsTypeSPF,
    97  		},
    98  		cloudprovider.PrivateZone: []cloudprovider.TDnsType{
    99  			cloudprovider.DnsTypeA,
   100  			cloudprovider.DnsTypeAAAA,
   101  			cloudprovider.DnsTypeCAA,
   102  			cloudprovider.DnsTypeCNAME,
   103  			cloudprovider.DnsTypeMX,
   104  			cloudprovider.DnsTypeNS,
   105  			cloudprovider.DnsTypeSRV,
   106  			cloudprovider.DnsTypeSOA,
   107  			cloudprovider.DnsTypeTXT,
   108  			cloudprovider.DnsTypePTR,
   109  			cloudprovider.DnsTypeNAPTR,
   110  			cloudprovider.DnsTypeSPF,
   111  		},
   112  	}
   113  }
   114  
   115  func (self *SAwsProviderFactory) GetSupportedDnsPolicyTypes() map[cloudprovider.TDnsZoneType][]cloudprovider.TDnsPolicyType {
   116  	return map[cloudprovider.TDnsZoneType][]cloudprovider.TDnsPolicyType{
   117  		cloudprovider.PublicZone: []cloudprovider.TDnsPolicyType{
   118  			cloudprovider.DnsPolicyTypeSimple,
   119  			cloudprovider.DnsPolicyTypeByGeoLocation,
   120  			cloudprovider.DnsPolicyTypeWeighted,
   121  			cloudprovider.DnsPolicyTypeFailover,
   122  			cloudprovider.DnsPolicyTypeMultiValueAnswer,
   123  			cloudprovider.DnsPolicyTypeLatency,
   124  		},
   125  		cloudprovider.PrivateZone: []cloudprovider.TDnsPolicyType{
   126  			cloudprovider.DnsPolicyTypeSimple,
   127  			cloudprovider.DnsPolicyTypeWeighted,
   128  			cloudprovider.DnsPolicyTypeFailover,
   129  			cloudprovider.DnsPolicyTypeMultiValueAnswer,
   130  			cloudprovider.DnsPolicyTypeLatency,
   131  		},
   132  	}
   133  }
   134  
   135  func (self *SAwsProviderFactory) GetSupportedDnsPolicyValues() map[cloudprovider.TDnsPolicyType][]cloudprovider.TDnsPolicyValue {
   136  	return map[cloudprovider.TDnsPolicyType][]cloudprovider.TDnsPolicyValue{
   137  		cloudprovider.DnsPolicyTypeByGeoLocation: cloudprovider.AwsGeoLocations,
   138  		cloudprovider.DnsPolicyTypeLatency:       cloudprovider.AwsRegions,
   139  		cloudprovider.DnsPolicyTypeFailover:      cloudprovider.AwsFailovers,
   140  	}
   141  }
   142  
   143  func (factory *SAwsProviderFactory) IsSupportCrossCloudEnvVpcPeering() bool {
   144  	return false
   145  }
   146  
   147  func (factory *SAwsProviderFactory) IsSupportCrossRegionVpcPeering() bool {
   148  	return true
   149  }
   150  
   151  func (factory *SAwsProviderFactory) IsSupportVpcPeeringVpcCidrOverlap() bool {
   152  	return false
   153  }
   154  
   155  func (factory *SAwsProviderFactory) IsSupportModifyRouteTable() bool {
   156  	return true
   157  }
   158  
   159  func (self *SAwsProviderFactory) ValidateCreateCloudaccountData(ctx context.Context, userCred mcclient.TokenCredential, input cloudprovider.SCloudaccountCredential) (cloudprovider.SCloudaccount, error) {
   160  	output := cloudprovider.SCloudaccount{}
   161  	if len(input.AccessKeyId) == 0 {
   162  		return output, errors.Wrap(httperrors.ErrMissingParameter, "access_key_id")
   163  	}
   164  	if len(input.AccessKeySecret) == 0 {
   165  		return output, errors.Wrap(httperrors.ErrMissingParameter, "access_key_secret")
   166  	}
   167  	if len(input.Environment) == 0 {
   168  		return output, errors.Wrap(httperrors.ErrMissingParameter, "environment")
   169  	}
   170  	output.Account = input.AccessKeyId
   171  	output.Secret = input.AccessKeySecret
   172  	output.AccessUrl = input.Environment
   173  	return output, nil
   174  }
   175  
   176  func (self *SAwsProviderFactory) ValidateUpdateCloudaccountCredential(ctx context.Context, userCred mcclient.TokenCredential, input cloudprovider.SCloudaccountCredential, cloudaccount string) (cloudprovider.SCloudaccount, error) {
   177  	output := cloudprovider.SCloudaccount{}
   178  	if len(input.AccessKeyId) == 0 {
   179  		return output, errors.Wrap(httperrors.ErrMissingParameter, "access_key_id")
   180  	}
   181  	if len(input.AccessKeySecret) == 0 {
   182  		return output, errors.Wrap(httperrors.ErrMissingParameter, "access_key_secret")
   183  	}
   184  	output = cloudprovider.SCloudaccount{
   185  		Account: input.AccessKeyId,
   186  		Secret:  input.AccessKeySecret,
   187  	}
   188  	return output, nil
   189  }
   190  
   191  func parseAccount(account, secret string) (accessKey string, secretKey string, accountId string) {
   192  	slash := strings.Index(account, "/")
   193  	if slash > 0 {
   194  		accessKey = account[:slash]
   195  		accountId = account[slash+1:]
   196  	} else {
   197  		accessKey = account
   198  	}
   199  	secretKey = secret
   200  	return
   201  }
   202  
   203  func (self *SAwsProviderFactory) GetProvider(cfg cloudprovider.ProviderConfig) (cloudprovider.ICloudProvider, error) {
   204  	extra := cloudprovider.SAWSExtraOptions{}
   205  	if cfg.Options != nil {
   206  		cfg.Options.Unmarshal(&extra)
   207  	}
   208  	accessKey, secret, accountId := parseAccount(cfg.Account, cfg.Secret)
   209  	client, err := aws.NewAwsClient(
   210  		aws.NewAwsClientConfig(
   211  			cfg.URL, accessKey, secret, accountId,
   212  		).SetAssumeRole(extra.AWSAssumeRoleName).CloudproviderConfig(cfg),
   213  	)
   214  	if err != nil {
   215  		return nil, errors.Wrap(err, "NewAwsClient")
   216  	}
   217  	return &SAwsProvider{
   218  		SBaseProvider: cloudprovider.NewBaseProvider(self),
   219  		client:        client,
   220  	}, nil
   221  }
   222  
   223  func (self *SAwsProviderFactory) GetClientRC(info cloudprovider.SProviderInfo) (map[string]string, error) {
   224  	accessKey, secret, accountId := parseAccount(info.Account, info.Secret)
   225  	return map[string]string{
   226  		"AWS_ACCESS_URL": info.Url,
   227  		"AWS_ACCESS_KEY": accessKey,
   228  		"AWS_SECRET":     secret,
   229  		"AWS_REGION":     aws.GetDefaultRegionId(info.Url),
   230  		"AWS_ACCOUNT_ID": accountId,
   231  	}, nil
   232  }
   233  
   234  func init() {
   235  	factory := SAwsProviderFactory{}
   236  	cloudprovider.RegisterFactory(&factory)
   237  }
   238  
   239  type SAwsProvider struct {
   240  	cloudprovider.SBaseProvider
   241  	client *aws.SAwsClient
   242  }
   243  
   244  func (self *SAwsProvider) GetSubAccounts() ([]cloudprovider.SSubAccount, error) {
   245  	return self.client.GetSubAccounts()
   246  }
   247  
   248  func (self *SAwsProvider) GetAccountId() string {
   249  	return self.client.GetAccountId()
   250  }
   251  
   252  func (self *SAwsProvider) GetIamLoginUrl() string {
   253  	return self.client.GetIamLoginUrl()
   254  }
   255  
   256  func (self *SAwsProvider) GetIRegions() []cloudprovider.ICloudRegion {
   257  	return self.client.GetIRegions()
   258  }
   259  
   260  func (self *SAwsProvider) GetSysInfo() (jsonutils.JSONObject, error) {
   261  	regions := self.client.GetIRegions()
   262  	info := jsonutils.NewDict()
   263  	info.Add(jsonutils.NewInt(int64(len(regions))), "region_count")
   264  	info.Add(jsonutils.NewString(aws.AWS_API_VERSION), "api_version")
   265  	return info, nil
   266  }
   267  
   268  func (self *SAwsProvider) GetVersion() string {
   269  	return aws.AWS_API_VERSION
   270  }
   271  
   272  func (self *SAwsProvider) GetIRegionById(id string) (cloudprovider.ICloudRegion, error) {
   273  	return self.client.GetIRegionById(id)
   274  }
   275  
   276  func (self *SAwsProvider) GetBalance() (float64, string, error) {
   277  	return 0.0, api.CLOUD_PROVIDER_HEALTH_NORMAL, cloudprovider.ErrNotSupported
   278  }
   279  
   280  func (self *SAwsProvider) GetIProjects() ([]cloudprovider.ICloudProject, error) {
   281  	return self.client.GetIProjects()
   282  }
   283  
   284  func (self *SAwsProvider) GetStorageClasses(regionId string) []string {
   285  	return []string{
   286  		"STANDARD",
   287  		"STANDARD_IA",
   288  		"ONEZONE_IA",
   289  		"GLACIER",
   290  		"DEEP_ARCHIVE",
   291  		"INTELLIGENT_TIERING",
   292  	}
   293  }
   294  
   295  func (self *SAwsProvider) GetBucketCannedAcls(regionId string) []string {
   296  	return self.client.GetBucketCannedAcls()
   297  }
   298  
   299  func (self *SAwsProvider) GetObjectCannedAcls(regionId string) []string {
   300  	return self.client.GetObjectCannedAcls()
   301  }
   302  
   303  func (self *SAwsProvider) GetCloudRegionExternalIdPrefix() string {
   304  	return self.client.GetAccessEnv() + "/"
   305  }
   306  
   307  func (self *SAwsProvider) GetCapabilities() []string {
   308  	return self.client.GetCapabilities()
   309  }
   310  
   311  func (self *SAwsProvider) CreateIClouduser(conf *cloudprovider.SClouduserCreateConfig) (cloudprovider.IClouduser, error) {
   312  	return self.client.CreateIClouduser(conf)
   313  }
   314  
   315  func (self *SAwsProvider) GetICloudusers() ([]cloudprovider.IClouduser, error) {
   316  	return self.client.GetICloudusers()
   317  }
   318  
   319  func (self *SAwsProvider) GetICloudgroups() ([]cloudprovider.ICloudgroup, error) {
   320  	return self.client.GetICloudgroups()
   321  }
   322  
   323  func (self *SAwsProvider) GetICloudgroupByName(name string) (cloudprovider.ICloudgroup, error) {
   324  	return self.client.GetICloudgroupByName(name)
   325  }
   326  
   327  func (self *SAwsProvider) CreateICloudgroup(name, desc string) (cloudprovider.ICloudgroup, error) {
   328  	return self.client.CreateICloudgroup(name, desc)
   329  }
   330  
   331  func (self *SAwsProvider) GetISystemCloudpolicies() ([]cloudprovider.ICloudpolicy, error) {
   332  	return self.client.GetISystemCloudpolicies()
   333  }
   334  
   335  func (self *SAwsProvider) GetICustomCloudpolicies() ([]cloudprovider.ICloudpolicy, error) {
   336  	return self.client.GetICustomCloudpolicies()
   337  }
   338  
   339  func (self *SAwsProvider) GetIClouduserByName(name string) (cloudprovider.IClouduser, error) {
   340  	return self.client.GetIClouduserByName(name)
   341  }
   342  
   343  func (self *SAwsProvider) CreateICloudpolicy(opts *cloudprovider.SCloudpolicyCreateOptions) (cloudprovider.ICloudpolicy, error) {
   344  	return self.client.CreateICloudpolicy(opts)
   345  }
   346  
   347  func (self *SAwsProvider) GetSamlEntityId() string {
   348  	return self.client.GetSamlEntityId()
   349  }
   350  
   351  func (self *SAwsProvider) GetICloudDnsZones() ([]cloudprovider.ICloudDnsZone, error) {
   352  	return self.client.GetICloudDnsZones()
   353  }
   354  
   355  func (self *SAwsProvider) GetICloudDnsZoneById(id string) (cloudprovider.ICloudDnsZone, error) {
   356  	return self.client.GetHostedZoneById(id)
   357  }
   358  
   359  func (self *SAwsProvider) CreateICloudDnsZone(opts *cloudprovider.SDnsZoneCreateOptions) (cloudprovider.ICloudDnsZone, error) {
   360  	return self.client.CreateHostedZone(opts)
   361  }
   362  
   363  func (self *SAwsProvider) GetICloudSAMLProviders() ([]cloudprovider.ICloudSAMLProvider, error) {
   364  	return self.client.GetICloudSAMLProviders()
   365  }
   366  
   367  func (self *SAwsProvider) CreateICloudSAMLProvider(opts *cloudprovider.SAMLProviderCreateOptions) (cloudprovider.ICloudSAMLProvider, error) {
   368  	sp, err := self.client.CreateSAMLProvider(opts.Name, opts.Metadata.String())
   369  	if err != nil {
   370  		return nil, errors.Wrap(err, "CreateSAMLProvider")
   371  	}
   372  	return sp, nil
   373  }
   374  
   375  func (self *SAwsProvider) GetICloudroles() ([]cloudprovider.ICloudrole, error) {
   376  	return self.client.GetICloudroles()
   377  }
   378  
   379  func (self *SAwsProvider) GetICloudroleById(id string) (cloudprovider.ICloudrole, error) {
   380  	roles, err := self.GetICloudroles()
   381  	if err != nil {
   382  		return nil, errors.Wrapf(err, "GetICloudroles")
   383  	}
   384  	for i := range roles {
   385  		if roles[i].GetGlobalId() == id {
   386  			return roles[i], nil
   387  		}
   388  	}
   389  	return nil, errors.Wrapf(cloudprovider.ErrNotFound, id)
   390  }
   391  
   392  func (self *SAwsProvider) GetICloudroleByName(name string) (cloudprovider.ICloudrole, error) {
   393  	role, err := self.client.GetRole(name)
   394  	if err != nil {
   395  		return nil, errors.Wrapf(err, "GetRole(%s)", name)
   396  	}
   397  	return role, nil
   398  }
   399  
   400  func (self *SAwsProvider) CreateICloudrole(opts *cloudprovider.SRoleCreateOptions) (cloudprovider.ICloudrole, error) {
   401  	role, err := self.client.CreateRole(opts)
   402  	if err != nil {
   403  		return nil, errors.Wrapf(err, "CreateRole")
   404  	}
   405  	return role, nil
   406  }
   407  
   408  func (self *SAwsProvider) GetMetrics(opts *cloudprovider.MetricListOptions) ([]cloudprovider.MetricValues, error) {
   409  	return self.client.GetMetrics(opts)
   410  }