fix(region): support cloudprovider bind project mapping

This commit is contained in:
Qu Xuan
2021-06-09 18:16:38 +08:00
parent 0b0ac0f151
commit 1bc8e38452
9 changed files with 293 additions and 275 deletions
+21 -234
View File
@@ -18,251 +18,38 @@ import (
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/cmd/climc/shell"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
"yunion.io/x/onecloud/pkg/mcclient/options/compute"
)
func init() {
cmd := shell.NewResourceCmd(&modules.Cloudproviders).WithKeyword("cloud-provider")
cmd.List(&compute.CloudproviderListOptions{})
cmd.Update(&compute.CloudproviderUpdateOptions{})
cmd.Show(&options.BaseIdOptions{})
cmd.Delete(&options.BaseIdOptions{})
cmd.Perform("change-project", &compute.CloudproviderChangeProjectOptions{})
cmd.Perform("enable", &options.BaseIdOptions{})
cmd.Perform("disable", &options.BaseIdOptions{})
cmd.Perform("sync", &compute.CloudproviderSyncOptions{})
cmd.Perform("project-mapping", &compute.ClouproviderProjectMappingOptions{})
type CloudproviderListOptions struct {
options.BaseListOptions
Usable bool `help:"Vpc & Network usable"`
HasObjectStorage bool `help:"filter cloudproviders that has object storage"`
NoObjectStorage bool `help:"filter cloudproviders that has no object storage"`
Capability []string `help:"capability filter" choices:"project|compute|network|loadbalancer|objectstore|rds|cache|event"`
Cloudregion string `help:"filter cloudproviders by cloudregion"`
HostSchedtagId string `help:"filter by host schedtag"`
}
R(&CloudproviderListOptions{}, "cloud-provider-list", "List cloud providers", func(s *mcclient.ClientSession, args *CloudproviderListOptions) error {
var params *jsonutils.JSONDict
{
var err error
params, err = args.BaseListOptions.Params()
if err != nil {
return err
}
if args.Usable {
params.Add(jsonutils.NewBool(true), "usable")
}
if args.HasObjectStorage {
params.Add(jsonutils.JSONTrue, "has_object_storage")
} else if args.NoObjectStorage {
params.Add(jsonutils.JSONFalse, "has_object_storage")
}
if len(args.Capability) > 0 {
params.Add(jsonutils.NewStringArray(args.Capability), "capability")
}
if len(args.Cloudregion) > 0 {
params.Add(jsonutils.NewString(args.Cloudregion), "cloudregion")
}
if len(args.HostSchedtagId) > 0 {
params.Add(jsonutils.NewString(args.HostSchedtagId), "host_schedtag_id")
}
}
result, err := modules.Cloudproviders.List(s, params)
if err != nil {
return err
}
printList(result, modules.Cloudproviders.GetColumns(s))
return nil
})
type CloudproviderUpdateOptions struct {
ID string `help:"ID or Name of cloud provider"`
Name string `help:"New name to update"`
AccessUrl string `help:"New access url"`
Desc string `help:"Description"`
}
R(&CloudproviderUpdateOptions{}, "cloud-provider-update", "Update a cloud provider", func(s *mcclient.ClientSession, args *CloudproviderUpdateOptions) error {
params := jsonutils.NewDict()
if len(args.Name) > 0 {
params.Add(jsonutils.NewString(args.Name), "name")
}
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")
}
if params.Size() == 0 {
return InvalidUpdateError()
}
result, err := modules.Cloudproviders.Update(s, args.ID, params)
if err != nil {
return err
}
printObject(result)
return nil
})
type CloudproviderChangeProjectOptions struct {
ID string `help:"ID or Name of cloud provider"`
TENANT string `help:"ID or Name of tenant"`
}
R(&CloudproviderChangeProjectOptions{}, "cloud-provider-change-project", "Change project for provider", func(s *mcclient.ClientSession, args *CloudproviderChangeProjectOptions) error {
result, err := modules.Cloudproviders.PerformAction(s, args.ID, "change-project", jsonutils.Marshal(map[string]string{"project": args.TENANT}))
if err != nil {
return err
}
printObject(result)
return nil
})
type CloudproviderShowOptions struct {
ID string `help:"ID or Name of cloud provider"`
}
R(&CloudproviderShowOptions{}, "cloud-provider-show", "Get details of a cloud provider", func(s *mcclient.ClientSession, args *CloudproviderShowOptions) error {
result, err := modules.Cloudproviders.Get(s, args.ID, nil)
if err != nil {
return err
}
printObject(result)
return nil
})
R(&CloudproviderShowOptions{}, "cloud-provider-delete", "Delete a cloud provider", func(s *mcclient.ClientSession, args *CloudproviderShowOptions) error {
result, err := modules.Cloudproviders.Delete(s, args.ID, nil)
if err != nil {
return err
}
printObject(result)
return nil
})
R(&CloudproviderShowOptions{}, "cloud-provider-enable", "Enable cloud provider", func(s *mcclient.ClientSession, args *CloudproviderShowOptions) error {
result, err := modules.Cloudproviders.PerformAction(s, args.ID, "enable", nil)
if err != nil {
return err
}
printObject(result)
return nil
})
R(&CloudproviderShowOptions{}, "cloud-provider-disable", "Disable cloud provider", func(s *mcclient.ClientSession, args *CloudproviderShowOptions) error {
result, err := modules.Cloudproviders.PerformAction(s, args.ID, "disable", nil)
if err != nil {
return err
}
printObject(result)
return nil
})
R(&CloudproviderShowOptions{}, "cloud-provider-balance", "Get balance", func(s *mcclient.ClientSession, args *CloudproviderShowOptions) error {
result, err := modules.Cloudproviders.GetSpecific(s, args.ID, "balance", nil)
if err != nil {
return err
}
printObject(result)
return nil
})
type CloudproviderUpdateCredentialOptions struct {
ID string `help:"ID or Name of cloud provider"`
ACCOUNT string `help:"new account"`
SECRET string `help:"new secret"`
}
R(&CloudproviderUpdateCredentialOptions{}, "cloud-provider-update-credential", "Update credential of a cloud provider", func(s *mcclient.ClientSession, args *CloudproviderUpdateCredentialOptions) error {
params := jsonutils.NewDict()
params.Add(jsonutils.NewString(args.ACCOUNT), "account")
params.Add(jsonutils.NewString(args.SECRET), "secret")
result, err := modules.Cloudproviders.PerformAction(s, args.ID, "update-credential", params)
if err != nil {
return err
}
printObject(result)
return nil
})
type CloudproviderSyncOptions struct {
ID string `help:"ID or Name of cloud provider"`
Force bool `help:"Force sync no matter what"`
FullSync bool `help:"Synchronize everything"`
ProjectSync bool `help:"Auto sync project info"`
Region []string `help:"region to sync"`
Zone []string `help:"region to sync"`
Host []string `help:"region to sync"`
}
R(&CloudproviderSyncOptions{}, "cloud-provider-sync", "Sync of a cloud provider account", func(s *mcclient.ClientSession, args *CloudproviderSyncOptions) error {
params := jsonutils.NewDict()
if args.Force {
params.Add(jsonutils.JSONTrue, "force")
}
if args.FullSync {
params.Add(jsonutils.JSONTrue, "full_sync")
}
if args.ProjectSync {
params.Add(jsonutils.JSONTrue, "project_sync")
}
if len(args.Region) > 0 {
params.Add(jsonutils.NewStringArray(args.Region), "region")
}
if len(args.Zone) > 0 {
params.Add(jsonutils.NewStringArray(args.Zone), "zone")
}
if len(args.Host) > 0 {
params.Add(jsonutils.NewStringArray(args.Host), "host")
}
result, err := modules.Cloudproviders.PerformAction(s, args.ID, "sync", params)
if err != nil {
return err
}
printObject(result)
return nil
})
type CloudproviderClientRCOptions struct {
ID string `help:"ID or name of cloud provider"`
}
R(&CloudproviderClientRCOptions{}, "cloud-provider-clirc", "Get client RC file of the cloud provider", func(s *mcclient.ClientSession, args *CloudproviderClientRCOptions) error {
result, err := modules.Cloudproviders.GetSpecific(s, args.ID, "clirc", nil)
if err != nil {
return err
}
cmd.GetWithCustomShow("clirc", func(result jsonutils.JSONObject) {
rc := make(map[string]string)
err = result.Unmarshal(&rc)
err := result.Unmarshal(&rc)
if err != nil {
return err
log.Errorf("error: %v", err)
return
}
for k, v := range rc {
fmt.Printf(`export %s="%s"`+"\n", k, v)
}
return nil
})
type CloudproviderStorageClassesOptions struct {
ID string `help:"ID or Name of cloud provider" json:"-"`
Cloudregion string `help:"cloud region name or Id"`
}
R(&CloudproviderStorageClassesOptions{}, "cloud-provider-storage-classes", "Get list of supported storage classes of a cloud provider", func(s *mcclient.ClientSession, args *CloudproviderStorageClassesOptions) error {
params, err := options.StructToParams(args)
if err != nil {
return err
}
result, err := modules.Cloudproviders.GetSpecific(s, args.ID, "storage-classes", params)
if err != nil {
return err
}
printObject(result)
return nil
})
R(&CloudproviderShowOptions{}, "cloud-provider-change-owner-candidate-domains", "Show candiate domains of a cloud provider changing owner", func(s *mcclient.ClientSession, args *CloudproviderShowOptions) error {
result, err := modules.Cloudproviders.GetSpecific(s, args.ID, "change-owner-candidate-domains", nil)
if err != nil {
return err
}
printObject(result)
return nil
})
}, &options.BaseIdOptions{})
cmd.Get("storage-classes", &compute.CloudproviderStorageClassesOptions{})
cmd.Get("change-owner-candidate-domains", &options.BaseIdOptions{})
cmd.Get("balance", &options.BaseIdOptions{})
}
+6 -2
View File
@@ -421,7 +421,7 @@ type IGetOpt interface {
IOpt
}
func (cmd ResourceCmd) Get(specific string, args IGetOpt) {
func (cmd ResourceCmd) GetWithCustomShow(specific string, show func(data jsonutils.JSONObject), args IGetOpt) {
man := cmd.manager
callback := func(s *mcclient.ClientSession, args IGetOpt) error {
params, err := args.Params()
@@ -432,12 +432,16 @@ func (cmd ResourceCmd) Get(specific string, args IGetOpt) {
if err != nil {
return err
}
printObject(ret)
show(ret)
return nil
}
cmd.RunWithDesc(specific, fmt.Sprintf("Get %s of a %s", specific, man.GetKeyword()), args, callback)
}
func (cmd ResourceCmd) Get(specific string, args IGetOpt) {
cmd.GetWithCustomShow(specific, printObject, args)
}
type IUpdateOpt interface {
IOpt
IIdOpt
+2
View File
@@ -137,6 +137,8 @@ type CloudproviderDetails struct {
// 子订阅品牌信息
Brand string `json:"brand"`
ProjectMappingResourceInfo
}
// 云订阅输入参数
+1 -1
View File
@@ -2885,5 +2885,5 @@ func (self *SCloudaccount) PerformProjectMapping(ctx context.Context, userCred m
if err != nil {
return nil, err
}
return nil, refreshMapping()
return nil, refreshPmCaches()
}
+89 -28
View File
@@ -37,6 +37,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/proxy"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/options"
"yunion.io/x/onecloud/pkg/httperrors"
@@ -52,6 +53,7 @@ type SCloudproviderManager struct {
db.SEnabledStatusStandaloneResourceBaseManager
db.SProjectizedResourceBaseManager
SProjectMappingResourceBaseManager
SSyncableBaseResourceManager
}
@@ -108,49 +110,61 @@ type SCloudprovider struct {
// 云账号的平台信息
Provider string `width:"64" charset:"ascii" list:"domain" create:"domain_required"`
SProjectMappingResourceBase
}
type providerMapping struct {
Id string
CloudaccountId string
ProjectMappingId string
type pmCache struct {
Id string
CloudaccountId string
AccountProjectMappingId string
ManagerProjectMappingId string
}
var providerProjectMapping map[string]*providerMapping = map[string]*providerMapping{}
func (self *pmCache) GetProjectMapping() (*SProjectMapping, error) {
if len(self.ManagerProjectMappingId) > 0 {
return GetRuleMapping(self.ManagerProjectMappingId)
}
if len(self.AccountProjectMappingId) > 0 {
return GetRuleMapping(self.AccountProjectMappingId)
}
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "empty project mapping id")
}
func refreshMapping() error {
q := CloudproviderManager.Query("cloudaccount_id", "id")
var pmCaches map[string]*pmCache = map[string]*pmCache{}
func refreshPmCaches() error {
q := CloudproviderManager.Query().SubQuery()
providers := q.Query(q.Field("cloudaccount_id"), q.Field("id"), q.Field("project_mapping_id").Label("manager_project_mapping_id"))
sq := CloudaccountManager.Query().SubQuery()
q = q.LeftJoin(sq, sqlchemy.Equals(q.Field("cloudaccount_id"), sq.Field("id"))).AppendField(sq.Field("project_mapping_id"))
pms := []providerMapping{}
err := q.All(&pms)
mq := providers.LeftJoin(sq, sqlchemy.Equals(q.Field("cloudaccount_id"), sq.Field("id"))).AppendField(sq.Field("project_mapping_id").Label("account_project_mapping_id"))
caches := []pmCache{}
err := mq.All(&caches)
if err != nil {
return errors.Wrapf(err, "q.All")
}
for i := range pms {
providerProjectMapping[pms[i].Id] = &pms[i]
for i := range caches {
pmCaches[caches[i].Id] = &caches[i]
}
return nil
}
func (self *providerMapping) GetCloudaccount() (*SCloudaccount, error) {
account, err := CloudaccountManager.FetchById(self.CloudaccountId)
func (self *SCloudprovider) GetProjectMapping() (*SProjectMapping, error) {
cache, err := func() (*pmCache, error) {
mp, ok := pmCaches[self.Id]
if ok {
return mp, nil
}
err := refreshPmCaches()
if err != nil {
return nil, errors.Wrapf(err, "refreshPmCaches")
}
return pmCaches[self.Id], nil
}()
if err != nil {
return nil, errors.Wrapf(err, "FetchById(%s)", self.CloudaccountId)
return nil, errors.Wrapf(err, "get project mapping cache")
}
return account.(*SCloudaccount), nil
}
func GetProviderMapping(id string) (*providerMapping, error) {
mp, ok := providerProjectMapping[id]
if ok {
return mp, nil
}
err := refreshMapping()
if err != nil {
return nil, err
}
return providerProjectMapping[id], nil
return cache.GetProjectMapping()
}
func (self *SCloudprovider) ValidateDeleteCondition(ctx context.Context) error {
@@ -976,6 +990,7 @@ func (manager *SCloudproviderManager) FetchCustomizeColumns(
stdRows := manager.SEnabledStatusStandaloneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
projRows := manager.SProjectizedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
pmRows := manager.SProjectMappingResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
accountIds := make([]string, len(objs))
for i := range rows {
provider := objs[i].(*SCloudprovider)
@@ -985,6 +1000,7 @@ func (manager *SCloudproviderManager) FetchCustomizeColumns(
ProjectizedResourceInfo: projRows[i],
SCloudproviderUsage: provider.getUsage(),
SyncStatus2: provider.getSyncStatus2(),
ProjectMappingResourceInfo: pmRows[i],
}
capabilities, _ := CloudproviderCapabilityManager.getCapabilities(provider.Id)
if len(capabilities) > 0 {
@@ -1885,3 +1901,48 @@ func (self *SCloudprovider) SyncCallSyncCloudproviderInterVpcNetwork(ctx context
}
}
}
func (manager *SCloudproviderManager) ListItemExportKeys(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, keys stringutils2.SSortedStrings) (*sqlchemy.SQuery, error) {
q, err := manager.SEnabledStatusStandaloneResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SEnabledStatusStandaloneResourceBaseManager.ListItemExportKeys")
}
q, err = manager.SProjectizedResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrapf(err, "SProjectizedResourceBaseManager.ListItemExportKeys")
}
q, err = manager.SProjectMappingResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrapf(err, "SProjectMappingResourceBaseManager.ListItemExportKeys")
}
return q, nil
}
func (self *SCloudprovider) AllowPerformProjectMapping(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
return db.IsAdminAllowPerform(userCred, self, "project-mapping")
}
// 绑定同步策略
func (self *SCloudprovider) PerformProjectMapping(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.CloudaccountProjectMappingInput) (jsonutils.JSONObject, error) {
if len(input.ProjectMappingId) > 0 {
_, err := validators.ValidateModel(userCred, ProjectMappingManager, &input.ProjectMappingId)
if err != nil {
return nil, err
}
if len(self.ProjectMappingId) > 0 && self.ProjectMappingId != input.ProjectMappingId {
return nil, httperrors.NewInputParameterError("cloudprovider %s has aleady bind project mapping %s", self.Name, self.ProjectMappingId)
}
}
// no changes
if self.ProjectMappingId == input.ProjectMappingId {
return nil, nil
}
_, err := db.Update(self, func() error {
self.ProjectMappingId = input.ProjectMappingId
return nil
})
if err != nil {
return nil, err
}
return nil, refreshPmCaches()
}
+11 -10
View File
@@ -1400,20 +1400,21 @@ func (manager *SCloudproviderregionManager) initAllRecords() {
func SyncCloudProject(userCred mcclient.TokenCredential, model db.IVirtualModel, syncOwnerId mcclient.IIdentityProvider, extModel cloudprovider.IVirtualResource, managerId string) {
newOwnerId, err := func() (mcclient.IIdentityProvider, error) {
pm, err := GetProviderMapping(managerId)
_manager, err := CloudproviderManager.FetchById(managerId)
if err != nil {
return nil, errors.Wrapf(err, "GetProviderMapping")
return nil, errors.Wrapf(err, "CloudproviderManager.FetchById(%s)", managerId)
}
if len(pm.ProjectMappingId) == 0 {
return nil, nil
}
account, err := pm.GetCloudaccount()
manager := _manager.(*SCloudprovider)
rm, err := manager.GetProjectMapping()
if err != nil {
return nil, errors.Wrapf(err, "GetCloudaccount")
if errors.Cause(err) == cloudprovider.ErrNotFound {
return nil, nil
}
return nil, errors.Wrapf(err, "GetProjectMapping")
}
rm, err := GetRuleMapping(pm.ProjectMappingId)
if err != nil {
return nil, errors.Wrapf(err, "GetRuleMapping")
account := manager.GetCloudaccount()
if account == nil {
return nil, fmt.Errorf("can not find manager %s account", manager.Name)
}
if rm != nil && rm.Enabled.Bool() {
extTags, err := extModel.GetTags()
+17
View File
@@ -236,6 +236,16 @@ func (self *SProjectMapping) GetCloudaccounts() ([]SCloudaccount, error) {
return accounts, nil
}
func (self *SProjectMapping) GetCloudproviders() ([]SCloudprovider, error) {
q := CloudproviderManager.Query().Equals("project_mapping_id", self.Id)
ret := []SCloudprovider{}
err := db.FetchModelObjects(CloudproviderManager, q, &ret)
if err != nil {
return nil, err
}
return ret, nil
}
func (self *SProjectMapping) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
delete(projectRuleMapping, self.Id)
return self.SEnabledStatusInfrasResourceBase.Delete(ctx, userCred)
@@ -249,6 +259,13 @@ func (self *SProjectMapping) ValidateDeleteCondition(ctx context.Context) error
if len(accounts) > 0 {
return httperrors.NewNotEmptyError("project mapping has associate %d accounts", len(accounts))
}
providers, err := self.GetCloudproviders()
if err != nil {
return errors.Wrapf(err, "GetCloudproviders")
}
if len(providers) > 0 {
return httperrors.NewNotEmptyError("project mapping has associate %d cloudproviders", len(providers))
}
return self.SEnabledStatusInfrasResourceBase.ValidateDeleteCondition(ctx)
}
+1
View File
@@ -57,6 +57,7 @@ var (
"natdentries",
"policy_assignments",
"proxysettings",
"project_mappings",
}
computeUserResources = []string{
"keypairs",
@@ -0,0 +1,145 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
type CloudproviderListOptions struct {
options.BaseListOptions
Usable bool `help:"Vpc & Network usable"`
HasObjectStorage bool `help:"filter cloudproviders that has object storage"`
NoObjectStorage bool `help:"filter cloudproviders that has no object storage"`
Capability []string `help:"capability filter" choices:"project|compute|network|loadbalancer|objectstore|rds|cache|event"`
Cloudregion string `help:"filter cloudproviders by cloudregion"`
HostSchedtagId string `help:"filter by host schedtag"`
}
func (opts *CloudproviderListOptions) Params() (jsonutils.JSONObject, error) {
params, err := opts.BaseListOptions.Params()
if err != nil {
return nil, err
}
if opts.Usable {
params.Add(jsonutils.NewBool(true), "usable")
}
if opts.HasObjectStorage {
params.Add(jsonutils.JSONTrue, "has_object_storage")
} else if opts.NoObjectStorage {
params.Add(jsonutils.JSONFalse, "has_object_storage")
}
if len(opts.Capability) > 0 {
params.Add(jsonutils.NewStringArray(opts.Capability), "capability")
}
if len(opts.Cloudregion) > 0 {
params.Add(jsonutils.NewString(opts.Cloudregion), "cloudregion")
}
if len(opts.HostSchedtagId) > 0 {
params.Add(jsonutils.NewString(opts.HostSchedtagId), "host_schedtag_id")
}
return params, nil
}
type CloudproviderUpdateOptions struct {
options.BaseIdOptions
Name string `help:"New name to update"`
AccessUrl string `help:"New access url"`
Desc string `help:"Description"`
}
func (opts *CloudproviderUpdateOptions) Params() (jsonutils.JSONObject, error) {
params := jsonutils.NewDict()
if len(opts.Name) > 0 {
params.Add(jsonutils.NewString(opts.Name), "name")
}
if len(opts.AccessUrl) > 0 {
params.Add(jsonutils.NewString(opts.AccessUrl), "access_url")
}
if len(opts.Desc) > 0 {
params.Add(jsonutils.NewString(opts.Desc), "description")
}
return params, nil
}
type CloudproviderChangeProjectOptions struct {
options.BaseIdOptions
TENANT string `help:"ID or Name of tenant"`
}
func (opts *CloudproviderChangeProjectOptions) Params() (jsonutils.JSONObject, error) {
return jsonutils.Marshal(map[string]string{"project": opts.TENANT}), nil
}
type CloudproviderSyncOptions struct {
options.BaseIdOptions
Force bool `help:"Force sync no matter what"`
FullSync bool `help:"Synchronize everything"`
ProjectSync bool `help:"Auto sync project info"`
Region []string `help:"region to sync"`
Zone []string `help:"region to sync"`
Host []string `help:"region to sync"`
}
func (opts *CloudproviderSyncOptions) Params() (jsonutils.JSONObject, error) {
params := jsonutils.NewDict()
if opts.Force {
params.Add(jsonutils.JSONTrue, "force")
}
if opts.FullSync {
params.Add(jsonutils.JSONTrue, "full_sync")
}
if opts.ProjectSync {
params.Add(jsonutils.JSONTrue, "project_sync")
}
if len(opts.Region) > 0 {
params.Add(jsonutils.NewStringArray(opts.Region), "region")
}
if len(opts.Zone) > 0 {
params.Add(jsonutils.NewStringArray(opts.Zone), "zone")
}
if len(opts.Host) > 0 {
params.Add(jsonutils.NewStringArray(opts.Host), "host")
}
return params, nil
}
type CloudproviderStorageClassesOptions struct {
options.BaseIdOptions
Cloudregion string `help:"cloud region name or Id"`
}
func (opts *CloudproviderStorageClassesOptions) Params() (jsonutils.JSONObject, error) {
return options.StructToParams(opts)
}
type ClouproviderProjectMappingOptions struct {
options.BaseIdOptions
ProjectMappingId string `json:"project_mapping_id" help:"project mapping id"`
}
func (opts *ClouproviderProjectMappingOptions) Params() (jsonutils.JSONObject, error) {
return jsonutils.Marshal(map[string]string{"project_mapping_id": opts.ProjectMappingId}), nil
}