package integration import ( "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/types" l5dv1alpha1 "edge-infra.dev/pkg/edge/linkerd/k8s/apis/linkerd/v1alpha1" "edge-infra.dev/pkg/k8s/runtime/conditions" "edge-infra.dev/pkg/k8s/runtime/inventory" "edge-infra.dev/test/f2" "edge-infra.dev/test/f2/x/ktest" ) func TestLinkerdWorkloadInjectionController(t *testing.T) { var ( k *ktest.K8s ) feature := f2.NewFeature("Workload Injection Controller"). Setup("setup", func(ctx f2.Context, t *testing.T) f2.Context { k = ktest.FromContextT(ctx, t) return ctx }). Test("workload injection empty spec injects proxy into all namespaces", func(ctx f2.Context, t *testing.T) f2.Context { workloadInjection := l5dreinjectionjob(l5dv1alpha1.LinkerdWorkloadInjectionSpec{}) require.NoError(t, k.Client.Create(ctx, workloadInjection)) assert.Eventually(t, func() bool { _ = k.Client.Get(ctx, types.NamespacedName{Name: workloadInjection.GetName()}, workloadInjection) return workloadInjection.IsCompleted() && conditions.IsReady(workloadInjection) }, ktest.Timeout, ktest.Tick, "Wait for linkerd reinjection job to complete") assert.Contains(t, workloadInjection.Status.Inventory.Entries, inventory.ResourceRef{ID: expectedInventoryID1, Version: expectedInventoryVersion}) assert.Contains(t, workloadInjection.Status.Inventory.Entries, inventory.ResourceRef{ID: expectedInventoryID2, Version: expectedInventoryVersion}) assert.Equal(t, 2, len(workloadInjection.Status.Inventory.Entries)) assert.Equal(t, inventory.ResourceInventory{}, *workloadInjection.Status.FailedInventory) require.NoError(t, k.Client.Delete(ctx, workloadInjection)) return ctx }). Test("proxy injected into specified namespaces", func(ctx f2.Context, t *testing.T) f2.Context { workloadInjection := l5dreinjectionjob(l5dv1alpha1.LinkerdWorkloadInjectionSpec{ Namespaces: []string{testNS1Name}, }) require.NoError(t, k.Client.Create(ctx, workloadInjection)) assert.Eventually(t, func() bool { _ = k.Client.Get(ctx, types.NamespacedName{Name: workloadInjection.GetName()}, workloadInjection) return workloadInjection.IsCompleted() && conditions.IsReady(workloadInjection) }, ktest.Timeout, ktest.Tick, "Wait for linkerd reinjection job to complete") assert.Contains(t, workloadInjection.Status.Inventory.Entries, inventory.ResourceRef{ID: expectedInventoryID1, Version: expectedInventoryVersion}) assert.Equal(t, 1, len(workloadInjection.Status.Inventory.Entries)) assert.Equal(t, inventory.ResourceInventory{}, *workloadInjection.Status.FailedInventory) require.NoError(t, k.Client.Delete(ctx, workloadInjection)) return ctx }). Test("recreating workload injection CR should inject proxies into new namespaces", func(ctx f2.Context, t *testing.T) f2.Context { workloadInjection := l5dreinjectionjob(l5dv1alpha1.LinkerdWorkloadInjectionSpec{ Namespaces: []string{testNS1Name}, }) require.NoError(t, k.Client.Create(ctx, workloadInjection)) assert.Eventually(t, func() bool { _ = k.Client.Get(ctx, types.NamespacedName{Name: workloadInjection.GetName()}, workloadInjection) return workloadInjection.IsCompleted() && conditions.IsReady(workloadInjection) }, ktest.Timeout, ktest.Tick, "Wait for linkerd reinjection job to complete") assert.Contains(t, workloadInjection.Status.Inventory.Entries, inventory.ResourceRef{ID: expectedInventoryID1, Version: expectedInventoryVersion}) assert.Equal(t, 1, len(workloadInjection.Status.Inventory.Entries)) assert.Equal(t, inventory.ResourceInventory{}, *workloadInjection.Status.FailedInventory) require.NoError(t, k.Client.Delete(ctx, workloadInjection)) newWorkloadinjection := l5dreinjectionjob(l5dv1alpha1.LinkerdWorkloadInjectionSpec{ Namespaces: []string{testNS1Name, testNS2Name}, }) require.NoError(t, k.Client.Create(ctx, newWorkloadinjection)) assert.Eventually(t, func() bool { _ = k.Client.Get(ctx, types.NamespacedName{Name: newWorkloadinjection.GetName()}, newWorkloadinjection) return newWorkloadinjection.IsCompleted() && conditions.IsReady(newWorkloadinjection) }, ktest.Timeout, ktest.Tick, "Wait for linkerd reinjection job to complete") assert.Contains(t, newWorkloadinjection.Status.Inventory.Entries, inventory.ResourceRef{ID: expectedInventoryID1, Version: expectedInventoryVersion}) assert.Contains(t, newWorkloadinjection.Status.Inventory.Entries, inventory.ResourceRef{ID: expectedInventoryID2, Version: expectedInventoryVersion}) assert.Equal(t, 2, len(newWorkloadinjection.Status.Inventory.Entries)) assert.Equal(t, inventory.ResourceInventory{}, *newWorkloadinjection.Status.FailedInventory) require.NoError(t, k.Client.Delete(ctx, newWorkloadinjection)) return ctx }). Test("proxy not injected into pods on host network", func(ctx f2.Context, t *testing.T) f2.Context { hostDeployment := createDeployment(testNS1Name, "host1") require.NoError(t, k.Client.Create(ctx, hostDeployment.DeepCopy())) k.WaitOn(t, k.ObjExists(hostDeployment)) pod := createPod(testNS1Name, "hostpod", true, ownerReference(hostDeployment)) require.NoError(t, k.Client.Create(ctx, pod)) workloadInjection := l5dreinjectionjob(l5dv1alpha1.LinkerdWorkloadInjectionSpec{ Namespaces: []string{testNS1Name}, }) require.NoError(t, k.Client.Create(ctx, workloadInjection)) assert.Eventually(t, func() bool { _ = k.Client.Get(ctx, types.NamespacedName{Name: workloadInjection.GetName()}, workloadInjection) return workloadInjection.IsCompleted() && conditions.IsReady(workloadInjection) }, ktest.Timeout, ktest.Tick, "Wait for linkerd reinjection job to complete") assert.Contains(t, workloadInjection.Status.Inventory.Entries, inventory.ResourceRef{ID: expectedInventoryID1, Version: expectedInventoryVersion}) assert.Equal(t, 1, len(workloadInjection.Status.Inventory.Entries)) assert.Equal(t, inventory.ResourceInventory{}, *workloadInjection.Status.FailedInventory) require.NoError(t, k.Client.Delete(ctx, workloadInjection)) return ctx }). Feature() f.Test(t, feature) }