Skip to content

Commit

Permalink
Propagate OCM annotations from primary PVC
Browse files Browse the repository at this point in the history
To ensure that OCM owns the volsync protected PVC when the application
is deleted or DR is disabled, copy the OCM annotations from the PVC to
the protectedPVC. The annotations are propagated to the target clusters
and used to create the PVC during failover and relocate.

Tested by adding a new section in existing test. The test ensures that
we copy only the OCM annotations and drop other annotations.

Fixes: RamenDR#1033

Signed-off-by: Nir Soffer <[email protected]>
(cherry picked from commit f19c8ed)
  • Loading branch information
nirs authored and raghavendra-talur committed Sep 11, 2023
1 parent eb311b8 commit 2f296bc
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 3 deletions.
18 changes: 18 additions & 0 deletions controllers/vrg_volsync.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package controllers
import (
"fmt"
"reflect"
"strings"

ramendrv1alpha1 "github.com/ramendr/ramen/api/v1alpha1"
corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -112,6 +113,7 @@ func (v *VRGInstance) reconcilePVCAsVolSyncPrimary(pvc corev1.PersistentVolumeCl
Name: pvc.Name,
ProtectedByVolSync: true,
StorageClassName: pvc.Spec.StorageClassName,
Annotations: protectedPVCAnnotations(pvc),
Labels: pvc.Labels,
AccessModes: pvc.Spec.AccessModes,
Resources: pvc.Spec.Resources,
Expand Down Expand Up @@ -367,3 +369,19 @@ func (v VRGInstance) isVolSyncProtectedPVCConditionReady(conType string) bool {

return ready
}

// protectedPVCAnnotations return the annotations that we must propagate to the
// destination cluster:
// - apps.open-cluster-management.io/* - required to make the protected PVC
// owned by OCM when DR is disabled.
func protectedPVCAnnotations(pvc corev1.PersistentVolumeClaim) map[string]string {
res := map[string]string{}

for key, value := range pvc.Annotations {
if strings.HasPrefix(key, "apps.open-cluster-management.io/") {
res[key] = value
}
}

return res
}
31 changes: 28 additions & 3 deletions controllers/vrg_volsync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,22 @@ var _ = Describe("VolumeReplicationGroupVolSyncController", func() {

Context("When matching PVCs are bound", func() {
var boundPvcs []corev1.PersistentVolumeClaim

pvcAnnotations := map[string]string{
"apps.open-cluster-management.io/hosting-subscription": "sub-name",
"apps.open-cluster-management.io/reconcile-option": "merge",
"pv.kubernetes.io/bind-completed": "yes",
"volume.kubernetes.io/storage-provisioner": "provisioner",
}

JustBeforeEach(func() {
boundPvcs = []corev1.PersistentVolumeClaim{} // Reset for each test
// Reset for each test
boundPvcs = []corev1.PersistentVolumeClaim{}

// Create some PVCs that are bound
for i := 0; i < 3; i++ {
newPvc := createPVCBoundToRunningPod(testCtx, testNamespace.GetName(), testMatchLabels)
newPvc := createPVCBoundToRunningPod(testCtx, testNamespace.GetName(),
testMatchLabels, pvcAnnotations)
boundPvcs = append(boundPvcs, *newPvc)
}

Expand Down Expand Up @@ -147,6 +157,20 @@ var _ = Describe("VolumeReplicationGroupVolSyncController", func() {
Expect(foundBoundPVC2).To(BeTrue())
})

It("Should report only OCM annotaions in Status", func() {
for _, vsPvc := range testVsrg.Status.ProtectedPVCs {
// OCM annontations are propagated.
Expect(vsPvc.Annotations).To(HaveKeyWithValue(
"apps.open-cluster-management.io/hosting-subscription", "sub-name"))
Expect(vsPvc.Annotations).To(HaveKeyWithValue(
"apps.open-cluster-management.io/reconcile-option", "merge"))

// Other annotations are droopped.
Expect(vsPvc.Annotations).NotTo(HaveKey("pv.kubernetes.io/bind-completed"))
Expect(vsPvc.Annotations).NotTo(HaveKey("volume.kubernetes.io/storage-provisioner"))
}
})

Context("When RSSpec entries are added to vrg spec", func() {
It("Should create ReplicationSources for each", func() {
allRSs := &volsyncv1alpha1.ReplicationSourceList{}
Expand Down Expand Up @@ -343,7 +367,7 @@ var _ = Describe("VolumeReplicationGroupVolSyncController", func() {

//nolint:funlen
func createPVCBoundToRunningPod(ctx context.Context, namespace string,
labels map[string]string,
labels map[string]string, annotations map[string]string,
) *corev1.PersistentVolumeClaim {
capacity := corev1.ResourceList{
corev1.ResourceStorage: resource.MustParse("1Gi"),
Expand All @@ -358,6 +382,7 @@ func createPVCBoundToRunningPod(ctx context.Context, namespace string,
TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{
GenerateName: "testpvc-",
Annotations: annotations,
Labels: labels,
Namespace: namespace,
},
Expand Down

0 comments on commit 2f296bc

Please sign in to comment.