From ccd4f46b8ecb238ae97266a33929c4a55e687a28 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Wed, 13 May 2020 16:48:06 +0200 Subject: [PATCH 1/4] First iteration of supporting hidden indices in indices table Tests probably have broken --- .../index_table/index_table.container.js | 10 +-- .../index_list/index_table/index_table.js | 14 ++-- .../application/store/actions/table_state.js | 4 +- .../application/store/reducers/table_state.js | 10 +-- .../application/store/selectors/index.js | 8 +- .../server/lib/fetch_indices.ts | 82 ++++++++++++------- 6 files changed, 77 insertions(+), 51 deletions(-) diff --git a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.container.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.container.js index 5d0e2fd4530ef2..f6250a7a6e25c7 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.container.js +++ b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.container.js @@ -11,7 +11,7 @@ import { getPager, getFilter, isDetailPanelOpen, - showSystemIndices, + showHiddenIndices, getSortField, isSortAscending, getIndicesAsArray, @@ -26,7 +26,7 @@ import { pageChanged, pageSizeChanged, sortChanged, - showSystemIndicesChanged, + showHiddenIndicesChanged, loadIndices, reloadIndices, toggleChanged, @@ -42,7 +42,7 @@ const mapStateToProps = state => { indices: getPageOfIndices(state), pager: getPager(state), filter: getFilter(state), - showSystemIndices: showSystemIndices(state), + showHiddenIndices: showHiddenIndices(state), sortField: getSortField(state), isSortAscending: isSortAscending(state), indicesLoading: indicesLoading(state), @@ -65,8 +65,8 @@ const mapDispatchToProps = dispatch => { sortChanged: (sortField, isSortAscending) => { dispatch(sortChanged({ sortField, isSortAscending })); }, - showSystemIndicesChanged: showSystemIndices => { - dispatch(showSystemIndicesChanged({ showSystemIndices })); + showHiddenIndicesChanged: showHiddenIndices => { + dispatch(showHiddenIndicesChanged({ showHiddenIndices })); }, toggleChanged: (toggleName, toggleValue) => { dispatch(toggleChanged({ toggleName, toggleValue })); diff --git a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.js index b659e2ec86a9b6..7a0a6269a6ab86 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.js +++ b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.js @@ -400,8 +400,8 @@ export class IndexTable extends Component { render() { const { filter, - showSystemIndices, - showSystemIndicesChanged, + showHiddenIndices, + showHiddenIndicesChanged, indices, loadIndices, indicesLoading, @@ -459,13 +459,13 @@ export class IndexTable extends Component { })} showSystemIndicesChanged(event.target.checked)} + id="checkboxShowHiddenIndices" + checked={showHiddenIndices} + onChange={event => showHiddenIndicesChanged(event.target.checked)} label={ } /> diff --git a/x-pack/plugins/index_management/public/application/store/actions/table_state.js b/x-pack/plugins/index_management/public/application/store/actions/table_state.js index cc6c66aab4f1a0..70e0de74d02788 100644 --- a/x-pack/plugins/index_management/public/application/store/actions/table_state.js +++ b/x-pack/plugins/index_management/public/application/store/actions/table_state.js @@ -17,8 +17,8 @@ export const pageSizeChanged = createAction('INDEX_MANAGEMENT_PAGE_SIZE_CHANGED' export const sortChanged = createAction('INDEX_MANAGEMENT_SORT_CHANGED'); -export const showSystemIndicesChanged = createAction( - 'INDEX_MANAGEMENT_SHOW_SYSTEM_INDICES_CHANGED' +export const showHiddenIndicesChanged = createAction( + 'INDEX_MANAGEMENT_SHOW_HIDDEN_INDICES_CHANGED' ); export const toggleChanged = createAction('INDEX_MANAGEMENT_TOGGLE_CHANGED'); diff --git a/x-pack/plugins/index_management/public/application/store/reducers/table_state.js b/x-pack/plugins/index_management/public/application/store/reducers/table_state.js index 8bb4e77619ef6e..e90fa72aa62fe2 100644 --- a/x-pack/plugins/index_management/public/application/store/reducers/table_state.js +++ b/x-pack/plugins/index_management/public/application/store/reducers/table_state.js @@ -10,7 +10,7 @@ import { pageChanged, pageSizeChanged, sortChanged, - showSystemIndicesChanged, + showHiddenIndicesChanged, toggleChanged, } from '../actions'; @@ -20,7 +20,7 @@ export const defaultTableState = { currentPage: 0, sortField: 'index.name', isSortAscending: true, - showSystemIndices: false, + showHiddenIndices: false, }; export const tableState = handleActions( @@ -33,12 +33,12 @@ export const tableState = handleActions( currentPage: 0, }; }, - [showSystemIndicesChanged](state, action) { - const { showSystemIndices } = action.payload; + [showHiddenIndicesChanged](state, action) { + const { showHiddenIndices } = action.payload; return { ...state, - showSystemIndices, + showHiddenIndices, }; }, [toggleChanged](state, action) { diff --git a/x-pack/plugins/index_management/public/application/store/selectors/index.js b/x-pack/plugins/index_management/public/application/store/selectors/index.js index 3ddbf28651fa07..0f481c55782b00 100644 --- a/x-pack/plugins/index_management/public/application/store/selectors/index.js +++ b/x-pack/plugins/index_management/public/application/store/selectors/index.js @@ -86,9 +86,9 @@ const getFilteredIndices = createSelector( (indices, allIds, tableState) => { let indexArray = allIds.map(indexName => indices[indexName]); indexArray = filterByToggles(indexArray, tableState.toggleNameToVisibleMap); - const systemFilteredIndexes = tableState.showSystemIndices + const systemFilteredIndexes = tableState.showHiddenIndices ? indexArray - : indexArray.filter(index => !(index.name + '').startsWith('.')); + : indexArray.filter(index => !(index.name + '').startsWith('.') && !index.hidden); const filter = tableState.filter || EuiSearchBar.Query.MATCH_ALL; return EuiSearchBar.Query.execute(filter, systemFilteredIndexes, { defaultFields: defaultFilterFields, @@ -151,9 +151,9 @@ export const getCurrentPage = createSelector(getPager, pager => { export const getFilter = createSelector(getTableState, ({ filter }) => filter); -export const showSystemIndices = createSelector( +export const showHiddenIndices = createSelector( getTableState, - ({ showSystemIndices }) => showSystemIndices + ({ showHiddenIndices }) => showHiddenIndices ); export const isSortAscending = createSelector( diff --git a/x-pack/plugins/index_management/server/lib/fetch_indices.ts b/x-pack/plugins/index_management/server/lib/fetch_indices.ts index d9f01ee060145c..4d82e7f48cfca9 100644 --- a/x-pack/plugins/index_management/server/lib/fetch_indices.ts +++ b/x-pack/plugins/index_management/server/lib/fetch_indices.ts @@ -3,9 +3,9 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ +import { CatIndicesParams } from 'elasticsearch'; import { IndexDataEnricher } from '../services'; import { Index, CallAsCurrentUser } from '../types'; -import { fetchAliases } from './fetch_aliases'; interface Hit { health: string; @@ -17,20 +17,61 @@ interface Hit { 'docs.count': any; 'store.size': any; sth: 'true' | 'false'; + hidden: boolean; } -interface Aliases { - [key: string]: string[]; +interface IndexInfo { + aliases: { [aliasName: string]: unknown }; + mappings: unknown; + settings: { + index: { + hidden: 'true' | 'false'; + }; + }; } -interface Params { - format: string; - h: string; - index?: string[]; +interface GetIndicesResponse { + [indexName: string]: IndexInfo; } -function formatHits(hits: Hit[], aliases: Aliases): Index[] { - return hits.map((hit: Hit) => { +async function fetchIndicesCall( + callAsCurrentUser: CallAsCurrentUser, + indexNames?: string[] +): Promise { + const indices: GetIndicesResponse = await callAsCurrentUser('transport.request', { + method: 'GET', + path: `/${indexNames ? indexNames : '*'}`, + query: { + expand_wildcards: 'hidden,all', + }, + }); + + if (!Object.keys(indices).length) { + return []; + } + + const catQuery: Pick & { + expand_wildcards: string; + index?: string; + } = { + format: 'json', + h: 'health,status,index,uuid,pri,rep,docs.count,sth,store.size', + expand_wildcards: 'hidden,all', + }; + + if (indexNames) { + catQuery.index = indexNames.join(','); + } + const catHits: Hit[] = await callAsCurrentUser('transport.request', { + method: 'GET', + path: '/_cat/indices', + query: catQuery, + }); + + return catHits.map(hit => { + const index = indices[hit.index]; + const aliases = Object.keys(index.aliases); + return { health: hit.health, status: hit.status, @@ -41,32 +82,17 @@ function formatHits(hits: Hit[], aliases: Aliases): Index[] { documents: hit['docs.count'], size: hit['store.size'], isFrozen: hit.sth === 'true', // sth value coming back as a string from ES - aliases: aliases.hasOwnProperty(hit.index) ? aliases[hit.index] : 'none', + aliases: aliases.length ? aliases : 'none', + hidden: index.settings.index.hidden === 'true', }; }); } -async function fetchIndicesCall(callAsCurrentUser: CallAsCurrentUser, indexNames?: string[]) { - const params: Params = { - format: 'json', - h: 'health,status,index,uuid,pri,rep,docs.count,sth,store.size', - }; - - if (indexNames) { - params.index = indexNames; - } - - return await callAsCurrentUser('cat.indices', params); -} - export const fetchIndices = async ( callAsCurrentUser: CallAsCurrentUser, indexDataEnricher: IndexDataEnricher, indexNames?: string[] ) => { - const aliases = await fetchAliases(callAsCurrentUser); - const hits = await fetchIndicesCall(callAsCurrentUser, indexNames); - const indices = formatHits(hits, aliases); - - return await indexDataEnricher.enrichIndices(indices, callAsCurrentUser); + const response = await fetchIndicesCall(callAsCurrentUser, indexNames); + return await indexDataEnricher.enrichIndices(response, callAsCurrentUser); }; From 9ca7880c9c5052ae1893142a097387331a0bfa3f Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Wed, 13 May 2020 16:53:14 +0200 Subject: [PATCH 2/4] Remove unused code --- .../server/lib/fetch_aliases.test.ts | 46 ------------------- .../server/lib/fetch_aliases.ts | 16 ------- .../server/lib/fetch_indices.ts | 1 + 3 files changed, 1 insertion(+), 62 deletions(-) delete mode 100644 x-pack/plugins/index_management/server/lib/fetch_aliases.test.ts delete mode 100644 x-pack/plugins/index_management/server/lib/fetch_aliases.ts diff --git a/x-pack/plugins/index_management/server/lib/fetch_aliases.test.ts b/x-pack/plugins/index_management/server/lib/fetch_aliases.test.ts deleted file mode 100644 index d5ba11df1f0a99..00000000000000 --- a/x-pack/plugins/index_management/server/lib/fetch_aliases.test.ts +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import sinon from 'sinon'; -import { fetchAliases } from './fetch_aliases'; - -describe('fetching aliases', () => { - const fetchFn = fetchAliases; - - test('should return map of aliases for indices', async () => { - const retVal = [ - { index: 'test1Index', alias: 'test1Alias' }, - { index: 'test2Index', alias: 'test1Alias' }, - { index: 'test3Index', alias: 'test2Alias' }, - { index: 'test3Index', alias: 'test3Alias' }, - ]; - const mockCallWithRequest = sinon.spy(() => { - return retVal; - }); - - const results = await fetchFn(mockCallWithRequest); - - expect(mockCallWithRequest.called); - expect(results).toBeDefined(); - expect(results).toMatchObject({ - test1Index: ['test1Alias'], - test2Index: ['test1Alias'], - test3Index: ['test2Alias', 'test3Alias'], - }); - }); - - test('should return an empty object if no aliases exist', async () => { - const mockCallWithRequest = sinon.spy(() => { - return []; - }); - - const results = await fetchFn(mockCallWithRequest); - - expect(mockCallWithRequest.called); - expect(results).toBeDefined(); - expect(results).toMatchObject({}); - }); -}); diff --git a/x-pack/plugins/index_management/server/lib/fetch_aliases.ts b/x-pack/plugins/index_management/server/lib/fetch_aliases.ts deleted file mode 100644 index 794a260fb9c518..00000000000000 --- a/x-pack/plugins/index_management/server/lib/fetch_aliases.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export async function fetchAliases(callWithRequest: any) { - const results = await callWithRequest('cat.aliases', { format: 'json' }); - return results.reduce( - (hash: { [key: string]: any }, { index, alias }: { index: string; alias: string }) => { - (hash[index] = hash[index] || []).push(alias); - return hash; - }, - {} - ); -} diff --git a/x-pack/plugins/index_management/server/lib/fetch_indices.ts b/x-pack/plugins/index_management/server/lib/fetch_indices.ts index 4d82e7f48cfca9..b965f8f2907d82 100644 --- a/x-pack/plugins/index_management/server/lib/fetch_indices.ts +++ b/x-pack/plugins/index_management/server/lib/fetch_indices.ts @@ -62,6 +62,7 @@ async function fetchIndicesCall( if (indexNames) { catQuery.index = indexNames.join(','); } + const catHits: Hit[] = await callAsCurrentUser('transport.request', { method: 'GET', path: '/_cat/indices', From 956d511a91a714a2f262595e35e8d8b8d9bdaadd Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Thu, 14 May 2020 12:06:53 +0200 Subject: [PATCH 3/4] Fix logic when calling get index endpoint with empty array Also remove unused translations --- .../server/lib/fetch_indices.ts | 21 ++++++++++++------- .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - .../management/index_management/indices.js | 2 ++ 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/x-pack/plugins/index_management/server/lib/fetch_indices.ts b/x-pack/plugins/index_management/server/lib/fetch_indices.ts index b965f8f2907d82..6c0d376922b622 100644 --- a/x-pack/plugins/index_management/server/lib/fetch_indices.ts +++ b/x-pack/plugins/index_management/server/lib/fetch_indices.ts @@ -38,9 +38,17 @@ async function fetchIndicesCall( callAsCurrentUser: CallAsCurrentUser, indexNames?: string[] ): Promise { + let indexNamesCSV: string; + if (indexNames && indexNames.length) { + indexNamesCSV = indexNames.join(','); + } else { + indexNamesCSV = '*'; + } + + // This call retrieves alias and settings (incl. hidden status) information about indices const indices: GetIndicesResponse = await callAsCurrentUser('transport.request', { method: 'GET', - path: `/${indexNames ? indexNames : '*'}`, + path: `/${indexNamesCSV}`, query: { expand_wildcards: 'hidden,all', }, @@ -57,18 +65,17 @@ async function fetchIndicesCall( format: 'json', h: 'health,status,index,uuid,pri,rep,docs.count,sth,store.size', expand_wildcards: 'hidden,all', + index: indexNamesCSV, }; - if (indexNames) { - catQuery.index = indexNames.join(','); - } - + // This call retrieves health and other high-level information about indices. const catHits: Hit[] = await callAsCurrentUser('transport.request', { method: 'GET', path: '/_cat/indices', query: catQuery, }); + // The two responses should be equal in the number of indices returned return catHits.map(hit => { const index = indices[hit.index]; const aliases = Object.keys(index.aliases); @@ -94,6 +101,6 @@ export const fetchIndices = async ( indexDataEnricher: IndexDataEnricher, indexNames?: string[] ) => { - const response = await fetchIndicesCall(callAsCurrentUser, indexNames); - return await indexDataEnricher.enrichIndices(response, callAsCurrentUser); + const indices = await fetchIndicesCall(callAsCurrentUser, indexNames); + return await indexDataEnricher.enrichIndices(indices, callAsCurrentUser); }; diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 149c13ea55fb21..31fdc189b75397 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -6736,7 +6736,6 @@ "xpack.idxMgmt.indexTable.serverErrorTitle": "インデックスの読み込み中にエラーが発生", "xpack.idxMgmt.indexTable.systemIndicesSearchIndicesAriaLabel": "インデックスの検索", "xpack.idxMgmt.indexTable.systemIndicesSearchInputPlaceholder": "検索", - "xpack.idxMgmt.indexTable.systemIndicesSwitchLabel": "システムインデックスを含める", "xpack.idxMgmt.indexTemplatesList.emptyPrompt.noIndexTemplatesTitle": "まだテンプレートがありません", "xpack.idxMgmt.indexTemplatesList.loadingIndexTemplatesDescription": "テンプレートを読み込み中…", "xpack.idxMgmt.indexTemplatesList.loadingIndexTemplatesErrorMessage": "テンプレートの読み込み中にエラーが発生", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index bd22f2a14a2920..dae498cf7dd073 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -6741,7 +6741,6 @@ "xpack.idxMgmt.indexTable.serverErrorTitle": "加载索引时出错", "xpack.idxMgmt.indexTable.systemIndicesSearchIndicesAriaLabel": "搜索索引", "xpack.idxMgmt.indexTable.systemIndicesSearchInputPlaceholder": "搜索", - "xpack.idxMgmt.indexTable.systemIndicesSwitchLabel": "包括系统索引", "xpack.idxMgmt.indexTemplatesList.emptyPrompt.noIndexTemplatesTitle": "您尚未有任何模板", "xpack.idxMgmt.indexTemplatesList.loadingIndexTemplatesDescription": "正在加载模板……", "xpack.idxMgmt.indexTemplatesList.loadingIndexTemplatesErrorMessage": "加载模板时出错", diff --git a/x-pack/test/api_integration/apis/management/index_management/indices.js b/x-pack/test/api_integration/apis/management/index_management/indices.js index ac50a20b02e3ba..5d523262d7f104 100644 --- a/x-pack/test/api_integration/apis/management/index_management/indices.js +++ b/x-pack/test/api_integration/apis/management/index_management/indices.js @@ -184,6 +184,7 @@ export default function({ getService }) { const { body } = await list().expect(200); const expectedKeys = [ 'health', + 'hidden', 'status', 'name', 'uuid', @@ -214,6 +215,7 @@ export default function({ getService }) { const { body } = await reload().expect(200); const expectedKeys = [ 'health', + 'hidden', 'status', 'name', 'uuid', From 11d1ef9b5b3eb5772af9ca8d47e0fecd8203420b Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Thu, 14 May 2020 17:34:22 +0200 Subject: [PATCH 4/4] More terse! --- .../index_management/server/lib/fetch_indices.ts | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/index_management/server/lib/fetch_indices.ts b/x-pack/plugins/index_management/server/lib/fetch_indices.ts index 6c0d376922b622..1f62680a41cbcb 100644 --- a/x-pack/plugins/index_management/server/lib/fetch_indices.ts +++ b/x-pack/plugins/index_management/server/lib/fetch_indices.ts @@ -38,17 +38,12 @@ async function fetchIndicesCall( callAsCurrentUser: CallAsCurrentUser, indexNames?: string[] ): Promise { - let indexNamesCSV: string; - if (indexNames && indexNames.length) { - indexNamesCSV = indexNames.join(','); - } else { - indexNamesCSV = '*'; - } + const indexNamesString = indexNames && indexNames.length ? indexNames.join(',') : '*'; // This call retrieves alias and settings (incl. hidden status) information about indices const indices: GetIndicesResponse = await callAsCurrentUser('transport.request', { method: 'GET', - path: `/${indexNamesCSV}`, + path: `/${indexNamesString}`, query: { expand_wildcards: 'hidden,all', }, @@ -65,7 +60,7 @@ async function fetchIndicesCall( format: 'json', h: 'health,status,index,uuid,pri,rep,docs.count,sth,store.size', expand_wildcards: 'hidden,all', - index: indexNamesCSV, + index: indexNamesString, }; // This call retrieves health and other high-level information about indices.