Skip to content

Commit 099b7a8

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

File tree

7 files changed

+945
-6
lines changed

7 files changed

+945
-6
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

+96-6
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,11 +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

339+
// SID for RamenDR
340+
storageID := getMD5Hash(string(r.storageClaim.UID)) + r.storageClaimHash
335341
// Create the received resources, if necessary.
336342
switch resource.Kind {
337343
case "Secret":
@@ -398,15 +404,35 @@ func (r *StorageClaimReconciler) reconcilePhases() (reconcile.Result, error) {
398404
// storageclaim is clusterscoped resources using its
399405
// hash as the clusterID
400406
data["clusterID"] = r.storageClaimHash
407+
labels["ramendr.openshift.io/replicationID"] = r.storageClaimHash
408+
labels["ramendr.openshift.io/storageID"] = storageID
401409
if resource.Name == "cephfs" {
402-
volumeSnapshotClass = r.getCephFSVolumeSnapshotClass(data)
410+
volumeSnapshotClass = r.getCephFSVolumeSnapshotClass(data, labels)
403411
} else if resource.Name == "ceph-rbd" {
404-
volumeSnapshotClass = r.getCephRBDVolumeSnapshotClass(data)
412+
volumeSnapshotClass = r.getCephRBDVolumeSnapshotClass(data, labels)
405413
}
406414
utils.AddAnnotation(volumeSnapshotClass, storageClaimAnnotation, r.storageClaim.Name)
407415
if err := r.createOrReplaceVolumeSnapshotClass(volumeSnapshotClass); err != nil {
408416
return reconcile.Result{}, fmt.Errorf("failed to create or update VolumeSnapshotClass: %s", err)
409417
}
418+
case "VolumeGroupSnapshotClass":
419+
var volumeGroupSnapshotClass *groupsnapapi.VolumeGroupSnapshotClass
420+
data["csi.storage.k8s.io/snapshotter-secret-namespace"] = r.OperatorNamespace
421+
// generate a new clusterID for cephfs subvolumegroup, as
422+
// storageclaim is clusterscoped resources using its
423+
// hash as the clusterID
424+
data["clusterID"] = r.storageClaimHash
425+
labels["ramendr.openshift.io/replicationID"] = r.storageClaimHash
426+
labels["ramendr.openshift.io/storageID"] = storageID
427+
if resource.Name == "cephfs" {
428+
volumeGroupSnapshotClass = r.getCephFSVolumeGroupSnapshotClass(data, labels)
429+
} else if resource.Name == "ceph-rbd" {
430+
volumeGroupSnapshotClass = r.getCephRBDVolumeGroupSnapshotClass(data, labels)
431+
}
432+
utils.AddAnnotation(volumeGroupSnapshotClass, storageClaimAnnotation, r.storageClaim.Name)
433+
if err := r.createOrReplaceVolumeGroupSnapshotClass(volumeGroupSnapshotClass); err != nil {
434+
return reconcile.Result{}, fmt.Errorf("failed to create or update volumeGroupSnapshot: %s", err)
435+
}
410436
}
411437
}
412438

@@ -501,10 +527,11 @@ func (r *StorageClaimReconciler) getCephRBDStorageClass(data map[string]string)
501527
return storageClass
502528
}
503529

504-
func (r *StorageClaimReconciler) getCephFSVolumeSnapshotClass(data map[string]string) *snapapi.VolumeSnapshotClass {
530+
func (r *StorageClaimReconciler) getCephFSVolumeSnapshotClass(data map[string]string, labels map[string]string) *snapapi.VolumeSnapshotClass {
505531
volumesnapshotclass := &snapapi.VolumeSnapshotClass{
506532
ObjectMeta: metav1.ObjectMeta{
507-
Name: r.storageClaim.Name,
533+
Name: r.storageClaim.Name,
534+
Labels: labels,
508535
},
509536
Driver: csi.GetCephFSDriverName(),
510537
DeletionPolicy: snapapi.VolumeSnapshotContentDelete,
@@ -513,10 +540,11 @@ func (r *StorageClaimReconciler) getCephFSVolumeSnapshotClass(data map[string]st
513540
return volumesnapshotclass
514541
}
515542

516-
func (r *StorageClaimReconciler) getCephRBDVolumeSnapshotClass(data map[string]string) *snapapi.VolumeSnapshotClass {
543+
func (r *StorageClaimReconciler) getCephRBDVolumeSnapshotClass(data map[string]string, labels map[string]string) *snapapi.VolumeSnapshotClass {
517544
volumesnapshotclass := &snapapi.VolumeSnapshotClass{
518545
ObjectMeta: metav1.ObjectMeta{
519-
Name: r.storageClaim.Name,
546+
Name: r.storageClaim.Name,
547+
Labels: labels,
520548
},
521549
Driver: csi.GetRBDDriverName(),
522550
DeletionPolicy: snapapi.VolumeSnapshotContentDelete,
@@ -651,6 +679,68 @@ func (r *StorageClaimReconciler) hasVolumeSnapshotContents() (bool, error) {
651679
return false, nil
652680
}
653681

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