climc 更新

This commit is contained in:
屈轩
2019-01-17 17:28:21 +08:00
parent b68bbef09d
commit 8f65712632
10 changed files with 276 additions and 64 deletions
+56 -19
View File
@@ -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: <AzureGermanCloud、AzureChinaCloud、AzureUSGovernmentCloud、AzurePublicCloud>"`
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
+6
View File
@@ -15,11 +15,17 @@ 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 {
+23 -42
View File
@@ -169,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)
@@ -249,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 {
@@ -299,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
}
+17
View File
@@ -37,6 +37,23 @@ func (self *SAliyunProviderFactory) ValidateCreateCloudaccountData(ctx context.C
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 {
+32
View File
@@ -5,6 +5,7 @@ import (
"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"
)
@@ -21,9 +22,40 @@ func (self *SAwsProviderFactory) ValidateChangeBandwidth(instanceId string, band
}
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 {
+16
View File
@@ -46,6 +46,22 @@ func (self *SAzureProviderFactory) ValidateCreateCloudaccountData(ctx context.Co
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
+22 -1
View File
@@ -40,12 +40,33 @@ func (self *SESXiProviderFactory) ValidateCreateCloudaccountData(ctx context.Con
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(host))
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 {
+32
View File
@@ -5,6 +5,7 @@ import (
"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"
)
@@ -18,9 +19,40 @@ func (self *SHuaweiProviderFactory) ValidateChangeBandwidth(instanceId string, b
}
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 {
+45
View File
@@ -2,11 +2,13 @@ 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"
)
@@ -24,9 +26,52 @@ func (self *SOpenStackProviderFactory) ValidateChangeBandwidth(instanceId string
}
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], ""
+27 -2
View File
@@ -3,6 +3,7 @@ package provider
import (
"context"
"fmt"
"strings"
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/cloudprovider"
@@ -39,11 +40,35 @@ func (self *SQcloudProviderFactory) ValidateCreateCloudaccountData(ctx context.C
if len(secretKey) == 0 {
return httperrors.NewMissingParameterError("secret_key")
}
data.Set("account", jsonutils.NewString(appID))
data.Set("secret", jsonutils.NewString(fmt.Sprintf("%s/%s", secretID, secretKey)))
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 {