Merge pull request #12664 from tb365/feature/tb-support-ctyun-crm-account

ctyun support crm account
This commit is contained in:
Zexi Li
2021-11-16 10:16:04 +08:00
committed by GitHub
12 changed files with 107 additions and 22 deletions
+3 -1
View File
@@ -31,6 +31,8 @@ import (
)
type BaseOptions struct {
cloudprovider.SCtyunExtraOptions
Help bool `help:"Show help" default:"false"`
Debug bool `help:"Show debug" default:"false"`
AccessKey string `help:"Access key" default:"$CTYUN_ACCESS_KEY"`
@@ -101,7 +103,7 @@ func newClient(options *BaseOptions) (*ctyun.SRegion, error) {
cli, err := ctyun.NewSCtyunClient(
ctyun.NewSCtyunClientConfig(
options.AccessKey, options.Secret,
options.AccessKey, options.Secret, &options.SCtyunExtraOptions,
).Debug(options.Debug).
CloudproviderConfig(
cloudprovider.ProviderConfig{
+6 -1
View File
@@ -99,6 +99,9 @@ type SCloudaccountCredential struct {
// Huawei Cloud Stack Online
*SHCSOEndpoints
// ctyun crm account extra info
*SCtyunExtraOptions
}
type SCloudaccount struct {
@@ -176,6 +179,7 @@ type SProviderInfo struct {
Url string
Account string
Secret string
Options *jsonutils.JSONDict
}
type ICloudProviderFactory interface {
@@ -400,7 +404,7 @@ func GetProvider(cfg ProviderConfig) (ICloudProvider, error) {
return driver.GetProvider(cfg)
}
func GetClientRC(name, accessUrl, account, secret, provider string) (map[string]string, error) {
func GetClientRC(name, accessUrl, account, secret, provider string, options *jsonutils.JSONDict) (map[string]string, error) {
driver, err := GetProviderFactory(provider)
if err != nil {
return nil, errors.Wrap(err, "GetProviderFactory")
@@ -410,6 +414,7 @@ func GetClientRC(name, accessUrl, account, secret, provider string) (map[string]
Url: accessUrl,
Account: account,
Secret: secret,
Options: options,
}
return driver.GetClientRC(info)
}
+1 -1
View File
@@ -47,7 +47,7 @@ type SHCSOEndpoints struct {
// 华为私有云Endpoint域名
// example: hcso.com.cn
// required:true
EndpointDomain string `default:"$HUAWEI_ENDPOINT_DOMAIN" metavar:"HUAWEI_ENDPOINT_DOMAIN"`
EndpointDomain string `default:"$HUAWEI_ENDPOINT_DOMAIN" metavar:"$HUAWEI_ENDPOINT_DOMAIN"`
// 可用区ID
// example: cn-north-2
+7
View File
@@ -17,3 +17,10 @@ package cloudprovider
type SAWSExtraOptions struct {
AWSAssumeRoleName string `json:"aws_assume_role_name"`
}
type SCtyunExtraOptions struct {
// customInfo type=1
CrmBizId string `help:"ctyun crm user biz id. eg. ACMB1000000000123456 " json:"crm_biz_id" default:"$CTYUN_CRM_BIZ_ID"`
// customInfo type=2
// OptionsAccountId string `help:"ctyun account id." json:"options_account_id"`
}
+4
View File
@@ -448,6 +448,10 @@ func (manager *SCloudaccountManager) validateCreateData(
endpointOptions = jsonutils.Marshal(input.SCloudaccountCredential.SHCSOEndpoints)
}
if input.SCloudaccountCredential.SCtyunExtraOptions != nil {
endpointOptions = jsonutils.Marshal(input.SCloudaccountCredential.SCtyunExtraOptions)
}
if endpointOptions != nil {
if input.Options == nil {
input.Options = jsonutils.NewDict()
+8 -1
View File
@@ -1675,7 +1675,14 @@ func (provider *SCloudprovider) GetDetailsClirc(ctx context.Context, userCred mc
if err != nil {
return nil, err
}
rc, err := cloudprovider.GetClientRC(provider.Name, accessUrl, provider.Account, passwd, provider.Provider)
account := provider.GetCloudaccount()
var options *jsonutils.JSONDict
if account != nil {
options = account.Options
}
rc, err := cloudprovider.GetClientRC(provider.Name, accessUrl, provider.Account, passwd, provider.Provider, options)
if err != nil {
return nil, err
}
+14 -1
View File
@@ -348,6 +348,8 @@ func (opts *SXskyCloudAccountCreateOptions) Params() (jsonutils.JSONObject, erro
type SCtyunCloudAccountCreateOptions struct {
SCloudAccountCreateBaseOptions
SAccessKeyCredentialWithEnvironment
cloudprovider.SCtyunExtraOptions
}
func (opts *SCtyunCloudAccountCreateOptions) Params() (jsonutils.JSONObject, error) {
@@ -848,10 +850,21 @@ func (opts *SS3CloudAccountUpdateOptions) Params() (jsonutils.JSONObject, error)
type SCtyunCloudAccountUpdateOptions struct {
SCloudAccountUpdateBaseOptions
cloudprovider.SCtyunExtraOptions
}
func (opts *SCtyunCloudAccountUpdateOptions) Params() (jsonutils.JSONObject, error) {
return jsonutils.Marshal(opts), nil
params := jsonutils.Marshal(opts).(*jsonutils.JSONDict)
options := jsonutils.NewDict()
if len(opts.SCtyunExtraOptions.CrmBizId) > 0 {
options.Add(jsonutils.NewString(opts.SCtyunExtraOptions.CrmBizId), "crm_biz_id")
}
if options.Size() > 0 {
params.Add(options, "options")
}
return params, nil
}
type SJDcloudCloudAccountUpdateOptions struct {
+35 -2
View File
@@ -46,7 +46,8 @@ const (
)
type CtyunClientConfig struct {
cpcfg cloudprovider.ProviderConfig
cpcfg cloudprovider.ProviderConfig
options *cloudprovider.SCtyunExtraOptions
projectId string
accessKey string
@@ -55,10 +56,11 @@ type CtyunClientConfig struct {
debug bool
}
func NewSCtyunClientConfig(accessKey, accessSecret string) *CtyunClientConfig {
func NewSCtyunClientConfig(accessKey, accessSecret string, options *cloudprovider.SCtyunExtraOptions) *CtyunClientConfig {
cfg := &CtyunClientConfig{
accessKey: accessKey,
accessSecret: accessSecret,
options: options,
}
return cfg
}
@@ -165,6 +167,32 @@ func (client *SCtyunClient) DoPost(apiName string, params map[string]jsonutils.J
return formRequest(client, httputils.POST, apiName, nil, params)
}
func getCustiomInfo(t string, crmBizId string, accountId string) jsonutils.JSONObject {
if len(t) == 0 {
return nil
}
customeInfo := jsonutils.NewDict()
//customeInfo.Set("name", jsonutils.NewString(""))
//customeInfo.Set("email", jsonutils.NewString(""))
//customeInfo.Set("phone", jsonutils.NewString(""))
indentity := jsonutils.NewDict()
if len(crmBizId) > 0 {
indentity.Set("crmBizId", jsonutils.NewString(crmBizId))
}
if len(accountId) > 0 {
indentity.Set("accountId", jsonutils.NewString(accountId))
}
if len(t) > 0 {
customeInfo.Set("type", jsonutils.NewString(t))
customeInfo.Set("identity", indentity)
}
return customeInfo
}
func formRequest(client *SCtyunClient, method httputils.THttpMethod, apiName string, queries map[string]string, params map[string]jsonutils.JSONObject) (jsonutils.JSONObject, error) {
header := http.Header{}
// signer
@@ -199,6 +227,11 @@ func formRequest(client *SCtyunClient, method httputils.THttpMethod, apiName str
header.Set("hmac", hsum)
// 平台类型,整数类型,取值范围:2或3,传2表示2.0自营资源,传3表示3.0合营资源,该参数不需要加密。
header.Set("platform", "3")
// crm账号需要设置customInfo。目前发现只有VPC列表查询需要用到这个参数,其他的接口还没有发现此要求。为了简便对于crm 统一设置此项
if client.options != nil && len(client.options.CrmBizId) > 0 {
customInfo := getCustiomInfo("1", client.options.CrmBizId, "")
header.Set("customInfo", customInfo.String())
}
}
var reqbody string
+1 -1
View File
@@ -45,7 +45,7 @@ func (self *SProject) GetHealthStatus() string {
func (self *SCtyunClient) FetchProjects() ([]SProject, error) {
client, err := NewSCtyunClient(
NewSCtyunClientConfig(
self.accessKey, self.accessSecret,
self.accessKey, self.accessSecret, self.options,
).Debug(self.debug),
)
if err != nil {
+25 -3
View File
@@ -19,6 +19,7 @@ import (
"strings"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
@@ -85,9 +86,17 @@ func (self *SCtyunProviderFactory) GetProvider(cfg cloudprovider.ProviderConfig)
account = segs[0]
}
options := cloudprovider.SCtyunExtraOptions{}
if cfg.Options != nil {
err := cfg.Options.Unmarshal(&options)
if err != nil {
log.Debugf("cfg.Options.Unmarshal %s", err)
}
}
client, err := ctyun.NewSCtyunClient(
ctyun.NewSCtyunClientConfig(
account, cfg.Secret,
account, cfg.Secret, &options,
).ProjectId(projectId).CloudproviderConfig(cfg),
)
if err != nil {
@@ -100,12 +109,25 @@ func (self *SCtyunProviderFactory) GetProvider(cfg cloudprovider.ProviderConfig)
}
func (self *SCtyunProviderFactory) GetClientRC(info cloudprovider.SProviderInfo) (map[string]string, error) {
return map[string]string{
ret := map[string]string{
"CTYUN_ACCESS_URL": info.Url,
"CTYUN_ACCESS_KEY": info.Account,
"CTYUN_SECRET": info.Secret,
"CTYUN_REGION": ctyun.CTYUN_DEFAULT_REGION,
}, nil
}
options := cloudprovider.SCtyunExtraOptions{}
if info.Options != nil {
err := info.Options.Unmarshal(&options)
if err != nil {
log.Debugf("info.Options.Unmarshal %s", err)
}
}
if len(options.CrmBizId) > 0 {
ret["CTYUN_CRM_BIZ_ID"] = options.CrmBizId
}
return ret, nil
}
func init() {
+2 -7
View File
@@ -48,7 +48,7 @@ type SRegion struct {
}
func (self *SRegion) fetchIVpcs() error {
vpcs, err := self.GetVpcs("", "", "")
vpcs, err := self.GetVpcs()
if err != nil {
return errors.Wrap(err, "SRegion.fetchIVpcs")
}
@@ -83,17 +83,12 @@ func (self *SRegion) fetchInfrastructure() error {
return nil
}
func (self *SRegion) GetVpcs(t string, crmBizId string, accountId string) ([]SVpc, error) {
func (self *SRegion) GetVpcs() ([]SVpc, error) {
vpcs := make([]SVpc, 0)
params := map[string]string{
"regionId": self.GetId(),
}
customInfo := self.getCustiomInfo(t, crmBizId, accountId)
if customInfo != nil {
params["customInfo"] = customInfo.String()
}
resp, err := self.client.DoGet("/apiproxy/v3/getVpcs", params)
if err != nil {
return nil, err
+1 -4
View File
@@ -21,12 +21,9 @@ import (
func init() {
type VpcListOptions struct {
Type string `json:"type"`
CrmBizId string `json:"crm_biz_id"`
AccountId string `json:"account_id"`
}
shellutils.R(&VpcListOptions{}, "vpc-list", "List vpcs", func(cli *ctyun.SRegion, args *VpcListOptions) error {
vpcs, e := cli.GetVpcs(args.Type, args.CrmBizId, args.AccountId)
vpcs, e := cli.GetVpcs()
if e != nil {
return e
}