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 }