+ {KUBECONFIG_EXEC_AUTHENTICATION_ERROR} +
+ )} > ); }; diff --git a/ui/types/formSchemas.test.ts b/ui/types/formSchemas.test.ts index e4fa3ea663..58eb33128f 100644 --- a/ui/types/formSchemas.test.ts +++ b/ui/types/formSchemas.test.ts @@ -150,3 +150,73 @@ describe("addCredentialsFormSchema - okta", () => { ); }); }); + +describe("addCredentialsFormSchema - kubernetes", () => { + const BASE_KUBERNETES_VALUES = { + [ProviderCredentialFields.PROVIDER_ID]: "provider-kubernetes-1", + [ProviderCredentialFields.PROVIDER_TYPE]: "kubernetes", + } as const; + + it("accepts kubeconfig content without exec authentication", () => { + const schema = addCredentialsFormSchema("kubernetes"); + + const result = schema.safeParse({ + ...BASE_KUBERNETES_VALUES, + [ProviderCredentialFields.KUBECONFIG_CONTENT]: `apiVersion: v1 +kind: Config +users: + - name: test-user + user: + token: test-token`, + }); + + expect(result.success).toBe(true); + }); + + it("reports kubeconfig exec authentication on kubeconfig_content field", () => { + const schema = addCredentialsFormSchema("kubernetes"); + + const result = schema.safeParse({ + ...BASE_KUBERNETES_VALUES, + [ProviderCredentialFields.KUBECONFIG_CONTENT]: `apiVersion: v1 +kind: Config +users: + - name: test-user + user: + exec: + apiVersion: client.authentication.k8s.io/v1 + command: kubectl`, + }); + + expect(result.success).toBe(false); + if (result.success) return; + + expect(result.error.issues).toContainEqual( + expect.objectContaining({ + path: [ProviderCredentialFields.KUBECONFIG_CONTENT], + }), + ); + }); + + it("accepts malformed kubeconfig content for backend validation", () => { + const schema = addCredentialsFormSchema("kubernetes"); + + const result = schema.safeParse({ + ...BASE_KUBERNETES_VALUES, + [ProviderCredentialFields.KUBECONFIG_CONTENT]: "apiVersion: [", + }); + + expect(result.success).toBe(true); + }); + + it("accepts non-mapping kubeconfig content for backend validation", () => { + const schema = addCredentialsFormSchema("kubernetes"); + + const result = schema.safeParse({ + ...BASE_KUBERNETES_VALUES, + [ProviderCredentialFields.KUBECONFIG_CONTENT]: "[]", + }); + + expect(result.success).toBe(true); + }); +}); diff --git a/ui/types/formSchemas.ts b/ui/types/formSchemas.ts index 81aa0889fa..bba1027585 100644 --- a/ui/types/formSchemas.ts +++ b/ui/types/formSchemas.ts @@ -1,3 +1,4 @@ +import yaml from "js-yaml"; import { z } from "zod"; import { ProviderCredentialFields } from "@/lib/provider-credentials/provider-credential-fields"; @@ -5,6 +6,35 @@ import { validateMutelistYaml, validateYaml } from "@/lib/yaml"; import { PROVIDER_TYPES, ProviderType } from "./providers"; +export const KUBECONFIG_EXEC_AUTHENTICATION_ERROR = + "Kubernetes kubeconfig exec authentication is not supported in Prowler Cloud for security reasons."; + +const isRecord = (value: unknown): value is Record