yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/azure/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/log" 24 "yunion.io/x/pkg/errors" 25 26 api "yunion.io/x/cloudmux/pkg/apis/compute" 27 "yunion.io/x/cloudmux/pkg/cloudprovider" 28 "yunion.io/x/onecloud/pkg/httperrors" 29 "yunion.io/x/onecloud/pkg/mcclient" 30 "yunion.io/x/cloudmux/pkg/multicloud/azure" 31 ) 32 33 type SAzureProviderFactory struct { 34 cloudprovider.SPublicCloudBaseProviderFactory 35 } 36 37 func (self *SAzureProviderFactory) GetId() string { 38 return azure.CLOUD_PROVIDER_AZURE 39 } 40 41 func (self *SAzureProviderFactory) GetName() string { 42 return azure.CLOUD_PROVIDER_AZURE_CN 43 } 44 45 func (self *SAzureProviderFactory) GetMaxCloudEventKeepDays() int { 46 return 90 47 } 48 49 func (self *SAzureProviderFactory) GetMaxCloudEventSyncDays() int { 50 return 7 51 } 52 53 func (self *SAzureProviderFactory) IsCloudeventRegional() bool { 54 return false 55 } 56 57 func (self *SAzureProviderFactory) IsSupportSAMLAuth() bool { 58 return true 59 } 60 61 func (self *SAzureProviderFactory) ValidateChangeBandwidth(instanceId string, bandwidth int64) error { 62 return fmt.Errorf("Changing %s bandwidth is not supported", azure.CLOUD_PROVIDER_AZURE) 63 } 64 65 func (self *SAzureProviderFactory) IsSupportPrepaidResources() bool { 66 return false 67 } 68 69 func (self *SAzureProviderFactory) IsSupportCloudIdService() bool { 70 return true 71 } 72 73 func (self *SAzureProviderFactory) IsSupportCreateCloudgroup() bool { 74 return true 75 } 76 77 func (self *SAzureProviderFactory) ValidateCreateCloudaccountData(ctx context.Context, userCred mcclient.TokenCredential, input cloudprovider.SCloudaccountCredential) (cloudprovider.SCloudaccount, error) { 78 output := cloudprovider.SCloudaccount{} 79 if len(input.DirectoryId) == 0 { 80 return output, errors.Wrap(httperrors.ErrMissingParameter, "directory_id") 81 } 82 if len(input.ClientId) == 0 { 83 return output, errors.Wrap(httperrors.ErrMissingParameter, "client_id") 84 } 85 if len(input.ClientSecret) == 0 { 86 return output, errors.Wrap(httperrors.ErrMissingParameter, "client_secret") 87 } 88 if len(input.Environment) == 0 { 89 return output, errors.Wrap(httperrors.ErrMissingParameter, "environment") 90 } 91 output.Account = input.DirectoryId 92 output.Secret = fmt.Sprintf("%s/%s", input.ClientId, input.ClientSecret) 93 output.AccessUrl = input.Environment 94 return output, nil 95 } 96 97 func (self *SAzureProviderFactory) ValidateUpdateCloudaccountCredential(ctx context.Context, userCred mcclient.TokenCredential, input cloudprovider.SCloudaccountCredential, cloudaccount string) (cloudprovider.SCloudaccount, error) { 98 output := cloudprovider.SCloudaccount{} 99 if len(input.ClientId) == 0 { 100 return output, errors.Wrap(httperrors.ErrMissingParameter, "client_id") 101 } 102 if len(input.ClientSecret) == 0 { 103 return output, errors.Wrap(httperrors.ErrMissingParameter, "client_secret") 104 } 105 output = cloudprovider.SCloudaccount{ 106 Account: cloudaccount, 107 Secret: fmt.Sprintf("%s/%s", input.ClientId, input.ClientSecret), 108 } 109 return output, nil 110 } 111 112 func parseAccount(account, secret string) (tenantId string, appId string, appKey string, subId string) { 113 clientInfo := strings.Split(secret, "/") 114 accountInfo := strings.Split(account, "/") 115 tenantId = accountInfo[0] 116 if len(accountInfo) > 1 { 117 subId = strings.Join(accountInfo[1:], "/") 118 } 119 appId = clientInfo[0] 120 if len(clientInfo) > 1 { 121 appKey = strings.Join(clientInfo[1:], "/") 122 } 123 return 124 } 125 126 func (self *SAzureProviderFactory) GetProvider(cfg cloudprovider.ProviderConfig) (cloudprovider.ICloudProvider, error) { 127 tenantId, appId, appKey, subId := parseAccount(cfg.Account, cfg.Secret) 128 if client, err := azure.NewAzureClient( 129 azure.NewAzureClientConfig( 130 cfg.URL, tenantId, appId, appKey, 131 ).SubscriptionId(subId).CloudproviderConfig(cfg), 132 ); err != nil { 133 return nil, err 134 } else { 135 return &SAzureProvider{ 136 SBaseProvider: cloudprovider.NewBaseProvider(self), 137 client: client, 138 }, nil 139 } 140 } 141 142 func (self *SAzureProviderFactory) GetClientRC(info cloudprovider.SProviderInfo) (map[string]string, error) { 143 tenantId, appId, appKey, subId := parseAccount(info.Account, info.Secret) 144 defaultRegion := "" 145 switch info.Url { 146 case "AzurePublicCloud": 147 defaultRegion = "eastus" 148 case "AzureChinaCloud": 149 defaultRegion = "chinaeast2" 150 } 151 return map[string]string{ 152 "AZURE_DIRECTORY_ID": tenantId, 153 "AZURE_SUBSCRIPTION_ID": subId, 154 "AZURE_APPLICATION_ID": appId, 155 "AZURE_APPLICATION_KEY": appKey, 156 "AZURE_REGION_ID": defaultRegion, 157 "AZURE_CLOUD_ENV": info.Url, 158 }, nil 159 } 160 161 func init() { 162 factory := SAzureProviderFactory{} 163 cloudprovider.RegisterFactory(&factory) 164 } 165 166 type SAzureProvider struct { 167 cloudprovider.SBaseProvider 168 client *azure.SAzureClient 169 } 170 171 func (self *SAzureProvider) GetSysInfo() (jsonutils.JSONObject, error) { 172 regions := self.client.GetIRegions() 173 info := jsonutils.NewDict() 174 info.Add(jsonutils.NewInt(int64(len(regions))), "region_count") 175 info.Add(jsonutils.NewString(azure.AZURE_API_VERSION), "api_version") 176 return info, nil 177 } 178 179 func (self *SAzureProvider) GetVersion() string { 180 return azure.AZURE_API_VERSION 181 } 182 183 func (self *SAzureProvider) GetSubAccounts() ([]cloudprovider.SSubAccount, error) { 184 return self.client.GetSubAccounts() 185 } 186 187 func (self *SAzureProvider) GetAccountId() string { 188 return self.client.GetAccountId() 189 } 190 191 func (self *SAzureProvider) GetIamLoginUrl() string { 192 return self.client.GetIamLoginUrl() 193 } 194 195 func (self *SAzureProvider) GetIRegions() []cloudprovider.ICloudRegion { 196 return self.client.GetIRegions() 197 } 198 199 func (self *SAzureProvider) GetIRegionById(id string) (cloudprovider.ICloudRegion, error) { 200 return self.client.GetIRegionById(id) 201 } 202 203 func (self *SAzureProvider) GetBalance() (float64, string, error) { 204 return 0.0, api.CLOUD_PROVIDER_HEALTH_NORMAL, cloudprovider.ErrNotSupported 205 } 206 207 func (self *SAzureProvider) GetIProjects() ([]cloudprovider.ICloudProject, error) { 208 return self.client.GetIProjects() 209 } 210 211 func (self *SAzureProvider) CreateIProject(name string) (cloudprovider.ICloudProject, error) { 212 return self.client.CreateIProject(name) 213 } 214 215 func (self *SAzureProvider) GetStorageClasses(regionId string) []string { 216 sc, err := self.client.GetStorageClasses(regionId) 217 if err != nil { 218 log.Errorf("Fail to find storage classes: %s", err) 219 return nil 220 } 221 return sc 222 } 223 224 func (self *SAzureProvider) GetBucketCannedAcls(regionId string) []string { 225 return []string{ 226 string(cloudprovider.ACLPrivate), 227 string(cloudprovider.ACLPublicRead), 228 } 229 } 230 231 func (self *SAzureProvider) GetObjectCannedAcls(regionId string) []string { 232 return []string{ 233 string(cloudprovider.ACLPrivate), 234 string(cloudprovider.ACLPublicRead), 235 } 236 } 237 238 func (self *SAzureProvider) GetCloudRegionExternalIdPrefix() string { 239 return self.client.GetAccessEnv() + "/" 240 } 241 242 func (self *SAzureProvider) GetCapabilities() []string { 243 return self.client.GetCapabilities() 244 } 245 246 func (self *SAzureProvider) CreateIClouduser(conf *cloudprovider.SClouduserCreateConfig) (cloudprovider.IClouduser, error) { 247 return self.client.CreateIClouduser(conf) 248 } 249 250 func (self *SAzureProvider) GetICloudusers() ([]cloudprovider.IClouduser, error) { 251 return self.client.GetICloudusers() 252 } 253 254 func (self *SAzureProvider) GetIClouduserByName(name string) (cloudprovider.IClouduser, error) { 255 return self.client.GetIClouduserByName(name) 256 } 257 258 func (self *SAzureProvider) GetICloudgroups() ([]cloudprovider.ICloudgroup, error) { 259 return self.client.GetICloudgroups() 260 } 261 262 func (self *SAzureProvider) CreateICloudgroup(name, desc string) (cloudprovider.ICloudgroup, error) { 263 return self.client.CreateICloudgroup(name, desc) 264 } 265 266 func (self *SAzureProvider) GetICloudgroupByName(name string) (cloudprovider.ICloudgroup, error) { 267 return self.client.GetICloudgroupByName(name) 268 } 269 270 func (self *SAzureProvider) GetEnrollmentAccounts() ([]cloudprovider.SEnrollmentAccount, error) { 271 return self.client.GetEnrollmentAccounts() 272 } 273 274 func (self *SAzureProvider) GetISystemCloudpolicies() ([]cloudprovider.ICloudpolicy, error) { 275 return self.client.GetISystemCloudpolicies() 276 } 277 278 func (self *SAzureProvider) GetICustomCloudpolicies() ([]cloudprovider.ICloudpolicy, error) { 279 return self.client.GetICustomCloudpolicies() 280 } 281 282 func (self *SAzureProvider) CreateSubscription(input cloudprovider.SubscriptionCreateInput) error { 283 return self.client.CreateSubscription(input.Name, input.EnrollmentAccountId, input.OfferType) 284 } 285 286 // fake func 287 func (self *SAzureProvider) CreateICloudSAMLProvider(opts *cloudprovider.SAMLProviderCreateOptions) (cloudprovider.ICloudSAMLProvider, error) { 288 return self.client.CreateSAMLProvider(opts) 289 } 290 291 func (self *SAzureProvider) GetSamlEntityId() string { 292 return cloudprovider.SAML_ENTITY_ID_AZURE 293 } 294 295 func (self *SAzureProvider) GetMetrics(opts *cloudprovider.MetricListOptions) ([]cloudprovider.MetricValues, error) { 296 return self.client.GetMetrics(opts) 297 }