Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
36fef75
inital effort to move to JWT and added jest based tests on libs
mattapperson Jun 27, 2018
aac4632
assign beats tests all passing
mattapperson Jun 27, 2018
9acb876
token tests now pass
mattapperson Jun 27, 2018
dd634b9
add more tests
mattapperson Jun 28, 2018
de2c4cc
all tests now green
mattapperson Jun 30, 2018
7c3c53a
move enrollment token back to a hash
mattapperson Jul 2, 2018
480fae5
remove un-needed comment
mattapperson Jul 2, 2018
03544e3
alias lodash get to avoid confusion
mattapperson Jul 2, 2018
3a7bdac
isolated hash creation
mattapperson Jul 2, 2018
5575ab5
Add initial efforts for backend framework adapter testing
mattapperson Jul 3, 2018
f17046e
move ES code to a DatabaseAdapter from BackendAdapter and add a TON o…
mattapperson Jul 6, 2018
d328dd3
re-typed
mattapperson Jul 9, 2018
d169319
renamed types to match pattern
mattapperson Jul 9, 2018
e430b44
aditional renames
mattapperson Jul 9, 2018
6334d76
adapter tests should always just use adapterSetup();
mattapperson Jul 11, 2018
95e5764
database now uses InternalRequest
mattapperson Jul 11, 2018
06568ca
corrected spelling of framework
mattapperson Jul 11, 2018
b7dc1e7
fix typings
mattapperson Jul 11, 2018
0b42c23
remove CRUFT
mattapperson Jul 11, 2018
69a2439
RequestOrInternal
mattapperson Jul 11, 2018
cfbc1a1
Dont pass around request objects everywhere, just pass the user. Also…
mattapperson Jul 11, 2018
8533c1b
fix tests, add test, removed extra comment
mattapperson Jul 12, 2018
ab88e51
fix auth
mattapperson Jul 12, 2018
ea26917
updated lock file
mattapperson Jul 12, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions x-pack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@
"@kbn/test": "link:../packages/kbn-test",
"@types/boom": "^4.3.8",
"@types/chance": "^1.0.1",
"@types/expect.js": "^0.3.29",
"@types/hapi": "15.0.1",
"@types/jest": "^22.2.3",
"@types/joi": "^10.4.0",
"@types/lodash": "^3.10.0",
Expand Down
31 changes: 31 additions & 0 deletions x-pack/plugins/beats/common/domain_types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* 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 { ConfigurationBlockTypes } from './constants';

export interface ConfigurationBlock {
type: ConfigurationBlockTypes;
block_yml: string;
}

export interface CMBeat {
id: string;
access_token: string;
verified_on?: string;
type: string;
version?: string;
host_ip: string;
host_name: string;
ephemeral_id?: string;
local_configuration_yml?: string;
tags?: string[];
central_configuration_yml?: string;
metadata?: {};
}

export interface BeatTag {
id: string;
configuration_blocks: ConfigurationBlock[];
}
22 changes: 12 additions & 10 deletions x-pack/plugins/beats/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,20 @@ import { initServerWithKibana } from './server/kibana.index';

const DEFAULT_ENROLLMENT_TOKENS_TTL_S = 10 * 60; // 10 minutes

export const config = Joi.object({
enabled: Joi.boolean().default(true),
encryptionKey: Joi.string(),
enrollmentTokensTtlInSeconds: Joi.number()
.integer()
.min(1)
.default(DEFAULT_ENROLLMENT_TOKENS_TTL_S),
}).default();
export const configPrefix = 'xpack.beats';

