Skip to content

Commit

Permalink
fix: 1. vpc, cloudprovider should not violate the sharing limit of cl…
Browse files Browse the repository at this point in the history
…oud account 2.

sharing mode of host and attached local storage should be consistent. 3.
cannot change owner of shared resource
  • Loading branch information
Qiu Jian committed May 8, 2020
1 parent 0c45818 commit f2e0fcf
Show file tree
Hide file tree
Showing 14 changed files with 142 additions and 31 deletions.
9 changes: 9 additions & 0 deletions cmd/climc/shell/compute/cloudproviders.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
})
}
45 changes: 45 additions & 0 deletions cmd/climc/shell/compute/storages.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
})
}
19 changes: 19 additions & 0 deletions cmd/climc/shell/compute/vpcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
package compute

import (
"fmt"

"yunion.io/x/jsonutils"

"yunion.io/x/onecloud/pkg/mcclient"
Expand Down Expand Up @@ -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
})
}
4 changes: 4 additions & 0 deletions pkg/cloudcommon/db/domainresource.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 4 additions & 0 deletions pkg/cloudcommon/db/virtualresource.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion pkg/compute/guestdrivers/managedvirtual.go
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
21 changes: 21 additions & 0 deletions pkg/compute/models/cloudproviders.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{}
}
2 changes: 1 addition & 1 deletion pkg/compute/models/disks.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
44 changes: 19 additions & 25 deletions pkg/compute/models/hosts.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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)
Expand All @@ -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()
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion pkg/compute/models/networks.go
Original file line number Diff line number Diff line change
Expand Up @@ -2567,7 +2567,7 @@ func (net *SNetwork) PerformStatus(ctx context.Context, userCred mcclient.TokenC

func (net *SNetwork) GetChangeOwnerCandidateDomainIds() []string {
candidates := [][]string{
net.SSharableVirtualResourceBase.GetChangeOwnerCandidateDomainIds(),
db.ISharableChangeOwnerCandidateDomainIds(net),
}
wire := net.GetWire()
if wire != nil {
Expand Down
2 changes: 1 addition & 1 deletion pkg/compute/models/purge.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
15 changes: 15 additions & 0 deletions pkg/compute/models/storages.go
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
2 changes: 1 addition & 1 deletion pkg/compute/models/vpcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -1093,7 +1093,7 @@ func (manager *SVpcManager) totalCount(

func (vpc *SVpc) GetChangeOwnerCandidateDomainIds() []string {
candidates := [][]string{
vpc.SEnabledStatusInfrasResourceBase.GetChangeOwnerCandidateDomainIds(),
db.ISharableChangeOwnerCandidateDomainIds(vpc),
}
globalVpc, _ := vpc.GetGlobalVpc()
if globalVpc != nil {
Expand Down
2 changes: 1 addition & 1 deletion pkg/compute/models/wires.go
Original file line number Diff line number Diff line change
Expand Up @@ -1012,7 +1012,7 @@ func (model *SWire) CustomizeCreate(ctx context.Context, userCred mcclient.Token

func (wire *SWire) GetChangeOwnerCandidateDomainIds() []string {
candidates := [][]string{
wire.SInfrasResourceBase.GetChangeOwnerCandidateDomainIds(),
db.ISharableChangeOwnerCandidateDomainIds(wire),
}
vpc := wire.GetVpc()
if vpc != nil {
Expand Down

0 comments on commit f2e0fcf

Please sign in to comment.