Skip to content

Commit

Permalink
Sending ClusterResourceQuota in ExternalResource
Browse files Browse the repository at this point in the history
Signed-off-by: rchikatw <[email protected]>
  • Loading branch information
rchikatw committed Jul 20, 2024
1 parent f62ae00 commit 7ecef44
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 3 deletions.
36 changes: 34 additions & 2 deletions services/provider/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,16 @@ import (
"time"

"github.com/blang/semver/v4"
quotav1 "github.com/openshift/api/quota/v1"
"github.com/red-hat-storage/ocs-operator/api/v4/v1alpha1"
ocsv1alpha1 "github.com/red-hat-storage/ocs-operator/api/v4/v1alpha1"
controllers "github.com/red-hat-storage/ocs-operator/v4/controllers/storageconsumer"
"github.com/red-hat-storage/ocs-operator/v4/controllers/util"
pb "github.com/red-hat-storage/ocs-operator/v4/services/provider/pb"
ocsVersion "github.com/red-hat-storage/ocs-operator/v4/version"
rookCephv1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

opv1a1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
"github.com/red-hat-storage/ocs-operator/v4/services"
Expand Down Expand Up @@ -369,6 +372,34 @@ func (s *OCSProviderServer) getExternalResources(ctx context.Context, consumerRe
}),
})

if consumerResource.Spec.StorageQuotaInGiB > 0 {
clusterResourceQuotaSpec := &quotav1.ClusterResourceQuotaSpec{
Selector: quotav1.ClusterResourceQuotaSelector{
LabelSelector: &metav1.LabelSelector{
MatchExpressions: []metav1.LabelSelectorRequirement{
{
Key: string(consumerResource.UID),
Operator: metav1.LabelSelectorOpDoesNotExist,
},
},
},
},
Quota: corev1.ResourceQuotaSpec{
Hard: corev1.ResourceList{"requests.storage": *resource.NewScaledQuantity(
int64(consumerResource.Spec.StorageQuotaInGiB),
resource.Giga,
)},
},
}

extR = append(extR, &pb.ExternalResource{
Name: "QuotaForConsumer",
Kind: "ClusterResourceQuota",
Data: mustMarshal(clusterResourceQuotaSpec),
})

}

return extR, nil
}

Expand Down Expand Up @@ -420,13 +451,14 @@ func (s *OCSProviderServer) getOnboardingValidationKey(ctx context.Context) (*rs
return publicKey, nil
}

func mustMarshal(data map[string]string) []byte {
newData, err := json.Marshal(data)
func mustMarshal[T any](value T) []byte {
newData, err := json.Marshal(value)
if err != nil {
panic("failed to marshal")
}
return newData
}

func getSubVolumeGroupClusterID(subVolumeGroup *rookCephv1.CephFilesystemSubVolumeGroup) string {
str := fmt.Sprintf(
"%s-%s-file-%s",
Expand Down
79 changes: 78 additions & 1 deletion services/provider/server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@ import (
"strconv"
"testing"

quotav1 "github.com/openshift/api/quota/v1"
ocsv1alpha1 "github.com/red-hat-storage/ocs-operator/api/v4/v1alpha1"
controllers "github.com/red-hat-storage/ocs-operator/v4/controllers/storageconsumer"
pb "github.com/red-hat-storage/ocs-operator/v4/services/provider/pb"
rookCephv1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1"
"github.com/stretchr/testify/assert"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
corev1 "k8s.io/api/core/v1"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
crClient "sigs.k8s.io/controller-runtime/pkg/client"
Expand All @@ -27,7 +30,24 @@ type externalResource struct {
}

var serverNamespace = "openshift-storage"

var clusterResourceQuotaSpec = &quotav1.ClusterResourceQuotaSpec{
Selector: quotav1.ClusterResourceQuotaSelector{
LabelSelector: &metav1.LabelSelector{
MatchExpressions: []metav1.LabelSelectorRequirement{
{
Key: "consumer-test",
Operator: metav1.LabelSelectorOpDoesNotExist,
},
},
},
},
Quota: corev1.ResourceQuotaSpec{
Hard: corev1.ResourceList{"requests.storage": *resource.NewScaledQuantity(
int64(consumerResource.Spec.StorageQuotaInGiB),
resource.Giga,
)},
},
}
var mockExtR = map[string]*externalResource{
"rook-ceph-mon-endpoints": {
Name: "rook-ceph-mon-endpoints",
Expand Down Expand Up @@ -64,6 +84,13 @@ var mockExtR = map[string]*externalResource{
"userKey": "AQADw/hhqBOcORAAJY3fKIvte++L/zYhASjYPQ==",
},
},
"QuotaForConsumer": {
Name: "QuotaForConsumer",
Kind: "ClusterResourceQuota",
Data: map[string]string{
"QuotaForConsumer": fmt.Sprintf("%+v\n", clusterResourceQuotaSpec),
},
},
}

var (
Expand Down Expand Up @@ -135,6 +162,26 @@ var (
State: ocsv1alpha1.StorageConsumerStateReady,
},
}

consumerResource6 = &ocsv1alpha1.StorageConsumer{
ObjectMeta: metav1.ObjectMeta{
Name: "consumer6",
UID: "uid6",
Namespace: serverNamespace,
},
Spec: ocsv1alpha1.StorageConsumerSpec{
StorageQuotaInGiB: 10240,
},
Status: ocsv1alpha1.StorageConsumerStatus{
CephResources: []*ocsv1alpha1.CephResourcesSpec{
{
Name: "995e66248ad3e8642de868f461cdd827",
Kind: "CephClient",
},
},
State: ocsv1alpha1.StorageConsumerStateReady,
},
}
)

func TestGetExternalResources(t *testing.T) {
Expand All @@ -146,6 +193,7 @@ func TestGetExternalResources(t *testing.T) {
consumerResource3,
consumerResource4,
consumerResource5,
consumerResource6,
}

client := newFakeClient(t, objects...)
Expand Down Expand Up @@ -229,6 +277,35 @@ func TestGetExternalResources(t *testing.T) {
assert.Equal(t, extResource.Name, mockResoruce.Name)
}

// When ocsv1alpha1.StorageConsumerStateReady and quota is set
req = pb.StorageConfigRequest{
StorageConsumerUUID: string(consumerResource6.UID),
}
storageConRes, err = server.GetStorageConfig(ctx, &req)
assert.NoError(t, err)
assert.NotNil(t, storageConRes)

for i := range storageConRes.ExternalResource {
extResource := storageConRes.ExternalResource[i]
mockResoruce, ok := mockExtR[extResource.Name]
assert.True(t, ok)

data, err := json.Marshal(mockResoruce.Data)
assert.NoError(t, err)
if extResource.Kind == "ClusterResourceQuota" {
var clusterResourceQuotaSpec quotav1.ClusterResourceQuotaSpec
err = json.Unmarshal([]byte(extResource.Data), &clusterResourceQuotaSpec)
assert.NoError(t, err)
quantity, _ := resource.ParseQuantity("10240G")
assert.Equal(t, clusterResourceQuotaSpec.Quota.Hard["requests.storage"], quantity)
} else {
assert.Equal(t, string(extResource.Data), string(data))
}

assert.Equal(t, extResource.Kind, mockResoruce.Kind)
assert.Equal(t, extResource.Name, mockResoruce.Name)
}

// When ocsv1alpha1.StorageConsumerStateReady but ceph resources is empty
req.StorageConsumerUUID = string(consumerResource5.UID)
storageConRes, err = server.GetStorageConfig(ctx, &req)
Expand Down

0 comments on commit 7ecef44

Please sign in to comment.