mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 18:51:07 -04:00
[data views] Disable scripted fields in serverless environment (#163228)
## Summary Disables scripted fields in serverless environments. Data view defined scripted fields are ignored and the scripted fields tab in data view management is hidden. scriptedFieldsEnabled is defined via conditional config that's only available in serverless environments. --------- Co-authored-by: Julia Rechkunova <julia.rechkunova@gmail.com>
This commit is contained in:
parent
af450729ff
commit
2b47e4b346
37 changed files with 241 additions and 24 deletions
|
@ -23,6 +23,7 @@ describe('createSearchSource', () => {
|
|||
getConfig: jest.fn(),
|
||||
search: jest.fn(),
|
||||
onResponse: (req, res) => res,
|
||||
scriptedFieldsEnabled: true,
|
||||
};
|
||||
|
||||
indexPatternContractMock = {
|
||||
|
|
|
@ -71,4 +71,5 @@ export const createSearchSourceMock = (
|
|||
)
|
||||
),
|
||||
onResponse: jest.fn().mockImplementation((req, res) => res),
|
||||
scriptedFieldsEnabled: true,
|
||||
});
|
||||
|
|
|
@ -94,6 +94,7 @@ describe('SearchSource', () => {
|
|||
getConfig: getConfigMock,
|
||||
search: mockSearchMethod,
|
||||
onResponse: jest.fn().mockImplementation((_, res) => res),
|
||||
scriptedFieldsEnabled: true,
|
||||
};
|
||||
|
||||
searchSource = new SearchSource({}, searchSourceDependencies);
|
||||
|
@ -651,6 +652,22 @@ describe('SearchSource', () => {
|
|||
const request = searchSource.getSearchRequestBody();
|
||||
expect(request.script_fields).toEqual({ hello: {}, world: {} });
|
||||
});
|
||||
|
||||
test('ignores scripted fields when scripted fields are disabled', async () => {
|
||||
searchSource.setField('index', {
|
||||
...indexPattern,
|
||||
getComputedFields: () => ({
|
||||
storedFields: [],
|
||||
scriptFields: { hello: {}, world: {} },
|
||||
docvalueFields: [],
|
||||
}),
|
||||
} as unknown as DataView);
|
||||
searchSourceDependencies.scriptedFieldsEnabled = false;
|
||||
searchSource.setField('fields', ['timestamp', '*']);
|
||||
|
||||
const request = searchSource.getSearchRequestBody();
|
||||
expect(request.script_fields).toEqual({});
|
||||
});
|
||||
});
|
||||
|
||||
describe('handling for when specific fields are provided', () => {
|
||||
|
|
|
@ -138,6 +138,7 @@ export const searchSourceRequiredUiSettings = [
|
|||
export interface SearchSourceDependencies extends FetchHandlers {
|
||||
aggs: AggsStart;
|
||||
search: ISearchGeneric;
|
||||
scriptedFieldsEnabled: boolean;
|
||||
}
|
||||
|
||||
interface ExpressionAstOptions {
|
||||
|
@ -798,10 +799,12 @@ export class SearchSource {
|
|||
// set defaults
|
||||
let fieldsFromSource = searchRequest.fieldsFromSource || [];
|
||||
body.fields = body.fields || [];
|
||||
body.script_fields = {
|
||||
...body.script_fields,
|
||||
...scriptFields,
|
||||
};
|
||||
body.script_fields = this.dependencies.scriptedFieldsEnabled
|
||||
? {
|
||||
...body.script_fields,
|
||||
...scriptFields,
|
||||
}
|
||||
: {};
|
||||
body.stored_fields = storedFields;
|
||||
body.runtime_mappings = runtimeFields || {};
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ describe('SearchSource service', () => {
|
|||
getConfig: jest.fn(),
|
||||
search: jest.fn(),
|
||||
onResponse: jest.fn(),
|
||||
scriptedFieldsEnabled: true,
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
@ -138,6 +138,7 @@ export class DataPublicPlugin
|
|||
fieldFormats,
|
||||
indexPatterns: dataViews,
|
||||
screenshotMode,
|
||||
scriptedFieldsEnabled: dataViews.scriptedFieldsEnabled,
|
||||
});
|
||||
setSearchService(search);
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@ describe('Search service', () => {
|
|||
fieldFormats: {} as FieldFormatsStart,
|
||||
indexPatterns: {} as DataViewsContract,
|
||||
screenshotMode: screenshotModePluginMock.createStartContract(),
|
||||
scriptedFieldsEnabled: true,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -86,6 +86,7 @@ export interface SearchServiceStartDependencies {
|
|||
fieldFormats: FieldFormatsStart;
|
||||
indexPatterns: DataViewsContract;
|
||||
screenshotMode: ScreenshotModePluginStart;
|
||||
scriptedFieldsEnabled: boolean;
|
||||
}
|
||||
|
||||
export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
|
||||
|
@ -216,7 +217,12 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
|
|||
|
||||
public start(
|
||||
{ http, theme, uiSettings, chrome, application }: CoreStart,
|
||||
{ fieldFormats, indexPatterns, screenshotMode }: SearchServiceStartDependencies
|
||||
{
|
||||
fieldFormats,
|
||||
indexPatterns,
|
||||
screenshotMode,
|
||||
scriptedFieldsEnabled,
|
||||
}: SearchServiceStartDependencies
|
||||
): ISearchStart {
|
||||
const search = ((request, options = {}) => {
|
||||
return this.searchInterceptor.search(request, options);
|
||||
|
@ -245,6 +251,7 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
|
|||
}
|
||||
return response;
|
||||
},
|
||||
scriptedFieldsEnabled,
|
||||
};
|
||||
|
||||
const config = this.initializerContext.config.get();
|
||||
|
|
|
@ -302,6 +302,7 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
|
|||
getConfig: <T = any>(key: string): T => uiSettingsCache[key],
|
||||
search: this.asScoped(request).search,
|
||||
onResponse: (req, res) => res,
|
||||
scriptedFieldsEnabled: true,
|
||||
};
|
||||
|
||||
return this.searchSourceService.start(scopedIndexPatterns, searchSourceDependencies);
|
||||
|
|
|
@ -569,7 +569,7 @@ export function Tabs({
|
|||
|
||||
const euiTabs: EuiTabbedContentTab[] = useMemo(
|
||||
() =>
|
||||
getTabs(indexPattern, fieldFilter, relationships.length).map(
|
||||
getTabs(indexPattern, fieldFilter, relationships.length, dataViews.scriptedFieldsEnabled).map(
|
||||
(tab: Pick<EuiTabbedContentTab, 'name' | 'id'>) => {
|
||||
return {
|
||||
...tab,
|
||||
|
@ -577,7 +577,7 @@ export function Tabs({
|
|||
};
|
||||
}
|
||||
),
|
||||
[fieldFilter, getContent, indexPattern, relationships]
|
||||
[fieldFilter, getContent, indexPattern, relationships, dataViews.scriptedFieldsEnabled]
|
||||
);
|
||||
|
||||
const [selectedTabId, setSelectedTabId] = useState(euiTabs[0].id);
|
||||
|
|
|
@ -15,7 +15,7 @@ import {
|
|||
TAB_SOURCE_FILTERS,
|
||||
TAB_RELATIONSHIPS,
|
||||
} from '../constants';
|
||||
import { areScriptedFieldsEnabled } from '../../utils';
|
||||
import { isRollup } from '../../utils';
|
||||
|
||||
function filterByName(items: DataViewField[], filter: string) {
|
||||
const lowercaseFilter = (filter || '').toLowerCase();
|
||||
|
@ -73,7 +73,12 @@ function getTitle(type: string, filteredCount: Dictionary<number>, totalCount: D
|
|||
return title + count;
|
||||
}
|
||||
|
||||
export function getTabs(indexPattern: DataView, fieldFilter: string, relationshipCount = 0) {
|
||||
export function getTabs(
|
||||
indexPattern: DataView,
|
||||
fieldFilter: string,
|
||||
relationshipCount = 0,
|
||||
scriptedFieldsEnabled: boolean
|
||||
) {
|
||||
const totalCount = getCounts(indexPattern.fields.getAll(), indexPattern.getSourceFiltering());
|
||||
const filteredCount = getCounts(
|
||||
indexPattern.fields.getAll(),
|
||||
|
@ -89,7 +94,7 @@ export function getTabs(indexPattern: DataView, fieldFilter: string, relationshi
|
|||
'data-test-subj': 'tab-indexedFields',
|
||||
});
|
||||
|
||||
if (areScriptedFieldsEnabled(indexPattern)) {
|
||||
if (!isRollup(indexPattern.type) && scriptedFieldsEnabled) {
|
||||
tabs.push({
|
||||
name: getTitle('scripted', filteredCount, totalCount),
|
||||
id: TAB_SCRIPTED_FIELDS,
|
||||
|
|
|
@ -213,7 +213,10 @@ export const IndexPatternTable = ({
|
|||
width: '70%',
|
||||
render: (name: string, dataView: IndexPatternTableItem) => (
|
||||
<div>
|
||||
<EuiLink {...reactRouterNavigate(history, `patterns/${dataView.id}`)}>
|
||||
<EuiLink
|
||||
{...reactRouterNavigate(history, `patterns/${dataView.id}`)}
|
||||
data-test-subj={`detail-link-${dataView.name}`}
|
||||
>
|
||||
{dataView.getName()}
|
||||
{dataView.name ? (
|
||||
<>
|
||||
|
|
|
@ -28,7 +28,7 @@ const rollupIndexPatternListName = i18n.translate(
|
|||
}
|
||||
);
|
||||
|
||||
const isRollup = (indexPatternType: string = '') => {
|
||||
export const isRollup = (indexPatternType: string = '') => {
|
||||
return indexPatternType === 'rollup';
|
||||
};
|
||||
|
||||
|
@ -85,10 +85,6 @@ export const getTags = (indexPattern: DataViewListItem | DataView, isDefault: bo
|
|||
return tags;
|
||||
};
|
||||
|
||||
export const areScriptedFieldsEnabled = (indexPattern: DataViewListItem | DataView) => {
|
||||
return !isRollup(indexPattern.type);
|
||||
};
|
||||
|
||||
export const getFieldInfo = (indexPattern: DataViewListItem | DataView, field: DataViewField) => {
|
||||
if (!isRollup(indexPattern.type)) {
|
||||
return [];
|
||||
|
|
|
@ -92,6 +92,10 @@ export async function mountManagementSection(
|
|||
savedObjectsManagement,
|
||||
};
|
||||
|
||||
const editPath = '/dataView/:id/field/:fieldName';
|
||||
const createPath = '/dataView/:id/create-field/';
|
||||
const createEditPath = dataViews.scriptedFieldsEnabled ? [editPath, createPath] : [editPath];
|
||||
|
||||
ReactDOM.render(
|
||||
<KibanaRenderContextProvider theme={theme} i18n={coreI18n}>
|
||||
<KibanaContextProvider services={deps}>
|
||||
|
@ -100,7 +104,7 @@ export async function mountManagementSection(
|
|||
<Route path={['/create']}>
|
||||
<IndexPatternTableWithRouter canSave={canSave} showCreateDialog={true} />
|
||||
</Route>
|
||||
<Route path={['/dataView/:id/field/:fieldName', '/dataView/:id/create-field/']}>
|
||||
<Route path={createEditPath}>
|
||||
<CreateEditFieldContainer />
|
||||
</Route>
|
||||
<Route path={['/dataView/:id']}>
|
||||
|
|
|
@ -115,6 +115,7 @@ describe('IndexPatterns', () => {
|
|||
onRedirectNoIndexPattern: () => {},
|
||||
getCanSave: () => Promise.resolve(true),
|
||||
getCanSaveAdvancedSettings: () => Promise.resolve(true),
|
||||
scriptedFieldsEnabled: true,
|
||||
});
|
||||
|
||||
indexPatternsNoAccess = new DataViewsService({
|
||||
|
@ -127,6 +128,7 @@ describe('IndexPatterns', () => {
|
|||
onRedirectNoIndexPattern: () => {},
|
||||
getCanSave: () => Promise.resolve(false),
|
||||
getCanSaveAdvancedSettings: () => Promise.resolve(false),
|
||||
scriptedFieldsEnabled: true,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -120,6 +120,8 @@ export interface DataViewsServiceDeps {
|
|||
* Determines whether the user can save advancedSettings (used for defaultIndex)
|
||||
*/
|
||||
getCanSaveAdvancedSettings: () => Promise<boolean>;
|
||||
|
||||
scriptedFieldsEnabled: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -325,6 +327,8 @@ export class DataViewsService {
|
|||
* Can the user save data views?
|
||||
*/
|
||||
public getCanSave: () => Promise<boolean>;
|
||||
|
||||
public readonly scriptedFieldsEnabled: boolean;
|
||||
/**
|
||||
* DataViewsService constructor
|
||||
* @param deps Service dependencies
|
||||
|
@ -339,6 +343,7 @@ export class DataViewsService {
|
|||
onError,
|
||||
getCanSave = () => Promise.resolve(false),
|
||||
getCanSaveAdvancedSettings,
|
||||
scriptedFieldsEnabled,
|
||||
} = deps;
|
||||
this.apiClient = apiClient;
|
||||
this.config = uiSettings;
|
||||
|
@ -350,6 +355,7 @@ export class DataViewsService {
|
|||
this.getCanSaveAdvancedSettings = getCanSaveAdvancedSettings;
|
||||
|
||||
this.dataViewCache = createDataViewCache();
|
||||
this.scriptedFieldsEnabled = scriptedFieldsEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -591,7 +597,9 @@ export class DataViewsService {
|
|||
private refreshFieldsFn = async (indexPattern: DataView) => {
|
||||
const { fields, indices } = await this.getFieldsAndIndicesForDataView(indexPattern);
|
||||
fields.forEach((field) => (field.isMapped = true));
|
||||
const scripted = indexPattern.getScriptedFields().map((field) => field.spec);
|
||||
const scripted = this.scriptedFieldsEnabled
|
||||
? indexPattern.getScriptedFields().map((field) => field.spec)
|
||||
: [];
|
||||
const fieldAttrs = indexPattern.getFieldAttrs();
|
||||
const fieldsWithSavedAttrs = Object.values(
|
||||
this.fieldArrayToMap([...fields, ...scripted], fieldAttrs)
|
||||
|
@ -655,7 +663,9 @@ export class DataViewsService {
|
|||
displayErrors: boolean = true
|
||||
) => {
|
||||
const fieldsAsArr = Object.values(fields);
|
||||
const scriptedFields = fieldsAsArr.filter((field) => field.scripted);
|
||||
const scriptedFields = this.scriptedFieldsEnabled
|
||||
? fieldsAsArr.filter((field) => field.scripted)
|
||||
: [];
|
||||
try {
|
||||
let updatedFieldList: FieldSpec[];
|
||||
const { fields: newFields, indices } = await this.getFieldsAndIndicesForWildcard(options);
|
||||
|
|
|
@ -525,3 +525,7 @@ export interface HasDataService {
|
|||
hasUserDataView: () => Promise<boolean>;
|
||||
hasDataView: () => Promise<boolean>;
|
||||
}
|
||||
|
||||
export interface ClientConfigType {
|
||||
scriptedFieldsEnabled?: boolean;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ export interface DataViewsServicePublicDeps extends DataViewsServiceDeps {
|
|||
showAllIndices?: boolean;
|
||||
isRollupIndex: (indexName: string) => boolean;
|
||||
}) => Promise<MatchedItem[]>;
|
||||
scriptedFieldsEnabled: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -44,6 +45,7 @@ export class DataViewsServicePublic extends DataViewsService {
|
|||
isRollupIndex: (indexName: string) => boolean;
|
||||
}) => Promise<MatchedItem[]>;
|
||||
public hasData: HasDataService;
|
||||
public readonly scriptedFieldsEnabled: boolean;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -55,5 +57,6 @@ export class DataViewsServicePublic extends DataViewsService {
|
|||
this.getCanSaveSync = deps.getCanSaveSync;
|
||||
this.hasData = deps.hasData;
|
||||
this.getIndices = deps.getIndices;
|
||||
this.scriptedFieldsEnabled = deps.scriptedFieldsEnabled;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { PluginInitializerContext } from '@kbn/core/public';
|
||||
|
||||
export {
|
||||
ILLEGAL_CHARACTERS_KEY,
|
||||
CONTAINS_SPACES_KEY,
|
||||
|
@ -55,8 +57,8 @@ export { UiSettingsPublicToCommon } from './ui_settings_wrapper';
|
|||
|
||||
import { DataViewsPublicPlugin } from './plugin';
|
||||
|
||||
export function plugin() {
|
||||
return new DataViewsPublicPlugin();
|
||||
export function plugin(initializerContext: PluginInitializerContext) {
|
||||
return new DataViewsPublicPlugin(initializerContext);
|
||||
}
|
||||
|
||||
export type {
|
||||
|
|
|
@ -6,9 +6,10 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { CoreSetup, CoreStart, Plugin } from '@kbn/core/public';
|
||||
import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from '@kbn/core/public';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { getIndexPatternLoad } from './expressions';
|
||||
import type { ClientConfigType } from '../common/types';
|
||||
import {
|
||||
DataViewsPublicPluginSetup,
|
||||
DataViewsPublicPluginStart,
|
||||
|
@ -40,6 +41,8 @@ export class DataViewsPublicPlugin
|
|||
{
|
||||
private readonly hasData = new HasData();
|
||||
|
||||
constructor(private readonly initializerContext: PluginInitializerContext) {}
|
||||
|
||||
public setup(
|
||||
core: CoreSetup<DataViewsPublicStartDependencies, DataViewsPublicPluginStart>,
|
||||
{ expressions, contentManagement }: DataViewsPublicSetupDependencies
|
||||
|
@ -74,6 +77,8 @@ export class DataViewsPublicPlugin
|
|||
10000
|
||||
);
|
||||
|
||||
const config = this.initializerContext.config.get<ClientConfigType>();
|
||||
|
||||
return new DataViewsServicePublic({
|
||||
hasData: this.hasData.start(core),
|
||||
uiSettings: new UiSettingsPublicToCommon(uiSettings),
|
||||
|
@ -91,6 +96,7 @@ export class DataViewsPublicPlugin
|
|||
getCanSaveAdvancedSettings: () =>
|
||||
Promise.resolve(application.capabilities.advancedSettings.save === true),
|
||||
getIndices: (props) => getIndices({ ...props, http: core.http }),
|
||||
scriptedFieldsEnabled: config.scriptedFieldsEnabled === false ? false : true, // accounting for null value
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -120,6 +120,7 @@ export interface DataViewsServicePublic extends DataViewsServicePublicMethods {
|
|||
showAllIndices?: boolean;
|
||||
isRollupIndex: (indexName: string) => boolean;
|
||||
}) => Promise<MatchedItem[]>;
|
||||
scriptedFieldsEnabled: boolean;
|
||||
}
|
||||
|
||||
export type DataViewsContract = DataViewsServicePublic;
|
||||
|
|
|
@ -25,6 +25,7 @@ interface DataViewsServiceFactoryDeps {
|
|||
uiSettings: UiSettingsServiceStart;
|
||||
fieldFormats: FieldFormatsStart;
|
||||
capabilities: CoreStart['capabilities'];
|
||||
scriptedFieldsEnabled: boolean;
|
||||
rollupsEnabled: boolean;
|
||||
}
|
||||
|
||||
|
@ -70,5 +71,6 @@ export const dataViewsServiceFactory = (deps: DataViewsServiceFactoryDeps) =>
|
|||
: request
|
||||
? (await capabilities.resolveCapabilities(request)).advancedSettings.save === true
|
||||
: false,
|
||||
scriptedFieldsEnabled: deps.scriptedFieldsEnabled,
|
||||
});
|
||||
};
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { schema, TypeOf } from '@kbn/config-schema';
|
||||
import type { PluginConfigDescriptor } from '@kbn/core/server';
|
||||
export { getFieldByName, findIndexPatternById } from './utils';
|
||||
export type { FieldDescriptor, RollupIndexCapability } from './fetcher';
|
||||
export { IndexPatternsFetcher, getCapabilitiesForRollupIndices } from './fetcher';
|
||||
|
@ -36,6 +38,24 @@ export type {
|
|||
};
|
||||
export { DataViewsServerPlugin as Plugin };
|
||||
|
||||
const configSchema = schema.object({
|
||||
scriptedFieldsEnabled: schema.conditional(
|
||||
schema.contextRef('serverless'),
|
||||
true,
|
||||
schema.boolean({ defaultValue: false }),
|
||||
schema.never()
|
||||
),
|
||||
});
|
||||
|
||||
type ConfigType = TypeOf<typeof configSchema>;
|
||||
|
||||
export const config: PluginConfigDescriptor<ConfigType> = {
|
||||
schema: configSchema,
|
||||
exposeToBrowser: {
|
||||
scriptedFieldsEnabled: true,
|
||||
},
|
||||
};
|
||||
|
||||
export {
|
||||
SERVICE_PATH,
|
||||
SERVICE_PATH_LEGACY,
|
||||
|
|
|
@ -12,6 +12,7 @@ export function createIndexPatternsStartMock() {
|
|||
const dataViewsServiceFactory = jest.fn().mockResolvedValue({ get: jest.fn() });
|
||||
return {
|
||||
dataViewsServiceFactory,
|
||||
getScriptedFieldsEnabled: jest.fn().mockReturnValue(true),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import { getIndexPatternLoad } from './expressions';
|
|||
import { registerIndexPatternsUsageCollector } from './register_index_pattern_usage_collection';
|
||||
import { createScriptedFieldsDeprecationsConfig } from './deprecations';
|
||||
import { DATA_VIEW_SAVED_OBJECT_TYPE, LATEST_VERSION } from '../common';
|
||||
import type { ClientConfigType } from '../common/types';
|
||||
import {
|
||||
DataViewsServerPluginSetup,
|
||||
DataViewsServerPluginStart,
|
||||
|
@ -35,7 +36,7 @@ export class DataViewsServerPlugin
|
|||
private readonly logger: Logger;
|
||||
private rollupsEnabled: boolean = false;
|
||||
|
||||
constructor(initializerContext: PluginInitializerContext) {
|
||||
constructor(private readonly initializerContext: PluginInitializerContext) {
|
||||
this.logger = initializerContext.logger.get('dataView');
|
||||
}
|
||||
|
||||
|
@ -75,16 +76,21 @@ export class DataViewsServerPlugin
|
|||
{ uiSettings, capabilities }: CoreStart,
|
||||
{ fieldFormats }: DataViewsServerPluginStartDependencies
|
||||
) {
|
||||
const config = this.initializerContext.config.get<ClientConfigType>();
|
||||
const scriptedFieldsEnabled = config.scriptedFieldsEnabled === false ? false : true; // accounting for null value
|
||||
|
||||
const serviceFactory = dataViewsServiceFactory({
|
||||
logger: this.logger.get('indexPatterns'),
|
||||
uiSettings,
|
||||
fieldFormats,
|
||||
capabilities,
|
||||
scriptedFieldsEnabled,
|
||||
rollupsEnabled: this.rollupsEnabled,
|
||||
});
|
||||
|
||||
return {
|
||||
dataViewsServiceFactory: serviceFactory,
|
||||
getScriptedFieldsEnabled: () => scriptedFieldsEnabled,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,10 @@ export interface DataViewsServerPluginStart {
|
|||
* Returns a DataViews service instance
|
||||
*/
|
||||
dataViewsServiceFactory: ServiceFactory;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
getScriptedFieldsEnabled: () => boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -60,6 +60,7 @@ describe('saved_searches_utils', () => {
|
|||
},
|
||||
"getConfig": [MockFunction],
|
||||
"onResponse": [MockFunction],
|
||||
"scriptedFieldsEnabled": true,
|
||||
"search": [MockFunction],
|
||||
},
|
||||
"fields": Object {},
|
||||
|
|
|
@ -23,7 +23,7 @@ declare global {
|
|||
}
|
||||
|
||||
const EXPOSED_CONFIG_SETTINGS_ERROR =
|
||||
'Actual config settings exposed to the browser do not match what is expected; this assertion fails if extra settings are present and/or expected settings are missing';
|
||||
'Actual config settings exposed to the browser do not match list defined in test; this assertion fails if extra settings are present and/or expected settings are missing';
|
||||
|
||||
export default function ({ getService }: PluginFunctionalProviderContext) {
|
||||
const appsMenu = getService('appsMenu');
|
||||
|
@ -104,6 +104,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
|
|||
'data.search.sessions.management.refreshTimeout (duration)',
|
||||
'data.search.sessions.maxUpdateRetries (number)',
|
||||
'data.search.sessions.notTouchedTimeout (duration)',
|
||||
'data_views.scriptedFieldsEnabled (any)', // It's a boolean (any because schema.conditional)
|
||||
'dev_tools.deeplinks.navLinkStatus (string)',
|
||||
'enterpriseSearch.canDeployEntSearch (boolean)',
|
||||
'enterpriseSearch.host (string)',
|
||||
|
|
|
@ -270,6 +270,7 @@ describe('Alerting Plugin', () => {
|
|||
dataViewsServiceFactory: jest
|
||||
.fn()
|
||||
.mockResolvedValue(dataViewPluginMocks.createStartContract()),
|
||||
getScriptedFieldsEnabled: jest.fn().mockReturnValue(true),
|
||||
} as DataViewsServerPluginStart,
|
||||
});
|
||||
|
||||
|
@ -318,6 +319,7 @@ describe('Alerting Plugin', () => {
|
|||
dataViewsServiceFactory: jest
|
||||
.fn()
|
||||
.mockResolvedValue(dataViewPluginMocks.createStartContract()),
|
||||
getScriptedFieldsEnabled: jest.fn().mockReturnValue(true),
|
||||
} as DataViewsServerPluginStart,
|
||||
});
|
||||
|
||||
|
@ -377,6 +379,7 @@ describe('Alerting Plugin', () => {
|
|||
dataViewsServiceFactory: jest
|
||||
.fn()
|
||||
.mockResolvedValue(dataViewPluginMocks.createStartContract()),
|
||||
getScriptedFieldsEnabled: jest.fn().mockReturnValue(true),
|
||||
} as DataViewsServerPluginStart,
|
||||
});
|
||||
|
||||
|
|
|
@ -133,6 +133,7 @@ describe('Task Runner', () => {
|
|||
const inMemoryMetrics = inMemoryMetricsMock.create();
|
||||
const dataViewsMock = {
|
||||
dataViewsServiceFactory: jest.fn().mockResolvedValue(dataViewPluginMocks.createStartContract()),
|
||||
getScriptedFieldsEnabled: jest.fn().mockReturnValue(true),
|
||||
} as DataViewsServerPluginStart;
|
||||
const alertsService = alertsServiceMock.create();
|
||||
const maintenanceWindowClient = maintenanceWindowClientMock.create();
|
||||
|
|
|
@ -129,6 +129,7 @@ describe('Task Runner', () => {
|
|||
const inMemoryMetrics = inMemoryMetricsMock.create();
|
||||
const dataViewsMock = {
|
||||
dataViewsServiceFactory: jest.fn().mockResolvedValue(dataViewPluginMocks.createStartContract()),
|
||||
getScriptedFieldsEnabled: jest.fn().mockReturnValue(true),
|
||||
} as DataViewsServerPluginStart;
|
||||
const mockAlertsService = alertsServiceMock.create();
|
||||
const mockAlertsClient = alertsClientMock.create();
|
||||
|
|
|
@ -76,6 +76,7 @@ const alertingEventLogger = alertingEventLoggerMock.create();
|
|||
const logger: ReturnType<typeof loggingSystemMock.createLogger> = loggingSystemMock.createLogger();
|
||||
const dataViewsMock = {
|
||||
dataViewsServiceFactory: jest.fn().mockResolvedValue(dataViewPluginMocks.createStartContract()),
|
||||
getScriptedFieldsEnabled: jest.fn().mockReturnValue(true),
|
||||
} as DataViewsServerPluginStart;
|
||||
const alertsService = alertsServiceMock.create();
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ const elasticsearchService = elasticsearchServiceMock.createInternalStart();
|
|||
const dataPlugin = dataPluginMock.createStartContract();
|
||||
const dataViewsMock = {
|
||||
dataViewsServiceFactory: jest.fn().mockResolvedValue(dataViewPluginMocks.createStartContract()),
|
||||
getScriptedFieldsEnabled: jest.fn().mockReturnValue(true),
|
||||
} as DataViewsServerPluginStart;
|
||||
const ruleType: UntypedNormalizedRuleType = {
|
||||
id: 'test',
|
||||
|
|
|
@ -13,6 +13,7 @@ export default function ({ loadTestFile }: FtrProviderContext) {
|
|||
loadTestFile(require.resolve('./spaces'));
|
||||
loadTestFile(require.resolve('./security_response_headers'));
|
||||
loadTestFile(require.resolve('./rollups'));
|
||||
loadTestFile(require.resolve('./scripted_fields'));
|
||||
loadTestFile(require.resolve('./index_management'));
|
||||
loadTestFile(require.resolve('./alerting'));
|
||||
loadTestFile(require.resolve('./ingest_pipelines'));
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import expect from 'expect';
|
||||
import { DATA_VIEW_PATH } from '@kbn/data-views-plugin/server';
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
|
||||
describe('scripted fields disabled', function () {
|
||||
before(async () => {
|
||||
await esArchiver.load('test/api_integration/fixtures/es_archiver/index_patterns/basic_index');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload(
|
||||
'test/api_integration/fixtures/es_archiver/index_patterns/basic_index'
|
||||
);
|
||||
});
|
||||
it('scripted fields are ignored when disabled', async () => {
|
||||
const response = await supertest
|
||||
.post(DATA_VIEW_PATH)
|
||||
.set('kbn-xsrf', 'some-xsrf-token')
|
||||
.send({
|
||||
data_view: {
|
||||
title: 'basic_index',
|
||||
fields: {
|
||||
foo_scripted: {
|
||||
name: 'foo_scripted',
|
||||
type: 'string',
|
||||
scripted: true,
|
||||
script: "doc['field_name'].value",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.body.data_view.fields.foo_scripted).toBeUndefined();
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import expect from 'expect';
|
||||
import { DATA_VIEW_PATH } from '@kbn/data-views-plugin/server';
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
const archivePath = 'test/api_integration/fixtures/es_archiver/index_patterns/basic_index';
|
||||
|
||||
export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
||||
const PageObjects = getPageObjects(['settings', 'common', 'header']);
|
||||
const esArchiver = getService('esArchiver');
|
||||
const supertest = getService('supertest');
|
||||
const testSubjects = getService('testSubjects');
|
||||
|
||||
describe('Data View Management', function () {
|
||||
let dataViewId = '';
|
||||
|
||||
before(async () => {
|
||||
await esArchiver.load(archivePath);
|
||||
|
||||
const response = await supertest
|
||||
.post(DATA_VIEW_PATH)
|
||||
.set('kbn-xsrf', 'some-xsrf-token')
|
||||
.send({
|
||||
data_view: {
|
||||
title: 'basic_index',
|
||||
},
|
||||
override: true,
|
||||
});
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
dataViewId = response.body.data_view.id;
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload(archivePath);
|
||||
await supertest.delete(`${DATA_VIEW_PATH}/${dataViewId}`).set('kbn-xsrf', 'some-xsrf-token');
|
||||
});
|
||||
|
||||
it('Scripted fields tab is missing', async () => {
|
||||
await PageObjects.common.navigateToUrl('management', 'kibana/dataViews', {
|
||||
shouldUseHashForSubUrl: false,
|
||||
});
|
||||
await testSubjects.click('detail-link-basic_index');
|
||||
await testSubjects.exists('tab-indexedFields');
|
||||
await testSubjects.missingOrFail('tab-scriptedFields');
|
||||
});
|
||||
});
|
||||
}
|
|
@ -17,5 +17,8 @@ export default function ({ loadTestFile }: FtrProviderContext) {
|
|||
|
||||
// Management
|
||||
loadTestFile(require.resolve('./index_management'));
|
||||
|
||||
// Data View Management
|
||||
loadTestFile(require.resolve('./data_view_mgmt'));
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue