2 * Copyright 2020 Intel Corporation, Inc
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 pkgerrors "github.com/pkg/errors"
23 // Quota contains the parameters needed for a Quota
25 MetaData QMetaDataList `json:"metadata"`
26 // Specification QSpec `json:"spec"`
27 Specification map[string]string `json:"spec"`
30 // MetaData contains the parameters needed for metadata
31 type QMetaDataList struct {
32 QuotaName string `json:"name"`
33 Description string `json:"description"`
36 // TODO: use QSpec fields to validate quota keys
37 // Spec contains the parameters needed for spec
39 LimitsCPU string `json:"limits.cpu"`
40 LimitsMemory string `json:"limits.memory"`
41 RequestsCPU string `json:"requests.cpu"`
42 RequestsMemory string `json:"requests.memory"`
43 RequestsStorage string `json:"requests.storage"`
44 LimitsEphemeralStorage string `json:"limits.ephemeral.storage"`
45 PersistentVolumeClaims string `json:"persistentvolumeclaims"`
46 Pods string `json:"pods"`
47 ConfigMaps string `json:"configmaps"`
48 ReplicationControllers string `json:"replicationcontrollers"`
49 ResourceQuotas string `json:"resourcequotas"`
50 Services string `json:"services"`
51 ServicesLoadBalancers string `json:"services.loadbalancers"`
52 ServicesNodePorts string `json:"services.nodeports"`
53 Secrets string `json:"secrets"`
54 CountReplicationControllers string `json:"count/replicationcontrollers"`
55 CountDeploymentsApps string `json:"count/deployments.apps"`
56 CountReplicasetsApps string `json:"count/replicasets.apps"`
57 CountStatefulSets string `json:"count/statefulsets.apps"`
58 CountJobsBatch string `json:"count/jobs.batch"`
59 CountCronJobsBatch string `json:"count/cronjobs.batch"`
60 CountDeploymentsExtensions string `json:"count/deployments.extensions"`
63 // QuotaKey is the key structure that is used in the database
64 type QuotaKey struct {
65 Project string `json:"project"`
66 LogicalCloudName string `json:"logical-cloud-name"`
67 QuotaName string `json:"qname"`
70 // QuotaManager is an interface that exposes the connection
72 type QuotaManager interface {
73 CreateQuota(project, logicalCloud string, c Quota) (Quota, error)
74 GetQuota(project, logicalCloud, name string) (Quota, error)
75 GetAllQuotas(project, logicalCloud string) ([]Quota, error)
76 DeleteQuota(project, logicalCloud, name string) error
77 UpdateQuota(project, logicalCloud, name string, c Quota) (Quota, error)
80 // QuotaClient implements the QuotaManager
81 // It will also be used to maintain some localized state
82 type QuotaClient struct {
88 // QuotaClient returns an instance of the QuotaClient
89 // which implements the QuotaManager
90 func NewQuotaClient() *QuotaClient {
91 service := DBService{}
93 storeName: "orchestrator",
99 // Create entry for the quota resource in the database
100 func (v *QuotaClient) CreateQuota(project, logicalCloud string, c Quota) (Quota, error) {
102 //Construct key consisting of name
105 LogicalCloudName: logicalCloud,
106 QuotaName: c.MetaData.QuotaName,
109 //Check if project exists
110 err := v.util.CheckProject(project)
112 return Quota{}, pkgerrors.New("Unable to find the project")
114 //check if logical cloud exists
115 err = v.util.CheckLogicalCloud(project, logicalCloud)
117 return Quota{}, pkgerrors.New("Unable to find the logical cloud")
119 //Check if this Quota already exists
120 _, err = v.GetQuota(project, logicalCloud, c.MetaData.QuotaName)
122 return Quota{}, pkgerrors.New("Quota already exists")
125 err = v.util.DBInsert(v.storeName, key, nil, v.tagMeta, c)
127 return Quota{}, pkgerrors.Wrap(err, "Creating DB Entry")
133 // Get returns Quota for corresponding quota name
134 func (v *QuotaClient) GetQuota(project, logicalCloud, quotaName string) (Quota, error) {
136 //Construct the composite key to select the entry
139 LogicalCloudName: logicalCloud,
140 QuotaName: quotaName,
142 value, err := v.util.DBFind(v.storeName, key, v.tagMeta)
144 return Quota{}, pkgerrors.Wrap(err, "Quota")
147 //value is a byte array
150 err = v.util.DBUnmarshal(value[0], &q)
152 return Quota{}, pkgerrors.Wrap(err, "Unmarshaling value")
157 return Quota{}, pkgerrors.New("Cluster Quota does not exist")
160 // GetAll returns all cluster quotas in the logical cloud
161 func (v *QuotaClient) GetAllQuotas(project, logicalCloud string) ([]Quota, error) {
162 //Construct the composite key to select the entry
165 LogicalCloudName: logicalCloud,
169 values, err := v.util.DBFind(v.storeName, key, v.tagMeta)
171 return []Quota{}, pkgerrors.Wrap(err, "Get All Quotas")
174 for _, value := range values {
176 err = v.util.DBUnmarshal(value, &q)
178 return []Quota{}, pkgerrors.Wrap(err, "Unmarshaling value")
180 resp = append(resp, q)
186 // Delete the Quota entry from database
187 func (v *QuotaClient) DeleteQuota(project, logicalCloud, quotaName string) error {
188 //Construct the composite key to select the entry
191 LogicalCloudName: logicalCloud,
192 QuotaName: quotaName,
194 err := v.util.DBRemove(v.storeName, key)
196 return pkgerrors.Wrap(err, "Delete Quota")
201 // Update an entry for the Quota in the database
202 func (v *QuotaClient) UpdateQuota(project, logicalCloud, quotaName string, c Quota) (Quota, error) {
206 LogicalCloudName: logicalCloud,
207 QuotaName: quotaName,
209 //Check quota URL name against the quota json name
210 if c.MetaData.QuotaName != quotaName {
211 return Quota{}, pkgerrors.New("Update Error - Quota name mismatch")
213 //Check if this Quota exists
214 _, err := v.GetQuota(project, logicalCloud, quotaName)
216 return Quota{}, pkgerrors.New("Cluster Quota does not exist")
218 err = v.util.DBInsert(v.storeName, key, nil, v.tagMeta, c)
220 return Quota{}, pkgerrors.Wrap(err, "Updating DB Entry")