Skip to content

Commit

Permalink
refactor: migrate from host
Browse files Browse the repository at this point in the history
  • Loading branch information
FabianKramm committed Aug 19, 2024
1 parent dbe7ae6 commit 501e5af
Show file tree
Hide file tree
Showing 15 changed files with 434 additions and 175 deletions.
7 changes: 4 additions & 3 deletions pkg/controllers/resources/events/syncer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"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"
"github.com/loft-sh/vcluster/pkg/util/translate"
"gotest.tools/assert"
corev1 "k8s.io/api/core/v1"
Expand All @@ -19,7 +20,7 @@ func newFakeSyncer(t *testing.T, ctx *synccontext.RegisterContext) (*synccontext
}

func TestSync(t *testing.T) {
translate.Default = translate.NewSingleNamespaceTranslator(syncertesting.DefaultTestTargetNamespace)
translate.Default = translate.NewSingleNamespaceTranslator(testingutil.DefaultTestTargetNamespace)

vNamespace := &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Expand All @@ -35,13 +36,13 @@ func TestSync(t *testing.T) {
pPod := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: translate.Default.HostName(nil, vPod.Name, vPod.Namespace).Name,
Namespace: syncertesting.DefaultTestTargetNamespace,
Namespace: testingutil.DefaultTestTargetNamespace,
},
}
pEvent := &corev1.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test-event",
Namespace: syncertesting.DefaultTestTargetNamespace,
Namespace: testingutil.DefaultTestTargetNamespace,
},
InvolvedObject: corev1.ObjectReference{
APIVersion: corev1.SchemeGroupVersion.String(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"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"

"github.com/loft-sh/vcluster/pkg/util/translate"
Expand All @@ -17,7 +18,7 @@ import (
)

func TestSync(t *testing.T) {
translate.Default = translate.NewSingleNamespaceTranslator(syncertesting.DefaultTestTargetNamespace)
translate.Default = translate.NewSingleNamespaceTranslator(testingutil.DefaultTestTargetNamespace)
vObjectMeta := metav1.ObjectMeta{
Name: "testPDB",
Namespace: "default",
Expand Down
29 changes: 15 additions & 14 deletions pkg/controllers/resources/pods/syncer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/loft-sh/vcluster/pkg/specialservices"
"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"
"github.com/loft-sh/vcluster/pkg/util/translate"
"gotest.tools/assert"
corev1 "k8s.io/api/core/v1"
Expand All @@ -22,8 +23,8 @@ import (
var (
pVclusterService = corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: syncertesting.DefaultTestVClusterServiceName,
Namespace: syncertesting.DefaultTestCurrentNamespace,
Name: testingutil.DefaultTestVClusterServiceName,
Namespace: testingutil.DefaultTestCurrentNamespace,
},
Spec: corev1.ServiceSpec{
ClusterIP: "1.2.3.4",
Expand All @@ -32,7 +33,7 @@ var (
pDNSService = corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: translate.Default.HostName(nil, "kube-dns", "kube-system").Name,
Namespace: syncertesting.DefaultTestTargetNamespace,
Namespace: testingutil.DefaultTestTargetNamespace,
},
Spec: corev1.ServiceSpec{
ClusterIP: "2.2.2.2",
Expand All @@ -41,7 +42,7 @@ var (
)

func TestSyncTable(t *testing.T) {
translate.Default = translate.NewSingleNamespaceTranslator(syncertesting.DefaultTestTargetNamespace)
translate.Default = translate.NewSingleNamespaceTranslator(testingutil.DefaultTestTargetNamespace)
specialservices.Default = specialservices.NewDefaultServiceSyncer()

vNamespace := corev1.Namespace{
Expand Down Expand Up @@ -285,7 +286,7 @@ func TestSyncTable(t *testing.T) {
}

func TestSync(t *testing.T) {
translate.Default = translate.NewSingleNamespaceTranslator(syncertesting.DefaultTestTargetNamespace)
translate.Default = translate.NewSingleNamespaceTranslator(testingutil.DefaultTestTargetNamespace)
specialservices.Default = specialservices.NewDefaultServiceSyncer()

PodLogsVolumeName := "pod-logs"
Expand Down Expand Up @@ -326,18 +327,18 @@ func TestSync(t *testing.T) {

pVclusterService := corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: syncertesting.DefaultTestVClusterServiceName,
Namespace: syncertesting.DefaultTestCurrentNamespace,
Name: testingutil.DefaultTestVClusterServiceName,
Namespace: testingutil.DefaultTestCurrentNamespace,
},
Spec: corev1.ServiceSpec{
ClusterIP: "1.2.3.4",
},
}
translate.VClusterName = syncertesting.DefaultTestVClusterName
translate.VClusterName = testingutil.DefaultTestVClusterName
pDNSService := corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: translate.Default.HostName(nil, "kube-dns", "kube-system").Name,
Namespace: syncertesting.DefaultTestTargetNamespace,
Namespace: testingutil.DefaultTestTargetNamespace,
},
Spec: corev1.ServiceSpec{
ClusterIP: "2.2.2.2",
Expand Down Expand Up @@ -390,14 +391,14 @@ func TestSync(t *testing.T) {

vHostpathNamespace := &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: syncertesting.DefaultTestCurrentNamespace,
Name: testingutil.DefaultTestCurrentNamespace,
},
}

vHostPathPod := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: HostpathPodName,
Namespace: syncertesting.DefaultTestCurrentNamespace,
Namespace: testingutil.DefaultTestCurrentNamespace,
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
Expand Down Expand Up @@ -449,13 +450,13 @@ func TestSync(t *testing.T) {
},
}

vHostPath := fmt.Sprintf(podtranslate.VirtualPathTemplate, syncertesting.DefaultTestCurrentNamespace, syncertesting.DefaultTestVClusterName)
vHostPath := fmt.Sprintf(podtranslate.VirtualPathTemplate, testingutil.DefaultTestCurrentNamespace, testingutil.DefaultTestVClusterName)

hostToContainer := corev1.MountPropagationHostToContainer
pHostPathPod := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: translate.Default.HostName(nil, vHostPathPod.Name, syncertesting.DefaultTestCurrentNamespace).Name,
Namespace: syncertesting.DefaultTestTargetNamespace,
Name: translate.Default.HostName(nil, vHostPathPod.Name, testingutil.DefaultTestCurrentNamespace).Name,
Namespace: testingutil.DefaultTestTargetNamespace,

Annotations: map[string]string{
podtranslate.ClusterAutoScalerAnnotation: "false",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ func TestVolumeTranslation(t *testing.T) {
fakeRecorder := record.NewFakeRecorder(10)
pClient := testingutil.NewFakeClient(scheme.Scheme)
vClient := testingutil.NewFakeClient(scheme.Scheme)
registerCtx := generictesting.NewFakeRegisterContext(generictesting.NewFakeConfig(), pClient, vClient)
registerCtx := generictesting.NewFakeRegisterContext(testingutil.NewFakeConfig(), pClient, vClient)
tr := &translator{
eventRecorder: fakeRecorder,
log: loghelper.New("pods-syncer-translator-test"),
Expand Down
2 changes: 1 addition & 1 deletion pkg/controllers/resources/storageclasses/syncer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
)

func TestSync(t *testing.T) {
translate.Default = translate.NewSingleNamespaceTranslator(syncertesting.DefaultTestTargetNamespace)
translate.Default = translate.NewSingleNamespaceTranslator(testingutil.DefaultTestTargetNamespace)

vObjectMeta := metav1.ObjectMeta{
Name: "testsc",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
)

func TestSync(t *testing.T) {
translate.Default = translate.NewSingleNamespaceTranslator(syncertesting.DefaultTestTargetNamespace)
translate.Default = translate.NewSingleNamespaceTranslator(testingutil.DefaultTestTargetNamespace)

vObjectMeta := metav1.ObjectMeta{
Name: "testclass",
Expand Down
60 changes: 1 addition & 59 deletions pkg/mappings/generic/mapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ import (
"github.com/loft-sh/vcluster/pkg/scheme"
"github.com/loft-sh/vcluster/pkg/syncer/synccontext"
"github.com/loft-sh/vcluster/pkg/util/translate"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/klog/v2"
Expand Down Expand Up @@ -72,62 +69,7 @@ func (n *mapper) GroupVersionKind() schema.GroupVersionKind {
return n.gvk
}

func (n *mapper) Migrate(ctx *synccontext.RegisterContext, mapper synccontext.Mapper) error {
gvk := mapper.GroupVersionKind()
listGvk := schema.GroupVersionKind{
Group: gvk.Group,
Version: gvk.Version,
Kind: gvk.Kind + "List",
}

list, err := scheme.Scheme.New(listGvk)
if err != nil {
if !runtime.IsNotRegisteredError(err) {
return fmt.Errorf("migrate create object list %s: %w", listGvk.String(), err)
}

list = &unstructured.UnstructuredList{}
}

uList, ok := list.(*unstructured.UnstructuredList)
if ok {
uList.SetKind(listGvk.Kind)
uList.SetAPIVersion(listGvk.GroupVersion().String())
}

// it's safe to list here without namespace as this will just list all items in the cache
err = ctx.VirtualManager.GetClient().List(ctx, list.(client.ObjectList))
if err != nil {
return fmt.Errorf("error listing %s: %w", listGvk.String(), err)
}

items, err := meta.ExtractList(list)
if err != nil {
return fmt.Errorf("extract list %s: %w", listGvk.String(), err)
}

for _, item := range items {
clientObject, ok := item.(client.Object)
if !ok {
continue
}

vName := types.NamespacedName{Name: clientObject.GetName(), Namespace: clientObject.GetNamespace()}
pName := mapper.VirtualToHost(ctx.ToSyncContext("migrate-"+listGvk.Kind), vName, clientObject)
if pName.Name != "" {
nameMapping := synccontext.NameMapping{
GroupVersionKind: n.gvk,
VirtualName: vName,
HostName: pName,
}

err = ctx.Mappings.Store().AddReferenceAndSave(ctx, nameMapping, nameMapping)
if err != nil {
return fmt.Errorf("error saving reference in store: %w", err)
}
}
}

func (n *mapper) Migrate(_ *synccontext.RegisterContext, _ synccontext.Mapper) error {
return nil
}

Expand Down
75 changes: 75 additions & 0 deletions pkg/mappings/generic/recorder.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
package generic

import (
"fmt"

"github.com/loft-sh/vcluster/pkg/scheme"
"github.com/loft-sh/vcluster/pkg/syncer/synccontext"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/klog/v2"
Expand All @@ -18,6 +24,75 @@ type recorder struct {
synccontext.Mapper
}

func (n *recorder) Migrate(ctx *synccontext.RegisterContext, mapper synccontext.Mapper) error {
gvk := n.Mapper.GroupVersionKind()
listGvk := schema.GroupVersionKind{
Group: gvk.Group,
Version: gvk.Version,
Kind: gvk.Kind + "List",
}

list, err := scheme.Scheme.New(listGvk)
if err != nil {
if !runtime.IsNotRegisteredError(err) {
return fmt.Errorf("migrate create object list %s: %w", listGvk.String(), err)
}

list = &unstructured.UnstructuredList{}
}

uList, ok := list.(*unstructured.UnstructuredList)
if ok {
uList.SetKind(listGvk.Kind)
uList.SetAPIVersion(listGvk.GroupVersion().String())
}

// it's safe to list here without namespace as this will just list all items in the cache
err = ctx.PhysicalManager.GetClient().List(ctx, list.(client.ObjectList))
if err != nil {
return fmt.Errorf("error listing %s: %w", listGvk.String(), err)
}

items, err := meta.ExtractList(list)
if err != nil {
return fmt.Errorf("extract list %s: %w", listGvk.String(), err)
}

for _, item := range items {
clientObject, ok := item.(client.Object)
if !ok {
continue
}

syncContext := ctx.ToSyncContext("migrate-" + listGvk.Kind)
syncContext.Mappings = nil
isManaged, err := n.Mapper.IsManaged(syncContext, clientObject)
if err != nil {
klog.FromContext(ctx).Error(err, "is managed")
continue
} else if !isManaged {
continue
}

pName := types.NamespacedName{Name: clientObject.GetName(), Namespace: clientObject.GetNamespace()}
vName := n.Mapper.HostToVirtual(syncContext, pName, clientObject)
if vName.Name != "" {
nameMapping := synccontext.NameMapping{
GroupVersionKind: n.Mapper.GroupVersionKind(),
VirtualName: vName,
HostName: pName,
}

err = ctx.Mappings.Store().AddReferenceAndSave(ctx, nameMapping, nameMapping)
if err != nil {
klog.FromContext(ctx).Error(err, "saving reference in store", "mapping", nameMapping.String())
}
}
}

return n.Mapper.Migrate(ctx, mapper)
}

func (n *recorder) VirtualToHost(ctx *synccontext.SyncContext, req types.NamespacedName, vObj client.Object) (retName types.NamespacedName) {
defer func() {
err := RecordMapping(ctx, retName, req, n.GroupVersionKind())
Expand Down
Loading

0 comments on commit 501e5af

Please sign in to comment.