diff --git a/cmd/climc/shell/cloudaccounts.go b/cmd/climc/shell/cloudaccounts.go index 9c9369875a..49998c86d5 100644 --- a/cmd/climc/shell/cloudaccounts.go +++ b/cmd/climc/shell/cloudaccounts.go @@ -1,6 +1,8 @@ package shell import ( + "fmt" + "yunion.io/x/jsonutils" "yunion.io/x/onecloud/pkg/mcclient" @@ -31,13 +33,24 @@ func init() { }) type CloudaccountCreateOptions struct { - NAME string `help:"Name of cloud account"` - ACCOUNT string `help:"Account to access the cloud account"` - SECRET string `help:"Secret to access the cloud account, clientId/clientScret for Azure"` - PROVIDER string `help:"Driver for cloud account" choices:"VMware|Aliyun|Azure|Qcloud|OpenStack|Huawei"` - AccessURL string `helo:"hello" metavar:"Azure choices: "` - Desc string `help:"Description"` - Enabled bool `help:"Enabled the account automatically"` + NAME string `help:"Name of cloud account"` + AccessKeyID string `help:"Aiyun|HuaWei|Aws access_key_id"` + AccessKeySecret string `help:"Aiyun|HuaWei|Aws access_key_secret"` + AppID string `help:"Qcloud appid"` + SecretID string `help:"Qcloud secret_id"` + SecretKey string `help:"Qcloud secret_key"` + ProjectName string `help:"OpenStack project_name"` + Username string `help:"OpenStack|VMware username"` + Password string `help:"OpenStack|VMware password"` + AuthURL string `help:"OpenStack auth_url"` + Host string `help:"VMware host"` + TenantID string `help:"Azure tenant_id"` + ClientID string `help:"Azure tenant_id"` + ClientSecret string `help:"Azure clinet_secret"` + Environment string `help:"Azure|Huawei|Aws environment" choices:"AzureGermanCloud|AzureChinaCloud|AzureUSGovernmentCloud|AzurePublicCloud|InternationalCloud|ChinaCloud|"` + PROVIDER string `help:"Driver for cloud account" choices:"VMware|Aliyun|Azure|Qcloud|OpenStack|Huawei|Aws"` + Desc string `help:"Description"` + Enabled bool `help:"Enabled the account automatically"` Import bool `help:"Import all sub account automatically"` AutoSync bool `help:"Enabled the account automatically"` @@ -46,9 +59,31 @@ func init() { R(&CloudaccountCreateOptions{}, "cloud-account-create", "Create a cloud account", func(s *mcclient.ClientSession, args *CloudaccountCreateOptions) error { params := jsonutils.NewDict() params.Add(jsonutils.NewString(args.NAME), "name") - params.Add(jsonutils.NewString(args.ACCOUNT), "account") - params.Add(jsonutils.NewString(args.SECRET), "secret") params.Add(jsonutils.NewString(args.PROVIDER), "provider") + data := jsonutils.Marshal(args) + + requireParamsMap := map[string][]string{ + "VMware": {"username", "password", "host"}, + "Aliyun": {"access_key_id", "access_key_secret"}, + "Azure": {"tenant_id", "client_id", "client_secret", "environment"}, + "Qcloud": {"app_id", "secret_id", "secret_key"}, + "OpenStack": {"project_name", "username", "password"}, + "Huawei": {"access_key_id", "access_key_secret", "environment"}, + "Aws": {"access_key_id", "access_key_secret", "environment"}, + } + + requireParams, ok := requireParamsMap[args.PROVIDER] + if !ok { + return fmt.Errorf("Unsupport provider %s", args.PROVIDER) + } + + for _, key := range requireParams { + v, _ := data.GetString(key) + if len(v) == 0 { + return fmt.Errorf("Missing %s", key) + } + params.Add(jsonutils.NewString(v), key) + } if args.Enabled { params.Add(jsonutils.JSONTrue, "enabled") @@ -64,9 +99,6 @@ func init() { } } - if len(args.AccessURL) > 0 { - params.Add(jsonutils.NewString(args.AccessURL), "access_url") - } if len(args.Desc) > 0 { params.Add(jsonutils.NewString(args.Desc), "description") } @@ -182,15 +214,20 @@ func init() { }) type CloudaccountUpdateCredentialOptions struct { - ID string `help:"ID or Name of cloud account"` - ACCOUNT string `help:"new account"` - SECRET string `help:"new secret"` + ID string `help:"ID or Name of cloud account"` + AccessKeyID string `help:"Aiyun|HuaWei|Aws access_key_id"` + AccessKeySecret string `help:"Aiyun|HuaWei|Aws access_key_secret"` + AppID string `help:"Qcloud appid"` + SecretID string `help:"Qcloud secret_id"` + SecretKey string `help:"Qcloud secret_key"` + ProjectName string `help:"OpenStack project_name"` + Username string `help:"OpenStack|VMware username"` + Password string `help:"OpenStack|VMware password"` + ClientID string `help:"Azure tenant_id"` + ClientSecret string `help:"Azure clinet_secret"` } R(&CloudaccountUpdateCredentialOptions{}, "cloud-account-update-credential", "Update credential of a cloud account", func(s *mcclient.ClientSession, args *CloudaccountUpdateCredentialOptions) error { - params := jsonutils.NewDict() - params.Add(jsonutils.NewString(args.ACCOUNT), "account") - params.Add(jsonutils.NewString(args.SECRET), "secret") - + params := jsonutils.Marshal(args) result, err := modules.Cloudaccounts.PerformAction(s, args.ID, "update-credential", params) if err != nil { return err diff --git a/pkg/cloudprovider/cloudprovider.go b/pkg/cloudprovider/cloudprovider.go index d3ac984b57..95185ef9a4 100644 --- a/pkg/cloudprovider/cloudprovider.go +++ b/pkg/cloudprovider/cloudprovider.go @@ -1,22 +1,31 @@ package cloudprovider import ( + "context" "fmt" "errors" "yunion.io/x/jsonutils" "yunion.io/x/log" + "yunion.io/x/onecloud/pkg/mcclient" ) var ( ErrNoSuchProvder = errors.New("no such provider") ) +type SCloudaccount struct { + Account string + Secret string +} + type ICloudProviderFactory interface { GetProvider(providerId, providerName, url, account, secret string) (ICloudProvider, error) GetId() string ValidateChangeBandwidth(instanceId string, bandwidth int64) error + ValidateCreateCloudaccountData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) error + ValidateUpdateCloudaccountCredential(ctx context.Context, userCred mcclient.TokenCredential, data jsonutils.JSONObject, cloudaccount string) (*SCloudaccount, error) } type ICloudProvider interface { diff --git a/pkg/compute/models/cloudaccounts.go b/pkg/compute/models/cloudaccounts.go index 071a077715..8f10df67a3 100644 --- a/pkg/compute/models/cloudaccounts.go +++ b/pkg/compute/models/cloudaccounts.go @@ -142,6 +142,10 @@ func (manager *SCloudaccountManager) ValidateCreateData(ctx context.Context, use if !cloudprovider.IsSupported(provider) { return nil, httperrors.NewInputParameterError("Unsupported provider %s", provider) } + providerDriver, _ := cloudprovider.GetProviderDriver(provider) + if err := providerDriver.ValidateCreateCloudaccountData(ctx, userCred, data); err != nil { + return nil, err + } // check duplication // url, account, provider must be unique account, _ := data.GetString("account") @@ -165,8 +169,8 @@ func (manager *SCloudaccountManager) ValidateCreateData(ctx context.Context, use if err == cloudprovider.ErrNoSuchProvder { return nil, httperrors.NewResourceNotFoundError("no such provider %s", provider) } - log.Debugf("ValidateCreateData %s", err.Error()) - return nil, httperrors.NewInputParameterError("invalid cloud account info") + //log.Debugf("ValidateCreateData %s", err.Error()) + return nil, httperrors.NewInputParameterError("invalid cloud account info error: %s", err.Error()) } return manager.SEnabledStatusStandaloneResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data) @@ -245,47 +249,37 @@ func (self *SCloudaccount) PerformUpdateCredential(ctx context.Context, userCred return nil, httperrors.NewInvalidStatusError("Account disabled") } - var err error - changed := false - secret, _ := data.GetString("secret") - account, _ := data.GetString("account") - if len(account) > 0 && self.Provider == CLOUD_PROVIDER_AZURE { - return nil, httperrors.NewInputParameterError("not allow update azure tenant info") + providerDriver, _ := cloudprovider.GetProviderDriver(self.Provider) + account, err := providerDriver.ValidateUpdateCloudaccountCredential(ctx, userCred, data, self.Account) + if err != nil { + return nil, err } - accessUrl, _ := data.GetString("access_url") - if len(secret) > 0 || len(account) > 0 || len(accessUrl) > 0 { + + changed := false + // secret, _ := data.GetString("secret") + // account, _ := data.GetString("account") + if len(account.Secret) > 0 || len(account.Account) > 0 { // check duplication q := self.GetModelManager().Query() - q = q.Equals("access_url", accessUrl) - q = q.Equals("account", account) + q = q.Equals("account", account.Account) q = q.NotEquals("id", self.Id) if q.Count() > 0 { - return nil, httperrors.NewConflictError("Access url and account conflict") + return nil, httperrors.NewConflictError("account %s conflict", account.Account) } } - validateUrl := self.AccessUrl - if len(accessUrl) > 0 { - validateUrl = accessUrl - } - validateAccount := self.Account - if len(account) > 0 { - validateAccount = account - } - validateSecret, _ := self.getPassword() - if len(secret) > 0 { - validateSecret = secret - } - if err := cloudprovider.IsValidCloudAccount(validateUrl, validateAccount, validateSecret, self.Provider); err != nil { - return nil, httperrors.NewInputParameterError("invalid cloud account info") + originSecret, _ := self.getPassword() + + if err := cloudprovider.IsValidCloudAccount(self.AccessUrl, account.Account, account.Secret, self.Provider); err != nil { + return nil, httperrors.NewInputParameterError("invalid cloud account info error: %s", err.Error()) } - if (len(account) > 0 && account != self.Account) || (len(accessUrl) > 0 && accessUrl != self.AccessUrl) { - if len(account) > 0 && account != self.Account { + if (account.Account != self.Account) || (account.Secret != originSecret) { + if account.Account != self.Account { for _, cloudprovider := range self.GetCloudproviders() { if cloudprovider.Account == self.Account { _, err = cloudprovider.GetModelManager().TableSpec().Update(&cloudprovider, func() error { - cloudprovider.Account = account + cloudprovider.Account = account.Account return nil }) if err != nil { @@ -295,30 +289,21 @@ func (self *SCloudaccount) PerformUpdateCredential(ctx context.Context, userCred } } _, err = self.GetModelManager().TableSpec().Update(self, func() error { - if len(account) > 0 { - self.Account = account - } - if len(accessUrl) > 0 { - self.AccessUrl = accessUrl - } + self.Account = account.Account return nil }) if err != nil { return nil, err } - changed = true - } - if len(secret) > 0 { - err = self.savePassword(secret) + err = self.savePassword(account.Secret) if err != nil { return nil, err } for _, provider := range self.GetCloudproviders() { - provider.savePassword(secret) + provider.savePassword(account.Secret) } - changed = true } diff --git a/pkg/util/aliyun/provider/provider.go b/pkg/util/aliyun/provider/provider.go index 3cbc985c7b..d62276a9c3 100644 --- a/pkg/util/aliyun/provider/provider.go +++ b/pkg/util/aliyun/provider/provider.go @@ -1,9 +1,13 @@ package provider import ( + "context" + "yunion.io/x/jsonutils" "yunion.io/x/onecloud/pkg/cloudprovider" + "yunion.io/x/onecloud/pkg/httperrors" + "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/util/aliyun" ) @@ -19,6 +23,37 @@ func (self *SAliyunProviderFactory) ValidateChangeBandwidth(instanceId string, b return nil } +func (self *SAliyunProviderFactory) ValidateCreateCloudaccountData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) error { + accessKeyID, _ := data.GetString("access_key_id") + if len(accessKeyID) == 0 { + return httperrors.NewMissingParameterError("access_key_id") + } + accessKeySecret, _ := data.GetString("access_key_secret") + if len(accessKeySecret) == 0 { + return httperrors.NewMissingParameterError("access_key_secret") + } + data.Set("account", jsonutils.NewString(accessKeyID)) + data.Set("secret", jsonutils.NewString(accessKeySecret)) + return nil +} + +func (self *SAliyunProviderFactory) ValidateUpdateCloudaccountCredential(ctx context.Context, userCred mcclient.TokenCredential, data jsonutils.JSONObject, cloudaccount string) (*cloudprovider.SCloudaccount, error) { + + accessKeyID, _ := data.GetString("access_key_id") + if len(accessKeyID) == 0 { + return nil, httperrors.NewMissingParameterError("access_key_id") + } + accessKeySecret, _ := data.GetString("access_key_secret") + if len(accessKeySecret) == 0 { + return nil, httperrors.NewMissingParameterError("access_key_secret") + } + account := &cloudprovider.SCloudaccount{ + Account: accessKeyID, + Secret: accessKeySecret, + } + return account, nil +} + func (self *SAliyunProviderFactory) GetProvider(providerId, providerName, url, account, secret string) (cloudprovider.ICloudProvider, error) { /* provider, ok := self.providerTable[providerId] if ok { diff --git a/pkg/util/aws/provider/provider.go b/pkg/util/aws/provider/provider.go index 6dbb9a48e4..dc2b617e53 100644 --- a/pkg/util/aws/provider/provider.go +++ b/pkg/util/aws/provider/provider.go @@ -1,8 +1,12 @@ package provider import ( + "context" + "yunion.io/x/jsonutils" "yunion.io/x/onecloud/pkg/cloudprovider" + "yunion.io/x/onecloud/pkg/httperrors" + "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/util/aws" ) @@ -17,6 +21,41 @@ func (self *SAwsProviderFactory) ValidateChangeBandwidth(instanceId string, band return nil } +func (self *SAwsProviderFactory) ValidateCreateCloudaccountData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) error { + accessKeyID, _ := data.GetString("access_key_id") + if len(accessKeyID) == 0 { + return httperrors.NewMissingParameterError("access_key_id") + } + accessKeySecret, _ := data.GetString("access_key_secret") + if len(accessKeySecret) == 0 { + return httperrors.NewMissingParameterError("access_key_secret") + } + environment, _ := data.GetString("environment") + if len(environment) == 0 { + return httperrors.NewMissingParameterError("environment") + } + data.Set("account", jsonutils.NewString(accessKeyID)) + data.Set("secret", jsonutils.NewString(accessKeySecret)) + data.Set("access_url", jsonutils.NewString(environment)) + return nil +} + +func (self *SAwsProviderFactory) ValidateUpdateCloudaccountCredential(ctx context.Context, userCred mcclient.TokenCredential, data jsonutils.JSONObject, cloudaccount string) (*cloudprovider.SCloudaccount, error) { + accessKeyID, _ := data.GetString("access_key_id") + if len(accessKeyID) == 0 { + return nil, httperrors.NewMissingParameterError("access_key_id") + } + accessKeySecret, _ := data.GetString("access_key_secret") + if len(accessKeySecret) == 0 { + return nil, httperrors.NewMissingParameterError("access_key_secret") + } + account := &cloudprovider.SCloudaccount{ + Account: accessKeyID, + Secret: accessKeySecret, + } + return account, nil +} + func (self *SAwsProviderFactory) GetProvider(providerId, providerName, url, account, secret string) (cloudprovider.ICloudProvider, error) { client, err := aws.NewAwsClient(providerId, providerName, url, account, secret) if err != nil { diff --git a/pkg/util/azure/provider/provider.go b/pkg/util/azure/provider/provider.go index f4fa7bb6e5..c4e9d31030 100644 --- a/pkg/util/azure/provider/provider.go +++ b/pkg/util/azure/provider/provider.go @@ -1,10 +1,13 @@ package provider import ( + "context" "fmt" "yunion.io/x/jsonutils" "yunion.io/x/onecloud/pkg/cloudprovider" + "yunion.io/x/onecloud/pkg/httperrors" + "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/util/azure" // "yunion.io/x/log" ) @@ -20,6 +23,45 @@ func (self *SAzureProviderFactory) ValidateChangeBandwidth(instanceId string, ba return fmt.Errorf("Changing %s bandwidth is not supported", azure.CLOUD_PROVIDER_AZURE) } +func (self *SAzureProviderFactory) ValidateCreateCloudaccountData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) error { + tenantID, _ := data.GetString("tenant_id") + if len(tenantID) == 0 { + return httperrors.NewMissingParameterError("tenant_id") + } + clientID, _ := data.GetString("client_id") + if len(clientID) == 0 { + return httperrors.NewMissingParameterError("client_id") + } + clientSecret, _ := data.GetString("client_secret") + if len(clientSecret) == 0 { + return httperrors.NewMissingParameterError("client_secret") + } + environment, _ := data.GetString("environment") + if len(environment) == 0 { + return httperrors.NewMissingParameterError("environment") + } + data.Set("account", jsonutils.NewString(tenantID)) + data.Set("secret", jsonutils.NewString(fmt.Sprintf("%s/%s", clientID, clientSecret))) + data.Set("access_url", jsonutils.NewString(environment)) + return nil +} + +func (self *SAzureProviderFactory) ValidateUpdateCloudaccountCredential(ctx context.Context, userCred mcclient.TokenCredential, data jsonutils.JSONObject, cloudaccount string) (*cloudprovider.SCloudaccount, error) { + clientID, _ := data.GetString("client_id") + if len(clientID) == 0 { + return nil, httperrors.NewMissingParameterError("client_id") + } + clientSecret, _ := data.GetString("client_secret") + if len(clientSecret) == 0 { + return nil, httperrors.NewMissingParameterError("client_secret") + } + account := &cloudprovider.SCloudaccount{ + Account: cloudaccount, + Secret: fmt.Sprintf("%s/%s", clientID, clientSecret), + } + return account, nil +} + func (self *SAzureProviderFactory) GetProvider(providerId, providerName, url, account, secret string) (cloudprovider.ICloudProvider, error) { if client, err := azure.NewAzureClient(providerId, providerName, account, secret, url); err != nil { return nil, err diff --git a/pkg/util/esxi/provider/provider.go b/pkg/util/esxi/provider/provider.go index 82130232c1..9ed8b1b9fa 100644 --- a/pkg/util/esxi/provider/provider.go +++ b/pkg/util/esxi/provider/provider.go @@ -1,6 +1,7 @@ package provider import ( + "context" "fmt" "net/url" "strconv" @@ -10,6 +11,8 @@ import ( "yunion.io/x/log" "yunion.io/x/onecloud/pkg/cloudprovider" + "yunion.io/x/onecloud/pkg/httperrors" + "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/util/esxi" ) @@ -24,6 +27,46 @@ func (self *SESXiProviderFactory) ValidateChangeBandwidth(instanceId string, ban return fmt.Errorf("Changing %s bandwidth is not supported", esxi.CLOUD_PROVIDER_VMWARE) } +func (self *SESXiProviderFactory) ValidateCreateCloudaccountData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) error { + username, _ := data.GetString("username") + if len(username) == 0 { + return httperrors.NewMissingParameterError("username") + } + password, _ := data.GetString("password") + if len(password) == 0 { + return httperrors.NewMissingParameterError("password") + } + host, _ := data.GetString("host") + if len(host) == 0 { + return httperrors.NewMissingParameterError("host") + } + port, _ := data.Int("port") + accessURL := fmt.Sprintf("https://%s:%d/sdk", host, port) + if port == 0 || port == 443 { + accessURL = fmt.Sprintf("https://%s/sdk", host) + } + data.Set("account", jsonutils.NewString(username)) + data.Set("secret", jsonutils.NewString(password)) + data.Set("access_url", jsonutils.NewString(accessURL)) + return nil +} + +func (self *SESXiProviderFactory) ValidateUpdateCloudaccountCredential(ctx context.Context, userCred mcclient.TokenCredential, data jsonutils.JSONObject, cloudaccount string) (*cloudprovider.SCloudaccount, error) { + username, _ := data.GetString("username") + if len(username) == 0 { + return nil, httperrors.NewMissingParameterError("username") + } + password, _ := data.GetString("password") + if len(password) == 0 { + return nil, httperrors.NewMissingParameterError("password") + } + account := &cloudprovider.SCloudaccount{ + Account: username, + Secret: password, + } + return account, nil +} + func parseHostPort(host string, defPort int) (string, int, error) { colonPos := strings.IndexByte(host, ':') if colonPos > 0 { diff --git a/pkg/util/huawei/provider/provider.go b/pkg/util/huawei/provider/provider.go index 954be702ad..1abcb9fd94 100644 --- a/pkg/util/huawei/provider/provider.go +++ b/pkg/util/huawei/provider/provider.go @@ -1,8 +1,12 @@ package provider import ( + "context" + "yunion.io/x/jsonutils" "yunion.io/x/onecloud/pkg/cloudprovider" + "yunion.io/x/onecloud/pkg/httperrors" + "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/util/huawei" ) @@ -14,6 +18,41 @@ func (self *SHuaweiProviderFactory) ValidateChangeBandwidth(instanceId string, b return nil } +func (self *SHuaweiProviderFactory) ValidateCreateCloudaccountData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) error { + accessKeyID, _ := data.GetString("access_key_id") + if len(accessKeyID) == 0 { + return httperrors.NewMissingParameterError("access_key_id") + } + accessKeySecret, _ := data.GetString("access_key_secret") + if len(accessKeySecret) == 0 { + return httperrors.NewMissingParameterError("access_key_secret") + } + environment, _ := data.GetString("environment") + if len(environment) == 0 { + return httperrors.NewMissingParameterError("environment") + } + data.Set("account", jsonutils.NewString(accessKeyID)) + data.Set("secret", jsonutils.NewString(accessKeySecret)) + data.Set("access_url", jsonutils.NewString(environment)) + return nil +} + +func (self *SHuaweiProviderFactory) ValidateUpdateCloudaccountCredential(ctx context.Context, userCred mcclient.TokenCredential, data jsonutils.JSONObject, cloudaccount string) (*cloudprovider.SCloudaccount, error) { + accessKeyID, _ := data.GetString("access_key_id") + if len(accessKeyID) == 0 { + return nil, httperrors.NewMissingParameterError("access_key_id") + } + accessKeySecret, _ := data.GetString("access_key_secret") + if len(accessKeySecret) == 0 { + return nil, httperrors.NewMissingParameterError("access_key_secret") + } + account := &cloudprovider.SCloudaccount{ + Account: accessKeyID, + Secret: accessKeySecret, + } + return account, nil +} + func (self *SHuaweiProviderFactory) GetProvider(providerId, providerName, url, account, secret string) (cloudprovider.ICloudProvider, error) { client, err := huawei.NewHuaweiClient(providerId, providerName, url, account, secret) if err != nil { diff --git a/pkg/util/openstack/provider/provider.go b/pkg/util/openstack/provider/provider.go index b5cb52d08c..a963d74e37 100644 --- a/pkg/util/openstack/provider/provider.go +++ b/pkg/util/openstack/provider/provider.go @@ -1,11 +1,15 @@ package provider import ( + "context" + "fmt" "strings" "yunion.io/x/jsonutils" "yunion.io/x/onecloud/pkg/cloudprovider" + "yunion.io/x/onecloud/pkg/httperrors" + "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/util/openstack" ) @@ -21,6 +25,53 @@ func (self *SOpenStackProviderFactory) ValidateChangeBandwidth(instanceId string return nil } +func (self *SOpenStackProviderFactory) ValidateCreateCloudaccountData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) error { + projectName, _ := data.GetString("project_name") + if len(projectName) == 0 { + return httperrors.NewMissingParameterError("project_name") + } + username, _ := data.GetString("username") + if len(username) == 0 { + return httperrors.NewMissingParameterError("username") + } + password, _ := data.GetString("password") + if len(password) == 0 { + return httperrors.NewMissingParameterError("password") + } + authURL, _ := data.GetString("auth_url") + if len(authURL) == 0 { + return httperrors.NewMissingParameterError("auth_url") + } + data.Set("account", jsonutils.NewString(fmt.Sprintf("%s/%s", projectName, username))) + data.Set("secret", jsonutils.NewString(password)) + data.Set("access_url", jsonutils.NewString(authURL)) + return nil +} + +func (self *SOpenStackProviderFactory) ValidateUpdateCloudaccountCredential(ctx context.Context, userCred mcclient.TokenCredential, data jsonutils.JSONObject, cloudaccount string) (*cloudprovider.SCloudaccount, error) { + projectName, _ := data.GetString("project_name") + if len(projectName) == 0 { + accountInfo := strings.Split(cloudaccount, "/") + if len(accountInfo) < 2 { + return nil, httperrors.NewMissingParameterError("project_name") + } + projectName = accountInfo[1] + } + username, _ := data.GetString("username") + if len(username) == 0 { + return nil, httperrors.NewMissingParameterError("username") + } + password, _ := data.GetString("password") + if len(password) == 0 { + return nil, httperrors.NewMissingParameterError("password") + } + account := &cloudprovider.SCloudaccount{ + Account: fmt.Sprintf("%s/%s", projectName, username), + Secret: password, + } + return account, nil +} + func (self *SOpenStackProviderFactory) GetProvider(providerId, providerName, url, account, password string) (cloudprovider.ICloudProvider, error) { accountInfo := strings.Split(account, "/") username, project := accountInfo[0], "" diff --git a/pkg/util/qcloud/provider/provider.go b/pkg/util/qcloud/provider/provider.go index 6a57047365..af1f4215c8 100644 --- a/pkg/util/qcloud/provider/provider.go +++ b/pkg/util/qcloud/provider/provider.go @@ -1,10 +1,14 @@ package provider import ( + "context" "fmt" + "strings" "yunion.io/x/jsonutils" "yunion.io/x/onecloud/pkg/cloudprovider" + "yunion.io/x/onecloud/pkg/httperrors" + "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/util/qcloud" ) @@ -23,6 +27,48 @@ func (self *SQcloudProviderFactory) ValidateChangeBandwidth(instanceId string, b return nil } +func (self *SQcloudProviderFactory) ValidateCreateCloudaccountData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) error { + appID, _ := data.GetString("app_id") + if len(appID) == 0 { + return httperrors.NewMissingParameterError("app_id") + } + secretID, _ := data.GetString("secret_id") + if len(secretID) == 0 { + return httperrors.NewMissingParameterError("secret_id") + } + secretKey, _ := data.GetString("secret_key") + if len(secretKey) == 0 { + return httperrors.NewMissingParameterError("secret_key") + } + data.Set("account", jsonutils.NewString(fmt.Sprintf("%s/%s", secretID, appID))) + data.Set("secret", jsonutils.NewString(secretKey)) + return nil +} + +func (self *SQcloudProviderFactory) ValidateUpdateCloudaccountCredential(ctx context.Context, userCred mcclient.TokenCredential, data jsonutils.JSONObject, cloudaccount string) (*cloudprovider.SCloudaccount, error) { + appID, _ := data.GetString("app_id") + if len(appID) == 0 { + accountInfo := strings.Split(cloudaccount, "/") + if len(accountInfo) < 2 { + return nil, httperrors.NewMissingParameterError("app_id") + } + appID = accountInfo[1] + } + secretID, _ := data.GetString("secret_id") + if len(secretID) == 0 { + return nil, httperrors.NewMissingParameterError("secret_id") + } + secretKey, _ := data.GetString("secret_key") + if len(secretKey) == 0 { + return nil, httperrors.NewMissingParameterError("secret_key") + } + account := &cloudprovider.SCloudaccount{ + Account: fmt.Sprintf("%s/%s", secretID, appID), + Secret: secretKey, + } + return account, nil +} + func (self *SQcloudProviderFactory) GetProvider(providerId, providerName, url, account, secret string) (cloudprovider.ICloudProvider, error) { client, err := qcloud.NewQcloudClient(providerId, providerName, account, secret) if err != nil {