Skip to content

Commit 63d1586

Browse files
committed
controllers: Generates VGSClass
Signed-off-by: raaizik <[email protected]>
1 parent 484006e commit 63d1586

File tree

7 files changed

+936
-0
lines changed

7 files changed

+936
-0
lines changed

config/rbac/role.yaml

+10
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,16 @@ rules:
133133
- get
134134
- list
135135
- watch
136+
- apiGroups:
137+
- groupsnapshot.storage.k8s.io
138+
resources:
139+
- volumegroupsnapshotclasses
140+
verbs:
141+
- create
142+
- delete
143+
- get
144+
- list
145+
- watch
136146
- apiGroups:
137147
- monitoring.coreos.com
138148
resources:

controllers/storageclaim_controller.go

+87
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
"github.com/red-hat-storage/ocs-client-operator/pkg/utils"
3333

3434
"github.com/go-logr/logr"
35+
groupsnapapi "github.com/kubernetes-csi/external-snapshotter/client/v6/apis/volumegroupsnapshot/v1alpha1"
3536
snapapi "github.com/kubernetes-csi/external-snapshotter/client/v6/apis/volumesnapshot/v1"
3637
providerclient "github.com/red-hat-storage/ocs-operator/v4/services/provider/client"
3738
corev1 "k8s.io/api/core/v1"
@@ -110,6 +111,7 @@ func (r *StorageClaimReconciler) SetupWithManager(mgr ctrl.Manager) error {
110111
For(&v1alpha1.StorageClaim{}, builder.WithPredicates(predicate.GenerationChangedPredicate{})).
111112
Owns(&storagev1.StorageClass{}).
112113
Owns(&snapapi.VolumeSnapshotClass{}).
114+
Owns(&groupsnapapi.VolumeGroupSnapshotClass{}).
113115
Complete(r)
114116
}
115117

