diff --git a/package-lock.json b/package-lock.json index fdd6bc5b9..2c4c6d03c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "packages": { "": { "name": "@flanksource/flanksource-ui", - "version": "1.0.779", + "version": "1.0.794", "dependencies": { "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@clerk/nextjs": "^5.3.0", diff --git a/public/mockServiceWorker.js b/public/mockServiceWorker.js index f7c6e5f52..51d85eeeb 100644 --- a/public/mockServiceWorker.js +++ b/public/mockServiceWorker.js @@ -8,121 +8,121 @@ * - Please do NOT serve this file on production. */ -const INTEGRITY_CHECKSUM = "3d6b9f06410d179a7f7404d4bf4c3c70"; -const activeClientIds = new Set(); +const INTEGRITY_CHECKSUM = '3d6b9f06410d179a7f7404d4bf4c3c70' +const activeClientIds = new Set() -self.addEventListener("install", function () { - self.skipWaiting(); -}); +self.addEventListener('install', function () { + self.skipWaiting() +}) -self.addEventListener("activate", function (event) { - event.waitUntil(self.clients.claim()); -}); +self.addEventListener('activate', function (event) { + event.waitUntil(self.clients.claim()) +}) -self.addEventListener("message", async function (event) { - const clientId = event.source.id; +self.addEventListener('message', async function (event) { + const clientId = event.source.id if (!clientId || !self.clients) { - return; + return } - const client = await self.clients.get(clientId); + const client = await self.clients.get(clientId) if (!client) { - return; + return } const allClients = await self.clients.matchAll({ - type: "window" - }); + type: 'window', + }) switch (event.data) { - case "KEEPALIVE_REQUEST": { + case 'KEEPALIVE_REQUEST': { sendToClient(client, { - type: "KEEPALIVE_RESPONSE" - }); - break; + type: 'KEEPALIVE_RESPONSE', + }) + break } - case "INTEGRITY_CHECK_REQUEST": { + case 'INTEGRITY_CHECK_REQUEST': { sendToClient(client, { - type: "INTEGRITY_CHECK_RESPONSE", - payload: INTEGRITY_CHECKSUM - }); - break; + type: 'INTEGRITY_CHECK_RESPONSE', + payload: INTEGRITY_CHECKSUM, + }) + break } - case "MOCK_ACTIVATE": { - activeClientIds.add(clientId); + case 'MOCK_ACTIVATE': { + activeClientIds.add(clientId) sendToClient(client, { - type: "MOCKING_ENABLED", - payload: true - }); - break; + type: 'MOCKING_ENABLED', + payload: true, + }) + break } - case "MOCK_DEACTIVATE": { - activeClientIds.delete(clientId); - break; + case 'MOCK_DEACTIVATE': { + activeClientIds.delete(clientId) + break } - case "CLIENT_CLOSED": { - activeClientIds.delete(clientId); + case 'CLIENT_CLOSED': { + activeClientIds.delete(clientId) const remainingClients = allClients.filter((client) => { - return client.id !== clientId; - }); + return client.id !== clientId + }) // Unregister itself when there are no more clients if (remainingClients.length === 0) { - self.registration.unregister(); + self.registration.unregister() } - break; + break } } -}); +}) -self.addEventListener("fetch", function (event) { - const { request } = event; - const accept = request.headers.get("accept") || ""; +self.addEventListener('fetch', function (event) { + const { request } = event + const accept = request.headers.get('accept') || '' // Bypass server-sent events. - if (accept.includes("text/event-stream")) { - return; + if (accept.includes('text/event-stream')) { + return } // Bypass navigation requests. - if (request.mode === "navigate") { - return; + if (request.mode === 'navigate') { + return } // Opening the DevTools triggers the "only-if-cached" request // that cannot be handled by the worker. Bypass such requests. - if (request.cache === "only-if-cached" && request.mode !== "same-origin") { - return; + if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') { + return } // Bypass all requests when there are no active clients. // Prevents the self-unregistered worked from handling requests // after it's been deleted (still remains active until the next reload). if (activeClientIds.size === 0) { - return; + return } // Generate unique request ID. - const requestId = Math.random().toString(16).slice(2); + const requestId = Math.random().toString(16).slice(2) event.respondWith( handleRequest(event, requestId).catch((error) => { - if (error.name === "NetworkError") { + if (error.name === 'NetworkError') { console.warn( '[MSW] Successfully emulated a network error for the "%s %s" request.', request.method, - request.url - ); - return; + request.url, + ) + return } // At this point, any exception indicates an issue with the original request/response. @@ -131,24 +131,24 @@ self.addEventListener("fetch", function (event) { [MSW] Caught an exception from the "%s %s" request (%s). This is probably not a problem with Mock Service Worker. There is likely an additional logging output above.`, request.method, request.url, - `${error.name}: ${error.message}` - ); - }) - ); -}); + `${error.name}: ${error.message}`, + ) + }), + ) +}) async function handleRequest(event, requestId) { - const client = await resolveMainClient(event); - const response = await getResponse(event, client, requestId); + const client = await resolveMainClient(event) + const response = await getResponse(event, client, requestId) // Send back the response clone for the "response:*" life-cycle events. // Ensure MSW is active and ready to handle the message, otherwise // this message will pend indefinitely. if (client && activeClientIds.has(client.id)) { - (async function () { - const clonedResponse = response.clone(); + ;(async function () { + const clonedResponse = response.clone() sendToClient(client, { - type: "RESPONSE", + type: 'RESPONSE', payload: { requestId, type: clonedResponse.type, @@ -158,13 +158,13 @@ async function handleRequest(event, requestId) { body: clonedResponse.body === null ? null : await clonedResponse.text(), headers: Object.fromEntries(clonedResponse.headers.entries()), - redirected: clonedResponse.redirected - } - }); - })(); + redirected: clonedResponse.redirected, + }, + }) + })() } - return response; + return response } // Resolve the main client for the given event. @@ -172,49 +172,49 @@ async function handleRequest(event, requestId) { // that registered the worker. It's with the latter the worker should // communicate with during the response resolving phase. async function resolveMainClient(event) { - const client = await self.clients.get(event.clientId); + const client = await self.clients.get(event.clientId) - if (client?.frameType === "top-level") { - return client; + if (client?.frameType === 'top-level') { + return client } const allClients = await self.clients.matchAll({ - type: "window" - }); + type: 'window', + }) return allClients .filter((client) => { // Get only those clients that are currently visible. - return client.visibilityState === "visible"; + return client.visibilityState === 'visible' }) .find((client) => { // Find the client ID that's recorded in the // set of clients that have registered the worker. - return activeClientIds.has(client.id); - }); + return activeClientIds.has(client.id) + }) } async function getResponse(event, client, requestId) { - const { request } = event; - const clonedRequest = request.clone(); + const { request } = event + const clonedRequest = request.clone() function passthrough() { // Clone the request because it might've been already used // (i.e. its body has been read and sent to the client). - const headers = Object.fromEntries(clonedRequest.headers.entries()); + const headers = Object.fromEntries(clonedRequest.headers.entries()) // Remove MSW-specific request headers so the bypassed requests // comply with the server's CORS preflight check. // Operate with the headers as an object because request "Headers" // are immutable. - delete headers["x-msw-bypass"]; + delete headers['x-msw-bypass'] - return fetch(clonedRequest, { headers }); + return fetch(clonedRequest, { headers }) } // Bypass mocking when the client is not active. if (!client) { - return passthrough(); + return passthrough() } // Bypass initial page load requests (i.e. static assets). @@ -222,18 +222,18 @@ async function getResponse(event, client, requestId) { // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet // and is not ready to handle requests. if (!activeClientIds.has(client.id)) { - return passthrough(); + return passthrough() } // Bypass requests with the explicit bypass header. // Such requests can be issued by "ctx.fetch()". - if (request.headers.get("x-msw-bypass") === "true") { - return passthrough(); + if (request.headers.get('x-msw-bypass') === 'true') { + return passthrough() } // Notify the client that a request has been intercepted. const clientMessage = await sendToClient(client, { - type: "REQUEST", + type: 'REQUEST', payload: { id: requestId, url: request.url, @@ -249,55 +249,55 @@ async function getResponse(event, client, requestId) { referrerPolicy: request.referrerPolicy, body: await request.text(), bodyUsed: request.bodyUsed, - keepalive: request.keepalive - } - }); + keepalive: request.keepalive, + }, + }) switch (clientMessage.type) { - case "MOCK_RESPONSE": { - return respondWithMock(clientMessage.data); + case 'MOCK_RESPONSE': { + return respondWithMock(clientMessage.data) } - case "MOCK_NOT_FOUND": { - return passthrough(); + case 'MOCK_NOT_FOUND': { + return passthrough() } - case "NETWORK_ERROR": { - const { name, message } = clientMessage.data; - const networkError = new Error(message); - networkError.name = name; + case 'NETWORK_ERROR': { + const { name, message } = clientMessage.data + const networkError = new Error(message) + networkError.name = name // Rejecting a "respondWith" promise emulates a network error. - throw networkError; + throw networkError } } - return passthrough(); + return passthrough() } function sendToClient(client, message) { return new Promise((resolve, reject) => { - const channel = new MessageChannel(); + const channel = new MessageChannel() channel.port1.onmessage = (event) => { if (event.data && event.data.error) { - return reject(event.data.error); + return reject(event.data.error) } - resolve(event.data); - }; + resolve(event.data) + } - client.postMessage(message, [channel.port2]); - }); + client.postMessage(message, [channel.port2]) + }) } function sleep(timeMs) { return new Promise((resolve) => { - setTimeout(resolve, timeMs); - }); + setTimeout(resolve, timeMs) + }) } async function respondWithMock(response) { - await sleep(response.delay); - return new Response(response.body, response); + await sleep(response.delay) + return new Response(response.body, response) } diff --git a/src/components/Agents/Add/AddAgentForm.tsx b/src/components/Agents/Add/AddAgentForm.tsx index 7fde2da0b..0c599117a 100644 --- a/src/components/Agents/Add/AddAgentForm.tsx +++ b/src/components/Agents/Add/AddAgentForm.tsx @@ -107,7 +107,7 @@ export default function AgentForm({ name: agent?.name ?? "", properties: agent?.properties ?? {}, kubernetes: { - interval: "30m", + schedule: "30m", enabled: false }, pushTelemetry: { @@ -173,7 +173,7 @@ export default function AgentForm({ { label: "12h", value: "12h" }, { label: "24h", value: "24h" } ]} - name="kubernetes.interval" + name="kubernetes.schedule" label="Scrape Interval" hintPosition="top" hint="How often to perform a full reconciliation of changes (in addition to real-time changes from Kubernetes events), set higher for larger clusters." diff --git a/src/components/Agents/InstalAgentInstruction/CLIInstallAgent.tsx b/src/components/Agents/InstalAgentInstruction/CLIInstallAgent.tsx index b260919be..af2e7bc5b 100644 --- a/src/components/Agents/InstalAgentInstruction/CLIInstallAgent.tsx +++ b/src/components/Agents/InstalAgentInstruction/CLIInstallAgent.tsx @@ -1,76 +1,38 @@ -import { GeneratedAgent } from "@flanksource-ui/api/services/agents"; -import { useUser } from "@flanksource-ui/context"; import CodeBlock from "@flanksource-ui/ui/Code/CodeBlock"; import Handlebars from "handlebars"; import { useMemo } from "react"; -import { AgentFormValues } from "../Add/AddAgentForm"; -import { useAgentsBaseURL } from "./useAgentsBaseURL"; +import { TemplateContextData } from "./InstallAgentModal"; -const helmCommand = `helm repo add flanksource https://flanksource.github.io/charts +// This a Handlebars template for the Helm command to install the agent and the +// kubernetes agent if the user has enabled it. +const helmCommand = `helm repo add {{ chart }} {{ repoName }}/{{ chart }} helm repo update -helm install mc-agent flanksource/mission-control-agent -n "mission-control-agent" \\ - --set upstream.createSecret=true \\ - --set upstream.host={{baseUrl}} \\ - --set upstream.username=token \\ - --set upstream.password={{generatedAgent.access_token}} \\ - --set upstream.agentName={{agentFormValues.name}} \\ -{{#if pushTelemetry}} - --set pushTelemetry.enabled=true \\ - --set pushTelemetry.topologyName={{pushTelemetry.topologyName}} -{{/if}} +helm install mc-agent flanksource/mission-control-agent -n "{{{ namespace }}}" \\ + {{#each values}} + --set {{{ this }}} \\ + {{/each}} --create-namespace -{{#if kubeOptions}} -helm install mc-agent-kubernetes flanksource/mission-control-kubernetes -n "mission-control-agent" \\ - --set scraper.clusterName="{{agentFormValues.name}}" \\ - --set scraper.interval="{{kubeOptions.interval}}" +{{#if kubeValues }} +helm install mc-agent-kubernetes flanksource/mission-control-kubernetes -n "{{{ namespace }}}" \\ + {{#each kubeValues}} + --set {{{ this }}} \\ + {{/each}} {{/if}} `; const template = Handlebars.compile(helmCommand); type Props = { - generatedAgent: GeneratedAgent; - agentFormValues?: AgentFormValues; + data: TemplateContextData; }; -export default function CLIInstallAgent({ - generatedAgent, - agentFormValues -}: Props) { - const baseUrl = useAgentsBaseURL(); - const { backendUrl, orgSlug } = useUser(); - +export default function CLIInstallAgent({ data }: Props) { const helmCommandTemplate = useMemo(() => { - const kubeOptions = agentFormValues?.kubernetes; - const pushTelemetry = agentFormValues?.pushTelemetry; - - return template( - { - generatedAgent, - baseUrl, - agentFormValues, - pushTelemetry: pushTelemetry?.enabled - ? { - ...pushTelemetry, - topologyName: orgSlug - ? `${orgSlug}-${pushTelemetry.topologyName}` - : pushTelemetry.topologyName - } - : undefined, - backendUrl, - kubeOptions: kubeOptions - ? { - interval: kubeOptions?.interval, - exclusions: `{${kubeOptions?.exclusions?.join(",")}}` - } - : undefined - }, - {} - ); - }, [agentFormValues, backendUrl, baseUrl, generatedAgent, orgSlug]); + return template(data, {}); + }, [data]); return (
diff --git a/src/components/Agents/InstalAgentInstruction/FluxInstallAgent.tsx b/src/components/Agents/InstalAgentInstruction/FluxInstallAgent.tsx index 944ede344..762e453ae 100644 --- a/src/components/Agents/InstalAgentInstruction/FluxInstallAgent.tsx +++ b/src/components/Agents/InstalAgentInstruction/FluxInstallAgent.tsx @@ -1,52 +1,46 @@ -import { GeneratedAgent } from "@flanksource-ui/api/services/agents"; -import { useUser } from "@flanksource-ui/context"; import { JSONViewer } from "@flanksource-ui/ui/Code/JSONViewer"; import Handlebars from "handlebars"; import { useMemo } from "react"; -import { AgentFormValues } from "../Add/AddAgentForm"; -import { useAgentsBaseURL } from "./useAgentsBaseURL"; +import { TemplateContextData } from "./InstallAgentModal"; +// This a Handlebars template for the HelmRelease to install the agent and the +// kubernetes agent if the user has enabled it. const fluxTemplate = `apiVersion: v1 kind: Namespace metadata: - name: mission-control-agent + name: {{ namespace }} --- +{{#if createRepository}} apiVersion: source.toolkit.fluxcd.io/v1beta1 kind: HelmRepository metadata: - name: flanksource - namespace: mission-control-agent + name: {{ repoName }} + namespace: {{ namespace }} spec: interval: 5m0s url: https://flanksource.github.io/charts --- +{{/if}} apiVersion: helm.toolkit.fluxcd.io/v2beta1 kind: HelmRelease metadata: - name: mission-control - namespace: mission-control-agent + name: {{{ chart }}} + namespace: {{ namespace }} spec: chart: spec: - chart: mission-control-agent + chart: {{{ chart }}} sourceRef: kind: HelmRepository - name: flanksource - namespace: mission-control-agent - interval: 1m + name: {{{ repoName }}} + namespace: {{{ namespace }}} + interval: 5m0s values: - upstream: - createSecret: true - host: {{baseUrl}} - username: token - agentName: {{agentFormValues.name}} - password: {{generatedAgent.access_token}} -{{#if pushTelemetry}} - pushTelemetry: - enabled: true - topologyName: {{pushTelemetry.topologyName}} -{{/if}} -{{#if kubeOptions}} +{{#each values}} + {{{ this }}} +{{/each}} + +{{#if kubeValues}} --- apiVersion: helm.toolkit.fluxcd.io/v2beta1 kind: HelmRelease @@ -62,53 +56,22 @@ spec: name: flanksource namespace: mission-control-agent values: - clusterName: "{{agentFormValues.name}}" - interval: "{{kubeOptions.interval}}" + {{#each kubeValues}} + {{{ this }}} + {{/each}} {{/if}} `; const template = Handlebars.compile(fluxTemplate); type Props = { - generatedAgent: GeneratedAgent; - agentFormValues?: AgentFormValues; + data: TemplateContextData; }; -export default function FluxInstallAgent({ - generatedAgent, - agentFormValues -}: Props) { - const baseUrl = useAgentsBaseURL(); - const { backendUrl, orgSlug } = useUser(); - +export default function FluxInstallAgent({ data }: Props) { const yaml = useMemo(() => { - const kubeOptions = agentFormValues?.kubernetes; - const pushTelemetry = agentFormValues?.pushTelemetry ?? undefined; - - return template( - { - generatedAgent, - baseUrl, - agentFormValues, - pushTelemetry: pushTelemetry?.enabled - ? { - ...pushTelemetry, - topologyName: orgSlug - ? `${orgSlug}-${pushTelemetry.topologyName}` - : pushTelemetry.topologyName - } - : undefined, - backendUrl, - kubeOptions: kubeOptions - ? { - interval: kubeOptions?.interval, - exclusions: kubeOptions?.exclusions - } - : undefined - }, - {} - ); - }, [agentFormValues, backendUrl, baseUrl, generatedAgent, orgSlug]); + return template(data, {}); + }, [data]); return (
diff --git a/src/components/Agents/InstalAgentInstruction/InstallAgentModal.tsx b/src/components/Agents/InstalAgentInstruction/InstallAgentModal.tsx index 77e1dee82..95d5baccd 100644 --- a/src/components/Agents/InstalAgentInstruction/InstallAgentModal.tsx +++ b/src/components/Agents/InstalAgentInstruction/InstallAgentModal.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useMemo, useState } from "react"; import { GeneratedAgent } from "../../../api/services/agents"; import { Button } from "../../../ui/Buttons/Button"; import { Modal } from "../../../ui/Modal"; @@ -6,6 +6,7 @@ import { Tab, Tabs } from "../../../ui/Tabs/Tabs"; import { AgentFormValues } from "../Add/AddAgentForm"; import CLIInstallAgent from "./CLIInstallAgent"; import FluxInstallAgent from "./FluxInstallAgent"; +import { useAgentsBaseURL } from "./useAgentsBaseURL"; export function WarningBox() { return ( @@ -83,6 +84,14 @@ export function MoreInfoBox() { ); } +export type TemplateContextData = { + namespace?: string; + chart?: string; + repoName?: string; + values?: string[]; + kubeValues?: string[]; +}; + type Props = { isOpen: boolean; onClose: () => void; @@ -97,6 +106,45 @@ export default function InstallAgentModal({ agentFormValues }: Props) { const [activeTab, setActiveTab] = useState<"cli" | "flux">("cli"); + const baseUrl = useAgentsBaseURL(); + + const data = useMemo(() => { + const kubeOptions = agentFormValues?.kubernetes; + const pushTelemetry = agentFormValues?.pushTelemetry ?? undefined; + + return { + chart: "mission-control-agent", + namespace: "mission-control-agent", + repoName: "flanksource", + // You can add more values here to be passed to the template for the + // values section of the HelmRelease + values: [ + `upstream.createSecret=true`, + `upstream.host=${baseUrl}`, + `upstream.username=token`, + `upstream.password=${generatedAgent?.access_token}`, + `upstream.agentName=${agentFormValues?.name}`, + ...(pushTelemetry?.enabled + ? [ + `pushTelemetry.enabled=true`, + `pushTelemetry.topologyName=${ + pushTelemetry.topologyName + }-${agentFormValues?.name}` + ] + : []) + ], + // You can add more values here to be passed to the template for the + // kubeValues section of the HelmRelease + kubeValues: kubeOptions + ? [ + `clusterName: "${agentFormValues?.name}"`, + `scraper.schedule: "${kubeOptions.schedule}"` + ] + : [] + } satisfies TemplateContextData; + }, [agentFormValues, baseUrl, generatedAgent]); + + console.log(JSON.stringify(data, null, 2)); return ( setActiveTab(v as any)} > - + - + diff --git a/src/components/Agents/InstalAgentInstruction/__tests__/CLIInstallAgent.unit.test.tsx b/src/components/Agents/InstalAgentInstruction/__tests__/CLIInstallAgent.unit.test.tsx index 022fdf91f..7c3269698 100644 --- a/src/components/Agents/InstalAgentInstruction/__tests__/CLIInstallAgent.unit.test.tsx +++ b/src/components/Agents/InstalAgentInstruction/__tests__/CLIInstallAgent.unit.test.tsx @@ -1,106 +1,68 @@ import { render, screen } from "@testing-library/react"; -import { AuthContext } from "../../../../context"; import InstallAgentModal from "../CLIInstallAgent"; -const testUser = { - id: "testid", - name: "testuser", - email: "testemail" -}; - global.ResizeObserver = jest.fn().mockImplementation(() => ({ observe: jest.fn(), unobserve: jest.fn(), disconnect: jest.fn() })); -describe("InstallAgentModal", () => { - const generatedAgent = { - id: "testid", - username: "testuser", - access_token: "testtoken" - }; +const mockInput = { + chart: "mission-control-agent", + namespace: "mission-control-agent", + repoName: "flanksource", + values: [ + "upstream.createSecret=true", + "upstream.host=http://localhost:3000", + "upstream.username=token", + "upstream.password=password", + "upstream.agentName=test-new-agent-instructions", + "pushTelemetry.enabled=true", + "pushTelemetry.topologyName=https://incident-commander.demo.aws.flanksource.com-test-new-agent-instructions" + ] +}; +const mockInputWithKubOptions = { + chart: "mission-control-agent", + namespace: "mission-control-agent", + repoName: "flanksource", + values: [ + "upstream.createSecret=true", + "upstream.host=http://localhost:3000", + "upstream.username=token", + "upstream.password=password", + "upstream.agentName=test-new-agent-instructions", + "pushTelemetry.enabled=true", + "pushTelemetry.topologyName=https://incident-commander.demo.aws.flanksource.com-test-new-agent-instructions" + ], + kubeValues: [ + 'clusterName: "test-new-agent-instructions"', + 'scraper.schedule: "30m"' + ] +}; + +describe("InstallAgentModal", () => { it("renders the Helm repository installation command", () => { - render( - - - - ); + render(); expect( screen.getByText( - "helm repo add flanksource https://flanksource.github.io/charts", + "helm repo add mission-control-agent flanksource/mission-control-agent", { exact: false } ).textContent - ).toMatchInlineSnapshot(` - "helm repo add flanksource https://flanksource.github.io/charts - - helm repo update - - helm install mc-agent flanksource/mission-control-agent -n "mission-control-agent" \\ - --set upstream.createSecret=true \\ - --set upstream.host=http://localhost \\ - --set upstream.username=token \\ - --set upstream.password=testtoken \\ - --set upstream.agentName= \\ - --create-namespace - - " - `); + ).toMatchSnapshot(); }); it("renders the Helm repository installation command with kube command", () => { - render( - - - - ); + render(); expect( screen.getByText( - "helm repo add flanksource https://flanksource.github.io/charts", + "helm repo add mission-control-agent flanksource/mission-control-agent", { exact: false } ).textContent - ).toMatchInlineSnapshot(` - "helm repo add flanksource https://flanksource.github.io/charts - - helm repo update - - helm install mc-agent flanksource/mission-control-agent -n "mission-control-agent" \\ - --set upstream.createSecret=true \\ - --set upstream.host=http://localhost \\ - --set upstream.username=token \\ - --set upstream.password=testtoken \\ - --set upstream.agentName=testname \\ - --create-namespace - - helm install mc-agent-kubernetes flanksource/mission-control-kubernetes -n "mission-control-agent" \\ - --set scraper.clusterName="testname" \\ - --set scraper.interval="1m" - " - `); + ).toMatchSnapshot(); }); }); diff --git a/src/components/Agents/InstalAgentInstruction/__tests__/FluxInstallAgent.unit.test.tsx b/src/components/Agents/InstalAgentInstruction/__tests__/FluxInstallAgent.unit.test.tsx index 118c38347..a1c9e0e09 100644 --- a/src/components/Agents/InstalAgentInstruction/__tests__/FluxInstallAgent.unit.test.tsx +++ b/src/components/Agents/InstalAgentInstruction/__tests__/FluxInstallAgent.unit.test.tsx @@ -1,13 +1,6 @@ import { fireEvent, render, screen, waitFor } from "@testing-library/react"; -import { AuthContext } from "../../../../context"; import FluxInstallAgent from "../FluxInstallAgent"; -const testUser = { - id: "testid", - name: "testuser", - email: "testemail" -}; - global.ResizeObserver = jest.fn().mockImplementation(() => ({ observe: jest.fn(), unobserve: jest.fn(), @@ -16,6 +9,40 @@ global.ResizeObserver = jest.fn().mockImplementation(() => ({ const writeText = jest.fn(); +const mockInput = { + chart: "mission-control-agent", + namespace: "mission-control-agent", + repoName: "flanksource", + values: [ + "upstream.createSecret=true", + "upstream.host=http://localhost:3000", + "upstream.username=token", + "upstream.password=password", + "upstream.agentName=test-new-agent-instructions", + "pushTelemetry.enabled=true", + "pushTelemetry.topologyName=https://incident-commander.demo.aws.flanksource.com-test-new-agent-instructions" + ] +}; + +const mockInputWithKubOptions = { + chart: "mission-control-agent", + namespace: "mission-control-agent", + repoName: "flanksource", + values: [ + "upstream.createSecret=true", + "upstream.host=http://localhost:3000", + "upstream.username=token", + "upstream.password=password", + "upstream.agentName=test-new-agent-instructions", + "pushTelemetry.enabled=true", + "pushTelemetry.topologyName=https://incident-commander.demo.aws.flanksource.com-test-new-agent-instructions" + ], + kubeValues: [ + 'clusterName: "test-new-agent-instructions"', + 'scraper.schedule: "30m"' + ] +}; + Object.assign(navigator, { clipboard: { writeText @@ -23,30 +50,8 @@ Object.assign(navigator, { }); describe("InstallAgentModal", () => { - const generatedAgent = { - id: "testid", - username: "testuser", - access_token: "testtoken" - }; - it("renders the Helm repository installation command", async () => { - render( - - - - ); + render(); const btn = screen.getByTitle(/Copy to clipboard/i); @@ -55,84 +60,11 @@ describe("InstallAgentModal", () => { await waitFor(() => { expect(writeText).toHaveBeenCalled(); }); - expect(writeText.mock["calls"][0][0]).toMatchInlineSnapshot(` - "apiVersion: v1 - kind: Namespace - metadata: - name: mission-control-agent - --- - apiVersion: source.toolkit.fluxcd.io/v1beta1 - kind: HelmRepository - metadata: - name: flanksource - namespace: mission-control-agent - spec: - interval: 5m0s - url: https://flanksource.github.io/charts - --- - apiVersion: helm.toolkit.fluxcd.io/v2beta1 - kind: HelmRelease - metadata: - name: mission-control - namespace: mission-control-agent - spec: - chart: - spec: - chart: mission-control-agent - sourceRef: - kind: HelmRepository - name: flanksource - namespace: mission-control-agent - interval: 1m - values: - upstream: - createSecret: true - host: http://localhost - username: token - agentName: testname - password: testtoken - --- - apiVersion: helm.toolkit.fluxcd.io/v2beta1 - kind: HelmRelease - metadata: - name: mission-control-kubernetes - namespace: mission-control-agent - spec: - chart: - spec: - chart: mission-control-kubernetes - sourceRef: - kind: HelmRepository - name: flanksource - namespace: mission-control-agent - values: - clusterName: "testname" - interval: "" - " - `); + expect(writeText.mock["calls"][0][0]).toMatchSnapshot(); }); it("renders the Helm repository installation command with kube command", async () => { - render( - - - - ); + render(); const btn = screen.getByTitle(/Copy to clipboard/i); fireEvent.click(btn); @@ -140,60 +72,6 @@ describe("InstallAgentModal", () => { await waitFor(() => { expect(writeText).toHaveBeenCalled(); }); - expect(writeText.mock["calls"][0][0]).toMatchInlineSnapshot(` - "apiVersion: v1 - kind: Namespace - metadata: - name: mission-control-agent - --- - apiVersion: source.toolkit.fluxcd.io/v1beta1 - kind: HelmRepository - metadata: - name: flanksource - namespace: mission-control-agent - spec: - interval: 5m0s - url: https://flanksource.github.io/charts - --- - apiVersion: helm.toolkit.fluxcd.io/v2beta1 - kind: HelmRelease - metadata: - name: mission-control - namespace: mission-control-agent - spec: - chart: - spec: - chart: mission-control-agent - sourceRef: - kind: HelmRepository - name: flanksource - namespace: mission-control-agent - interval: 1m - values: - upstream: - createSecret: true - host: http://localhost - username: token - agentName: testname - password: testtoken - --- - apiVersion: helm.toolkit.fluxcd.io/v2beta1 - kind: HelmRelease - metadata: - name: mission-control-kubernetes - namespace: mission-control-agent - spec: - chart: - spec: - chart: mission-control-kubernetes - sourceRef: - kind: HelmRepository - name: flanksource - namespace: mission-control-agent - values: - clusterName: "testname" - interval: "" - " - `); + expect(writeText.mock["calls"][0][0]).toMatchSnapshot(); }); }); diff --git a/src/components/Agents/InstalAgentInstruction/__tests__/__snapshots__/CLIInstallAgent.unit.test.tsx.snap b/src/components/Agents/InstalAgentInstruction/__tests__/__snapshots__/CLIInstallAgent.unit.test.tsx.snap new file mode 100644 index 000000000..bf646d2d1 --- /dev/null +++ b/src/components/Agents/InstalAgentInstruction/__tests__/__snapshots__/CLIInstallAgent.unit.test.tsx.snap @@ -0,0 +1,40 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`InstallAgentModal renders the Helm repository installation command 1`] = ` +"helm repo add mission-control-agent flanksource/mission-control-agent + +helm repo update + +helm install mc-agent flanksource/mission-control-agent -n "mission-control-agent" \\ + --set upstream.createSecret=true \\ + --set upstream.host=http://localhost:3000 \\ + --set upstream.username=token \\ + --set upstream.password=password \\ + --set upstream.agentName=test-new-agent-instructions \\ + --set pushTelemetry.enabled=true \\ + --set pushTelemetry.topologyName=https://incident-commander.demo.aws.flanksource.com-test-new-agent-instructions \\ + --create-namespace + +" +`; + +exports[`InstallAgentModal renders the Helm repository installation command with kube command 1`] = ` +"helm repo add mission-control-agent flanksource/mission-control-agent + +helm repo update + +helm install mc-agent flanksource/mission-control-agent -n "mission-control-agent" \\ + --set upstream.createSecret=true \\ + --set upstream.host=http://localhost:3000 \\ + --set upstream.username=token \\ + --set upstream.password=password \\ + --set upstream.agentName=test-new-agent-instructions \\ + --set pushTelemetry.enabled=true \\ + --set pushTelemetry.topologyName=https://incident-commander.demo.aws.flanksource.com-test-new-agent-instructions \\ + --create-namespace + +helm install mc-agent-kubernetes flanksource/mission-control-kubernetes -n "mission-control-agent" \\ + --set clusterName: "test-new-agent-instructions" \\ + --set scraper.schedule: "30m" \\ +" +`; diff --git a/src/components/Agents/InstalAgentInstruction/__tests__/__snapshots__/FluxInstallAgent.unit.test.tsx.snap b/src/components/Agents/InstalAgentInstruction/__tests__/__snapshots__/FluxInstallAgent.unit.test.tsx.snap new file mode 100644 index 000000000..dc77868e3 --- /dev/null +++ b/src/components/Agents/InstalAgentInstruction/__tests__/__snapshots__/FluxInstallAgent.unit.test.tsx.snap @@ -0,0 +1,65 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`InstallAgentModal renders the Helm repository installation command 1`] = ` +"apiVersion: v1 +kind: Namespace +metadata: + name: mission-control-agent +--- +apiVersion: helm.toolkit.fluxcd.io/v2beta1 +kind: HelmRelease +metadata: + name: mission-control-agent + namespace: mission-control-agent +spec: + chart: + spec: + chart: mission-control-agent + sourceRef: + kind: HelmRepository + name: flanksource + namespace: mission-control-agent + interval: 5m0s + values: + upstream.createSecret=true + upstream.host=http://localhost:3000 + upstream.username=token + upstream.password=password + upstream.agentName=test-new-agent-instructions + pushTelemetry.enabled=true + pushTelemetry.topologyName=https://incident-commander.demo.aws.flanksource.com-test-new-agent-instructions + + " +`; + +exports[`InstallAgentModal renders the Helm repository installation command with kube command 1`] = ` +"apiVersion: v1 +kind: Namespace +metadata: + name: mission-control-agent +--- +apiVersion: helm.toolkit.fluxcd.io/v2beta1 +kind: HelmRelease +metadata: + name: mission-control-agent + namespace: mission-control-agent +spec: + chart: + spec: + chart: mission-control-agent + sourceRef: + kind: HelmRepository + name: flanksource + namespace: mission-control-agent + interval: 5m0s + values: + upstream.createSecret=true + upstream.host=http://localhost:3000 + upstream.username=token + upstream.password=password + upstream.agentName=test-new-agent-instructions + pushTelemetry.enabled=true + pushTelemetry.topologyName=https://incident-commander.demo.aws.flanksource.com-test-new-agent-instructions + + " +`;