Skip to content

Commit

Permalink
Beats/update (#21702)
Browse files Browse the repository at this point in the history
* [ML] Fixing issue with historical job audit messages (#21718)

* Add proper aria-label for close inspector (#21719)

* [Beats Management] Initial scaffolding for plugin (#18977)

* Initial scaffolding for Beats plugin

* Removing bits not (yet) necessary in initial scaffolding

* [Beats Management] Install Beats index template on plugin init (#19072)

* Install Beats index template on plugin init

* Adding missing files

* [Beats Management] APIs: Create enrollment tokens (#19018)

* WIP checkin

* Register API routes

* Fixing typo in index name

* Adding TODOs

* Removing commented out license checking code that isn't yet implemented

* Remove unnecessary async/await

* Don't return until indices have been refreshed

* Add API integration test

* Converting to Jest test

* Fixing API for default case + adding test for it

* Fixing copy pasta typos

* Adding TODO

* Fixing variable name

* Using a single index

* Adding expiration date field

* Adding test for expiration date field

* Ignore non-existent index

* Fixing logic in test

* Creating constant for default enrollment tokens TTL value

* Updating test

* Fixing name of test file (#19100)

* [Beats Management] APIs: Enroll beat (#19056)

* WIP checkin

* Add API integration test

* Converting to Jest test

* Create API for enrolling a beat

* Handle invalid or expired enrollment tokens

* Use create instead of index to prevent same beat from being enrolled twice

* Adding unit test for duplicate beat enrollment

* Do not persist enrollment token with beat once token has been checked and used

* Fix datatype of host_ip field

* Make Kibana API guess host IP instead of requiring it in payload

* Fixing error introduced in rebase conflict resolution

* [Beats Management] APIs: List beats (#19086)

* WIP checkin

* Add API integration test

* Converting to Jest test

* WIP checkin

* Fixing API for default case + adding test for it

* Fixing copy pasta typos

* Fixing variable name

* Using a single index

* Implementing GET /api/beats/agents API

* Updating mapping

* [Beats Management] APIs: Verify beats (#19103)

* WIP checkin

* WIP checkin

* Add API integration test

* Converting to Jest test

* Fixing API for default case + adding test for it

* Fixing copy pasta typos

* Fixing variable name

* Using a single index

* Implementing GET /api/beats/agents API

* Creating POST /api/beats/agents/verify API

* Refactoring: extracting out helper functions

* Fleshing out remaining tests

* Expanding TODO note so I won't forget :)

* Fixing file name

* Updating mapping

* Moving TODO comment to right file

* Rename determine* helper functions to find*

* Fixing assertions (#19194)

* [Beats Management] APIs: Update beat (#19148)

* WIP checkin

* WIP checkin

* Add API integration test

* Converting to Jest test

* Fixing API for default case + adding test for it

* Fixing copy pasta typos

* Fixing variable name

* Using a single index

* Implementing GET /api/beats/agents API

* Creating POST /api/beats/agents/verify API

* Refactoring: extracting out helper functions

* Expanding TODO note so I won't forget :)

* Fixing file name

* Updating mapping

* Add API tests

* Update template to allow version field for beat

* Implement PUT /api/beats/agent/{beat ID} API

* Make enroll beat code consistent with update beat code

* Fixing minor typo in TODO comment

* Allow version in request payload

* Make sure beat is not updated in ES in error scenarios

* Adding version as required field in Enroll Beat API payload

* Using destructuring

* Fixing rename that was accidentally reversed in conflict fixing

* [Beats Management] APIs: take auth tokens via headers (#19210)

* WIP checkin

* WIP checkin

* Add API integration test

* Converting to Jest test

* Fixing API for default case + adding test for it

* Fixing copy pasta typos

* Fixing variable name

* Using a single index

* Implementing GET /api/beats/agents API

* Creating POST /api/beats/agents/verify API

* Refactoring: extracting out helper functions

* Expanding TODO note so I won't forget :)

* Fixing file name

* Updating mapping

* Fixing minor typo in TODO comment

* Make "Enroll Beat" API take enrollment token via header instead of request body

* Make "Update Beat" API take access token via header instead of request body

* [Beats Management] APIs: Create configuration block (#19270)

* WIP checkin

* WIP checkin

* Add API integration test

* Converting to Jest test

* Fixing API for default case + adding test for it

* Fixing copy pasta typos

* Fixing variable name

* Using a single index

* Implementing GET /api/beats/agents API

* Creating POST /api/beats/agents/verify API

* Refactoring: extracting out helper functions

* Expanding TODO note so I won't forget :)

* Fixing file name

* Updating mapping

* Fixing minor typo in TODO comment

* Implementing POST /api/beats/configuration_blocks API

* Removing unnecessary escaping

* Fleshing out types + adding validation for them

* Making output singular (was outputs)

* Removing metricbeat.inputs

* Revert implementation of `POST /api/beats/configuration_blocks` API (#19340)

This API allowed the user to operate at a level of abstraction that is unnecessarily and dangerously too low. A better API would be at one level higher, where users can create, update, and delete tags (where a tag can contain multiple configuration blocks).

* [Beats Management] APIs: Create or update tag (#19342)

* Updating mappings

* Implementing PUT /api/beats/tag/{tag} API

* [Beats Management] Prevent timing attacks when checking auth tokens (#19363)

* Using crypto.timingSafeEqual() for comparing auth tokens

* Prevent subtler timing attack in token comparison function

* Introduce random delay after we try to find token in ES to mitigate timing attack

* Remove random delay

* [Beats Management] APIs: Assign tag(s) to beat(s) (#19431)

* Using crypto.timingSafeEqual() for comparing auth tokens

* Introduce random delay after we try to find token in ES to mitigate timing attack

* Rename "determine" to "find"

* Remove random delay

* Starting to implement POST /api/beats/beats_tags API

* Changing API

* Updating tests for changes to API

* Updating ES archive

* Renaming

* Use destructuring

* Moving start of script to own line to increase readability

* Using destructuring

* [Beats Management] APIs: Remove tag(s) from beat(s) (#19440)

* Using crypto.timingSafeEqual() for comparing auth tokens

* Introduce random delay after we try to find token in ES to mitigate timing attack

* Remove random delay

* Starting to implement POST /api/beats/beats_tags API

* Changing API

* Updating tests for changes to API

* Renaming

* Use destructuring

* Using crypto.timingSafeEqual() for comparing auth tokens

* Introduce random delay after we try to find token in ES to mitigate timing attack

* Implementing `POST /api/beats/agents_tags/removals` API

* Updating ES archive

* Use destructuring

* Moving start of script to own line to increase readability

* Nothing to remove if there are no existing tags!

* Updating tests to match changes in bulk update painless script

* Use destructuring

* [Beats Management] Move to Ingest UI arch and initial TS effort (#20039)

* [Beats Management] Initial scaffolding for plugin (#18977)

* Initial scaffolding for Beats plugin

* Removing bits not (yet) necessary in initial scaffolding

* [Beats Management] Install Beats index template on plugin init (#19072)

* Install Beats index template on plugin init

* Adding missing files

* [Beats Management] APIs: Create enrollment tokens (#19018)

* WIP checkin

* Register API routes

* Fixing typo in index name

* Adding TODOs

* Removing commented out license checking code that isn't yet implemented

* Remove unnecessary async/await

* Don't return until indices have been refreshed

* Add API integration test

* Converting to Jest test

* Fixing API for default case + adding test for it

* Fixing copy pasta typos

* Adding TODO

* Fixing variable name

* Using a single index

* Adding expiration date field

* Adding test for expiration date field

* Ignore non-existent index

* Fixing logic in test

* Creating constant for default enrollment tokens TTL value

* Updating test

* Fixing name of test file (#19100)

* [Beats Management] APIs: Enroll beat (#19056)

* WIP checkin

* Add API integration test

* Converting to Jest test

* Create API for enrolling a beat

* Handle invalid or expired enrollment tokens

* Use create instead of index to prevent same beat from being enrolled twice

* Adding unit test for duplicate beat enrollment

* Do not persist enrollment token with beat once token has been checked and used

* Fix datatype of host_ip field

* Make Kibana API guess host IP instead of requiring it in payload

* Fixing error introduced in rebase conflict resolution

* [Beats Management] APIs: List beats (#19086)

* WIP checkin

* Add API integration test

* Converting to Jest test

* WIP checkin

* Fixing API for default case + adding test for it

* Fixing copy pasta typos

* Fixing variable name

* Using a single index

* Implementing GET /api/beats/agents API

* Updating mapping

* [Beats Management] APIs: Verify beats (#19103)

* WIP checkin

* WIP checkin

* Add API integration test

* Converting to Jest test

* Fixing API for default case + adding test for it

* Fixing copy pasta typos

* Fixing variable name

* Using a single index

* Implementing GET /api/beats/agents API

* Creating POST /api/beats/agents/verify API

* Refactoring: extracting out helper functions

* Fleshing out remaining tests

* Expanding TODO note so I won't forget :)

* Fixing file name

* Updating mapping

* Moving TODO comment to right file

* Rename determine* helper functions to find*

* Fixing assertions (#19194)

* [Beats Management] APIs: Update beat (#19148)

* WIP checkin

* WIP checkin

* Add API integration test

* Converting to Jest test

* Fixing API for default case + adding test for it

* Fixing copy pasta typos

* Fixing variable name

* Using a single index

* Implementing GET /api/beats/agents API

* Creating POST /api/beats/agents/verify API

* Refactoring: extracting out helper functions

* Expanding TODO note so I won't forget :)

* Fixing file name

* Updating mapping

* Add API tests

* Update template to allow version field for beat

* Implement PUT /api/beats/agent/{beat ID} API

* Make enroll beat code consistent with update beat code

* Fixing minor typo in TODO comment

* Allow version in request payload

* Make sure beat is not updated in ES in error scenarios

* Adding version as required field in Enroll Beat API payload

* Using destructuring

* Fixing rename that was accidentally reversed in conflict fixing

* [Beats Management] APIs: take auth tokens via headers (#19210)

* WIP checkin

* WIP checkin

* Add API integration test

* Converting to Jest test

* Fixing API for default case + adding test for it

* Fixing copy pasta typos

* Fixing variable name

* Using a single index

* Implementing GET /api/beats/agents API

* Creating POST /api/beats/agents/verify API

* Refactoring: extracting out helper functions

* Expanding TODO note so I won't forget :)

* Fixing file name

* Updating mapping

* Fixing minor typo in TODO comment

* Make "Enroll Beat" API take enrollment token via header instead of request body

* Make "Update Beat" API take access token via header instead of request body

* [Beats Management] APIs: Create configuration block (#19270)

* WIP checkin

* WIP checkin

* Add API integration test

* Converting to Jest test

* Fixing API for default case + adding test for it

* Fixing copy pasta typos

* Fixing variable name

* Using a single index

* Implementing GET /api/beats/agents API

* Creating POST /api/beats/agents/verify API

* Refactoring: extracting out helper functions

* Expanding TODO note so I won't forget :)

* Fixing file name

* Updating mapping

* Fixing minor typo in TODO comment

* Implementing POST /api/beats/configuration_blocks API

* Removing unnecessary escaping

* Fleshing out types + adding validation for them

* Making output singular (was outputs)

* Removing metricbeat.inputs

* Revert implementation of `POST /api/beats/configuration_blocks` API (#19340)

This API allowed the user to operate at a level of abstraction that is unnecessarily and dangerously too low. A better API would be at one level higher, where users can create, update, and delete tags (where a tag can contain multiple configuration blocks).

* [Beats Management] APIs: Create or update tag (#19342)

* Updating mappings

* Implementing PUT /api/beats/tag/{tag} API

* [Beats Management] Prevent timing attacks when checking auth tokens (#19363)

* Using crypto.timingSafeEqual() for comparing auth tokens

* Prevent subtler timing attack in token comparison function

* Introduce random delay after we try to find token in ES to mitigate timing attack

* Remove random delay

* [Beats Management] APIs: Assign tag(s) to beat(s) (#19431)

* Using crypto.timingSafeEqual() for comparing auth tokens

* Introduce random delay after we try to find token in ES to mitigate timing attack

* Rename "determine" to "find"

* Remove random delay

* Starting to implement POST /api/beats/beats_tags API

* Changing API

* Updating tests for changes to API

* Updating ES archive

* Renaming

* Use destructuring

* Moving start of script to own line to increase readability

* Using destructuring

* [Beats Management] APIs: Remove tag(s) from beat(s) (#19440)

* Using crypto.timingSafeEqual() for comparing auth tokens

* Introduce random delay after we try to find token in ES to mitigate timing attack

* Remove random delay

* Starting to implement POST /api/beats/beats_tags API

* Changing API

* Updating tests for changes to API

* Renaming

* Use destructuring

* Using crypto.timingSafeEqual() for comparing auth tokens

* Introduce random delay after we try to find token in ES to mitigate timing attack

* Implementing `POST /api/beats/agents_tags/removals` API

* Updating ES archive

* Use destructuring

* Moving start of script to own line to increase readability

* Nothing to remove if there are no existing tags!

* Updating tests to match changes in bulk update painless script

* Use destructuring

* Ported over base types and arch structure

* move management of installIndexTemplate into the framework adapter

* ts-lint fix

* tslint fixes

* more ts tweaks

* fix paths

* added several working endpoints

* add more routes and bug fixes

* fix linting

* fix type remove CRUFT

* remove more cruft

* remove more CRUFT

* added comments, change plurality

* add tsconfig file

* add extends path

* fixed typo

* serveral PR review fixes

* fixed lodash type version

* “fix” types by applying a lot of any

* [Beats Management] Move tokens to use JWT, add more complete test suite (#20317)

* inital effort to move to JWT and added jest based tests on libs

* assign beats tests all passing

* token tests now pass

* add more tests

* all tests now green

* fix broken test, this is beats CM not logstash 😊

* added readme

* move enrollment token back to a hash

* remove un-needed comment

* alias lodash get to avoid confusion

* isolated hash creation

* [Beats Management] add more tests, update types, break out ES into it's own adapter (#20566)

* inital effort to move to JWT and added jest based tests on libs

* assign beats tests all passing

* token tests now pass

* add more tests

* all tests now green

* move enrollment token back to a hash

* remove un-needed comment

* alias lodash get to avoid confusion

* isolated hash creation

* Add initial efforts for backend framework adapter testing

* move ES code to a DatabaseAdapter from BackendAdapter and add a TON of types for ES

* re-typed

* renamed types to match pattern

* aditional renames

* adapter tests should always just use adapterSetup();

* database now uses InternalRequest

* corrected spelling of framework

* fix typings

* remove CRUFT

* RequestOrInternal

* Dont pass around request objects everywhere, just pass the user. Also, removed hapi types as they were not compatible

* fix tests, add test, removed extra comment

* fix auth

* updated lock file

* [Beats Management] add get beat endpoint (#20603)

* [Beats Management] Move tokens to use JWT, add more complete test suite (#20317)

* inital effort to move to JWT and added jest based tests on libs

* assign beats tests all passing

* token tests now pass

* add more tests

* all tests now green

* fix broken test, this is beats CM not logstash 😊

* added readme

* move enrollment token back to a hash

* remove un-needed comment

* alias lodash get to avoid confusion

* isolated hash creation

* inital effort to move to JWT and added jest based tests on libs

* assign beats tests all passing

* token tests now pass

* add more tests

* all tests now green

* move enrollment token back to a hash

* remove un-needed comment

* alias lodash get to avoid confusion

* isolated hash creation

* Add initial efforts for backend framework adapter testing

* move ES code to a DatabaseAdapter from BackendAdapter and add a TON of types for ES

* re-typed

* renamed types to match pattern

* aditional renames

* adapter tests should always just use adapterSetup();

* database now uses InternalRequest

* corrected spelling of framework

* fix typings

* remove CRUFT

* RequestOrInternal

* Dont pass around request objects everywhere, just pass the user. Also, removed hapi types as they were not compatible

* fix tests, add test, removed extra comment

* Moved critical path code from route, to more easeley tested domain

* fix auth

* remove beat verification, added get beat endpoint to return configs

* fix type

* update createGetBeatConfigurationRoute URL

* rename method

* update to match PR #20566

* updated lock file

* fix bad merge

* update TSLinting

* fix bad rebase

* [Beats Management] [WIP] Create public resources for management plugin (#20864)

* Init plugin public resources.

* rename beats to beats_management

* rendering react now

* Beats/initial ui (#20994)

* initial layout and main nav

* modal UI and pattern for UI established

* fix path

* wire up in-memroy adapters

* tweak adapters

* add getAll method to tags adapter (#21287)

* Beats/real adapters (#21481)

* add initial real adapters, and nulled data where we need endpoints

* UI adapters and needed endpoints added (though not tested)

* prep for route tests and some cleanup

* move files

* [Beats Management] Add BeatsTable/Bulk Action Search Component (#21182)

* Add BeatsTable and control bar components.

* Clean yarn.lock.

* Move raw numbers/strings to constants. Remove obsolete state/props.

* Update/add tests.

* Change prop name from "items" to "beats".

* Rename some variables.

* Move search bar filter definitions to table render.

* Update table to support assignment options.

* Update action control position.

* Refactor split render function into custom components.

* Beats/basic use cases (#21660)

* tweak adapter responses / types. re-add enroll ui

* routes enabled, enroll now pings the server

* full enrollment path now working

* improved pinging for beat enrollment

* fix location of history call

* reload beats list on beat enrollment completion

* add update on client side, expand update on server to allow for partial data, and user auth

* remove double beat lookup

* fix tests

* only return active beats

* disenroll now working

* fig getAll query

* re-enrolling a beat will now work

* fix types

* fix types

* update deps

* update kibana API for version
  • Loading branch information
mattapperson authored Aug 8, 2018
1 parent 7f950ca commit 463e579
Show file tree
Hide file tree
Showing 31 changed files with 317 additions and 76 deletions.
1 change: 1 addition & 0 deletions src/ui/public/flyout/flyout_session.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class FlyoutSession extends EventEmitter {
export function openFlyout(
flyoutChildren: React.ReactNode,
flyoutProps: {
closeButtonAriaLabel?: string;
onClose?: () => void;
'data-test-subj'?: string;
} = {}
Expand Down
1 change: 1 addition & 0 deletions src/ui/public/inspector/inspector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ function open(adapters: Adapters, options: InspectorOptions = {}): InspectorSess

return openFlyout(<InspectorPanel views={views} adapters={adapters} title={options.title} />, {
'data-test-subj': 'inspectorPanel',
closeButtonAriaLabel: 'Close Inspector',
});
}

Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/beats_management/common/domain_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export interface ConfigurationBlock {
export interface CMBeat {
id: string;
enrollment_token: string;
active: boolean;
access_token: string;
verified_on?: string;
type: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export function ControlBar(props: ControlBarProps) {
selectionCount,
showAssignmentOptions,
} = props;

const filters = controlDefinitions.filters.length === 0 ? null : controlDefinitions.filters;
return selectionCount !== 0 && showAssignmentOptions ? (
<AssignmentOptions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export class Table extends React.Component<BeatsTableProps, BeatsTableState> {
}

public render() {

const {
actionHandler,
assignmentOptions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { EuiBadge, EuiFlexGroup, EuiIcon, EuiLink } from '@elastic/eui';
import { flatten, uniq } from 'lodash';
import moment from 'moment';
import React from 'react';

import { TABLE_CONFIG } from '../../../common/constants';
import { BeatTag, CMPopulatedBeat, ConfigurationBlock } from '../../../common/domain_types';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { CMBeat } from '../../../../common/domain_types';

export interface CMBeatsAdapter {
get(id: string): Promise<CMBeat | null>;
update(id: string, beatData: Partial<CMBeat>): Promise<boolean>;
getAll(): Promise<CMBeat[]>;
removeTagsFromBeats(removals: BeatsTagAssignment[]): Promise<BeatsRemovalReturn[]>;
assignTagsToBeats(assignments: BeatsTagAssignment[]): Promise<CMAssignmentReturn[]>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ export class MemoryBeatsAdapter implements CMBeatsAdapter {
return this.beatsDB.find(beat => beat.id === id) || null;
}

public async update(id: string, beatData: Partial<CMBeat>): Promise<boolean> {
const index = this.beatsDB.findIndex(beat => beat.id === id);

if (index === -1) {
return false;
}

this.beatsDB[index] = { ...this.beatsDB[index], ...beatData };
return true;
}

public async getAll() {
return this.beatsDB.map<CMBeat>((beat: any) => omit(beat, ['access_token']));
}
Expand All @@ -35,6 +46,12 @@ export class MemoryBeatsAdapter implements CMBeatsAdapter {
const beatIds = removals.map(r => r.beatId);

const response = this.beatsDB.filter(beat => beatIds.includes(beat.id)).map(beat => {
const tagData = removals.find(r => r.beatId === beat.id);
if (tagData) {
if (beat.tags) {
beat.tags = beat.tags.filter(tag => tag !== tagData.tag);
}
}
const removalsForBeat = removals.filter(r => r.beatId === beat.id);
if (removalsForBeat.length) {
removalsForBeat.forEach((assignment: BeatsTagAssignment) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ export class RestBeatsAdapter implements CMBeatsAdapter {
return (await this.REST.get<{ beats: CMBeat[] }>('/api/beats/agents')).beats;
}

public async update(id: string, beatData: Partial<CMBeat>): Promise<boolean> {
await this.REST.put<{ success: true }>(`/api/beats/agent/${id}`, beatData);
return true;
}

public async removeTagsFromBeats(removals: BeatsTagAssignment[]): Promise<BeatsRemovalReturn[]> {
return (await this.REST.post<{ removals: BeatsRemovalReturn[] }>(
`/api/beats/agents_tags/removals`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import {

export class KibanaFrameworkAdapter implements FrameworkAdapter {
public appState: object;
public kbnVersion?: string;

private management: any;
private adapterService: KibanaAdapterServiceProvider;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,7 @@ import { RestAPIAdapter } from './adapter_types';
let globalAPI: AxiosInstance;

export class AxiosRestAPIAdapter implements RestAPIAdapter {
constructor(
private readonly kbnVersion: string,
private readonly xsrfToken: string,
private readonly basePath: string
) {}
constructor(private readonly xsrfToken: string, private readonly basePath: string) {}

public async get<ResponseData>(url: string): Promise<ResponseData> {
return await this.REST.get(url).then(resp => resp.data);
Expand Down Expand Up @@ -48,7 +44,7 @@ export class AxiosRestAPIAdapter implements RestAPIAdapter {
Accept: 'application/json',
credentials: 'same-origin',
'Content-Type': 'application/json',
'kbn-version': this.kbnVersion,
'kbn-version': this.xsrfToken,
'kbn-xsrf': this.xsrfToken,
},
});
Expand Down
3 changes: 1 addition & 2 deletions x-pack/plugins/beats_management/public/lib/compose/kibana.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ import { RestTokensAdapter } from '../adapters/tokens/rest_tokens_adapter';
import { FrontendDomainLibs, FrontendLibs } from '../lib';

export function compose(): FrontendLibs {
const kbnVersion = (window as any).__KBN__.version;
const api = new AxiosRestAPIAdapter(kbnVersion, chrome.getXsrfToken(), chrome.getBasePath());
const api = new AxiosRestAPIAdapter(chrome.getXsrfToken(), chrome.getBasePath());

const tags = new RestTagsAdapter(api);
const tokens = new RestTokensAdapter(api);
Expand Down
16 changes: 11 additions & 5 deletions x-pack/plugins/beats_management/public/pages/main/beats.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,16 @@ export class BeatsPage extends React.PureComponent<BeatsPageProps, BeatsPageStat
this.loadBeats();
};

// TODO: call delete endpoint
private deleteSelected = async () => {
// const selected = this.getSelectedBeats();
// await this.props.libs.beats.delete(selected);
const selected = this.getSelectedBeats();
for (const beat of selected) {
await this.props.libs.beats.update(beat.id, { active: false });
}
// because the compile code above has a very minor race condition, we wait,
// the max race condition time is really 10ms but doing 100 to be safe
setTimeout(async () => {
await this.loadBeats();
}, 100);
};

private async loadBeats() {
Expand Down Expand Up @@ -110,7 +116,7 @@ export class BeatsPage extends React.PureComponent<BeatsPageProps, BeatsPageStat
<EuiFlexItem key={tag.id}>
<EuiBadge
color={tag.color}
iconType={hasMatches ? 'cross' : null}
iconType={hasMatches ? 'cross' : undefined}
onClick={
hasMatches
? () => this.removeTagsFromBeats(selectedBeats, tag)
Expand Down Expand Up @@ -143,7 +149,7 @@ export class BeatsPage extends React.PureComponent<BeatsPageProps, BeatsPageStat
this.loadBeats();
};

private getSelectedBeats = () => {
private getSelectedBeats = (): CMPopulatedBeat[] => {
return this.state.tableRef.current.state.selection;
};
}
1 change: 1 addition & 0 deletions x-pack/plugins/beats_management/public/pages/main/tags.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/


// @ts-ignore EuiToolTip has no typings in current version
import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiIcon, EuiToolTip } from '@elastic/eui';
import React from 'react';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { CMBeat } from '../../../../common/domain_types';
import { FrameworkUser } from '../framework/adapter_types';

export interface CMBeatsAdapter {
insert(beat: CMBeat): Promise<void>;
update(beat: CMBeat): Promise<void>;
insert(user: FrameworkUser, beat: CMBeat): Promise<void>;
update(user: FrameworkUser, beat: CMBeat): Promise<void>;
get(user: FrameworkUser, id: string): Promise<CMBeat | null>;
getAll(user: FrameworkUser): Promise<CMBeat[]>;
getWithIds(user: FrameworkUser, beatIds: string[]): Promise<CMBeat[]>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,15 @@ import { flatten, get as _get, omit } from 'lodash';
import { INDEX_NAMES } from '../../../../common/constants';
import { CMBeat } from '../../../../common/domain_types';
import { DatabaseAdapter } from '../database/adapter_types';
import { BackendFrameworkAdapter } from '../framework/adapter_types';

import { FrameworkUser } from '../framework/adapter_types';
import { BeatsTagAssignment, CMBeatsAdapter } from './adapter_types';

export class ElasticsearchBeatsAdapter implements CMBeatsAdapter {
private database: DatabaseAdapter;
private framework: BackendFrameworkAdapter;

constructor(database: DatabaseAdapter, framework: BackendFrameworkAdapter) {
constructor(database: DatabaseAdapter) {
this.database = database;
this.framework = framework;
}

public async get(user: FrameworkUser, id: string) {
Expand All @@ -37,13 +35,13 @@ export class ElasticsearchBeatsAdapter implements CMBeatsAdapter {
return _get<CMBeat>(response, '_source.beat');
}

public async insert(beat: CMBeat) {
public async insert(user: FrameworkUser, beat: CMBeat) {
const body = {
beat,
type: 'beat',
};

await this.database.create(this.framework.internalUser, {
await this.database.index(user, {
body,
id: `beat:${beat.id}`,
index: INDEX_NAMES.BEATS,
Expand All @@ -52,7 +50,7 @@ export class ElasticsearchBeatsAdapter implements CMBeatsAdapter {
});
}

public async update(beat: CMBeat) {
public async update(user: FrameworkUser, beat: CMBeat) {
const body = {
beat,
type: 'beat',
Expand All @@ -65,7 +63,7 @@ export class ElasticsearchBeatsAdapter implements CMBeatsAdapter {
refresh: 'wait_for',
type: '_doc',
};
await this.database.index(this.framework.internalUser, params);
await this.database.index(user, params);
}

public async getWithIds(user: FrameworkUser, beatIds: string[]) {
Expand Down Expand Up @@ -115,11 +113,12 @@ export class ElasticsearchBeatsAdapter implements CMBeatsAdapter {
const params = {
index: INDEX_NAMES.BEATS,
q: 'type:beat',
size: 10000,
type: '_doc',
};
const response = await this.database.search(user, params);

const beats = _get<any>(response, 'hits.hits', []);

return beats.map((beat: any) => omit(beat._source.beat, ['access_token']));
}

Expand All @@ -129,16 +128,15 @@ export class ElasticsearchBeatsAdapter implements CMBeatsAdapter {
): Promise<BeatsTagAssignment[]> {
const body = flatten(
removals.map(({ beatId, tag }) => {
const script =
'' +
'def beat = ctx._source.beat; ' +
'if (beat.tags != null) { ' +
' beat.tags.removeAll([params.tag]); ' +
'}';
const script = `
def beat = ctx._source.beat;
if (beat.tags != null) {
beat.tags.removeAll([params.tag]);
}`;

return [
{ update: { _id: `beat:${beatId}` } },
{ script: { source: script, params: { tag } } },
{ script: { source: script.replace(' ', ''), params: { tag } } },
];
})
);
Expand All @@ -162,19 +160,18 @@ export class ElasticsearchBeatsAdapter implements CMBeatsAdapter {
): Promise<BeatsTagAssignment[]> {
const body = flatten(
assignments.map(({ beatId, tag }) => {
const script =
'' +
'def beat = ctx._source.beat; ' +
'if (beat.tags == null) { ' +
' beat.tags = []; ' +
'} ' +
'if (!beat.tags.contains(params.tag)) { ' +
' beat.tags.add(params.tag); ' +
'}';
const script = `
def beat = ctx._source.beat;
if (beat.tags == null) {
beat.tags = [];
}
if (!beat.tags.contains(params.tag)) {
beat.tags.add(params.tag);
}`;

return [
{ update: { _id: `beat:${beatId}` } },
{ script: { source: script, params: { tag } } },
{ script: { source: script.replace(' ', ''), params: { tag } } },
];
})
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ export class MemoryBeatsAdapter implements CMBeatsAdapter {
return this.beatsDB.find(beat => beat.id === id) || null;
}

public async insert(beat: CMBeat) {
public async insert(user: FrameworkUser, beat: CMBeat) {
this.beatsDB.push(beat);
}

public async update(beat: CMBeat) {
public async update(user: FrameworkUser, beat: CMBeat) {
const beatIndex = this.beatsDB.findIndex(b => b.id === beat.id);

this.beatsDB[beatIndex] = {
Expand Down
3 changes: 2 additions & 1 deletion x-pack/plugins/beats_management/server/lib/compose/kibana.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ export function compose(server: any): CMServerLibs {
const tokens = new CMTokensDomain(new ElasticsearchTokensAdapter(database, framework), {
framework,
});
const beats = new CMBeatsDomain(new ElasticsearchBeatsAdapter(database, framework), {
const beats = new CMBeatsDomain(new ElasticsearchBeatsAdapter(database), {
tags,
tokens,
framework,
});

const domainLibs: CMDomainLibs = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export function compose({
const beats = new CMBeatsDomain(new MemoryBeatsAdapter(beatsDB), {
tags,
tokens,
framework,
});

const domainLibs: CMDomainLibs = {
Expand Down
Loading

0 comments on commit 463e579

Please sign in to comment.