diff --git a/cmd/climc/shell/compute/cloudaccounts.go b/cmd/climc/shell/compute/cloudaccounts.go index 4daae0c20b..ae72a354e9 100644 --- a/cmd/climc/shell/compute/cloudaccounts.go +++ b/cmd/climc/shell/compute/cloudaccounts.go @@ -1037,4 +1037,12 @@ func init() { return nil }) + R(&CloudaccountShowOptions{}, "cloud-account-change-owner-candidate-domains", "Show candiate domains of a cloud account changing project", func(s *mcclient.ClientSession, args *CloudaccountShowOptions) error { + result, err := modules.Cloudaccounts.GetSpecific(s, args.ID, "change-owner-candidate-domains", nil) + if err != nil { + return err + } + printObject(result) + return nil + }) } diff --git a/cmd/climc/shell/compute/cloudproviders.go b/cmd/climc/shell/compute/cloudproviders.go index 72413e1633..5c0e61ebd0 100644 --- a/cmd/climc/shell/compute/cloudproviders.go +++ b/cmd/climc/shell/compute/cloudproviders.go @@ -245,4 +245,13 @@ func init() { 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 + }) } diff --git a/cmd/climc/shell/compute/globalvpcs.go b/cmd/climc/shell/compute/globalvpcs.go index fbef67661a..7a5404a9d7 100644 --- a/cmd/climc/shell/compute/globalvpcs.go +++ b/cmd/climc/shell/compute/globalvpcs.go @@ -15,6 +15,8 @@ package compute import ( + "yunion.io/x/jsonutils" + "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/mcclient/modules" "yunion.io/x/onecloud/pkg/mcclient/options" @@ -48,4 +50,32 @@ func init() { printObject(result) return nil }) + + type GlobalVpcPublicOptions struct { + ID string `help:"ID or name of global vpc" json:"-"` + Scope string `help:"sharing scope" choices:"system|domain"` + SharedDomains []string `help:"share to domains"` + } + R(&GlobalVpcPublicOptions{}, "global-vpc-public", "Make global vpc public", func(s *mcclient.ClientSession, args *GlobalVpcPublicOptions) error { + params := jsonutils.Marshal(args) + result, err := modules.GlobalVpcs.PerformAction(s, args.ID, "public", params) + if err != nil { + return err + } + printObject(result) + return nil + }) + + type GlobalVpcPrivateOptions struct { + ID string `help:"ID or name of global vpc" json:"-"` + } + R(&GlobalVpcPrivateOptions{}, "global-vpc-private", "Make global vpc private", func(s *mcclient.ClientSession, args *GlobalVpcPrivateOptions) error { + params := jsonutils.Marshal(args) + result, err := modules.GlobalVpcs.PerformAction(s, args.ID, "private", params) + if err != nil { + return err + } + printObject(result) + return nil + }) } diff --git a/cmd/climc/shell/compute/storages.go b/cmd/climc/shell/compute/storages.go index 636f4a0769..203ad24b23 100644 --- a/cmd/climc/shell/compute/storages.go +++ b/cmd/climc/shell/compute/storages.go @@ -215,4 +215,49 @@ func init() { printObject(storage) return nil }) + + type StorageChangeOwnerOptions struct { + ID string `help:"ID or name of storage" json:"-"` + ProjectDomain string `json:"project_domain" help:"target domain"` + } + R(&StorageChangeOwnerOptions{}, "storage-change-owner", "Change owner domain of storage", func(s *mcclient.ClientSession, args *StorageChangeOwnerOptions) error { + if len(args.ProjectDomain) == 0 { + return fmt.Errorf("empty project_domain") + } + params := jsonutils.Marshal(args) + ret, err := modules.Storages.PerformAction(s, args.ID, "change-owner", params) + if err != nil { + return err + } + printObject(ret) + return nil + }) + + type StoragePublicOptions struct { + ID string `help:"ID or name of storage" json:"-"` + Scope string `help:"sharing scope" choices:"system|domain"` + SharedDomains []string `help:"share to domains"` + } + R(&StoragePublicOptions{}, "storage-public", "Make a storage public", func(s *mcclient.ClientSession, args *StoragePublicOptions) error { + params := jsonutils.Marshal(args) + result, err := modules.Storages.PerformAction(s, args.ID, "public", params) + if err != nil { + return err + } + printObject(result) + return nil + }) + + type StoragePrivateOptions struct { + ID string `help:"ID or name of storage" json:"-"` + } + R(&StoragePrivateOptions{}, "storage-private", "Make a storage private", func(s *mcclient.ClientSession, args *StoragePrivateOptions) error { + params := jsonutils.Marshal(args) + result, err := modules.Storages.PerformAction(s, args.ID, "private", params) + if err != nil { + return err + } + printObject(result) + return nil + }) } diff --git a/cmd/climc/shell/compute/vpcs.go b/cmd/climc/shell/compute/vpcs.go index ec067eeee7..88ae862539 100644 --- a/cmd/climc/shell/compute/vpcs.go +++ b/cmd/climc/shell/compute/vpcs.go @@ -15,6 +15,8 @@ package compute import ( + "fmt" + "yunion.io/x/jsonutils" "yunion.io/x/onecloud/pkg/mcclient" @@ -218,4 +220,21 @@ func init() { printObject(result) return nil }) + + type VpcChangeOwnerOptions struct { + ID string `help:"ID or name of vpc" json:"-"` + ProjectDomain string `json:"project_domain" help:"target domain"` + } + R(&VpcChangeOwnerOptions{}, "vpc-change-owner", "Change owner domain of vpc", func(s *mcclient.ClientSession, args *VpcChangeOwnerOptions) error { + if len(args.ProjectDomain) == 0 { + return fmt.Errorf("empty project_domain") + } + params := jsonutils.Marshal(args) + ret, err := modules.Vpcs.PerformAction(s, args.ID, "change-owner", params) + if err != nil { + return err + } + printObject(ret) + return nil + }) } diff --git a/pkg/cloudcommon/db/domainresource.go b/pkg/cloudcommon/db/domainresource.go index 6ec13e48c0..8826c6a3ee 100644 --- a/pkg/cloudcommon/db/domainresource.go +++ b/pkg/cloudcommon/db/domainresource.go @@ -133,6 +133,10 @@ func (model *SDomainLevelResourceBase) AllowPerformChangeOwner(ctx context.Conte } func (model *SDomainLevelResourceBase) PerformChangeOwner(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input apis.PerformChangeDomainOwnerInput) (jsonutils.JSONObject, error) { + if model.GetIStandaloneModel().IsShared() { + return nil, errors.Wrap(httperrors.ErrForbidden, "cannot change owner of shared resource") + } + manager := model.GetModelManager() data := jsonutils.Marshal(input) diff --git a/pkg/cloudcommon/db/infraresource.go b/pkg/cloudcommon/db/infraresource.go index 56744b1589..84d3a4b1c1 100644 --- a/pkg/cloudcommon/db/infraresource.go +++ b/pkg/cloudcommon/db/infraresource.go @@ -270,9 +270,9 @@ func (model *SInfrasResourceBase) GetRequiredSharedDomainIds() []string { return []string{model.DomainId} } -func (model *SInfrasResourceBase) ValidateDeleteCondition(ctx context.Context) error { +/*func (model *SInfrasResourceBase) ValidateDeleteCondition(ctx context.Context) error { if model.IsShared() { return httperrors.NewForbiddenError("%s %s is shared", model.Keyword(), model.Name) } return model.SDomainLevelResourceBase.ValidateDeleteCondition(ctx) -} +}*/ diff --git a/pkg/cloudcommon/db/sharablevirtual.go b/pkg/cloudcommon/db/sharablevirtual.go index 0e0a2862be..504199d028 100644 --- a/pkg/cloudcommon/db/sharablevirtual.go +++ b/pkg/cloudcommon/db/sharablevirtual.go @@ -267,9 +267,9 @@ func (model *SSharableVirtualResourceBase) GetRequiredSharedDomainIds() []string return []string{model.DomainId} } -func (model *SSharableVirtualResourceBase) ValidateDeleteCondition(ctx context.Context) error { +/*func (model *SSharableVirtualResourceBase) ValidateDeleteCondition(ctx context.Context) error { if model.IsShared() { return httperrors.NewForbiddenError("%s %s is shared", model.Keyword(), model.Name) } return model.SVirtualResourceBase.ValidateDeleteCondition(ctx) -} +}*/ diff --git a/pkg/cloudcommon/db/virtualresource.go b/pkg/cloudcommon/db/virtualresource.go index 2062d59dea..59373d1b78 100644 --- a/pkg/cloudcommon/db/virtualresource.go +++ b/pkg/cloudcommon/db/virtualresource.go @@ -258,6 +258,10 @@ func (model *SVirtualResourceBase) AllowPerformChangeOwner(ctx context.Context, } func (model *SVirtualResourceBase) PerformChangeOwner(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input apis.PerformChangeProjectOwnerInput) (jsonutils.JSONObject, error) { + if model.GetIStandaloneModel().IsShared() { + return nil, errors.Wrap(httperrors.ErrForbidden, "cannot change owner of shared resource") + } + manager := model.GetModelManager() data := jsonutils.Marshal(input) diff --git a/pkg/compute/guestdrivers/managedvirtual.go b/pkg/compute/guestdrivers/managedvirtual.go index e624c06897..975a65d9de 100644 --- a/pkg/compute/guestdrivers/managedvirtual.go +++ b/pkg/compute/guestdrivers/managedvirtual.go @@ -1054,7 +1054,7 @@ func (self *SManagedVirtualizedGuestDriver) chooseHostStorage( if len(storageIds) != 0 { return models.StorageManager.FetchStorageById(storageIds[0]) } - storages := host.GetAttachedStorages("") + storages := host.GetAttachedEnabledHostStorages(nil) for i := 0; i < len(storages); i += 1 { if storages[i].StorageType == backend { return &storages[i] diff --git a/pkg/compute/models/cloudproviders.go b/pkg/compute/models/cloudproviders.go index 15a6abad6f..4bacfbe6c4 100644 --- a/pkg/compute/models/cloudproviders.go +++ b/pkg/compute/models/cloudproviders.go @@ -1524,3 +1524,24 @@ func (provider *SCloudprovider) IsSharable(reqUsrId mcclient.IIdentityProvider) } return false } + +func (provider *SCloudprovider) AllowGetDetailsChangeOwnerCandidateDomains(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool { + return provider.DomainId == userCred.GetProjectDomainId() || db.IsAdminAllowGetSpec(userCred, provider, "change-owner-candidate-domains") +} + +func (provider *SCloudprovider) GetDetailsChangeOwnerCandidateDomains(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (apis.ChangeOwnerCandidateDomainsOutput, error) { + return db.IOwnerResourceBaseModelGetChangeOwnerCandidateDomains(provider) +} + +func (provider *SCloudprovider) GetChangeOwnerCandidateDomainIds() []string { + account := provider.GetCloudaccount() + if account.ShareMode == api.CLOUD_ACCOUNT_SHARE_MODE_ACCOUNT_DOMAIN { + return []string{account.DomainId} + } + // if account's public_scope=domain and share_mode=provider_domain, only allow to share to specific domains + if account.PublicScope == string(rbacutils.ScopeDomain) { + sharedDomains := account.GetSharedDomains() + return append(sharedDomains, account.DomainId) + } + return []string{} +} diff --git a/pkg/compute/models/disks.go b/pkg/compute/models/disks.go index 90d256ad2f..89f0e37320 100644 --- a/pkg/compute/models/disks.go +++ b/pkg/compute/models/disks.go @@ -580,7 +580,7 @@ func (disk *SDisk) SetStorageByHost(hostId string, diskConfig *api.DiskConfig, s storage = host.GetLeastUsedStorage(backend) } else { // unlimited pulic cloud storages - storages := host.GetAttachedStorages("") + storages := host.GetAttachedEnabledHostStorages(nil) for _, s := range storages { if s.StorageType == backend { tmpS := s diff --git a/pkg/compute/models/hosts.go b/pkg/compute/models/hosts.go index fbd6a5ceed..e88f8b5229 100644 --- a/pkg/compute/models/hosts.go +++ b/pkg/compute/models/hosts.go @@ -888,11 +888,11 @@ func (self *SHost) GetFetchUrl(disableHttps bool) string { return fmt.Sprintf("%s://%s:%d", managerUrl.Scheme, strings.Split(managerUrl.Host, ":")[0], port+40000) } -func (self *SHost) GetAttachedStorages(storageType string) []SStorage { +func (self *SHost) GetAttachedEnabledHostStorages(storageType []string) []SStorage { return self._getAttachedStorages(tristate.False, tristate.True, storageType) } -func (self *SHost) _getAttachedStorages(isBaremetal tristate.TriState, enabled tristate.TriState, storageType string) []SStorage { +func (self *SHost) _getAttachedStorages(isBaremetal tristate.TriState, enabled tristate.TriState, storageType []string) []SStorage { storages := StorageManager.Query().SubQuery() hoststorages := HoststorageManager.Query().SubQuery() q := storages.Query() @@ -908,7 +908,7 @@ func (self *SHost) _getAttachedStorages(isBaremetal tristate.TriState, enabled t q = q.NotEquals("storage_type", api.STORAGE_BAREMETAL) } if len(storageType) > 0 { - q = q.Equals("storage_type", storageType) + q = q.In("storage_type", storageType) } q = q.Filter(sqlchemy.Equals(hoststorages.Field("host_id"), self.Id)) ret := make([]SStorage, 0) @@ -921,7 +921,7 @@ func (self *SHost) _getAttachedStorages(isBaremetal tristate.TriState, enabled t } func (self *SHost) SyncAttachedStorageStatus() { - storages := self.GetAttachedStorages("") + storages := self.GetAttachedEnabledHostStorages(nil) if storages != nil { for _, storage := range storages { storage.SyncStatusWithHosts() @@ -1212,26 +1212,15 @@ func (cap *SStorageCapacity) toCapacityInfo() api.SStorageCapacityInfo { func (self *SHost) GetAttachedLocalStorageCapacity() SStorageCapacity { ret := SStorageCapacity{} - storages := self.GetAttachedStorages("") + storages := self.GetAttachedEnabledHostStorages(api.HOST_STORAGE_LOCAL_TYPES) for _, s := range storages { - if !utils.IsInStringArray(s.StorageType, api.HOST_STORAGE_LOCAL_TYPES) { - continue - } ret.Add(s.getStorageCapacity()) } return ret } func (self *SHost) GetAttachedLocalStorages() []SStorage { - ret := make([]SStorage, 0) - storages := self.GetAttachedStorages("") - for _, s := range storages { - if !utils.IsInStringArray(s.StorageType, api.HOST_STORAGE_LOCAL_TYPES) { - continue - } - ret = append(ret, s) - } - return ret + return self.GetAttachedEnabledHostStorages(api.HOST_STORAGE_LOCAL_TYPES) } func _getLeastUsedStorage(storages []SStorage, backends []string) *SStorage { @@ -1267,7 +1256,7 @@ func getLeastUsedStorage(storages []SStorage, backend string) *SStorage { } func (self *SHost) GetLeastUsedStorage(backend string) *SStorage { - storages := self.GetAttachedStorages("") + storages := self.GetAttachedEnabledHostStorages(nil) if storages != nil { return getLeastUsedStorage(storages, backend) } @@ -2704,7 +2693,7 @@ func (self *SHost) Request(ctx context.Context, userCred mcclient.TokenCredentia } func (self *SHost) GetLocalStoragecache() *SStoragecache { - localStorages := self.GetAttachedStorages(api.STORAGE_LOCAL) + localStorages := self.GetAttachedLocalStorages() for i := 0; i < len(localStorages); i += 1 { sc := localStorages[i].GetStoragecache() if sc != nil { @@ -2715,7 +2704,7 @@ func (self *SHost) GetLocalStoragecache() *SStoragecache { } func (self *SHost) GetStoragecache() *SStoragecache { - localStorages := self.GetAttachedStorages("") + localStorages := self.GetAttachedEnabledHostStorages(nil) for i := 0; i < len(localStorages); i += 1 { sc := localStorages[i].GetStoragecache() if sc != nil { @@ -5075,15 +5064,20 @@ func (model *SHost) CustomizeCreate(ctx context.Context, userCred mcclient.Token } func (host *SHost) PerformChangeOwner(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input apis.PerformChangeDomainOwnerInput) (jsonutils.JSONObject, error) { - localStorages := host.GetAttachedLocalStorages() + ret, err := host.SEnabledStatusInfrasResourceBase.PerformChangeOwner(ctx, userCred, query, input) + if err != nil { + return nil, errors.Wrap(err, "SEnabledStatusInfrasResourceBase.PerformChangeOwner") + } + + localStorages := host._getAttachedStorages(tristate.None, tristate.None, api.HOST_STORAGE_LOCAL_TYPES) for i := range localStorages { - _, err := localStorages[i].PerformChangeOwner(ctx, userCred, query, input) + _, err := localStorages[i].performChangeOwnerInternal(ctx, userCred, query, input) if err != nil { return nil, errors.Wrap(err, "local storage change owner") } } - return host.SEnabledStatusInfrasResourceBase.PerformChangeOwner(ctx, userCred, query, input) + return ret, nil } func GetHostQuotaKeysFromCreateInput(input api.HostCreateInput) quotas.SDomainRegionalCloudResourceKeys { @@ -5125,7 +5119,7 @@ func (host *SHost) GetUsages() []db.IUsage { func (host *SHost) PerformPublic(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input apis.PerformPublicDomainInput) (jsonutils.JSONObject, error) { // perform public for all connected local storage - storages := host.GetAttachedLocalStorages() + storages := host._getAttachedStorages(tristate.None, tristate.None, api.HOST_STORAGE_LOCAL_TYPES) for i := range storages { _, err := storages[i].performPublicInternal(ctx, userCred, query, input) if err != nil { @@ -5137,7 +5131,7 @@ func (host *SHost) PerformPublic(ctx context.Context, userCred mcclient.TokenCre func (host *SHost) PerformPrivate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input apis.PerformPrivateInput) (jsonutils.JSONObject, error) { // perform private for all connected local storage - storages := host.GetAttachedLocalStorages() + storages := host._getAttachedStorages(tristate.None, tristate.None, api.HOST_STORAGE_LOCAL_TYPES) for i := range storages { _, err := storages[i].performPrivateInternal(ctx, userCred, query, input) if err != nil { diff --git a/pkg/compute/models/networks.go b/pkg/compute/models/networks.go index 6bee7c59fc..cc237a198c 100644 --- a/pkg/compute/models/networks.go +++ b/pkg/compute/models/networks.go @@ -2566,11 +2566,13 @@ func (net *SNetwork) PerformStatus(ctx context.Context, userCred mcclient.TokenC } func (net *SNetwork) GetChangeOwnerCandidateDomainIds() []string { - candidates := [][]string{ - net.SSharableVirtualResourceBase.GetChangeOwnerCandidateDomainIds(), - } + candidates := [][]string{} wire := net.GetWire() if wire != nil { + vpc := wire.GetVpc() + if vpc != nil { + candidates = append(candidates, vpc.GetChangeOwnerCandidateDomainIds()) + } candidates = append(candidates, db.ISharableChangeOwnerCandidateDomainIds(wire)) } return db.ISharableMergeChangeOwnerCandidateDomainIds(net, candidates...) diff --git a/pkg/compute/models/purge.go b/pkg/compute/models/purge.go index faec8cc4e7..fef464fb36 100644 --- a/pkg/compute/models/purge.go +++ b/pkg/compute/models/purge.go @@ -94,7 +94,7 @@ func (host *SHost) purge(ctx context.Context, userCred mcclient.TokenCredential) } // clean all disks on locally attached storages - storages := host._getAttachedStorages(tristate.None, tristate.None, api.STORAGE_LOCAL) + storages := host._getAttachedStorages(tristate.None, tristate.None, api.HOST_STORAGE_LOCAL_TYPES) for i := range storages { err := storages[i].purgeDisks(ctx, userCred) if err != nil { diff --git a/pkg/compute/models/secgroups.go b/pkg/compute/models/secgroups.go index 7183b17df7..b8b22fbe77 100644 --- a/pkg/compute/models/secgroups.go +++ b/pkg/compute/models/secgroups.go @@ -819,6 +819,7 @@ func (manager *SSecurityGroupManager) InitializeData() error { secGrp.DomainId = auth.AdminCredential().GetProjectDomainId() // secGrp.IsEmulated = false secGrp.IsPublic = true + secGrp.PublicScope = string(rbacutils.ScopeSystem) err = manager.TableSpec().Insert(secGrp) if err != nil { log.Errorf("Insert default secgroup failed!!! %s", err) diff --git a/pkg/compute/models/storages.go b/pkg/compute/models/storages.go index e761fd2003..0ba80a0fe4 100644 --- a/pkg/compute/models/storages.go +++ b/pkg/compute/models/storages.go @@ -1458,6 +1458,21 @@ func (self *SStorage) StartDeleteRbdDisks(ctx context.Context, userCred mcclient return nil } +func (storage *SStorage) PerformChangeOwner(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input apis.PerformChangeDomainOwnerInput) (jsonutils.JSONObject, error) { + // not allow to perform public for locally connected storage + if storage.IsLocal() { + hosts := storage.GetAttachedHosts() + if len(hosts) > 0 { + return nil, errors.Wrap(httperrors.ErrForbidden, "not allow to change owner for local storage") + } + } + return storage.performChangeOwnerInternal(ctx, userCred, query, input) +} + +func (storage *SStorage) performChangeOwnerInternal(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input apis.PerformChangeDomainOwnerInput) (jsonutils.JSONObject, error) { + return storage.SEnabledStatusInfrasResourceBase.PerformChangeOwner(ctx, userCred, query, input) +} + func (storage *SStorage) PerformPublic(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input apis.PerformPublicDomainInput) (jsonutils.JSONObject, error) { // not allow to perform public for locally connected storage if storage.IsLocal() { diff --git a/pkg/compute/models/vpcs.go b/pkg/compute/models/vpcs.go index 00b7d40e7d..9d36129a67 100644 --- a/pkg/compute/models/vpcs.go +++ b/pkg/compute/models/vpcs.go @@ -573,6 +573,7 @@ func (manager *SVpcManager) InitializeData() error { defVpc.Description = "Default VPC" defVpc.Status = api.VPC_STATUS_AVAILABLE defVpc.IsDefault = true + defVpc.IsPublic = true defVpc.PublicScope = string(rbacutils.ScopeSystem) err = manager.TableSpec().Insert(&defVpc) if err != nil { @@ -1093,12 +1094,13 @@ func (manager *SVpcManager) totalCount( func (vpc *SVpc) GetChangeOwnerCandidateDomainIds() []string { candidates := [][]string{ - vpc.SEnabledStatusInfrasResourceBase.GetChangeOwnerCandidateDomainIds(), + vpc.SManagedResourceBase.GetChangeOwnerCandidateDomainIds(), } globalVpc, _ := vpc.GetGlobalVpc() if globalVpc != nil { candidates = append(candidates, db.ISharableChangeOwnerCandidateDomainIds(globalVpc)) } + log.Debugf("Candidate: %s", candidates) return db.ISharableMergeChangeOwnerCandidateDomainIds(vpc, candidates...) } diff --git a/pkg/compute/models/wires.go b/pkg/compute/models/wires.go index 6a30bc49cd..f7360edc36 100644 --- a/pkg/compute/models/wires.go +++ b/pkg/compute/models/wires.go @@ -1011,12 +1011,12 @@ func (model *SWire) CustomizeCreate(ctx context.Context, userCred mcclient.Token } func (wire *SWire) GetChangeOwnerCandidateDomainIds() []string { - candidates := [][]string{ - wire.SInfrasResourceBase.GetChangeOwnerCandidateDomainIds(), - } + candidates := [][]string{} vpc := wire.GetVpc() if vpc != nil { - candidates = append(candidates, db.ISharableChangeOwnerCandidateDomainIds(vpc)) + candidates = append(candidates, + vpc.GetChangeOwnerCandidateDomainIds(), + db.ISharableChangeOwnerCandidateDomainIds(vpc)) } return db.ISharableMergeChangeOwnerCandidateDomainIds(wire, candidates...) } diff --git a/pkg/mcclient/modules/mod_vpcs.go b/pkg/mcclient/modules/mod_vpcs.go index 46f501191e..f2c10d27aa 100644 --- a/pkg/mcclient/modules/mod_vpcs.go +++ b/pkg/mcclient/modules/mod_vpcs.go @@ -22,7 +22,7 @@ var ( func init() { Vpcs = NewComputeManager("vpc", "vpcs", - []string{"ID", "Name", "Enabled", "Status", "Cloudregion_Id", "Is_default", "Cidr_Block", "Region", "Public_Scope"}, + []string{"ID", "Name", "Enabled", "Status", "Cloudregion_Id", "Is_default", "Cidr_Block", "Region", "Public_Scope", "Domain_Id", "Domain"}, []string{}) registerCompute(&Vpcs)