From a7928fcaaf26426f5a14d39717194183a011741c Mon Sep 17 00:00:00 2001 From: Fabian Kramm Date: Tue, 24 Sep 2024 23:14:19 +0200 Subject: [PATCH] fix: pv syncing --- .../persistentvolumes/syncer_test.go | 11 +++++++- .../volumesnapshotcontents/syncer_test.go | 5 ++++ pkg/mappings/generic/mapper.go | 2 +- pkg/mappings/resources/persistentvolumes.go | 26 ++++++++++++++++--- .../resources/volumesnapshotcontents.go | 26 ++++++++++++++++--- 5 files changed, 62 insertions(+), 8 deletions(-) diff --git a/pkg/controllers/resources/persistentvolumes/syncer_test.go b/pkg/controllers/resources/persistentvolumes/syncer_test.go index 6825aef1a..ac0ed3140 100644 --- a/pkg/controllers/resources/persistentvolumes/syncer_test.go +++ b/pkg/controllers/resources/persistentvolumes/syncer_test.go @@ -4,8 +4,10 @@ import ( "testing" "time" + "github.com/loft-sh/vcluster/pkg/config" "github.com/loft-sh/vcluster/pkg/syncer/synccontext" syncertesting "github.com/loft-sh/vcluster/pkg/syncer/testing" + testingutil "github.com/loft-sh/vcluster/pkg/util/testing" "gotest.tools/assert" "k8s.io/apimachinery/pkg/api/resource" @@ -188,7 +190,10 @@ func TestSync(t *testing.T) { }, } - syncertesting.RunTests(t, []*syncertesting.SyncTest{ + syncertesting.RunTestsWithContext(t, func(vConfig *config.VirtualClusterConfig, pClient *testingutil.FakeIndexClient, vClient *testingutil.FakeIndexClient) *synccontext.RegisterContext { + vConfig.Sync.ToHost.PersistentVolumes.Enabled = true + return syncertesting.NewFakeRegisterContext(vConfig, pClient, vClient) + }, []*syncertesting.SyncTest{ { Name: "Create Backward", InitialVirtualState: []runtime.Object{basePvc}, @@ -202,6 +207,10 @@ func TestSync(t *testing.T) { }, Sync: func(ctx *synccontext.RegisterContext) { syncContext, syncer := newFakeSyncer(t, ctx) + + vName := syncer.HostToVirtual(syncContext, types.NamespacedName{Name: basePPv.Name}, basePPv) + assert.Equal(t, vName.Name, baseVPv.Name) + _, err := syncer.SyncToVirtual(syncContext, synccontext.NewSyncToVirtualEvent(basePPv)) assert.NilError(t, err) }, diff --git a/pkg/controllers/resources/volumesnapshots/volumesnapshotcontents/syncer_test.go b/pkg/controllers/resources/volumesnapshots/volumesnapshotcontents/syncer_test.go index 13577e303..b0504de67 100644 --- a/pkg/controllers/resources/volumesnapshots/volumesnapshotcontents/syncer_test.go +++ b/pkg/controllers/resources/volumesnapshots/volumesnapshotcontents/syncer_test.go @@ -10,6 +10,7 @@ import ( syncertesting "github.com/loft-sh/vcluster/pkg/syncer/testing" testingutil "github.com/loft-sh/vcluster/pkg/util/testing" "gotest.tools/assert" + "k8s.io/apimachinery/pkg/types" "k8s.io/utils/ptr" volumesnapshotv1 "github.com/kubernetes-csi/external-snapshotter/client/v4/apis/volumesnapshot/v1" @@ -177,6 +178,10 @@ func TestSync(t *testing.T) { }, Sync: func(ctx *synccontext.RegisterContext) { syncCtx, syncer := newFakeSyncer(t, ctx) + + vName := syncer.HostToVirtual(syncCtx, types.NamespacedName{Name: pDynamic.Name}, pDynamic) + assert.Equal(t, vName.Name, pDynamic.Name) + _, err := syncer.SyncToVirtual(syncCtx, synccontext.NewSyncToVirtualEvent(pDynamic.DeepCopy())) assert.NilError(t, err) }, diff --git a/pkg/mappings/generic/mapper.go b/pkg/mappings/generic/mapper.go index efccc595f..6e4bf1abb 100644 --- a/pkg/mappings/generic/mapper.go +++ b/pkg/mappings/generic/mapper.go @@ -37,7 +37,7 @@ func NewMapperWithObject(ctx *synccontext.RegisterContext, obj client.Object, tr return newMapper(ctx, obj, true, translateName) } -// NewMapperWithoutRecorder creates a new mapper with a recorder to store mappings in the mappings store +// NewMapperWithoutRecorder creates a new mapper without a recorder to store mappings in the mappings store func NewMapperWithoutRecorder(ctx *synccontext.RegisterContext, obj client.Object, translateName PhysicalNameWithObjectFunc) (synccontext.Mapper, error) { return newMapper(ctx, obj, false, translateName) } diff --git a/pkg/mappings/resources/persistentvolumes.go b/pkg/mappings/resources/persistentvolumes.go index dbb8be989..3d9c9dc11 100644 --- a/pkg/mappings/resources/persistentvolumes.go +++ b/pkg/mappings/resources/persistentvolumes.go @@ -15,16 +15,36 @@ func CreatePersistentVolumesMapper(ctx *synccontext.RegisterContext) (synccontex return generic.NewMirrorMapper(&corev1.PersistentVolume{}) } - return generic.NewMapperWithObject(ctx, &corev1.PersistentVolume{}, func(_ *synccontext.SyncContext, name, _ string, vObj client.Object) types.NamespacedName { + mapper, err := generic.NewMapperWithoutRecorder(ctx, &corev1.PersistentVolume{}, func(_ *synccontext.SyncContext, vName, _ string, vObj client.Object) types.NamespacedName { if vObj == nil { - return types.NamespacedName{Name: name} + return types.NamespacedName{Name: vName} } vPv, ok := vObj.(*corev1.PersistentVolume) if !ok || vPv.Annotations == nil || vPv.Annotations[constants.HostClusterPersistentVolumeAnnotation] == "" { - return types.NamespacedName{Name: translate.Default.HostNameCluster(name)} + return types.NamespacedName{Name: translate.Default.HostNameCluster(vName)} } return types.NamespacedName{Name: vPv.Annotations[constants.HostClusterPersistentVolumeAnnotation]} }) + if err != nil { + return nil, err + } + + return generic.WithRecorder(&persistentVolumeMapper{ + Mapper: mapper, + }), nil +} + +type persistentVolumeMapper struct { + synccontext.Mapper +} + +func (p *persistentVolumeMapper) HostToVirtual(ctx *synccontext.SyncContext, req types.NamespacedName, pObj client.Object) types.NamespacedName { + vName := p.Mapper.HostToVirtual(ctx, req, pObj) + if vName.Name != "" { + return vName + } + + return types.NamespacedName{Name: req.Name} } diff --git a/pkg/mappings/resources/volumesnapshotcontents.go b/pkg/mappings/resources/volumesnapshotcontents.go index b2585cd9c..b5b50c056 100644 --- a/pkg/mappings/resources/volumesnapshotcontents.go +++ b/pkg/mappings/resources/volumesnapshotcontents.go @@ -26,16 +26,36 @@ func CreateVolumeSnapshotContentsMapper(ctx *synccontext.RegisterContext) (syncc return nil, err } - return generic.NewMapperWithObject(ctx, &volumesnapshotv1.VolumeSnapshotContent{}, func(_ *synccontext.SyncContext, name, _ string, vObj client.Object) types.NamespacedName { + mapper, err := generic.NewMapperWithoutRecorder(ctx, &volumesnapshotv1.VolumeSnapshotContent{}, func(_ *synccontext.SyncContext, vName, _ string, vObj client.Object) types.NamespacedName { if vObj == nil { - return types.NamespacedName{Name: name} + return types.NamespacedName{Name: vName} } vVSC, ok := vObj.(*volumesnapshotv1.VolumeSnapshotContent) if !ok || vVSC.Annotations == nil || vVSC.Annotations[constants.HostClusterVSCAnnotation] == "" { - return types.NamespacedName{Name: translate.Default.HostNameCluster(name)} + return types.NamespacedName{Name: translate.Default.HostNameCluster(vName)} } return types.NamespacedName{Name: vVSC.Annotations[constants.HostClusterVSCAnnotation]} }) + if err != nil { + return nil, err + } + + return generic.WithRecorder(&volumeSnapshotContentMapper{ + Mapper: mapper, + }), nil +} + +type volumeSnapshotContentMapper struct { + synccontext.Mapper +} + +func (p *volumeSnapshotContentMapper) HostToVirtual(ctx *synccontext.SyncContext, req types.NamespacedName, pObj client.Object) types.NamespacedName { + vName := p.Mapper.HostToVirtual(ctx, req, pObj) + if vName.Name != "" { + return vName + } + + return types.NamespacedName{Name: req.Name} }