projectquota.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package models
  15. import (
  16. "context"
  17. "yunion.io/x/jsonutils"
  18. "yunion.io/x/pkg/util/rbacscope"
  19. identityapi "yunion.io/x/onecloud/pkg/apis/identity"
  20. "yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
  21. commonOptions "yunion.io/x/onecloud/pkg/cloudcommon/options"
  22. "yunion.io/x/onecloud/pkg/compute/options"
  23. "yunion.io/x/onecloud/pkg/mcclient/auth"
  24. )
  25. var (
  26. ProjectQuota SProjectQuota
  27. ProjectQuotaManager *SQuotaManager
  28. ProjectUsageManager *SQuotaManager
  29. ProjectPendingUsageManager *SQuotaManager
  30. )
  31. func init() {
  32. ProjectQuota = SProjectQuota{}
  33. ProjectUsageManager = &SQuotaManager{
  34. SQuotaBaseManager: quotas.NewQuotaUsageManager(ProjectQuota,
  35. rbacscope.ScopeProject,
  36. "project_quota_usage_tbl",
  37. "project_quota_usage",
  38. "project_quota_usages",
  39. ),
  40. }
  41. ProjectPendingUsageManager = &SQuotaManager{
  42. SQuotaBaseManager: quotas.NewQuotaUsageManager(ProjectQuota,
  43. rbacscope.ScopeProject,
  44. "project_quota_pending_usage_tbl",
  45. "project_quota_pending_usage",
  46. "project_quota_pending_usages",
  47. ),
  48. }
  49. ProjectQuotaManager = &SQuotaManager{
  50. SQuotaBaseManager: quotas.NewQuotaBaseManager(ProjectQuota,
  51. rbacscope.ScopeProject,
  52. "project_quota_tbl",
  53. ProjectPendingUsageManager,
  54. ProjectUsageManager,
  55. "project_quota",
  56. "project_quotas",
  57. ),
  58. }
  59. quotas.Register(ProjectQuotaManager)
  60. }
  61. type SProjectQuota struct {
  62. quotas.SQuotaBase
  63. quotas.SBaseProjectQuotaKeys
  64. Secgroup int `default:"-1" allow_zero:"true" json:"secgroup"`
  65. }
  66. func (self *SProjectQuota) GetKeys() quotas.IQuotaKeys {
  67. return self.SBaseProjectQuotaKeys
  68. }
  69. func (self *SProjectQuota) SetKeys(keys quotas.IQuotaKeys) {
  70. self.SBaseProjectQuotaKeys = keys.(quotas.SBaseProjectQuotaKeys)
  71. }
  72. func (self *SProjectQuota) FetchSystemQuota() {
  73. keys := self.SBaseProjectQuotaKeys
  74. base := 0
  75. switch options.Options.DefaultQuotaValue {
  76. case commonOptions.DefaultQuotaUnlimit:
  77. base = -1
  78. case commonOptions.DefaultQuotaZero:
  79. base = 0
  80. if keys.Scope() == rbacscope.ScopeDomain { // domain level quota
  81. base = 10
  82. } else if keys.DomainId == identityapi.DEFAULT_DOMAIN_ID && keys.ProjectId == auth.AdminCredential().GetProjectId() {
  83. base = 1
  84. }
  85. case commonOptions.DefaultQuotaDefault:
  86. base = 1
  87. if keys.Scope() == rbacscope.ScopeDomain {
  88. base = 10
  89. }
  90. }
  91. defaultValue := func(def int) int {
  92. if base < 0 {
  93. return -1
  94. } else {
  95. return def * base
  96. }
  97. }
  98. self.Secgroup = defaultValue(options.Options.DefaultSecgroupQuota)
  99. }
  100. func (self *SProjectQuota) FetchUsage(ctx context.Context) error {
  101. regionKeys := self.SBaseProjectQuotaKeys
  102. scope := regionKeys.Scope()
  103. ownerId := regionKeys.OwnerId()
  104. self.Secgroup, _ = totalSecurityGroupCount(scope, ownerId)
  105. return nil
  106. }
  107. func (self *SProjectQuota) ResetNegative() {
  108. if self.Secgroup < 0 {
  109. self.Secgroup = 0
  110. }
  111. }
  112. func (self *SProjectQuota) IsEmpty() bool {
  113. if self.Secgroup > 0 {
  114. return false
  115. }
  116. return true
  117. }
  118. func (self *SProjectQuota) Add(quota quotas.IQuota) {
  119. squota := quota.(*SProjectQuota)
  120. self.Secgroup = self.Secgroup + quotas.NonNegative(squota.Secgroup)
  121. }
  122. func (self *SProjectQuota) Sub(quota quotas.IQuota) {
  123. squota := quota.(*SProjectQuota)
  124. self.Secgroup = nonNegative(self.Secgroup - squota.Secgroup)
  125. }
  126. func (self *SProjectQuota) Allocable(request quotas.IQuota) int {
  127. squota := request.(*SProjectQuota)
  128. cnt := -1
  129. if self.Secgroup >= 0 && squota.Secgroup > 0 && (cnt < 0 || cnt > self.Secgroup/squota.Secgroup) {
  130. cnt = self.Secgroup / squota.Secgroup
  131. }
  132. return cnt
  133. }
  134. func (self *SProjectQuota) Update(quota quotas.IQuota) {
  135. squota := quota.(*SProjectQuota)
  136. if squota.Secgroup > 0 {
  137. self.Secgroup = squota.Secgroup
  138. }
  139. }
  140. func (used *SProjectQuota) Exceed(request quotas.IQuota, quota quotas.IQuota) error {
  141. err := quotas.NewOutOfQuotaError()
  142. sreq := request.(*SProjectQuota)
  143. squota := quota.(*SProjectQuota)
  144. if quotas.Exceed(used.Secgroup, sreq.Secgroup, squota.Secgroup) {
  145. err.Add(used, "secgroup", squota.Secgroup, used.Secgroup, sreq.Secgroup)
  146. }
  147. if err.IsError() {
  148. return err
  149. } else {
  150. return nil
  151. }
  152. }
  153. func (self *SProjectQuota) ToJSON(prefix string) jsonutils.JSONObject {
  154. ret := jsonutils.NewDict()
  155. ret.Add(jsonutils.NewInt(int64(self.Secgroup)), keyName(prefix, "secgroup"))
  156. return ret
  157. }