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 }