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

Introduce Elasticsearch service. #28344

Merged
merged 46 commits into from
Feb 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
aded160
Introduce Elasticsearch service.
azasypkin Jan 9, 2019
f2d353c
Move config parsing and logging to the core.
azasypkin Jan 11, 2019
7cfbd46
Migrate more code to new `createClister`.
azasypkin Jan 16, 2019
80c55b6
Remove redundant `esRequestTimeout` and `esApiVersion` injected UI va…
azasypkin Jan 17, 2019
5e36d57
Introduce ScopedClusterClient.
azasypkin Jan 22, 2019
bf37868
Add docs for the cluster clients.
azasypkin Jan 23, 2019
536f7d4
Switch back to observables.
azasypkin Jan 23, 2019
a001ca5
Fix reporting.
azasypkin Jan 24, 2019
b1ff21f
Merge branch 'master' into issue-18841-core-es-server
azasypkin Jan 25, 2019
1efb49b
Merge branch 'master' into issue-18841-core-es-server
azasypkin Jan 25, 2019
35af3fb
Merge branch 'master' into issue-18841-core-es-server
azasypkin Jan 29, 2019
00c27a5
Merge branch 'master' into issue-18841-core-es-server
azasypkin Feb 1, 2019
ed7824c
Rollback config deprecation handling code from core.
azasypkin Feb 1, 2019
c86648a
Get rid of `loggerContext` on ES config. Switch monitoring logging ta…
azasypkin Feb 1, 2019
0dfb081
Use `elasticsearch` instead of `es`.
azasypkin Feb 1, 2019
38ee25d
Make elasticsearch available to plugins.
azasypkin Feb 1, 2019
6fb8436
Fix @kbn/config-schema tests.
azasypkin Feb 1, 2019
884a301
Add `elasticsearch_client_config` parser tests.
azasypkin Feb 1, 2019
9c22b2c
Merge branch 'master' into issue-18841-core-es-server
azasypkin Feb 4, 2019
808bef2
Merge branch 'master' into issue-18841-core-es-server
azasypkin Feb 5, 2019
a03fe15
Add JSDocs and tests for `ElasticsearchConfig`.
azasypkin Feb 5, 2019
8d93aca
Merge branch 'master' into issue-18841-core-es-server
azasypkin Feb 7, 2019
433c1b3
Add `ClusterClient` tests.
azasypkin Feb 7, 2019
fe18972
Patch new metrics code that depends on `elasticsearch` config.
azasypkin Feb 7, 2019
dff904c
Rename `bwc` from ES service start contract to `legacy`.
azasypkin Feb 7, 2019
3d2259c
Add `ScopedClusterClient` tests.
azasypkin Feb 8, 2019
3b3e6ed
Fix `LegacyService` tests.
azasypkin Feb 8, 2019
6903641
Add `ElasticsearchService` tests.
azasypkin Feb 8, 2019
9809342
Fix plugin tests.
azasypkin Feb 8, 2019
3ec803d
Fix remaining core tests.
azasypkin Feb 8, 2019
329d777
Cleanup.
azasypkin Feb 8, 2019
b27e89a
Fix legacy tests.
azasypkin Feb 8, 2019
2dca5f5
Merge branch 'master' into issue-18841-core-es-server
azasypkin Feb 8, 2019
bb1b0b2
Fix x-pack legacy tests.
azasypkin Feb 9, 2019
66694bd
Clone ES config.
azasypkin Feb 9, 2019
8d0538f
Merge branch 'master' into issue-18841-core-es-server
azasypkin Feb 19, 2019
eb5d27c
Handle latest conflicting changes from upstream.
azasypkin Feb 19, 2019
d3307ff
Review №2: tweak tests, clone client config if SSL part is not provid…
azasypkin Feb 20, 2019
fcc01be
Merge branch 'master' into issue-18841-core-es-server
azasypkin Feb 25, 2019
678c383
Merge branch 'master' into issue-18841-core-es-server
azasypkin Feb 25, 2019
1980439
Review №3: use `hasOwnProperty` in `utils.pick` + fixed other nits.
azasypkin Feb 25, 2019
e8b5bbe
Merge branch 'master' into issue-18841-core-es-server
azasypkin Feb 26, 2019
ae0e742
Merge branch 'master' into issue-18841-core-es-server
azasypkin Feb 26, 2019
0af2ede
Merge branch 'master' into issue-18841-core-es-server
azasypkin Feb 27, 2019
b09ef5f
Merge branch 'master' into issue-18841-core-es-server
azasypkin Feb 28, 2019
c236a63
Review №4: fix typo in test name.
azasypkin Feb 28, 2019
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 packages/kbn-config-schema/src/duration/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ function numberToDuration(numberMs: number) {
return momentDuration(numberMs);

This comment was marked as resolved.

}

export function ensureDuration(value?: Duration | string | number) {
export function ensureDuration(value: Duration | string | number) {
if (typeof value === 'string') {
return stringToDuration(value);
}
Expand Down
7 changes: 7 additions & 0 deletions packages/kbn-config-schema/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ import {
TypeOf,
TypeOptions,
UnionType,
URIOptions,
URIType,
} from './types';

export { ObjectType, TypeOf, Type };
Expand All @@ -65,6 +67,10 @@ function string(options?: StringOptions): Type<string> {
return new StringType(options);
}

function uri(options?: URIOptions): Type<string> {
return new URIType(options);
}

function literal<T extends string | number | boolean>(value: T): Type<T> {
return new LiteralType(value);
}
Expand Down Expand Up @@ -188,6 +194,7 @@ export const schema = {
recordOf,
siblingRef,
string,
uri,
};

export type Schema = typeof schema;
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`#scheme returns error when shorter string 1`] = `"expected URI with scheme [http|https] but but got [ftp://elastic.co]."`;

exports[`#scheme returns error when shorter string 2`] = `"expected URI with scheme [http|https] but but got [file:///kibana.log]."`;

exports[`#validate throws when returns string 1`] = `"validator failure"`;

exports[`is required by default 1`] = `"expected value of type [string] but got [undefined]."`;

exports[`returns error when not string 1`] = `"expected value of type [string] but got [number]."`;

exports[`returns error when not string 2`] = `"expected value of type [string] but got [Array]."`;

exports[`returns error when not string 3`] = `"expected value of type [string] but got [RegExp]."`;

exports[`returns error when value is not a URI 1`] = `"value is [3domain.local] but it must be a valid URI (see RFC 3986)."`;

exports[`returns error when value is not a URI 2`] = `"value is [http://8010:0:0:0:9:500:300C:200A] but it must be a valid URI (see RFC 3986)."`;

exports[`returns error when value is not a URI 3`] = `"value is [-] but it must be a valid URI (see RFC 3986)."`;

exports[`returns error when value is not a URI 4`] = `"value is [https://example.com?baz[]=foo&baz[]=bar] but it must be a valid URI (see RFC 3986)."`;

exports[`returns error when value is not a URI 5`] = `"value is [http://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] but it must be a valid URI (see RFC 3986)."`;
66 changes: 65 additions & 1 deletion packages/kbn-config-schema/src/types/duration_type.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import { duration as momentDuration } from 'moment';
import { schema } from '..';

const { duration } = schema;
const { duration, object, contextRef, siblingRef } = schema;

test('returns value by default', () => {
expect(duration().validate('123s')).toMatchSnapshot();
Expand Down Expand Up @@ -58,6 +58,70 @@ describe('#defaultValue', () => {
}).validate(undefined)
).toMatchSnapshot();
});

test('can be a function that returns compatible type', () => {
expect(
duration({
defaultValue: () => 600,
}).validate(undefined)
).toMatchInlineSnapshot(`"PT0.6S"`);

expect(
duration({
defaultValue: () => '1h',
}).validate(undefined)
).toMatchInlineSnapshot(`"PT1H"`);

expect(
duration({
defaultValue: () => momentDuration(1, 'hour'),
}).validate(undefined)
).toMatchInlineSnapshot(`"PT1H"`);
});

