-
Notifications
You must be signed in to change notification settings - Fork 8.6k
Beats/real adapters #21481
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Beats/real adapters #21481
Changes from all commits
70d52d8
73e549a
1ead4c0
39b65d7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| /* | ||
| * 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 { RestAPIAdapter } from '../rest_api/adapter_types'; | ||
| import { | ||
| BeatsRemovalReturn, | ||
| BeatsTagAssignment, | ||
| CMAssignmentReturn, | ||
| CMBeatsAdapter, | ||
| } from './adapter_types'; | ||
| export class RestBeatsAdapter implements CMBeatsAdapter { | ||
| constructor(private readonly REST: RestAPIAdapter) {} | ||
|
|
||
| public async get(id: string): Promise<CMBeat | null> { | ||
| return await this.REST.get<CMBeat>(`/api/beats/agent/${id}`); | ||
| } | ||
|
|
||
| public async getAll(): Promise<CMBeat[]> { | ||
| return await this.REST.get<CMBeat[]>('/api/beats/agents'); | ||
| } | ||
|
|
||
| public async removeTagsFromBeats(removals: BeatsTagAssignment[]): Promise<BeatsRemovalReturn[]> { | ||
| return await this.REST.post<BeatsRemovalReturn[]>(`/api/beats/agents_tags/removals`, { | ||
| removals, | ||
| }); | ||
| } | ||
|
|
||
| public async assignTagsToBeats(assignments: BeatsTagAssignment[]): Promise<CMAssignmentReturn[]> { | ||
| return await this.REST.post<CMAssignmentReturn[]>(`/api/beats/agents_tags/assignments`, { | ||
| assignments, | ||
| }); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| /* | ||
| * 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 interface RestAPIAdapter { | ||
| get<ResponseData>(url: string): Promise<ResponseData>; | ||
| post<ResponseData>(url: string, body?: { [key: string]: any }): Promise<ResponseData>; | ||
| delete<T>(url: string): Promise<T>; | ||
| put<ResponseData>(url: string, body?: any): Promise<ResponseData>; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| /* | ||
| * 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 axios, { AxiosInstance } from 'axios'; | ||
| 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 | ||
| ) {} | ||
|
|
||
| public async get<ResponseData>(url: string): Promise<ResponseData> { | ||
| return await this.REST.get(url).then(resp => resp.data); | ||
| } | ||
|
|
||
| public async post<ResponseData>( | ||
| url: string, | ||
| body?: { [key: string]: any } | ||
| ): Promise<ResponseData> { | ||
| return await this.REST.post(url, body).then(resp => resp.data); | ||
| } | ||
|
|
||
| public async delete<T>(url: string): Promise<T> { | ||
| return await this.REST.delete(url).then(resp => resp.data); | ||
| } | ||
|
|
||
| public async put<ResponseData>(url: string, body?: any): Promise<ResponseData> { | ||
| return await this.REST.put(url, body).then(resp => resp.data); | ||
| } | ||
|
|
||
| private get REST() { | ||
| if (globalAPI) { | ||
| return globalAPI; | ||
| } | ||
|
|
||
| globalAPI = axios.create({ | ||
| baseURL: this.basePath, | ||
| withCredentials: true, | ||
| responseType: 'json', | ||
| timeout: 30000, | ||
| headers: { | ||
| Accept: 'application/json', | ||
| credentials: 'same-origin', | ||
| 'Content-Type': 'application/json', | ||
| 'kbn-version': this.kbnVersion, | ||
| 'kbn-xsrf': this.xsrfToken, | ||
| }, | ||
| }); | ||
| // Add a request interceptor | ||
| globalAPI.interceptors.request.use( | ||
| config => { | ||
| // Do something before request is sent | ||
| return config; | ||
| }, | ||
| error => { | ||
| // Do something with request error | ||
| return Promise.reject(error); | ||
| } | ||
| ); | ||
|
|
||
| // Add a response interceptor | ||
| globalAPI.interceptors.response.use( | ||
| response => { | ||
| // Do something with response data | ||
| return response; | ||
| }, | ||
| error => { | ||
| // Do something with response error | ||
| return Promise.reject(error); | ||
| } | ||
| ); | ||
|
|
||
| return globalAPI; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,5 +8,5 @@ import { BeatTag } from '../../../../common/domain_types'; | |
| export interface CMTagsAdapter { | ||
| getTagsWithIds(tagIds: string[]): Promise<BeatTag[]>; | ||
| getAll(): Promise<BeatTag[]>; | ||
| upsertTag(tag: BeatTag): Promise<{}>; | ||
| upsertTag(tag: BeatTag): Promise<BeatTag | null>; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| /* | ||
| * 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 { BeatTag } from '../../../../common/domain_types'; | ||
| import { RestAPIAdapter } from '../rest_api/adapter_types'; | ||
| import { CMTagsAdapter } from './adapter_types'; | ||
|
|
||
| export class RestTagsAdapter implements CMTagsAdapter { | ||
| constructor(private readonly REST: RestAPIAdapter) {} | ||
|
|
||
| public async getTagsWithIds(tagIds: string[]): Promise<BeatTag[]> { | ||
| return await this.REST.get<BeatTag[]>(`/api/beats/tags/${tagIds.join(',')}`); | ||
| } | ||
|
|
||
| public async getAll(): Promise<BeatTag[]> { | ||
| return await this.REST.get<BeatTag[]>(`/api/beats/tags`); | ||
| } | ||
|
|
||
| public async upsertTag(tag: BeatTag): Promise<BeatTag | null> { | ||
| return await this.REST.put<BeatTag>(`/api/beats/tag/{tag}`, { | ||
| configuration_blocks: tag.configuration_blocks, | ||
| }); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| /* | ||
| * 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 { RestAPIAdapter } from '../rest_api/adapter_types'; | ||
| import { CMTokensAdapter, TokenEnrollmentData } from './adapter_types'; | ||
|
|
||
| export class RestTokensAdapter implements CMTokensAdapter { | ||
| constructor(private readonly REST: RestAPIAdapter) {} | ||
|
|
||
| public async createEnrollmentToken(): Promise<TokenEnrollmentData> { | ||
| const tokens = await this.REST.post<TokenEnrollmentData[]>('/api/beats/enrollment_tokens'); | ||
| return tokens[0]; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just out of curiosity - why do we only return the first element here? What could be in the rest of the list?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the endpoint supports multiple tokens being created (for use with things like puppet and such), the UI only needs one. One is also the default amount |
||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this where we'll put an endpoint that returns a
CMPopulatedBeat[]once we have the updated types merged as well? Containing the full tag data, etc.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes