Skip to content
Merged
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
e96973f
[Beats Management] Initial scaffolding for plugin (#18977)
ycombinator May 11, 2018
f48ba09
[Beats Management] Install Beats index template on plugin init (#19072)
ycombinator May 15, 2018
934ce9d
[Beats Management] APIs: Create enrollment tokens (#19018)
ycombinator May 15, 2018
625d2cc
Fixing name of test file (#19100)
ycombinator May 16, 2018
705bd00
[Beats Management] APIs: Enroll beat (#19056)
ycombinator May 16, 2018
725daa2
[Beats Management] APIs: List beats (#19086)
ycombinator May 16, 2018
06f2506
[Beats Management] APIs: Verify beats (#19103)
ycombinator May 17, 2018
2bb3fbf
Fixing assertions (#19194)
ycombinator May 18, 2018
f28c61d
[Beats Management] APIs: Update beat (#19148)
ycombinator May 21, 2018
d8ac2a9
[Beats Management] APIs: take auth tokens via headers (#19210)
ycombinator May 22, 2018
2c86794
[Beats Management] APIs: Create configuration block (#19270)
ycombinator May 22, 2018
aa636aa
Revert implementation of `POST /api/beats/configuration_blocks` API (…
ycombinator May 23, 2018
5886ebd
[Beats Management] APIs: Create or update tag (#19342)
ycombinator May 23, 2018
4cee944
[Beats Management] Prevent timing attacks when checking auth tokens (…
ycombinator May 25, 2018
0305f9f
[Beats Management] APIs: Assign tag(s) to beat(s) (#19431)
ycombinator May 31, 2018
f4ab093
[Beats Management] APIs: Remove tag(s) from beat(s) (#19440)
ycombinator May 31, 2018
fb3baea
Ported over base types and arch structure
mattapperson Jun 19, 2018
e1e6fdd
move management of installIndexTemplate into the framework adapter
mattapperson Jun 19, 2018
e91867d
Merge branch 'master' of github.com:elastic/kibana into beats-management
mattapperson Jun 19, 2018
b6480bd
ts-lint fix
mattapperson Jun 19, 2018
1edda86
tslint fixes
mattapperson Jun 19, 2018
56ec992
more ts tweaks
mattapperson Jun 19, 2018
f4c28ea
fix paths
mattapperson Jun 19, 2018
cb34d4c
Merge branch 'master' of github.com:elastic/kibana into beats-management
mattapperson Jun 20, 2018
70dc670
added several working endpoints
mattapperson Jun 21, 2018
0202118
add more routes and bug fixes
mattapperson Jun 22, 2018
7eacf7a
fix linting
mattapperson Jun 22, 2018
f925c06
Merge branch 'feature/x-pack/management/beats' into beats-management
mattapperson Jun 22, 2018
d91e414
fix type remove CRUFT
mattapperson Jun 25, 2018
8738ad0
remove more cruft
mattapperson Jun 25, 2018
730353c
remove more CRUFT
mattapperson Jun 25, 2018
3f6df69
added comments, change plurality
mattapperson Jun 25, 2018
8d70b50
add tsconfig file
mattapperson Jun 25, 2018
0b2d0a0
add extends path
mattapperson Jun 25, 2018
2ab2dff
fixed typo
mattapperson Jun 25, 2018
21838ed
serveral PR review fixes
mattapperson Jun 26, 2018
980e678
fixed lodash type version
mattapperson Jun 26, 2018
37adfdc
“fix” types by applying a lot of any
mattapperson Jun 26, 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: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@
"tree-kill": "^1.1.0",
"ts-jest": "^22.4.6",
"ts-loader": "^3.5.0",
"ts-node": "^6.0.3",
"ts-node": "^6.1.1",
"tslint": "^5.10.0",
"tslint-config-prettier": "^1.12.0",
"tslint-plugin-prettier": "^1.3.0",
Expand Down
5 changes: 2 additions & 3 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"compilerOptions": {
"baseUrl": ".",
"sourceMap": true,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ts-loader webpack config already sets this depending on the sourceMaps kibana config:

sourceMap: Boolean(this.sourceMaps),

Setting it here might lead to undesired artifacts in the build output. Maybe we want to ask the kibana platform team for their perspective?

"paths": {
"ui/*": ["src/ui/public/*"]
},
Expand Down Expand Up @@ -41,7 +42,5 @@
// Disallow inconsistently-cased references to the same file.
"forceConsistentCasingInFileNames": true
},
"include": [
"src/**/*"
]
"include": ["src/**/*"]
}
5 changes: 5 additions & 0 deletions x-pack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@
"@kbn/es": "link:../packages/kbn-es",
"@kbn/plugin-helpers": "link:../packages/kbn-plugin-helpers",
"@kbn/test": "link:../packages/kbn-test",
"@types/boom": "^4.3.8",
"@types/hapi": "15.0.1",
"@types/jest": "^22.2.3",
"@types/joi": "^10.4.4",
"@types/lodash": "^4.14.107",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The lodash version included in x-pack is 3.10.1. These typings are probably incorrect for that version.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm facing the same problem for the infra ui. To solve this I'm currently talking with the platform team about using the yarn package alias syntax to allow both versions to co-exist.

"@types/pngjs": "^3.3.1",
"abab": "^1.0.4",
"ansicolors": "0.3.2",
Expand Down Expand Up @@ -85,6 +89,7 @@
"@kbn/ui-framework": "link:../packages/kbn-ui-framework",
"@samverschueren/stream-to-observable": "^0.3.0",
"@slack/client": "^4.2.2",
"@types/uuid": "^3.4.3",
"angular-paging": "2.2.1",
"angular-resource": "1.4.9",
"angular-sanitize": "1.4.9",
Expand Down
19 changes: 0 additions & 19 deletions x-pack/plugins/beats/common/constants/configuration_blocks.js

This file was deleted.

15 changes: 15 additions & 0 deletions x-pack/plugins/beats/common/constants/configuration_blocks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* 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 enum ConfigurationBlockTypes {
FilebeatInputs = 'filebeat.inputs',
FilebeatModules = 'filebeat.modules',
MetricbeatModules = 'metricbeat.modules',
Output = 'output',
Processors = 'processors',
}

export const UNIQUENESS_ENFORCING_TYPES = [ConfigurationBlockTypes.Output];
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@

export { PLUGIN } from './plugin';
export { INDEX_NAMES } from './index_names';
export { CONFIGURATION_BLOCKS } from './configuration_blocks';
export {
UNIQUENESS_ENFORCING_TYPES,
ConfigurationBlockTypes,
} from './configuration_blocks';
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
*/

export const INDEX_NAMES = {
BEATS: '.management-beats'
BEATS: '.management-beats',
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
*/

export const PLUGIN = {
ID: 'beats'
ID: 'beats',
};
26 changes: 14 additions & 12 deletions x-pack/plugins/beats/index.js → x-pack/plugins/beats/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,26 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { installIndexTemplate } from './server/lib/index_template';
import { registerApiRoutes } from './server/routes/api';
import { PLUGIN } from './common/constants';
import { initServerWithKibana } from './server/kibana.index';

const DEFAULT_ENROLLMENT_TOKENS_TTL_S = 10 * 60; // 10 minutes

export function beats(kibana) {
export function beats(kibana) {
return new kibana.Plugin({
config: Joi =>
Joi.object({
enabled: Joi.boolean().default(true),
enrollmentTokensTtlInSeconds: Joi.number()
.integer()
.min(1)
.default(DEFAULT_ENROLLMENT_TOKENS_TTL_S),
}).default(),
configPrefix: 'xpack.beats',
id: PLUGIN.ID,
require: ['kibana', 'elasticsearch', 'xpack_main'],
configPrefix: 'xpack.beats',
config: Joi => Joi.object({
enabled: Joi.boolean().default(true),
enrollmentTokensTtlInSeconds: Joi.number().integer().min(1).default(DEFAULT_ENROLLMENT_TOKENS_TTL_S)
}).default(),
init: async function (server) {
await installIndexTemplate(server);
registerApiRoutes(server);
}
async init(server) {
initServerWithKibana(server);
},
});
}
14 changes: 14 additions & 0 deletions x-pack/plugins/beats/server/kibana.index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* 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 { Server } from 'hapi';
import { compose } from './lib/compose/kibana';
import { initManagementServer } from './management_server';

export const initServerWithKibana = (hapiServer: Server) => {
const libs = compose(hapiServer);
initManagementServer(libs);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
/*
* 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 { flatten, get, omit } from 'lodash';
import moment from 'moment';
import { INDEX_NAMES } from '../../../../common/constants';
import {
BackendFrameworkAdapter,
CMBeat,
CMBeatsAdapter,
CMTagAssignment,
FrameworkRequest,
} from '../../lib';

export class ElasticsearchBeatsAdapter implements CMBeatsAdapter {
private framework: BackendFrameworkAdapter;

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

public async get(id: string) {
const params = {
id: `beat:${id}`,
ignore: [404],
index: INDEX_NAMES.BEATS,
type: '_doc',
};

const response = await this.framework.callWithInternalUser('get', params);
if (!response.found) {
return null;
}

return get(response, '_source.beat');
}

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

const params = {
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) {
const body = {
beat,
type: 'beat',
};

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

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

const params = {
_source: false,
body: {
ids,
},
index: INDEX_NAMES.BEATS,
type: '_doc',
};
const response = await this.framework.callWithRequest(req, 'mget', params);
return get(response, 'docs', []);
}

// TODO merge with getBeatsWithIds
public async getVerifiedWithIds(req: FrameworkRequest, beatIds: string[]) {
const ids = beatIds.map(beatId => `beat:${beatId}`);

const params = {
_sourceInclude: ['beat.id', 'beat.verified_on'],
body: {
ids,
},
index: INDEX_NAMES.BEATS,
type: '_doc',
};
const response = await this.framework.callWithRequest(req, 'mget', params);
return get(response, 'docs', []);
}

public async verifyBeats(req: FrameworkRequest, beatIds: string[]) {
if (!Array.isArray(beatIds) || beatIds.length === 0) {
return [];
}

const verifiedOn = moment().toJSON();
const body = flatten(
beatIds.map(beatId => [
{ update: { _id: `beat:${beatId}` } },
{ doc: { beat: { verified_on: verifiedOn } } },
])
);

const params = {
body,
index: INDEX_NAMES.BEATS,
refresh: 'wait_for',
type: '_doc',
};

const response = await this.framework.callWithRequest(req, 'bulk', params);
return get(response, 'items', []);
}

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

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

public async removeTagsFromBeats(
req: FrameworkRequest,
removals: CMTagAssignment[]
): Promise<CMTagAssignment[]> {
const body = flatten(
removals.map(({ beatId, 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 } } },
];
})
);

const params = {
body,
index: INDEX_NAMES.BEATS,
refresh: 'wait_for',
type: '_doc',
};

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

// formerly persistAssignments
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay to remove this comment now?

public async assignTagsToBeats(
req: FrameworkRequest,
assignments: CMTagAssignment[]
): Promise<CMTagAssignment[]> {
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); ' +
'}';

return [
{ update: { _id: `beat:${beatId}` } },
{ script: { source: script, params: { tag } } },
];
})
);

const params = {
body,
index: INDEX_NAMES.BEATS,
refresh: 'wait_for',
type: '_doc',
};

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