Skip to content

Commit

Permalink
[data views] Allow data views created on hidden and system indices (#…
Browse files Browse the repository at this point in the history
…168174)

## Summary

Previously, the 'Allow hidden and system indices' advanced option when
creating a data view was only a UI convenience. It allowed you to see
which hidden and system indices you were matching but they would be
would be selected just the same once the data view was loaded. At some
point something changed and now there are system and hidden indices that
require `expandWildcards: hidden` to be passed to field caps in order to
see anything. `allowHidden: boolean` is added to the DataView and
DataViewSpec and passed through when field caps requests are made.

This is primarily a tool for troubleshooting. For instance, instead of
hitting a full data stream across a number of data tiers you can select
a specific index to compare its performance.

Closes: #164652
  • Loading branch information
mattkime authored Oct 13, 2023
1 parent 43a1e15 commit 85d8231
Show file tree
Hide file tree
Showing 14 changed files with 87 additions and 3 deletions.
2 changes: 1 addition & 1 deletion packages/kbn-optimizer/limits.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pageLoadAssetSize:
dataViewEditor: 28082
dataViewFieldEditor: 27000
dataViewManagement: 5000
dataViews: 47300
dataViews: 48300
dataVisualizer: 27530
devTools: 38637
discover: 99999
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ const IndexPatternEditorFlyoutContentComponent = ({
timeFieldName: formData.timestampField?.value,
id: formData.id,
name: formData.name,
allowHidden: formData.allowHidden,
};

if (type === INDEX_PATTERN_TYPE.ROLLUP && rollupIndex) {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/plugins/data_views/common/data_views/data_view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ export class DataView implements DataViewBase {
*/
public matchedIndices: string[] = [];

private allowHidden: boolean = false;

/**
* constructor
* @param config - config data and dependencies
Expand Down Expand Up @@ -187,6 +189,7 @@ export class DataView implements DataViewBase {
this.runtimeFieldMap = cloneDeep(spec.runtimeFieldMap) || {};
this.namespaces = spec.namespaces || [];
this.name = spec.name || '';
this.allowHidden = spec.allowHidden || false;
}

/**
Expand All @@ -201,6 +204,8 @@ export class DataView implements DataViewBase {

getIndexPattern = () => this.title;

getAllowHidden = () => this.allowHidden;

/**
* Set index pattern
* @param string index pattern string
Expand Down
4 changes: 4 additions & 0 deletions src/plugins/data_views/common/data_views/data_views.ts
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,7 @@ export class DataViewsService {
allowNoIndex: true,
pattern: dataView.getIndexPattern(),
metaFields,
allowHidden: dataView.getAllowHidden(),
});
};

Expand All @@ -596,6 +597,7 @@ export class DataViewsService {
rollupIndex: options.rollupIndex,
allowNoIndex: true,
indexFilter: options.indexFilter,
allowHidden: options.allowHidden,
});
};

Expand Down Expand Up @@ -747,6 +749,7 @@ export class DataViewsService {
fieldAttrs,
allowNoIndex,
name,
allowHidden,
},
} = savedObject;

Expand Down Expand Up @@ -774,6 +777,7 @@ export class DataViewsService {
allowNoIndex,
runtimeFieldMap: parsedRuntimeFieldMap,
name,
allowHidden,
};
};

Expand Down
9 changes: 9 additions & 0 deletions src/plugins/data_views/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ export interface DataViewAttributes {
* Name of the data view. Human readable name used to differentiate data view.
*/
name?: string;
/**
* Allow hidden and system indices when loading field list
*/
allowHidden?: boolean;
}

/**
Expand Down Expand Up @@ -309,6 +313,7 @@ export interface GetFieldsOptions {
indexFilter?: QueryDslQueryContainer;
includeUnmapped?: boolean;
fields?: string[];
allowHidden?: boolean;
}

/**
Expand Down Expand Up @@ -512,6 +517,10 @@ export type DataViewSpec = {
* Name of the data view. Human readable name used to differentiate data view.
*/
name?: string;
/**
* Whether the data view is hidden from the user
*/
allowHidden?: boolean;
};

// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
Expand Down
14 changes: 13 additions & 1 deletion src/plugins/data_views/server/fetcher/index_patterns_fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,23 @@ export class IndexPatternsFetcher {
rollupIndex?: string;
indexFilter?: QueryDslQueryContainer;
fields?: string[];
allowHidden?: boolean;
}): Promise<{ fields: FieldDescriptor[]; indices: string[] }> {
const { pattern, metaFields = [], fieldCapsOptions, type, rollupIndex, indexFilter } = options;
const {
pattern,
metaFields = [],
fieldCapsOptions,
type,
rollupIndex,
indexFilter,
allowHidden,
} = options;
const allowNoIndices = fieldCapsOptions
? fieldCapsOptions.allow_no_indices
: this.allowNoIndices;

const expandWildcards = allowHidden ? 'all' : 'open';

const fieldCapsResponse = await getFieldCapabilities({
callCluster: this.elasticsearchClient,
indices: pattern,
Expand All @@ -85,6 +96,7 @@ export class IndexPatternsFetcher {
},
indexFilter,
fields: options.fields || ['*'],
expandWildcards,
});

if (this.rollupsEnabled && type === 'rollup' && rollupIndex) {
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/data_views/server/fetcher/lib/es_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

import { ElasticsearchClient } from '@kbn/core/server';
import { ExpandWildcard } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import { QueryDslQueryContainer } from '../../../common/types';
import { convertEsError } from './errors';

Expand Down Expand Up @@ -45,6 +46,7 @@ interface FieldCapsApiParams {
fieldCapsOptions?: { allow_no_indices: boolean; include_unmapped?: boolean };
indexFilter?: QueryDslQueryContainer;
fields?: string[];
expandWildcard?: ExpandWildcard;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ describe('index_patterns/field_capabilities/field_capabilities', () => {
const fillUndefinedParams = (args) => ({
callCluster: undefined,
indices: undefined,
expandWildcard: undefined,
fieldCapsOptions: undefined,
indexFilter: undefined,
fields: undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import { defaults, keyBy, sortBy } from 'lodash';

import { ElasticsearchClient } from '@kbn/core/server';
import { ExpandWildcard } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import { callFieldCapsApi } from '../es_api';
import { readFieldCapsResponse } from './field_caps_response';
import { mergeOverrides } from './overrides';
Expand All @@ -22,6 +23,7 @@ interface FieldCapabilitiesParams {
fieldCapsOptions?: { allow_no_indices: boolean; include_unmapped?: boolean };
indexFilter?: QueryDslQueryContainer;
fields?: string[];
expandWildcards?: ExpandWildcard;
}

/**
Expand All @@ -42,13 +44,15 @@ export async function getFieldCapabilities(params: FieldCapabilitiesParams) {
indexFilter,
metaFields = [],
fields,
expandWildcards,
} = params;
const esFieldCaps = await callFieldCapsApi({
callCluster,
indices,
fieldCapsOptions,
indexFilter,
fields,
expandWildcard: expandWildcards,
});
const fieldCapsArr = readFieldCapsResponse(esFieldCaps.body);
const fieldsFromFieldCapsByName = keyBy(fieldCapsArr, 'name');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ interface IQuery {
allow_no_index?: boolean;
include_unmapped?: boolean;
fields?: string[];
allow_hidden?: boolean;
}

const querySchema = schema.object({
Expand All @@ -62,6 +63,7 @@ const querySchema = schema.object({
allow_no_index: schema.maybe(schema.boolean()),
include_unmapped: schema.maybe(schema.boolean()),
fields: schema.maybe(schema.oneOf([schema.string(), schema.arrayOf(schema.string())])),
allow_hidden: schema.maybe(schema.boolean()),
});

const fieldSubTypeSchema = schema.object({
Expand Down Expand Up @@ -122,6 +124,7 @@ const handler: (isRollupsEnabled: () => boolean) => RequestHandler<{}, IQuery, I
rollup_index: rollupIndex,
allow_no_index: allowNoIndex,
include_unmapped: includeUnmapped,
allow_hidden: allowHidden,
} = request.query;

// not available to get request
Expand All @@ -147,6 +150,7 @@ const handler: (isRollupsEnabled: () => boolean) => RequestHandler<{}, IQuery, I
includeUnmapped,
},
indexFilter,
allowHidden,
...(parsedFields.length > 0 ? { fields: parsedFields } : {}),
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const retry = getService('retry');
const testSubjects = getService('testSubjects');
const find = getService('find');
const es = getService('es');
const PageObjects = getPageObjects(['settings', 'common', 'header']);

describe('creating and deleting default data view', function describeIndexTests() {
Expand Down Expand Up @@ -250,5 +251,32 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
});
});

describe('hidden index support', () => {
it('can create data view against hidden index', async () => {
const pattern = 'logstash-2015.09.21';

await es.transport.request({
path: '/logstash-2015.09.21/_settings',
method: 'PUT',
body: {
index: {
hidden: true,
},
},
});

await PageObjects.settings.createIndexPattern(
pattern,
undefined,
undefined,
undefined,
undefined,
true
);
const patternName = await PageObjects.settings.getIndexPageHeading();
expect(patternName).to.be(pattern);
});
});
});
}
13 changes: 12 additions & 1 deletion test/functional/page_objects/settings_page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -470,13 +470,19 @@ export class SettingsPageObject extends FtrService {
await customDataViewIdInput.type(value);
}

async allowHiddenClick() {
await this.testSubjects.click('toggleAdvancedSetting');
await this.testSubjects.click('allowHiddenField');
}

async createIndexPattern(
indexPatternName: string,
// null to bypass default value
timefield: string | null = '@timestamp',
isStandardIndexPattern = true,
customDataViewId?: string,
dataViewName?: string
dataViewName?: string,
allowHidden?: boolean
) {
await this.retry.try(async () => {
await this.header.waitUntilLoadingHasFinished();
Expand All @@ -489,6 +495,11 @@ export class SettingsPageObject extends FtrService {
} else {
await this.clickAddNewIndexPatternButton();
}

if (allowHidden) {
await this.allowHiddenClick();
}

await this.header.waitUntilLoadingHasFinished();
if (!isStandardIndexPattern) {
await this.selectRollupIndexPatternType();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ describe('LogViewsClient class', () => {
},
],
"dataViewReference": DataView {
"allowHidden": false,
"allowNoIndex": false,
"deleteFieldFormat": [Function],
"fieldAttrs": Object {},
Expand All @@ -273,6 +274,7 @@ describe('LogViewsClient class', () => {
},
"fields": FldList [],
"flattenHit": [Function],
"getAllowHidden": [Function],
"getFieldAttrs": [Function],
"getIndexPattern": [Function],
"getName": [Function],
Expand Down

0 comments on commit 85d8231

Please sign in to comment.