Skip to content

Commit

Permalink
controllers: create VRCs
Browse files Browse the repository at this point in the history
Signed-off-by: raaizik <[email protected]>
  • Loading branch information
raaizik committed Nov 11, 2024
1 parent 13fdfb2 commit 4eb8312
Show file tree
Hide file tree
Showing 15 changed files with 936 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ metadata:
categories: Storage
console.openshift.io/plugins: '["odf-client-console"]'
containerImage: quay.io/ocs-dev/ocs-client-operator:latest
createdAt: "2024-11-10T14:44:36Z"
createdAt: "2024-11-11T14:29:17Z"
description: OpenShift Data Foundation client operator enables consumption of
storage services from a remote centralized OpenShift Data Foundation provider
cluster.
Expand Down Expand Up @@ -309,11 +309,8 @@ spec:
resources:
- drclusterconfigs
verbs:
- create
- delete
- get
- list
- update
- watch
- apiGroups:
- security.openshift.io
Expand Down
3 changes: 0 additions & 3 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -266,11 +266,8 @@ rules:
resources:
- drclusterconfigs
verbs:
- create
- delete
- get
- list
- update
- watch
- apiGroups:
- security.openshift.io
Expand Down
8 changes: 5 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.22.5
replace (
github.com/portworx/sched-ops => github.com/portworx/sched-ops v0.20.4-openstorage-rc3 // required by Rook v1.12
github.com/red-hat-storage/ocs-client-operator/api => ./api
k8s.io/client-go v12.0.0+incompatible => k8s.io/client-go v0.29.0
vbom.ml/util => github.com/fvbommel/util v0.0.0-20180919145318-efcd4e0f9787
)

