|
| 1 | +//go:build integ |
| 2 | +// +build integ |
| 3 | + |
1 | 4 | /* |
2 | | - * Copyright The Kmesh Authors. |
3 | | - * |
4 | | - * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | - * you may not use this file except in compliance with the License. |
6 | | - * You may obtain a copy of the License at: |
7 | | - * |
8 | | - * http://www.apache.org/licenses/LICENSE-2.0 |
9 | | - * |
10 | | - * Unless required by applicable law or agreed to in writing, software |
11 | | - * distributed under the License is distributed on an "AS IS" BASIS, |
12 | | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | - * See the License for the specific language governing permissions and |
14 | | - * limitations under the License. |
15 | | - */ |
| 5 | +End-to-End Test for kmeshctl authz Commands in Kmesh. |
| 6 | +
|
| 7 | +This test performs the following steps: |
| 8 | +1. Automatically retrieves a running Kmesh Daemon pod from the "kmesh-system" namespace. |
| 9 | +2. Waits for the pod to become ready. |
| 10 | +3. Enables authorization offloading using "kmeshctl authz enable <pod>". |
| 11 | +4. Verifies the status using "kmeshctl authz status <pod>" (expecting enabled output). |
| 12 | +5. Disables authorization using "kmeshctl authz disable <pod>". |
| 13 | +6. Verifies the status again (expecting disabled output). |
16 | 14 |
|
17 | | -package kmeshctl_test |
| 15 | +This test ensures that the authz commands work correctly on a live cluster. |
| 16 | +*/ |
| 17 | + |
| 18 | +package kmesh |
18 | 19 |
|
19 | 20 | import ( |
20 | 21 | "fmt" |
21 | 22 | "strings" |
22 | 23 | "testing" |
23 | 24 | "time" |
24 | 25 |
|
| 26 | + "istio.io/istio/pkg/test/framework" |
25 | 27 | "istio.io/istio/pkg/test/shell" |
| 28 | + "istio.io/istio/pkg/test/util/retry" |
26 | 29 | ) |
27 | 30 |
|
28 | | -// TestKmeshctlAuthz verifies the kmeshctl authz (enable/disable/status) against a Kmesh Daemon pod. |
29 | | -func TestKmeshctlAuthz(t *testing.T) { |
30 | | - // 1) Grab the first Kmesh daemon pod from the cluster: |
31 | | - podName, err := getFirstKmeshPod() |
| 31 | +// getKmeshPod retrieves the name of a running Kmesh daemon pod in the kmesh-system namespace. |
| 32 | +// It uses kubectl with a jsonpath query to return the first pod with label "app=kmesh". |
| 33 | +func getKmeshPod() (string, error) { |
| 34 | + out, err := shell.Execute(true, "kubectl get pods -n kmesh-system -l app=kmesh -o jsonpath='{.items[0].metadata.name}'") |
32 | 35 | if err != nil { |
33 | | - t.Fatalf("could not retrieve a kmesh daemon pod name: %v", err) |
| 36 | + return "", fmt.Errorf("failed to get kmesh pod: %v", err) |
34 | 37 | } |
35 | | - t.Logf("Using Kmesh daemon pod: %s", podName) |
| 38 | + podName := strings.Trim(out, "'") |
| 39 | + if podName == "" { |
| 40 | + return "", fmt.Errorf("no kmesh pod found") |
| 41 | + } |
| 42 | + return podName, nil |
| 43 | +} |
| 44 | + |
| 45 | +// runKmeshCtl builds and executes a kmeshctl authz command with the provided arguments. |
| 46 | +// It returns the command output (stdout) or an error. |
| 47 | +func runKmeshCtl(pod string, args ...string) (string, error) { |
| 48 | + // Construct the command string, e.g., "kmeshctl authz enable <pod>" |
| 49 | + cmd := "kmeshctl authz " + strings.Join(args, " ") + " " + pod |
| 50 | + return shell.Execute(true, cmd) |
| 51 | +} |
| 52 | + |
| 53 | +func TestKmeshctlAuthz(t *testing.T) { |
| 54 | + framework.NewTest(t).Run(func(t framework.TestContext) { |
| 55 | + var pod string |
| 56 | + var err error |
36 | 57 |
|
37 | | - // 2) Enable Authz on the Kmesh Daemon Pod |
38 | | - t.Run("enable-authz", func(t *testing.T) { |
39 | | - cmd := fmt.Sprintf("kmeshctl authz enable %s", podName) |
40 | | - out, err := shell.Execute(true, cmd) |
| 58 | + // --- Pod Detection and Readiness --- |
| 59 | + // Retry until we can fetch a Kmesh daemon pod from the kmesh-system namespace. |
| 60 | + err = retry.Until(func() bool { |
| 61 | + pod, err = getKmeshPod() |
| 62 | + if err != nil { |
| 63 | + t.Logf("Retrying getKmeshPod: %v", err) |
| 64 | + return false |
| 65 | + } |
| 66 | + // Additionally, use kubectl wait to ensure the pod is Ready. |
| 67 | + _, err = shell.Execute(true, "kubectl wait pod -n kmesh-system -l app=kmesh --for=condition=Ready --timeout=60s") |
| 68 | + if err != nil { |
| 69 | + t.Logf("Pod not yet ready: %v", err) |
| 70 | + return false |
| 71 | + } |
| 72 | + t.Logf("Found ready Kmesh pod: %s", pod) |
| 73 | + return true |
| 74 | + }, retry.Timeout(90*time.Second), retry.Delay(3*time.Second)) |
41 | 75 | if err != nil { |
42 | | - t.Fatalf("failed to enable authz on pod %q: %v\noutput: %s", podName, err, out) |
| 76 | + t.Fatalf("Failed to retrieve a ready Kmesh pod: %v", err) |
43 | 77 | } |
44 | | - t.Logf("enable-authz output:\n%s", out) |
45 | | - }) |
46 | 78 |
|
47 | | - // 3) Check that Authz is enabled |
48 | | - t.Run("verify-authz-enabled", func(t *testing.T) { |
49 | | - // Wait a moment for Kmesh Daemon to process. |
50 | | - time.Sleep(2 * time.Second) |
51 | | - |
52 | | - cmd := fmt.Sprintf("kmeshctl authz status %s", podName) |
53 | | - out, err := shell.Execute(true, cmd) |
| 79 | + // --- Enable Authz --- |
| 80 | + t.Log("Enabling authz on the Kmesh pod...") |
| 81 | + enableOut, err := runKmeshCtl(pod, "enable") |
54 | 82 | if err != nil { |
55 | | - t.Fatalf("failed to check authz status: %v\noutput: %s", err, out) |
| 83 | + t.Fatalf("Failed to enable authz: %v", err) |
| 84 | + } |
| 85 | + t.Logf("Authz enable output: %s", enableOut) |
| 86 | + // Expect the output to indicate authz is enabled (case-insensitive check for "true" or "enabled"). |
| 87 | + if !strings.Contains(strings.ToLower(enableOut), "true") && !strings.Contains(strings.ToLower(enableOut), "enabled") { |
| 88 | + t.Fatalf("Unexpected output from enable command: %s", enableOut) |
56 | 89 | } |
57 | | - t.Logf("status output:\n%s", out) |
58 | 90 |
|
59 | | - // We assume the status output includes "true" or "enabled" if authz is on. |
60 | | - if !strings.Contains(out, "true") && !strings.Contains(strings.ToLower(out), "enabled") { |
61 | | - t.Fatalf("expected authz to be enabled, got: %s", out) |
| 91 | + // --- Verify Authz Enabled --- |
| 92 | + // Allow a brief wait for the daemon to update its status. |
| 93 | + time.Sleep(2 * time.Second) |
| 94 | + t.Log("Verifying authz status (expected to be enabled)...") |
| 95 | + statusOut, err := runKmeshCtl(pod, "status") |
| 96 | + if err != nil { |
| 97 | + t.Fatalf("Failed to get authz status: %v", err) |
| 98 | + } |
| 99 | + t.Logf("Authz status output after enable: %s", statusOut) |
| 100 | + if !strings.Contains(strings.ToLower(statusOut), "true") && !strings.Contains(strings.ToLower(statusOut), "enabled") { |
| 101 | + t.Fatalf("Authz status is not enabled as expected: %s", statusOut) |
62 | 102 | } |
63 | | - }) |
64 | 103 |
|
65 | | - // 4) Disable Authz on the Kmesh Daemon Pod |
66 | | - t.Run("disable-authz", func(t *testing.T) { |
67 | | - cmd := fmt.Sprintf("kmeshctl authz disable %s", podName) |
68 | | - out, err := shell.Execute(true, cmd) |
| 104 | + // --- Disable Authz --- |
| 105 | + t.Log("Disabling authz on the Kmesh pod...") |
| 106 | + disableOut, err := runKmeshCtl(pod, "disable") |
69 | 107 | if err != nil { |
70 | | - t.Fatalf("failed to disable authz on pod %q: %v\noutput: %s", podName, err, out) |
| 108 | + t.Fatalf("Failed to disable authz: %v", err) |
| 109 | + } |
| 110 | + t.Logf("Authz disable output: %s", disableOut) |
| 111 | + // Expect the disable output to indicate authz is disabled (look for "false" or "disabled"). |
| 112 | + if !strings.Contains(strings.ToLower(disableOut), "false") && !strings.Contains(strings.ToLower(disableOut), "disabled") { |
| 113 | + t.Fatalf("Unexpected output from disable command: %s", disableOut) |
71 | 114 | } |
72 | | - t.Logf("disable-authz output:\n%s", out) |
73 | | - }) |
74 | 115 |
|
75 | | - // 5) Check that Authz is disabled |
76 | | - t.Run("verify-authz-disabled", func(t *testing.T) { |
77 | | - // Wait a moment for Kmesh Daemon to process. |
| 116 | + // --- Verify Authz Disabled --- |
| 117 | + // Wait again briefly before checking status. |
78 | 118 | time.Sleep(2 * time.Second) |
79 | | - |
80 | | - cmd := fmt.Sprintf("kmeshctl authz status %s", podName) |
81 | | - out, err := shell.Execute(true, cmd) |
| 119 | + t.Log("Verifying authz status (expected to be disabled)...") |
| 120 | + statusOut, err = runKmeshCtl(pod, "status") |
82 | 121 | if err != nil { |
83 | | - t.Fatalf("failed to check authz status: %v\noutput: %s", err, out) |
| 122 | + t.Fatalf("Failed to get authz status after disable: %v", err) |
84 | 123 | } |
85 | | - t.Logf("status output:\n%s", out) |
86 | | - |
87 | | - // We assume the status output includes "false" or "disabled" if authz is off. |
88 | | - if !strings.Contains(out, "false") && !strings.Contains(strings.ToLower(out), "disabled") { |
89 | | - t.Fatalf("expected authz to be disabled, got: %s", out) |
| 124 | + t.Logf("Authz status output after disable: %s", statusOut) |
| 125 | + if !strings.Contains(strings.ToLower(statusOut), "false") && !strings.Contains(strings.ToLower(statusOut), "disabled") { |
| 126 | + t.Fatalf("Authz status is not disabled as expected: %s", statusOut) |
90 | 127 | } |
91 | | - }) |
92 | | -} |
93 | 128 |
|
94 | | -// getFirstKmeshPod uses kubectl to find the first Kmesh Daemon pod (label app=kmesh) in kmesh-system. |
95 | | -func getFirstKmeshPod() (string, error) { |
96 | | - cmd := `kubectl get pods -n kmesh-system -l app=kmesh -o jsonpath='{.items[0].metadata.name}'` |
97 | | - out, err := shell.Execute(true, cmd) |
98 | | - if err != nil { |
99 | | - return "", fmt.Errorf("error retrieving kmesh daemon pod name: %v", err) |
100 | | - } |
101 | | - trimmed := strings.TrimSpace(out) |
102 | | - if trimmed == "" { |
103 | | - return "", fmt.Errorf("no Kmesh daemon pod found in kmesh-system namespace") |
104 | | - } |
105 | | - return trimmed, nil |
| 129 | + t.Log("kmeshctl authz commands test passed successfully.") |
| 130 | + }) |
106 | 131 | } |
0 commit comments