test('can be a reference to a moment.Duration', () => {
expect(
object({
source: duration({ defaultValue: 600 }),
target: duration({ defaultValue: siblingRef('source') }),
fromContext: duration({ defaultValue: contextRef('val') }),
}).validate(undefined, { val: momentDuration(700, 'ms') })
).toMatchInlineSnapshot(`
Object {
"fromContext": "PT0.7S",
"source": "PT0.6S",
"target": "PT0.6S",
}
`);

expect(
object({
source: duration({ defaultValue: '1h' }),
target: duration({ defaultValue: siblingRef('source') }),
fromContext: duration({ defaultValue: contextRef('val') }),
}).validate(undefined, { val: momentDuration(2, 'hour') })
).toMatchInlineSnapshot(`
Object {
"fromContext": "PT2H",
"source": "PT1H",
"target": "PT1H",
}
`);

expect(
object({
source: duration({ defaultValue: momentDuration(1, 'hour') }),
target: duration({ defaultValue: siblingRef('source') }),
fromContext: duration({ defaultValue: contextRef('val') }),
}).validate(undefined, { val: momentDuration(2, 'hour') })
).toMatchInlineSnapshot(`
Object {
"fromContext": "PT2H",
"source": "PT1H",
"target": "PT1H",
}
`);
});
});

