Merge pull request #6219 from swordqiu/hotfix/qj-domain-sharing-bugfixes-20200508

fix: 1. vpc, cloudprovider should not violate the sharing limit of cl…
This commit is contained in:
Zexi Li
2020-05-11 12:37:31 +08:00
committed by GitHub
20 changed files with 195 additions and 41 deletions
+4
View File
@@ -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)
+2 -2
View File
@@ -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)
}
}*/
+2 -2
View File
@@ -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)
}
}*/
+4
View File
@@ -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)
+1 -1
View File
@@ -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]
+21
View File
@@ -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{}
}
+1 -1
View File
@@ -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
View File
@@ -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 {
+5 -3
View File
@@ -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...)
+1 -1
View File
@@ -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 {
+1
View File
@@ -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)
+15
View File
@@ -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() {
+3 -1
View File
@@ -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...)
}
+4 -4
View File
@@ -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...)
}
+1 -1
View File
@@ -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)