Skip to content

Commit 69179e6

Browse files
author
Liza K
committed
Merge branch 'master' of github.com:elastic/kibana into search/client-session-service
2 parents 0cca933 + 1bcbac7 commit 69179e6

File tree

10 files changed

+135
-50
lines changed

10 files changed

+135
-50
lines changed

.github/CODEOWNERS

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,16 @@
66
# used for the 'team' designator within Kibana Stats
77

88
# App
9-
/x-pack/plugins/dashboard_enhanced/ @elastic/kibana-app
109
/x-pack/plugins/discover_enhanced/ @elastic/kibana-app
1110
/x-pack/plugins/lens/ @elastic/kibana-app
1211
/x-pack/plugins/graph/ @elastic/kibana-app
1312
/src/plugins/advanced_settings/ @elastic/kibana-app
1413
/src/plugins/charts/ @elastic/kibana-app
15-
/src/plugins/dashboard/ @elastic/kibana-app
1614
/src/plugins/discover/ @elastic/kibana-app
17-
/src/plugins/input_control_vis/ @elastic/kibana-app
1815
/src/plugins/management/ @elastic/kibana-app
1916
/src/plugins/kibana_legacy/ @elastic/kibana-app
2017
/src/plugins/timelion/ @elastic/kibana-app
2118
/src/plugins/vis_default_editor/ @elastic/kibana-app
22-
/src/plugins/vis_type_markdown/ @elastic/kibana-app
2319
/src/plugins/vis_type_metric/ @elastic/kibana-app
2420
/src/plugins/vis_type_table/ @elastic/kibana-app
2521
/src/plugins/vis_type_tagcloud/ @elastic/kibana-app
@@ -35,19 +31,15 @@
3531
#CC# /src/legacy/core_plugins/kibana/common/utils @elastic/kibana-app
3632
#CC# /src/legacy/core_plugins/kibana/migrations @elastic/kibana-app
3733
#CC# /src/legacy/core_plugins/kibana/public @elastic/kibana-app
38-
#CC# /src/legacy/core_plugins/kibana/public/dashboard/ @elastic/kibana-app
3934
#CC# /src/legacy/core_plugins/kibana/public/discover/ @elastic/kibana-app
4035
#CC# /src/legacy/core_plugins/kibana/public/local_application_service/ @elastic/kibana-app
41-
#CC# /src/legacy/core_plugins/input_control_vis @elastic/kibana-app
4236
#CC# /src/legacy/core_plugins/timelion @elastic/kibana-app
4337
#CC# /src/legacy/core_plugins/vis_type_tagcloud @elastic/kibana-app
4438
#CC# /src/legacy/core_plugins/vis_type_vega @elastic/kibana-app
4539
#CC# /src/legacy/core_plugins/vis_type_vislib/ @elastic/kibana-app
4640
#CC# /src/legacy/server/url_shortening/ @elastic/kibana-app
4741
#CC# /src/legacy/ui/public/state_management @elastic/kibana-app
4842
#CC# /src/plugins/index_pattern_management/public @elastic/kibana-app
49-
#CC# /x-pack/legacy/plugins/dashboard_mode/ @elastic/kibana-app
50-
#CC# /x-pack/plugins/dashboard_mode @elastic/kibana-app
5143

5244
# App Architecture
5345
/examples/bfetch_explorer/ @elastic/kibana-app-arch
@@ -127,10 +119,18 @@
127119
#CC# /x-pack/plugins/beats_management/ @elastic/beats
128120

129121
# Canvas
122+
/src/plugins/dashboard/ @elastic/kibana-app
123+
/src/plugins/input_control_vis/ @elastic/kibana-app
124+
/src/plugins/vis_type_markdown/ @elastic/kibana-app
130125
/x-pack/plugins/canvas/ @elastic/kibana-canvas
126+
/x-pack/plugins/dashboard_enhanced/ @elastic/kibana-app
131127
/x-pack/test/functional/apps/canvas/ @elastic/kibana-canvas
128+
#CC# /src/legacy/core_plugins/kibana/public/dashboard/ @elastic/kibana-app
129+
#CC# /src/legacy/core_plugins/input_control_vis @elastic/kibana-app
132130
#CC# /src/plugins/kibana_react/public/code_editor/ @elastic/kibana-canvas
133131
#CC# /x-pack/legacy/plugins/canvas/ @elastic/kibana-canvas
132+
#CC# /x-pack/plugins/dashboard_mode @elastic/kibana-app
133+
#CC# /x-pack/legacy/plugins/dashboard_mode/ @elastic/kibana-app
134134

