From 7175ed751a371ff5ef78388274c999dc2b7aa1e9 Mon Sep 17 00:00:00 2001 From: M Sajid Mansoori Date: Wed, 1 Jul 2026 17:40:30 +0530 Subject: [PATCH 1/2] test: add tier0 NetworkPolicy migration coverage for namespace-admin flow --- .../mta_839_networkpolicy_migration_test.go | 165 ++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 e2e-tests/tests/tier0/mta_839_networkpolicy_migration_test.go diff --git a/e2e-tests/tests/tier0/mta_839_networkpolicy_migration_test.go b/e2e-tests/tests/tier0/mta_839_networkpolicy_migration_test.go new file mode 100644 index 00000000..46e57cdb --- /dev/null +++ b/e2e-tests/tests/tier0/mta_839_networkpolicy_migration_test.go @@ -0,0 +1,165 @@ +package e2e + +import ( + "encoding/json" + "fmt" + "log" + "path/filepath" + + "github.com/konveyor/crane/e2e-tests/config" + . "github.com/konveyor/crane/e2e-tests/framework" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var _ = Describe("NetworkPolicy migration", func() { + It("[MTA-839] NetworkPolicy is exported, transformed, and applied to target cluster", Label("tier0"), func() { + appName := "simple-nginx-nopv" + namespace := "test-netpol" + deploymentName := appName + "-deployment" + serviceName := "my-" + appName + networkPolicyName := appName + "-policy" + + scenario := NewMigrationScenario( + appName, + namespace, + config.K8sDeployBin, + config.CraneBin, + config.SourceContext, + config.TargetContext, + ) + if scenario.KubectlSrcNonAdmin.Context == "" { + Skip("source-nonadmin-context is required for namespace-admin NetworkPolicy migration test") + } + if scenario.KubectlTgtNonAdmin.Context == "" { + Skip("target-nonadmin-context is required for namespace-admin NetworkPolicy migration test") + } + srcApp := scenario.SrcAppNonAdmin + tgtApp := scenario.TgtAppNonAdmin + srcApp.ExtraVars = map[string]any{ + "non_admin_user": "true", + } + tgtApp.ExtraVars = map[string]any{ + "non_admin_user": "true", + } + + By("Grant namespace-admin permissions to non-admin user on source and target") + kubectlSrcNonAdmin, kubectlTgtNonAdmin, cleanup, err := SetupNamespaceAdminUsersForScenario(scenario, namespace) + Expect(err).NotTo(HaveOccurred()) + DeferCleanup(func() { + By("Delete test namespace on source and target (wait for completion)") + for _, k := range []KubectlRunner{scenario.KubectlSrc, scenario.KubectlTgt} { + if _, err := k.Run("delete", "namespace", namespace, "--ignore-not-found=true", "--wait=true"); err != nil { + log.Printf("cleanup: failed to delete namespace %q on context %q: %v", namespace, k.Context, err) + } + } + }) + DeferCleanup(cleanup) + + By("Prepare source app as namespace-admin") + log.Printf("Preparing source app %s in namespace %s\n", srcApp.Name, srcApp.Namespace) + Expect(PrepareSourceApp(srcApp, kubectlSrcNonAdmin)).NotTo(HaveOccurred()) + log.Printf("Source app %s prepared successfully\n", srcApp.Name) + + networkPolicyManifest := fmt.Sprintf(`apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: %s + namespace: %s +spec: + podSelector: + matchLabels: + app: %s + policyTypes: + - Ingress + - Egress + ingress: + - from: + - podSelector: {} + ports: + - protocol: TCP + port: 8080 + egress: + - to: + - namespaceSelector: {} + ports: + - protocol: UDP + port: 53 + - protocol: TCP + port: 53 +`, networkPolicyName, namespace, appName) + + By("Create NetworkPolicy on source cluster") + Expect(kubectlSrcNonAdmin.ApplyYAMLSpec(networkPolicyManifest, namespace)).NotTo(HaveOccurred()) + + By("Verify NetworkPolicy exists on source before export") + srcNetpolJSON, err := kubectlSrcNonAdmin.Run("get", "networkpolicy", networkPolicyName, "-n", namespace, "-o", "json") + Expect(err).NotTo(HaveOccurred(), "NetworkPolicy should exist on source cluster") + log.Printf("NetworkPolicy %s found on source cluster\n", networkPolicyName) + + var srcNetpol map[string]any + Expect(json.Unmarshal([]byte(srcNetpolJSON), &srcNetpol)).NotTo(HaveOccurred()) + + paths, err := NewScenarioPaths("crane-export-netpol-*") + Expect(err).NotTo(HaveOccurred()) + exportOpts := ExportOptions{Namespace: srcApp.Namespace, ExportDir: paths.ExportDir} + transformOpts := TransformOptions{ExportDir: paths.ExportDir, TransformDir: paths.TransformDir} + applyOpts := ApplyOptions{ExportDir: paths.ExportDir, TransformDir: paths.TransformDir, + OutputDir: paths.OutputDir} + DeferCleanup(func() { + By("Cleanup source and target resources") + if err := CleanupScenario(paths.TempDir, srcApp, tgtApp); err != nil { + log.Printf("cleanup: %v", err) + } + }) + + runner := scenario.CraneNonAdmin + runner.WorkDir = paths.TempDir + + By("Wait for source quiesce to stabilize before export") + WaitForSourceQuiesce(kubectlSrcNonAdmin, namespace, "app="+appName, serviceName) + + By("Run crane export/transform/apply pipeline") + log.Printf("Running crane pipeline for namespace %s\n", srcApp.Namespace) + Expect(RunCranePipelineWithChecks(runner, exportOpts, transformOpts, applyOpts)).NotTo(HaveOccurred()) + log.Printf("Crane pipeline completed for namespace %s\n", srcApp.Namespace) + + By("Verify NetworkPolicy manifest is present in output directory") + netpolGlob := filepath.Join(paths.OutputDir, "resources", namespace, "NetworkPolicy_*.yaml") + netpolMatches, err := filepath.Glob(netpolGlob) + Expect(err).NotTo(HaveOccurred()) + Expect(netpolMatches).NotTo(BeEmpty(), "expected NetworkPolicy manifest in output directory") + log.Printf("NetworkPolicy manifest found in output: %v\n", netpolMatches) + + By("Apply rendered manifests to target as namespace-admin") + log.Printf("Applying rendered manifests on target namespace %s from %s\n", namespace, paths.OutputDir) + Expect(ApplyOutputToTargetNonAdmin(kubectlTgtNonAdmin, paths.OutputDir)).NotTo(HaveOccurred()) + + By("Scale target deployment and validate app") + log.Printf("Scaling target deployment %s to 1\n", deploymentName) + Expect(kubectlTgtNonAdmin.ScaleDeployment(namespace, appName, 1)).NotTo(HaveOccurred()) + + log.Printf("Validating app %s on target cluster\n", tgtApp.Name) + Eventually(tgtApp.Validate, "2m", "10s").Should(Succeed()) + log.Printf("Target validation completed for app %s\n", tgtApp.Name) + + By("Verify NetworkPolicy is present on target cluster") + tgtNetpolJSON, err := kubectlTgtNonAdmin.Run("get", "networkpolicy", networkPolicyName, "-n", namespace, "-o", "json") + Expect(err).NotTo(HaveOccurred(), "NetworkPolicy should be present on target cluster") + log.Printf("NetworkPolicy %s found on target cluster\n", networkPolicyName) + + var tgtNetpol map[string]any + Expect(json.Unmarshal([]byte(tgtNetpolJSON), &tgtNetpol)).NotTo(HaveOccurred()) + + srcSpec, ok := srcNetpol["spec"].(map[string]any) + Expect(ok).To(BeTrue(), "source NetworkPolicy spec should be a map") + tgtSpec, ok := tgtNetpol["spec"].(map[string]any) + Expect(ok).To(BeTrue(), "target NetworkPolicy spec should be a map") + + By("Verify NetworkPolicy spec matches source for key migration fields") + Expect(tgtSpec["podSelector"]).To(Equal(srcSpec["podSelector"])) + Expect(tgtSpec["policyTypes"]).To(Equal(srcSpec["policyTypes"])) + Expect(tgtSpec["ingress"]).To(Equal(srcSpec["ingress"])) + Expect(tgtSpec["egress"]).To(Equal(srcSpec["egress"])) + }) +}) From 0b4e24fe3ce09574dac53b1ad84dcadb9dfb52b9 Mon Sep 17 00:00:00 2001 From: M Sajid Mansoori Date: Thu, 2 Jul 2026 10:06:07 +0530 Subject: [PATCH 2/2] Fix compliance issue Signed-off-by: M Sajid Mansoori --- .../tier0/mta_839_networkpolicy_migration_test.go | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/e2e-tests/tests/tier0/mta_839_networkpolicy_migration_test.go b/e2e-tests/tests/tier0/mta_839_networkpolicy_migration_test.go index 46e57cdb..a44906b5 100644 --- a/e2e-tests/tests/tier0/mta_839_networkpolicy_migration_test.go +++ b/e2e-tests/tests/tier0/mta_839_networkpolicy_migration_test.go @@ -28,12 +28,6 @@ var _ = Describe("NetworkPolicy migration", func() { config.SourceContext, config.TargetContext, ) - if scenario.KubectlSrcNonAdmin.Context == "" { - Skip("source-nonadmin-context is required for namespace-admin NetworkPolicy migration test") - } - if scenario.KubectlTgtNonAdmin.Context == "" { - Skip("target-nonadmin-context is required for namespace-admin NetworkPolicy migration test") - } srcApp := scenario.SrcAppNonAdmin tgtApp := scenario.TgtAppNonAdmin srcApp.ExtraVars = map[string]any{ @@ -43,8 +37,8 @@ var _ = Describe("NetworkPolicy migration", func() { "non_admin_user": "true", } - By("Grant namespace-admin permissions to non-admin user on source and target") - kubectlSrcNonAdmin, kubectlTgtNonAdmin, cleanup, err := SetupNamespaceAdminUsersForScenario(scenario, namespace) + By("Set up active kubectl runners for source and target") + kubectlSrcNonAdmin, kubectlTgtNonAdmin, cleanup, err := SetupActiveKubectlRunners(scenario, namespace) Expect(err).NotTo(HaveOccurred()) DeferCleanup(func() { By("Delete test namespace on source and target (wait for completion)")