Skip to content

Commit 134f221

Browse files
committed
Refactoring and PR feedback
1 parent 61e8986 commit 134f221

File tree

7 files changed

+68
-47
lines changed

7 files changed

+68
-47
lines changed

src/core/server/elasticsearch/elasticsearch_config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ const configSchema = schema.object({
106106
ignoreVersionMismatch: schema.conditional(
107107
schema.contextRef('dev'),
108108
false,
109-
schema.any({
109+
schema.boolean({
110110
validate: rawValue => {
111111
if (rawValue === true) {
112112
return '"ignoreVersionMismatch" can only be set to true in development mode';

src/core/server/elasticsearch/elasticsearch_service.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,13 @@ export class ElasticsearchService implements CoreService<InternalElasticsearchSe
170170
unknown
171171
>).connect();
172172

173+
// TODO: Move to Status Service https://github.com/elastic/kibana/issues/41983
174+
esNodesCompatibility$.subscribe(({ isCompatible, message }) => {
175+
if (!isCompatible && message) {
176+
this.log.error(message);
177+
}
178+
});
179+
173180
return {
174181
legacy: { config$: clients$.pipe(map(clients => clients.config)) },
175182

src/core/server/elasticsearch/version_check/ensure_es_version.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ describe('mapNodesVersionCompatibility', () => {
111111
describe('pollEsNodesVersion', () => {
112112
const callWithInternalUser = jest.fn();
113113
it('keeps polling when a poll request throws', done => {
114-
expect.assertions(2);
114+
expect.assertions(3);
115115
callWithInternalUser.mockResolvedValueOnce(createNodes('5.1.0', '5.2.0', '5.0.0'));
116116
callWithInternalUser.mockRejectedValueOnce(new Error('mock request error'));
117117
callWithInternalUser.mockResolvedValueOnce(createNodes('5.1.0', '5.2.0', '5.1.1-Beta1'));
@@ -122,7 +122,7 @@ describe('pollEsNodesVersion', () => {
122122
kibanaVersion: KIBANA_VERSION,
123123
log: mockLogger,
124124
})
125-
.pipe(take(2))
125+
.pipe(take(3))
126126
.subscribe({
127127
next: result => expect(result.isCompatible).toBeDefined(),
128128
complete: done,

src/core/server/elasticsearch/version_check/ensure_es_version.ts

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@
2222
* that defined in Kibana's package.json.
2323
*/
2424

25-
import { coerce } from 'semver';
26-
import { interval } from 'rxjs';
27-
import { map, switchMap, catchError, distinctUntilChanged } from 'rxjs/operators';
28-
import { isEsCompatibleWithKibana } from './is_es_compatible_with_kibana';
25+
import { interval, from } from 'rxjs';
26+
import { map, switchMap, distinctUntilChanged, catchError, startWith } from 'rxjs/operators';
27+
import {
28+
esVersionCompatibleWithKibana,
29+
esVersionEqualsKibana,
30+
} from './es_kibana_version_compatability';
2931
import { Logger } from '../../logging';
3032
import { APICaller } from '..';
3133

@@ -37,12 +39,6 @@ export interface PollEsNodesVersionOptions {
3739
esVersionCheckInterval: number;
3840
}
3941

40-
export interface NodesInfo {
41-
nodes: {
42-
[key: string]: NodeInfo;
43-
};
44-
}
45-
4642
interface NodeInfo {
4743
version: string;
4844
ip: string;
@@ -52,6 +48,12 @@ interface NodeInfo {
5248
name: string;
5349
}
5450

51+
export interface NodesInfo {
52+
nodes: {
53+
[key: string]: NodeInfo;
54+
};
55+
}
56+
5557
export interface NodesVersionCompatibility {
5658
isCompatible: boolean;
5759
message?: string;
@@ -77,18 +79,14 @@ export function mapNodesVersionCompatibility(
7779

7880
// Aggregate incompatible ES nodes.
7981
const incompatibleNodes = nodes.filter(
80-
node => !isEsCompatibleWithKibana(node.version, kibanaVersion)
82+
node => !esVersionCompatibleWithKibana(node.version, kibanaVersion)
8183
);
8284

8385
// Aggregate ES nodes which should prompt a Kibana upgrade. It's acceptable
84-
// if ES and Kibana versions are not the same so long as they are not
86+
// if ES and Kibana versions are not the same as long as they are not
8587
// incompatible, but we should warn about it.
8688
// Ignore version qualifiers https://github.com/elastic/elasticsearch/issues/36859
87-
const warningNodes = nodes.filter(node => {
88-
const nodeSemVer = coerce(node.version);
89-
const kibanaSemver = coerce(kibanaVersion);
90-
return nodeSemVer && kibanaSemver && nodeSemVer.version !== kibanaSemver.version;
91-
});
89+
const warningNodes = nodes.filter(node => !esVersionEqualsKibana(node.version, kibanaVersion));
9290

9391
let message;
9492
if (incompatibleNodes.length > 0) {
@@ -115,6 +113,18 @@ export function mapNodesVersionCompatibility(
115113
};
116114
}
117115

116+
// Returns true if two NodesVersionCompatibility entries match
117+
function compareNodes(prev: NodesVersionCompatibility, curr: NodesVersionCompatibility) {
118+
const nodesEqual = (n: NodeInfo, m: NodeInfo) => n.ip === m.ip && n.version === m.version;
119+
return (
120+
curr.isCompatible === prev.isCompatible &&
121+
curr.incompatibleNodes.length === prev.incompatibleNodes.length &&
122+
curr.warningNodes.length === prev.warningNodes.length &&
123+
curr.incompatibleNodes.every((node, i) => nodesEqual(node, prev.incompatibleNodes[i])) &&
124+
curr.warningNodes.every((node, i) => nodesEqual(node, prev.warningNodes[i]))
125+
);
126+
}
127+
118128
export const pollEsNodesVersion = ({
119129
callWithInternalUser,
120130
log,
@@ -130,22 +140,21 @@ export const pollEsNodesVersion = ({
130140
filterPath: ['nodes.*.version', 'nodes.*.http.publish_address', 'nodes.*.ip'],
131141
});
132142
}),
133-
// Log, but otherwise ignore 'nodes.info' request errors
134-
catchError((err, caught$) => {
135-
log.error('Unable to retrieve version information from Elasticsearch nodes.', err);
136-
return caught$;
137-
}),
138143
map((nodesInfo: NodesInfo) =>
139144
mapNodesVersionCompatibility(nodesInfo, kibanaVersion, ignoreVersionMismatch)
140145
),
141-
// Only emit if the IP or version numbers of the nodes changed from the
142-
// previous result.
143-
distinctUntilChanged((prev, curr) => {
144-
const nodesEqual = (n: NodeInfo, m: NodeInfo) => n.ip === m.ip && n.version === m.version;
145-
return (
146-
curr.incompatibleNodes.every((node, i) => nodesEqual(node, prev.incompatibleNodes[i])) &&
147-
curr.warningNodes.every((node, i) => nodesEqual(node, prev.warningNodes[i]))
146+
catchError((_err, caught$) => {
147+
// Return `isCompatible=false` when there's a 'nodes.info' request error
148+
return caught$.pipe(
149+
startWith({
150+
isCompatible: false,
151+
message: 'Unable to retrieve version information from Elasticsearch nodes.',
152+
incompatibleNodes: [],
153+
warningNodes: [],
154+
kibanaVersion,
155+
})
148156
);
149-
})
157+
}),
158+
distinctUntilChanged(compareNodes) // Only emit if there are new nodes or versions
150159
);
151160
};

src/core/server/elasticsearch/version_check/is_es_compatible_with_kibana.test.ts renamed to src/core/server/elasticsearch/version_check/es_kibana_version_compatability.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,39 +17,39 @@
1717
* under the License.
1818
*/
1919

20-
import { isEsCompatibleWithKibana } from './is_es_compatible_with_kibana';
20+
import { esVersionCompatibleWithKibana } from './es_kibana_version_compatability';
2121

2222
describe('plugins/elasticsearch', () => {
2323
describe('lib/is_es_compatible_with_kibana', () => {
2424
describe('returns false', () => {
2525
it('when ES major is greater than Kibana major', () => {
26-
expect(isEsCompatibleWithKibana('1.0.0', '0.0.0')).toBe(false);
26+
expect(esVersionCompatibleWithKibana('1.0.0', '0.0.0')).toBe(false);
2727
});
2828

2929
it('when ES major is less than Kibana major', () => {
30-
expect(isEsCompatibleWithKibana('0.0.0', '1.0.0')).toBe(false);
30+
expect(esVersionCompatibleWithKibana('0.0.0', '1.0.0')).toBe(false);
3131
});
3232

3333
it('when majors are equal, but ES minor is less than Kibana minor', () => {
34-
expect(isEsCompatibleWithKibana('1.0.0', '1.1.0')).toBe(false);
34+
expect(esVersionCompatibleWithKibana('1.0.0', '1.1.0')).toBe(false);
3535
});
3636
});
3737

3838
describe('returns true', () => {
3939
it('when version numbers are the same', () => {
40-
expect(isEsCompatibleWithKibana('1.1.1', '1.1.1')).toBe(true);
40+
expect(esVersionCompatibleWithKibana('1.1.1', '1.1.1')).toBe(true);
4141
});
4242

4343
it('when majors are equal, and ES minor is greater than Kibana minor', () => {
44-
expect(isEsCompatibleWithKibana('1.1.0', '1.0.0')).toBe(true);
44+
expect(esVersionCompatibleWithKibana('1.1.0', '1.0.0')).toBe(true);
4545
});
4646

4747
it('when majors and minors are equal, and ES patch is greater than Kibana patch', () => {
48-
expect(isEsCompatibleWithKibana('1.1.1', '1.1.0')).toBe(true);
48+
expect(esVersionCompatibleWithKibana('1.1.1', '1.1.0')).toBe(true);
4949
});
5050

5151
it('when majors and minors are equal, but ES patch is less than Kibana patch', () => {
52-
expect(isEsCompatibleWithKibana('1.1.0', '1.1.1')).toBe(true);
52+
expect(esVersionCompatibleWithKibana('1.1.0', '1.1.1')).toBe(true);
5353
});
5454
});
5555
});

src/core/server/elasticsearch/version_check/is_es_compatible_with_kibana.ts renamed to src/core/server/elasticsearch/version_check/es_kibana_version_compatability.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,14 @@
1717
* under the License.
1818
*/
1919

20+
import semver, { coerce } from 'semver';
21+
2022
/**
21-
* Let's weed out the ES versions that won't work with a given Kibana version.
23+
* Checks for the compatibilitiy between Elasticsearch and Kibana versions
2224
* 1. Major version differences will never work together.
2325
* 2. Older versions of ES won't work with newer versions of Kibana.
2426
*/
25-
26-
import semver from 'semver';
27-
28-
export function isEsCompatibleWithKibana(esVersion: string, kibanaVersion: string) {
27+
export function esVersionCompatibleWithKibana(esVersion: string, kibanaVersion: string) {
2928
const esVersionNumbers = {
3029
major: semver.major(esVersion),
3130
minor: semver.minor(esVersion),
@@ -50,3 +49,9 @@ export function isEsCompatibleWithKibana(esVersion: string, kibanaVersion: strin
5049

5150
return true;
5251
}
52+
53+
export function esVersionEqualsKibana(nodeVersion: string, kibanaVersion: string) {
54+
const nodeSemVer = coerce(nodeVersion);
55+
const kibanaSemver = coerce(kibanaVersion);
56+
return nodeSemVer && kibanaSemver && nodeSemVer.version === kibanaSemver.version;
57+
}

src/legacy/core_plugins/elasticsearch/lib/version_health_check.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export const versionHealthCheck = (esPlugin, logWithMetadata, esNodesCompatibili
2525
if (!isCompatible) {
2626
esPlugin.status.red(message);
2727
} else {
28-
if (message && message.length > 0) {
28+
if (message) {
2929
logWithMetadata(['warning'], message, {
3030
kibanaVersion,
3131
nodes: warningNodes,

0 commit comments

Comments
 (0)