From 2f345dc51180fd2c18d345ccab610cebb10ae93c Mon Sep 17 00:00:00 2001 From: Jen Huang Date: Thu, 10 Oct 2019 10:00:10 -0700 Subject: [PATCH 1/4] Fix agent table empty prompt --- .../legacy/plugins/fleet/public/pages/agent_list/index.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/legacy/plugins/fleet/public/pages/agent_list/index.tsx b/x-pack/legacy/plugins/fleet/public/pages/agent_list/index.tsx index dcfcdd4576d94..9d7f5b5a3d94d 100644 --- a/x-pack/legacy/plugins/fleet/public/pages/agent_list/index.tsx +++ b/x-pack/legacy/plugins/fleet/public/pages/agent_list/index.tsx @@ -197,18 +197,18 @@ export const AgentListPage: React.SFC = ({ libs }) => { Date: Mon, 14 Oct 2019 15:17:22 -0700 Subject: [PATCH 2/4] First pass at agent enrollment flyout with placeholders --- .../components/agent_enrollment.tsx | 139 ++++++++++++++++ .../enrollment_instructions/container.tsx | 10 ++ .../enrollment_instructions/index.tsx | 33 ++++ .../enrollment_instructions/shell.tsx | 154 ++++++++++++++++++ .../enrollment_instructions/tools.tsx | 10 ++ .../fleet/public/pages/agent_list/index.tsx | 13 +- 6 files changed, 356 insertions(+), 3 deletions(-) create mode 100644 x-pack/legacy/plugins/fleet/public/pages/agent_list/components/agent_enrollment.tsx create mode 100644 x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/container.tsx create mode 100644 x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/index.tsx create mode 100644 x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/shell.tsx create mode 100644 x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/tools.tsx diff --git a/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/agent_enrollment.tsx b/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/agent_enrollment.tsx new file mode 100644 index 0000000000000..38e1b0f4f9b78 --- /dev/null +++ b/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/agent_enrollment.tsx @@ -0,0 +1,139 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import React, { useState, Fragment } from 'react'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { + EuiFlyout, + EuiFlyoutHeader, + EuiTitle, + EuiFlyoutBody, + EuiFlyoutFooter, + EuiFlexGroup, + EuiFlexItem, + EuiButtonEmpty, + EuiButton, + EuiSpacer, + EuiText, + EuiFilterGroup, + EuiFilterButton, +} from '@elastic/eui'; +import { FrontendLibs } from '../../../lib/types'; +import { + ShellEnrollmentInstructions, + ContainerEnrollmentInstructions, + ToolsEnrollmentInstructions, +} from './enrollment_instructions'; + +interface RouterProps { + libs: FrontendLibs; + onClose: () => void; +} + +export const AgentEnrollmentFlyout: React.SFC = ({ libs, onClose }) => { + const [quickInstallType, setQuickInstallType] = useState<'shell' | 'container' | 'tools'>( + 'shell' + ); + + const renderHeader = () => ( + + +

+ +

+
+ + +

+ +

+
+
+ ); + + const renderInstructions = () => ( + + +
+ +
+
+ + + setQuickInstallType('shell')} + > + + + setQuickInstallType('container')} + > + + + setQuickInstallType('tools')} + > + + + + + {quickInstallType === 'shell' ? ( + + ) : null} + {quickInstallType === 'container' ? : null} + {quickInstallType === 'tools' ? : null} +
+ ); + + const renderBody = () => {renderInstructions()}; + + const renderFooter = () => ( + + + + + Close + + + + + Continue + + + + + ); + + return ( + + {renderHeader()} + {renderBody()} + {renderFooter()} + + ); +}; diff --git a/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/container.tsx b/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/container.tsx new file mode 100644 index 0000000000000..03711d531b3aa --- /dev/null +++ b/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/container.tsx @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import React from 'react'; + +export const ContainerEnrollmentInstructions: React.SFC = () => { + return
Container instructions
; +}; diff --git a/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/index.tsx b/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/index.tsx new file mode 100644 index 0000000000000..3dd894773a41d --- /dev/null +++ b/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/index.tsx @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import React from 'react'; +import { EuiSteps, EuiText, EuiCodeBlock } from '@elastic/eui'; + +export { ShellEnrollmentInstructions } from './shell'; +export { ContainerEnrollmentInstructions } from './container'; +export { ToolsEnrollmentInstructions } from './tools'; + +export type ManualEnrollmentInstructions = Array<{ + title: string; + textPre?: string; + commands?: string[]; +}>; + +export const ManualEnrollmentSteps: React.SFC<{ instructions: ManualEnrollmentInstructions }> = ({ + instructions, +}) => ( + ({ + title, + children: ( + + {textPre ?

{textPre}

: null} + {commands ? {commands.join(`\n`)} : null} +
+ ), + }))} + /> +); diff --git a/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/shell.tsx b/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/shell.tsx new file mode 100644 index 0000000000000..2b224cfb476da --- /dev/null +++ b/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/shell.tsx @@ -0,0 +1,154 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import React, { useState, Fragment } from 'react'; +import { + EuiFieldText, + EuiCopy, + EuiButtonEmpty, + EuiPopover, + EuiSpacer, + EuiContextMenuPanel, + EuiContextMenuItem, +} from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { i18n } from '@kbn/i18n'; +import { ManualEnrollmentInstructions, ManualEnrollmentSteps } from './'; + +// No need for i18n as these are platform names +const PLATFORMS = { + macos: 'macOS', + windows: 'Windows', + linux: 'Linux', +}; + +// Manual instructions based on platform +const PLATFORM_INSTRUCTIONS: { + [key: string]: ManualEnrollmentInstructions; +} = { + macos: [ + { + title: i18n.translate('xpack.fleet.agentEnrollment.typeShell.manualInstall.stepOneTitle', { + defaultMessage: 'Download and install Elastic Agent', + }), + textPre: 'Lorem ipsum instructions here.', + commands: [ + 'curl -L -O https://artifacts.elastic.co/downloads/some-file-to-download.tar.gz', + 'tar xzvf some-file-to-download.tar.gz', + 'cd some-file-to-download/', + ], + }, + { + title: i18n.translate('xpack.fleet.agentEnrollment.typeShell.manualInstall.stepTwoTitle', { + defaultMessage: 'Edit the configuration', + }), + textPre: 'Modify the configuration file to set the connection information:', + commands: [ + 'output.elasticsearch:', + ' hosts: [""]', + ' username: "elastic"', + ' password: ""', + 'setup.kibana:', + ' host: ""', + ], + }, + { + title: i18n.translate('xpack.fleet.agentEnrollment.typeShell.manualInstall.stepThreeTitle', { + defaultMessage: 'Start the agent', + }), + commands: ['./somefile setup', './somefile -e'], + }, + ], +}; + +interface Props { + kibanaUrl: string; +} + +export const ShellEnrollmentInstructions: React.SFC = ({ kibanaUrl }) => { + // Platform state + const [currentPlatform, setCurrentPlatform] = useState('macos'); + const [isPlatformOptionsOpen, setIsPlatformOptionsOpen] = useState(false); + const [isManualInstallationOpen, setIsManualInstallationOpen] = useState(false); + + // Build quick installation command + const quickInstallInstructions = `curl ${kibanaUrl}/api/fleet/install/${currentPlatform} | bash`; + + return ( + + setIsPlatformOptionsOpen(true)} + > + {PLATFORMS[currentPlatform]} + + } + isOpen={isPlatformOptionsOpen} + closePopover={() => setIsPlatformOptionsOpen(false)} + > + ( + { + setCurrentPlatform(platform as typeof currentPlatform); + setIsPlatformOptionsOpen(false); + }} + > + {name} + + ))} + /> + + } + append={ + + {copy => ( + + + + )} + + } + /> + + + + setIsManualInstallationOpen(!isManualInstallationOpen)} + iconType={isManualInstallationOpen ? 'arrowUp' : 'arrowDown'} + iconSide="right" + size="xs" + flush="left" + > + + + + {isManualInstallationOpen ? ( + + + + + ) : null} + + ); +}; diff --git a/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/tools.tsx b/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/tools.tsx new file mode 100644 index 0000000000000..ad7da6928ec7a --- /dev/null +++ b/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/tools.tsx @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import React from 'react'; + +export const ToolsEnrollmentInstructions: React.SFC = () => { + return
Tools instructions
; +}; diff --git a/x-pack/legacy/plugins/fleet/public/pages/agent_list/index.tsx b/x-pack/legacy/plugins/fleet/public/pages/agent_list/index.tsx index 9d7f5b5a3d94d..6dec90a2f332b 100644 --- a/x-pack/legacy/plugins/fleet/public/pages/agent_list/index.tsx +++ b/x-pack/legacy/plugins/fleet/public/pages/agent_list/index.tsx @@ -28,6 +28,7 @@ import { AgentHealth } from '../../components/agent_health'; import { ConnectedLink } from '../../components/navigation/connected_link'; import { usePagination } from '../../hooks/use_pagination'; import { SearchBar } from '../../components/search_bar'; +import { AgentEnrollmentFlyout } from './components/agent_enrollment'; interface RouterProps { libs: FrontendLibs; @@ -42,9 +43,11 @@ export const AgentListPage: React.SFC = ({ libs }) => { // Table and search states const [search, setSearch] = useState(''); - const { pagination, pageSizeOptions, setPagination } = usePagination(); + // Agent enrollment flyout state + const [isEnrollmentFlyoutOpen, setIsEnrollmentFlyoutOpen] = useState(false); + // Fetch agents method const fetchAgents = async () => { setIsLoading(true); @@ -151,7 +154,7 @@ export const AgentListPage: React.SFC = ({ libs }) => { } actions={ - + setIsEnrollmentFlyoutOpen(true)}> = ({ libs }) => { return ( + {isEnrollmentFlyoutOpen ? ( + setIsEnrollmentFlyoutOpen(false)} /> + ) : null} +

@@ -185,7 +192,7 @@ export const AgentListPage: React.SFC = ({ libs }) => { - + setIsEnrollmentFlyoutOpen(true)}> Date: Tue, 15 Oct 2019 11:19:23 -0700 Subject: [PATCH 3/4] Move enrollment commands into separate file and enable templated vars --- .../{container.tsx => container/index.tsx} | 0 .../enrollment_instructions/index.tsx | 42 ++++++++++++++++-- .../{shell.tsx => shell/index.tsx} | 21 +++------ .../shell/mac_commands.ts | 43 +++++++++++++++++++ .../{tools.tsx => tools/index.tsx} | 0 5 files changed, 88 insertions(+), 18 deletions(-) rename x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/{container.tsx => container/index.tsx} (100%) rename x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/{shell.tsx => shell/index.tsx} (89%) create mode 100644 x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/shell/mac_commands.ts rename x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/{tools.tsx => tools/index.tsx} (100%) diff --git a/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/container.tsx b/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/container/index.tsx similarity index 100% rename from x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/container.tsx rename to x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/container/index.tsx diff --git a/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/index.tsx b/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/index.tsx index 3dd894773a41d..ed1294c47d4ee 100644 --- a/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/index.tsx +++ b/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/index.tsx @@ -5,6 +5,7 @@ */ import React from 'react'; import { EuiSteps, EuiText, EuiCodeBlock } from '@elastic/eui'; +import { Writer } from 'mustache'; export { ShellEnrollmentInstructions } from './shell'; export { ContainerEnrollmentInstructions } from './container'; @@ -13,21 +14,56 @@ export { ToolsEnrollmentInstructions } from './tools'; export type ManualEnrollmentInstructions = Array<{ title: string; textPre?: string; - commands?: string[]; + commands?: string; + commandsLang?: 'bash' | 'yaml'; }>; export const ManualEnrollmentSteps: React.SFC<{ instructions: ManualEnrollmentInstructions }> = ({ instructions, }) => ( ({ + steps={instructions.map(({ title, textPre, commands, commandsLang }) => ({ title, children: ( {textPre ?

{textPre}

: null} - {commands ? {commands.join(`\n`)} : null} + {commands ? ( + // TODO: Increase overflowHeight when https://github.com/elastic/eui/issues/2435 is fixed + // or be smarter with setting this number before release + + {replaceTemplateStrings(commands.trim())} + + ) : null}
), }))} /> ); + +// Setup for replacing template variables in install instructions +const TEMPLATE_TAGS = ['{', '}']; +const mustacheWriter = new Writer(); + +// do not html escape output +// @ts-ignore +mustacheWriter.escapedValue = function escapedValue(token, context) { + const value = context.lookup(token[1]); + if (value != null) { + return value; + } +}; + +// Configure available variable values +export function replaceTemplateStrings(text: string = '') { + const variables = { + // '{' and '}' can not be used in template since they are used as template tags. + // Must use '{curlyOpen}'' and '{curlyClose}' + curlyOpen: '{', + curlyClose: '}', + config: { + enrollmentToken: 'sometesttoken', + }, + }; + mustacheWriter.parse(text, TEMPLATE_TAGS); + return mustacheWriter.render(text, variables, () => {}); +} diff --git a/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/shell.tsx b/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/shell/index.tsx similarity index 89% rename from x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/shell.tsx rename to x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/shell/index.tsx index 2b224cfb476da..a518a75ccdb9a 100644 --- a/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/shell.tsx +++ b/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/shell/index.tsx @@ -15,7 +15,8 @@ import { } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import { ManualEnrollmentInstructions, ManualEnrollmentSteps } from './'; +import { ManualEnrollmentInstructions, ManualEnrollmentSteps } from '../'; +import * as MAC_COMMANDS from './mac_commands'; // No need for i18n as these are platform names const PLATFORMS = { @@ -34,31 +35,21 @@ const PLATFORM_INSTRUCTIONS: { defaultMessage: 'Download and install Elastic Agent', }), textPre: 'Lorem ipsum instructions here.', - commands: [ - 'curl -L -O https://artifacts.elastic.co/downloads/some-file-to-download.tar.gz', - 'tar xzvf some-file-to-download.tar.gz', - 'cd some-file-to-download/', - ], + commands: MAC_COMMANDS.INSTALL, }, { title: i18n.translate('xpack.fleet.agentEnrollment.typeShell.manualInstall.stepTwoTitle', { defaultMessage: 'Edit the configuration', }), textPre: 'Modify the configuration file to set the connection information:', - commands: [ - 'output.elasticsearch:', - ' hosts: [""]', - ' username: "elastic"', - ' password: ""', - 'setup.kibana:', - ' host: ""', - ], + commands: MAC_COMMANDS.CONFIG, + commandsLang: 'yaml', }, { title: i18n.translate('xpack.fleet.agentEnrollment.typeShell.manualInstall.stepThreeTitle', { defaultMessage: 'Start the agent', }), - commands: ['./somefile setup', './somefile -e'], + commands: MAC_COMMANDS.START, }, ], }; diff --git a/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/shell/mac_commands.ts b/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/shell/mac_commands.ts new file mode 100644 index 0000000000000..d2c168b84d389 --- /dev/null +++ b/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/shell/mac_commands.ts @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export const INSTALL = ` +curl -L -O https://artifacts.elastic.co/downloads/some-file-to-download.tar.gz +tar xzvf some-file-to-download.tar.gz +cd some-file-to-download/ +`; + +export const CONFIG = ` +output.elasticsearch: + hosts: [""] + username: "elastic" + password: "" +setup.kibana: + host: "" +output.elasticsearch: + hosts: [""] + username: "elastic" + password: "" +setup.kibana: + host: "" +output.elasticsearch: + hosts: [""] + username: "elastic" + password: "" +setup.kibana: + host: "" +output.elasticsearch: + hosts: [""] + username: "elastic" + password: "" +setup.kibana: + host: "" +`; + +export const START = ` +./somefile setup +./somefile --token={config.enrollmentToken} +`; diff --git a/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/tools.tsx b/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/tools/index.tsx similarity index 100% rename from x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/tools.tsx rename to x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/tools/index.tsx From fcd56d3e9ba89ac181aaae741708450c996802c9 Mon Sep 17 00:00:00 2001 From: Jen Huang Date: Wed, 16 Oct 2019 10:15:18 -0700 Subject: [PATCH 4/4] Use default double braces for templating --- .../components/enrollment_instructions/index.tsx | 7 +------ .../enrollment_instructions/shell/mac_commands.ts | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/index.tsx b/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/index.tsx index ed1294c47d4ee..4640746ca7ad9 100644 --- a/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/index.tsx +++ b/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/index.tsx @@ -41,7 +41,6 @@ export const ManualEnrollmentSteps: React.SFC<{ instructions: ManualEnrollmentIn ); // Setup for replacing template variables in install instructions -const TEMPLATE_TAGS = ['{', '}']; const mustacheWriter = new Writer(); // do not html escape output @@ -56,14 +55,10 @@ mustacheWriter.escapedValue = function escapedValue(token, context) { // Configure available variable values export function replaceTemplateStrings(text: string = '') { const variables = { - // '{' and '}' can not be used in template since they are used as template tags. - // Must use '{curlyOpen}'' and '{curlyClose}' - curlyOpen: '{', - curlyClose: '}', config: { enrollmentToken: 'sometesttoken', }, }; - mustacheWriter.parse(text, TEMPLATE_TAGS); + mustacheWriter.parse(text); return mustacheWriter.render(text, variables, () => {}); } diff --git a/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/shell/mac_commands.ts b/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/shell/mac_commands.ts index d2c168b84d389..e853dcf1100cc 100644 --- a/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/shell/mac_commands.ts +++ b/x-pack/legacy/plugins/fleet/public/pages/agent_list/components/enrollment_instructions/shell/mac_commands.ts @@ -39,5 +39,5 @@ setup.kibana: export const START = ` ./somefile setup -./somefile --token={config.enrollmentToken} +./somefile --token={{config.enrollmentToken}} `;