Skip to content

Commit

Permalink
[7.x] [console] Deprecate "proxyFilter" and "proxyConfig" on 8.x (#11…
Browse files Browse the repository at this point in the history
…3555) (#113781)

* [console] Deprecate "proxyFilter" and "proxyConfig" on 8.x (#113555)

* Change MAJOR_VERSION to 7.16.0
  • Loading branch information
sebelga authored Oct 4, 2021
1 parent b47f88a commit cef53a9
Show file tree
Hide file tree
Showing 10 changed files with 214 additions and 112 deletions.
9 changes: 9 additions & 0 deletions src/plugins/console/common/constants/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

export { MAJOR_VERSION } from './plugin';
9 changes: 9 additions & 0 deletions src/plugins/console/common/constants/plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

export const MAJOR_VERSION = '7.16.0';
4 changes: 3 additions & 1 deletion src/plugins/console/kibana.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
{
"id": "console",
"version": "kibana",
"version": "8.0.0",
"kibanaVersion": "kibana",
"server": true,
"ui": true,
"owner": {
"name": "Stack Management",
"githubTeam": "kibana-stack-management"
},
"configPath": ["console"],
"requiredPlugins": ["devTools", "share"],
"optionalPlugins": ["usageCollection", "home"],
"requiredBundles": ["esUiShared", "kibanaReact", "kibanaUtils", "home"]
Expand Down
87 changes: 60 additions & 27 deletions src/plugins/console/server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,70 @@
* Side Public License, v 1.
*/

import { SemVer } from 'semver';
import { schema, TypeOf } from '@kbn/config-schema';
import { PluginConfigDescriptor } from 'kibana/server';

export type ConfigType = TypeOf<typeof config>;
import { MAJOR_VERSION } from '../common/constants';

export const config = schema.object(
{
enabled: schema.boolean({ defaultValue: true }),
proxyFilter: schema.arrayOf(schema.string(), { defaultValue: ['.*'] }),
ssl: schema.object({ verify: schema.boolean({ defaultValue: false }) }, {}),
proxyConfig: schema.arrayOf(
schema.object({
match: schema.object({
protocol: schema.string({ defaultValue: '*' }),
host: schema.string({ defaultValue: '*' }),
port: schema.string({ defaultValue: '*' }),
path: schema.string({ defaultValue: '*' }),
}),

timeout: schema.number(),
ssl: schema.object(
{
verify: schema.boolean(),
ca: schema.arrayOf(schema.string()),
cert: schema.string(),
key: schema.string(),
},
{ defaultValue: undefined }
),
const kibanaVersion = new SemVer(MAJOR_VERSION);

const baseSettings = {
enabled: schema.boolean({ defaultValue: true }),
ssl: schema.object({ verify: schema.boolean({ defaultValue: false }) }, {}),
};

// Settings only available in 7.x
const deprecatedSettings = {
proxyFilter: schema.arrayOf(schema.string(), { defaultValue: ['.*'] }),
proxyConfig: schema.arrayOf(
schema.object({
match: schema.object({
protocol: schema.string({ defaultValue: '*' }),
host: schema.string({ defaultValue: '*' }),
port: schema.string({ defaultValue: '*' }),
path: schema.string({ defaultValue: '*' }),
}),
{ defaultValue: [] }
),

timeout: schema.number(),
ssl: schema.object(
{
verify: schema.boolean(),
ca: schema.arrayOf(schema.string()),
cert: schema.string(),
key: schema.string(),
},
{ defaultValue: undefined }
),
}),
{ defaultValue: [] }
),
};

const configSchema = schema.object(
{
...baseSettings,
},
{ defaultValue: undefined }
);

const configSchema7x = schema.object(
{
...baseSettings,
...deprecatedSettings,
},
{ defaultValue: undefined }
);

export type ConfigType = TypeOf<typeof configSchema>;
export type ConfigType7x = TypeOf<typeof configSchema7x>;

export const config: PluginConfigDescriptor<ConfigType | ConfigType7x> = {
schema: kibanaVersion.major < 8 ? configSchema7x : configSchema,
deprecations: ({ deprecate, unused }) => [
deprecate('enabled', '8.0.0'),
deprecate('proxyFilter', '8.0.0'),
deprecate('proxyConfig', '8.0.0'),
unused('ssl'),
],
};
9 changes: 2 additions & 7 deletions src/plugins/console/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,11 @@
* Side Public License, v 1.
*/

import { PluginConfigDescriptor, PluginInitializerContext } from 'kibana/server';
import { PluginInitializerContext } from 'kibana/server';

import { ConfigType, config as configSchema } from './config';
import { ConsoleServerPlugin } from './plugin';

export { ConsoleSetup, ConsoleStart } from './types';
export { config } from './config';

export const plugin = (ctx: PluginInitializerContext) => new ConsoleServerPlugin(ctx);

export const config: PluginConfigDescriptor<ConfigType> = {
deprecations: ({ deprecate, unused, rename }) => [deprecate('enabled', '8.0.0'), unused('ssl')],
schema: configSchema,
};
22 changes: 16 additions & 6 deletions src/plugins/console/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@
*/

import { CoreSetup, Logger, Plugin, PluginInitializerContext } from 'kibana/server';
import { SemVer } from 'semver';

import { ProxyConfigCollection } from './lib';
import { SpecDefinitionsService, EsLegacyConfigService } from './services';
import { ConfigType } from './config';
import { ConfigType, ConfigType7x } from './config';

import { registerRoutes } from './routes';

Expand All @@ -23,7 +24,7 @@ export class ConsoleServerPlugin implements Plugin<ConsoleSetup, ConsoleStart> {

esLegacyConfigService = new EsLegacyConfigService();

constructor(private readonly ctx: PluginInitializerContext<ConfigType>) {
constructor(private readonly ctx: PluginInitializerContext<ConfigType | ConfigType7x>) {
this.log = this.ctx.logger.get();
}

Expand All @@ -34,10 +35,17 @@ export class ConsoleServerPlugin implements Plugin<ConsoleSetup, ConsoleStart> {
save: true,
},
}));

const kibanaVersion = new SemVer(this.ctx.env.packageInfo.version);
const config = this.ctx.config.get();
const globalConfig = this.ctx.config.legacy.get();
const proxyPathFilters = config.proxyFilter.map((str: string) => new RegExp(str));

let pathFilters: RegExp[] | undefined;
let proxyConfigCollection: ProxyConfigCollection | undefined;
if (kibanaVersion.major < 8) {
// "pathFilters" and "proxyConfig" are only used in 7.x
pathFilters = (config as ConfigType7x).proxyFilter.map((str: string) => new RegExp(str));
proxyConfigCollection = new ProxyConfigCollection((config as ConfigType7x).proxyConfig);
}

this.esLegacyConfigService.setup(elasticsearch.legacy.config$);

Expand All @@ -51,16 +59,18 @@ export class ConsoleServerPlugin implements Plugin<ConsoleSetup, ConsoleStart> {
specDefinitionService: this.specDefinitionsService,
},
proxy: {
proxyConfigCollection: new ProxyConfigCollection(config.proxyConfig),
readLegacyESConfig: async (): Promise<ESConfigForProxy> => {
const legacyConfig = await this.esLegacyConfigService.readConfig();
return {
...globalConfig.elasticsearch,
...legacyConfig,
};
},
pathFilters: proxyPathFilters,
// Deprecated settings (only used in 7.x):
proxyConfigCollection,
pathFilters,
},
kibanaVersion,
});

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import { Agent, IncomingMessage } from 'http';
import * as url from 'url';
import { pick, trimStart, trimEnd } from 'lodash';
import { SemVer } from 'semver';

import { KibanaRequest, RequestHandler } from 'kibana/server';

Expand Down Expand Up @@ -58,17 +59,22 @@ function filterHeaders(originalHeaders: object, headersToKeep: string[]): object
function getRequestConfig(
headers: object,
esConfig: ESConfigForProxy,
proxyConfigCollection: ProxyConfigCollection,
uri: string
uri: string,
kibanaVersion: SemVer,
proxyConfigCollection?: ProxyConfigCollection
): { agent: Agent; timeout: number; headers: object; rejectUnauthorized?: boolean } {
const filteredHeaders = filterHeaders(headers, esConfig.requestHeadersWhitelist);
const newHeaders = setHeaders(filteredHeaders, esConfig.customHeaders);

if (proxyConfigCollection.hasConfig()) {
return {
...proxyConfigCollection.configForUri(uri),
headers: newHeaders,
};
if (kibanaVersion.major < 8) {
// In 7.x we still support the proxyConfig setting defined in kibana.yml
// From 8.x we don't support it anymore so we don't try to read it here.
if (proxyConfigCollection!.hasConfig()) {
return {
...proxyConfigCollection!.configForUri(uri),
headers: newHeaders,
};
}
}

return {
Expand Down Expand Up @@ -106,18 +112,23 @@ export const createHandler =
({
log,
proxy: { readLegacyESConfig, pathFilters, proxyConfigCollection },
kibanaVersion,
}: RouteDependencies): RequestHandler<unknown, Query, Body> =>
async (ctx, request, response) => {
const { body, query } = request;
const { path, method } = query;

if (!pathFilters.some((re) => re.test(path))) {
return response.forbidden({
body: `Error connecting to '${path}':\n\nUnable to send requests to that path.`,
headers: {
'Content-Type': 'text/plain',
},
});
if (kibanaVersion.major < 8) {
// The "console.proxyFilter" setting in kibana.yaml has been deprecated in 8.x
// We only read it on the 7.x branch
if (!pathFilters!.some((re) => re.test(path))) {
return response.forbidden({
body: `Error connecting to '${path}':\n\nUnable to send requests to that path.`,
headers: {
'Content-Type': 'text/plain',
},
});
}
}

const legacyConfig = await readLegacyESConfig();
Expand All @@ -134,8 +145,9 @@ export const createHandler =
const { timeout, agent, headers, rejectUnauthorized } = getRequestConfig(
request.headers,
legacyConfig,
proxyConfigCollection,
uri.toString()
uri.toString(),
kibanaVersion,
proxyConfigCollection
);

const requestHeaders = {
Expand Down
32 changes: 23 additions & 9 deletions src/plugins/console/server/routes/api/console/proxy/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,41 @@
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { SemVer } from 'semver';

jest.mock('../../../../lib/proxy_request', () => ({
proxyRequest: jest.fn(),
}));

import { duration } from 'moment';
import { MAJOR_VERSION } from '../../../../../common/constants';
import { ProxyConfigCollection } from '../../../../lib';
import { RouteDependencies, ProxyDependencies } from '../../../../routes';
import { EsLegacyConfigService, SpecDefinitionsService } from '../../../../services';
import { coreMock, httpServiceMock } from '../../../../../../../core/server/mocks';

const defaultProxyValue = Object.freeze({
readLegacyESConfig: async () => ({
requestTimeout: duration(30000),
customHeaders: {},
requestHeadersWhitelist: [],
hosts: ['http://localhost:9200'],
}),
pathFilters: [/.*/],
proxyConfigCollection: new ProxyConfigCollection([]),
const kibanaVersion = new SemVer(MAJOR_VERSION);

const readLegacyESConfig = async () => ({
requestTimeout: duration(30000),
customHeaders: {},
requestHeadersWhitelist: [],
hosts: ['http://localhost:9200'],
});

let defaultProxyValue = Object.freeze({
readLegacyESConfig,
});

if (kibanaVersion.major < 8) {
// In 7.x we still support the "pathFilter" and "proxyConfig" kibana.yml settings
defaultProxyValue = Object.freeze({
readLegacyESConfig,
pathFilters: [/.*/],
proxyConfigCollection: new ProxyConfigCollection([]),
});
}

interface MockDepsArgument extends Partial<Omit<RouteDependencies, 'proxy'>> {
proxy?: Partial<ProxyDependencies>;
}
Expand All @@ -51,5 +64,6 @@ export const getProxyRouteHandlerDeps = ({
}
: defaultProxyValue,
log,
kibanaVersion,
};
};
Loading

0 comments on commit cef53a9

Please sign in to comment.