Skip to content
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

[http] Do not do client version check on serverless as we do for onprem #159101

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 5 additions & 1 deletion config/serverless.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,12 @@ server.securityResponseHeaders.strictTransportSecurity: max-age=31536000; includ
# Disable embedding for serverless MVP
server.securityResponseHeaders.disableEmbedding: true

# default to newest routes
server.versioned.versionResolution: newest
# do not enforce client version check
server.versioned.strictClientVersionCheck: false

# Enforce single "default" space
xpack.spaces.maxSpaces: 1

# Allow unauthenticated access to task manager utilization API for auto-scaling
xpack.task_manager.unsafe.authenticate_background_task_utilization: false
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

export { filterHeaders } from './src/headers';
export { Router } from './src/router';
export { Router, type RouterOptions } from './src/router';
export { isKibanaRequest, isRealRequest, ensureRawRequest, CoreKibanaRequest } from './src/request';
export { isSafeMethod } from './src/route';
export { HapiResponseAdapter } from './src/response_adapter';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,22 @@
* Side Public License, v 1.
*/

import { Router } from './router';
import { Router, type RouterOptions } from './router';
import { loggingSystemMock } from '@kbn/core-logging-server-mocks';
import { schema } from '@kbn/config-schema';

const logger = loggingSystemMock.create().get();
const enhanceWithContext = (fn: (...args: any[]) => any) => fn.bind(null, {});

const routerOptions: RouterOptions = {
isDev: false,
versionedRouteResolution: 'oldest',
};

describe('Router', () => {
describe('Options', () => {
it('throws if validation for a route is not defined explicitly', () => {
const router = new Router('', logger, enhanceWithContext);
const router = new Router('', logger, enhanceWithContext, routerOptions);
expect(
// we use 'any' because validate is a required field
() => router.get({ path: '/' } as any, (context, req, res) => res.ok({}))
Expand All @@ -25,7 +30,7 @@ describe('Router', () => {
);
});
it('throws if validation for a route is declared wrong', () => {
const router = new Router('', logger, enhanceWithContext);
const router = new Router('', logger, enhanceWithContext, routerOptions);
expect(() =>
router.get(
// we use 'any' because validate requires valid Type or function usage
Expand All @@ -41,7 +46,7 @@ describe('Router', () => {
});

it('throws if options.body.output is not a valid value', () => {
const router = new Router('', logger, enhanceWithContext);
const router = new Router('', logger, enhanceWithContext, routerOptions);
expect(() =>
router.post(
// we use 'any' because TS already checks we cannot provide this body.output
Expand All @@ -58,14 +63,14 @@ describe('Router', () => {
});

it('should default `output: "stream" and parse: false` when no body validation is required but not a GET', () => {
const router = new Router('', logger, enhanceWithContext);
const router = new Router('', logger, enhanceWithContext, routerOptions);
router.post({ path: '/', validate: {} }, (context, req, res) => res.ok({}));
const [route] = router.getRoutes();
expect(route.options).toEqual({ body: { output: 'stream', parse: false } });
});

it('should NOT default `output: "stream" and parse: false` when the user has specified body options (he cares about it)', () => {
const router = new Router('', logger, enhanceWithContext);
const router = new Router('', logger, enhanceWithContext, routerOptions);
router.post(
{ path: '/', options: { body: { maxBytes: 1 } }, validate: {} },
(context, req, res) => res.ok({})
Expand All @@ -75,7 +80,7 @@ describe('Router', () => {
});

it('should NOT default `output: "stream" and parse: false` when no body validation is required and GET', () => {
const router = new Router('', logger, enhanceWithContext);
const router = new Router('', logger, enhanceWithContext, routerOptions);
router.get({ path: '/', validate: {} }, (context, req, res) => res.ok({}));
const [route] = router.getRoutes();
expect(route.options).toEqual({});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,14 @@ function validOptions(
}

/** @internal */
interface RouterOptions {
export interface RouterOptions {
/** Whether we are running in development */
isDev?: boolean;
/** Whether we are running in a serverless */
isServerless?: boolean;
/**
* Which route resolution algo to use
* @default 'oldest'
*/
versionedRouteResolution?: 'newest' | 'oldest';
}

/**
Expand All @@ -143,7 +146,7 @@ export class Router<Context extends RequestHandlerContextBase = RequestHandlerCo
public readonly routerPath: string,
private readonly log: Logger,
private readonly enhanceWithContext: ContextEnhancer<any, any, any, any, any>,
private readonly options: RouterOptions = { isDev: false, isServerless: false }
private readonly options: RouterOptions
) {
const buildMethod =
<Method extends RouteMethod>(method: Method) =>
Expand Down Expand Up @@ -220,7 +223,7 @@ export class Router<Context extends RequestHandlerContextBase = RequestHandlerCo
this.versionedRouter = CoreVersionedRouter.from({
router: this,
isDev: this.options.isDev,
defaultHandlerResolutionStrategy: this.options.isServerless ? 'newest' : 'oldest',
defaultHandlerResolutionStrategy: this.options.versionedRouteResolution,
});
}
return this.versionedRouter;
Expand Down
8 changes: 6 additions & 2 deletions packages/core/http/core-http-server-internal/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ export type {
} from './src/types';
export { BasePath } from './src/base_path_service';

export { cspConfig, CspConfig } from './src/csp';
export { cspConfig, CspConfig, type CspConfigType } from './src/csp';

export { externalUrlConfig, ExternalUrlConfig } from './src/external_url';
export {
externalUrlConfig,
ExternalUrlConfig,
type ExternalUrlConfigType,
} from './src/external_url';

export { createCookieSessionStorageFactory } from './src/cookie_session_storage';

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions packages/core/http/core-http-server-internal/src/http_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,14 @@ const configSchema = schema.object(
}
),
restrictInternalApis: schema.boolean({ defaultValue: false }), // allow access to internal routes by default to prevent breaking changes in current offerings
versioned: schema.object({
// Which handler resolution algo to use: "newest" or "oldest"
versionResolution: schema.oneOf([schema.literal('newest'), schema.literal('oldest')], {
defaultValue: 'oldest',
}),
// Whether we enforce version checks on client requests
strictClientVersionCheck: schema.boolean({ defaultValue: true }),
}),
},
{
validate: (rawConfig) => {
Expand Down Expand Up @@ -239,6 +247,7 @@ export class HttpConfig implements IHttpConfig {
public externalUrl: IExternalUrlConfig;
public xsrf: { disableProtection: boolean; allowlist: string[] };
public requestId: { allowFromAnyIp: boolean; ipAllowlist: string[] };
public versioned: { versionResolution: 'newest' | 'oldest'; strictClientVersionCheck: boolean };
public shutdownTimeout: Duration;
public restrictInternalApis: boolean;

Expand Down Expand Up @@ -286,6 +295,7 @@ export class HttpConfig implements IHttpConfig {

this.restrictInternalApis = rawHttpConfig.restrictInternalApis;
this.eluMonitor = rawHttpConfig.eluMonitor;
this.versioned = rawHttpConfig.versioned;
}
}

Expand Down
Loading