yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/google/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  	"fmt"
    20  	"strings"
    21  
    22  	"yunion.io/x/jsonutils"
    23  	"yunion.io/x/pkg/errors"
    24  
    25  	api "yunion.io/x/cloudmux/pkg/apis/compute"
    26  	"yunion.io/x/cloudmux/pkg/cloudprovider"
    27  	"yunion.io/x/onecloud/pkg/httperrors"
    28  	"yunion.io/x/onecloud/pkg/mcclient"
    29  	"yunion.io/x/cloudmux/pkg/multicloud/google"
    30  )
    31  
    32  type SGoogleProviderFactory struct {
    33  	cloudprovider.SPublicCloudBaseProviderFactory
    34  }
    35  
    36  func (self *SGoogleProviderFactory) GetId() string {
    37  	return google.CLOUD_PROVIDER_GOOGLE
    38  }
    39  
    40  func (self *SGoogleProviderFactory) GetName() string {
    41  	return google.CLOUD_PROVIDER_GOOGLE_CN
    42  }
    43  
    44  func (self *SGoogleProviderFactory) ValidateChangeBandwidth(instanceId string, bandwidth int64) error {
    45  	return nil
    46  }
    47  
    48  func (self *SGoogleProviderFactory) IsSupportPrepaidResources() bool {
    49  	return false
    50  }
    51  
    52  func (self *SGoogleProviderFactory) IsClouduserSupportPassword() bool {
    53  	return false
    54  }
    55  
    56  func (factory *SGoogleProviderFactory) IsCloudpolicyWithSubscription() bool {
    57  	return true
    58  }
    59  
    60  func (factory *SGoogleProviderFactory) IsClouduserpolicyWithSubscription() bool {
    61  	return true
    62  }
    63  
    64  func (factory *SGoogleProviderFactory) IsSupportCloudIdService() bool {
    65  	return true
    66  }
    67  
    68  func (factory *SGoogleProviderFactory) IsClouduserNeedInitPolicy() bool {
    69  	return true
    70  }
    71  
    72  func (factory *SGoogleProviderFactory) IsSupportResetClouduserPassword() bool {
    73  	return false
    74  }
    75  
    76  func (factory *SGoogleProviderFactory) GetClouduserMinPolicyCount() int {
    77  	return 1
    78  }
    79  
    80  func (self *SGoogleProviderFactory) IsClouduserBelongCloudprovider() bool {
    81  	return true
    82  }
    83  
    84  func (self *SGoogleProviderFactory) NeedSyncSkuFromCloud() bool {
    85  	return false
    86  }
    87  
    88  func (self *SGoogleProviderFactory) ValidateCreateCloudaccountData(ctx context.Context, userCred mcclient.TokenCredential, input cloudprovider.SCloudaccountCredential) (cloudprovider.SCloudaccount, error) {
    89  	output := cloudprovider.SCloudaccount{}
    90  	for key, value := range map[string]string{
    91  		"client_email":   input.GCPClientEmail,
    92  		"project_id":     input.GCPProjectId,
    93  		"private_key_id": input.GCPPrivateKeyId,
    94  		"private_key":    input.GCPPrivateKey,
    95  	} {
    96  		if len(value) == 0 {
    97  			return output, errors.Wrap(httperrors.ErrMissingParameter, key)
    98  		}
    99  	}
   100  	output.Account = fmt.Sprintf("%s/%s", input.GCPProjectId, input.GCPClientEmail)
   101  	output.Secret = fmt.Sprintf("%s/%s", input.GCPPrivateKeyId, input.GCPPrivateKey)
   102  	return output, nil
   103  }
   104  
   105  func (self *SGoogleProviderFactory) ValidateUpdateCloudaccountCredential(ctx context.Context, userCred mcclient.TokenCredential, input cloudprovider.SCloudaccountCredential, cloudaccount string) (cloudprovider.SCloudaccount, error) {
   106  	output := cloudprovider.SCloudaccount{}
   107  	projectID, clientEmail := "", ""
   108  	accountInfo := strings.Split(cloudaccount, "/")
   109  	if len(accountInfo) == 2 {
   110  		projectID, clientEmail = accountInfo[0], accountInfo[1]
   111  	}
   112  
   113  	for key, value := range map[string]string{
   114  		"private_key_id": input.GCPPrivateKeyId,
   115  		"private_key":    input.GCPPrivateKey,
   116  	} {
   117  		if len(value) == 0 {
   118  			return output, errors.Wrap(httperrors.ErrMissingParameter, key)
   119  		}
   120  	}
   121  	if len(input.GCPClientEmail) == 0 {
   122  		input.GCPClientEmail = clientEmail
   123  	}
   124  
   125  	if len(input.GCPProjectId) == 0 {
   126  		input.GCPProjectId = projectID
   127  	}
   128  
   129  	output = cloudprovider.SCloudaccount{
   130  		Account: fmt.Sprintf("%s/%s", input.GCPProjectId, input.GCPClientEmail),
   131  		Secret:  fmt.Sprintf("%s/%s", input.GCPPrivateKeyId, input.GCPPrivateKey),
   132  	}
   133  	return output, nil
   134  }
   135  
   136  func (self *SGoogleProviderFactory) GetProvider(cfg cloudprovider.ProviderConfig) (cloudprovider.ICloudProvider, error) {
   137  	privateKeyID, privateKey := "", ""
   138  	privateKeyInfo := strings.Split(cfg.Secret, "/")
   139  	if len(privateKeyInfo) < 2 {
   140  		return nil, fmt.Errorf("Missing privateKeyID or privateKey for google cloud")
   141  	}
   142  	privateKeyID = privateKeyInfo[0]
   143  	privateKey = strings.Join(privateKeyInfo[1:], "/")
   144  	projectID, clientEmail := "", ""
   145  	accountInfo := strings.Split(cfg.Account, "/")
   146  	if len(accountInfo) < 2 {
   147  		return nil, fmt.Errorf("Invalid projectID or client email for google cloud %s", cfg.Account)
   148  	}
   149  	projectID, clientEmail = accountInfo[0], accountInfo[1]
   150  
   151  	client, err := google.NewGoogleClient(
   152  		google.NewGoogleClientConfig(
   153  			projectID, clientEmail, privateKeyID, privateKey,
   154  		).CloudproviderConfig(cfg),
   155  	)
   156  	if err != nil {
   157  		return nil, err
   158  	}
   159  	return &SGoogleProvider{
   160  		SBaseProvider: cloudprovider.NewBaseProvider(self),
   161  		client:        client,
   162  	}, nil
   163  }
   164  
   165  func parseAccount(account, secret string) (projectId string, clientEmail string, privateKey string, privateKeyId string) {
   166  	accountInfo := strings.Split(account, "/")
   167  	if len(accountInfo) == 2 {
   168  		projectId, clientEmail = accountInfo[0], accountInfo[1]
   169  	}
   170  	secretInfo := strings.Split(secret, "/")
   171  	if len(secretInfo) >= 2 {
   172  		privateKeyId, privateKey = secretInfo[0], strings.Join(secretInfo[1:], "/")
   173  	}
   174  	return
   175  }
   176  
   177  func (self *SGoogleProviderFactory) GetClientRC(info cloudprovider.SProviderInfo) (map[string]string, error) {
   178  	projectId, clientEmail, privateKey, privateKeyId := parseAccount(info.Account, info.Secret)
   179  	return map[string]string{
   180  		"GOOGLE_CLIENT_EMAIL":   clientEmail,
   181  		"GOOGLE_PROJECT_ID":     projectId,
   182  		"GOOGLE_PRIVATE_KEY_ID": privateKeyId,
   183  		"GOOGLE_PRIVATE_KEY":    privateKey,
   184  	}, nil
   185  }
   186  
   187  func init() {
   188  	factory := SGoogleProviderFactory{}
   189  	cloudprovider.RegisterFactory(&factory)
   190  }
   191  
   192  type SGoogleProvider struct {
   193  	cloudprovider.SBaseProvider
   194  	client *google.SGoogleClient
   195  }
   196  
   197  func (self *SGoogleProvider) GetSysInfo() (jsonutils.JSONObject, error) {
   198  	regions := self.client.GetIRegions()
   199  	info := jsonutils.NewDict()
   200  	info.Add(jsonutils.NewInt(int64(len(regions))), "region_count")
   201  	info.Add(jsonutils.NewString(google.GOOGLE_API_VERSION), "api_version")
   202  	return info, nil
   203  }
   204  
   205  func (self *SGoogleProvider) GetVersion() string {
   206  	return google.GOOGLE_API_VERSION
   207  }
   208  
   209  func (self *SGoogleProvider) GetSubAccounts() ([]cloudprovider.SSubAccount, error) {
   210  	return self.client.GetSubAccounts()
   211  }
   212  
   213  func (self *SGoogleProvider) GetAccountId() string {
   214  	return self.client.GetAccountId()
   215  }
   216  
   217  func (self *SGoogleProvider) GetIamLoginUrl() string {
   218  	return "https://console.cloud.google.com"
   219  }
   220  
   221  func (self *SGoogleProvider) GetIRegions() []cloudprovider.ICloudRegion {
   222  	return self.client.GetIRegions()
   223  }
   224  
   225  func (self *SGoogleProvider) GetIRegionById(extId string) (cloudprovider.ICloudRegion, error) {
   226  	return self.client.GetIRegionById(extId)
   227  }
   228  
   229  func (self *SGoogleProvider) GetBalance() (float64, string, error) {
   230  	return 0.0, api.CLOUD_PROVIDER_HEALTH_NORMAL, cloudprovider.ErrNotSupported
   231  }
   232  
   233  func (self *SGoogleProvider) GetIProjects() ([]cloudprovider.ICloudProject, error) {
   234  	return self.client.GetIProjects()
   235  }
   236  
   237  func (self *SGoogleProvider) GetStorageClasses(regionId string) []string {
   238  	return []string{
   239  		"STANDARD", "NEARLINE", "COLDLINE", "ARCHIVE",
   240  	}
   241  }
   242  
   243  func (self *SGoogleProvider) GetBucketCannedAcls(regionId string) []string {
   244  	return []string{
   245  		string(cloudprovider.ACLPrivate),
   246  		string(cloudprovider.ACLAuthRead),
   247  		string(cloudprovider.ACLPublicRead),
   248  		string(cloudprovider.ACLPublicReadWrite),
   249  	}
   250  }
   251  
   252  func (self *SGoogleProvider) GetObjectCannedAcls(regionId string) []string {
   253  	return []string{
   254  		string(cloudprovider.ACLPrivate),
   255  		string(cloudprovider.ACLAuthRead),
   256  		string(cloudprovider.ACLPublicRead),
   257  		string(cloudprovider.ACLPublicReadWrite),
   258  	}
   259  }
   260  
   261  func (self *SGoogleProvider) GetCapabilities() []string {
   262  	return self.client.GetCapabilities()
   263  }
   264  
   265  func (self *SGoogleProvider) GetICloudusers() ([]cloudprovider.IClouduser, error) {
   266  	return self.client.GetICloudusers()
   267  }
   268  
   269  func (self *SGoogleProvider) GetICloudgroups() ([]cloudprovider.ICloudgroup, error) {
   270  	return []cloudprovider.ICloudgroup{}, nil
   271  }
   272  
   273  func (self *SGoogleProvider) GetICloudgroupByName(name string) (cloudprovider.ICloudgroup, error) {
   274  	return nil, cloudprovider.ErrNotFound
   275  }
   276  
   277  func (self *SGoogleProvider) GetISystemCloudpolicies() ([]cloudprovider.ICloudpolicy, error) {
   278  	return self.client.GetISystemCloudpolicies()
   279  }
   280  
   281  func (self *SGoogleProvider) GetICustomCloudpolicies() ([]cloudprovider.ICloudpolicy, error) {
   282  	return self.client.GetICustomCloudpolicies()
   283  }
   284  
   285  func (self *SGoogleProvider) CreateIClouduser(conf *cloudprovider.SClouduserCreateConfig) (cloudprovider.IClouduser, error) {
   286  	return self.client.CreateIClouduser(conf)
   287  }
   288  
   289  func (self *SGoogleProvider) GetIClouduserByName(name string) (cloudprovider.IClouduser, error) {
   290  	return self.client.GetIClouduserByName(name)
   291  }
   292  
   293  func (self *SGoogleProvider) CreateICloudpolicy(opts *cloudprovider.SCloudpolicyCreateOptions) (cloudprovider.ICloudpolicy, error) {
   294  	return self.client.CreateICloudpolicy(opts)
   295  }
   296  
   297  func (self *SGoogleProvider) GetSamlEntityId() string {
   298  	return cloudprovider.SAML_ENTITY_ID_GOOGLE
   299  }
   300  
   301  func (self *SGoogleProvider) GetICloudGlobalVpcs() ([]cloudprovider.ICloudGlobalVpc, error) {
   302  	return self.client.GetICloudGlobalVpcs()
   303  }
   304  
   305  func (self *SGoogleProvider) GetICloudGlobalVpcById(id string) (cloudprovider.ICloudGlobalVpc, error) {
   306  	return self.client.GetICloudGlobalVpcById(id)
   307  }
   308  
   309  func (self *SGoogleProvider) CreateICloudGlobalVpc(opts *cloudprovider.GlobalVpcCreateOptions) (cloudprovider.ICloudGlobalVpc, error) {
   310  	return self.client.CreateICloudGlobalVpc(opts)
   311  }
   312  
   313  func (self *SGoogleProvider) GetMetrics(opts *cloudprovider.MetricListOptions) ([]cloudprovider.MetricValues, error) {
   314  	return self.client.GetMetrics(opts)
   315  }