diff --git a/package-lock.json b/package-lock.json index dc1473eee..450efad63 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44951,4 +44951,4 @@ } } } -} +} \ No newline at end of file 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 deleted file mode 100644 index b260919be..000000000 --- a/src/components/Agents/InstalAgentInstruction/CLIInstallAgent.tsx +++ /dev/null @@ -1,81 +0,0 @@ -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"; - -const helmCommand = `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={{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}} - --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}} -`; - -const template = Handlebars.compile(helmCommand); - -type Props = { - generatedAgent: GeneratedAgent; - agentFormValues?: AgentFormValues; -}; - -export default function CLIInstallAgent({ - generatedAgent, - agentFormValues -}: Props) { - const baseUrl = useAgentsBaseURL(); - const { backendUrl, orgSlug } = useUser(); - - 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 ( -
-

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 944ede344..000000000 --- a/src/components/Agents/InstalAgentInstruction/FluxInstallAgent.tsx +++ /dev/null @@ -1,118 +0,0 @@ -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"; - -const fluxTemplate = `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: {{baseUrl}} - username: token - agentName: {{agentFormValues.name}} - password: {{generatedAgent.access_token}} -{{#if pushTelemetry}} - pushTelemetry: - enabled: true - topologyName: {{pushTelemetry.topologyName}} -{{/if}} -{{#if kubeOptions}} ---- -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: "{{agentFormValues.name}}" - interval: "{{kubeOptions.interval}}" -{{/if}} - `; - -const template = Handlebars.compile(fluxTemplate); - -type Props = { - generatedAgent: GeneratedAgent; - agentFormValues?: AgentFormValues; -}; - -export default function FluxInstallAgent({ - generatedAgent, - agentFormValues -}: Props) { - const baseUrl = useAgentsBaseURL(); - const { backendUrl, orgSlug } = useUser(); - - 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 ( -
- -
- ); -} diff --git a/src/components/Agents/InstalAgentInstruction/InstallAgentModal.tsx b/src/components/Agents/InstalAgentInstruction/InstallAgentModal.tsx index 77e1dee82..58bf4f2c7 100644 --- a/src/components/Agents/InstalAgentInstruction/InstallAgentModal.tsx +++ b/src/components/Agents/InstalAgentInstruction/InstallAgentModal.tsx @@ -1,25 +1,12 @@ -import { 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"; - -export function WarningBox() { - return ( -
- - Access token will be shown only once. Please copy it and store it - securely. - -
- ); -} +import { useAgentsBaseURL } from "./useAgentsBaseURL"; export function MoreInfoBox() { return ( @@ -96,7 +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", + createNamespace: true, + createRepo: true, + updateHelmRepo: true, + releaseName: "mc-agent", + chartUrl: "https://flanksource.github.io/charts", + // 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 + ? [ + { + 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 ChartData[]; + }, [agentFormValues, baseUrl, generatedAgent]); 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 c90391482..000000000 --- a/src/components/Agents/InstalAgentInstruction/__tests__/CLIInstallAgent.unit.test.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import { render, screen } from "@testing-library/react"; -import { AuthContext, FakeUser, Roles } from "../../../../context"; -import InstallAgentModal from "../CLIInstallAgent"; - -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" - }; - - it("renders the Helm repository installation command", () => { - render( - - - - ); - expect( - screen.getByText( - "helm repo add flanksource https://flanksource.github.io/charts", - { - 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 - - " - `); - }); - - it("renders the Helm repository installation command with kube command", () => { - render( - - - - ); - expect( - screen.getByText( - "helm repo add flanksource https://flanksource.github.io/charts", - { - 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" - " - `); - }); -}); 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 2c4d89c88..000000000 --- a/src/components/Agents/InstalAgentInstruction/__tests__/FluxInstallAgent.unit.test.tsx +++ /dev/null @@ -1,189 +0,0 @@ -import { fireEvent, render, screen, waitFor } from "@testing-library/react"; -import { AuthContext, FakeUser, Roles } 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(), - disconnect: jest.fn() -})); - -const writeText = jest.fn(); - -Object.assign(navigator, { - clipboard: { - writeText - } -}); - -describe("InstallAgentModal", () => { - const generatedAgent = { - id: "testid", - username: "testuser", - access_token: "testtoken" - }; - - 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]).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: "" - " - `); - }); - - 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]).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: "" - " - `); - }); -}); diff --git a/src/ui/HelmSnippet/CLISnippet.tsx b/src/ui/HelmSnippet/CLISnippet.tsx new file mode 100644 index 000000000..29b37bd82 --- /dev/null +++ b/src/ui/HelmSnippet/CLISnippet.tsx @@ -0,0 +1,66 @@ +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.repoName }}} {{{ this.chartUrl }}} +{{/if}} +{{#if this.updateHelmRepo }} +helm repo update +{{/if}} + +helm install {{{ this.chart }}} {{{ 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.map((chart) => { + return { + ...chart, + chartUrl: chart.chartUrl ?? "https://flanksource.github.io/charts" + }; + }) + }, + {} + ); + }, [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..08d92d297 --- /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/v1 +kind: HelmRepository +metadata: + name: {{ this.repoName }} + namespace: {{ this.namespace }} +spec: + interval: 5m0s + url: {{{ this.chartUrl }}} +--- +{{/if}} +apiVersion: helm.toolkit.fluxcd.io/v2 +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..3c5cb921d --- /dev/null +++ b/src/ui/HelmSnippet/__tests__/CLISnippet.unit.test.tsx @@ -0,0 +1,29 @@ +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 flanksource", { + exact: false + }).textContent + ).toMatchSnapshot(); + }); + + it("renders the Helm repository installation command with kube command", () => { + render(); + expect( + screen.getByText("helm repo add flanksource", { + 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..69cb7e902 --- /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 flanksource https://flanksource.github.io/charts + +helm install mission-control-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 flanksource https://flanksource.github.io/charts + +helm install mission-control-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/ui/HelmSnippet/__tests__/__snapshots__/FluxSnippet.unit.test.tsx.snap b/src/ui/HelmSnippet/__tests__/__snapshots__/FluxSnippet.unit.test.tsx.snap new file mode 100644 index 000000000..d41e36220 --- /dev/null +++ b/src/ui/HelmSnippet/__tests__/__snapshots__/FluxSnippet.unit.test.tsx.snap @@ -0,0 +1,83 @@ +// 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: source.toolkit.fluxcd.io/v1 +kind: HelmRepository +metadata: + name: flanksource + namespace: mission-control-agent +spec: + interval: 5m0s + url: https://flanksource.github.io/charts +--- +apiVersion: helm.toolkit.fluxcd.io/v2 +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: 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: source.toolkit.fluxcd.io/v1 +kind: HelmRepository +metadata: + name: flanksource + namespace: mission-control-agent +spec: + interval: 5m0s + url: https://flanksource.github.io/charts +--- +apiVersion: helm.toolkit.fluxcd.io/v2 +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: 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` + } +];