mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-19 02:37:24 +08:00
fix: 1. vpc, cloudprovider should not violate the sharing limit of cloud account 2.
sharing mode of host and attached local storage should be consistent. 3. cannot change owner of shared resource
This commit is contained in:
@@ -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
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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{}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
+19
-25
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user