135135
# Core UI
136136
# Exclude tutorials folder for now because they are not owned by Kibana app and most will move out soon

x-pack/plugins/security_solution/public/detections/components/user_info/index.test.tsx

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,17 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66

7-
import { renderHook } from '@testing-library/react-hooks';
8-
import { useUserInfo } from './index';
7+
import { renderHook, act } from '@testing-library/react-hooks';
8+
import { useUserInfo, ManageUserInfo } from './index';
99

10-
import { usePrivilegeUser } from '../../containers/detection_engine/alerts/use_privilege_user';
11-
import { useSignalIndex } from '../../containers/detection_engine/alerts/use_signal_index';
1210
import { useKibana } from '../../../common/lib/kibana';
13-
jest.mock('../../containers/detection_engine/alerts/use_privilege_user');
14-
jest.mock('../../containers/detection_engine/alerts/use_signal_index');
11+
import * as api from '../../containers/detection_engine/alerts/api';
12+
1513
jest.mock('../../../common/lib/kibana');
14+
jest.mock('../../containers/detection_engine/alerts/api');
1615

1716
describe('useUserInfo', () => {
1817
beforeAll(() => {
19-
(usePrivilegeUser as jest.Mock).mockReturnValue({});
20-
(useSignalIndex as jest.Mock).mockReturnValue({});
2118
(useKibana as jest.Mock).mockReturnValue({
2219
services: {
2320
application: {
@@ -30,21 +27,40 @@ describe('useUserInfo', () => {
3027
},
3128
});
3229
});
33-
it('returns default state', () => {
34-
const { result } = renderHook(() => useUserInfo());
30+
it('returns default state', async () => {
31+
await act(async () => {
32+
const { result, waitForNextUpdate } = renderHook(() => useUserInfo());
33+
await waitForNextUpdate();
3534

36-
expect(result).toEqual({
37-
current: {
38-
canUserCRUD: null,
39-
hasEncryptionKey: null,
40-
hasIndexManage: null,
41-
hasIndexWrite: null,
42-
isAuthenticated: null,
43-
isSignalIndexExists: null,
44-
loading: true,
45-
signalIndexName: null,
46-
},
47-
error: undefined,
35+
expect(result).toEqual({
36+
current: {
37+
canUserCRUD: null,
38+
hasEncryptionKey: null,
39+
hasIndexManage: null,
40+
hasIndexWrite: null,
41+
isAuthenticated: null,
42+
isSignalIndexExists: null,
43+
loading: true,
44+
signalIndexName: null,
45+
signalIndexTemplateOutdated: null,
46+
},
47+
error: undefined,
48+
});
49+
});
50+
});
51+
52+
it('calls createSignalIndex if signal index template is outdated', async () => {
53+
const spyOnCreateSignalIndex = jest.spyOn(api, 'createSignalIndex');
54+
const spyOnGetSignalIndex = jest.spyOn(api, 'getSignalIndex').mockResolvedValueOnce({
55+
name: 'mock-signal-index',
56+
template_outdated: true,
57+
});
58+
await act(async () => {
59+
const { waitForNextUpdate } = renderHook(() => useUserInfo(), { wrapper: ManageUserInfo });
60+
await waitForNextUpdate();
61+
await waitForNextUpdate();
4862
});
63+
expect(spyOnGetSignalIndex).toHaveBeenCalledTimes(2);
64+
expect(spyOnCreateSignalIndex).toHaveBeenCalledTimes(1);
4965
});
5066
});

x-pack/plugins/security_solution/public/detections/components/user_info/index.tsx

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export interface State {
2020
hasEncryptionKey: boolean | null;
2121
loading: boolean;
2222
signalIndexName: string | null;
23+
signalIndexTemplateOutdated: boolean | null;
2324
}
2425

2526
export const initialState: State = {
@@ -31,6 +32,7 @@ export const initialState: State = {
3132
hasEncryptionKey: null,
3233
loading: true,
3334
signalIndexName: null,
35+
signalIndexTemplateOutdated: null,
3436
};
3537

3638
export type Action =
@@ -62,6 +64,10 @@ export type Action =
6264
| {
6365
type: 'updateSignalIndexName';
6466
signalIndexName: string | null;
67+
}
68+
| {
69+
type: 'updateSignalIndexTemplateOutdated';
70+
signalIndexTemplateOutdated: boolean | null;
6571
};
6672

6773
export const userInfoReducer = (state: State, action: Action): State => {
@@ -114,6 +120,12 @@ export const userInfoReducer = (state: State, action: Action): State => {
114120
signalIndexName: action.signalIndexName,
115121
};
116122
}
123+
case 'updateSignalIndexTemplateOutdated': {
124+
return {
125+
...state,
126+
signalIndexTemplateOutdated: action.signalIndexTemplateOutdated,
127+
};
128+
}
117129
default:
118130
return state;
119131
}
@@ -144,6 +156,7 @@ export const useUserInfo = (): State => {
144156
hasEncryptionKey,
145157
loading,
146158
signalIndexName,
159+
signalIndexTemplateOutdated,
147160
},
148161
dispatch,
149162
] = useUserData();
@@ -158,6 +171,7 @@ export const useUserInfo = (): State => {
158171
loading: indexNameLoading,
159172
signalIndexExists: isApiSignalIndexExists,
160173
signalIndexName: apiSignalIndexName,
174+
signalIndexTemplateOutdated: apiSignalIndexTemplateOutdated,
161175
createDeSignalIndex: createSignalIndex,
162176
} = useSignalIndex();
163177

@@ -166,7 +180,7 @@ export const useUserInfo = (): State => {
166180
typeof uiCapabilities.siem.crud === 'boolean' ? uiCapabilities.siem.crud : false;
167181

168182
useEffect(() => {
169-
if (loading !== privilegeLoading || indexNameLoading) {
183+
if (loading !== (privilegeLoading || indexNameLoading)) {
170184
dispatch({ type: 'updateLoading', loading: privilegeLoading || indexNameLoading });
171185
}
172186
}, [dispatch, loading, privilegeLoading, indexNameLoading]);
@@ -217,18 +231,38 @@ export const useUserInfo = (): State => {
217231
}
218232
}, [dispatch, loading, signalIndexName, apiSignalIndexName]);
219233

234+
useEffect(() => {
235+
if (
236+
!loading &&
237+
signalIndexTemplateOutdated !== apiSignalIndexTemplateOutdated &&
238+
apiSignalIndexTemplateOutdated != null
239+
) {
240+
dispatch({
241+
type: 'updateSignalIndexTemplateOutdated',
242+
signalIndexTemplateOutdated: apiSignalIndexTemplateOutdated,
243+
});
244+
}
245+
}, [dispatch, loading, signalIndexTemplateOutdated, apiSignalIndexTemplateOutdated]);
246+
220247
useEffect(() => {
221248
if (
222249
isAuthenticated &&
223250
hasEncryptionKey &&
224251
hasIndexManage &&
225-
isSignalIndexExists != null &&
226-
!isSignalIndexExists &&
252+
((isSignalIndexExists != null && !isSignalIndexExists) ||
253+
(signalIndexTemplateOutdated != null && signalIndexTemplateOutdated)) &&
227254
createSignalIndex != null
228255
) {
229256
createSignalIndex();
230257
}
231-
}, [createSignalIndex, isAuthenticated, hasEncryptionKey, isSignalIndexExists, hasIndexManage]);
258+
}, [
259+
createSignalIndex,
260+
isAuthenticated,
261+
hasEncryptionKey,
262+
isSignalIndexExists,
263+
hasIndexManage,
264+
signalIndexTemplateOutdated,
265+
]);
232266

233267
return {
234268
loading,
@@ -239,5 +273,6 @@ export const useUserInfo = (): State => {
239273
hasIndexManage,
240274
hasIndexWrite,
241275
signalIndexName,
276+
signalIndexTemplateOutdated,
242277
};
243278
};

x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/mock.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,7 @@ export const mockStatusAlertQuery: object = {
980980

981981
export const mockSignalIndex: AlertsIndex = {
982982
name: 'mock-signal-index',
983+
template_outdated: false,
983984
};
984985

985986
export const mockUserPrivilege: Privilege = {

x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export interface UpdateAlertStatusProps {
4444

4545
export interface AlertsIndex {
4646
name: string;
47+
template_outdated: boolean;
4748
}
4849

4950
export interface Privilege {

x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_signal_index.test.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ describe('useSignalIndex', () => {
2626
loading: true,
2727
signalIndexExists: null,
2828
signalIndexName: null,
29+
signalIndexTemplateOutdated: null,
2930
});
3031
});
3132
});
@@ -42,6 +43,7 @@ describe('useSignalIndex', () => {
4243
loading: false,
4344
signalIndexExists: true,
4445
signalIndexName: 'mock-signal-index',
46+
signalIndexTemplateOutdated: false,
4547
});
4648
});
4749
});
@@ -62,6 +64,7 @@ describe('useSignalIndex', () => {
6264
loading: false,
6365
signalIndexExists: true,
6466
signalIndexName: 'mock-signal-index',
67+
signalIndexTemplateOutdated: false,
6568
});
6669
});
6770
});
@@ -101,6 +104,7 @@ describe('useSignalIndex', () => {
101104
loading: false,
102105
signalIndexExists: false,
103106
signalIndexName: null,
107+
signalIndexTemplateOutdated: null,
104108
});
105109
});
106110
});
@@ -121,6 +125,7 @@ describe('useSignalIndex', () => {
121125
loading: false,
122126
signalIndexExists: false,
123127
signalIndexName: null,
128+
signalIndexTemplateOutdated: null,
124129
});
125130
});
126131
});

