Skip to content

Commit 5e3f9ac

Browse files
authored
API Resource Quota return all storage classes if no quota is set for a namespace (#560)
1 parent 2305c05 commit 5e3f9ac

File tree

4 files changed

+181
-107
lines changed

4 files changed

+181
-107
lines changed

portal-ui/bindata_assetfs.go

Lines changed: 129 additions & 106 deletions
Large diffs are not rendered by default.

restapi/k8s_client.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"context"
2121

2222
v1 "k8s.io/api/core/v1"
23+
storagev1 "k8s.io/api/storage/v1"
2324
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2425
"k8s.io/client-go/kubernetes"
2526
)
@@ -29,6 +30,8 @@ import (
2930
// that are used within this project.
3031
type K8sClientI interface {
3132
getResourceQuota(ctx context.Context, namespace, resource string, opts metav1.GetOptions) (*v1.ResourceQuota, error)
33+
getNamespace(ctx context.Context, name string, opts metav1.GetOptions) (*v1.Namespace, error)
34+
getStorageClasses(ctx context.Context, opts metav1.ListOptions) (*storagev1.StorageClassList, error)
3235
getSecret(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*v1.Secret, error)
3336
getService(ctx context.Context, namespace, serviceName string, opts metav1.GetOptions) (*v1.Service, error)
3437
deletePodCollection(ctx context.Context, namespace string, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error
@@ -66,3 +69,11 @@ func (c *k8sClient) deleteSecret(ctx context.Context, namespace string, name str
6669
func (c *k8sClient) createSecret(ctx context.Context, namespace string, secret *v1.Secret, opts metav1.CreateOptions) (*v1.Secret, error) {
6770
return c.client.CoreV1().Secrets(namespace).Create(ctx, secret, opts)
6871
}
72+
73+
func (c *k8sClient) getNamespace(ctx context.Context, name string, opts metav1.GetOptions) (*v1.Namespace, error) {
74+
return c.client.CoreV1().Namespaces().Get(ctx, name, opts)
75+
}
76+
77+
func (c *k8sClient) getStorageClasses(ctx context.Context, opts metav1.ListOptions) (*storagev1.StorageClassList, error) {
78+
return c.client.StorageV1().StorageClasses().List(ctx, opts)
79+
}

restapi/resource_quota.go

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ package restapi
1818

1919
import (
2020
"context"
21+
"fmt"
22+
23+
"k8s.io/apimachinery/pkg/api/errors"
2124

2225
"github.com/minio/console/cluster"
2326

@@ -43,6 +46,30 @@ func registerResourceQuotaHandlers(api *operations.ConsoleAPI) {
4346
func getResourceQuota(ctx context.Context, client K8sClientI, namespace, resourcequota string) (*models.ResourceQuota, error) {
4447
resourceQuota, err := client.getResourceQuota(ctx, namespace, resourcequota, metav1.GetOptions{})
4548
if err != nil {
49+
// if there's no resource quotas
50+
if errors.IsNotFound(err) {
51+
// validate if at least the namespace is valid, if it is, return all storage classes with max capacity
52+
_, err := client.getNamespace(ctx, namespace, metav1.GetOptions{})
53+
if err != nil {
54+
return nil, err
55+
}
56+
storageClasses, err := client.getStorageClasses(ctx, metav1.ListOptions{})
57+
if err != nil {
58+
return nil, err
59+
}
60+
rq := models.ResourceQuota{Name: resourceQuota.Name}
61+
for _, sc := range storageClasses.Items {
62+
// Create Resource element with hard limit maxed out
63+
name := fmt.Sprintf("%s.storageclass.storage.k8s.io/requests.storage", sc.Name)
64+
element := models.ResourceQuotaElement{
65+
Name: name,
66+
Hard: 9223372036854775807,
67+
}
68+
rq.Elements = append(rq.Elements, &element)
69+
}
70+
return &rq, nil
71+
}
72+
4673
return nil, err
4774
}
4875
rq := models.ResourceQuota{Name: resourceQuota.Name}
@@ -78,7 +105,6 @@ func getResourceQuotaResponse(session *models.Principal, params admin_api.GetRes
78105
resourceQuota, err := getResourceQuota(ctx, k8sClient, params.Namespace, params.ResourceQuotaName)
79106
if err != nil {
80107
return nil, prepareError(err)
81-
82108
}
83109
return resourceQuota, nil
84110
}

restapi/resource_quota_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"reflect"
66
"testing"
77

8+
storagev1 "k8s.io/api/storage/v1"
9+
810
"errors"
911

1012
"github.com/minio/console/models"
@@ -16,12 +18,24 @@ import (
1618
type k8sClientMock struct{}
1719

1820
var k8sclientGetResourceQuotaMock func(ctx context.Context, namespace, resource string, opts metav1.GetOptions) (*v1.ResourceQuota, error)
21+
var k8sclientGetNameSpaceMock func(ctx context.Context, name string, opts metav1.GetOptions) (*v1.Namespace, error)
22+
var k8sclientStorageClassesMock func(ctx context.Context, opts metav1.ListOptions) (*storagev1.StorageClassList, error)
1923

2024
// mock functions
2125
func (c k8sClientMock) getResourceQuota(ctx context.Context, namespace, resource string, opts metav1.GetOptions) (*v1.ResourceQuota, error) {
2226
return k8sclientGetResourceQuotaMock(ctx, namespace, resource, opts)
2327
}
2428

29+
// mock functions
30+
func (c k8sClientMock) getNamespace(ctx context.Context, name string, opts metav1.GetOptions) (*v1.Namespace, error) {
31+
return k8sclientGetNameSpaceMock(ctx, name, opts)
32+
}
33+
34+
// mock functions
35+
func (c k8sClientMock) getStorageClasses(ctx context.Context, opts metav1.ListOptions) (*storagev1.StorageClassList, error) {
36+
return k8sclientStorageClassesMock(ctx, opts)
37+
}
38+
2539
func Test_ResourceQuota(t *testing.T) {
2640
mockHardResourceQuota := v1.ResourceList{
2741
"storage": resource.MustParse("1000"),

0 commit comments

Comments
 (0)