Expand All @@ -19,18 +20,21 @@ exclude (

require (
github.com/ceph/ceph-csi-operator/api v0.0.0-20240812072523-4d50cf3a32a0
github.com/csi-addons/kubernetes-csi-addons v0.8.0
github.com/go-logr/logr v1.4.2
github.com/kubernetes-csi/external-snapshotter/client/v8 v8.0.0
github.com/onsi/ginkgo v1.16.5
github.com/onsi/gomega v1.34.1
github.com/openshift/api v0.0.0-20240828125535-01b3675ba7b3
github.com/operator-framework/api v0.27.0
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.76.0
github.com/ramendr/ramen/api v0.0.0-20241001141243-29d6f22ad237
github.com/ramendr/ramen/api v0.0.0-20241105140706-d8587766acb3
github.com/red-hat-storage/ocs-client-operator/api v0.0.0-00010101000000-000000000000
github.com/red-hat-storage/ocs-operator/services/provider/api/v4 v4.0.0-20241015071140-98c8184c6eec
github.com/stretchr/testify v1.9.0
google.golang.org/grpc v1.66.0
gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/api v0.31.0
k8s.io/apiextensions-apiserver v0.31.0
k8s.io/apimachinery v0.31.0
Expand All @@ -45,10 +49,8 @@ require (
github.com/klauspost/compress v1.17.9 // indirect
github.com/kube-object-storage/lib-bucket-provisioner v0.0.0-20221122204822-d1a8c34382f1 // indirect
github.com/openshift/custom-resource-status v1.1.3-0.20220503160415-f2fdb4999d87 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/x448/float16 v0.8.4 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/component-base v0.31.0 // indirect
sigs.k8s.io/container-object-storage-interface-api v0.1.0 // indirect
)
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/csi-addons/kubernetes-csi-addons v0.8.0 h1:zvYGp4DM6KdQzEX3dQSYKykqJdLZlxpVBJjtpbaqFjs=
github.com/csi-addons/kubernetes-csi-addons v0.8.0/go.mod h1:dvinzoiXlqdOGDpKkYx8Jxl507BzVEEEO+SI0OmBaRI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
Expand Down Expand Up @@ -323,8 +325,8 @@ github.com/prometheus/common v0.57.0 h1:Ro/rKjwdq9mZn1K5QPctzh+MA4Lp0BuYk5ZZEVho
github.com/prometheus/common v0.57.0/go.mod h1:7uRPFSUTbfZWsJ7MHY56sqt7hLQu3bxXHDnNhl8E9qI=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/ramendr/ramen/api v0.0.0-20241001141243-29d6f22ad237 h1:ig6ePD0yopC5Qi5BRmhsIsKaOkdsGXTSmG3HTYIpquo=
github.com/ramendr/ramen/api v0.0.0-20241001141243-29d6f22ad237/go.mod h1:nO6VM/+PEhcPGyFIQJdhY6ip822cA61PAy/s6IjenAA=
github.com/ramendr/ramen/api v0.0.0-20241105140706-d8587766acb3 h1:q4UjNvv3jzKOeG/S+S1Ms2FV3WajBIE6266/7BIxdX4=
github.com/ramendr/ramen/api v0.0.0-20241105140706-d8587766acb3/go.mod h1:O7VpTy8MMrh31DF4fv+2SZBSouAr8NlzIY4KYx7K75U=
github.com/red-hat-storage/ocs-operator/services/provider/api/v4 v4.0.0-20241015071140-98c8184c6eec h1:M64BdwKMV3jKxcRsZiaGbRKsvlbhRGVZgcb4V/MFeWk=
github.com/red-hat-storage/ocs-operator/services/provider/api/v4 v4.0.0-20241015071140-98c8184c6eec/go.mod h1:t9GJk69TGXABBF8fFPB+ImpbA9mJyRS86wW6+Qn8xHo=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
Expand Down
85 changes: 83 additions & 2 deletions internal/controller/storageclaim_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,20 @@ import (
"context"
"encoding/json"
"fmt"
"reflect"
"slices"
"strings"
"time"

"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/event"

v1alpha1 "github.com/red-hat-storage/ocs-client-operator/api/v1alpha1"
"github.com/red-hat-storage/ocs-client-operator/pkg/templates"
"github.com/red-hat-storage/ocs-client-operator/pkg/utils"

csiopv1a1 "github.com/ceph/ceph-csi-operator/api/v1alpha1"
replicationv1alpha1 "github.com/csi-addons/kubernetes-csi-addons/apis/replication.storage/v1alpha1"
"github.com/go-logr/logr"

snapapi "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1"
Expand Down Expand Up @@ -109,12 +114,44 @@ func (r *StorageClaimReconciler) SetupWithManager(mgr ctrl.Manager) error {
}); err != nil {
return fmt.Errorf("unable to set up FieldIndexer for VSC csi driver name: %v", err)
}
enqueueStorageClaim := handler.EnqueueRequestsFromMapFunc(
func(context context.Context, obj client.Object) []reconcile.Request {
sclaims := &v1alpha1.StorageClaimList{}
err := r.list(sclaims)
if err != nil {
r.log.Error(err, "Unable to list StorageClaim objects")
return []reconcile.Request{}
}

// Return name and namespace of the StorageClaim object
request := []reconcile.Request{}
for _, claim := range sclaims.Items {
request = append(request, reconcile.Request{
NamespacedName: types.NamespacedName{
Name: claim.Name,
},
})
}
return request
},
)

drClusterConfigPredicate := predicate.Funcs{
UpdateFunc: func(e event.UpdateEvent) bool {
if e.ObjectOld == nil || e.ObjectNew == nil {
return false
}
oldObj := e.ObjectOld.(*ramenv1alpha1.DRClusterConfig)
newObj := e.ObjectNew.(*ramenv1alpha1.DRClusterConfig)
return !reflect.DeepEqual(oldObj.Spec.ReplicationSchedules, newObj.Spec.ReplicationSchedules)
},
}
generationChangePredicate := predicate.GenerationChangedPredicate{}
bldr := ctrl.NewControllerManagedBy(mgr).
For(&v1alpha1.StorageClaim{}, builder.WithPredicates(generationChangePredicate)).
Owns(&storagev1.StorageClass{}).
Owns(&snapapi.VolumeSnapshotClass{}).
Owns(&replicationv1alpha1.VolumeReplicationClass{}, builder.WithPredicates(generationChangePredicate)).
Owns(&csiopv1a1.ClientProfile{}, builder.WithPredicates(generationChangePredicate)).
Watches(
&extv1.CustomResourceDefinition{},
Expand All @@ -127,7 +164,8 @@ func (r *StorageClaimReconciler) SetupWithManager(mgr ctrl.Manager) error {
)

if r.AvailableCrds[drClusterConfigCRDName] {
bldr = bldr.Owns(&ramenv1alpha1.DRClusterConfig{}, builder.WithPredicates(generationChangePredicate))
bldr = bldr.Watches(&ramenv1alpha1.DRClusterConfig{}, enqueueStorageClaim,
builder.WithPredicates(drClusterConfigPredicate))
}

return bldr.Complete(r)
Expand All @@ -141,8 +179,8 @@ func (r *StorageClaimReconciler) SetupWithManager(mgr ctrl.Manager) error {
//+kubebuilder:rbac:groups=snapshot.storage.k8s.io,resources=volumesnapshotclasses,verbs=get;list;watch;create;delete
//+kubebuilder:rbac:groups=core,resources=persistentvolumes,verbs=get;list;watch
//+kubebuilder:rbac:groups=snapshot.storage.k8s.io,resources=volumesnapshotcontents,verbs=get;list;watch
//+kubebuilder:rbac:groups=ramendr.openshift.io,resources=drclusterconfigs,verbs=get;list;watch
//+kubebuilder:rbac:groups=csi.ceph.io,resources=clientprofiles,verbs=get;list;update;create;watch;delete
//+kubebuilder:rbac:groups=ramendr.openshift.io,resources=drclusterconfigs,verbs=get;list;update;create;watch;delete

// Reconcile is part of the main kubernetes reconciliation loop which aims to
// move the current state of the cluster closer to the desired state.
Expand Down Expand Up @@ -424,6 +462,49 @@ func (r *StorageClaimReconciler) reconcilePhases() (reconcile.Result, error) {
if err != nil {
return reconcile.Result{}, fmt.Errorf("failed to create or update VolumeSnapshotClass: %s", err)
}
case "VolumeReplicationClass":
data := map[string]string{}
err = json.Unmarshal(resource.Data, &data)
if err != nil {
return reconcile.Result{}, fmt.Errorf("failed to unmarshal StorageClaim configuration response: %v", err)
}
var volumeReplicationClass, volumeReplicationClassFlattenMode *replicationv1alpha1.VolumeReplicationClass
data["replication.storage.openshift.io/replication-secret-namespace"] = r.OperatorNamespace
// generate a new clusterID for cephfs subvolumegroup, as
// storageclaim is clusterscoped resources using its
// hash as the clusterID
data["clusterID"] = r.storageClaimHash

volumeReplicationClass = &replicationv1alpha1.VolumeReplicationClass{
ObjectMeta: metav1.ObjectMeta{
Name: r.storageClaim.Name,
},
}
volumeReplicationClassFlattenMode = &replicationv1alpha1.VolumeReplicationClass{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("%s-flatten", r.storageClient.Name),
},
}
err = utils.CreateOrReplace(r.ctx, r.Client, volumeReplicationClass, func() error {
utils.AddLabels(volumeReplicationClass, resource.Labels)
utils.AddAnnotation(volumeReplicationClass, storageClaimAnnotation, r.storageClaim.Name)
utils.AddAnnotations(volumeReplicationClass, resource.Annotations)
volumeReplicationClass.Spec.Parameters = data
return nil
})
if err != nil {
return reconcile.Result{}, fmt.Errorf("failed to create or update VolumeReplicationClass: %s", err)
}
err = utils.CreateOrReplace(r.ctx, r.Client, volumeReplicationClassFlattenMode, func() error {
utils.AddLabels(volumeReplicationClassFlattenMode, resource.Labels)
utils.AddAnnotation(volumeReplicationClassFlattenMode, storageClaimAnnotation, r.storageClaim.Name)
utils.AddAnnotations(volumeReplicationClassFlattenMode, resource.Annotations)
volumeReplicationClassFlattenMode.Spec.Parameters = data
return nil
})
if err != nil {
return reconcile.Result{}, fmt.Errorf("failed to create or update VolumeReplicationClass for flatten mode: %s", err)
}
case "ClientProfile":
clientProfile := &csiopv1a1.ClientProfile{}
clientProfile.Name = r.storageClaimHash
Expand Down
10 changes: 10 additions & 0 deletions pkg/utils/k8sutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,16 @@ func AddAnnotation(obj metav1.Object, key string, value string) bool {
return false
}

// AddAnnotations adds values from newAnnotations to the keys on the supplied obj or overwrites values for existing keys on the obj
func AddAnnotations(obj metav1.Object, newAnnotations map[string]string) {
annotations := obj.GetAnnotations()
if annotations == nil {
annotations = map[string]string{}
obj.SetAnnotations(annotations)
}
maps.Copy(annotations, newAnnotations)
}

func GetMD5Hash(text string) string {
hash := md5.Sum([]byte(text))
return hex.EncodeToString(hash[:])
Expand Down
Loading

0 comments on commit 4eb8312

Please sign in to comment.