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"`
29 // MetaData contains the parameters needed for metadata
30 type QMetaDataList struct {
31 QuotaName string `json:"name"`
32 Description string `json:"description"`
35 // Spec contains the parameters needed for spec
37 LimitsCPU string `json:"limits.cpu"`
38 LimitsMemory string `json:"limits.memory"`
39 RequestsCPU string `json:"requests.cpu"`
40 RequestsMemory string `json:"requests.memory"`
41 RequestsStorage string `json:"requests.storage"`
42 LimitsEphemeralStorage string `json:"limits.ephemeral.storage"`
43 PersistentVolumeClaims string `json:"persistentvolumeclaims"`
44 Pods string `json:"pods"`
45 ConfigMaps string `json:"configmaps"`
46 ReplicationControllers string `json:"replicationcontrollers"`
47 ResourceQuotas string `json:"resourcequotas"`
48 Services string `json:"services"`
49 ServicesLoadBalancers string `json:"services.loadbalancers"`
50 ServicesNodePorts string `json:"services.nodeports"`
51 Secrets string `json:"secrets"`
52 CountReplicationControllers string `json:"count/replicationcontrollers"`
53 CountDeploymentsApps string `json:"count/deployments.apps"`
54 CountReplicasetsApps string `json:"count/replicasets.apps"`
55 CountStatefulSets string `json:"count/statefulsets.apps"`
56 CountJobsBatch string `json:"count/jobs.batch"`
57 CountCronJobsBatch string `json:"count/cronjobs.batch"`
58 CountDeploymentsExtensions string `json:"count/deployments.extensions"`
61 // QuotaKey is the key structure that is used in the database
62 type QuotaKey struct {
63 Project string `json:"project"`
64 LogicalCloudName string `json:"logical-cloud-name"`
65 QuotaName string `json:"qname"`
68 // QuotaManager is an interface that exposes the connection
70 type QuotaManager interface {
71 CreateQuota(project, logicalCloud string, c Quota) (Quota, error)
72 GetQuota(project, logicalCloud, name string) (Quota, error)
73 GetAllQuotas(project, logicalCloud string) ([]Quota, error)
74 DeleteQuota(project, logicalCloud, name string) error
75 UpdateQuota(project, logicalCloud, name string, c Quota) (Quota, error)
78 // QuotaClient implements the QuotaManager
79 // It will also be used to maintain some localized state
80 type QuotaClient struct {
86 // QuotaClient returns an instance of the QuotaClient
87 // which implements the QuotaManager
88 func NewQuotaClient() *QuotaClient {
89 service := DBService{}
91 storeName: "orchestrator",
97 // Create entry for the quota resource in the database
98 func (v *QuotaClient) CreateQuota(project, logicalCloud string, c Quota) (Quota, error) {
100 //Construct key consisting of name
103 LogicalCloudName: logicalCloud,
104 QuotaName: c.MetaData.QuotaName,
107 //Check if project exists
108 err := v.util.CheckProject(project)
110 return Quota{}, pkgerrors.New("Unable to find the project")
112 //check if logical cloud exists
113 err = v.util.CheckLogicalCloud(project, logicalCloud)
115 return Quota{}, pkgerrors.New("Unable to find the logical cloud")
117 //Check if this Quota already exists
118 _, err = v.GetQuota(project, logicalCloud, c.MetaData.QuotaName)
120 return Quota{}, pkgerrors.New("Quota already exists")
123 err = v.util.DBInsert(v.storeName, key, nil, v.tagMeta, c)
125 return Quota{}, pkgerrors.Wrap(err, "Creating DB Entry")
131 // Get returns Quota for corresponding quota name
132 func (v *QuotaClient) GetQuota(project, logicalCloud, quotaName string) (Quota, error) {
134 //Construct the composite key to select the entry
137 LogicalCloudName: logicalCloud,
138 QuotaName: quotaName,
140 value, err := v.util.DBFind(v.storeName, key, v.tagMeta)
142 return Quota{}, pkgerrors.Wrap(err, "Quota")
145 //value is a byte array
148 err = v.util.DBUnmarshal(value[0], &q)
150 return Quota{}, pkgerrors.Wrap(err, "Unmarshaling value")
155 return Quota{}, pkgerrors.New("Cluster Quota does not exist")
158 // GetAll returns all cluster quotas in the logical cloud
159 func (v *QuotaClient) GetAllQuotas(project, logicalCloud string) ([]Quota, error) {
160 //Construct the composite key to select the entry
163 LogicalCloudName: logicalCloud,
167 values, err := v.util.DBFind(v.storeName, key, v.tagMeta)
169 return []Quota{}, pkgerrors.Wrap(err, "Get All Quotas")
172 for _, value := range values {
174 err = v.util.DBUnmarshal(value, &q)
176 return []Quota{}, pkgerrors.Wrap(err, "Unmarshaling value")
178 resp = append(resp, q)
184 // Delete the Quota entry from database
185 func (v *QuotaClient) DeleteQuota(project, logicalCloud, quotaName string) error {
186 //Construct the composite key to select the entry
189 LogicalCloudName: logicalCloud,
190 QuotaName: quotaName,
192 err := v.util.DBRemove(v.storeName, key)
194 return pkgerrors.Wrap(err, "Delete Quota")
199 // Update an entry for the Quota in the database
200 func (v *QuotaClient) UpdateQuota(project, logicalCloud, quotaName string, c Quota) (Quota, error) {
204 LogicalCloudName: logicalCloud,
205 QuotaName: quotaName,
207 //Check quota URL name against the quota json name
208 if c.MetaData.QuotaName != quotaName {
209 return Quota{}, pkgerrors.New("Update Error - Quota name mismatch")
211 //Check if this Quota exists
212 _, err := v.GetQuota(project, logicalCloud, quotaName)
214 return Quota{}, pkgerrors.New("Cluster Quota does not exist")
216 err = v.util.DBInsert(v.storeName, key, nil, v.tagMeta, c)
218 return Quota{}, pkgerrors.Wrap(err, "Updating DB Entry")