test('returns error when not string or non-safe positive integer', () => {
Expand Down
23 changes: 18 additions & 5 deletions packages/kbn-config-schema/src/types/duration_type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,33 @@ import typeDetect from 'type-detect';
import { Duration, ensureDuration } from '../duration';
import { SchemaTypeError } from '../errors';
import { internals } from '../internals';
import { Reference } from '../references';
import { Type } from './type';

type DurationValueType = Duration | string | number;

export interface DurationOptions {
// we need to special-case defaultValue as we want to handle string inputs too
defaultValue?: DurationValueType | Reference<DurationValueType> | (() => DurationValueType);
validate?: (value: Duration) => string | void;
defaultValue?: Duration | string | number;
}

export class DurationType extends Type<Duration> {
constructor(options: DurationOptions = {}) {
super(internals.duration(), {
...options,
defaultValue: ensureDuration(options.defaultValue),
});
let defaultValue;
if (typeof options.defaultValue === 'function') {
const originalDefaultValue = options.defaultValue;
defaultValue = () => ensureDuration(originalDefaultValue());
} else if (
typeof options.defaultValue === 'string' ||
typeof options.defaultValue === 'number'
) {
defaultValue = ensureDuration(options.defaultValue);
} else {
defaultValue = options.defaultValue;
}

super(internals.duration(), { ...options, defaultValue });
}

protected handleError(type: string, { message, value }: Record<string, any>, path: string[]) {
Expand Down
1 change: 1 addition & 0 deletions packages/kbn-config-schema/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ export { ObjectType, Props, TypeOf } from './object_type';
export { RecordOfOptions, RecordOfType } from './record_type';
export { StringOptions, StringType } from './string_type';
export { UnionType } from './union_type';
export { URIOptions, URIType } from './uri_type';
144 changes: 144 additions & 0 deletions packages/kbn-config-schema/src/types/uri_type.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { schema } from '..';

test('is required by default', () => {
expect(() => schema.uri().validate(undefined)).toThrowErrorMatchingSnapshot();
});

test('returns value for valid URI as per RFC3986', () => {
const uriSchema = schema.uri();

expect(uriSchema.validate('http://tools.ietf.org/html/rfc3986')).toBe(
'http://tools.ietf.org/html/rfc3986'
);
expect(uriSchema.validate('udp://3domain.local')).toBe('udp://3domain.local');
expect(uriSchema.validate('urn:elastic:kibana')).toBe('urn:elastic:kibana');
expect(uriSchema.validate('ftp://ftp.ietf.org/rfc/rfc3986.txt')).toBe(
'ftp://ftp.ietf.org/rfc/rfc3986.txt'
);
expect(uriSchema.validate('mailto:Platform.Kibana@elastic.co')).toBe(
'mailto:Platform.Kibana@elastic.co'
);
expect(uriSchema.validate('tel:+500-111-222-333')).toBe('tel:+500-111-222-333');
expect(uriSchema.validate('file:///kibana.log')).toBe('file:///kibana.log');
expect(uriSchema.validate('http://elastic@localhost:9200')).toBe('http://elastic@localhost:9200');
expect(uriSchema.validate('http://elastic:changeme@localhost:9200')).toBe(
'http://elastic:changeme@localhost:9200'
);
expect(uriSchema.validate('ldap://[2001:db8::7]/c=GB?objectClass?one')).toBe(
'ldap://[2001:db8::7]/c=GB?objectClass?one'
);

const uriWithMaxAllowedLength = `http://${'a'.repeat(255)}`;
expect(uriSchema.validate(uriWithMaxAllowedLength)).toBe(uriWithMaxAllowedLength);
});

test('returns error when value is not a URI', () => {
const uriSchema = schema.uri();

expect(() => uriSchema.validate('3domain.local')).toThrowErrorMatchingSnapshot();
expect(() =>
uriSchema.validate('http://8010:0:0:0:9:500:300C:200A')
).toThrowErrorMatchingSnapshot();
expect(() => uriSchema.validate('-')).toThrowErrorMatchingSnapshot();
expect(() =>
uriSchema.validate('https://example.com?baz[]=foo&baz[]=bar')
).toThrowErrorMatchingSnapshot();

const tooLongUri = `http://${'a'.repeat(256)}`;
expect(() => uriSchema.validate(tooLongUri)).toThrowErrorMatchingSnapshot();
});

describe('#scheme', () => {
test('returns value when URI has required scheme', () => {
const uriSchema = schema.uri({ scheme: ['http', 'https'] });

expect(uriSchema.validate('http://elastic.co')).toBe('http://elastic.co');
expect(uriSchema.validate('https://elastic.co')).toBe('https://elastic.co');
});

test('returns error when shorter string', () => {
const uriSchema = schema.uri({ scheme: ['http', 'https'] });

expect(() => uriSchema.validate('ftp://elastic.co')).toThrowErrorMatchingSnapshot();
expect(() => uriSchema.validate('file:///kibana.log')).toThrowErrorMatchingSnapshot();
});
});

describe('#defaultValue', () => {
test('returns default when URI is undefined', () => {
expect(schema.uri({ defaultValue: 'http://localhost:9200' }).validate(undefined)).toBe(
'http://localhost:9200'
);
});

test('returns value when specified', () => {
expect(
schema.uri({ defaultValue: 'http://localhost:9200' }).validate('http://kibana.local')
).toBe('http://kibana.local');
});

test('returns value from context when context reference is specified', () => {
expect(
schema.uri({ defaultValue: schema.contextRef('some_uri') }).validate(undefined, {
some_uri: 'http://kibana.local',
})
).toBe('http://kibana.local');
});
});

describe('#validate', () => {
test('is called with input value', () => {
let calledWith;

const validator = (val: any) => {
calledWith = val;
};

schema.uri({ validate: validator }).validate('http://kibana.local');

expect(calledWith).toBe('http://kibana.local');
});

test('is not called with default value in no input', () => {
const validate = jest.fn();

schema.uri({ validate, defaultValue: 'http://kibana.local' }).validate(undefined);

expect(validate).not.toHaveBeenCalled();
});

test('throws when returns string', () => {
const validate = () => 'validator failure';

expect(() =>
schema.uri({ validate }).validate('http://kibana.local')
).toThrowErrorMatchingSnapshot();
});
});

test('returns error when not string', () => {
expect(() => schema.uri().validate(123)).toThrowErrorMatchingSnapshot();

expect(() => schema.uri().validate([1, 2, 3])).toThrowErrorMatchingSnapshot();

expect(() => schema.uri().validate(/abc/)).toThrowErrorMatchingSnapshot();
});
44 changes: 44 additions & 0 deletions packages/kbn-config-schema/src/types/uri_type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import typeDetect from 'type-detect';
import { internals } from '../internals';
import { Type, TypeOptions } from './type';

export type URIOptions = TypeOptions<string> & {
scheme?: string | string[];
};

export class URIType extends Type<string> {
constructor(options: URIOptions = {}) {
super(internals.string().uri({ scheme: options.scheme }), options);
}

protected handleError(type: string, { value, scheme }: Record<string, unknown>) {
switch (type) {
case 'any.required':
epixa marked this conversation as resolved.
Show resolved Hide resolved
case 'string.base':
return `expected value of type [string] but got [${typeDetect(value)}].`;
case 'string.uriCustomScheme':
return `expected URI with scheme [${scheme}] but but got [${value}].`;
case 'string.uri':
return `value is [${value}] but it must be a valid URI (see RFC 3986).`;
}
}
}
Loading