Skip to content

Commit 6b42af7

Browse files
author
John Schulz
committed
Use updated onPreAuth from Platform
1 parent b3c6ce9 commit 6b42af7

File tree

6 files changed

+75
-4
lines changed

6 files changed

+75
-4
lines changed

x-pack/plugins/ingest_manager/common/constants/routes.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ export const PACKAGE_CONFIG_API_ROOT = `${API_ROOT}/package_configs`;
1111
export const AGENT_CONFIG_API_ROOT = `${API_ROOT}/agent_configs`;
1212
export const FLEET_API_ROOT = `${API_ROOT}/fleet`;
1313

14+
export const LIMITED_CONCURRENCY_ROUTE_TAG = 'ingest:limited-concurrency';
15+
1416
// EPM API routes
1517
const EPM_PACKAGES_MANY = `${EPM_API_ROOT}/packages`;
1618
const EPM_PACKAGES_ONE = `${EPM_PACKAGES_MANY}/{pkgkey}`;

x-pack/plugins/ingest_manager/server/constants/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export {
1515
AGENT_UPDATE_ACTIONS_INTERVAL_MS,
1616
INDEX_PATTERN_PLACEHOLDER_SUFFIX,
1717
// Routes
18+
LIMITED_CONCURRENCY_ROUTE_TAG,
1819
PLUGIN_ID,
1920
EPM_API_ROUTES,
2021
DATA_STREAM_API_ROUTES,

x-pack/plugins/ingest_manager/server/plugin.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import {
3434
} from './constants';
3535
import { registerSavedObjects, registerEncryptedSavedObjects } from './saved_objects';
3636
import {
37+
preAuthHandler,
3738
registerEPMRoutes,
3839
registerPackageConfigRoutes,
3940
registerDataStreamRoutes,
@@ -231,6 +232,9 @@ export class IngestManagerPlugin
231232
);
232233
}
233234
} else {
235+
// we currently only use this global interceptor if fleet is enabled
236+
// since it would run this func on *every* req (other plugins, CSS, etc)
237+
this.httpSetup.registerOnPreAuth(preAuthHandler);
234238
registerAgentRoutes(router);
235239
registerEnrollmentApiKeyRoutes(router);
236240
registerInstallScriptRoutes({

x-pack/plugins/ingest_manager/server/routes/agent/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*/
1111

1212
import { IRouter } from 'src/core/server';
13-
import { PLUGIN_ID, AGENT_API_ROUTES } from '../../constants';
13+
import { PLUGIN_ID, AGENT_API_ROUTES, LIMITED_CONCURRENCY_ROUTE_TAG } from '../../constants';
1414
import {
1515
GetAgentsRequestSchema,
1616
GetOneAgentRequestSchema,
@@ -85,7 +85,7 @@ export const registerRoutes = (router: IRouter) => {
8585
{
8686
path: AGENT_API_ROUTES.CHECKIN_PATTERN,
8787
validate: PostAgentCheckinRequestSchema,
88-
options: { tags: [] },
88+
options: { tags: [LIMITED_CONCURRENCY_ROUTE_TAG] },
8989
},
9090
postAgentCheckinHandler
9191
);
@@ -95,7 +95,7 @@ export const registerRoutes = (router: IRouter) => {
9595
{
9696
path: AGENT_API_ROUTES.ENROLL_PATTERN,
9797
validate: PostAgentEnrollRequestSchema,
98-
options: { tags: [] },
98+
options: { tags: [LIMITED_CONCURRENCY_ROUTE_TAG] },
9999
},
100100
postAgentEnrollHandler
101101
);
@@ -105,7 +105,7 @@ export const registerRoutes = (router: IRouter) => {
105105
{
106106
path: AGENT_API_ROUTES.ACKS_PATTERN,
107107
validate: PostAgentAcksRequestSchema,
108-
options: { tags: [] },
108+
options: { tags: [LIMITED_CONCURRENCY_ROUTE_TAG] },
109109
},
110110
postAgentAcksHandlerBuilder({
111111
acknowledgeAgentActions: AgentService.acknowledgeAgentActions,
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
import { KibanaRequest, LifecycleResponseFactory, OnPreAuthToolkit } from 'kibana/server';
8+
import { LIMITED_CONCURRENCY_ROUTE_TAG } from '../../common';
9+
10+
class MaxCounter {
11+
constructor(private readonly max: number = 1) {}
12+
private counter = 0;
13+
valueOf() {
14+
return this.counter;
15+
}
16+
increase() {
17+
if (this.counter < this.max) {
18+
this.counter += 1;
19+
}
20+
}
21+
decrease() {
22+
this.counter += 1;
23+
}
24+
lessThanMax() {
25+
return this.counter < this.max;
26+
}
27+
}
28+
29+
function shouldHandleRequest(request: KibanaRequest) {
30+
const tags = request.route.options.tags;
31+
return tags.includes(LIMITED_CONCURRENCY_ROUTE_TAG);
32+
}
33+
34+
const LIMITED_CONCURRENCY_MAX_REQUESTS = 250;
35+
const counter = new MaxCounter(LIMITED_CONCURRENCY_MAX_REQUESTS);
36+
37+
export function preAuthHandler(
38+
request: KibanaRequest,
39+
response: LifecycleResponseFactory,
40+
toolkit: OnPreAuthToolkit
41+
) {
42+
if (!shouldHandleRequest(request)) {
43+
return toolkit.next();
44+
}
45+
46+
if (!counter.lessThanMax()) {
47+
return response.customError({
48+
body: 'Too Many Agents',
49+
statusCode: 503,
50+
headers: {
51+
'Retry-After': '30',
52+
},
53+
});
54+
}
55+
56+
counter.increase();
57+
58+
// requests.events.aborted$ has a bug where it's fired even when the request completes...
59+
// we can take advantage of this bug just for load testing...
60+
request.events.aborted$.toPromise().then(() => counter.decrease());
61+
62+
return toolkit.next();
63+
}

x-pack/plugins/ingest_manager/server/routes/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ export { registerRoutes as registerInstallScriptRoutes } from './install_script'
1414
export { registerRoutes as registerOutputRoutes } from './output';
1515
export { registerRoutes as registerSettingsRoutes } from './settings';
1616
export { registerRoutes as registerAppRoutes } from './app';
17+
export { preAuthHandler } from './global_interceptors';

0 commit comments

Comments
 (0)