import { describe, it, expect, vi } from "vitest"; import { ensureTenant } from "../../src/tenant-orchestrator.js"; function makeMockClients() { const calls: { kind: string; name: string; namespace?: string; body?: unknown }[] = []; function track(kind: string) { return vi.fn(async (...args: unknown[]) => { const arg = (args[0] ?? {}) as { name?: string; namespace?: string; body?: unknown }; calls.push({ kind, name: arg.name ?? "", namespace: arg.namespace, body: arg.body }); return { body: arg.body }; }); } return { calls, core: { createNamespace: track("Namespace"), readNamespacedServiceAccount: vi.fn().mockRejectedValue({ code: 404 }), createNamespacedServiceAccount: track("ServiceAccount"), replaceNamespacedServiceAccount: track("ServiceAccountReplace"), readNamespacedResourceQuota: vi.fn().mockRejectedValue({ code: 404 }), createNamespacedResourceQuota: track("ResourceQuota"), replaceNamespacedResourceQuota: track("ResourceQuotaReplace"), readNamespacedLimitRange: vi.fn().mockRejectedValue({ code: 404 }), createNamespacedLimitRange: track("LimitRange"), replaceNamespacedLimitRange: track("LimitRangeReplace"), readNamespace: vi.fn().mockRejectedValue({ code: 404 }), }, rbac: { readNamespacedRole: vi.fn().mockRejectedValue({ code: 404 }), createNamespacedRole: track("Role"), replaceNamespacedRole: track("RoleReplace"), readNamespacedRoleBinding: vi.fn().mockRejectedValue({ code: 404 }), createNamespacedRoleBinding: track("RoleBinding"), replaceNamespacedRoleBinding: track("RoleBindingReplace"), }, networking: { readNamespacedNetworkPolicy: vi.fn().mockRejectedValue({ code: 404 }), createNamespacedNetworkPolicy: track("NetworkPolicy"), replaceNamespacedNetworkPolicy: track("NetworkPolicyReplace"), deleteNamespacedNetworkPolicy: vi.fn().mockRejectedValue({ code: 404 }), }, custom: { getNamespacedCustomObject: vi.fn().mockRejectedValue({ code: 404 }), createNamespacedCustomObject: track("CiliumNetworkPolicy"), replaceNamespacedCustomObject: track("CiliumNetworkPolicyReplace"), deleteNamespacedCustomObject: vi.fn().mockRejectedValue({ code: 404 }), }, }; } describe("ensureTenant", () => { const baseInput = { namespace: "paperclip-acme", companyId: "11111111-1111-1111-1111-111111111111", paperclipServerNamespace: "paperclip", serviceAccountAnnotations: {}, egressMode: "standard" as const, egressAllowFqdns: ["api.anthropic.com"], egressAllowCidrs: [] as string[], resourceQuota: { pods: "20", requestsCpu: "5", requestsMemory: "20Gi", limitsCpu: "20", limitsMemory: "80Gi" }, }; it("creates all required resources in the correct order on a fresh tenant", async () => { const clients = makeMockClients(); await ensureTenant(clients as never, baseInput); const order = clients.calls.map((c) => c.kind); expect(order).toEqual([ "Namespace", "ServiceAccount", "Role", "RoleBinding", "ResourceQuota", "LimitRange", "NetworkPolicy", "NetworkPolicy", ]); }); it("creates a CiliumNetworkPolicy instead of standard egress when egressMode=cilium", async () => { const clients = makeMockClients(); await ensureTenant(clients as never, { ...baseInput, egressMode: "cilium" }); const cnpCall = clients.calls.find((c) => c.kind === "CiliumNetworkPolicy"); expect(cnpCall).toBeDefined(); const npCalls = clients.calls.filter((c) => c.kind === "NetworkPolicy"); expect(npCalls).toHaveLength(1); expect((npCalls[0].body as { metadata: { name: string } }).metadata.name).toBe("paperclip-deny-all"); }); it("applies serviceAccountAnnotations to the ServiceAccount", async () => { const clients = makeMockClients(); await ensureTenant(clients as never, { ...baseInput, serviceAccountAnnotations: { "eks.amazonaws.com/role-arn": "arn:aws:iam::123:role/paperclip" }, }); const saCall = clients.calls.find((c) => c.kind === "ServiceAccount"); const sa = saCall!.body as { metadata: { annotations: Record } }; expect(sa.metadata.annotations["eks.amazonaws.com/role-arn"]).toBe("arn:aws:iam::123:role/paperclip"); }); it("does not recreate a namespace that already exists", async () => { const clients = makeMockClients(); clients.core.readNamespace.mockResolvedValue({ body: { metadata: { name: baseInput.namespace } } }); await ensureTenant(clients as never, baseInput); expect(clients.core.createNamespace).not.toHaveBeenCalled(); }); it("reconciles existing managed resources with the latest desired manifests", async () => { const clients = makeMockClients(); const existing = { metadata: { resourceVersion: "rv-1" } }; clients.core.readNamespace.mockResolvedValue({ metadata: { name: baseInput.namespace } }); clients.core.readNamespacedServiceAccount.mockResolvedValue(existing); clients.rbac.readNamespacedRole.mockResolvedValue(existing); clients.rbac.readNamespacedRoleBinding.mockResolvedValue(existing); clients.core.readNamespacedResourceQuota.mockResolvedValue(existing); clients.core.readNamespacedLimitRange.mockResolvedValue(existing); clients.networking.readNamespacedNetworkPolicy.mockResolvedValue(existing); await ensureTenant(clients as never, { ...baseInput, serviceAccountAnnotations: { "eks.amazonaws.com/role-arn": "arn:aws:iam::123:role/paperclip" }, resourceQuota: { ...baseInput.resourceQuota, pods: "25" }, }); expect(clients.core.replaceNamespacedServiceAccount).toHaveBeenCalledWith( expect.objectContaining({ body: expect.objectContaining({ metadata: expect.objectContaining({ annotations: { "eks.amazonaws.com/role-arn": "arn:aws:iam::123:role/paperclip" }, resourceVersion: "rv-1", }), }), }), ); expect(clients.core.replaceNamespacedResourceQuota).toHaveBeenCalledWith( expect.objectContaining({ body: expect.objectContaining({ metadata: expect.objectContaining({ resourceVersion: "rv-1" }), spec: expect.objectContaining({ hard: expect.objectContaining({ pods: "25" }) }), }), }), ); expect(clients.networking.replaceNamespacedNetworkPolicy).toHaveBeenCalled(); }); it("removes stale standard egress NetworkPolicy when cilium mode is selected", async () => { const clients = makeMockClients(); await ensureTenant(clients as never, { ...baseInput, egressMode: "cilium" }); expect(clients.networking.deleteNamespacedNetworkPolicy).toHaveBeenCalledWith({ namespace: baseInput.namespace, name: "paperclip-egress-allow", }); }); it("handles concurrent first-run create conflicts by rereading and replacing managed resources", async () => { const clients = makeMockClients(); const existing = { metadata: { resourceVersion: "rv-race" } }; clients.core.createNamespace.mockRejectedValueOnce({ code: 409 }); clients.core.readNamespacedServiceAccount .mockRejectedValueOnce({ code: 404 }) .mockResolvedValue(existing); clients.core.createNamespacedServiceAccount.mockRejectedValueOnce({ code: 409 }); await ensureTenant(clients as never, baseInput); expect(clients.core.createNamespace).toHaveBeenCalled(); expect(clients.core.replaceNamespacedServiceAccount).toHaveBeenCalledWith( expect.objectContaining({ body: expect.objectContaining({ metadata: expect.objectContaining({ resourceVersion: "rv-race" }), }), }), ); }); });