x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_signal_index.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export interface ReturnSignalIndex {
1717
loading: boolean;
1818
signalIndexExists: boolean | null;
1919
signalIndexName: string | null;
20+
signalIndexTemplateOutdated: boolean | null;
2021
createDeSignalIndex: Func | null;
2122
}
2223

@@ -27,11 +28,10 @@ export interface ReturnSignalIndex {
2728
*/
2829
export const useSignalIndex = (): ReturnSignalIndex => {
2930
const [loading, setLoading] = useState(true);
30-
const [signalIndex, setSignalIndex] = useState<
31-
Pick<ReturnSignalIndex, 'signalIndexExists' | 'signalIndexName' | 'createDeSignalIndex'>
32-
>({
31+
const [signalIndex, setSignalIndex] = useState<Omit<ReturnSignalIndex, 'loading'>>({
3332
signalIndexExists: null,
3433
signalIndexName: null,
34+
signalIndexTemplateOutdated: null,
3535
createDeSignalIndex: null,
3636
});
3737
const [, dispatchToaster] = useStateToaster();
@@ -49,6 +49,7 @@ export const useSignalIndex = (): ReturnSignalIndex => {
4949
setSignalIndex({
5050
signalIndexExists: true,
5151
signalIndexName: signal.name,
52+
signalIndexTemplateOutdated: signal.template_outdated,
5253
createDeSignalIndex: createIndex,
5354
});
5455
}
@@ -57,6 +58,7 @@ export const useSignalIndex = (): ReturnSignalIndex => {
5758
setSignalIndex({
5859
signalIndexExists: false,
5960
signalIndexName: null,
61+
signalIndexTemplateOutdated: null,
6062
createDeSignalIndex: createIndex,
6163
});
6264
if (isSecurityAppError(error) && error.body.status_code !== 404) {
@@ -87,6 +89,7 @@ export const useSignalIndex = (): ReturnSignalIndex => {
8789
setSignalIndex({
8890
signalIndexExists: false,
8991
signalIndexName: null,
92+
signalIndexTemplateOutdated: null,
9093
createDeSignalIndex: createIndex,
9194
});
9295
errorToToaster({ title: i18n.SIGNAL_POST_FAILURE, error, dispatchToaster });
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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 { get } from 'lodash';
8+
import { LegacyAPICaller } from '../../../../../../../../src/core/server';
9+
import { getSignalsTemplate } from './get_signals_template';
10+
import { getTemplateExists } from '../../index/get_template_exists';
11+
12+
export const templateNeedsUpdate = async (callCluster: LegacyAPICaller, index: string) => {
13+
const templateExists = await getTemplateExists(callCluster, index);
14+
let existingTemplateVersion: number | undefined;
15+
if (templateExists) {
16+
const existingTemplate: unknown = await callCluster('indices.getTemplate', {
17+
name: index,
18+
});
19+
existingTemplateVersion = get(existingTemplate, [index, 'version']);
20+
}
21+
const newTemplate = getSignalsTemplate(index);
22+
if (existingTemplateVersion === undefined || existingTemplateVersion < newTemplate.version) {
23+
return true;
24+
}
25+
return false;
26+
};

0 commit comments

Comments
 (0)