Skip to content

Commit 11aaa39

Browse files
committed
make clusterquota/status endpoint
1 parent 970b73a commit 11aaa39

File tree

13 files changed

+273
-24
lines changed

13 files changed

+273
-24
lines changed

api/swagger-spec/oapi-v1.json

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4589,6 +4589,147 @@
45894589
}
45904590
]
45914591
},
4592+
{
4593+
"path": "/oapi/v1/clusterresourcequotas/{name}/status",
4594+
"description": "OpenShift REST API, version v1",
4595+
"operations": [
4596+
{
4597+
"type": "v1.ClusterResourceQuota",
4598+
"method": "GET",
4599+
"summary": "read status of the specified ClusterResourceQuota",
4600+
"nickname": "readClusterResourceQuotaStatus",
4601+
"parameters": [
4602+
{
4603+
"type": "string",
4604+
"paramType": "query",
4605+
"name": "pretty",
4606+
"description": "If 'true', then the output is pretty printed.",
4607+
"required": false,
4608+
"allowMultiple": false
4609+
},
4610+
{
4611+
"type": "string",
4612+
"paramType": "path",
4613+
"name": "name",
4614+
"description": "name of the ClusterResourceQuota",
4615+
"required": true,
4616+
"allowMultiple": false
4617+
}
4618+
],
4619+
"responseMessages": [
4620+
{
4621+
"code": 200,
4622+
"message": "OK",
4623+
"responseModel": "v1.ClusterResourceQuota"
4624+
}
4625+
],
4626+
"produces": [
4627+
"application/json",
4628+
"application/yaml",
4629+
"application/vnd.kubernetes.protobuf"
4630+
],
4631+
"consumes": [
4632+
"*/*"
4633+
]
4634+
},
4635+
{
4636+
"type": "v1.ClusterResourceQuota",
4637+
"method": "PUT",
4638+
"summary": "replace status of the specified ClusterResourceQuota",
4639+
"nickname": "replaceClusterResourceQuotaStatus",
4640+
"parameters": [
4641+
{
4642+
"type": "string",
4643+
"paramType": "query",
4644+
"name": "pretty",
4645+
"description": "If 'true', then the output is pretty printed.",
4646+
"required": false,
4647+
"allowMultiple": false
4648+
},
4649+
{
4650+
"type": "v1.ClusterResourceQuota",
4651+
"paramType": "body",
4652+
"name": "body",
4653+
"description": "",
4654+
"required": true,
4655+
"allowMultiple": false
4656+
},
4657+
{
4658+
"type": "string",
4659+
"paramType": "path",
4660+
"name": "name",
4661+
"description": "name of the ClusterResourceQuota",
4662+
"required": true,
4663+
"allowMultiple": false
4664+
}
4665+
],
4666+
"responseMessages": [
4667+
{
4668+
"code": 200,
4669+
"message": "OK",
4670+
"responseModel": "v1.ClusterResourceQuota"
4671+
}
4672+
],
4673+
"produces": [
4674+
"application/json",
4675+
"application/yaml",
4676+
"application/vnd.kubernetes.protobuf"
4677+
],
4678+
"consumes": [
4679+
"*/*"
4680+
]
4681+
},
4682+
{
4683+
"type": "v1.ClusterResourceQuota",
4684+
"method": "PATCH",
4685+
"summary": "partially update status of the specified ClusterResourceQuota",
4686+
"nickname": "patchClusterResourceQuotaStatus",
4687+
"parameters": [
4688+
{
4689+
"type": "string",
4690+
"paramType": "query",
4691+
"name": "pretty",
4692+
"description": "If 'true', then the output is pretty printed.",
4693+
"required": false,
4694+
"allowMultiple": false
4695+
},
4696+
{
4697+
"type": "unversioned.Patch",
4698+
"paramType": "body",
4699+
"name": "body",
4700+
"description": "",
4701+
"required": true,
4702+
"allowMultiple": false
4703+
},
4704+
{
4705+
"type": "string",
4706+
"paramType": "path",
4707+
"name": "name",
4708+
"description": "name of the ClusterResourceQuota",
4709+
"required": true,
4710+
"allowMultiple": false
4711+
}
4712+
],
4713+
"responseMessages": [
4714+
{
4715+
"code": 200,
4716+
"message": "OK",
4717+
"responseModel": "v1.ClusterResourceQuota"
4718+
}
4719+
],
4720+
"produces": [
4721+
"application/json",
4722+
"application/yaml",
4723+
"application/vnd.kubernetes.protobuf"
4724+
],
4725+
"consumes": [
4726+
"application/json-patch+json",
4727+
"application/merge-patch+json",
4728+
"application/strategic-merge-patch+json"
4729+
]
4730+
}
4731+
]
4732+
},
45924733
{
45934734
"path": "/oapi/v1/clusterrolebindings",
45944735
"description": "OpenShift REST API, version v1",

pkg/client/clusteresourcequota.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ type ClusterResourceQuotaInterface interface {
1818
Update(resourceQuota *quotaapi.ClusterResourceQuota) (*quotaapi.ClusterResourceQuota, error)
1919
Delete(name string) error
2020
Watch(opts kapi.ListOptions) (watch.Interface, error)
21+
22+
UpdateStatus(resourceQuota *quotaapi.ClusterResourceQuota) (*quotaapi.ClusterResourceQuota, error)
2123
}
2224

2325
type clusterResourceQuotas struct {
@@ -63,3 +65,9 @@ func (c *clusterResourceQuotas) Delete(name string) (err error) {
6365
func (c *clusterResourceQuotas) Watch(opts kapi.ListOptions) (watch.Interface, error) {
6466
return c.r.Get().Prefix("watch").Resource("clusterresourcequotas").VersionedParams(&opts, kapi.ParameterCodec).Watch()
6567
}
68+
69+
func (c *clusterResourceQuotas) UpdateStatus(resourceQuota *quotaapi.ClusterResourceQuota) (result *quotaapi.ClusterResourceQuota, err error) {
70+
result = &quotaapi.ClusterResourceQuota{}
71+
err = c.r.Put().Resource("clusterresourcequotas").Name(resourceQuota.Name).SubResource("status").Body(resourceQuota).Do().Into(result)
72+
return
73+
}

pkg/client/testclient/fake_clusterresourcequota.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,19 @@ func (c *FakeClusterResourceQuotas) Delete(name string) error {
5757
func (c *FakeClusterResourceQuotas) Watch(opts kapi.ListOptions) (watch.Interface, error) {
5858
return c.Fake.InvokesWatch(ktestclient.NewRootWatchAction("clusterresourcequotas", opts))
5959
}
60+
61+
func (c *FakeClusterResourceQuotas) UpdateStatus(inObj *quotaapi.ClusterResourceQuota) (*quotaapi.ClusterResourceQuota, error) {
62+
action := ktestclient.UpdateActionImpl{}
63+
action.Verb = "update"
64+
action.Resource = "clusterresourcequotas"
65+
action.Subresource = "status"
66+
action.Object = inObj
67+
68+
obj, err := c.Fake.Invokes(action, inObj)
69+
if obj == nil {
70+
return nil, err
71+
}
72+
73+
return obj.(*quotaapi.ClusterResourceQuota), err
74+
75+
}

pkg/cmd/server/bootstrappolicy/policy.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,7 @@ func GetBootstrapClusterRoles() []authorizationapi.ClusterRole {
139139

140140
authorizationapi.NewRule(read...).Groups(projectGroup).Resources("projectrequests", "projects").RuleOrDie(),
141141

142-
authorizationapi.NewRule(read...).Groups(quotaGroup).Resources("appliedclusterresourcequotas").RuleOrDie(),
143-
144-
authorizationapi.NewRule(read...).Groups(quotaGroup).Resources("clusterresourcequotas").RuleOrDie(),
142+
authorizationapi.NewRule(read...).Groups(quotaGroup).Resources("appliedclusterresourcequotas", "clusterresourcequotas", "clusterresourcequotas/status").RuleOrDie(),
145143

146144
authorizationapi.NewRule(read...).Groups(routeGroup).Resources("routes", "routes/status").RuleOrDie(),
147145

pkg/cmd/server/origin/helpers.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,10 @@ func restInPeace(s rest.StandardStorage, err error) rest.StandardStorage {
1313
}
1414
return s
1515
}
16+
17+
func updateInPeace(s rest.Updater, err error) rest.Updater {
18+
if err != nil {
19+
glog.Fatal(err)
20+
}
21+
return s
22+
}

pkg/cmd/server/origin/master.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,8 @@ func (c *MasterConfig) GetRestStorage() map[string]rest.Storage {
618618
"clusterRoleBindings": clusterRoleBindingStorage,
619619
"clusterRoles": clusterRoleStorage,
620620

621-
"clusterResourceQuotas": restInPeace(clusterresourcequotaregistry.NewStorage(c.RESTOptionsGetter)),
621+
"clusterResourceQuotas": restInPeace(clusterresourcequotaregistry.NewStorage(c.RESTOptionsGetter)),
622+
"clusterResourceQuotas/status": updateInPeace(clusterresourcequotaregistry.NewStatusStorage(c.RESTOptionsGetter)),
622623
"appliedClusterResourceQuotas": appliedclusterresourcequotaregistry.NewREST(
623624
c.ClusterQuotaMappingController.GetClusterQuotaMapper(), c.Informers.ClusterResourceQuotas().Lister(), c.Informers.Namespaces().Lister()),
624625
}

pkg/quota/admission/clusterresourcequota/accessor.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ func (e *clusterQuotaAccessor) UpdateQuotaStatus(newQuota *kapi.ResourceQuota) e
8282
newNamespaceTotals.Used = utilquota.Add(oldNamespaceTotals.Used, usageDiff)
8383
clusterQuota.Status.Namespaces.Insert(newQuota.Namespace, newNamespaceTotals)
8484

85-
updatedQuota, err := e.clusterQuotaClient.ClusterResourceQuotas().Update(clusterQuota)
85+
updatedQuota, err := e.clusterQuotaClient.ClusterResourceQuotas().UpdateStatus(clusterQuota)
8686
if err != nil {
8787
return err
8888
}

pkg/quota/admission/clusterresourcequota/accessor_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,11 @@ func TestUpdateQuota(t *testing.T) {
123123

124124
var actualQuota *quotaapi.ClusterResourceQuota
125125
for _, action := range client.Actions() {
126-
updateAction, ok := action.(ktestclient.UpdateAction)
126+
updateAction, ok := action.(ktestclient.UpdateActionImpl)
127127
if !ok {
128128
continue
129129
}
130-
if updateAction.Matches("update", "clusterresourcequotas") {
130+
if updateAction.Matches("update", "clusterresourcequotas") && updateAction.Subresource == "status" {
131131
actualQuota = updateAction.GetObject().(*quotaapi.ClusterResourceQuota)
132132
break
133133
}

pkg/quota/controller/clusterquotareconciliation/reconcilation_controller.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,8 +291,7 @@ func (c *ClusterQuotaReconcilationController) syncQuotaForNamespaces(originalQuo
291291
return kutilerrors.NewAggregate(reconcilationErrors), retryItems
292292
}
293293

294-
// TODO separate out status updating
295-
if _, err := c.clusterQuotaClient.ClusterResourceQuotas().Update(quota); err != nil {
294+
if _, err := c.clusterQuotaClient.ClusterResourceQuotas().UpdateStatus(quota); err != nil {
296295
return kutilerrors.NewAggregate(append(reconcilationErrors, err)), workItems
297296
}
298297

pkg/quota/controller/clusterquotareconciliation/reconciliation_controller_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,11 +249,11 @@ func TestSyncFunc(t *testing.T) {
249249

250250
var actualQuota *quotaapi.ClusterResourceQuota
251251
for _, action := range client.Actions() {
252-
updateAction, ok := action.(ktestclient.UpdateAction)
252+
updateAction, ok := action.(ktestclient.UpdateActionImpl)
253253
if !ok {
254254
continue
255255
}
256-
if updateAction.Matches("update", "clusterresourcequotas") {
256+
if updateAction.Matches("update", "clusterresourcequotas") && updateAction.Subresource == "status" {
257257
actualQuota = updateAction.GetObject().(*quotaapi.ClusterResourceQuota)
258258
break
259259
}

pkg/quota/registry/clusterresourcequota/etcd.go

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package clusterresourcequota
22

33
import (
44
kapi "k8s.io/kubernetes/pkg/api"
5+
"k8s.io/kubernetes/pkg/api/rest"
56
"k8s.io/kubernetes/pkg/fields"
67
"k8s.io/kubernetes/pkg/labels"
78
"k8s.io/kubernetes/pkg/registry/generic"
@@ -21,6 +22,46 @@ type REST struct {
2122

2223
// NewStorage returns a RESTStorage object that will work against nodes.
2324
func NewStorage(optsGetter restoptions.Getter) (*REST, error) {
25+
store, err := makeStore(optsGetter)
26+
if err != nil {
27+
return nil, err
28+
}
29+
30+
return &REST{Store: store}, nil
31+
}
32+
33+
func NewStatusStorage(optsGetter restoptions.Getter) (*StatusREST, error) {
34+
store, err := makeStore(optsGetter)
35+
if err != nil {
36+
return nil, err
37+
}
38+
store.CreateStrategy = nil
39+
store.DeleteStrategy = nil
40+
store.UpdateStrategy = StatusStrategy
41+
42+
return &StatusREST{store: store}, nil
43+
}
44+
45+
// StatusREST implements the REST endpoint for changing the status of a resourcequota.
46+
type StatusREST struct {
47+
store *registry.Store
48+
}
49+
50+
func (r *StatusREST) New() runtime.Object {
51+
return &quotaapi.ClusterResourceQuota{}
52+
}
53+
54+
// Get retrieves the object from the storage. It is required to support Patch.
55+
func (r *StatusREST) Get(ctx kapi.Context, name string) (runtime.Object, error) {
56+
return r.store.Get(ctx, name)
57+
}
58+
59+
// Update alters the status subset of an object.
60+
func (r *StatusREST) Update(ctx kapi.Context, name string, objInfo rest.UpdatedObjectInfo) (runtime.Object, bool, error) {
61+
return r.store.Update(ctx, name, objInfo)
62+
}
63+
64+
func makeStore(optsGetter restoptions.Getter) (*registry.Store, error) {
2465
store := &registry.Store{
2566
NewFunc: func() runtime.Object { return &quotaapi.ClusterResourceQuota{} },
2667
NewListFunc: func() runtime.Object { return &quotaapi.ClusterResourceQuotaList{} },
@@ -48,5 +89,5 @@ func NewStorage(optsGetter restoptions.Getter) (*REST, error) {
4889
return nil, err
4990
}
5091

51-
return &REST{store}, nil
92+
return store, nil
5293
}

0 commit comments

Comments
 (0)