mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-19 02:37:24 +08:00
337 lines
9.6 KiB
Go
337 lines
9.6 KiB
Go
// 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 models
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"yunion.io/x/jsonutils"
|
|
"yunion.io/x/pkg/tristate"
|
|
"yunion.io/x/pkg/util/sets"
|
|
|
|
api "yunion.io/x/onecloud/pkg/apis/compute"
|
|
identityapi "yunion.io/x/onecloud/pkg/apis/identity"
|
|
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
|
|
"yunion.io/x/onecloud/pkg/compute/options"
|
|
"yunion.io/x/onecloud/pkg/mcclient"
|
|
"yunion.io/x/onecloud/pkg/util/rbacutils"
|
|
)
|
|
|
|
type SQuotaManager struct {
|
|
quotas.SQuotaBaseManager
|
|
}
|
|
|
|
var QuotaManager *SQuotaManager
|
|
var QuotaUsageManager *SQuotaManager
|
|
|
|
func init() {
|
|
pendingStore := quotas.NewMemoryQuotaStore()
|
|
|
|
QuotaUsageManager = &SQuotaManager{
|
|
SQuotaBaseManager: quotas.NewQuotaUsageManager(SQuota{}, "quota_usage_tbl"),
|
|
}
|
|
|
|
QuotaManager = &SQuotaManager{
|
|
SQuotaBaseManager: quotas.NewQuotaBaseManager(SQuota{}, "quota_tbl", pendingStore, QuotaUsageManager),
|
|
}
|
|
}
|
|
|
|
type SQuota struct {
|
|
quotas.SQuotaBase
|
|
|
|
Cpu int
|
|
Memory int
|
|
Storage int
|
|
Port int
|
|
Eip int
|
|
Eport int
|
|
Bw int
|
|
Ebw int
|
|
// Keypair int
|
|
// Image int
|
|
Group int
|
|
Secgroup int
|
|
IsolatedDevice int
|
|
Snapshot int
|
|
}
|
|
|
|
func (self *SQuota) FetchSystemQuota(scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvider) {
|
|
base := 0
|
|
if scope == rbacutils.ScopeDomain {
|
|
base = 10
|
|
} else if ownerId.GetProjectDomainId() == identityapi.DEFAULT_DOMAIN_ID && ownerId.GetProjectName() == identityapi.SystemAdminProject {
|
|
base = 1
|
|
}
|
|
self.Cpu = options.Options.DefaultCpuQuota * base
|
|
self.Memory = options.Options.DefaultMemoryQuota * base
|
|
self.Storage = options.Options.DefaultStorageQuota * base
|
|
self.Port = options.Options.DefaultPortQuota * base
|
|
self.Eip = options.Options.DefaultEipQuota * base
|
|
self.Eport = options.Options.DefaultEportQuota * base
|
|
self.Bw = options.Options.DefaultBwQuota * base
|
|
self.Ebw = options.Options.DefaultEbwQuota * base
|
|
self.Group = options.Options.DefaultGroupQuota * base
|
|
self.Secgroup = options.Options.DefaultSecgroupQuota * base
|
|
self.IsolatedDevice = options.Options.DefaultIsolatedDeviceQuota * base
|
|
self.Snapshot = options.Options.DefaultSnapshotQuota * base
|
|
}
|
|
|
|
func (self *SQuota) FetchUsage(ctx context.Context, scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvider, name []string) error {
|
|
diskSize := totalDiskSize(scope, ownerId, tristate.None, tristate.None, false)
|
|
net := totalGuestNicCount(scope, ownerId, nil, false)
|
|
lbnic, _ := totalLBNicCount(scope, ownerId)
|
|
// net := WireManager.TotalCount(nil, nil, nil, "", scope, ownerId)
|
|
hypervisors := sets.NewString(api.HYPERVISORS...)
|
|
hypervisors.Delete(api.HYPERVISOR_CONTAINER)
|
|
guest := totalGuestResourceCount(scope, ownerId, nil, nil, hypervisors.List(), false, false, nil, nil, nil, "")
|
|
eipUsage := ElasticipManager.TotalCount(scope, ownerId, nil, nil, "")
|
|
snapshotCount, _ := TotalSnapshotCount(scope, ownerId, nil, nil, "")
|
|
// XXX
|
|
// keypair belongs to user
|
|
// keypair := totalKeypairCount(projectId)
|
|
|
|
self.Cpu = guest.TotalCpuCount
|
|
self.Memory = guest.TotalMemSize
|
|
self.Storage = diskSize
|
|
self.Eip = eipUsage.Total()
|
|
// log.Debugf("%d %d %d\n", net.InternalNicCount, net.InternalVirtualNicCount, lbnic)
|
|
self.Port = net.InternalNicCount + net.InternalVirtualNicCount + lbnic
|
|
self.Eport = net.ExternalNicCount + net.ExternalVirtualNicCount
|
|
self.Bw = net.InternalBandwidth
|
|
self.Ebw = net.ExternalBandwidth
|
|
// self.Port = net.GuestNicCount + net.GroupNicCount + net.LbNicCount
|
|
// if scope == rbacutils.ScopeSystem {
|
|
// self.Port += net.HostNicCount + net.ReservedCount
|
|
// }
|
|
self.Group = 0
|
|
self.Secgroup, _ = totalSecurityGroupCount(scope, ownerId)
|
|
self.IsolatedDevice = guest.TotalIsolatedCount
|
|
self.Snapshot = snapshotCount
|
|
return nil
|
|
}
|
|
|
|
func (self *SQuota) IsEmpty() bool {
|
|
if self.Cpu > 0 {
|
|
return false
|
|
}
|
|
if self.Memory > 0 {
|
|
return false
|
|
}
|
|
if self.Storage > 0 {
|
|
return false
|
|
}
|
|
if self.Port > 0 {
|
|
return false
|
|
}
|
|
if self.Eip > 0 {
|
|
return false
|
|
}
|
|
if self.Eport > 0 {
|
|
return false
|
|
}
|
|
if self.Bw > 0 {
|
|
return false
|
|
}
|
|
if self.Ebw > 0 {
|
|
return false
|
|
}
|
|
if self.Group > 0 {
|
|
return false
|
|
}
|
|
if self.Secgroup > 0 {
|
|
return false
|
|
}
|
|
if self.IsolatedDevice > 0 {
|
|
return false
|
|
}
|
|
if self.Snapshot > 0 {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func (self *SQuota) Add(quota quotas.IQuota) {
|
|
squota := quota.(*SQuota)
|
|
self.Cpu = self.Cpu + squota.Cpu
|
|
self.Memory = self.Memory + squota.Memory
|
|
self.Storage = self.Storage + squota.Storage
|
|
self.Port = self.Port + squota.Port
|
|
self.Eip = self.Eip + squota.Eip
|
|
self.Eport = self.Eport + squota.Eport
|
|
self.Bw = self.Bw + squota.Bw
|
|
self.Ebw = self.Ebw + squota.Ebw
|
|
self.Group = self.Group + squota.Group
|
|
self.Secgroup = self.Secgroup + squota.Secgroup
|
|
self.IsolatedDevice = self.IsolatedDevice + squota.IsolatedDevice
|
|
self.Snapshot = self.Snapshot + squota.Snapshot
|
|
}
|
|
|
|
func nonNegative(val int) int {
|
|
return quotas.NonNegative(val)
|
|
}
|
|
|
|
func (self *SQuota) Sub(quota quotas.IQuota) {
|
|
squota := quota.(*SQuota)
|
|
self.Cpu = nonNegative(self.Cpu - squota.Cpu)
|
|
self.Memory = nonNegative(self.Memory - squota.Memory)
|
|
self.Storage = nonNegative(self.Storage - squota.Storage)
|
|
self.Port = nonNegative(self.Port - squota.Port)
|
|
self.Eip = nonNegative(self.Eip - squota.Eip)
|
|
self.Eport = nonNegative(self.Eport - squota.Eport)
|
|
self.Bw = nonNegative(self.Bw - squota.Bw)
|
|
self.Ebw = nonNegative(self.Ebw - squota.Ebw)
|
|
self.Group = nonNegative(self.Group - squota.Group)
|
|
self.Secgroup = nonNegative(self.Secgroup - squota.Secgroup)
|
|
self.IsolatedDevice = nonNegative(self.IsolatedDevice - squota.IsolatedDevice)
|
|
self.Snapshot = nonNegative(self.Snapshot - squota.Snapshot)
|
|
}
|
|
|
|
func (self *SQuota) Update(quota quotas.IQuota) {
|
|
squota := quota.(*SQuota)
|
|
if squota.Cpu > 0 {
|
|
self.Cpu = squota.Cpu
|
|
}
|
|
if squota.Memory > 0 {
|
|
self.Memory = squota.Memory
|
|
}
|
|
if squota.Storage > 0 {
|
|
self.Storage = squota.Storage
|
|
}
|
|
if squota.Port > 0 {
|
|
self.Port = squota.Port
|
|
}
|
|
if squota.Eip > 0 {
|
|
self.Eip = squota.Eip
|
|
}
|
|
if squota.Eport > 0 {
|
|
self.Eport = squota.Eport
|
|
}
|
|
if squota.Bw > 0 {
|
|
self.Bw = squota.Bw
|
|
}
|
|
if squota.Ebw > 0 {
|
|
self.Ebw = squota.Ebw
|
|
}
|
|
if squota.Group > 0 {
|
|
self.Group = squota.Group
|
|
}
|
|
if squota.Secgroup > 0 {
|
|
self.Secgroup = squota.Secgroup
|
|
}
|
|
if squota.IsolatedDevice > 0 {
|
|
self.IsolatedDevice = squota.IsolatedDevice
|
|
}
|
|
if squota.Snapshot > 0 {
|
|
self.Snapshot = squota.Snapshot
|
|
}
|
|
}
|
|
|
|
func (self *SQuota) Exceed(request quotas.IQuota, quota quotas.IQuota) error {
|
|
err := quotas.NewOutOfQuotaError()
|
|
sreq := request.(*SQuota)
|
|
squota := quota.(*SQuota)
|
|
if sreq.Cpu > 0 && self.Cpu > squota.Cpu {
|
|
err.Add("cpu", squota.Cpu, self.Cpu)
|
|
}
|
|
if sreq.Memory > 0 && self.Memory > squota.Memory {
|
|
err.Add("memory", squota.Memory, self.Memory)
|
|
}
|
|
if sreq.Storage > 0 && self.Storage > squota.Storage {
|
|
err.Add("storage", squota.Storage, self.Storage)
|
|
}
|
|
if sreq.Port > 0 && self.Port > squota.Port {
|
|
err.Add("port", squota.Port, self.Port)
|
|
}
|
|
if sreq.Eip > 0 && self.Eip > squota.Eip {
|
|
err.Add("eip", squota.Eip, self.Eip)
|
|
}
|
|
if sreq.Eport > 0 && self.Eport > squota.Eport {
|
|
err.Add("eport", squota.Eport, self.Eport)
|
|
}
|
|
if sreq.Bw > 0 && self.Bw > squota.Bw {
|
|
err.Add("bw", squota.Bw, self.Bw)
|
|
}
|
|
if sreq.Ebw > 0 && self.Ebw > squota.Ebw {
|
|
err.Add("ebw", squota.Ebw, self.Ebw)
|
|
}
|
|
if sreq.Group > 0 && self.Group > squota.Group {
|
|
err.Add("group", squota.Group, self.Group)
|
|
}
|
|
if sreq.Secgroup > 0 && self.Secgroup > squota.Secgroup {
|
|
err.Add("secgroup", squota.Secgroup, self.Secgroup)
|
|
}
|
|
if sreq.IsolatedDevice > 0 && self.IsolatedDevice > squota.IsolatedDevice {
|
|
err.Add("isolated_device", squota.IsolatedDevice, self.IsolatedDevice)
|
|
}
|
|
if sreq.Snapshot > 0 && self.Snapshot > squota.Snapshot {
|
|
err.Add("snapshot", squota.Snapshot, self.Snapshot)
|
|
}
|
|
if err.IsError() {
|
|
return err
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func keyName(prefix, name string) string {
|
|
if len(prefix) > 0 {
|
|
return fmt.Sprintf("%s.%s", prefix, name)
|
|
} else {
|
|
return name
|
|
}
|
|
}
|
|
|
|
func (self *SQuota) ToJSON(prefix string) jsonutils.JSONObject {
|
|
ret := jsonutils.NewDict()
|
|
if self.Cpu > 0 {
|
|
ret.Add(jsonutils.NewInt(int64(self.Cpu)), keyName(prefix, "cpu"))
|
|
}
|
|
if self.Memory > 0 {
|
|
ret.Add(jsonutils.NewInt(int64(self.Memory)), keyName(prefix, "memory"))
|
|
}
|
|
if self.Storage > 0 {
|
|
ret.Add(jsonutils.NewInt(int64(self.Storage)), keyName(prefix, "storage"))
|
|
}
|
|
if self.Port > 0 {
|
|
ret.Add(jsonutils.NewInt(int64(self.Port)), keyName(prefix, "port"))
|
|
}
|
|
if self.Eip > 0 {
|
|
ret.Add(jsonutils.NewInt(int64(self.Eip)), keyName(prefix, "eip"))
|
|
}
|
|
if self.Eport > 0 {
|
|
ret.Add(jsonutils.NewInt(int64(self.Eport)), keyName(prefix, "eport"))
|
|
}
|
|
if self.Bw > 0 {
|
|
ret.Add(jsonutils.NewInt(int64(self.Bw)), keyName(prefix, "bw"))
|
|
}
|
|
if self.Ebw > 0 {
|
|
ret.Add(jsonutils.NewInt(int64(self.Ebw)), keyName(prefix, "ebw"))
|
|
}
|
|
if self.Group > 0 {
|
|
ret.Add(jsonutils.NewInt(int64(self.Group)), keyName(prefix, "group"))
|
|
}
|
|
if self.Secgroup > 0 {
|
|
ret.Add(jsonutils.NewInt(int64(self.Secgroup)), keyName(prefix, "secgroup"))
|
|
}
|
|
if self.IsolatedDevice > 0 {
|
|
ret.Add(jsonutils.NewInt(int64(self.IsolatedDevice)), keyName(prefix, "isolated_device"))
|
|
}
|
|
if self.Snapshot > 0 {
|
|
ret.Add(jsonutils.NewInt(int64(self.Snapshot)), keyName(prefix, "snapshot"))
|
|
}
|
|
return ret
|
|
}
|