diff --git a/test/e2e/metrics_test.go b/test/e2e/metrics_test.go new file mode 100644 index 000000000..9d7b6a643 --- /dev/null +++ b/test/e2e/metrics_test.go @@ -0,0 +1,85 @@ +package e2e + +import ( + "bytes" + "os/exec" + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +// nolint:gosec +func TestOperatorControllerMetrics(t *testing.T) { + var ( + token string + curlPod = "curl-metrics" + namespace = "olmv1-system" + ) + + // Step 1: Create ClusterRoleBinding for metrics access + t.Log("Creating ClusterRoleBinding for operator controller metrics") + cmd := exec.Command("kubectl", "create", "clusterrolebinding", "operator-controller-metrics-binding", + "--clusterrole=operator-controller-metrics-reader", + "--serviceaccount="+namespace+":operator-controller-controller-manager") + output, err := cmd.CombinedOutput() + require.NoError(t, err, "Error creating ClusterRoleBinding: %s", string(output)) + + // Step 2: Generate ServiceAccount Token + t.Log("Generating ServiceAccount token") + tokenCmd := exec.Command("kubectl", "create", "token", "operator-controller-controller-manager", "-n", namespace) + tokenOutput, err := tokenCmd.Output() + require.NoError(t, err, "Error creating token: %s", string(tokenOutput)) + token = string(bytes.TrimSpace(tokenOutput)) + + // Step 3: Create and Run the Curl Pod + t.Log("Creating curl pod to validate the metrics endpoint") + cmd = exec.Command("kubectl", "run", curlPod, + "--image=curlimages/curl:7.87.0", "-n", namespace, + "--restart=Never", + "--overrides", `{ + "spec": { + "containers": [{ + "name": "curl", + "image": "curlimages/curl:7.87.0", + "command": ["sh", "-c", "sleep 3600"], + "securityContext": { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": ["ALL"] + }, + "runAsNonRoot": true, + "runAsUser": 1000, + "seccompProfile": { + "type": "RuntimeDefault" + } + } + }], + "serviceAccountName": "operator-controller-controller-manager" + } + }`) + output, err = cmd.CombinedOutput() + require.NoError(t, err, "Error creating curl pod: %s", string(output)) + + // Step 4: Validate Pod Readiness + t.Log("Waiting for the curl pod to be ready") + require.Eventually(t, func() bool { + statusCmd := exec.Command("kubectl", "get", "pod", curlPod, "-n", namespace, "-o", "jsonpath={.status.phase}") + statusOutput, _ := statusCmd.Output() + return string(bytes.TrimSpace(statusOutput)) == "Running" + }, 60*time.Second, 5*time.Second, "Curl pod is not running") + + // Step 5: Call the Metrics Endpoint + t.Log("Validating the metrics endpoint") + metricsURL := "https://operator-controller-controller-manager-metrics-service." + namespace + ".svc.cluster.local:8443/metrics" + curlCmd := exec.Command("kubectl", "exec", curlPod, "-n", namespace, "--", + "curl", "-v", "-k", "-H", "Authorization: Bearer "+token, metricsURL) + output, err = curlCmd.CombinedOutput() + require.NoError(t, err, "Error calling metrics endpoint: %s", string(output)) + require.Contains(t, string(output), "200 OK", "Metrics endpoint did not return 200 OK") + + // Step 6: Cleanup + t.Log("Cleaning up resources") + _ = exec.Command("kubectl", "delete", "pod", curlPod, "-n", namespace, "--ignore-not-found=true").Run() + _ = exec.Command("kubectl", "delete", "clusterrolebinding", "operator-controller-metrics-binding", "--ignore-not-found=true").Run() +}