@@ -119,6 +121,7 @@ func (r *StorageClaimReconciler) SetupWithManager(mgr ctrl.Manager) error {
119121
//+kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch;create;update;delete
120122
//+kubebuilder:rbac:groups=storage.k8s.io,resources=storageclasses,verbs=get;list;watch;create;update;patch;delete
121123
//+kubebuilder:rbac:groups=snapshot.storage.k8s.io,resources=volumesnapshotclasses,verbs=get;list;watch;create;delete
124+
//+kubebuilder:rbac:groups=groupsnapshot.storage.k8s.io,resources=volumegroupsnapshotclasses,verbs=get;list;watch;create;delete
122125
//+kubebuilder:rbac:groups=core,resources=persistentvolumes,verbs=get;list;watch
123126
//+kubebuilder:rbac:groups=snapshot.storage.k8s.io,resources=volumesnapshotcontents,verbs=get;list;watch
124127

@@ -327,12 +330,14 @@ func (r *StorageClaimReconciler) reconcilePhases() (reconcile.Result, error) {
327330
// Go over the received objects and operate on them accordingly.
328331
for _, resource := range resources {
329332
data := map[string]string{}
333+
labels := map[string]string{}
330334
err = json.Unmarshal(resource.Data, &data)
331335
if err != nil {
332336
return reconcile.Result{}, fmt.Errorf("failed to unmarshal StorageClaim configuration response: %v", err)
333337
}
334338

335339
// Create the received resources, if necessary.
340+
storageID := getMD5Hash(string(r.storageClaim.UID)) + r.storageClaimHash
336341
switch resource.Kind {
337342
case "Secret":
338343
secret := &corev1.Secret{}
@@ -398,6 +403,8 @@ func (r *StorageClaimReconciler) reconcilePhases() (reconcile.Result, error) {
398403
// storageclaim is clusterscoped resources using its
399404
// hash as the clusterID
400405
data["clusterID"] = r.storageClaimHash
406+
labels["ramendr.openshift.io/replicationID"] = r.storageClaimHash
407+
labels["ramendr.openshift.io/storageID"] = storageID
401408
if resource.Name == "cephfs" {
402409
volumeSnapshotClass = r.getCephFSVolumeSnapshotClass(data)
403410
} else if resource.Name == "ceph-rbd" {
@@ -407,6 +414,24 @@ func (r *StorageClaimReconciler) reconcilePhases() (reconcile.Result, error) {
407414
if err := r.createOrReplaceVolumeSnapshotClass(volumeSnapshotClass); err != nil {
408415
return reconcile.Result{}, fmt.Errorf("failed to create or update VolumeSnapshotClass: %s", err)
409416
}
417+
case "VolumeGroupSnapshotClass":
418+
var volumeGroupSnapshotClass *groupsnapapi.VolumeGroupSnapshotClass
419+
data["csi.storage.k8s.io/snapshotter-secret-namespace"] = r.OperatorNamespace
420+
// generate a new clusterID for cephfs subvolumegroup, as
421+
// storageclaim is clusterscoped resources using its
422+
// hash as the clusterID
423+
data["clusterID"] = r.storageClaimHash
424+
labels["ramendr.openshift.io/replicationID"] = r.storageClaimHash
425+
labels["ramendr.openshift.io/storageID"] = storageID
426+
if resource.Name == "cephfs" {
427+
volumeGroupSnapshotClass = r.getCephFSVolumeGroupSnapshotClass(data, labels)
428+
} else if resource.Name == "ceph-rbd" {
429+
volumeGroupSnapshotClass = r.getCephRBDVolumeGroupSnapshotClass(data, labels)
430+
}
431+
utils.AddAnnotation(volumeGroupSnapshotClass, storageClaimAnnotation, r.storageClaim.Name)
432+
if err := r.createOrReplaceVolumeGroupSnapshotClass(volumeGroupSnapshotClass); err != nil {
433+
return reconcile.Result{}, fmt.Errorf("failed to create or update volumeGroupSnapshot: %s", err)
434+
}
410435
}
411436
}
412437

@@ -651,6 +676,68 @@ func (r *StorageClaimReconciler) hasVolumeSnapshotContents() (bool, error) {
651676
return false, nil
652677
}
653678

679+
func (r *StorageClaimReconciler) getCephFSVolumeGroupSnapshotClass(data map[string]string, labels map[string]string) *groupsnapapi.VolumeGroupSnapshotClass {
680+
volumgroupesnapshotclass := &groupsnapapi.VolumeGroupSnapshotClass{
681+
ObjectMeta: metav1.ObjectMeta{
682+
Name: r.storageClaim.Name,
683+
Labels: labels,
684+
},
685+
Driver: csi.GetCephFSDriverName(),
686+
DeletionPolicy: snapapi.VolumeSnapshotContentDelete,
687+
Parameters: data,
688+
}
689+
return volumgroupesnapshotclass
690+
}
691+
692+
func (r *StorageClaimReconciler) getCephRBDVolumeGroupSnapshotClass(data map[string]string, labels map[string]string) *groupsnapapi.VolumeGroupSnapshotClass {
693+
volumegroupsnapshotclass := &groupsnapapi.VolumeGroupSnapshotClass{
694+
ObjectMeta: metav1.ObjectMeta{
695+
Name: r.storageClaim.Name,
696+
Labels: labels,
697+
},
698+
Driver: csi.GetRBDDriverName(),
699+
DeletionPolicy: snapapi.VolumeSnapshotContentDelete,
700+
Parameters: data,
701+
}
702+
return volumegroupsnapshotclass
703+
}
704+
705+
func (r *StorageClaimReconciler) createOrReplaceVolumeGroupSnapshotClass(volumeGroupSnapshotClass *groupsnapapi.VolumeGroupSnapshotClass) error {
706+
existing := &groupsnapapi.VolumeGroupSnapshotClass{}
707+
existing.Name = r.storageClaim.Name
708+
709+
if err := r.own(volumeGroupSnapshotClass); err != nil {
710+
return fmt.Errorf("failed to own volumegroupsnapshotclass: %v", err)
711+
}
712+
713+
if err := r.get(existing); err != nil && !errors.IsNotFound(err) {
714+
return fmt.Errorf("failed to get VolumeGroupSnapshotClass: %v", err)
715+
}
716+
717+
// If present then compare the existing VolumeGroupSnapshotClass parameters with
718+
// the received VolumeGroupSnapshotClass parameters, and only proceed if they differ.
719+
if reflect.DeepEqual(existing.Parameters, volumeGroupSnapshotClass.Parameters) {
720+
return nil
721+
}
722+
723+
// VolumeGroupSnapshotClass already exists, but parameters have changed. Delete the existing VolumeGroupSnapshotClass and create a new one.
724+
if existing.UID != "" {
725+
// Since we have to update the existing VolumeGroupSnapshotClass, so we will delete the existing VolumeGroupSnapshotClass and create a new one.
726+
r.log.Info("VolumeGroupSnapshotClass needs to be updated, deleting it.", "Name", existing.Name)
727+
728+
// Delete the VolumeGroupSnapshotClass.
729+
if err := r.delete(existing); err != nil {
730+
r.log.Error(err, "Failed to delete VolumeGroupSnapshotClass.", "Name", existing.Name)
731+
return fmt.Errorf("failed to delete VolumeGroupSnapshotClass: %v", err)
732+
}
733+
}
734+
r.log.Info("Creating VolumeGroupSnapshotClass.", "Name", existing.Name)
735+
if err := r.Client.Create(r.ctx, volumeGroupSnapshotClass); err != nil {
736+
return fmt.Errorf("failed to create VolumeGroupSnapshotClass: %v", err)
737+
}
738+
return nil
739+
}
740+
654741
func getMD5Hash(text string) string {
655742
hash := md5.Sum([]byte(text))
656743
return hex.EncodeToString(hash[:])

vendor/github.com/kubernetes-csi/external-snapshotter/client/v6/apis/volumegroupsnapshot/v1alpha1/doc.go

+20
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/kubernetes-csi/external-snapshotter/client/v6/apis/volumegroupsnapshot/v1alpha1/register.go

+57
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)