From d6e190d4d17c6bff5da2182eebc3b998fda83159 Mon Sep 17 00:00:00 2001 From: Ravjot Singh Date: Mon, 17 Feb 2025 06:50:16 +0530 Subject: [PATCH 1/2] feat(authz): Add E2E test for kmeshctl authz functionality Signed-off-by: Ravjot Singh --- test/e2e/kmeshctl_test.go | 106 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 test/e2e/kmeshctl_test.go diff --git a/test/e2e/kmeshctl_test.go b/test/e2e/kmeshctl_test.go new file mode 100644 index 000000000..931b8ece2 --- /dev/null +++ b/test/e2e/kmeshctl_test.go @@ -0,0 +1,106 @@ +/* + * Copyright The Kmesh Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package kmeshctl_test + +import ( + "fmt" + "strings" + "testing" + "time" + + "istio.io/istio/pkg/test/shell" +) + +// TestKmeshctlAuthz verifies the kmeshctl authz (enable/disable/status) against a Kmesh Daemon pod. +func TestKmeshctlAuthz(t *testing.T) { + // 1) Grab the first Kmesh daemon pod from the cluster: + podName, err := getFirstKmeshPod() + if err != nil { + t.Fatalf("could not retrieve a kmesh daemon pod name: %v", err) + } + t.Logf("Using Kmesh daemon pod: %s", podName) + + // 2) Enable Authz on the Kmesh Daemon Pod + t.Run("enable-authz", func(t *testing.T) { + cmd := fmt.Sprintf("kmeshctl authz enable %s", podName) + out, err := shell.Execute(true, cmd) + if err != nil { + t.Fatalf("failed to enable authz on pod %q: %v\noutput: %s", podName, err, out) + } + t.Logf("enable-authz output:\n%s", out) + }) + + // 3) Check that Authz is enabled + t.Run("verify-authz-enabled", func(t *testing.T) { + // Wait a moment for Kmesh Daemon to process. + time.Sleep(2 * time.Second) + + cmd := fmt.Sprintf("kmeshctl authz status %s", podName) + out, err := shell.Execute(true, cmd) + if err != nil { + t.Fatalf("failed to check authz status: %v\noutput: %s", err, out) + } + t.Logf("status output:\n%s", out) + + // We assume the status output includes "true" or "enabled" if authz is on. + if !strings.Contains(out, "true") && !strings.Contains(strings.ToLower(out), "enabled") { + t.Fatalf("expected authz to be enabled, got: %s", out) + } + }) + + // 4) Disable Authz on the Kmesh Daemon Pod + t.Run("disable-authz", func(t *testing.T) { + cmd := fmt.Sprintf("kmeshctl authz disable %s", podName) + out, err := shell.Execute(true, cmd) + if err != nil { + t.Fatalf("failed to disable authz on pod %q: %v\noutput: %s", podName, err, out) + } + t.Logf("disable-authz output:\n%s", out) + }) + + // 5) Check that Authz is disabled + t.Run("verify-authz-disabled", func(t *testing.T) { + // Wait a moment for Kmesh Daemon to process. + time.Sleep(2 * time.Second) + + cmd := fmt.Sprintf("kmeshctl authz status %s", podName) + out, err := shell.Execute(true, cmd) + if err != nil { + t.Fatalf("failed to check authz status: %v\noutput: %s", err, out) + } + t.Logf("status output:\n%s", out) + + // We assume the status output includes "false" or "disabled" if authz is off. + if !strings.Contains(out, "false") && !strings.Contains(strings.ToLower(out), "disabled") { + t.Fatalf("expected authz to be disabled, got: %s", out) + } + }) +} + +// getFirstKmeshPod uses kubectl to find the first Kmesh Daemon pod (label app=kmesh) in kmesh-system. +func getFirstKmeshPod() (string, error) { + cmd := `kubectl get pods -n kmesh-system -l app=kmesh -o jsonpath='{.items[0].metadata.name}'` + out, err := shell.Execute(true, cmd) + if err != nil { + return "", fmt.Errorf("error retrieving kmesh daemon pod name: %v", err) + } + trimmed := strings.TrimSpace(out) + if trimmed == "" { + return "", fmt.Errorf("no Kmesh daemon pod found in kmesh-system namespace") + } + return trimmed, nil +} From 7ee9e61c3619572dc6598aeb5108d187af8f9fe3 Mon Sep 17 00:00:00 2001 From: ravjot07 Date: Wed, 19 Mar 2025 07:34:13 +0530 Subject: [PATCH 2/2] debug this test Signed-off-by: ravjot07 --- test/e2e/kmeshctl_test.go | 173 ++++++++++++++++++++++---------------- test/e2e/run_test.sh | 5 ++ 2 files changed, 104 insertions(+), 74 deletions(-) diff --git a/test/e2e/kmeshctl_test.go b/test/e2e/kmeshctl_test.go index 931b8ece2..0e0c8cbda 100644 --- a/test/e2e/kmeshctl_test.go +++ b/test/e2e/kmeshctl_test.go @@ -1,20 +1,21 @@ +//go:build integ +// +build integ + /* - * Copyright The Kmesh Authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +End-to-End Test for kmeshctl authz Commands in Kmesh. + +This test performs the following steps: +1. Automatically retrieves a running Kmesh Daemon pod from the "kmesh-system" namespace. +2. Waits for the pod to become ready. +3. Enables authorization offloading using "kmeshctl authz enable ". +4. Verifies the status using "kmeshctl authz status " (expecting enabled output). +5. Disables authorization using "kmeshctl authz disable ". +6. Verifies the status again (expecting disabled output). -package kmeshctl_test +This test ensures that the authz commands work correctly on a live cluster. +*/ + +package kmesh import ( "fmt" @@ -22,85 +23,109 @@ import ( "testing" "time" + "istio.io/istio/pkg/test/framework" "istio.io/istio/pkg/test/shell" + "istio.io/istio/pkg/test/util/retry" ) -// TestKmeshctlAuthz verifies the kmeshctl authz (enable/disable/status) against a Kmesh Daemon pod. -func TestKmeshctlAuthz(t *testing.T) { - // 1) Grab the first Kmesh daemon pod from the cluster: - podName, err := getFirstKmeshPod() +// getKmeshPod retrieves the name of a running Kmesh daemon pod in the kmesh-system namespace. +// It uses kubectl with a jsonpath query to return the first pod with label "app=kmesh". +func getKmeshPod() (string, error) { + out, err := shell.Execute(true, "kubectl get pods -n kmesh-system -l app=kmesh -o jsonpath='{.items[0].metadata.name}'") if err != nil { - t.Fatalf("could not retrieve a kmesh daemon pod name: %v", err) + return "", fmt.Errorf("failed to get kmesh pod: %v", err) } - t.Logf("Using Kmesh daemon pod: %s", podName) + podName := strings.Trim(out, "'") + if podName == "" { + return "", fmt.Errorf("no kmesh pod found") + } + return podName, nil +} + +// runKmeshCtl builds and executes a kmeshctl authz command with the provided arguments. +// It returns the command output (stdout) or an error. +func runKmeshCtl(pod string, args ...string) (string, error) { + // Construct the command string, e.g., "kmeshctl authz enable " + cmd := "kmeshctl authz " + strings.Join(args, " ") + " " + pod + return shell.Execute(true, cmd) +} + +func TestKmeshctlAuthz(t *testing.T) { + framework.NewTest(t).Run(func(t framework.TestContext) { + var pod string + var err error - // 2) Enable Authz on the Kmesh Daemon Pod - t.Run("enable-authz", func(t *testing.T) { - cmd := fmt.Sprintf("kmeshctl authz enable %s", podName) - out, err := shell.Execute(true, cmd) + // --- Pod Detection and Readiness --- + // Retry until we can fetch a Kmesh daemon pod from the kmesh-system namespace. + err = retry.Until(func() bool { + pod, err = getKmeshPod() + if err != nil { + t.Logf("Retrying getKmeshPod: %v", err) + return false + } + // Additionally, use kubectl wait to ensure the pod is Ready. + _, err = shell.Execute(true, "kubectl wait pod -n kmesh-system -l app=kmesh --for=condition=Ready --timeout=60s") + if err != nil { + t.Logf("Pod not yet ready: %v", err) + return false + } + t.Logf("Found ready Kmesh pod: %s", pod) + return true + }, retry.Timeout(90*time.Second), retry.Delay(3*time.Second)) if err != nil { - t.Fatalf("failed to enable authz on pod %q: %v\noutput: %s", podName, err, out) + t.Fatalf("Failed to retrieve a ready Kmesh pod: %v", err) } - t.Logf("enable-authz output:\n%s", out) - }) - // 3) Check that Authz is enabled - t.Run("verify-authz-enabled", func(t *testing.T) { - // Wait a moment for Kmesh Daemon to process. - time.Sleep(2 * time.Second) - - cmd := fmt.Sprintf("kmeshctl authz status %s", podName) - out, err := shell.Execute(true, cmd) + // --- Enable Authz --- + t.Log("Enabling authz on the Kmesh pod...") + enableOut, err := runKmeshCtl(pod, "enable") if err != nil { - t.Fatalf("failed to check authz status: %v\noutput: %s", err, out) + t.Fatalf("Failed to enable authz: %v", err) + } + t.Logf("Authz enable output: %s", enableOut) + // Expect the output to indicate authz is enabled (case-insensitive check for "true" or "enabled"). + if !strings.Contains(strings.ToLower(enableOut), "true") && !strings.Contains(strings.ToLower(enableOut), "enabled") { + t.Fatalf("Unexpected output from enable command: %s", enableOut) } - t.Logf("status output:\n%s", out) - // We assume the status output includes "true" or "enabled" if authz is on. - if !strings.Contains(out, "true") && !strings.Contains(strings.ToLower(out), "enabled") { - t.Fatalf("expected authz to be enabled, got: %s", out) + // --- Verify Authz Enabled --- + // Allow a brief wait for the daemon to update its status. + time.Sleep(2 * time.Second) + t.Log("Verifying authz status (expected to be enabled)...") + statusOut, err := runKmeshCtl(pod, "status") + if err != nil { + t.Fatalf("Failed to get authz status: %v", err) + } + t.Logf("Authz status output after enable: %s", statusOut) + if !strings.Contains(strings.ToLower(statusOut), "true") && !strings.Contains(strings.ToLower(statusOut), "enabled") { + t.Fatalf("Authz status is not enabled as expected: %s", statusOut) } - }) - // 4) Disable Authz on the Kmesh Daemon Pod - t.Run("disable-authz", func(t *testing.T) { - cmd := fmt.Sprintf("kmeshctl authz disable %s", podName) - out, err := shell.Execute(true, cmd) + // --- Disable Authz --- + t.Log("Disabling authz on the Kmesh pod...") + disableOut, err := runKmeshCtl(pod, "disable") if err != nil { - t.Fatalf("failed to disable authz on pod %q: %v\noutput: %s", podName, err, out) + t.Fatalf("Failed to disable authz: %v", err) + } + t.Logf("Authz disable output: %s", disableOut) + // Expect the disable output to indicate authz is disabled (look for "false" or "disabled"). + if !strings.Contains(strings.ToLower(disableOut), "false") && !strings.Contains(strings.ToLower(disableOut), "disabled") { + t.Fatalf("Unexpected output from disable command: %s", disableOut) } - t.Logf("disable-authz output:\n%s", out) - }) - // 5) Check that Authz is disabled - t.Run("verify-authz-disabled", func(t *testing.T) { - // Wait a moment for Kmesh Daemon to process. + // --- Verify Authz Disabled --- + // Wait again briefly before checking status. time.Sleep(2 * time.Second) - - cmd := fmt.Sprintf("kmeshctl authz status %s", podName) - out, err := shell.Execute(true, cmd) + t.Log("Verifying authz status (expected to be disabled)...") + statusOut, err = runKmeshCtl(pod, "status") if err != nil { - t.Fatalf("failed to check authz status: %v\noutput: %s", err, out) + t.Fatalf("Failed to get authz status after disable: %v", err) } - t.Logf("status output:\n%s", out) - - // We assume the status output includes "false" or "disabled" if authz is off. - if !strings.Contains(out, "false") && !strings.Contains(strings.ToLower(out), "disabled") { - t.Fatalf("expected authz to be disabled, got: %s", out) + t.Logf("Authz status output after disable: %s", statusOut) + if !strings.Contains(strings.ToLower(statusOut), "false") && !strings.Contains(strings.ToLower(statusOut), "disabled") { + t.Fatalf("Authz status is not disabled as expected: %s", statusOut) } - }) -} -// getFirstKmeshPod uses kubectl to find the first Kmesh Daemon pod (label app=kmesh) in kmesh-system. -func getFirstKmeshPod() (string, error) { - cmd := `kubectl get pods -n kmesh-system -l app=kmesh -o jsonpath='{.items[0].metadata.name}'` - out, err := shell.Execute(true, cmd) - if err != nil { - return "", fmt.Errorf("error retrieving kmesh daemon pod name: %v", err) - } - trimmed := strings.TrimSpace(out) - if trimmed == "" { - return "", fmt.Errorf("no Kmesh daemon pod found in kmesh-system namespace") - } - return trimmed, nil + t.Log("kmeshctl authz commands test passed successfully.") + }) } diff --git a/test/e2e/run_test.sh b/test/e2e/run_test.sh index a05e1014a..a6888730b 100755 --- a/test/e2e/run_test.sh +++ b/test/e2e/run_test.sh @@ -21,6 +21,11 @@ mkdir -p "${TMPBIN}" export PATH="$PATH:$TMPBIN" +if ! which kmeshctl &> /dev/null; then + echo "Error: kmeshctl is not in PATH. Please build and install kmeshctl before running tests." + exit 1 +fi + # Provision a kind clustr for testing. function setup_kind_cluster() { local NAME="${1:-kmesh-testing}"