Skip to content

Commit

Permalink
[Fleet] Update install.sh instructions
Browse files Browse the repository at this point in the history
  • Loading branch information
nchaulet committed May 4, 2020
1 parent 7def0a9 commit 57c1c18
Show file tree
Hide file tree
Showing 13 changed files with 186 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,35 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { EuiText, EuiSpacer } from '@elastic/eui';
import React from 'react';
import { EuiText, EuiSpacer, EuiCode, EuiCodeBlock } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { EnrollmentAPIKey } from '../../../types';

export const ManualInstructions: React.FunctionComponent = () => {
interface Props {
kibanaUrl: string;
apiKey: EnrollmentAPIKey;
}

export const ManualInstructions: React.FunctionComponent<Props> = ({ kibanaUrl, apiKey }) => {
const command = `
./elastic-agent enroll ${kibanaUrl} ${apiKey.api_key}
./elastic-agent run`;
return (
<>
<EuiText>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam vestibulum ullamcorper
turpis vitae interdum. Maecenas orci magna, auctor volutpat pellentesque eu, consectetur id
est. Nunc orci lacus, condimentum vel congue ac, fringilla eget tortor. Aliquam blandit,
nisi et congue euismod, leo lectus blandit risus, eu blandit erat metus sit amet leo. Nam
dictum lobortis condimentum.
</EuiText>
<EuiSpacer size="m" />
<EuiText>
Vivamus sem sapien, dictum eu tellus vel, rutrum aliquam purus. Cras quis cursus nibh.
Aliquam fermentum ipsum nec turpis luctus lobortis. Nulla facilisi. Etiam nec fringilla
urna, sed vehicula ipsum. Quisque vel pellentesque lorem, at egestas enim. Nunc semper elit
lectus, in sollicitudin erat fermentum in. Pellentesque tempus massa eget purus pharetra
blandit.
<FormattedMessage
id="todo"
defaultMessage="From the agent’s directory, run these commands to enroll and start the Elastic Agent. {enrollCommand} will write to your agent’s configuration file so that it has the correct settings. You can use this command to setup agents on more than one host."
values={{
enrollCommand: <EuiCode>agent enroll</EuiCode>,
}}
/>
</EuiText>
<EuiSpacer size="m" />
<EuiText>
Mauris congue enim nulla, nec semper est posuere non. Donec et eros eu nisi gravida
malesuada eget in velit. Morbi placerat semper euismod. Suspendisse potenti. Morbi quis
porta erat, quis cursus nulla. Aenean mauris lorem, mollis in mattis et, lobortis a lectus.
</EuiText>
<EuiCodeBlock fontSize="m">
<pre>{command}</pre>
</EuiCodeBlock>
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,15 @@

import { FormattedMessage } from '@kbn/i18n/react';
import React from 'react';
import { EuiCopy, EuiCode, EuiText, EuiSpacer, EuiButton } from '@elastic/eui';
import {
EuiCopy,
EuiCodeBlock,
EuiCode,
EuiLink,
EuiText,
EuiSpacer,
EuiButton,
} from '@elastic/eui';
import { EnrollmentAPIKey } from '../../../types';

interface Props {
Expand All @@ -30,7 +38,34 @@ export const QuickSetupInstructions: React.FunctionComponent<Props> = ({
} \\\nsh -c "$(curl ${kibanaUrl}/api/ingest_manager/fleet/install/${platform})"`;

if (platform === 'windows') {
return <p>TODO Special case</p>;
const command = `./elastic-agent enroll ${kibanaUrl} ${apiKey.api_key}
./elastic-agent run`;

return (
<EuiText>
<FormattedMessage
id="xpack.ingestManager.quickSetupInstructions.windowsInstruction"
defaultMessage="1. Download the Elastic agent Windows zip file from the {downloadLink}.{spacer}
2. Extract the contents of the zip{spacer}
3. From the agent’s directory, run these commands to enroll and start the Elastic Agent{spacer}
"
values={{
spacer: <EuiSpacer size="s" />,
downloadLink: (
<EuiLink href="https://ela.st/download-elastic-agent" target="_blank">
<FormattedMessage
id="xpack.ingestManager.quickSetupInstructions.downloadLink"
defaultMessage="download page"
/>
</EuiLink>
),
}}
/>
<EuiCodeBlock fontSize="m" paddingSize="s">
<pre>{command}</pre>
</EuiCodeBlock>
</EuiText>
);
}

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
EuiFlyout,
EuiFlyoutBody,
EuiFlyoutHeader,
EuiSpacer,
EuiTitle,
EuiFlexGroup,
EuiFlexItem,
Expand All @@ -20,6 +19,7 @@ import {
EuiSteps,
EuiText,
EuiSelect,
EuiLink,
} from '@elastic/eui';
import { EuiContainedStepProps } from '@elastic/eui/src/components/steps/steps';
import { i18n } from '@kbn/i18n';
Expand Down Expand Up @@ -52,19 +52,27 @@ export const AgentEnrollmentFlyout: React.FunctionComponent<Props> = ({
...(selectedTab === 'manual'
? [
{
title: i18n.translate(
'xpack.ingestManager.agentEnrollment.stepChoosePackagePlatformTitle',
{
defaultMessage: 'Select a package to download',
}
),
children: <p> TODO list of packages </p>,
},
{
title: i18n.translate('xpack.ingestManager.agentEnrollment.stepDownloadPackageTitle', {
title: i18n.translate('xpack.ingestManager.agentEnrollment.stepDownloadAgentTitle', {
defaultMessage: 'Download the Elastic Agent',
}),
children: <p> TODO list of packages </p>,
children: (
<EuiText>
<FormattedMessage
id="xpack.ingestManager.agentEnrollment.downloadDescription"
defaultMessage="Download the Elastic agent on your host’s machine. You can download the agent binary and it’s verification signature from Elastic’s {downloadLink}."
values={{
downloadLink: (
<EuiLink href="https://ela.st/download-elastic-agent" target="_blank">
<FormattedMessage
id="xpack.ingestManager.agentEnrollment.downloadLink"
defaultMessage="download page"
/>
</EuiLink>
),
}}
/>
</EuiText>
),
},
]
: []),
Expand All @@ -82,7 +90,12 @@ export const AgentEnrollmentFlyout: React.FunctionComponent<Props> = ({
title: i18n.translate('xpack.ingestManager.agentEnrollment.stepRunAgentTitle', {
defaultMessage: 'Enroll and run the Elastic Agent',
}),
children: <p> TODO list of packages </p>,
children: apiKey.data && (
<ManualInstructions
apiKey={apiKey.data.item}
kibanaUrl={`${window.location.origin}${core.http.basePath.get()}`}
/>
),
},
]
: [
Expand All @@ -108,7 +121,7 @@ export const AgentEnrollmentFlyout: React.FunctionComponent<Props> = ({
text: i18n.translate(
'xpack.ingestManager.agentEnrollment.platformDarwinLabel',
{
defaultMessage: 'Mac',
defaultMessage: 'Macos',
}
),
value: 'macos',
Expand Down Expand Up @@ -158,7 +171,6 @@ export const AgentEnrollmentFlyout: React.FunctionComponent<Props> = ({
/>
</h2>
</EuiTitle>
<EuiSpacer size="l" />
</EuiFlyoutHeader>
<div>
<EuiTabs>
Expand Down
14 changes: 8 additions & 6 deletions x-pack/plugins/ingest_manager/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
Plugin,
PluginInitializerContext,
SavedObjectsServiceStart,
HttpServerInfo,
} from 'kibana/server';
import { LicensingPluginSetup, ILicense } from '../../licensing/server';
import {
Expand Down Expand Up @@ -70,8 +69,9 @@ export interface IngestManagerAppContext {
config$?: Observable<IngestManagerConfigType>;
savedObjects: SavedObjectsServiceStart;
isProductionMode: boolean;
serverInfo?: HttpServerInfo;
kibanaVersion: string;
cloud?: CloudSetup;
coreSetup?: CoreSetup;
}

export type IngestManagerSetupContract = void;
Expand Down Expand Up @@ -108,15 +108,17 @@ export class IngestManagerPlugin
private cloud: CloudSetup | undefined;

private isProductionMode: boolean;
private serverInfo: HttpServerInfo | undefined;
private kibanaVersion: string;
private coreSetup: CoreSetup | undefined;

constructor(private readonly initializerContext: PluginInitializerContext) {
this.config$ = this.initializerContext.config.create<IngestManagerConfigType>();
this.isProductionMode = this.initializerContext.env.mode.prod;
this.kibanaVersion = this.initializerContext.env.packageInfo.version;
}

public async setup(core: CoreSetup, deps: IngestManagerSetupDeps) {
this.serverInfo = core.http.getServerInfo();
this.coreSetup = core;
this.licensing$ = deps.licensing.license$;
if (deps.security) {
this.security = deps.security;
Expand Down Expand Up @@ -179,7 +181,6 @@ export class IngestManagerPlugin
registerEnrollmentApiKeyRoutes(router);
registerInstallScriptRoutes({
router,
serverInfo: core.http.getServerInfo(),
basePath: core.http.basePath,
});
}
Expand All @@ -197,7 +198,8 @@ export class IngestManagerPlugin
config$: this.config$,
savedObjects: core.savedObjects,
isProductionMode: this.isProductionMode,
serverInfo: this.serverInfo,
kibanaVersion: this.kibanaVersion,
coreSetup: this.coreSetup,
cloud: this.cloud,
});
licenseService.start(this.licensing$);
Expand Down
33 changes: 22 additions & 11 deletions x-pack/plugins/ingest_manager/server/routes/install_script/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,25 @@
* you may not use this file except in compliance with the Elastic License.
*/
import url from 'url';
import { IRouter, BasePath, HttpServerInfo, KibanaRequest } from 'src/core/server';
import { IRouter, BasePath, KibanaRequest } from 'src/core/server';
import { INSTALL_SCRIPT_API_ROUTES } from '../../constants';
import { getScript } from '../../services/install_script';
import { InstallScriptRequestSchema } from '../../types';
import { appContextService, settingsService } from '../../services';

function getInternalUserSOClient(request: KibanaRequest) {
// soClient as kibana internal users, be carefull on how you use it, security is not enabled
return appContextService.getSavedObjects().getScopedClient(request, {
excludedWrappers: ['security'],
});
}

export const registerRoutes = ({
router,
basePath,
serverInfo,
}: {
router: IRouter;
basePath: Pick<BasePath, 'serverBasePath'>;
serverInfo: HttpServerInfo;
}) => {
const kibanaUrl = url.format({
protocol: serverInfo.protocol,
hostname: serverInfo.host,
port: serverInfo.port,
pathname: basePath.serverBasePath,
});

router.get(
{
path: INSTALL_SCRIPT_API_ROUTES,
Expand All @@ -36,6 +34,19 @@ export const registerRoutes = ({
request: KibanaRequest<{ osType: 'macos' }>,
response
) {
const soClient = getInternalUserSOClient(request);
const core = appContextService.getCoreSetup();
const serverInfo = core.http.getServerInfo();
const basePath = core.http.basePath;
const kibanaUrl =
(await settingsService.getSettings(soClient)).kibana_url ||
url.format({
protocol: serverInfo.protocol,
hostname: serverInfo.host,
port: serverInfo.port,
pathname: basePath.serverBasePath,
});

const script = getScript(request.params.osType, kibanaUrl);

return response.ok({ body: script });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const getFleetStatusHandler: RequestHandler = async (context, request, re
try {
const isAdminUserSetup = (await outputService.getAdminUser(soClient)) !== null;
const isApiKeysEnabled = await appContextService.getSecurity().authc.areAPIKeysEnabled();
const isTLSEnabled = appContextService.getServerInfo().protocol === 'https';
const isTLSEnabled = appContextService.getCoreSetup().http.getServerInfo().protocol === 'https';
const isProductionMode = appContextService.getIsProductionMode();
const isCloud = appContextService.getCloud()?.isCloudEnabled ?? false;
const isTLSCheckDisabled = appContextService.getConfig()?.fleet?.tlsCheckDisabled ?? false;
Expand Down
23 changes: 16 additions & 7 deletions x-pack/plugins/ingest_manager/server/services/app_context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/
import { BehaviorSubject, Observable } from 'rxjs';
import { first } from 'rxjs/operators';
import { SavedObjectsServiceStart, HttpServerInfo } from 'src/core/server';
import { SavedObjectsServiceStart, CoreSetup } from 'src/core/server';
import { EncryptedSavedObjectsPluginStart } from '../../../encrypted_saved_objects/server';
import { SecurityPluginSetup } from '../../../security/server';
import { IngestManagerConfigType } from '../../common';
Expand All @@ -18,17 +18,19 @@ class AppContextService {
private config$?: Observable<IngestManagerConfigType>;
private configSubject$?: BehaviorSubject<IngestManagerConfigType>;
private savedObjects: SavedObjectsServiceStart | undefined;
private serverInfo: HttpServerInfo | undefined;
private isProductionMode: boolean = false;
private kibanaVersion: string | undefined;
private cloud?: CloudSetup;
private coreSetup?: CoreSetup;

public async start(appContext: IngestManagerAppContext) {
this.encryptedSavedObjects = appContext.encryptedSavedObjects;
this.security = appContext.security;
this.savedObjects = appContext.savedObjects;
this.serverInfo = appContext.serverInfo;
this.isProductionMode = appContext.isProductionMode;
this.cloud = appContext.cloud;
this.kibanaVersion = appContext.kibanaVersion;
this.coreSetup = appContext.coreSetup;

if (appContext.config$) {
this.config$ = appContext.config$;
Expand Down Expand Up @@ -77,11 +79,18 @@ class AppContextService {
return this.isProductionMode;
}

public getServerInfo() {
if (!this.serverInfo) {
throw new Error('Server info not set.');
public getCoreSetup() {
if (!this.coreSetup) {
throw new Error('CoreSetup not set.');
}
return this.serverInfo;
return this.coreSetup;
}

public getKibanaVersion() {
if (!this.kibanaVersion) {
throw new Error('Kibana version is not set.');
}
return this.kibanaVersion;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { appContextService } from '../app_context';
import { macosInstallTemplate } from './install_templates/macos';
import { linuxInstallTemplate } from './install_templates/linux';

export function getScript(osType: 'macos' | 'linux', kibanaUrl: string): string {
const variables = { kibanaUrl };
const variables = { kibanaUrl, kibanaVersion: appContextService.getKibanaVersion() };

switch (osType) {
case 'macos':
return macosInstallTemplate(variables);
case 'linux':
return macosInstallTemplate(variables);
return linuxInstallTemplate(variables);
default:
throw new Error(`${osType} is not supported.`);
}
Expand Down
Loading

0 comments on commit 57c1c18

Please sign in to comment.