Skip to content

Commit

Permalink
[BeatsCM] Cleanup and refactor (#26636)
Browse files Browse the repository at this point in the history
* Refactor BeatsCM

* update deps

* update more deps

* update for new EUI definitions

* update import

* Revert "update deps"

This reverts commit 759a145.

* use _source_includes

* remove _source_includes

* work-around due to watcher UI tests

* Keep all xpack checks safe because we cant trust its there in tests for some reason

* VALIDATION. This commit is to ensure the errors in CI are coming from beats

* remove validation that this is a beats CM issue

* More try/catch to try and find where this error is

* testing another call

* revert back to dangerouslyGetActiveInjector

* ensure expire always is a number

* fix swallowed error

* Update x-pack/plugins/beats_management/public/lib/compose/kibana.ts

Co-Authored-By: mattapperson <[email protected]>

* Update x-pack/plugins/beats_management/public/utils/page_loader.test.ts

Co-Authored-By: mattapperson <[email protected]>

* Update x-pack/plugins/beats_management/public/utils/page_loader.ts

Co-Authored-By: mattapperson <[email protected]>

* fix for new webpack import

* Fix translation map

* fix URL path

* fix other link

* removing tag from beats via tag details screen now uses container

* remove debug text

* added comment/readme about routing on the client side

* enrolled beat UI now works on overview screen

* newly enrolled beat now reloads the beats table

* fix TS errors
  • Loading branch information
mattapperson authored and chrisronline committed Dec 12, 2018
1 parent da114df commit cee968e
Show file tree
Hide file tree
Showing 121 changed files with 2,809 additions and 2,635 deletions.
4 changes: 3 additions & 1 deletion x-pack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@
"@kbn/babel-preset": "1.0.0",
"@kbn/es-query": "1.0.0",
"@kbn/i18n": "1.0.0",
"@kbn/ui-framework": "1.0.0",
"@kbn/interpreter": "1.0.0",
"@kbn/ui-framework": "1.0.0",
"@samverschueren/stream-to-observable": "^0.3.0",
"@scant/router": "^0.1.0",
"@slack/client": "^4.2.2",
Expand Down Expand Up @@ -181,6 +181,7 @@
"icalendar": "0.7.1",
"inline-style": "^2.0.0",
"intl": "^1.2.5",
"io-ts": "^1.4.2",
"isomorphic-fetch": "2.2.1",
"joi": "^13.5.2",
"jquery": "^3.3.1",
Expand Down Expand Up @@ -258,6 +259,7 @@
"typescript-fsa-reducers": "^0.4.5",
"ui-select": "0.19.4",
"unbzip2-stream": "1.0.9",
"unstated": "^2.1.1",
"uuid": "3.0.1",
"venn.js": "0.2.9",
"xregexp": "3.2.0"
Expand Down
3 changes: 2 additions & 1 deletion x-pack/plugins/beats_management/common/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
export { PLUGIN } from './plugin';
export { INDEX_NAMES } from './index_names';
export { UNIQUENESS_ENFORCING_TYPES, ConfigurationBlockTypes } from './configuration_blocks';
export const BASE_PATH = '/management/beats_management/';
export const BASE_PATH = '/management/beats_management';
export { TABLE_CONFIG } from './table';
export { REQUIRED_ROLES, LICENSES, REQUIRED_LICENSES } from './security';
1 change: 1 addition & 0 deletions x-pack/plugins/beats_management/common/constants/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
export const PLUGIN = {
ID: 'beats_management',
};
export const CONFIG_PREFIX = 'xpack.beats';
10 changes: 10 additions & 0 deletions x-pack/plugins/beats_management/common/constants/security.ts
Original file line number Diff line number Diff line change
@@ -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.
*/

export const REQUIRED_ROLES = ['beats_admin'];
export const REQUIRED_LICENSES = ['standard', 'gold', 'trial', 'platinum'];
export const LICENSES = ['oss', 'standard', 'gold', 'trial', 'platinum'];
export type LicenseType = 'oss' | 'trial' | 'standard' | 'basic' | 'gold' | 'platinum';
9 changes: 5 additions & 4 deletions x-pack/plugins/beats_management/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,24 @@
import Joi from 'joi';
import { resolve } from 'path';
import { PLUGIN } from './common/constants';
import { CONFIG_PREFIX } from './common/constants/plugin';
import { initServerWithKibana } from './server/kibana.index';
import { KibanaLegacyServer } from './server/lib/adapters/framework/adapter_types';

const DEFAULT_ENROLLMENT_TOKENS_TTL_S = 10 * 60; // 10 minutes

export const config = Joi.object({
enabled: Joi.boolean().default(true),
encryptionKey: Joi.string(),
defaultUserRoles: Joi.array()
.items(Joi.string())
.default(['superuser']),
encryptionKey: Joi.string().default('xpack_beats_default_encryptionKey'),
enrollmentTokensTtlInSeconds: Joi.number()
.integer()
.min(1)
.max(10 * 60 * 14) // No more then 2 weeks for security reasons
.default(DEFAULT_ENROLLMENT_TOKENS_TTL_S),
}).default();
export const configPrefix = 'xpack.beats';

export function beats(kibana: any) {
return new kibana.Plugin({
Expand All @@ -33,8 +34,8 @@ export function beats(kibana: any) {
managementSections: ['plugins/beats_management'],
},
config: () => config,
configPrefix,
init(server: any) {
configPrefix: CONFIG_PREFIX,
init(server: KibanaLegacyServer) {
initServerWithKibana(server);
},
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import {
// @ts-ignore typings for EuiBasicTable not present in current version
EuiBasicTable,
EuiButton,
EuiFlexGroup,
EuiFlexItem,
EuiLoadingSpinner,
Expand All @@ -15,37 +13,43 @@ import {
EuiSelect,
EuiTitle,
} from '@elastic/eui';
import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react';
import { FormattedMessage } from '@kbn/i18n/react';
import { capitalize } from 'lodash';
import React from 'react';
import { RouteComponentProps } from 'react-router';
import { CMBeat } from '../../../common/domain_types';
import { AppURLState } from '../../app';
import { URLStateProps, withUrlState } from '../../containers/with_url_state';
import { FrontendLibs } from '../../lib/lib';
import { CMBeat } from '../../common/domain_types';

interface BeatsProps extends URLStateProps<AppURLState>, RouteComponentProps<any> {
match: any;
libs: FrontendLibs;
intl: InjectedIntl;
interface ComponentProps {
/** Such as kibanas basePath, for use to generate command */
frameworkBasePath?: string;
enrollmentToken?: string;
getBeatWithToken(token: string): Promise<CMBeat | null>;
createEnrollmentToken(): Promise<void>;
onBeatEnrolled(enrolledBeat: CMBeat): void;
}
export class EnrollBeat extends React.Component<BeatsProps, any> {

interface ComponentState {
enrolledBeat: CMBeat | null;
hasPolledForBeat: boolean;
command: string;
beatType: string;
}

export class EnrollBeat extends React.Component<ComponentProps, ComponentState> {
private pinging = false;
constructor(props: BeatsProps) {
constructor(props: ComponentProps) {
super(props);

this.state = {
enrolledBeat: null,
hasPolledForBeat: false,
command: 'sudo filebeat',
beatType: 'filebeat',
};
}
public pingForBeatWithToken = async (
libs: FrontendLibs,
token: string
): Promise<CMBeat | void> => {
public pingForBeatWithToken = async (token: string): Promise<CMBeat | void> => {
try {
const beats = await libs.beats.getBeatWithToken(token);
const beats = await this.props.getBeatWithToken(token);

if (!beats) {
throw new Error('no beats');
}
Expand All @@ -54,69 +58,34 @@ export class EnrollBeat extends React.Component<BeatsProps, any> {
if (this.pinging) {
const timeout = (ms: number) => new Promise(res => setTimeout(res, ms));
await timeout(5000);
return await this.pingForBeatWithToken(libs, token);
return await this.pingForBeatWithToken(token);
}
}
};
public async componentDidMount() {
if (!this.props.urlState.enrollmentToken) {
const enrollmentToken = await this.props.libs.tokens.createEnrollmentToken();
this.props.setUrlState({
enrollmentToken,
});
if (!this.props.enrollmentToken) {
await this.props.createEnrollmentToken();
}
}
public waitForToken = async (token: string) => {
if (this.pinging) {
public waitForTokenToEnrollBeat = async () => {
if (this.pinging || !this.props.enrollmentToken) {
return;
}
this.pinging = true;
const enrolledBeat = (await this.pingForBeatWithToken(this.props.libs, token)) as CMBeat;
const enrolledBeat = (await this.pingForBeatWithToken(this.props.enrollmentToken)) as CMBeat;

this.setState({
enrolledBeat,
});
this.props.onBeatEnrolled(enrolledBeat);
this.pinging = false;
};
public render() {
if (!this.props.urlState.enrollmentToken) {
if (!this.props.enrollmentToken && !this.state.enrolledBeat) {
return null;
}
if (this.props.urlState.enrollmentToken && !this.state.enrolledBeat) {
this.waitForToken(this.props.urlState.enrollmentToken);
}
const { goTo, intl } = this.props;

const actions = [];

switch (this.props.location.pathname) {
case '/overview/initial/beats':
actions.push({
goTo: '/overview/initial/tag',
name: intl.formatMessage({
id: 'xpack.beatsManagement.enrollBeat.continueButtonLabel',
defaultMessage: 'Continue',
}),
});
break;
case '/overview/beats/enroll':
actions.push({
goTo: '/overview/beats/enroll',
name: intl.formatMessage({
id: 'xpack.beatsManagement.enrollBeat.enrollAnotherBeatButtonLabel',
defaultMessage: 'Enroll another Beat',
}),
newToken: true,
});
actions.push({
goTo: '/overview/beats',
name: intl.formatMessage({
id: 'xpack.beatsManagement.enrollBeat.doneButtonLabel',
defaultMessage: 'Done',
}),
clearToken: true,
});
break;
if (this.props.enrollmentToken && !this.state.enrolledBeat) {
this.waitForTokenToEnrollBeat();
}

return (
Expand Down Expand Up @@ -229,10 +198,7 @@ export class EnrollBeat extends React.Component<BeatsProps, any> {
/>
{`//`}
{window.location.host}
{this.props.libs.framework.baseURLPath
? this.props.libs.framework.baseURLPath
: ''}{' '}
{this.props.urlState.enrollmentToken}
{this.props.frameworkBasePath} {this.props.enrollmentToken}
</div>
</div>
<br />
Expand Down Expand Up @@ -309,38 +275,9 @@ export class EnrollBeat extends React.Component<BeatsProps, any> {
/>
<br />
<br />
{actions.map(action => (
<EuiButton
key={action.name}
size="s"
color="primary"
style={{ marginLeft: 10 }}
onClick={async () => {
if (action.clearToken) {
this.props.setUrlState({ enrollmentToken: '' });
}

if (action.newToken) {
const enrollmentToken = await this.props.libs.tokens.createEnrollmentToken();

this.props.setUrlState({ enrollmentToken });
return this.setState({
enrolledBeat: null,
});
}
goTo(action.goTo);
}}
>
{action.name}
</EuiButton>
))}
</EuiModalBody>
)}
</React.Fragment>
);
}
}

export const EnrollBeatPageUi = withUrlState<BeatsProps>(EnrollBeat);

export const EnrollBeatPage = injectI18n(EnrollBeatPageUi);
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@
* you may not use this file except in compliance with the Elastic License.
*/

export type FlatObject<T> = { [Key in keyof T]: string };
import styled from 'styled-components';

export interface AppURLState {
beatsKBar?: string;
tagsKBar?: string;
enrollmentToken?: string;
createdTag?: string;
}
export const Background = styled.div`
flex-grow: 1;
height: 100vh;
background: #f5f5f5;
`;

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import {
EuiEmptyPrompt,
EuiFlexGroup,
EuiFlexItem,
EuiModal,
EuiOverlayMask,
EuiPage,
EuiPageBody,
EuiPageContent,
Expand All @@ -21,13 +19,11 @@ import {
interface LayoutProps {
title: string;
actionSection?: React.ReactNode;
modalRender?: () => React.ReactNode;
modalClosePath?: string;
}

export const NoDataLayout: React.SFC<LayoutProps> = withRouter<any>(
({ actionSection, title, modalRender, modalClosePath, children, history }) => {
const modalContent = modalRender && modalRender();
({ actionSection, title, modalClosePath, children, history }) => {
return (
<EuiPage>
<EuiPageBody>
Expand All @@ -44,18 +40,6 @@ export const NoDataLayout: React.SFC<LayoutProps> = withRouter<any>(
</EuiFlexItem>
</EuiFlexGroup>
</EuiPageBody>
{modalContent && (
<EuiOverlayMask>
<EuiModal
onClose={() => {
history.push(modalClosePath);
}}
style={{ width: '640px' }}
>
{modalContent}
</EuiModal>
</EuiOverlayMask>
)}
</EuiPage>
);
}
Expand Down
Loading

0 comments on commit cee968e

Please sign in to comment.