export function beats(kibana: any) {
return new kibana.Plugin({
config: () =>
Joi.object({
enabled: Joi.boolean().default(true),
encryptionKey: Joi.string(),
enrollmentTokensTtlInSeconds: Joi.number()
.integer()
.min(1)
.default(DEFAULT_ENROLLMENT_TOKENS_TTL_S),
}).default(),
configPrefix: 'xpack.beats',
config: () => config,
configPrefix,
id: PLUGIN.ID,
require: ['kibana', 'elasticsearch', 'xpack_main'],
init(server: any) {
Expand Down
10 changes: 9 additions & 1 deletion x-pack/plugins/beats/readme.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
# Documentation for Beats CM in x-pack kibana

### Run tests
### Run tests (from x-pack dir)

Functional tests

```
node scripts/jest.js plugins/beats --watch
```

Functional API tests

```
node scripts/functional_tests --config test/api_integration/config
```
3 changes: 1 addition & 2 deletions x-pack/plugins/beats/server/kibana.index.ts
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.
*/

import { Server } from 'hapi';
import { compose } from './lib/compose/kibana';
import { initManagementServer } from './management_server';

export const initServerWithKibana = (hapiServer: Server) => {
export const initServerWithKibana = (hapiServer: any) => {
const libs = compose(hapiServer);
initManagementServer(libs);
};
45 changes: 45 additions & 0 deletions x-pack/plugins/beats/server/lib/adapters/beats/adapter_types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* 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 { CMBeat } from '../../../../common/domain_types';
import { FrameworkUser } from '../framework/adapter_types';

// FIXME: fix getBeatsWithIds return type
export interface CMBeatsAdapter {
insert(beat: CMBeat): Promise<void>;
update(beat: CMBeat): Promise<void>;
get(id: string): any;
getAll(user: FrameworkUser): any;
getWithIds(user: FrameworkUser, beatIds: string[]): any;
verifyBeats(user: FrameworkUser, beatIds: string[]): any;
removeTagsFromBeats(
user: FrameworkUser,
removals: BeatsTagAssignment[]
): Promise<BeatsTagAssignment[]>;
assignTagsToBeats(
user: FrameworkUser,
assignments: BeatsTagAssignment[]
): Promise<BeatsTagAssignment[]>;
}

export interface BeatsTagAssignment {
beatId: string;
tag: string;
idxInRequest?: number;
}

interface BeatsReturnedTagAssignment {
status: number | null;
result?: string;
}

export interface CMAssignmentReturn {
assignments: BeatsReturnedTagAssignment[];
}

export interface BeatsRemovalReturn {
removals: BeatsReturnedTagAssignment[];
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@
import { flatten, get as _get, omit } from 'lodash';
import moment from 'moment';
import { INDEX_NAMES } from '../../../../common/constants';
import {
BackendFrameworkAdapter,
CMBeat,
CMBeatsAdapter,
CMTagAssignment,
FrameworkRequest,
} from '../../lib';
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(framework: BackendFrameworkAdapter) {
constructor(database: DatabaseAdapter, framework: BackendFrameworkAdapter) {
this.database = database;
this.framework = framework;
}

Expand All @@ -30,7 +30,10 @@ export class ElasticsearchBeatsAdapter implements CMBeatsAdapter {
type: '_doc',
};

const response = await this.framework.callWithInternalUser('get', params);
const response = await this.database.get(
this.framework.internalUser,
params
);
if (!response.found) {
return null;
}
Expand All @@ -44,14 +47,13 @@ export class ElasticsearchBeatsAdapter implements CMBeatsAdapter {
type: 'beat',
};

const params = {
await this.database.create(this.framework.internalUser, {
body,
id: `beat:${beat.id}`,
index: INDEX_NAMES.BEATS,
refresh: 'wait_for',
type: '_doc',
};
await this.framework.callWithInternalUser('create', params);
});
}

public async update(beat: CMBeat) {
Expand All @@ -67,10 +69,10 @@ export class ElasticsearchBeatsAdapter implements CMBeatsAdapter {
refresh: 'wait_for',
type: '_doc',
};
return await this.framework.callWithInternalUser('index', params);
await this.database.index(this.framework.internalUser, params);
}

public async getWithIds(req: FrameworkRequest, beatIds: string[]) {
public async getWithIds(user: FrameworkUser, beatIds: string[]) {
const ids = beatIds.map(beatId => `beat:${beatId}`);

const params = {
Expand All @@ -81,14 +83,14 @@ export class ElasticsearchBeatsAdapter implements CMBeatsAdapter {
index: INDEX_NAMES.BEATS,
type: '_doc',
};
const response = await this.framework.callWithRequest(req, 'mget', params);
const response = await this.database.mget(user, params);

return get(response, 'docs', [])
return _get(response, 'docs', [])
.filter((b: any) => b.found)
.map((b: any) => b._source.beat);
}

public async verifyBeats(req: FrameworkRequest, beatIds: string[]) {
public async verifyBeats(user: FrameworkUser, beatIds: string[]) {
if (!Array.isArray(beatIds) || beatIds.length === 0) {
return [];
}
Expand All @@ -101,42 +103,36 @@ export class ElasticsearchBeatsAdapter implements CMBeatsAdapter {
])
);

const params = {
const response = await this.database.bulk(user, {
_sourceInclude: ['beat.id', 'beat.verified_on'],
body,
index: INDEX_NAMES.BEATS,
refresh: 'wait_for',
type: '_doc',
};

const response = await this.framework.callWithRequest(req, 'bulk', params);
});

return _get(response, 'items', []).map(b => ({
..._get(b, 'update.get._source.beat', {}),
updateStatus: _get(b, 'update.result', 'unknown error'),
}));
}

public async getAll(req: FrameworkRequest) {
public async getAll(user: FrameworkUser) {
const params = {
index: INDEX_NAMES.BEATS,
q: 'type:beat',
type: '_doc',
};
const response = await this.framework.callWithRequest(
req,
'search',
params
);
const response = await this.database.search(user, params);

const beats = get<any>(response, 'hits.hits', []);
const beats = _get<any>(response, 'hits.hits', []);
return beats.map((beat: any) => omit(beat._source.beat, ['access_token']));
}

public async removeTagsFromBeats(
req: FrameworkRequest,
removals: CMTagAssignment[]
): Promise<CMTagAssignment[]> {
user: FrameworkUser,
removals: BeatsTagAssignment[]
): Promise<BeatsTagAssignment[]> {
const body = flatten(
removals.map(({ beatId, tag }) => {
const script =
Expand All @@ -153,15 +149,13 @@ export class ElasticsearchBeatsAdapter implements CMBeatsAdapter {
})
);

const params = {
const response = await this.database.bulk(user, {
body,
index: INDEX_NAMES.BEATS,
refresh: 'wait_for',
type: '_doc',
};

const response = await this.framework.callWithRequest(req, 'bulk', params);
return get<any>(response, 'items', []).map(
});
return _get<any>(response, 'items', []).map(
(item: any, resultIdx: number) => ({
idxInRequest: removals[resultIdx].idxInRequest,
result: item.update.result,
Expand All @@ -171,9 +165,9 @@ export class ElasticsearchBeatsAdapter implements CMBeatsAdapter {
}

public async assignTagsToBeats(
req: FrameworkRequest,
assignments: CMTagAssignment[]
): Promise<CMTagAssignment[]> {
user: FrameworkUser,
assignments: BeatsTagAssignment[]
): Promise<BeatsTagAssignment[]> {
const body = flatten(
assignments.map(({ beatId, tag }) => {
const script =
Expand All @@ -193,18 +187,18 @@ export class ElasticsearchBeatsAdapter implements CMBeatsAdapter {
})
);

const params = {
const response = await this.database.bulk(user, {
body,
index: INDEX_NAMES.BEATS,
refresh: 'wait_for',
type: '_doc',
};

const response = await this.framework.callWithRequest(req, 'bulk', params);
return get<any>(response, 'items', []).map((item: any, resultIdx: any) => ({
idxInRequest: assignments[resultIdx].idxInRequest,
result: item.update.result,
status: item.update.status,
}));
});
return _get<any>(response, 'items', []).map(
(item: any, resultIdx: any) => ({
idxInRequest: assignments[resultIdx].idxInRequest,
result: item.update.result,
status: item.update.status,
})
);
}
}
Loading