| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493 |
- // 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 quotas
- import (
- "fmt"
- "strings"
- "yunion.io/x/pkg/util/rbacscope"
- "yunion.io/x/onecloud/pkg/cloudcommon/db"
- "yunion.io/x/onecloud/pkg/mcclient"
- )
- type SBaseDomainQuotaKeys struct {
- // 配额适用的域ID
- DomainId string `width:"64" charset:"ascii" nullable:"false" primary:"true" list:"user" json:"domain_id"`
- }
- type SBaseProjectQuotaKeys struct {
- SBaseDomainQuotaKeys
- // 配额适用的项目ID
- ProjectId string `name:"tenant_id" width:"64" charset:"ascii" nullable:"false" primary:"true" list:"user" json:"project_id"`
- }
- type SBaseDomainQuotaDetailKeys struct {
- // 配额适用的项目的域名称
- Domain string `json:"domain"`
- }
- type SBaseProjectQuotaDetailKeys struct {
- SBaseDomainQuotaDetailKeys
- // 配额适用的项目名称
- Project string `json:"project"`
- }
- type SCloudResourceBaseKeys struct {
- // 配额适用的平台名称,参考List接口的平台列表
- Provider string `width:"32" charset:"ascii" nullable:"false" primary:"true" list:"user" json:"provider"`
- // 配额适用的品牌名称,参考List接口的品牌列表
- Brand string `width:"32" charset:"ascii" nullable:"false" primary:"true" list:"user" json:"brand"`
- // 配额适用的云环境,参考List接口的云环境列表
- CloudEnv string `width:"32" charset:"ascii" nullable:"false" primary:"true" list:"user" json:"cloud_env"`
- // 配额适用的云账号ID
- AccountId string `width:"64" charset:"ascii" nullable:"false" primary:"true" list:"user" json:"account_id"`
- // 配额适用的云订阅ID
- ManagerId string `width:"64" charset:"ascii" nullable:"false" primary:"true" list:"user" json:"manager_id"`
- }
- type SCloudResourceKeys struct {
- SBaseProjectQuotaKeys
- SCloudResourceBaseKeys
- }
- type SCloudResourceDetailKeys struct {
- SBaseProjectQuotaDetailKeys
- SCloudResourceDetailBaseKeys
- }
- type SCloudResourceDetailBaseKeys struct {
- // 配额适用的云账号名称
- Account string `json:"account"`
- // 配额适用的云订阅名称
- Manager string `json:"manager"`
- }
- type SRegionalBaseKeys struct {
- // 配额适用的区域ID
- RegionId string `width:"64" charset:"ascii" nullable:"false" primary:"true" list:"user" json:"region_id"`
- }
- type SRegionalCloudResourceKeys struct {
- SCloudResourceKeys
- SRegionalBaseKeys
- }
- type SRegionalCloudResourceDetailKeys struct {
- SCloudResourceDetailKeys
- SRegionalCloudResourceDetailBaseKeys
- }
- type SRegionalCloudResourceDetailBaseKeys struct {
- // 配额适用的区域名称
- Region string `json:"region"`
- }
- type SDomainRegionalCloudResourceKeys struct {
- SBaseDomainQuotaKeys
- SCloudResourceBaseKeys
- SRegionalBaseKeys
- }
- type SDomainRegionalCloudResourceDetailKeys struct {
- SBaseDomainQuotaDetailKeys
- SCloudResourceDetailBaseKeys
- SRegionalCloudResourceDetailBaseKeys
- }
- type SZonalCloudResourceKeys struct {
- SRegionalCloudResourceKeys
- // 配额适用的可用区ID
- ZoneId string `width:"64" charset:"ascii" nullable:"false" primary:"true" list:"user" json:"zone_id"`
- }
- type SZonalCloudResourceDetailKeys struct {
- SRegionalCloudResourceDetailKeys
- // 配额适用的可用区名称
- Zone string `json:"zone"`
- }
- func (k SBaseDomainQuotaKeys) Fields() []string {
- return []string{
- "domain_id",
- }
- }
- func (k SBaseProjectQuotaKeys) Fields() []string {
- return append(k.SBaseDomainQuotaKeys.Fields(),
- "tenant_id",
- )
- }
- func (k SCloudResourceBaseKeys) Fields() []string {
- return []string{
- "provider",
- "brand",
- "cloud_env",
- "account_id",
- "manager_id",
- }
- }
- func (k SCloudResourceKeys) Fields() []string {
- ret := k.SBaseProjectQuotaKeys.Fields()
- ret = append(ret, k.SCloudResourceBaseKeys.Fields()...)
- return ret
- }
- func (k SRegionalCloudResourceKeys) Fields() []string {
- return append(k.SCloudResourceKeys.Fields(),
- "region_id",
- )
- }
- func (k SZonalCloudResourceKeys) Fields() []string {
- return append(k.SRegionalCloudResourceKeys.Fields(),
- "zone_id",
- )
- }
- func (k SDomainRegionalCloudResourceKeys) Fields() []string {
- ret := k.SBaseDomainQuotaKeys.Fields()
- ret = append(ret, k.SCloudResourceBaseKeys.Fields()...)
- ret = append(ret, "region_id")
- return ret
- }
- func (k SBaseDomainQuotaKeys) Values() []string {
- return []string{
- k.DomainId,
- }
- }
- func (k SBaseProjectQuotaKeys) Values() []string {
- return append(k.SBaseDomainQuotaKeys.Values(),
- k.ProjectId,
- )
- }
- func (k SCloudResourceBaseKeys) Values() []string {
- return []string{
- k.Provider,
- k.Brand,
- k.CloudEnv,
- k.AccountId,
- k.ManagerId,
- }
- }
- func (k SCloudResourceKeys) Values() []string {
- ret := k.SBaseProjectQuotaKeys.Values()
- ret = append(ret, k.SCloudResourceBaseKeys.Values()...)
- return ret
- }
- func (k SRegionalCloudResourceKeys) Values() []string {
- return append(k.SCloudResourceKeys.Values(),
- k.RegionId,
- )
- }
- func (k SZonalCloudResourceKeys) Values() []string {
- return append(k.SRegionalCloudResourceKeys.Values(),
- k.ZoneId,
- )
- }
- func (k SDomainRegionalCloudResourceKeys) Values() []string {
- ret := k.SBaseDomainQuotaKeys.Values()
- ret = append(ret, k.SCloudResourceBaseKeys.Values()...)
- ret = append(ret, k.RegionId)
- return ret
- }
- func (k1 SBaseDomainQuotaKeys) Compare(ik IQuotaKeys) int {
- k2 := ik.(SBaseDomainQuotaKeys)
- if k1.DomainId < k2.DomainId {
- return -1
- } else if k1.DomainId > k2.DomainId {
- return 1
- }
- return 0
- }
- func (k1 SBaseProjectQuotaKeys) Compare(ik IQuotaKeys) int {
- k2 := ik.(SBaseProjectQuotaKeys)
- r := k1.SBaseDomainQuotaKeys.Compare(k2.SBaseDomainQuotaKeys)
- if r != 0 {
- return r
- }
- if k1.ProjectId < k2.ProjectId {
- return -1
- } else if k1.ProjectId > k2.ProjectId {
- return 1
- }
- return 0
- }
- func (k1 SCloudResourceBaseKeys) compare(k2 SCloudResourceBaseKeys) int {
- if k1.CloudEnv < k2.CloudEnv {
- return -1
- } else if k1.CloudEnv > k2.CloudEnv {
- return 1
- }
- if k1.Provider < k2.Provider {
- return -1
- } else if k1.Provider > k2.Provider {
- return 1
- }
- if k1.Brand < k2.Brand {
- return -1
- } else if k1.Brand > k2.Brand {
- return 1
- }
- return 0
- }
- func (k1 SCloudResourceKeys) Compare(ik IQuotaKeys) int {
- k2 := ik.(SCloudResourceKeys)
- r := k1.SBaseProjectQuotaKeys.Compare(k2.SBaseProjectQuotaKeys)
- if r != 0 {
- return r
- }
- r = k1.SCloudResourceBaseKeys.compare(k2.SCloudResourceBaseKeys)
- if r != 0 {
- return r
- }
- return 0
- }
- func (k1 SRegionalCloudResourceKeys) Compare(ik IQuotaKeys) int {
- k2 := ik.(SRegionalCloudResourceKeys)
- r := k1.SCloudResourceKeys.Compare(k2.SCloudResourceKeys)
- if r != 0 {
- return r
- }
- if k1.RegionId < k2.RegionId {
- return -1
- } else if k1.RegionId > k2.RegionId {
- return 1
- }
- return 0
- }
- func (k1 SZonalCloudResourceKeys) Compare(ik IQuotaKeys) int {
- k2 := ik.(SZonalCloudResourceKeys)
- r := k1.SRegionalCloudResourceKeys.Compare(k2.SRegionalCloudResourceKeys)
- if r != 0 {
- return r
- }
- if k1.ZoneId < k2.ZoneId {
- return -1
- } else if k1.ZoneId > k2.ZoneId {
- return 1
- }
- return 0
- }
- func (k1 SDomainRegionalCloudResourceKeys) Compare(ik IQuotaKeys) int {
- k2 := ik.(SDomainRegionalCloudResourceKeys)
- r := k1.SBaseDomainQuotaKeys.Compare(k2.SBaseDomainQuotaKeys)
- if r != 0 {
- return r
- }
- r = k1.SCloudResourceBaseKeys.compare(k2.SCloudResourceBaseKeys)
- if r != 0 {
- return r
- }
- if k1.RegionId < k2.RegionId {
- return -1
- } else if k1.RegionId > k2.RegionId {
- return 1
- }
- return 0
- }
- func QuotaKeyWeight(k IQuotaKeys) uint64 {
- w := uint64(0)
- for i, v := range k.Values() {
- if len(v) > 0 {
- w += (uint64(1) << uint(i))
- }
- }
- return w
- }
- func (k SBaseDomainQuotaKeys) Scope() rbacscope.TRbacScope {
- if len(k.DomainId) > 0 {
- return rbacscope.ScopeDomain
- } else {
- return rbacscope.ScopeSystem
- }
- }
- func (k SBaseProjectQuotaKeys) Scope() rbacscope.TRbacScope {
- if len(k.DomainId) > 0 && len(k.ProjectId) > 0 {
- return rbacscope.ScopeProject
- } else if len(k.DomainId) > 0 && len(k.ProjectId) == 0 {
- return rbacscope.ScopeDomain
- } else if len(k.DomainId) == 0 && len(k.ProjectId) == 0 {
- return rbacscope.ScopeSystem
- } else {
- return rbacscope.ScopeNone
- }
- }
- func (k SBaseDomainQuotaKeys) OwnerId() mcclient.IIdentityProvider {
- return &db.SOwnerId{DomainId: k.DomainId}
- }
- func (k SBaseProjectQuotaKeys) OwnerId() mcclient.IIdentityProvider {
- return &db.SOwnerId{
- DomainId: k.DomainId,
- ProjectId: k.ProjectId,
- }
- }
- func QuotaKeyString(k IQuotaKeys) string {
- parts := make([]string, 0)
- fields := k.Fields()
- values := k.Values()
- for i := range fields {
- if len(values[i]) > 0 {
- parts = append(parts, fmt.Sprintf("%s=%s", fields[i], values[i]))
- }
- }
- return strings.Join(parts, ",")
- }
- func IsBaseProjectQuotaKeys(k IQuotaKeys) bool {
- fields := k.Fields()
- values := k.Values()
- for i := range fields {
- if fields[i] != "domain_id" && fields[i] != "tenant_id" && len(values[i]) > 0 {
- return false
- }
- }
- return true
- }
- func IsBaseDomainQuotaKeys(k IQuotaKeys) bool {
- fields := k.Fields()
- values := k.Values()
- for i := range fields {
- if fields[i] != "domain_id" && len(values[i]) > 0 {
- return false
- }
- }
- return true
- }
- func OwnerIdProjectQuotaKeys(scope rbacscope.TRbacScope, ownerId mcclient.IIdentityProvider) SBaseProjectQuotaKeys {
- if scope == rbacscope.ScopeDomain {
- return SBaseProjectQuotaKeys{
- SBaseDomainQuotaKeys: SBaseDomainQuotaKeys{
- DomainId: ownerId.GetProjectDomainId(),
- },
- }
- } else {
- return SBaseProjectQuotaKeys{
- SBaseDomainQuotaKeys: SBaseDomainQuotaKeys{
- DomainId: ownerId.GetProjectDomainId(),
- },
- ProjectId: ownerId.GetProjectId(),
- }
- }
- }
- func OwnerIdDomainQuotaKeys(ownerId mcclient.IIdentityProvider) SBaseDomainQuotaKeys {
- return SBaseDomainQuotaKeys{DomainId: ownerId.GetProjectDomainId()}
- }
- type TQuotaKeysRelation string
- const (
- QuotaKeysContain = TQuotaKeysRelation("contain")
- QuotaKeysBelong = TQuotaKeysRelation("belong")
- QuotaKeysEqual = TQuotaKeysRelation("equal")
- QuotaKeysExclude = TQuotaKeysRelation("exclude")
- )
- func stringRelation(s1, s2 string) TQuotaKeysRelation {
- if s1 == s2 {
- return QuotaKeysEqual
- } else if len(s1) == 0 {
- return QuotaKeysContain
- } else if len(s2) == 0 {
- return QuotaKeysBelong
- } else {
- return QuotaKeysExclude
- }
- }
- func relation(k1, k2 IQuotaKeys) TQuotaKeysRelation {
- a1 := k1.Values()
- a2 := k2.Values()
- relationMap := make(map[TQuotaKeysRelation]int, 0)
- for i := 0; i < len(a1); i += 1 {
- rel := stringRelation(a1[i], a2[i])
- if _, ok := relationMap[rel]; ok {
- relationMap[rel] = relationMap[rel] + 1
- } else {
- relationMap[rel] = 1
- }
- }
- switch len(relationMap) {
- case 1:
- for k := range relationMap {
- return k
- }
- case 2:
- _, equalExist := relationMap[QuotaKeysEqual]
- if equalExist {
- if _, ok := relationMap[QuotaKeysContain]; ok {
- return QuotaKeysContain
- }
- if _, ok := relationMap[QuotaKeysBelong]; ok {
- return QuotaKeysBelong
- }
- return QuotaKeysExclude
- }
- }
- return QuotaKeysExclude
- }
- type TQuotaList []IQuota
- func (a TQuotaList) Len() int { return len(a) }
- func (a TQuotaList) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
- func (a TQuotaList) Less(i, j int) bool {
- iKeys := a[i].GetKeys()
- jKeys := a[j].GetKeys()
- relation := relation(iKeys, jKeys)
- switch relation {
- case QuotaKeysContain:
- return true
- case QuotaKeysBelong:
- return false
- }
- iw := QuotaKeyWeight(iKeys)
- jw := QuotaKeyWeight(jKeys)
- if iw < jw {
- return true
- } else if iw > jw {
- return false
- }
- return iKeys.Compare(jKeys) < 0
- }
|