diff --git a/src/components/Agents/InstalAgentInstruction/CLIInstallAgent.tsx b/src/components/Agents/InstalAgentInstruction/CLIInstallAgent.tsx deleted file mode 100644 index af2e7bc5b..000000000 --- a/src/components/Agents/InstalAgentInstruction/CLIInstallAgent.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import CodeBlock from "@flanksource-ui/ui/Code/CodeBlock"; -import Handlebars from "handlebars"; -import { useMemo } from "react"; -import { TemplateContextData } from "./InstallAgentModal"; - -// 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 "{{{ namespace }}}" \\ - {{#each values}} - --set {{{ this }}} \\ - {{/each}} - --create-namespace - -{{#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 = { - data: TemplateContextData; -}; - -export default function CLIInstallAgent({ data }: Props) { - const helmCommandTemplate = useMemo(() => { - return template(data, {}); - }, [data]); - - return ( -
-

Copy the following command to install agent

- -
- ); -} diff --git a/src/components/Agents/InstalAgentInstruction/FluxInstallAgent.tsx b/src/components/Agents/InstalAgentInstruction/FluxInstallAgent.tsx deleted file mode 100644 index 762e453ae..000000000 --- a/src/components/Agents/InstalAgentInstruction/FluxInstallAgent.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import { JSONViewer } from "@flanksource-ui/ui/Code/JSONViewer"; -import Handlebars from "handlebars"; -import { useMemo } from "react"; -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: {{ namespace }} ---- -{{#if createRepository}} -apiVersion: source.toolkit.fluxcd.io/v1beta1 -kind: HelmRepository -metadata: - name: {{ repoName }} - namespace: {{ namespace }} -spec: - interval: 5m0s - url: https://flanksource.github.io/charts ---- -{{/if}} -apiVersion: helm.toolkit.fluxcd.io/v2beta1 -kind: HelmRelease -metadata: - name: {{{ chart }}} - namespace: {{ namespace }} -spec: - chart: - spec: - chart: {{{ chart }}} - sourceRef: - kind: HelmRepository - name: {{{ repoName }}} - namespace: {{{ namespace }}} - interval: 5m0s - values: -{{#each values}} - {{{ this }}} -{{/each}} - -{{#if kubeValues}} ---- -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: - {{#each kubeValues}} - {{{ this }}} - {{/each}} -{{/if}} - `; - -const template = Handlebars.compile(fluxTemplate); - -type Props = { - data: TemplateContextData; -}; - -export default function FluxInstallAgent({ data }: Props) { - const yaml = useMemo(() => { - return template(data, {}); - }, [data]); - - return ( -
- -
- ); -} diff --git a/src/components/Agents/InstalAgentInstruction/InstallAgentModal.tsx b/src/components/Agents/InstalAgentInstruction/InstallAgentModal.tsx index 95d5baccd..4952c32e2 100644 --- a/src/components/Agents/InstalAgentInstruction/InstallAgentModal.tsx +++ b/src/components/Agents/InstalAgentInstruction/InstallAgentModal.tsx @@ -1,27 +1,13 @@ -import { useMemo, useState } from "react"; +import HelmInstallationSnippets, { + ChartData +} from "@flanksource-ui/ui/HelmSnippet/HelmInstallationSnippets"; +import { useMemo } from "react"; import { GeneratedAgent } from "../../../api/services/agents"; import { Button } from "../../../ui/Buttons/Button"; import { Modal } from "../../../ui/Modal"; -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 ( -
- - Access token will be shown only once. Please copy it and store it - securely. - -
- ); -} - export function MoreInfoBox() { return (
@@ -84,14 +70,6 @@ export function MoreInfoBox() { ); } -export type TemplateContextData = { - namespace?: string; - chart?: string; - repoName?: string; - values?: string[]; - kubeValues?: string[]; -}; - type Props = { isOpen: boolean; onClose: () => void; @@ -105,47 +83,81 @@ export default function InstallAgentModal({ generatedAgent, 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 + return [ + { + chart: "mission-control-agent", + namespace: "mission-control-agent", + repoName: "flanksource", + createNamespace: true, + createRepo: true, + updateHelmRepo: true, + releaseName: "mc-agent", + // You can add more values here to be passed to the template for the + // values section of the HelmRelease + values: [ + { + key: "upstream.createSecret", + value: "true" + }, + { + key: "upstream.host", + value: baseUrl + }, + { + key: "upstream.username", + value: "token" + }, + { + key: "upstream.password", + value: generatedAgent?.access_token + }, + { + key: "upstream.agentName", + value: agentFormValues?.name + }, + ...(pushTelemetry?.enabled + ? [ + { + key: "pushTelemetry.enabled", + value: "true" + }, + { + key: "pushTelemetry.topologyName", + value: `${pushTelemetry.topologyName}` + } + ] + : []) + ] + }, + ...(kubeOptions?.enabled ? [ - `clusterName: "${agentFormValues?.name}"`, - `scraper.schedule: "${kubeOptions.schedule}"` + { + chart: "mission-control-kubernetes", + namespace: "mission-control-agent", + repoName: "flanksource", + releaseName: "mc-agent-kubernetes", + values: [ + { + key: "clusterName", + value: agentFormValues?.name + }, + { + key: "scraper.schedule", + value: kubeOptions.schedule + } + ] + } ] - : [] - } satisfies TemplateContextData; + : []) + ] satisfies ChartData[]; }, [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 deleted file mode 100644 index 7c3269698..000000000 --- a/src/components/Agents/InstalAgentInstruction/__tests__/CLIInstallAgent.unit.test.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import { render, screen } from "@testing-library/react"; -import InstallAgentModal from "../CLIInstallAgent"; - -global.ResizeObserver = jest.fn().mockImplementation(() => ({ - observe: jest.fn(), - unobserve: jest.fn(), - disconnect: 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"' - ] -}; - -describe("InstallAgentModal", () => { - it("renders the Helm repository installation command", () => { - render(); - expect( - screen.getByText( - "helm repo add mission-control-agent flanksource/mission-control-agent", - { - exact: false - } - ).textContent - ).toMatchSnapshot(); - }); - - it("renders the Helm repository installation command with kube command", () => { - render(); - expect( - screen.getByText( - "helm repo add mission-control-agent flanksource/mission-control-agent", - { - exact: false - } - ).textContent - ).toMatchSnapshot(); - }); -}); diff --git a/src/components/Agents/InstalAgentInstruction/__tests__/FluxInstallAgent.unit.test.tsx b/src/components/Agents/InstalAgentInstruction/__tests__/FluxInstallAgent.unit.test.tsx deleted file mode 100644 index a1c9e0e09..000000000 --- a/src/components/Agents/InstalAgentInstruction/__tests__/FluxInstallAgent.unit.test.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import { fireEvent, render, screen, waitFor } from "@testing-library/react"; -import FluxInstallAgent from "../FluxInstallAgent"; - -global.ResizeObserver = jest.fn().mockImplementation(() => ({ - observe: jest.fn(), - unobserve: jest.fn(), - disconnect: jest.fn() -})); - -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 - } -}); - -describe("InstallAgentModal", () => { - it("renders the Helm repository installation command", async () => { - render(); - - const btn = screen.getByTitle(/Copy to clipboard/i); - - fireEvent.click(btn); - - await waitFor(() => { - expect(writeText).toHaveBeenCalled(); - }); - expect(writeText.mock["calls"][0][0]).toMatchSnapshot(); - }); - - it("renders the Helm repository installation command with kube command", async () => { - render(); - const btn = screen.getByTitle(/Copy to clipboard/i); - - fireEvent.click(btn); - - await waitFor(() => { - expect(writeText).toHaveBeenCalled(); - }); - 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 deleted file mode 100644 index bf646d2d1..000000000 --- a/src/components/Agents/InstalAgentInstruction/__tests__/__snapshots__/CLIInstallAgent.unit.test.tsx.snap +++ /dev/null @@ -1,40 +0,0 @@ -// 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/ui/DataTable/Hooks/useReactTablePaginationState.tsx b/src/ui/DataTable/Hooks/useReactTablePaginationState.tsx index 02ef6e57e..e19a74797 100644 --- a/src/ui/DataTable/Hooks/useReactTablePaginationState.tsx +++ b/src/ui/DataTable/Hooks/useReactTablePaginationState.tsx @@ -1,11 +1,19 @@ import { OnChangeFn, PaginationState } from "@tanstack/react-table"; +import { useAtom } from "jotai"; +import { atomWithStorage } from "jotai/utils"; import { useCallback } from "react"; import { useSearchParams } from "react-router-dom"; +const pageSizeAtom = atomWithStorage("pageSize", "50", undefined, { + getOnInit: true +}); + export default function useReactTablePaginationState() { + const [pageSizeFromStorage, setPageSizeFromStorage] = useAtom(pageSizeAtom); + const [params, setParams] = useSearchParams({ pageIndex: "0", - pageSize: "50" + pageSize: pageSizeFromStorage ?? "50" }); const pageIndex = parseInt(params.get("pageIndex") ?? "0", 10); @@ -23,8 +31,9 @@ export default function useReactTablePaginationState() { params.set("pageIndex", updated.pageIndex.toString()); params.set("pageSize", updated.pageSize.toString()); setParams(params); + setPageSizeFromStorage(updated.pageSize.toString()); }, - [pageIndex, pageSize, params, setParams] + [pageIndex, pageSize, params, setPageSizeFromStorage, setParams] ); return { diff --git a/src/ui/HelmSnippet/CLISnippet.tsx b/src/ui/HelmSnippet/CLISnippet.tsx new file mode 100644 index 000000000..d42c2778e --- /dev/null +++ b/src/ui/HelmSnippet/CLISnippet.tsx @@ -0,0 +1,61 @@ +import CodeBlock from "@flanksource-ui/ui/Code/CodeBlock"; +import Handlebars from "handlebars"; +import { useMemo } from "react"; +import { ChartData } from "./HelmInstallationSnippets"; + +// This a Handlebars template for the Helm command to install the agent and the +// kubernetes agent if the user has enabled it. +const helmCommand = `{{#each charts}} +{{#if this.valueFile }} +cat > values.yaml << EOF +{{ this.valueFile }} +EOF + +{{/if}} +{{#if this.createRepo }} +helm repo add {{{ this.chart }}} {{{ this.repoName }}}/{{{ this.chart }}} +{{/if}} +{{#if this.updateHelmRepo }} +helm repo update +{{/if}} + +helm install {{{ this.releaseName }}} {{{ this.repoName }}}/{{{ this.chart }}} -n "{{{ this.namespace }}}" \\ + {{#each this.values}} + --set {{{ this.key }}}={{{ this.value }}} {{#unless @last}} \\ \n{{/unless}}{{/each}}{{#if this.createNamespace }} \\ + --create-namespace {{#if this.valueFile }} \\ {{/if}} +{{/if}} {{#if this.valueFile }} \\ + --set-file values.yaml {{#if this.args}} \\ {{/if}} +{{/if }} {{#if this.args}} \\ + {{#each this.args}} + {{ this }} {{#unless @last}} \\ {{/unless}} + {{/each}} +{{/if}} {{#if this.wait }} \\ + --wait +{{/if}} + +{{/each}} +`; + +const template = Handlebars.compile(helmCommand); + +type Props = { + data: ChartData[]; +}; + +export default function CLIInstallAgent({ data }: Props) { + const helmCommandTemplate = useMemo(() => { + return template( + { + charts: data + }, + {} + ); + }, [data]); + + return ( +
+

Copy the following command to install the chart

+ +
+ ); +} diff --git a/src/ui/HelmSnippet/FluxSnippet.tsx b/src/ui/HelmSnippet/FluxSnippet.tsx new file mode 100644 index 000000000..871943fd5 --- /dev/null +++ b/src/ui/HelmSnippet/FluxSnippet.tsx @@ -0,0 +1,79 @@ +import { JSONViewer } from "@flanksource-ui/ui/Code/JSONViewer"; +import Handlebars from "handlebars"; +import { useMemo } from "react"; +import { ChartData } from "./HelmInstallationSnippets"; + +// This a Handlebars template for the HelmRelease to install the agent and the +// kubernetes agent if the user has enabled it. +const fluxTemplate = `{{#each charts }} +{{#if this.createNamespace}} +apiVersion: v1 +kind: Namespace +metadata: + name: {{ this.namespace }} +--- +{{/if}} +{{#if this.createRepo}} +apiVersion: source.toolkit.fluxcd.io/v1beta1 +kind: HelmRepository +metadata: + name: {{ this.repoName }} + namespace: {{ this.namespace }} +spec: + interval: 5m0s + url: {{{ this.chartUrl }}} +--- +{{/if}} +apiVersion: helm.toolkit.fluxcd.io/v2beta1 +kind: HelmRelease +metadata: + name: {{{ this.chart }}} + namespace: {{ this.namespace }} +spec: + chart: + spec: + chart: {{{ this.chart }}} + sourceRef: + kind: HelmRepository + name: {{{ this.repoName }}} + namespace: {{{ this.namespace }}} + interval: 5m0s + values: + {{#if this.valueFile }} +{{ this.valueFile }} + {{/if}} +{{#each this.values}} + {{{ this.key }}}: {{{ this.value }}} +{{/each}} +--- +{{/each}}`; + +const template = Handlebars.compile(fluxTemplate); + +type Props = { + data: ChartData[]; +}; + +export default function FluxSnippet({ data }: Props) { + const yaml = useMemo(() => { + return template( + { + charts: data.map((data) => ({ + ...data, + chartUrl: data?.chartUrl ?? "https://flanksource.github.io/charts", + valueFile: data?.valueFile + ? // Indent the valueFile content + data?.valueFile?.replace(/^/gm, " ") + : undefined + })) + }, + {} + ); + }, [data]); + + return ( +
+ +
+ ); +} diff --git a/src/ui/HelmSnippet/HelmInstallationSnippets.stories.tsx b/src/ui/HelmSnippet/HelmInstallationSnippets.stories.tsx new file mode 100644 index 000000000..a10756fc2 --- /dev/null +++ b/src/ui/HelmSnippet/HelmInstallationSnippets.stories.tsx @@ -0,0 +1,34 @@ +import { Meta, StoryFn } from "@storybook/react"; +import HelmInstallationSnippets from "./HelmInstallationSnippets"; +import { + mockInput, + mockInputWithKubOptions, + mockInputWithValueFile +} from "./__tests__/mocks/mocks"; + +export default { + title: "ui/HelmInstallationSnippets", + component: HelmInstallationSnippets +} satisfies Meta; + +const Template: StoryFn = (args) => ( + +); + +export const Default = Template.bind({}); + +Default.args = { + charts: [mockInput] +}; + +export const WithKubeOptions = Template.bind({}); + +WithKubeOptions.args = { + charts: mockInputWithKubOptions +}; + +export const WithKubeOptionsAndValueFile = Template.bind({}); + +WithKubeOptionsAndValueFile.args = { + charts: mockInputWithValueFile +}; diff --git a/src/ui/HelmSnippet/HelmInstallationSnippets.tsx b/src/ui/HelmSnippet/HelmInstallationSnippets.tsx new file mode 100644 index 000000000..5fa757b16 --- /dev/null +++ b/src/ui/HelmSnippet/HelmInstallationSnippets.tsx @@ -0,0 +1,61 @@ +import { useState } from "react"; +import { Tab, Tabs } from "../Tabs/Tabs"; +import CLIInstallAgent from "./CLISnippet"; +import FluxSnippet from "./FluxSnippet"; + +export function WarningBox() { + return ( +
+ + Access token will be shown only once. Please copy it and store it + securely. + +
+ ); +} + +export type ChartData = { + namespace?: string; + createNamespace?: boolean; + chart?: string; + chartUrl?: string; + repoName?: string; + releaseName: string; + values?: { + key: string; + value?: string; + }[]; + args?: string[]; + createRepo?: boolean; + wait?: boolean; + valueFile?: string; + updateHelmRepo?: boolean; +}; + +type HelmInstallationSnippetsProps = { + charts: ChartData[]; + isWarningDisplayed?: boolean; +}; + +export default function HelmInstallationSnippets({ + charts, + isWarningDisplayed = false +}: HelmInstallationSnippetsProps) { + const [activeTab, setActiveTab] = useState<"flux" | "cli">("flux"); + + return ( + setActiveTab(v as any)}> + + + {isWarningDisplayed && } + + + + {isWarningDisplayed && } + + + ); +} diff --git a/src/ui/HelmSnippet/__tests__/CLISnippet.unit.test.tsx b/src/ui/HelmSnippet/__tests__/CLISnippet.unit.test.tsx new file mode 100644 index 000000000..8793d3657 --- /dev/null +++ b/src/ui/HelmSnippet/__tests__/CLISnippet.unit.test.tsx @@ -0,0 +1,35 @@ +import { render, screen } from "@testing-library/react"; +import InstallAgentModal from "../CLISnippet"; +import { mockInput, mockInputWithKubOptions } from "./mocks/mocks"; + +global.ResizeObserver = jest.fn().mockImplementation(() => ({ + observe: jest.fn(), + unobserve: jest.fn(), + disconnect: jest.fn() +})); + +describe("InstallAgentModal", () => { + it("renders the Helm repository installation command", () => { + render(); + expect( + screen.getByText( + "helm repo add mission-control-agent flanksource/mission-control-agent", + { + exact: false + } + ).textContent + ).toMatchSnapshot(); + }); + + it("renders the Helm repository installation command with kube command", () => { + render(); + expect( + screen.getByText( + "helm repo add mission-control-agent flanksource/mission-control-agent", + { + exact: false + } + ).textContent + ).toMatchSnapshot(); + }); +}); diff --git a/src/ui/HelmSnippet/__tests__/FluxSnippet.unit.test.tsx b/src/ui/HelmSnippet/__tests__/FluxSnippet.unit.test.tsx new file mode 100644 index 000000000..56a54b5f4 --- /dev/null +++ b/src/ui/HelmSnippet/__tests__/FluxSnippet.unit.test.tsx @@ -0,0 +1,44 @@ +import { fireEvent, render, screen, waitFor } from "@testing-library/react"; +import FluxSnippet from "../FluxSnippet"; +import { mockInput, mockInputWithKubOptions } from "./mocks/mocks"; + +global.ResizeObserver = jest.fn().mockImplementation(() => ({ + observe: jest.fn(), + unobserve: jest.fn(), + disconnect: jest.fn() +})); + +const writeText = jest.fn(); + +Object.assign(navigator, { + clipboard: { + writeText + } +}); + +describe("InstallAgentModal", () => { + it("renders the Helm repository installation command", async () => { + render(); + + const btn = screen.getByTitle(/Copy to clipboard/i); + + fireEvent.click(btn); + + await waitFor(() => { + expect(writeText).toHaveBeenCalled(); + }); + expect(writeText.mock["calls"][0][0]).toMatchSnapshot(); + }); + + it("renders the Helm repository installation command with kube command", async () => { + render(); + const btn = screen.getByTitle(/Copy to clipboard/i); + + fireEvent.click(btn); + + await waitFor(() => { + expect(writeText).toHaveBeenCalled(); + }); + expect(writeText.mock["calls"][0][0]).toMatchSnapshot(); + }); +}); diff --git a/src/ui/HelmSnippet/__tests__/__snapshots__/CLISnippet.unit.test.tsx.snap b/src/ui/HelmSnippet/__tests__/__snapshots__/CLISnippet.unit.test.tsx.snap new file mode 100644 index 000000000..0bcd53a5f --- /dev/null +++ b/src/ui/HelmSnippet/__tests__/__snapshots__/CLISnippet.unit.test.tsx.snap @@ -0,0 +1,37 @@ +// 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 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=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 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=incident-commander.demo.aws.flanksource.com-test-new-agent-instructions \\ + --create-namespace + + +helm install mc-agent-kubernetes flanksource/mc-agent-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/ui/HelmSnippet/__tests__/__snapshots__/FluxSnippet.unit.test.tsx.snap similarity index 50% rename from src/components/Agents/InstalAgentInstruction/__tests__/__snapshots__/FluxInstallAgent.unit.test.tsx.snap rename to src/ui/HelmSnippet/__tests__/__snapshots__/FluxSnippet.unit.test.tsx.snap index dc77868e3..d2f5f84d7 100644 --- a/src/components/Agents/InstalAgentInstruction/__tests__/__snapshots__/FluxInstallAgent.unit.test.tsx.snap +++ b/src/ui/HelmSnippet/__tests__/__snapshots__/FluxSnippet.unit.test.tsx.snap @@ -6,6 +6,15 @@ 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: @@ -21,15 +30,15 @@ spec: 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 - - " + 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: incident-commander.demo.aws.flanksource.com-test-new-agent-instructions +--- +" `; exports[`InstallAgentModal renders the Helm repository installation command with kube command 1`] = ` @@ -38,6 +47,15 @@ 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: @@ -53,13 +71,13 @@ spec: 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 - - " + 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: incident-commander.demo.aws.flanksource.com-test-new-agent-instructions +--- +" `; diff --git a/src/ui/HelmSnippet/__tests__/mocks/mocks.ts b/src/ui/HelmSnippet/__tests__/mocks/mocks.ts new file mode 100644 index 000000000..4a5fd6e51 --- /dev/null +++ b/src/ui/HelmSnippet/__tests__/mocks/mocks.ts @@ -0,0 +1,154 @@ +import { ChartData } from "../../HelmInstallationSnippets"; + +export const mockInput: ChartData = { + chart: "mission-control-agent", + namespace: "mission-control-agent", + repoName: "flanksource", + createRepo: true, + releaseName: "mc-agent", + createNamespace: true, + values: [ + { + key: "upstream.createSecret", + value: "true" + }, + { + key: "upstream.host", + value: "http://localhost:3000" + }, + { + key: "upstream.username", + value: "token" + }, + { + key: "upstream.password", + value: "password" + }, + { + key: "upstream.agentName", + value: "test-new-agent-instructions" + }, + { + key: "pushTelemetry.enabled", + value: "true" + }, + { + key: "pushTelemetry.topologyName", + value: + "incident-commander.demo.aws.flanksource.com-test-new-agent-instructions" + } + ] +}; + +export const mockInputWithKubOptions: ChartData[] = [ + { + chart: "mission-control-agent", + namespace: "mission-control-agent", + repoName: "flanksource", + createRepo: true, + createNamespace: true, + releaseName: "mc-agent", + values: [ + { + key: "upstream.createSecret", + value: "true" + }, + { + key: "upstream.host", + value: "http://localhost:3000" + }, + { + key: "upstream.username", + value: "token" + }, + { + key: "upstream.password", + value: "password" + }, + { + key: "upstream.agentName", + value: "test-new-agent-instructions" + }, + { + key: "pushTelemetry.enabled", + value: "true" + }, + { + key: "pushTelemetry.topologyName", + value: + "incident-commander.demo.aws.flanksource.com-test-new-agent-instructions" + } + ] + }, + { + chart: "mc-agent-kubernetes", + repoName: "flanksource", + namespace: "mission-control-agent", + releaseName: "mc-agent-kubernetes", + values: [ + { + key: "clusterName", + value: "test-new-agent-instructions" + }, + { + key: "scraper.schedule", + value: "30m" + } + ] + } +]; + +export const mockInputWithValueFile: ChartData[] = [ + { + chart: "mission-control-agent", + namespace: "mission-control-agent", + repoName: "flanksource", + createRepo: true, + releaseName: "mc-agent", + createNamespace: true, + values: [ + { + key: "upstream.createSecret", + value: "true" + }, + { + key: "upstream.host", + value: "http://localhost:3000" + }, + { + key: "upstream.username", + value: "token" + }, + { + key: "upstream.password", + value: "password" + }, + { + key: "upstream.agentName", + value: "test-new-agent-instructions" + }, + { + key: "pushTelemetry.enabled", + value: "true" + }, + { + key: "pushTelemetry.topologyName", + value: + "incident-commander.demo.aws.flanksource.com-test-new-agent-instructions" + } + ], + valueFile: `key: value +key2: value2 +key3: value3 +key4: value4` + }, + { + chart: "mc-agent-kubernetes", + repoName: "flanksource", + namespace: "mission-control-agent", + releaseName: "mc-agent-kubernetes", + valueFile: `key: value +key2: value2 +key3: value3` + } +];