= ({
{
field: 'packageTitle',
name: i18n.translate(
- 'xpack.ingestManager.configDetails.datasourcesTable.packageNameColumnTitle',
+ 'xpack.ingestManager.configDetails.packageConfigsTable.packageNameColumnTitle',
{
defaultMessage: 'Integration',
}
),
- render(packageTitle: string, datasource: InMemoryDatasource) {
+ render(packageTitle: string, packageConfig: InMemoryPackageConfig) {
return (
- {datasource.package && (
+ {packageConfig.package && (
@@ -159,24 +164,24 @@ export const DatasourcesTable: React.FunctionComponent = ({
{
field: 'namespace',
name: i18n.translate(
- 'xpack.ingestManager.configDetails.datasourcesTable.namespaceColumnTitle',
+ 'xpack.ingestManager.configDetails.packageConfigsTable.namespaceColumnTitle',
{
defaultMessage: 'Namespace',
}
),
- render: (namespace: InMemoryDatasource['namespace']) => {
+ render: (namespace: InMemoryPackageConfig['namespace']) => {
return namespace ? {namespace} : '';
},
},
{
field: 'streams',
name: i18n.translate(
- 'xpack.ingestManager.configDetails.datasourcesTable.streamsCountColumnTitle',
+ 'xpack.ingestManager.configDetails.packageConfigsTable.streamsCountColumnTitle',
{
defaultMessage: 'Streams',
}
),
- render: (streams: InMemoryDatasource['streams']) => {
+ render: (streams: InMemoryPackageConfig['streams']) => {
return (
<>
{streams.enabled}
@@ -187,67 +192,67 @@ export const DatasourcesTable: React.FunctionComponent = ({
},
{
name: i18n.translate(
- 'xpack.ingestManager.configDetails.datasourcesTable.actionsColumnTitle',
+ 'xpack.ingestManager.configDetails.packageConfigsTable.actionsColumnTitle',
{
defaultMessage: 'Actions',
}
),
actions: [
{
- render: (datasource: InMemoryDatasource) => (
+ render: (packageConfig: InMemoryPackageConfig) => (
{}}
- // key="datasourceView"
+ // key="packageConfigView"
// >
//
// ,
,
- // FIXME: implement Copy datasource action
- // {}} key="datasourceCopy">
+ // FIXME: implement Copy package config action
+ // {}} key="packageConfigCopy">
//
// ,
-
- {(deleteDatasourcePrompt) => {
+
+ {(deletePackageConfigsPrompt) => {
return (
{
- deleteDatasourcePrompt([datasource.id], refreshConfig);
+ deletePackageConfigsPrompt([packageConfig.id], refreshConfig);
}}
>
);
}}
- ,
+ ,
]}
/>
),
@@ -259,9 +264,9 @@ export const DatasourcesTable: React.FunctionComponent = ({
);
return (
-
+
itemId="id"
- items={datasources}
+ items={packageConfigs}
columns={columns}
sorting={{
sort: {
@@ -273,14 +278,14 @@ export const DatasourcesTable: React.FunctionComponent = ({
search={{
toolsRight: [
,
],
diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/index.tsx
index eaa161d57bbe4..4ae16eb91e582 100644
--- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/index.tsx
+++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/index.tsx
@@ -28,7 +28,7 @@ import { Loading } from '../../../components';
import { WithHeaderLayout } from '../../../layouts';
import { ConfigRefreshContext, useGetAgentStatus, AgentStatusRefreshContext } from './hooks';
import { LinkedAgentCount, AgentConfigActionMenu } from '../components';
-import { ConfigDatasourcesView, ConfigSettingsView } from './components';
+import { ConfigPackageConfigsView, ConfigSettingsView } from './components';
import { useIntraAppState } from '../../../hooks/use_intra_app_state';
const Divider = styled.div`
@@ -120,13 +120,16 @@ export const AgentConfigDetailsPage: React.FunctionComponent = () => {
},
{ isDivider: true },
{
- label: i18n.translate('xpack.ingestManager.configDetails.summary.datasources', {
- defaultMessage: 'Data sources',
+ label: i18n.translate('xpack.ingestManager.configDetails.summary.package_configs', {
+ defaultMessage: 'Integrations',
}),
content: (
),
@@ -204,12 +207,12 @@ export const AgentConfigDetailsPage: React.FunctionComponent = () => {
const headerTabs = useMemo(() => {
return [
{
- id: 'datasources',
- name: i18n.translate('xpack.ingestManager.configDetails.subTabs.datasourcesTabText', {
- defaultMessage: 'Data sources',
+ id: 'integrations',
+ name: i18n.translate('xpack.ingestManager.configDetails.subTabs.packageConfigsTabText', {
+ defaultMessage: 'Integrations',
}),
- href: getHref('configuration_details', { configId, tabId: 'datasources' }),
- isSelected: tabId === '' || tabId === 'datasources',
+ href: getHref('configuration_details', { configId, tabId: 'integrations' }),
+ isSelected: tabId === '' || tabId === 'integrations',
},
{
id: 'settings',
@@ -292,7 +295,7 @@ const AgentConfigDetailsContent: React.FunctionComponent<{ agentConfig: AgentCon
{
- return ;
+ return ;
}}
/>
diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/edit_datasource_page/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/edit_package_config_page/index.tsx
similarity index 64%
rename from x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/edit_datasource_page/index.tsx
rename to x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/edit_package_config_page/index.tsx
index af39cb87f18c9..7fbcdbb9738cb 100644
--- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/edit_datasource_page/index.tsx
+++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/edit_package_config_page/index.tsx
@@ -16,31 +16,34 @@ import {
EuiFlexItem,
EuiSpacer,
} from '@elastic/eui';
-import { AgentConfig, PackageInfo, NewDatasource } from '../../../types';
+import { AgentConfig, PackageInfo, NewPackageConfig } from '../../../types';
import {
useLink,
useBreadcrumbs,
useCore,
useConfig,
- sendUpdateDatasource,
+ sendUpdatePackageConfig,
sendGetAgentStatus,
sendGetOneAgentConfig,
- sendGetOneDatasource,
+ sendGetOnePackageConfig,
sendGetPackageInfoByKey,
} from '../../../hooks';
import { Loading, Error } from '../../../components';
import { ConfirmDeployConfigModal } from '../components';
-import { CreateDatasourcePageLayout } from '../create_datasource_page/components';
+import { CreatePackageConfigPageLayout } from '../create_package_config_page/components';
import {
- DatasourceValidationResults,
- validateDatasource,
+ PackageConfigValidationResults,
+ validatePackageConfig,
validationHasErrors,
-} from '../create_datasource_page/services';
-import { DatasourceFormState, CreateDatasourceFrom } from '../create_datasource_page/types';
-import { StepConfigureDatasource } from '../create_datasource_page/step_configure_datasource';
-import { StepDefineDatasource } from '../create_datasource_page/step_define_datasource';
+} from '../create_package_config_page/services';
+import {
+ PackageConfigFormState,
+ CreatePackageConfigFrom,
+} from '../create_package_config_page/types';
+import { StepConfigurePackage } from '../create_package_config_page/step_configure_package';
+import { StepDefinePackageConfig } from '../create_package_config_page/step_define_package_config';
-export const EditDatasourcePage: React.FunctionComponent = () => {
+export const EditPackageConfigPage: React.FunctionComponent = () => {
const {
notifications,
chrome: { getIsNavDrawerLocked$ },
@@ -50,7 +53,7 @@ export const EditDatasourcePage: React.FunctionComponent = () => {
fleet: { enabled: isFleetEnabled },
} = useConfig();
const {
- params: { configId, datasourceId },
+ params: { configId, packageConfigId },
} = useRouteMatch();
const history = useHistory();
const { getHref, getPath } = useLink();
@@ -64,34 +67,35 @@ export const EditDatasourcePage: React.FunctionComponent = () => {
return () => subscription.unsubscribe();
});
- // Agent config, package info, and datasource states
+ // Agent config, package info, and package config states
const [isLoadingData, setIsLoadingData] = useState(true);
const [loadingError, setLoadingError] = useState();
const [agentConfig, setAgentConfig] = useState();
const [packageInfo, setPackageInfo] = useState();
- const [datasource, setDatasource] = useState({
+ const [packageConfig, setPackageConfig] = useState({
name: '',
description: '',
+ namespace: '',
config_id: '',
enabled: true,
output_id: '',
inputs: [],
});
- // Retrieve agent config, package, and datasource info
+ // Retrieve agent config, package, and package config info
useEffect(() => {
const getData = async () => {
setIsLoadingData(true);
setLoadingError(undefined);
try {
- const [{ data: agentConfigData }, { data: datasourceData }] = await Promise.all([
+ const [{ data: agentConfigData }, { data: packageConfigData }] = await Promise.all([
sendGetOneAgentConfig(configId),
- sendGetOneDatasource(datasourceId),
+ sendGetOnePackageConfig(packageConfigId),
]);
if (agentConfigData?.item) {
setAgentConfig(agentConfigData.item);
}
- if (datasourceData?.item) {
+ if (packageConfigData?.item) {
const {
id,
revision,
@@ -100,30 +104,30 @@ export const EditDatasourcePage: React.FunctionComponent = () => {
created_at,
updated_by,
updated_at,
- ...restOfDatasource
- } = datasourceData.item;
- // Remove `agent_stream` from all stream info, we assign this after saving
- const newDatasource = {
- ...restOfDatasource,
+ ...restOfPackageConfig
+ } = packageConfigData.item;
+ // Remove `compiled_stream` from all stream info, we assign this after saving
+ const newPackageConfig = {
+ ...restOfPackageConfig,
inputs: inputs.map((input) => {
const { streams, ...restOfInput } = input;
return {
...restOfInput,
streams: streams.map((stream) => {
- const { agent_stream, ...restOfStream } = stream;
+ const { compiled_stream, ...restOfStream } = stream;
return restOfStream;
}),
};
}),
};
- setDatasource(newDatasource);
- if (datasourceData.item.package) {
+ setPackageConfig(newPackageConfig);
+ if (packageConfigData.item.package) {
const { data: packageData } = await sendGetPackageInfoByKey(
- `${datasourceData.item.package.name}-${datasourceData.item.package.version}`
+ `${packageConfigData.item.package.name}-${packageConfigData.item.package.version}`
);
if (packageData?.response) {
setPackageInfo(packageData.response);
- setValidationResults(validateDatasource(newDatasource, packageData.response));
+ setValidationResults(validatePackageConfig(newPackageConfig, packageData.response));
setFormState('VALID');
}
}
@@ -134,7 +138,7 @@ export const EditDatasourcePage: React.FunctionComponent = () => {
setIsLoadingData(false);
};
getData();
- }, [configId, datasourceId]);
+ }, [configId, packageConfigId]);
// Retrieve agent count
const [agentCount, setAgentCount] = useState(0);
@@ -151,21 +155,21 @@ export const EditDatasourcePage: React.FunctionComponent = () => {
}
}, [configId, isFleetEnabled]);
- // Datasource validation state
- const [validationResults, setValidationResults] = useState();
+ // Package config validation state
+ const [validationResults, setValidationResults] = useState();
const hasErrors = validationResults ? validationHasErrors(validationResults) : false;
- // Update datasource method
- const updateDatasource = (updatedFields: Partial) => {
- const newDatasource = {
- ...datasource,
+ // Update package config method
+ const updatePackageConfig = (updatedFields: Partial) => {
+ const newPackageConfig = {
+ ...packageConfig,
...updatedFields,
};
- setDatasource(newDatasource);
+ setPackageConfig(newPackageConfig);
// eslint-disable-next-line no-console
- console.debug('Datasource updated', newDatasource);
- const newValidationResults = updateDatasourceValidation(newDatasource);
+ console.debug('Package config updated', newPackageConfig);
+ const newValidationResults = updatePackageConfigValidation(newPackageConfig);
const hasValidationErrors = newValidationResults
? validationHasErrors(newValidationResults)
: false;
@@ -174,12 +178,15 @@ export const EditDatasourcePage: React.FunctionComponent = () => {
}
};
- const updateDatasourceValidation = (newDatasource?: NewDatasource) => {
+ const updatePackageConfigValidation = (newPackageConfig?: NewPackageConfig) => {
if (packageInfo) {
- const newValidationResult = validateDatasource(newDatasource || datasource, packageInfo);
+ const newValidationResult = validatePackageConfig(
+ newPackageConfig || packageConfig,
+ packageInfo
+ );
setValidationResults(newValidationResult);
// eslint-disable-next-line no-console
- console.debug('Datasource validation results', newValidationResult);
+ console.debug('Package config validation results', newValidationResult);
return newValidationResult;
}
@@ -188,11 +195,11 @@ export const EditDatasourcePage: React.FunctionComponent = () => {
// Cancel url
const cancelUrl = getHref('configuration_details', { configId });
- // Save datasource
- const [formState, setFormState] = useState('INVALID');
- const saveDatasource = async () => {
+ // Save package config
+ const [formState, setFormState] = useState('INVALID');
+ const savePackageConfig = async () => {
setFormState('LOADING');
- const result = await sendUpdateDatasource(datasourceId, datasource);
+ const result = await sendUpdatePackageConfig(packageConfigId, packageConfig);
setFormState('SUBMITTED');
return result;
};
@@ -206,19 +213,19 @@ export const EditDatasourcePage: React.FunctionComponent = () => {
setFormState('CONFIRM');
return;
}
- const { error } = await saveDatasource();
+ const { error } = await savePackageConfig();
if (!error) {
history.push(getPath('configuration_details', { configId }));
notifications.toasts.addSuccess({
- title: i18n.translate('xpack.ingestManager.editDatasource.updatedNotificationTitle', {
- defaultMessage: `Successfully updated '{datasourceName}'`,
+ title: i18n.translate('xpack.ingestManager.editPackageConfig.updatedNotificationTitle', {
+ defaultMessage: `Successfully updated '{packageConfigName}'`,
values: {
- datasourceName: datasource.name,
+ packageConfigName: packageConfig.name,
},
}),
text:
agentCount && agentConfig
- ? i18n.translate('xpack.ingestManager.editDatasource.updatedNotificationMessage', {
+ ? i18n.translate('xpack.ingestManager.editPackageConfig.updatedNotificationMessage', {
defaultMessage: `Fleet will deploy updates to all agents that use the '{agentConfigName}' configuration`,
values: {
agentConfigName: agentConfig.name,
@@ -235,28 +242,28 @@ export const EditDatasourcePage: React.FunctionComponent = () => {
};
const layoutProps = {
- from: 'edit' as CreateDatasourceFrom,
+ from: 'edit' as CreatePackageConfigFrom,
cancelUrl,
agentConfig,
packageInfo,
};
return (
-
+
{isLoadingData ? (
) : loadingError || !agentConfig || !packageInfo ? (
}
error={
loadingError ||
- i18n.translate('xpack.ingestManager.editDatasource.errorLoadingDataMessage', {
- defaultMessage: 'There was an error loading this data source information',
+ i18n.translate('xpack.ingestManager.editPackageConfig.errorLoadingDataMessage', {
+ defaultMessage: 'There was an error loading this intergration information',
})
}
/>
@@ -275,35 +282,35 @@ export const EditDatasourcePage: React.FunctionComponent = () => {
steps={[
{
title: i18n.translate(
- 'xpack.ingestManager.editDatasource.stepDefineDatasourceTitle',
+ 'xpack.ingestManager.editPackageConfig.stepDefinePackageConfigTitle',
{
- defaultMessage: 'Define your data source',
+ defaultMessage: 'Define your integration',
}
),
children: (
-
),
},
{
title: i18n.translate(
- 'xpack.ingestManager.editDatasource.stepConfgiureDatasourceTitle',
+ 'xpack.ingestManager.editPackageConfig.stepConfigurePackageConfigTitle',
{
defaultMessage: 'Select the data you want to collect',
}
),
children: (
-
@@ -326,7 +333,7 @@ export const EditDatasourcePage: React.FunctionComponent = () => {
@@ -341,8 +348,8 @@ export const EditDatasourcePage: React.FunctionComponent = () => {
fill
>
@@ -350,7 +357,7 @@ export const EditDatasourcePage: React.FunctionComponent = () => {
>
)}
-
+
);
};
@@ -358,6 +365,6 @@ const Breadcrumb: React.FunctionComponent<{ configName: string; configId: string
configName,
configId,
}) => {
- useBreadcrumbs('edit_datasource', { configName, configId });
+ useBreadcrumbs('edit_integration', { configName, configId });
return null;
};
diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/index.tsx
index 74fa67078f741..727ef23347251 100644
--- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/index.tsx
+++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/index.tsx
@@ -9,8 +9,8 @@ import { PAGE_ROUTING_PATHS } from '../../constants';
import { useBreadcrumbs } from '../../hooks';
import { AgentConfigListPage } from './list_page';
import { AgentConfigDetailsPage } from './details_page';
-import { CreateDatasourcePage } from './create_datasource_page';
-import { EditDatasourcePage } from './edit_datasource_page';
+import { CreatePackageConfigPage } from './create_package_config_page';
+import { EditPackageConfigPage } from './edit_package_config_page';
export const AgentConfigApp: React.FunctionComponent = () => {
useBreadcrumbs('configurations');
@@ -18,11 +18,11 @@ export const AgentConfigApp: React.FunctionComponent = () => {
return (
-
-
+
+
-
-
+
+
diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/list_page/components/create_config.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/list_page/components/create_config.tsx
index f746fadc4b0a3..d1abd88adba86 100644
--- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/list_page/components/create_config.tsx
+++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/list_page/components/create_config.tsx
@@ -64,7 +64,7 @@ export const CreateAgentConfigFlyout: React.FunctionComponent = ({ onClos
diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/list_page/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/list_page/index.tsx
index 8b1ff0988d443..0a9daf0038aab 100644
--- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/list_page/index.tsx
+++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/list_page/index.tsx
@@ -176,12 +176,13 @@ export const AgentConfigListPage: React.FunctionComponent<{}> = () => {
),
},
{
- field: 'datasources',
- name: i18n.translate('xpack.ingestManager.agentConfigList.datasourcesCountColumnTitle', {
- defaultMessage: 'Data sources',
+ field: 'package_configs',
+ name: i18n.translate('xpack.ingestManager.agentConfigList.packageConfigsCountColumnTitle', {
+ defaultMessage: 'Integrations',
}),
dataType: 'number',
- render: (datasources: AgentConfig['datasources']) => (datasources ? datasources.length : 0),
+ render: (packageConfigs: AgentConfig['package_configs']) =>
+ packageConfigs ? packageConfigs.length : 0,
},
{
name: i18n.translate('xpack.ingestManager.agentConfigList.actionsColumnTitle', {
diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/index.tsx
index ca1a8df534044..cb0664143bb34 100644
--- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/index.tsx
+++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/index.tsx
@@ -8,7 +8,7 @@ import React from 'react';
import { HashRouter as Router, Switch, Route } from 'react-router-dom';
import { PAGE_ROUTING_PATHS } from '../../constants';
import { useConfig, useBreadcrumbs } from '../../hooks';
-import { CreateDatasourcePage } from '../agent_config/create_datasource_page';
+import { CreatePackageConfigPage } from '../agent_config/create_package_config_page';
import { EPMHomePage } from './screens/home';
import { Detail } from './screens/detail';
@@ -19,8 +19,8 @@ export const EPMApp: React.FunctionComponent = () => {
return epm.enabled ? (
-
-
+
+
diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/content.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/content.tsx
index 96aebb08e0c63..c9a8cabdf414b 100644
--- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/content.tsx
+++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/content.tsx
@@ -4,17 +4,16 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule, EuiSpacer } from '@elastic/eui';
+import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui';
import React from 'react';
import styled from 'styled-components';
import { DEFAULT_PANEL, DetailParams } from '.';
import { PackageInfo } from '../../../../types';
import { AssetsFacetGroup } from '../../components/assets_facet_group';
-import { Requirements } from '../../components/requirements';
import { CenterColumn, LeftColumn, RightColumn } from './layout';
import { OverviewPanel } from './overview_panel';
import { SideNavLinks } from './side_nav_links';
-import { DataSourcesPanel } from './data_sources_panel';
+import { PackageConfigsPanel } from './package_configs_panel';
import { SettingsPanel } from './settings_panel';
type ContentProps = PackageInfo & Pick & { hasIconPanel: boolean };
@@ -63,8 +62,8 @@ export function ContentPanel(props: ContentPanelProps) {
latestVersion={latestVersion}
/>
);
- case 'data-sources':
- return ;
+ case 'usages':
+ return ;
case 'overview':
default:
return ;
@@ -73,17 +72,11 @@ export function ContentPanel(props: ContentPanelProps) {
type RightColumnContentProps = PackageInfo & Pick;
function RightColumnContent(props: RightColumnContentProps) {
- const { assets, requirement, panel } = props;
+ const { assets, panel } = props;
switch (panel) {
case 'overview':
return (
-
-
-
-
-
-
diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/header.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/header.tsx
index db046d18ccebc..875a8f5c5c127 100644
--- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/header.tsx
+++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/header.tsx
@@ -70,10 +70,10 @@ export function Header(props: HeaderProps) {
{
+export const PackageConfigsPanel = ({ name, version }: PackageConfigsPanelProps) => {
const { getPath } = useLink();
const getPackageInstallStatus = useGetPackageInstallStatus();
const packageInstallStatus = getPackageInstallStatus(name);
@@ -23,11 +22,5 @@ export const DataSourcesPanel = ({ name, version }: DataSourcesPanelProps) => {
// this happens if they arrive with a direct url or they uninstall while on this tab
if (packageInstallStatus.status !== InstallStatus.installed)
return ;
- return (
-
-
- Data Sources
-
-
- );
+ return null;
};
diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/settings_panel.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/settings_panel.tsx
index 986b946131e33..125289ce3ee8d 100644
--- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/settings_panel.tsx
+++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/settings_panel.tsx
@@ -10,8 +10,8 @@ import { EuiTitle, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui';
import { EuiSpacer } from '@elastic/eui';
import styled from 'styled-components';
import { InstallStatus, PackageInfo } from '../../../../types';
-import { useGetDatasources } from '../../../../hooks';
-import { DATASOURCE_SAVED_OBJECT_TYPE } from '../../../../constants';
+import { useGetPackageConfigs } from '../../../../hooks';
+import { PACKAGE_CONFIG_SAVED_OBJECT_TYPE } from '../../../../constants';
import { useGetPackageInstallStatus } from '../../hooks';
import { InstallationButton } from './installation_button';
import { UpdateIcon } from '../../components/icons';
@@ -46,13 +46,13 @@ export const SettingsPanel = (
) => {
const { name, title, removable, latestVersion, version } = props;
const getPackageInstallStatus = useGetPackageInstallStatus();
- const { data: datasourcesData } = useGetDatasources({
+ const { data: packageConfigsData } = useGetPackageConfigs({
perPage: 0,
page: 1,
- kuery: `${DATASOURCE_SAVED_OBJECT_TYPE}.package.name:${props.name}`,
+ kuery: `${PACKAGE_CONFIG_SAVED_OBJECT_TYPE}.package.name:${props.name}`,
});
const { status: installationStatus, version: installedVersion } = getPackageInstallStatus(name);
- const packageHasDatasources = !!datasourcesData?.total;
+ const packageHasUsages = !!packageConfigsData?.total;
const updateAvailable = installedVersion && installedVersion < latestVersion ? true : false;
const isViewingOldPackage = version < latestVersion;
// hide install/remove options if the user has version of the package is installed
@@ -185,16 +185,16 @@ export const SettingsPanel = (
- {packageHasDatasources && removable === true && (
+ {packageHasUsages && removable === true && (
= {
overview: i18n.translate('xpack.ingestManager.epm.packageDetailsNav.overviewLinkText', {
defaultMessage: 'Overview',
}),
- 'data-sources': i18n.translate('xpack.ingestManager.epm.packageDetailsNav.datasourcesLinkText', {
- defaultMessage: 'Data sources',
+ usages: i18n.translate('xpack.ingestManager.epm.packageDetailsNav.packageConfigsLinkText', {
+ defaultMessage: 'Usages',
}),
settings: i18n.translate('xpack.ingestManager.epm.packageDetailsNav.settingsLinkText', {
defaultMessage: 'Settings',
@@ -43,12 +43,9 @@ export function SideNavLinks({ name, version, active }: NavLinkProps) {
? p.theme.eui.euiFontWeightSemiBold
: p.theme.eui.euiFontWeightRegular};
`;
- // Don't display Data Sources tab as we haven't implemented this yet
- // FIXME: Restore when we implement data sources page
- if (
- panel === 'data-sources' &&
- (true || packageInstallStatus.status !== InstallStatus.installed)
- )
+ // Don't display usages tab as we haven't implemented this yet
+ // FIXME: Restore when we implement usages page
+ if (panel === 'usages' && (true || packageInstallStatus.status !== InstallStatus.installed))
return null;
return (
diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_config_datasource_badges.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_config_package_badges.tsx
similarity index 68%
rename from x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_config_datasource_badges.tsx
rename to x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_config_package_badges.tsx
index 30bc9dc701427..fcdb5ff02e7a4 100644
--- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_config_datasource_badges.tsx
+++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_config_package_badges.tsx
@@ -6,7 +6,7 @@
import React from 'react';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiSpacer, EuiText, EuiFlexGroup, EuiFlexItem, EuiBadge } from '@elastic/eui';
-import { Datasource } from '../../../types';
+import { PackageConfig } from '../../../types';
import { useGetOneAgentConfig } from '../../../hooks';
import { PackageIcon } from '../../../components/package_icon';
@@ -14,7 +14,7 @@ interface Props {
agentConfigId: string;
}
-export const AgentConfigDatasourceBadges: React.FunctionComponent = ({ agentConfigId }) => {
+export const AgentConfigPackageBadges: React.FunctionComponent = ({ agentConfigId }) => {
const agentConfigRequest = useGetOneAgentConfig(agentConfigId);
const agentConfig = agentConfigRequest.data ? agentConfigRequest.data.item : null;
@@ -26,16 +26,16 @@ export const AgentConfigDatasourceBadges: React.FunctionComponent = ({ ag
{agentConfig.datasources.length},
+ count: agentConfig.package_configs.length,
+ countValue: {agentConfig.package_configs.length},
}}
/>
- {(agentConfig.datasources as Datasource[]).map((datasource, idx) => {
- if (!datasource.package) {
+ {(agentConfig.package_configs as PackageConfig[]).map((packageConfig, idx) => {
+ if (!packageConfig.package) {
return null;
}
return (
@@ -43,13 +43,13 @@ export const AgentConfigDatasourceBadges: React.FunctionComponent = ({ ag
- {datasource.package.title}
+ {packageConfig.package.title}
);
diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/config_selection.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/config_selection.tsx
index 6e7427c6ab55e..8cd337586d1bc 100644
--- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/config_selection.tsx
+++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/config_selection.tsx
@@ -10,7 +10,7 @@ import { FormattedMessage } from '@kbn/i18n/react';
import { EuiSelect, EuiSpacer, EuiText, EuiButtonEmpty } from '@elastic/eui';
import { AgentConfig } from '../../../../types';
import { useGetEnrollmentAPIKeys } from '../../../../hooks';
-import { AgentConfigDatasourceBadges } from '../agent_config_datasource_badges';
+import { AgentConfigPackageBadges } from '../agent_config_package_badges';
interface Props {
agentConfigs: AgentConfig[];
@@ -83,7 +83,7 @@ export const EnrollmentStepAgentConfig: React.FC = ({ agentConfigs, onKey
/>
{selectedState.agentConfigId && (
-
+
)}
void;
@@ -113,7 +113,7 @@ export const AgentReassignConfigFlyout: React.FunctionComponent = ({ onCl
{selectedAgentConfigId && (
-
+
)}
diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/overview/components/configuration_section.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/overview/components/configuration_section.tsx
index 68364f9acbbf9..ed4b3fc8e6a5d 100644
--- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/overview/components/configuration_section.tsx
+++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/overview/components/configuration_section.tsx
@@ -15,7 +15,7 @@ import {
} from '@elastic/eui';
import { OverviewPanel } from './overview_panel';
import { OverviewStats } from './overview_stats';
-import { useLink, useGetDatasources } from '../../../hooks';
+import { useLink, useGetPackageConfigs } from '../../../hooks';
import { AgentConfig } from '../../../types';
import { Loading } from '../../fleet/components';
@@ -23,7 +23,7 @@ export const OverviewConfigurationSection: React.FC<{ agentConfigs: AgentConfig[
agentConfigs,
}) => {
const { getHref } = useLink();
- const datasourcesRequest = useGetDatasources({
+ const packageConfigsRequest = useGetPackageConfigs({
page: 1,
perPage: 10000,
});
@@ -48,7 +48,7 @@ export const OverviewConfigurationSection: React.FC<{ agentConfigs: AgentConfig[
- {datasourcesRequest.isLoading ? (
+ {packageConfigsRequest.isLoading ? (
) : (
<>
@@ -63,12 +63,12 @@ export const OverviewConfigurationSection: React.FC<{ agentConfigs: AgentConfig[
-
+
>
)}
diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/services/index.ts b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/services/index.ts
index ece7aef2c247f..5dc9026aebdee 100644
--- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/services/index.ts
+++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/services/index.ts
@@ -8,7 +8,7 @@ export { getFlattenedObject } from '../../../../../../../src/core/public';
export {
agentConfigRouteService,
- datasourceRouteService,
+ packageConfigRouteService,
dataStreamRouteService,
fleetSetupRouteService,
agentRouteService,
@@ -18,8 +18,8 @@ export {
outputRoutesService,
settingsRoutesService,
appRoutesService,
- packageToConfigDatasourceInputs,
- storedDatasourcesToAgentInputs,
+ packageToPackageConfigInputs,
+ storedPackageConfigsToAgentInputs,
configToYaml,
AgentStatusKueryHelper,
} from '../../../../common';
diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/types/index.ts b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/types/index.ts
index 90315f38fd476..43ec2f6d1a74d 100644
--- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/types/index.ts
+++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/types/index.ts
@@ -13,11 +13,11 @@ export {
NewAgentConfig,
AgentEvent,
EnrollmentAPIKey,
- Datasource,
- NewDatasource,
- DatasourceInput,
- DatasourceInputStream,
- DatasourceConfigRecordEntry,
+ PackageConfig,
+ NewPackageConfig,
+ PackageConfigInput,
+ PackageConfigInputStream,
+ PackageConfigConfigRecordEntry,
Output,
DataStream,
// API schema - misc setup, status
@@ -35,11 +35,11 @@ export {
CopyAgentConfigResponse,
DeleteAgentConfigRequest,
DeleteAgentConfigResponse,
- // API schemas - Datasource
- CreateDatasourceRequest,
- CreateDatasourceResponse,
- UpdateDatasourceRequest,
- UpdateDatasourceResponse,
+ // API schemas - Package config
+ CreatePackageConfigRequest,
+ CreatePackageConfigResponse,
+ UpdatePackageConfigRequest,
+ UpdatePackageConfigResponse,
// API schemas - Data Streams
GetDataStreamsResponse,
// API schemas - Agents
diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/types/intra_app_route_state.ts b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/types/intra_app_route_state.ts
index c5833adcded5f..4fd770501ae3f 100644
--- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/types/intra_app_route_state.ts
+++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/types/intra_app_route_state.ts
@@ -5,16 +5,16 @@
*/
import { ApplicationStart } from 'kibana/public';
-import { Datasource } from '../../../../common/types/models';
+import { PackageConfig } from './';
/**
- * Supported routing state for the create datasource page routes
+ * Supported routing state for the create package config page routes
*/
-export interface CreateDatasourceRouteState {
- /** On a successful save of the datasource, use navigate to the given app */
+export interface CreatePackageConfigRouteState {
+ /** On a successful save of the package config, use navigate to the given app */
onSaveNavigateTo?:
| Parameters
- | ((newDatasource: Datasource) => Parameters);
+ | ((newPackageConfig: PackageConfig) => Parameters);
/** On cancel, navigate to the given app */
onCancelNavigateTo?: Parameters;
/** Url to be used on cancel links */
@@ -41,6 +41,6 @@ export interface AgentDetailsReassignConfigAction {
* All possible Route states.
*/
export type AnyIntraAppRouteState =
- | CreateDatasourceRouteState
+ | CreatePackageConfigRouteState
| AgentConfigDetailsDeployAgentAction
| AgentDetailsReassignConfigAction;
diff --git a/x-pack/plugins/ingest_manager/public/index.ts b/x-pack/plugins/ingest_manager/public/index.ts
index ac56349b30c13..866d17145b075 100644
--- a/x-pack/plugins/ingest_manager/public/index.ts
+++ b/x-pack/plugins/ingest_manager/public/index.ts
@@ -13,10 +13,10 @@ export const plugin = (initializerContext: PluginInitializerContext) => {
};
export {
- CustomConfigureDatasourceContent,
- CustomConfigureDatasourceProps,
- registerDatasource,
-} from './applications/ingest_manager/sections/agent_config/create_datasource_page/components/custom_configure_datasource';
+ CustomConfigurePackageConfigContent,
+ CustomConfigurePackageConfigProps,
+ registerPackageConfigComponent,
+} from './applications/ingest_manager/sections/agent_config/create_package_config_page/components/custom_package_config';
-export { NewDatasource } from './applications/ingest_manager/types';
+export { NewPackageConfig } from './applications/ingest_manager/types';
export * from './applications/ingest_manager/types/intra_app_route_state';
diff --git a/x-pack/plugins/ingest_manager/public/plugin.ts b/x-pack/plugins/ingest_manager/public/plugin.ts
index 4a10a26151e78..69dd5e42a0bc5 100644
--- a/x-pack/plugins/ingest_manager/public/plugin.ts
+++ b/x-pack/plugins/ingest_manager/public/plugin.ts
@@ -18,7 +18,7 @@ import { PLUGIN_ID, CheckPermissionsResponse, PostIngestSetupResponse } from '..
import { IngestManagerConfigType } from '../common/types';
import { setupRouteService, appRoutesService } from '../common';
-import { registerDatasource } from './applications/ingest_manager/sections/agent_config/create_datasource_page/components/custom_configure_datasource';
+import { registerPackageConfigComponent } from './applications/ingest_manager/sections/agent_config/create_package_config_page/components/custom_package_config';
export { IngestManagerConfigType } from '../common/types';
@@ -31,7 +31,7 @@ export interface IngestManagerSetup {}
* Describes public IngestManager plugin contract returned at the `start` stage.
*/
export interface IngestManagerStart {
- registerDatasource: typeof registerDatasource;
+ registerPackageConfigComponent: typeof registerPackageConfigComponent;
success: Promise;
}
@@ -102,7 +102,7 @@ export class IngestManagerPlugin
return {
success: successPromise,
- registerDatasource,
+ registerPackageConfigComponent,
};
}
diff --git a/x-pack/plugins/ingest_manager/server/constants/index.ts b/x-pack/plugins/ingest_manager/server/constants/index.ts
index ebcce6320ec4b..650211ce9c1b2 100644
--- a/x-pack/plugins/ingest_manager/server/constants/index.ts
+++ b/x-pack/plugins/ingest_manager/server/constants/index.ts
@@ -16,7 +16,7 @@ export {
PLUGIN_ID,
EPM_API_ROUTES,
DATA_STREAM_API_ROUTES,
- DATASOURCE_API_ROUTES,
+ PACKAGE_CONFIG_API_ROUTES,
AGENT_API_ROUTES,
AGENT_CONFIG_API_ROUTES,
FLEET_SETUP_API_ROUTES,
@@ -31,7 +31,7 @@ export {
AGENT_EVENT_SAVED_OBJECT_TYPE,
AGENT_ACTION_SAVED_OBJECT_TYPE,
AGENT_CONFIG_SAVED_OBJECT_TYPE,
- DATASOURCE_SAVED_OBJECT_TYPE,
+ PACKAGE_CONFIG_SAVED_OBJECT_TYPE,
OUTPUT_SAVED_OBJECT_TYPE,
PACKAGES_SAVED_OBJECT_TYPE,
INDEX_PATTERN_SAVED_OBJECT_TYPE,
diff --git a/x-pack/plugins/ingest_manager/server/index.ts b/x-pack/plugins/ingest_manager/server/index.ts
index 1e9011c9dfe4f..5d6a1ad321b6d 100644
--- a/x-pack/plugins/ingest_manager/server/index.ts
+++ b/x-pack/plugins/ingest_manager/server/index.ts
@@ -43,7 +43,7 @@ export const config = {
export type IngestManagerConfigType = TypeOf;
-export { DatasourceServiceInterface } from './services/datasource';
+export { PackageConfigServiceInterface } from './services/package_config';
export const plugin = (initializerContext: PluginInitializerContext) => {
return new IngestManagerPlugin(initializerContext);
diff --git a/x-pack/plugins/ingest_manager/server/integration_tests/router.test.ts b/x-pack/plugins/ingest_manager/server/integration_tests/router.test.ts
index bfd8428222643..9d671c629ef91 100644
--- a/x-pack/plugins/ingest_manager/server/integration_tests/router.test.ts
+++ b/x-pack/plugins/ingest_manager/server/integration_tests/router.test.ts
@@ -46,8 +46,8 @@ describe('ingestManager', () => {
await kbnTestServer.request.get(root, '/api/ingest_manager/agent_configs').expect(404);
});
- it('does not have datasources api', async () => {
- await kbnTestServer.request.get(root, '/api/ingest_manager/datasources').expect(404);
+ it('does not have package configs api', async () => {
+ await kbnTestServer.request.get(root, '/api/ingest_manager/package_configs').expect(404);
});
it('does not have EPM api', async () => {
@@ -79,8 +79,8 @@ describe('ingestManager', () => {
await kbnTestServer.request.get(root, '/api/ingest_manager/agent_configs').expect(200);
});
- it('has datasources api', async () => {
- await kbnTestServer.request.get(root, '/api/ingest_manager/datasources').expect(200);
+ it('has package configs api', async () => {
+ await kbnTestServer.request.get(root, '/api/ingest_manager/package_configs').expect(200);
});
it('does not have EPM api', async () => {
@@ -92,7 +92,7 @@ describe('ingestManager', () => {
});
});
- // For now, only the manager routes (/agent_configs & /datasources) are added
+ // For now, only the manager routes (/agent_configs & /package_configs) are added
// EPM and ingest will be conditionally added when we enable these lines
// https://github.com/jfsiii/kibana/blob/f73b54ebb7e0f6fc00efd8a6800a01eb2d9fb772/x-pack/plugins/ingest_manager/server/plugin.ts#L84
// adding tests to confirm the Fleet & EPM routes are never added
@@ -118,8 +118,8 @@ describe('ingestManager', () => {
await kbnTestServer.request.get(root, '/api/ingest_manager/agent_configs').expect(200);
});
- it('has datasources api', async () => {
- await kbnTestServer.request.get(root, '/api/ingest_manager/datasources').expect(200);
+ it('has package configs api', async () => {
+ await kbnTestServer.request.get(root, '/api/ingest_manager/package_configs').expect(200);
});
it('does have EPM api', async () => {
@@ -152,8 +152,8 @@ describe('ingestManager', () => {
await kbnTestServer.request.get(root, '/api/ingest_manager/agent_configs').expect(200);
});
- it('has datasources api', async () => {
- await kbnTestServer.request.get(root, '/api/ingest_manager/datasources').expect(200);
+ it('has package configs api', async () => {
+ await kbnTestServer.request.get(root, '/api/ingest_manager/package_configs').expect(200);
});
it('does not have EPM api', async () => {
@@ -187,8 +187,8 @@ describe('ingestManager', () => {
await kbnTestServer.request.get(root, '/api/ingest_manager/agent_configs').expect(200);
});
- it('has datasources api', async () => {
- await kbnTestServer.request.get(root, '/api/ingest_manager/datasources').expect(200);
+ it('has package configs api', async () => {
+ await kbnTestServer.request.get(root, '/api/ingest_manager/package_configs').expect(200);
});
it('does have EPM api', async () => {
diff --git a/x-pack/plugins/ingest_manager/server/mocks.ts b/x-pack/plugins/ingest_manager/server/mocks.ts
index 3bdef14dc85a0..f305d9dd0c1a7 100644
--- a/x-pack/plugins/ingest_manager/server/mocks.ts
+++ b/x-pack/plugins/ingest_manager/server/mocks.ts
@@ -8,7 +8,7 @@ import { loggingSystemMock, savedObjectsServiceMock } from 'src/core/server/mock
import { IngestManagerAppContext } from './plugin';
import { encryptedSavedObjectsMock } from '../../encrypted_saved_objects/server/mocks';
import { securityMock } from '../../security/server/mocks';
-import { DatasourceServiceInterface } from './services/datasource';
+import { PackageConfigServiceInterface } from './services/package_config';
export const createAppContextStartContractMock = (): IngestManagerAppContext => {
return {
@@ -21,10 +21,10 @@ export const createAppContextStartContractMock = (): IngestManagerAppContext =>
};
};
-export const createDatasourceServiceMock = () => {
+export const createPackageConfigServiceMock = () => {
return {
assignPackageStream: jest.fn(),
- buildDatasourceFromPackage: jest.fn(),
+ buildPackageConfigFromPackage: jest.fn(),
bulkCreate: jest.fn(),
create: jest.fn(),
delete: jest.fn(),
@@ -32,5 +32,5 @@ export const createDatasourceServiceMock = () => {
getByIDs: jest.fn(),
list: jest.fn(),
update: jest.fn(),
- } as jest.Mocked;
+ } as jest.Mocked;
};
diff --git a/x-pack/plugins/ingest_manager/server/plugin.ts b/x-pack/plugins/ingest_manager/server/plugin.ts
index 1ae9528f34410..91201dbf9848b 100644
--- a/x-pack/plugins/ingest_manager/server/plugin.ts
+++ b/x-pack/plugins/ingest_manager/server/plugin.ts
@@ -25,7 +25,7 @@ import {
PLUGIN_ID,
OUTPUT_SAVED_OBJECT_TYPE,
AGENT_CONFIG_SAVED_OBJECT_TYPE,
- DATASOURCE_SAVED_OBJECT_TYPE,
+ PACKAGE_CONFIG_SAVED_OBJECT_TYPE,
PACKAGES_SAVED_OBJECT_TYPE,
AGENT_SAVED_OBJECT_TYPE,
AGENT_EVENT_SAVED_OBJECT_TYPE,
@@ -34,7 +34,7 @@ import {
import { registerSavedObjects, registerEncryptedSavedObjects } from './saved_objects';
import {
registerEPMRoutes,
- registerDatasourceRoutes,
+ registerPackageConfigRoutes,
registerDataStreamRoutes,
registerAgentConfigRoutes,
registerSetupRoutes,
@@ -45,14 +45,14 @@ import {
registerSettingsRoutes,
registerAppRoutes,
} from './routes';
-import { IngestManagerConfigType, NewDatasource } from '../common';
+import { IngestManagerConfigType, NewPackageConfig } from '../common';
import {
appContextService,
licenseService,
ESIndexPatternSavedObjectService,
ESIndexPatternService,
AgentService,
- datasourceService,
+ packageConfigService,
} from './services';
import {
getAgentStatusById,
@@ -91,7 +91,7 @@ export type IngestManagerSetupContract = void;
const allSavedObjectTypes = [
OUTPUT_SAVED_OBJECT_TYPE,
AGENT_CONFIG_SAVED_OBJECT_TYPE,
- DATASOURCE_SAVED_OBJECT_TYPE,
+ PACKAGE_CONFIG_SAVED_OBJECT_TYPE,
PACKAGES_SAVED_OBJECT_TYPE,
AGENT_SAVED_OBJECT_TYPE,
AGENT_EVENT_SAVED_OBJECT_TYPE,
@@ -102,8 +102,8 @@ const allSavedObjectTypes = [
* Callbacks supported by the Ingest plugin
*/
export type ExternalCallback = [
- 'datasourceCreate',
- (newDatasource: NewDatasource) => Promise
+ 'packageConfigCreate',
+ (newPackageConfig: NewPackageConfig) => Promise
];
export type ExternalCallbacksStorage = Map>;
@@ -115,9 +115,9 @@ export interface IngestManagerStartContract {
esIndexPatternService: ESIndexPatternService;
agentService: AgentService;
/**
- * Services for Ingest's Datasources
+ * Services for Ingest's package configs
*/
- datasourceService: typeof datasourceService;
+ packageConfigService: typeof packageConfigService;
/**
* Register callbacks for inclusion in ingest API processing
* @param args
@@ -205,7 +205,7 @@ export class IngestManagerPlugin
if (this.security) {
registerSetupRoutes(router, config);
registerAgentConfigRoutes(router);
- registerDatasourceRoutes(router);
+ registerPackageConfigRoutes(router);
registerOutputRoutes(router);
registerSettingsRoutes(router);
registerDataStreamRoutes(router);
@@ -265,7 +265,7 @@ export class IngestManagerPlugin
getAgentStatusById,
authenticateAgentWithAccessToken,
},
- datasourceService,
+ packageConfigService,
registerExternalCallback: (...args: ExternalCallback) => {
return appContextService.addExternalCallback(...args);
},
diff --git a/x-pack/plugins/ingest_manager/server/routes/agent_config/handlers.ts b/x-pack/plugins/ingest_manager/server/routes/agent_config/handlers.ts
index d01b361bd6ca4..7b12a076ff041 100644
--- a/x-pack/plugins/ingest_manager/server/routes/agent_config/handlers.ts
+++ b/x-pack/plugins/ingest_manager/server/routes/agent_config/handlers.ts
@@ -7,7 +7,7 @@ import { TypeOf } from '@kbn/config-schema';
import { RequestHandler, ResponseHeaders } from 'src/core/server';
import bluebird from 'bluebird';
import { configToYaml } from '../../../common/services';
-import { appContextService, agentConfigService, datasourceService } from '../../services';
+import { appContextService, agentConfigService, packageConfigService } from '../../services';
import { listAgents } from '../../services/agents';
import { AGENT_SAVED_OBJECT_TYPE } from '../../constants';
import {
@@ -20,7 +20,7 @@ import {
GetFullAgentConfigRequestSchema,
AgentConfig,
DefaultPackages,
- NewDatasource,
+ NewPackageConfig,
} from '../../types';
import {
GetAgentConfigsResponse,
@@ -107,30 +107,34 @@ export const createAgentConfigHandler: RequestHandler<
const withSysMonitoring = request.query.sys_monitoring ?? false;
try {
// eslint-disable-next-line prefer-const
- let [agentConfig, newSysDatasource] = await Promise.all(
- [
- agentConfigService.create(soClient, request.body, {
- user,
- }),
- // If needed, retrieve System package information and build a new Datasource for the system package
- // NOTE: we ignore failures in attempting to create datasource, since config might have been created
- // successfully
- withSysMonitoring
- ? datasourceService
- .buildDatasourceFromPackage(soClient, DefaultPackages.system)
- .catch(() => undefined)
- : undefined,
- ]
- );
+ let [agentConfig, newSysPackageConfig] = await Promise.all<
+ AgentConfig,
+ NewPackageConfig | undefined
+ >([
+ agentConfigService.create(soClient, request.body, {
+ user,
+ }),
+ // If needed, retrieve System package information and build a new package config for the system package
+ // NOTE: we ignore failures in attempting to create package config, since config might have been created
+ // successfully
+ withSysMonitoring
+ ? packageConfigService
+ .buildPackageConfigFromPackage(soClient, DefaultPackages.system)
+ .catch(() => undefined)
+ : undefined,
+ ]);
- // Create the system monitoring datasource and add it to config.
- if (withSysMonitoring && newSysDatasource !== undefined && agentConfig !== undefined) {
- newSysDatasource.config_id = agentConfig.id;
- const sysDatasource = await datasourceService.create(soClient, newSysDatasource, { user });
+ // Create the system monitoring package config and add it to agent config.
+ if (withSysMonitoring && newSysPackageConfig !== undefined && agentConfig !== undefined) {
+ newSysPackageConfig.config_id = agentConfig.id;
+ newSysPackageConfig.namespace = agentConfig.namespace;
+ const sysPackageConfig = await packageConfigService.create(soClient, newSysPackageConfig, {
+ user,
+ });
- if (sysDatasource) {
- agentConfig = await agentConfigService.assignDatasources(soClient, agentConfig.id, [
- sysDatasource.id,
+ if (sysPackageConfig) {
+ agentConfig = await agentConfigService.assignPackageConfigs(soClient, agentConfig.id, [
+ sysPackageConfig.id,
]);
}
}
diff --git a/x-pack/plugins/ingest_manager/server/routes/datasource/index.ts b/x-pack/plugins/ingest_manager/server/routes/datasource/index.ts
deleted file mode 100644
index 7217f28053cf3..0000000000000
--- a/x-pack/plugins/ingest_manager/server/routes/datasource/index.ts
+++ /dev/null
@@ -1,73 +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 { IRouter } from 'src/core/server';
-import { PLUGIN_ID, DATASOURCE_API_ROUTES } from '../../constants';
-import {
- GetDatasourcesRequestSchema,
- GetOneDatasourceRequestSchema,
- CreateDatasourceRequestSchema,
- UpdateDatasourceRequestSchema,
- DeleteDatasourcesRequestSchema,
-} from '../../types';
-import {
- getDatasourcesHandler,
- getOneDatasourceHandler,
- createDatasourceHandler,
- updateDatasourceHandler,
- deleteDatasourceHandler,
-} from './handlers';
-
-export const registerRoutes = (router: IRouter) => {
- // List
- router.get(
- {
- path: DATASOURCE_API_ROUTES.LIST_PATTERN,
- validate: GetDatasourcesRequestSchema,
- options: { tags: [`access:${PLUGIN_ID}-read`] },
- },
- getDatasourcesHandler
- );
-
- // Get one
- router.get(
- {
- path: DATASOURCE_API_ROUTES.INFO_PATTERN,
- validate: GetOneDatasourceRequestSchema,
- options: { tags: [`access:${PLUGIN_ID}-read`] },
- },
- getOneDatasourceHandler
- );
-
- // Create
- router.post(
- {
- path: DATASOURCE_API_ROUTES.CREATE_PATTERN,
- validate: CreateDatasourceRequestSchema,
- options: { tags: [`access:${PLUGIN_ID}-all`] },
- },
- createDatasourceHandler
- );
-
- // Update
- router.put(
- {
- path: DATASOURCE_API_ROUTES.UPDATE_PATTERN,
- validate: UpdateDatasourceRequestSchema,
- options: { tags: [`access:${PLUGIN_ID}-all`] },
- },
- updateDatasourceHandler
- );
-
- // Delete
- router.post(
- {
- path: DATASOURCE_API_ROUTES.DELETE_PATTERN,
- validate: DeleteDatasourcesRequestSchema,
- options: { tags: [`access:${PLUGIN_ID}`] },
- },
- deleteDatasourceHandler
- );
-};
diff --git a/x-pack/plugins/ingest_manager/server/routes/index.ts b/x-pack/plugins/ingest_manager/server/routes/index.ts
index 0978c2aa57bf6..f6b4439d8bef1 100644
--- a/x-pack/plugins/ingest_manager/server/routes/index.ts
+++ b/x-pack/plugins/ingest_manager/server/routes/index.ts
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
export { registerRoutes as registerAgentConfigRoutes } from './agent_config';
-export { registerRoutes as registerDatasourceRoutes } from './datasource';
+export { registerRoutes as registerPackageConfigRoutes } from './package_config';
export { registerRoutes as registerDataStreamRoutes } from './data_streams';
export { registerRoutes as registerEPMRoutes } from './epm';
export { registerRoutes as registerSetupRoutes } from './setup';
diff --git a/x-pack/plugins/ingest_manager/server/routes/datasource/datasource_handlers.test.ts b/x-pack/plugins/ingest_manager/server/routes/package_config/handlers.test.ts
similarity index 85%
rename from x-pack/plugins/ingest_manager/server/routes/datasource/datasource_handlers.test.ts
rename to x-pack/plugins/ingest_manager/server/routes/package_config/handlers.test.ts
index 07cbeb8b2cec5..6d712ce063290 100644
--- a/x-pack/plugins/ingest_manager/server/routes/datasource/datasource_handlers.test.ts
+++ b/x-pack/plugins/ingest_manager/server/routes/package_config/handlers.test.ts
@@ -7,23 +7,23 @@
import { httpServerMock, httpServiceMock } from 'src/core/server/mocks';
import { IRouter, KibanaRequest, Logger, RequestHandler, RouteConfig } from 'kibana/server';
import { registerRoutes } from './index';
-import { DATASOURCE_API_ROUTES } from '../../../common/constants';
+import { PACKAGE_CONFIG_API_ROUTES } from '../../../common/constants';
import { xpackMocks } from '../../../../../mocks';
import { appContextService } from '../../services';
import { createAppContextStartContractMock } from '../../mocks';
-import { DatasourceServiceInterface, ExternalCallback } from '../..';
-import { CreateDatasourceRequestSchema } from '../../types/rest_spec';
-import { datasourceService } from '../../services';
+import { PackageConfigServiceInterface, ExternalCallback } from '../..';
+import { CreatePackageConfigRequestSchema } from '../../types/rest_spec';
+import { packageConfigService } from '../../services';
-const datasourceServiceMock = datasourceService as jest.Mocked;
+const packageConfigServiceMock = packageConfigService as jest.Mocked;
-jest.mock('../../services/datasource', (): {
- datasourceService: jest.Mocked;
+jest.mock('../../services/package_config', (): {
+ packageConfigService: jest.Mocked;
} => {
return {
- datasourceService: {
+ packageConfigService: {
assignPackageStream: jest.fn((packageInfo, dataInputs) => Promise.resolve(dataInputs)),
- buildDatasourceFromPackage: jest.fn(),
+ buildPackageConfigFromPackage: jest.fn(),
bulkCreate: jest.fn(),
create: jest.fn((soClient, newData) =>
Promise.resolve({
@@ -52,7 +52,7 @@ jest.mock('../../services/epm/packages', () => {
};
});
-describe('When calling datasource', () => {
+describe('When calling package config', () => {
let routerMock: jest.Mocked;
let routeHandler: RequestHandler;
let routeConfig: RouteConfig;
@@ -77,12 +77,12 @@ describe('When calling datasource', () => {
describe('create api handler', () => {
const getCreateKibanaRequest = (
- newData?: typeof CreateDatasourceRequestSchema.body
- ): KibanaRequest => {
+ newData?: typeof CreatePackageConfigRequestSchema.body
+ ): KibanaRequest => {
return httpServerMock.createKibanaRequest<
undefined,
undefined,
- typeof CreateDatasourceRequestSchema.body
+ typeof CreatePackageConfigRequestSchema.body
>({
path: routeConfig.path,
method: 'post',
@@ -102,7 +102,7 @@ describe('When calling datasource', () => {
// Set the routeConfig and routeHandler to the Create API
beforeAll(() => {
[routeConfig, routeHandler] = routerMock.post.mock.calls.find(([{ path }]) =>
- path.startsWith(DATASOURCE_API_ROUTES.CREATE_PATTERN)
+ path.startsWith(PACKAGE_CONFIG_API_ROUTES.CREATE_PATTERN)
)!;
});
@@ -151,8 +151,8 @@ describe('When calling datasource', () => {
});
beforeEach(() => {
- appContextService.addExternalCallback('datasourceCreate', callbackOne);
- appContextService.addExternalCallback('datasourceCreate', callbackTwo);
+ appContextService.addExternalCallback('packageConfigCreate', callbackOne);
+ appContextService.addExternalCallback('packageConfigCreate', callbackTwo);
});
afterEach(() => (callbackCallingOrder.length = 0));
@@ -164,7 +164,7 @@ describe('When calling datasource', () => {
expect(callbackCallingOrder).toEqual(['one', 'two']);
});
- it('should feed datasource returned by last callback', async () => {
+ it('should feed package config returned by last callback', async () => {
const request = getCreateKibanaRequest();
await routeHandler(context, request, response);
expect(response.ok).toHaveBeenCalled();
@@ -213,7 +213,7 @@ describe('When calling datasource', () => {
const request = getCreateKibanaRequest();
await routeHandler(context, request, response);
expect(response.ok).toHaveBeenCalled();
- expect(datasourceServiceMock.create.mock.calls[0][1]).toEqual({
+ expect(packageConfigServiceMock.create.mock.calls[0][1]).toEqual({
config_id: 'a5ca00c0-b30c-11ea-9732-1bb05811278c',
description: '',
enabled: true,
@@ -268,8 +268,8 @@ describe('When calling datasource', () => {
});
beforeEach(() => {
- appContextService.addExternalCallback('datasourceCreate', callbackThree);
- appContextService.addExternalCallback('datasourceCreate', callbackFour);
+ appContextService.addExternalCallback('packageConfigCreate', callbackThree);
+ appContextService.addExternalCallback('packageConfigCreate', callbackFour);
});
it('should skip over callback exceptions and still execute other callbacks', async () => {
@@ -285,16 +285,16 @@ describe('When calling datasource', () => {
await routeHandler(context, request, response);
expect(response.ok).toHaveBeenCalled();
expect(errorLogger.mock.calls).toEqual([
- ['An external registered [datasourceCreate] callback failed when executed'],
+ ['An external registered [packageConfigCreate] callback failed when executed'],
[new Error('callbackThree threw error on purpose')],
]);
});
- it('should create datasource with last successful returned datasource', async () => {
+ it('should create package config with last successful returned package config', async () => {
const request = getCreateKibanaRequest();
await routeHandler(context, request, response);
expect(response.ok).toHaveBeenCalled();
- expect(datasourceServiceMock.create.mock.calls[0][1]).toEqual({
+ expect(packageConfigServiceMock.create.mock.calls[0][1]).toEqual({
config_id: 'a5ca00c0-b30c-11ea-9732-1bb05811278c',
description: '',
enabled: true,
diff --git a/x-pack/plugins/ingest_manager/server/routes/datasource/handlers.ts b/x-pack/plugins/ingest_manager/server/routes/package_config/handlers.ts
similarity index 56%
rename from x-pack/plugins/ingest_manager/server/routes/datasource/handlers.ts
rename to x-pack/plugins/ingest_manager/server/routes/package_config/handlers.ts
index 4f83d24a846ea..e212c861ce770 100644
--- a/x-pack/plugins/ingest_manager/server/routes/datasource/handlers.ts
+++ b/x-pack/plugins/ingest_manager/server/routes/package_config/handlers.ts
@@ -6,25 +6,28 @@
import { TypeOf } from '@kbn/config-schema';
import Boom from 'boom';
import { RequestHandler } from 'src/core/server';
-import { appContextService, datasourceService } from '../../services';
+import { appContextService, packageConfigService } from '../../services';
import { ensureInstalledPackage, getPackageInfo } from '../../services/epm/packages';
import {
- GetDatasourcesRequestSchema,
- GetOneDatasourceRequestSchema,
- CreateDatasourceRequestSchema,
- UpdateDatasourceRequestSchema,
- DeleteDatasourcesRequestSchema,
- NewDatasource,
+ GetPackageConfigsRequestSchema,
+ GetOnePackageConfigRequestSchema,
+ CreatePackageConfigRequestSchema,
+ UpdatePackageConfigRequestSchema,
+ DeletePackageConfigsRequestSchema,
+ NewPackageConfig,
} from '../../types';
-import { CreateDatasourceResponse, DeleteDatasourcesResponse } from '../../../common';
+import { CreatePackageConfigResponse, DeletePackageConfigsResponse } from '../../../common';
-export const getDatasourcesHandler: RequestHandler<
+export const getPackageConfigsHandler: RequestHandler<
undefined,
- TypeOf
+ TypeOf
> = async (context, request, response) => {
const soClient = context.core.savedObjects.client;
try {
- const { items, total, page, perPage } = await datasourceService.list(soClient, request.query);
+ const { items, total, page, perPage } = await packageConfigService.list(
+ soClient,
+ request.query
+ );
return response.ok({
body: {
items,
@@ -42,23 +45,23 @@ export const getDatasourcesHandler: RequestHandler<
}
};
-export const getOneDatasourceHandler: RequestHandler> = async (context, request, response) => {
const soClient = context.core.savedObjects.client;
try {
- const datasource = await datasourceService.get(soClient, request.params.datasourceId);
- if (datasource) {
+ const packageConfig = await packageConfigService.get(soClient, request.params.packageConfigId);
+ if (packageConfig) {
return response.ok({
body: {
- item: datasource,
+ item: packageConfig,
success: true,
},
});
} else {
return response.customError({
statusCode: 404,
- body: { message: 'Datasource not found' },
+ body: { message: 'Package config not found' },
});
}
} catch (e) {
@@ -69,10 +72,10 @@ export const getOneDatasourceHandler: RequestHandler
+ TypeOf
> = async (context, request, response) => {
const soClient = context.core.savedObjects.client;
const callCluster = context.core.elasticsearch.legacy.client.callAsCurrentUser;
@@ -80,33 +83,30 @@ export const createDatasourceHandler: RequestHandler<
const logger = appContextService.getLogger();
let newData = { ...request.body };
try {
- // If we have external callbacks, then process those now before creating the actual datasource
- const externalCallbacks = appContextService.getExternalCallbacks('datasourceCreate');
+ // If we have external callbacks, then process those now before creating the actual package config
+ const externalCallbacks = appContextService.getExternalCallbacks('packageConfigCreate');
if (externalCallbacks && externalCallbacks.size > 0) {
- let updatedNewData: NewDatasource = newData;
+ let updatedNewData: NewPackageConfig = newData;
for (const callback of externalCallbacks) {
try {
// ensure that the returned value by the callback passes schema validation
- updatedNewData = CreateDatasourceRequestSchema.body.validate(
+ updatedNewData = CreatePackageConfigRequestSchema.body.validate(
await callback(updatedNewData)
);
} catch (error) {
// Log the error, but keep going and process the other callbacks
- logger.error('An external registered [datasourceCreate] callback failed when executed');
+ logger.error(
+ 'An external registered [packageConfigCreate] callback failed when executed'
+ );
logger.error(error);
}
}
- // The type `NewDatasource` and the `DatasourceBaseSchema` are incompatible.
- // `NewDatasrouce` defines `namespace` as optional string, which means that `undefined` is a
- // valid value, however, the schema defines it as string with a minimum length of 1.
- // Here, we need to cast the value back to the schema type and ignore the TS error.
- // @ts-ignore
- newData = updatedNewData as typeof CreateDatasourceRequestSchema.body;
+ newData = updatedNewData;
}
- // Make sure the datasource package is installed
+ // Make sure the associated package is installed
if (newData.package?.name) {
await ensureInstalledPackage({
savedObjectsClient: soClient,
@@ -118,15 +118,15 @@ export const createDatasourceHandler: RequestHandler<
pkgName: newData.package.name,
pkgVersion: newData.package.version,
});
- newData.inputs = (await datasourceService.assignPackageStream(
+ newData.inputs = (await packageConfigService.assignPackageStream(
pkgInfo,
newData.inputs
- )) as TypeOf['inputs'];
+ )) as TypeOf['inputs'];
}
- // Create datasource
- const datasource = await datasourceService.create(soClient, newData, { user });
- const body: CreateDatasourceResponse = { item: datasource, success: true };
+ // Create package config
+ const packageConfig = await packageConfigService.create(soClient, newData, { user });
+ const body: CreatePackageConfigResponse = { item: packageConfig, success: true };
return response.ok({
body,
});
@@ -139,42 +139,42 @@ export const createDatasourceHandler: RequestHandler<
}
};
-export const updateDatasourceHandler: RequestHandler<
- TypeOf,
+export const updatePackageConfigHandler: RequestHandler<
+ TypeOf,
unknown,
- TypeOf
+ TypeOf
> = async (context, request, response) => {
const soClient = context.core.savedObjects.client;
const user = (await appContextService.getSecurity()?.authc.getCurrentUser(request)) || undefined;
try {
- const datasource = await datasourceService.get(soClient, request.params.datasourceId);
+ const packageConfig = await packageConfigService.get(soClient, request.params.packageConfigId);
- if (!datasource) {
- throw Boom.notFound('Datasource not found');
+ if (!packageConfig) {
+ throw Boom.notFound('Package config not found');
}
const newData = { ...request.body };
- const pkg = newData.package || datasource.package;
- const inputs = newData.inputs || datasource.inputs;
+ const pkg = newData.package || packageConfig.package;
+ const inputs = newData.inputs || packageConfig.inputs;
if (pkg && (newData.inputs || newData.package)) {
const pkgInfo = await getPackageInfo({
savedObjectsClient: soClient,
pkgName: pkg.name,
pkgVersion: pkg.version,
});
- newData.inputs = (await datasourceService.assignPackageStream(pkgInfo, inputs)) as TypeOf<
- typeof CreateDatasourceRequestSchema.body
+ newData.inputs = (await packageConfigService.assignPackageStream(pkgInfo, inputs)) as TypeOf<
+ typeof CreatePackageConfigRequestSchema.body
>['inputs'];
}
- const updatedDatasource = await datasourceService.update(
+ const updatedPackageConfig = await packageConfigService.update(
soClient,
- request.params.datasourceId,
+ request.params.packageConfigId,
newData,
{ user }
);
return response.ok({
- body: { item: updatedDatasource, success: true },
+ body: { item: updatedPackageConfig, success: true },
});
} catch (e) {
return response.customError({
@@ -184,17 +184,17 @@ export const updateDatasourceHandler: RequestHandler<
}
};
-export const deleteDatasourceHandler: RequestHandler<
+export const deletePackageConfigHandler: RequestHandler<
unknown,
unknown,
- TypeOf
+ TypeOf
> = async (context, request, response) => {
const soClient = context.core.savedObjects.client;
const user = (await appContextService.getSecurity()?.authc.getCurrentUser(request)) || undefined;
try {
- const body: DeleteDatasourcesResponse = await datasourceService.delete(
+ const body: DeletePackageConfigsResponse = await packageConfigService.delete(
soClient,
- request.body.datasourceIds,
+ request.body.packageConfigIds,
{ user }
);
return response.ok({
diff --git a/x-pack/plugins/ingest_manager/server/routes/package_config/index.ts b/x-pack/plugins/ingest_manager/server/routes/package_config/index.ts
new file mode 100644
index 0000000000000..1da045e052997
--- /dev/null
+++ b/x-pack/plugins/ingest_manager/server/routes/package_config/index.ts
@@ -0,0 +1,73 @@
+/*
+ * 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 { IRouter } from 'src/core/server';
+import { PLUGIN_ID, PACKAGE_CONFIG_API_ROUTES } from '../../constants';
+import {
+ GetPackageConfigsRequestSchema,
+ GetOnePackageConfigRequestSchema,
+ CreatePackageConfigRequestSchema,
+ UpdatePackageConfigRequestSchema,
+ DeletePackageConfigsRequestSchema,
+} from '../../types';
+import {
+ getPackageConfigsHandler,
+ getOnePackageConfigHandler,
+ createPackageConfigHandler,
+ updatePackageConfigHandler,
+ deletePackageConfigHandler,
+} from './handlers';
+
+export const registerRoutes = (router: IRouter) => {
+ // List
+ router.get(
+ {
+ path: PACKAGE_CONFIG_API_ROUTES.LIST_PATTERN,
+ validate: GetPackageConfigsRequestSchema,
+ options: { tags: [`access:${PLUGIN_ID}-read`] },
+ },
+ getPackageConfigsHandler
+ );
+
+ // Get one
+ router.get(
+ {
+ path: PACKAGE_CONFIG_API_ROUTES.INFO_PATTERN,
+ validate: GetOnePackageConfigRequestSchema,
+ options: { tags: [`access:${PLUGIN_ID}-read`] },
+ },
+ getOnePackageConfigHandler
+ );
+
+ // Create
+ router.post(
+ {
+ path: PACKAGE_CONFIG_API_ROUTES.CREATE_PATTERN,
+ validate: CreatePackageConfigRequestSchema,
+ options: { tags: [`access:${PLUGIN_ID}-all`] },
+ },
+ createPackageConfigHandler
+ );
+
+ // Update
+ router.put(
+ {
+ path: PACKAGE_CONFIG_API_ROUTES.UPDATE_PATTERN,
+ validate: UpdatePackageConfigRequestSchema,
+ options: { tags: [`access:${PLUGIN_ID}-all`] },
+ },
+ updatePackageConfigHandler
+ );
+
+ // Delete
+ router.post(
+ {
+ path: PACKAGE_CONFIG_API_ROUTES.DELETE_PATTERN,
+ validate: DeletePackageConfigsRequestSchema,
+ options: { tags: [`access:${PLUGIN_ID}`] },
+ },
+ deletePackageConfigHandler
+ );
+};
diff --git a/x-pack/plugins/ingest_manager/server/saved_objects/index.ts b/x-pack/plugins/ingest_manager/server/saved_objects/index.ts
index 1d412937e244f..98de9ac217af9 100644
--- a/x-pack/plugins/ingest_manager/server/saved_objects/index.ts
+++ b/x-pack/plugins/ingest_manager/server/saved_objects/index.ts
@@ -9,7 +9,7 @@ import { EncryptedSavedObjectsPluginSetup } from '../../../encrypted_saved_objec
import {
OUTPUT_SAVED_OBJECT_TYPE,
AGENT_CONFIG_SAVED_OBJECT_TYPE,
- DATASOURCE_SAVED_OBJECT_TYPE,
+ PACKAGE_CONFIG_SAVED_OBJECT_TYPE,
PACKAGES_SAVED_OBJECT_TYPE,
AGENT_SAVED_OBJECT_TYPE,
AGENT_EVENT_SAVED_OBJECT_TYPE,
@@ -17,14 +17,13 @@ import {
ENROLLMENT_API_KEYS_SAVED_OBJECT_TYPE,
GLOBAL_SETTINGS_SAVED_OBJECT_TYPE,
} from '../constants';
-import { migrateDatasourcesToV790 } from './migrations/datasources_v790';
-import { migrateAgentConfigToV790 } from './migrations/agent_config_v790';
+
/*
* Saved object types and mappings
*
- * Please update typings in `/common/types` if mappings are updated.
+ * Please update typings in `/common/types` as well as
+ * schemas in `/server/types` if mappings are updated.
*/
-
const savedObjectTypes: { [key: string]: SavedObjectsType } = {
[GLOBAL_SETTINGS_SAVED_OBJECT_TYPE]: {
name: GLOBAL_SETTINGS_SAVED_OBJECT_TYPE,
@@ -122,20 +121,17 @@ const savedObjectTypes: { [key: string]: SavedObjectsType } = {
properties: {
id: { type: 'keyword' },
name: { type: 'text' },
- is_default: { type: 'boolean' },
- namespace: { type: 'keyword' },
description: { type: 'text' },
+ namespace: { type: 'keyword' },
+ is_default: { type: 'boolean' },
status: { type: 'keyword' },
- datasources: { type: 'keyword' },
+ package_configs: { type: 'keyword' },
updated_at: { type: 'date' },
updated_by: { type: 'keyword' },
revision: { type: 'integer' },
monitoring_enabled: { type: 'keyword', index: false },
},
},
- migrations: {
- '7.9.0': migrateAgentConfigToV790,
- },
},
[ENROLLMENT_API_KEYS_SAVED_OBJECT_TYPE]: {
name: ENROLLMENT_API_KEYS_SAVED_OBJECT_TYPE,
@@ -178,8 +174,8 @@ const savedObjectTypes: { [key: string]: SavedObjectsType } = {
},
},
},
- [DATASOURCE_SAVED_OBJECT_TYPE]: {
- name: DATASOURCE_SAVED_OBJECT_TYPE,
+ [PACKAGE_CONFIG_SAVED_OBJECT_TYPE]: {
+ name: PACKAGE_CONFIG_SAVED_OBJECT_TYPE,
hidden: false,
namespaceType: 'agnostic',
management: {
@@ -190,8 +186,9 @@ const savedObjectTypes: { [key: string]: SavedObjectsType } = {
name: { type: 'keyword' },
description: { type: 'text' },
namespace: { type: 'keyword' },
- config_id: { type: 'keyword' },
enabled: { type: 'boolean' },
+ config_id: { type: 'keyword' },
+ output_id: { type: 'keyword' },
package: {
properties: {
name: { type: 'keyword' },
@@ -199,16 +196,14 @@ const savedObjectTypes: { [key: string]: SavedObjectsType } = {
version: { type: 'keyword' },
},
},
- output_id: { type: 'keyword' },
inputs: {
type: 'nested',
enabled: false,
properties: {
type: { type: 'keyword' },
enabled: { type: 'boolean' },
- processors: { type: 'keyword' },
- config: { type: 'flattened' },
vars: { type: 'flattened' },
+ config: { type: 'flattened' },
streams: {
type: 'nested',
properties: {
@@ -220,10 +215,9 @@ const savedObjectTypes: { [key: string]: SavedObjectsType } = {
type: { type: 'keyword' },
},
},
- processors: { type: 'keyword' },
- config: { type: 'flattened' },
- agent_stream: { type: 'flattened' },
vars: { type: 'flattened' },
+ config: { type: 'flattened' },
+ compiled_stream: { type: 'flattened' },
},
},
},
@@ -235,9 +229,6 @@ const savedObjectTypes: { [key: string]: SavedObjectsType } = {
created_by: { type: 'keyword' },
},
},
- migrations: {
- '7.9.0': migrateDatasourcesToV790,
- },
},
[PACKAGES_SAVED_OBJECT_TYPE]: {
name: PACKAGES_SAVED_OBJECT_TYPE,
diff --git a/x-pack/plugins/ingest_manager/server/saved_objects/migrations/agent_config_v790.ts b/x-pack/plugins/ingest_manager/server/saved_objects/migrations/agent_config_v790.ts
deleted file mode 100644
index 0c850f2c25fbf..0000000000000
--- a/x-pack/plugins/ingest_manager/server/saved_objects/migrations/agent_config_v790.ts
+++ /dev/null
@@ -1,24 +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 { SavedObjectMigrationFn } from 'kibana/server';
-import { cloneDeep } from 'lodash';
-import { AgentConfig } from '../../types';
-
-type Pre790AgentConfig = Exclude & {
- updated_on: string;
-};
-
-export const migrateAgentConfigToV790: SavedObjectMigrationFn = (
- doc
-) => {
- const updatedAgentConfig = cloneDeep(doc);
-
- updatedAgentConfig.attributes.updated_at = doc.attributes.updated_on;
- delete updatedAgentConfig.attributes.updated_on;
-
- return updatedAgentConfig;
-};
diff --git a/x-pack/plugins/ingest_manager/server/saved_objects/migrations/datasources_v790.ts b/x-pack/plugins/ingest_manager/server/saved_objects/migrations/datasources_v790.ts
deleted file mode 100644
index d1e4b29daefc6..0000000000000
--- a/x-pack/plugins/ingest_manager/server/saved_objects/migrations/datasources_v790.ts
+++ /dev/null
@@ -1,43 +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 { SavedObjectMigrationFn } from 'kibana/server';
-import { cloneDeep } from 'lodash';
-import { Datasource, DatasourceInput, DatasourceInputStream } from '../../types';
-
-type Pre790Datasource = Exclude<
- Datasource,
- 'created_at' | 'created_by' | 'updated_at' | 'updated_by'
-> & {
- inputs: Array<
- Exclude & {
- streams: Array<
- Exclude & {
- dataset: string;
- }
- >;
- }
- >;
-};
-
-export const migrateDatasourcesToV790: SavedObjectMigrationFn = (
- doc
-) => {
- const updatedDatasource = cloneDeep(doc);
- const defDate = new Date().toISOString();
-
- updatedDatasource.attributes.created_by = 'system';
- updatedDatasource.attributes.created_at = updatedDatasource?.updated_at ?? defDate;
- updatedDatasource.attributes.updated_by = 'system';
- updatedDatasource.attributes.updated_at = updatedDatasource?.updated_at ?? defDate;
- updatedDatasource.attributes.inputs.forEach((input) => {
- input.streams.forEach((stream) => {
- stream.dataset = { name: (stream.dataset as unknown) as string, type: '' };
- });
- });
-
- return updatedDatasource;
-};
diff --git a/x-pack/plugins/ingest_manager/server/services/agent_config.ts b/x-pack/plugins/ingest_manager/server/services/agent_config.ts
index 9c27e9b7a3a7a..ada35d1825069 100644
--- a/x-pack/plugins/ingest_manager/server/services/agent_config.ts
+++ b/x-pack/plugins/ingest_manager/server/services/agent_config.ts
@@ -12,7 +12,7 @@ import {
AGENT_SAVED_OBJECT_TYPE,
} from '../constants';
import {
- Datasource,
+ PackageConfig,
NewAgentConfig,
AgentConfig,
AgentConfigSOAttributes,
@@ -20,9 +20,9 @@ import {
AgentConfigStatus,
ListWithKuery,
} from '../types';
-import { DeleteAgentConfigResponse, storedDatasourcesToAgentInputs } from '../../common';
+import { DeleteAgentConfigResponse, storedPackageConfigsToAgentInputs } from '../../common';
import { listAgents } from './agents';
-import { datasourceService } from './datasource';
+import { packageConfigService } from './package_config';
import { outputService } from './output';
import { agentConfigUpdateEventHandler } from './agent_config_update';
@@ -115,7 +115,7 @@ class AgentConfigService {
public async get(
soClient: SavedObjectsClientContract,
id: string,
- withDatasources: boolean = true
+ withPackageConfigs: boolean = true
): Promise {
const agentConfigSO = await soClient.get(SAVED_OBJECT_TYPE, id);
if (!agentConfigSO) {
@@ -128,11 +128,11 @@ class AgentConfigService {
const agentConfig = { id: agentConfigSO.id, ...agentConfigSO.attributes };
- if (withDatasources) {
- agentConfig.datasources =
- (await datasourceService.getByIDs(
+ if (withPackageConfigs) {
+ agentConfig.package_configs =
+ (await packageConfigService.getByIDs(
soClient,
- (agentConfigSO.attributes.datasources as string[]) || []
+ (agentConfigSO.attributes.package_configs as string[]) || []
)) || [];
}
@@ -200,15 +200,20 @@ class AgentConfigService {
options
);
- // Copy all datasources
- if (baseAgentConfig.datasources.length) {
- const newDatasources = (baseAgentConfig.datasources as Datasource[]).map(
- (datasource: Datasource) => {
- const { id: datasourceId, ...newDatasource } = datasource;
- return newDatasource;
+ // Copy all package configs
+ if (baseAgentConfig.package_configs.length) {
+ const newPackageConfigs = (baseAgentConfig.package_configs as PackageConfig[]).map(
+ (packageConfig: PackageConfig) => {
+ const { id: packageConfigId, ...newPackageConfig } = packageConfig;
+ return newPackageConfig;
}
);
- await datasourceService.bulkCreate(soClient, newDatasources, newAgentConfig.id, options);
+ await packageConfigService.bulkCreate(
+ soClient,
+ newPackageConfigs,
+ newAgentConfig.id,
+ options
+ );
}
// Get updated config
@@ -228,10 +233,10 @@ class AgentConfigService {
return this._update(soClient, id, {}, options?.user);
}
- public async assignDatasources(
+ public async assignPackageConfigs(
soClient: SavedObjectsClientContract,
id: string,
- datasourceIds: string[],
+ packageConfigIds: string[],
options?: { user?: AuthenticatedUser }
): Promise {
const oldAgentConfig = await this.get(soClient, id, false);
@@ -244,18 +249,18 @@ class AgentConfigService {
soClient,
id,
{
- datasources: uniq(
- [...((oldAgentConfig.datasources || []) as string[])].concat(datasourceIds)
+ package_configs: uniq(
+ [...((oldAgentConfig.package_configs || []) as string[])].concat(packageConfigIds)
),
},
options?.user
);
}
- public async unassignDatasources(
+ public async unassignPackageConfigs(
soClient: SavedObjectsClientContract,
id: string,
- datasourceIds: string[],
+ packageConfigIds: string[],
options?: { user?: AuthenticatedUser }
): Promise {
const oldAgentConfig = await this.get(soClient, id, false);
@@ -269,9 +274,9 @@ class AgentConfigService {
id,
{
...oldAgentConfig,
- datasources: uniq(
- [...((oldAgentConfig.datasources || []) as string[])].filter(
- (dsId) => !datasourceIds.includes(dsId)
+ package_configs: uniq(
+ [...((oldAgentConfig.package_configs || []) as string[])].filter(
+ (pkgConfigId) => !packageConfigIds.includes(pkgConfigId)
)
),
},
@@ -318,8 +323,8 @@ class AgentConfigService {
throw new Error('Cannot delete agent config that is assigned to agent(s)');
}
- if (config.datasources && config.datasources.length) {
- await datasourceService.delete(soClient, config.datasources as string[], {
+ if (config.package_configs && config.package_configs.length) {
+ await packageConfigService.delete(soClient, config.package_configs as string[], {
skipUnassignFromAgentConfigs: true,
});
}
@@ -373,7 +378,7 @@ class AgentConfigService {
{} as FullAgentConfig['outputs']
),
},
- inputs: storedDatasourcesToAgentInputs(config.datasources as Datasource[]),
+ inputs: storedPackageConfigsToAgentInputs(config.package_configs as PackageConfig[]),
revision: config.revision,
...(config.monitoring_enabled && config.monitoring_enabled.length > 0
? {
diff --git a/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts b/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts
index abc4518e70573..6ea59c9a76a49 100644
--- a/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts
+++ b/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts
@@ -139,9 +139,11 @@ describe('test agent acks services', () => {
name: 'system-1',
type: 'logs',
use_output: 'default',
- package: {
- name: 'system',
- version: '0.3.0',
+ meta: {
+ package: {
+ name: 'system',
+ version: '0.3.0',
+ },
},
dataset: {
namespace: 'default',
@@ -279,9 +281,11 @@ describe('test agent acks services', () => {
name: 'system-1',
type: 'logs',
use_output: 'default',
- package: {
- name: 'system',
- version: '0.3.0',
+ meta: {
+ package: {
+ name: 'system',
+ version: '0.3.0',
+ },
},
dataset: {
namespace: 'default',
diff --git a/x-pack/plugins/ingest_manager/server/services/agents/acks.ts b/x-pack/plugins/ingest_manager/server/services/agents/acks.ts
index e391e81ebd0a6..c59bac6a5469a 100644
--- a/x-pack/plugins/ingest_manager/server/services/agents/acks.ts
+++ b/x-pack/plugins/ingest_manager/server/services/agents/acks.ts
@@ -92,8 +92,9 @@ function getLatestConfigIfUpdated(agent: Agent, actions: AgentAction[]) {
function buildUpdateAgentConfig(agentId: string, config: FullAgentConfig) {
const packages = config.inputs.reduce((acc, input) => {
- if (input.package && input.package.name && acc.indexOf(input.package.name) < 0) {
- return [input.package.name, ...acc];
+ const packageName = input.meta?.package?.name;
+ if (packageName && acc.indexOf(packageName) < 0) {
+ return [packageName, ...acc];
}
return acc;
}, []);
diff --git a/x-pack/plugins/ingest_manager/server/services/epm/agent/agent.ts b/x-pack/plugins/ingest_manager/server/services/epm/agent/agent.ts
index 0bcb2464f8d74..d697ad0576396 100644
--- a/x-pack/plugins/ingest_manager/server/services/epm/agent/agent.ts
+++ b/x-pack/plugins/ingest_manager/server/services/epm/agent/agent.ts
@@ -6,9 +6,9 @@
import Handlebars from 'handlebars';
import { safeLoad, safeDump } from 'js-yaml';
-import { DatasourceConfigRecord } from '../../../../common';
+import { PackageConfigConfigRecord } from '../../../../common';
-export function createStream(variables: DatasourceConfigRecord, streamTemplate: string) {
+export function createStream(variables: PackageConfigConfigRecord, streamTemplate: string) {
const { vars, yamlValues } = buildTemplateVariables(variables, streamTemplate);
const template = Handlebars.compile(streamTemplate, { noEscape: true });
@@ -52,7 +52,7 @@ function replaceVariablesInYaml(yamlVariables: { [k: string]: any }, yaml: any)
return yaml;
}
-function buildTemplateVariables(variables: DatasourceConfigRecord, streamTemplate: string) {
+function buildTemplateVariables(variables: PackageConfigConfigRecord, streamTemplate: string) {
const yamlValues: { [k: string]: any } = {};
const vars = Object.entries(variables).reduce((acc, [key, recordEntry]) => {
// support variables with . like key.patterns
diff --git a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/__snapshots__/template.test.ts.snap b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/__snapshots__/template.test.ts.snap
index b1212cf3a6535..635742c82f9a4 100644
--- a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/__snapshots__/template.test.ts.snap
+++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/__snapshots__/template.test.ts.snap
@@ -93,6 +93,12 @@ exports[`tests loading base.yml: base.yml 1`] = `
},
"data_stream": {
"timestamp_field": "@timestamp"
+ },
+ "_meta": {
+ "package": {
+ "name": "nginx"
+ },
+ "managed_by": "ingest-manager"
}
}
`;
@@ -190,6 +196,12 @@ exports[`tests loading coredns.logs.yml: coredns.logs.yml 1`] = `
},
"data_stream": {
"timestamp_field": "@timestamp"
+ },
+ "_meta": {
+ "package": {
+ "name": "coredns"
+ },
+ "managed_by": "ingest-manager"
}
}
`;
@@ -1671,6 +1683,12 @@ exports[`tests loading system.yml: system.yml 1`] = `
},
"data_stream": {
"timestamp_field": "@timestamp"
+ },
+ "_meta": {
+ "package": {
+ "name": "system"
+ },
+ "managed_by": "ingest-manager"
}
}
`;
diff --git a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/install.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/install.ts
index 9d0b6b5d078ad..a318aecf347d6 100644
--- a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/install.ts
+++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/install.ts
@@ -153,6 +153,7 @@ export async function installTemplateForDataset({
fields,
dataset,
packageVersion: pkg.version,
+ packageName: pkg.name,
});
}
@@ -161,11 +162,13 @@ export async function installTemplate({
fields,
dataset,
packageVersion,
+ packageName,
}: {
callCluster: CallESAsCurrentUser;
fields: Field[];
dataset: Dataset;
packageVersion: string;
+ packageName: string;
}): Promise {
const mappings = generateMappings(processFields(fields));
const templateName = generateTemplateName(dataset);
@@ -177,7 +180,13 @@ export async function installTemplate({
packageVersion,
});
}
- const template = getTemplate(dataset.type, templateName, mappings, pipelineName);
+ const template = getTemplate({
+ type: dataset.type,
+ templateName,
+ mappings,
+ pipelineName,
+ packageName,
+ });
// TODO: Check return values for errors
const callClusterParams: {
method: string;
diff --git a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/template.test.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/template.test.ts
index cacf84381dd88..73a6767f6b947 100644
--- a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/template.test.ts
+++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/template.test.ts
@@ -24,7 +24,12 @@ expect.addSnapshotSerializer({
test('get template', () => {
const templateName = 'logs-nginx-access-abcd';
- const template = getTemplate('logs', templateName, { properties: {} });
+ const template = getTemplate({
+ type: 'logs',
+ templateName,
+ packageName: 'nginx',
+ mappings: { properties: {} },
+ });
expect(template.index_patterns).toStrictEqual([`${templateName}-*`]);
});
@@ -35,7 +40,12 @@ test('tests loading base.yml', () => {
const processedFields = processFields(fields);
const mappings = generateMappings(processedFields);
- const template = getTemplate('logs', 'foo', mappings);
+ const template = getTemplate({
+ type: 'logs',
+ templateName: 'foo',
+ packageName: 'nginx',
+ mappings,
+ });
expect(template).toMatchSnapshot(path.basename(ymlPath));
});
@@ -47,7 +57,12 @@ test('tests loading coredns.logs.yml', () => {
const processedFields = processFields(fields);
const mappings = generateMappings(processedFields);
- const template = getTemplate('logs', 'foo', mappings);
+ const template = getTemplate({
+ type: 'logs',
+ templateName: 'foo',
+ packageName: 'coredns',
+ mappings,
+ });
expect(template).toMatchSnapshot(path.basename(ymlPath));
});
@@ -59,7 +74,12 @@ test('tests loading system.yml', () => {
const processedFields = processFields(fields);
const mappings = generateMappings(processedFields);
- const template = getTemplate('metrics', 'whatsthis', mappings);
+ const template = getTemplate({
+ type: 'metrics',
+ templateName: 'whatsthis',
+ packageName: 'system',
+ mappings,
+ });
expect(template).toMatchSnapshot(path.basename(ymlPath));
});
diff --git a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/template.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/template.ts
index 9e8f327d520e3..06c07da6cd77a 100644
--- a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/template.ts
+++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/template.ts
@@ -37,13 +37,20 @@ const DEFAULT_IGNORE_ABOVE = 1024;
*
* @param indexPattern String with the index pattern
*/
-export function getTemplate(
- type: string,
- templateName: string,
- mappings: IndexTemplateMappings,
- pipelineName?: string | undefined
-): IndexTemplate {
- const template = getBaseTemplate(type, templateName, mappings);
+export function getTemplate({
+ type,
+ templateName,
+ mappings,
+ pipelineName,
+ packageName,
+}: {
+ type: string;
+ templateName: string;
+ mappings: IndexTemplateMappings;
+ pipelineName?: string | undefined;
+ packageName: string;
+}): IndexTemplate {
+ const template = getBaseTemplate(type, templateName, mappings, packageName);
if (pipelineName) {
template.template.settings.index.default_pipeline = pipelineName;
}
@@ -236,7 +243,8 @@ export function generateESIndexPatterns(datasets: Dataset[] | undefined): Record
function getBaseTemplate(
type: string,
templateName: string,
- mappings: IndexTemplateMappings
+ mappings: IndexTemplateMappings,
+ packageName: string
): IndexTemplate {
return {
// This takes precedence over all index templates installed with the 'base' package
@@ -297,6 +305,12 @@ function getBaseTemplate(
data_stream: {
timestamp_field: '@timestamp',
},
+ _meta: {
+ package: {
+ name: packageName,
+ },
+ managed_by: 'ingest-manager',
+ },
};
}
diff --git a/x-pack/plugins/ingest_manager/server/services/epm/packages/remove.ts b/x-pack/plugins/ingest_manager/server/services/epm/packages/remove.ts
index 9b506a2d055a7..94af672d8e29f 100644
--- a/x-pack/plugins/ingest_manager/server/services/epm/packages/remove.ts
+++ b/x-pack/plugins/ingest_manager/server/services/epm/packages/remove.ts
@@ -6,12 +6,12 @@
import { SavedObjectsClientContract } from 'src/core/server';
import Boom from 'boom';
-import { PACKAGES_SAVED_OBJECT_TYPE, DATASOURCE_SAVED_OBJECT_TYPE } from '../../../constants';
+import { PACKAGES_SAVED_OBJECT_TYPE, PACKAGE_CONFIG_SAVED_OBJECT_TYPE } from '../../../constants';
import { AssetReference, AssetType, ElasticsearchAssetType } from '../../../types';
import { CallESAsCurrentUser } from '../../../types';
import { getInstallation, savedObjectTypes } from './index';
import { installIndexPatterns } from '../kibana/index_pattern/install';
-import { datasourceService } from '../..';
+import { packageConfigService } from '../..';
export async function removeInstallation(options: {
savedObjectsClient: SavedObjectsClientContract;
@@ -27,15 +27,15 @@ export async function removeInstallation(options: {
throw Boom.badRequest(`${pkgName} is installed by default and cannot be removed`);
const installedObjects = installation.installed || [];
- const { total } = await datasourceService.list(savedObjectsClient, {
- kuery: `${DATASOURCE_SAVED_OBJECT_TYPE}.package.name:${pkgName}`,
+ const { total } = await packageConfigService.list(savedObjectsClient, {
+ kuery: `${PACKAGE_CONFIG_SAVED_OBJECT_TYPE}.package.name:${pkgName}`,
page: 0,
perPage: 0,
});
if (total > 0)
throw Boom.badRequest(
- `unable to remove package with existing datasource(s) in use by agent(s)`
+ `unable to remove package with existing package config(s) in use by agent(s)`
);
// Delete the manager saved object with references to the asset objects
diff --git a/x-pack/plugins/ingest_manager/server/services/index.ts b/x-pack/plugins/ingest_manager/server/services/index.ts
index 49896959f3c3a..74adab09d12eb 100644
--- a/x-pack/plugins/ingest_manager/server/services/index.ts
+++ b/x-pack/plugins/ingest_manager/server/services/index.ts
@@ -59,8 +59,8 @@ export interface AgentService {
}
// Saved object services
-export { datasourceService } from './datasource';
export { agentConfigService } from './agent_config';
+export { packageConfigService } from './package_config';
export { outputService } from './output';
export { settingsService };
diff --git a/x-pack/plugins/ingest_manager/server/services/datasource.test.ts b/x-pack/plugins/ingest_manager/server/services/package_config.test.ts
similarity index 92%
rename from x-pack/plugins/ingest_manager/server/services/datasource.test.ts
rename to x-pack/plugins/ingest_manager/server/services/package_config.test.ts
index 8d98e41c8ae69..f8dd1c65e3e72 100644
--- a/x-pack/plugins/ingest_manager/server/services/datasource.test.ts
+++ b/x-pack/plugins/ingest_manager/server/services/package_config.test.ts
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { datasourceService } from './datasource';
+import { packageConfigService } from './package_config';
import { PackageInfo } from '../types';
async function mockedGetAssetsData(_a: any, _b: any, dataset: string) {
@@ -37,10 +37,10 @@ jest.mock('./epm/registry', () => {
};
});
-describe('Datasource service', () => {
+describe('Package config service', () => {
describe('assignPackageStream', () => {
it('should work with config variables from the stream', async () => {
- const inputs = await datasourceService.assignPackageStream(
+ const inputs = await packageConfigService.assignPackageStream(
({
datasets: [
{
@@ -89,7 +89,7 @@ describe('Datasource service', () => {
value: ['/var/log/set.log'],
},
},
- agent_stream: {
+ compiled_stream: {
metricset: ['dataset1'],
paths: ['/var/log/set.log'],
type: 'log',
@@ -101,7 +101,7 @@ describe('Datasource service', () => {
});
it('should work with config variables at the input level', async () => {
- const inputs = await datasourceService.assignPackageStream(
+ const inputs = await packageConfigService.assignPackageStream(
({
datasets: [
{
@@ -150,7 +150,7 @@ describe('Datasource service', () => {
id: 'dataset01',
dataset: { name: 'package.dataset1', type: 'logs' },
enabled: true,
- agent_stream: {
+ compiled_stream: {
metricset: ['dataset1'],
paths: ['/var/log/set.log'],
type: 'log',
diff --git a/x-pack/plugins/ingest_manager/server/services/datasource.ts b/x-pack/plugins/ingest_manager/server/services/package_config.ts
similarity index 67%
rename from x-pack/plugins/ingest_manager/server/services/datasource.ts
rename to x-pack/plugins/ingest_manager/server/services/package_config.ts
index fecec0c463459..c886f4868ad30 100644
--- a/x-pack/plugins/ingest_manager/server/services/datasource.ts
+++ b/x-pack/plugins/ingest_manager/server/services/package_config.ts
@@ -6,18 +6,18 @@
import { SavedObjectsClientContract } from 'src/core/server';
import { AuthenticatedUser } from '../../../security/server';
import {
- DeleteDatasourcesResponse,
- packageToConfigDatasource,
- DatasourceInput,
- DatasourceInputStream,
+ DeletePackageConfigsResponse,
+ packageToPackageConfig,
+ PackageConfigInput,
+ PackageConfigInputStream,
PackageInfo,
} from '../../common';
-import { DATASOURCE_SAVED_OBJECT_TYPE } from '../constants';
+import { PACKAGE_CONFIG_SAVED_OBJECT_TYPE } from '../constants';
import {
- NewDatasource,
- Datasource,
+ NewPackageConfig,
+ PackageConfig,
ListWithKuery,
- DatasourceSOAttributes,
+ PackageConfigSOAttributes,
RegistryPackage,
} from '../types';
import { agentConfigService } from './agent_config';
@@ -27,23 +27,23 @@ import { getPackageInfo, getInstallation } from './epm/packages';
import { getAssetsData } from './epm/packages/assets';
import { createStream } from './epm/agent/agent';
-const SAVED_OBJECT_TYPE = DATASOURCE_SAVED_OBJECT_TYPE;
+const SAVED_OBJECT_TYPE = PACKAGE_CONFIG_SAVED_OBJECT_TYPE;
function getDataset(st: string) {
return st.split('.')[1];
}
-class DatasourceService {
+class PackageConfigService {
public async create(
soClient: SavedObjectsClientContract,
- datasource: NewDatasource,
+ packageConfig: NewPackageConfig,
options?: { id?: string; user?: AuthenticatedUser }
- ): Promise {
+ ): Promise {
const isoDate = new Date().toISOString();
- const newSo = await soClient.create(
+ const newSo = await soClient.create(
SAVED_OBJECT_TYPE,
{
- ...datasource,
+ ...packageConfig,
revision: 1,
created_at: isoDate,
created_by: options?.user?.username ?? 'system',
@@ -54,7 +54,7 @@ class DatasourceService {
);
// Assign it to the given agent config
- await agentConfigService.assignDatasources(soClient, datasource.config_id, [newSo.id], {
+ await agentConfigService.assignPackageConfigs(soClient, packageConfig.config_id, [newSo.id], {
user: options?.user,
});
@@ -66,16 +66,16 @@ class DatasourceService {
public async bulkCreate(
soClient: SavedObjectsClientContract,
- datasources: NewDatasource[],
+ packageConfigs: NewPackageConfig[],
configId: string,
options?: { user?: AuthenticatedUser }
- ): Promise {
+ ): Promise {
const isoDate = new Date().toISOString();
- const { saved_objects: newSos } = await soClient.bulkCreate>(
- datasources.map((datasource) => ({
+ const { saved_objects: newSos } = await soClient.bulkCreate>(
+ packageConfigs.map((packageConfig) => ({
type: SAVED_OBJECT_TYPE,
attributes: {
- ...datasource,
+ ...packageConfig,
config_id: configId,
revision: 1,
created_at: isoDate,
@@ -87,7 +87,7 @@ class DatasourceService {
);
// Assign it to the given agent config
- await agentConfigService.assignDatasources(
+ await agentConfigService.assignPackageConfigs(
soClient,
configId,
newSos.map((newSo) => newSo.id),
@@ -102,37 +102,40 @@ class DatasourceService {
}));
}
- public async get(soClient: SavedObjectsClientContract, id: string): Promise {
- const datasourceSO = await soClient.get(SAVED_OBJECT_TYPE, id);
- if (!datasourceSO) {
+ public async get(
+ soClient: SavedObjectsClientContract,
+ id: string
+ ): Promise {
+ const packageConfigSO = await soClient.get(SAVED_OBJECT_TYPE, id);
+ if (!packageConfigSO) {
return null;
}
- if (datasourceSO.error) {
- throw new Error(datasourceSO.error.message);
+ if (packageConfigSO.error) {
+ throw new Error(packageConfigSO.error.message);
}
return {
- id: datasourceSO.id,
- ...datasourceSO.attributes,
+ id: packageConfigSO.id,
+ ...packageConfigSO.attributes,
};
}
public async getByIDs(
soClient: SavedObjectsClientContract,
ids: string[]
- ): Promise {
- const datasourceSO = await soClient.bulkGet(
+ ): Promise {
+ const packageConfigSO = await soClient.bulkGet(
ids.map((id) => ({
id,
type: SAVED_OBJECT_TYPE,
}))
);
- if (!datasourceSO) {
+ if (!packageConfigSO) {
return null;
}
- return datasourceSO.saved_objects.map((so) => ({
+ return packageConfigSO.saved_objects.map((so) => ({
id: so.id,
...so.attributes,
}));
@@ -141,10 +144,10 @@ class DatasourceService {
public async list(
soClient: SavedObjectsClientContract,
options: ListWithKuery
- ): Promise<{ items: Datasource[]; total: number; page: number; perPage: number }> {
+ ): Promise<{ items: PackageConfig[]; total: number; page: number; perPage: number }> {
const { page = 1, perPage = 20, kuery } = options;
- const datasources = await soClient.find({
+ const packageConfigs = await soClient.find({
type: SAVED_OBJECT_TYPE,
page,
perPage,
@@ -158,11 +161,11 @@ class DatasourceService {
});
return {
- items: datasources.saved_objects.map((datasourceSO) => ({
- id: datasourceSO.id,
- ...datasourceSO.attributes,
+ items: packageConfigs.saved_objects.map((packageConfigSO) => ({
+ id: packageConfigSO.id,
+ ...packageConfigSO.attributes,
})),
- total: datasources.total,
+ total: packageConfigs.total,
page,
perPage,
};
@@ -171,46 +174,48 @@ class DatasourceService {
public async update(
soClient: SavedObjectsClientContract,
id: string,
- datasource: NewDatasource,
+ packageConfig: NewPackageConfig,
options?: { user?: AuthenticatedUser }
- ): Promise {
- const oldDatasource = await this.get(soClient, id);
+ ): Promise {
+ const oldPackageConfig = await this.get(soClient, id);
- if (!oldDatasource) {
- throw new Error('Datasource not found');
+ if (!oldPackageConfig) {
+ throw new Error('Package config not found');
}
- await soClient.update(SAVED_OBJECT_TYPE, id, {
- ...datasource,
- revision: oldDatasource.revision + 1,
+ await soClient.update(SAVED_OBJECT_TYPE, id, {
+ ...packageConfig,
+ revision: oldPackageConfig.revision + 1,
updated_at: new Date().toISOString(),
updated_by: options?.user?.username ?? 'system',
});
// Bump revision of associated agent config
- await agentConfigService.bumpRevision(soClient, datasource.config_id, { user: options?.user });
+ await agentConfigService.bumpRevision(soClient, packageConfig.config_id, {
+ user: options?.user,
+ });
- return (await this.get(soClient, id)) as Datasource;
+ return (await this.get(soClient, id)) as PackageConfig;
}
public async delete(
soClient: SavedObjectsClientContract,
ids: string[],
options?: { user?: AuthenticatedUser; skipUnassignFromAgentConfigs?: boolean }
- ): Promise {
- const result: DeleteDatasourcesResponse = [];
+ ): Promise {
+ const result: DeletePackageConfigsResponse = [];
for (const id of ids) {
try {
- const oldDatasource = await this.get(soClient, id);
- if (!oldDatasource) {
- throw new Error('Datasource not found');
+ const oldPackageConfig = await this.get(soClient, id);
+ if (!oldPackageConfig) {
+ throw new Error('Package config not found');
}
if (!options?.skipUnassignFromAgentConfigs) {
- await agentConfigService.unassignDatasources(
+ await agentConfigService.unassignPackageConfigs(
soClient,
- oldDatasource.config_id,
- [oldDatasource.id],
+ oldPackageConfig.config_id,
+ [oldPackageConfig.id],
{
user: options?.user,
}
@@ -232,10 +237,10 @@ class DatasourceService {
return result;
}
- public async buildDatasourceFromPackage(
+ public async buildPackageConfigFromPackage(
soClient: SavedObjectsClientContract,
pkgName: string
- ): Promise {
+ ): Promise {
const pkgInstall = await getInstallation({ savedObjectsClient: soClient, pkgName });
if (pkgInstall) {
const [pkgInfo, defaultOutputId] = await Promise.all([
@@ -250,15 +255,15 @@ class DatasourceService {
if (!defaultOutputId) {
throw new Error('Default output is not set');
}
- return packageToConfigDatasource(pkgInfo, '', defaultOutputId);
+ return packageToPackageConfig(pkgInfo, '', defaultOutputId);
}
}
}
public async assignPackageStream(
pkgInfo: PackageInfo,
- inputs: DatasourceInput[]
- ): Promise {
+ inputs: PackageConfigInput[]
+ ): Promise {
const registryPkgInfo = await Registry.fetchInfo(pkgInfo.name, pkgInfo.version);
const inputsPromises = inputs.map((input) =>
_assignPackageStreamToInput(registryPkgInfo, pkgInfo, input)
@@ -271,7 +276,7 @@ class DatasourceService {
async function _assignPackageStreamToInput(
registryPkgInfo: RegistryPackage,
pkgInfo: PackageInfo,
- input: DatasourceInput
+ input: PackageConfigInput
) {
const streamsPromises = input.streams.map((stream) =>
_assignPackageStreamToStream(registryPkgInfo, pkgInfo, input, stream)
@@ -284,11 +289,11 @@ async function _assignPackageStreamToInput(
async function _assignPackageStreamToStream(
registryPkgInfo: RegistryPackage,
pkgInfo: PackageInfo,
- input: DatasourceInput,
- stream: DatasourceInputStream
+ input: PackageConfigInput,
+ stream: PackageConfigInputStream
) {
if (!stream.enabled) {
- return { ...stream, agent_stream: undefined };
+ return { ...stream, compiled_stream: undefined };
}
const datasetPath = getDataset(stream.dataset.name);
const packageDatasets = pkgInfo.datasets;
@@ -332,10 +337,10 @@ async function _assignPackageStreamToStream(
pkgStream.buffer.toString()
);
- stream.agent_stream = yaml;
+ stream.compiled_stream = yaml;
return { ...stream };
}
-export type DatasourceServiceInterface = DatasourceService;
-export const datasourceService = new DatasourceService();
+export type PackageConfigServiceInterface = PackageConfigService;
+export const packageConfigService = new PackageConfigService();
diff --git a/x-pack/plugins/ingest_manager/server/services/setup.ts b/x-pack/plugins/ingest_manager/server/services/setup.ts
index 9cf1e5b368385..61e1d0ad94db8 100644
--- a/x-pack/plugins/ingest_manager/server/services/setup.ts
+++ b/x-pack/plugins/ingest_manager/server/services/setup.ts
@@ -13,8 +13,8 @@ import { outputService } from './output';
import { ensureInstalledDefaultPackages } from './epm/packages/install';
import { ensureDefaultIndices } from './epm/kibana/index_pattern/install';
import {
- packageToConfigDatasource,
- Datasource,
+ packageToPackageConfig,
+ PackageConfig,
AgentConfig,
Installation,
Output,
@@ -22,7 +22,7 @@ import {
decodeCloudId,
} from '../../common';
import { getPackageInfo } from './epm/packages';
-import { datasourceService } from './datasource';
+import { packageConfigService } from './package_config';
import { generateEnrollmentAPIKey } from './api_keys';
import { settingsService } from '.';
import { appContextService } from './app_context';
@@ -86,13 +86,13 @@ export async function setupIngestManager(
]);
// ensure default packages are added to the default conifg
- const configWithDatasource = await agentConfigService.get(soClient, config.id, true);
- if (!configWithDatasource) {
+ const configWithPackageConfigs = await agentConfigService.get(soClient, config.id, true);
+ if (!configWithPackageConfigs) {
throw new Error('Config not found');
}
if (
- configWithDatasource.datasources.length &&
- typeof configWithDatasource.datasources[0] === 'string'
+ configWithPackageConfigs.package_configs.length &&
+ typeof configWithPackageConfigs.package_configs[0] === 'string'
) {
throw new Error('Config not found');
}
@@ -104,11 +104,19 @@ export async function setupIngestManager(
continue;
}
- const isInstalled = configWithDatasource.datasources.some((d: Datasource | string) => {
- return typeof d !== 'string' && d.package?.name === installedPackage.name;
- });
+ const isInstalled = configWithPackageConfigs.package_configs.some(
+ (d: PackageConfig | string) => {
+ return typeof d !== 'string' && d.package?.name === installedPackage.name;
+ }
+ );
+
if (!isInstalled) {
- await addPackageToConfig(soClient, installedPackage, configWithDatasource, defaultOutput);
+ await addPackageToConfig(
+ soClient,
+ installedPackage,
+ configWithPackageConfigs,
+ defaultOutput
+ );
}
}
@@ -194,17 +202,16 @@ async function addPackageToConfig(
pkgVersion: packageToInstall.version,
});
- const newDatasource = packageToConfigDatasource(
+ const newPackageConfig = packageToPackageConfig(
packageInfo,
config.id,
defaultOutput.id,
- undefined,
config.namespace
);
- newDatasource.inputs = await datasourceService.assignPackageStream(
+ newPackageConfig.inputs = await packageConfigService.assignPackageStream(
packageInfo,
- newDatasource.inputs
+ newPackageConfig.inputs
);
- await datasourceService.create(soClient, newDatasource);
+ await packageConfigService.create(soClient, newPackageConfig);
}
diff --git a/x-pack/plugins/ingest_manager/server/types/index.tsx b/x-pack/plugins/ingest_manager/server/types/index.tsx
index eedb5d86abda3..179474d31bc18 100644
--- a/x-pack/plugins/ingest_manager/server/types/index.tsx
+++ b/x-pack/plugins/ingest_manager/server/types/index.tsx
@@ -17,11 +17,11 @@ export {
AgentEventSOAttributes,
AgentAction,
AgentActionSOAttributes,
- Datasource,
- DatasourceInput,
- DatasourceInputStream,
- NewDatasource,
- DatasourceSOAttributes,
+ PackageConfig,
+ PackageConfigInput,
+ PackageConfigInputStream,
+ NewPackageConfig,
+ PackageConfigSOAttributes,
FullAgentConfigInput,
FullAgentConfig,
AgentConfig,
diff --git a/x-pack/plugins/ingest_manager/server/types/models/agent_config.ts b/x-pack/plugins/ingest_manager/server/types/models/agent_config.ts
index ee91813a48e2f..a9e14301cd7c3 100644
--- a/x-pack/plugins/ingest_manager/server/types/models/agent_config.ts
+++ b/x-pack/plugins/ingest_manager/server/types/models/agent_config.ts
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { schema } from '@kbn/config-schema';
-import { DatasourceSchema } from './datasource';
+import { PackageConfigSchema } from './package_config';
import { AgentConfigStatus } from '../../../common';
const AgentConfigBaseSchema = {
@@ -27,7 +27,10 @@ export const AgentConfigSchema = schema.object({
schema.literal(AgentConfigStatus.Active),
schema.literal(AgentConfigStatus.Inactive),
]),
- datasources: schema.oneOf([schema.arrayOf(schema.string()), schema.arrayOf(DatasourceSchema)]),
+ package_configs: schema.oneOf([
+ schema.arrayOf(schema.string()),
+ schema.arrayOf(PackageConfigSchema),
+ ]),
updated_at: schema.string(),
updated_by: schema.string(),
});
diff --git a/x-pack/plugins/ingest_manager/server/types/models/index.ts b/x-pack/plugins/ingest_manager/server/types/models/index.ts
index 7da36c8a18ad2..268e87eb529be 100644
--- a/x-pack/plugins/ingest_manager/server/types/models/index.ts
+++ b/x-pack/plugins/ingest_manager/server/types/models/index.ts
@@ -5,6 +5,6 @@
*/
export * from './agent_config';
export * from './agent';
-export * from './datasource';
+export * from './package_config';
export * from './output';
export * from './enrollment_api_key';
diff --git a/x-pack/plugins/ingest_manager/server/types/models/datasource.ts b/x-pack/plugins/ingest_manager/server/types/models/package_config.ts
similarity index 84%
rename from x-pack/plugins/ingest_manager/server/types/models/datasource.ts
rename to x-pack/plugins/ingest_manager/server/types/models/package_config.ts
index 114986c4a486e..4b9718dfbe165 100644
--- a/x-pack/plugins/ingest_manager/server/types/models/datasource.ts
+++ b/x-pack/plugins/ingest_manager/server/types/models/package_config.ts
@@ -13,7 +13,7 @@ const ConfigRecordSchema = schema.recordOf(
})
);
-const DatasourceBaseSchema = {
+const PackageConfigBaseSchema = {
name: schema.string(),
description: schema.maybe(schema.string()),
namespace: schema.string({ minLength: 1 }),
@@ -31,7 +31,6 @@ const DatasourceBaseSchema = {
schema.object({
type: schema.string(),
enabled: schema.boolean(),
- processors: schema.maybe(schema.arrayOf(schema.string())),
vars: schema.maybe(ConfigRecordSchema),
config: schema.maybe(
schema.recordOf(
@@ -47,7 +46,6 @@ const DatasourceBaseSchema = {
id: schema.string(),
enabled: schema.boolean(),
dataset: schema.object({ name: schema.string(), type: schema.string() }),
- processors: schema.maybe(schema.arrayOf(schema.string())),
vars: schema.maybe(ConfigRecordSchema),
config: schema.maybe(
schema.recordOf(
@@ -64,11 +62,11 @@ const DatasourceBaseSchema = {
),
};
-export const NewDatasourceSchema = schema.object({
- ...DatasourceBaseSchema,
+export const NewPackageConfigSchema = schema.object({
+ ...PackageConfigBaseSchema,
});
-export const DatasourceSchema = schema.object({
- ...DatasourceBaseSchema,
+export const PackageConfigSchema = schema.object({
+ ...PackageConfigBaseSchema,
id: schema.string(),
});
diff --git a/x-pack/plugins/ingest_manager/server/types/rest_spec/datasource.ts b/x-pack/plugins/ingest_manager/server/types/rest_spec/datasource.ts
deleted file mode 100644
index fce2c94b282bd..0000000000000
--- a/x-pack/plugins/ingest_manager/server/types/rest_spec/datasource.ts
+++ /dev/null
@@ -1,33 +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 { schema } from '@kbn/config-schema';
-import { NewDatasourceSchema } from '../models';
-import { ListWithKuerySchema } from './index';
-
-export const GetDatasourcesRequestSchema = {
- query: ListWithKuerySchema,
-};
-
-export const GetOneDatasourceRequestSchema = {
- params: schema.object({
- datasourceId: schema.string(),
- }),
-};
-
-export const CreateDatasourceRequestSchema = {
- body: NewDatasourceSchema,
-};
-
-export const UpdateDatasourceRequestSchema = {
- ...GetOneDatasourceRequestSchema,
- body: NewDatasourceSchema,
-};
-
-export const DeleteDatasourcesRequestSchema = {
- body: schema.object({
- datasourceIds: schema.arrayOf(schema.string()),
- }),
-};
diff --git a/x-pack/plugins/ingest_manager/server/types/rest_spec/index.ts b/x-pack/plugins/ingest_manager/server/types/rest_spec/index.ts
index 7dc3d4f8f1961..f3ee868f43f00 100644
--- a/x-pack/plugins/ingest_manager/server/types/rest_spec/index.ts
+++ b/x-pack/plugins/ingest_manager/server/types/rest_spec/index.ts
@@ -6,7 +6,7 @@
export * from './common';
export * from './agent_config';
export * from './agent';
-export * from './datasource';
+export * from './package_config';
export * from './epm';
export * from './enrollment_api_key';
export * from './install_script';
diff --git a/x-pack/plugins/ingest_manager/server/types/rest_spec/package_config.ts b/x-pack/plugins/ingest_manager/server/types/rest_spec/package_config.ts
new file mode 100644
index 0000000000000..7b7ae1957c15e
--- /dev/null
+++ b/x-pack/plugins/ingest_manager/server/types/rest_spec/package_config.ts
@@ -0,0 +1,33 @@
+/*
+ * 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 { schema } from '@kbn/config-schema';
+import { NewPackageConfigSchema } from '../models';
+import { ListWithKuerySchema } from './index';
+
+export const GetPackageConfigsRequestSchema = {
+ query: ListWithKuerySchema,
+};
+
+export const GetOnePackageConfigRequestSchema = {
+ params: schema.object({
+ packageConfigId: schema.string(),
+ }),
+};
+
+export const CreatePackageConfigRequestSchema = {
+ body: NewPackageConfigSchema,
+};
+
+export const UpdatePackageConfigRequestSchema = {
+ ...GetOnePackageConfigRequestSchema,
+ body: NewPackageConfigSchema,
+};
+
+export const DeletePackageConfigsRequestSchema = {
+ body: schema.object({
+ packageConfigIds: schema.arrayOf(schema.string()),
+ }),
+};
diff --git a/x-pack/plugins/ingest_pipelines/__jest__/client_integration/fixtures.ts b/x-pack/plugins/ingest_pipelines/__jest__/client_integration/fixtures.ts
new file mode 100644
index 0000000000000..8dddb2421f03d
--- /dev/null
+++ b/x-pack/plugins/ingest_pipelines/__jest__/client_integration/fixtures.ts
@@ -0,0 +1,117 @@
+/*
+ * 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 const nestedProcessorsErrorFixture = {
+ attributes: {
+ error: {
+ root_cause: [
+ {
+ type: 'parse_exception',
+ reason: '[field] required property is missing',
+ property_name: 'field',
+ processor_type: 'circle',
+ suppressed: [
+ {
+ type: 'parse_exception',
+ reason: '[field] required property is missing',
+ property_name: 'field',
+ processor_type: 'circle',
+ },
+ {
+ type: 'parse_exception',
+ reason: '[field] required property is missing',
+ property_name: 'field',
+ processor_type: 'circle',
+ suppressed: [
+ {
+ type: 'parse_exception',
+ reason: '[field] required property is missing',
+ property_name: 'field',
+ processor_type: 'csv',
+ },
+ ],
+ },
+ {
+ type: 'parse_exception',
+ reason: '[field] required property is missing',
+ property_name: 'field',
+ processor_type: 'circle',
+ },
+ {
+ type: 'parse_exception',
+ reason: '[field] required property is missing',
+ property_name: 'field',
+ processor_type: 'circle',
+ },
+ {
+ type: 'parse_exception',
+ reason: '[field] required property is missing',
+ property_name: 'field',
+ processor_type: 'circle',
+ },
+ {
+ type: 'parse_exception',
+ reason: '[field] required property is missing',
+ property_name: 'field',
+ processor_type: 'circle',
+ },
+ ],
+ },
+ ],
+ type: 'parse_exception',
+ reason: '[field] required property is missing',
+ property_name: 'field',
+ processor_type: 'circle',
+ suppressed: [
+ {
+ type: 'parse_exception',
+ reason: '[field] required property is missing',
+ property_name: 'field',
+ processor_type: 'circle',
+ },
+ {
+ type: 'parse_exception',
+ reason: '[field] required property is missing',
+ property_name: 'field',
+ processor_type: 'circle',
+ suppressed: [
+ {
+ type: 'parse_exception',
+ reason: '[field] required property is missing',
+ property_name: 'field',
+ processor_type: 'csv',
+ },
+ ],
+ },
+ {
+ type: 'parse_exception',
+ reason: '[field] required property is missing',
+ property_name: 'field',
+ processor_type: 'circle',
+ },
+ {
+ type: 'parse_exception',
+ reason: '[field] required property is missing',
+ property_name: 'field',
+ processor_type: 'circle',
+ },
+ {
+ type: 'parse_exception',
+ reason: '[field] required property is missing',
+ property_name: 'field',
+ processor_type: 'circle',
+ },
+ {
+ type: 'parse_exception',
+ reason: '[field] required property is missing',
+ property_name: 'field',
+ processor_type: 'circle',
+ },
+ ],
+ },
+ status: 400,
+ },
+};
diff --git a/x-pack/plugins/ingest_pipelines/__jest__/client_integration/helpers/pipeline_form.helpers.ts b/x-pack/plugins/ingest_pipelines/__jest__/client_integration/helpers/pipeline_form.helpers.ts
index 8a14ed13f2022..85848b3d2f73c 100644
--- a/x-pack/plugins/ingest_pipelines/__jest__/client_integration/helpers/pipeline_form.helpers.ts
+++ b/x-pack/plugins/ingest_pipelines/__jest__/client_integration/helpers/pipeline_form.helpers.ts
@@ -42,6 +42,8 @@ export type PipelineFormTestSubjects =
| 'submitButton'
| 'pageTitle'
| 'savePipelineError'
+ | 'savePipelineError.showErrorsButton'
+ | 'savePipelineError.hideErrorsButton'
| 'pipelineForm'
| 'versionToggle'
| 'versionField'
diff --git a/x-pack/plugins/ingest_pipelines/__jest__/client_integration/ingest_pipelines_create.test.tsx b/x-pack/plugins/ingest_pipelines/__jest__/client_integration/ingest_pipelines_create.test.tsx
index 2cfccbdc6d578..813057813f139 100644
--- a/x-pack/plugins/ingest_pipelines/__jest__/client_integration/ingest_pipelines_create.test.tsx
+++ b/x-pack/plugins/ingest_pipelines/__jest__/client_integration/ingest_pipelines_create.test.tsx
@@ -9,6 +9,8 @@ import { act } from 'react-dom/test-utils';
import { setupEnvironment, pageHelpers, nextTick } from './helpers';
import { PipelinesCreateTestBed } from './helpers/pipelines_create.helpers';
+import { nestedProcessorsErrorFixture } from './fixtures';
+
const { setup } = pageHelpers.pipelinesCreate;
jest.mock('@elastic/eui', () => {
@@ -163,6 +165,25 @@ describe('', () => {
expect(exists('savePipelineError')).toBe(true);
expect(find('savePipelineError').text()).toContain(error.message);
});
+
+ test('displays nested pipeline errors as a flat list', async () => {
+ const { actions, find, exists, waitFor } = testBed;
+ httpRequestsMockHelpers.setCreatePipelineResponse(undefined, {
+ body: nestedProcessorsErrorFixture,
+ });
+
+ await act(async () => {
+ actions.clickSubmitButton();
+ await waitFor('savePipelineError');
+ });
+
+ expect(exists('savePipelineError')).toBe(true);
+ expect(exists('savePipelineError.showErrorsButton')).toBe(true);
+ find('savePipelineError.showErrorsButton').simulate('click');
+ expect(exists('savePipelineError.hideErrorsButton')).toBe(true);
+ expect(exists('savePipelineError.showErrorsButton')).toBe(false);
+ expect(find('savePipelineError').find('li').length).toBe(8);
+ });
});
describe('test pipeline', () => {
diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form.tsx
index 05c9f0a08b0c7..a68e667f4ab43 100644
--- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form.tsx
+++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form.tsx
@@ -11,17 +11,18 @@ import { EuiButton, EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiSpacer } from
import { useForm, Form, FormConfig } from '../../../shared_imports';
import { Pipeline } from '../../../../common/types';
-import { PipelineRequestFlyout } from './pipeline_request_flyout';
-import { PipelineTestFlyout } from './pipeline_test_flyout';
-import { PipelineFormFields } from './pipeline_form_fields';
-import { PipelineFormError } from './pipeline_form_error';
-import { pipelineFormSchema } from './schema';
import {
OnUpdateHandlerArg,
OnUpdateHandler,
SerializeResult,
} from '../pipeline_processors_editor';
+import { PipelineRequestFlyout } from './pipeline_request_flyout';
+import { PipelineTestFlyout } from './pipeline_test_flyout';
+import { PipelineFormFields } from './pipeline_form_fields';
+import { PipelineFormError } from './pipeline_form_error';
+import { pipelineFormSchema } from './schema';
+
export interface PipelineFormProps {
onSave: (pipeline: Pipeline) => void;
onCancel: () => void;
@@ -116,7 +117,7 @@ export const PipelineForm: React.FunctionComponent = ({
error={form.getErrors()}
>
{/* Request error */}
- {saveError && }
+ {saveError && }
{/* All form fields */}
= ({ errorMessage }) => {
- return (
- <>
-
- }
- color="danger"
- iconType="alert"
- data-test-subj="savePipelineError"
- >
- {errorMessage}
-
-
- >
- );
-};
diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form_error/error_utils.test.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form_error/error_utils.test.ts
new file mode 100644
index 0000000000000..1739365eb197d
--- /dev/null
+++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form_error/error_utils.test.ts
@@ -0,0 +1,67 @@
+/*
+ * 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 { toKnownError } from './error_utils';
+import { nestedProcessorsErrorFixture } from '../../../../../__jest__/client_integration/fixtures';
+
+describe('toKnownError', () => {
+ test('undefined, null, numbers, arrays and bad objects', () => {
+ expect(toKnownError(undefined)).toEqual({ errors: [{ reason: 'An unknown error occurred.' }] });
+ expect(toKnownError(null)).toEqual({ errors: [{ reason: 'An unknown error occurred.' }] });
+ expect(toKnownError(123)).toEqual({ errors: [{ reason: 'An unknown error occurred.' }] });
+ expect(toKnownError([])).toEqual({ errors: [{ reason: 'An unknown error occurred.' }] });
+ expect(toKnownError({})).toEqual({ errors: [{ reason: 'An unknown error occurred.' }] });
+ expect(toKnownError({ attributes: {} })).toEqual({
+ errors: [{ reason: 'An unknown error occurred.' }],
+ });
+ });
+
+ test('non-processors errors', () => {
+ expect(toKnownError(new Error('my error'))).toEqual({ errors: [{ reason: 'my error' }] });
+ expect(toKnownError({ message: 'my error' })).toEqual({ errors: [{ reason: 'my error' }] });
+ });
+
+ test('processors errors', () => {
+ expect(toKnownError(nestedProcessorsErrorFixture)).toMatchInlineSnapshot(`
+ Object {
+ "errors": Array [
+ Object {
+ "processorType": "circle",
+ "reason": "[field] required property is missing",
+ },
+ Object {
+ "processorType": "circle",
+ "reason": "[field] required property is missing",
+ },
+ Object {
+ "processorType": "circle",
+ "reason": "[field] required property is missing",
+ },
+ Object {
+ "processorType": "csv",
+ "reason": "[field] required property is missing",
+ },
+ Object {
+ "processorType": "circle",
+ "reason": "[field] required property is missing",
+ },
+ Object {
+ "processorType": "circle",
+ "reason": "[field] required property is missing",
+ },
+ Object {
+ "processorType": "circle",
+ "reason": "[field] required property is missing",
+ },
+ Object {
+ "processorType": "circle",
+ "reason": "[field] required property is missing",
+ },
+ ],
+ }
+ `);
+ });
+});
diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form_error/error_utils.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form_error/error_utils.ts
new file mode 100644
index 0000000000000..7f32f962f657c
--- /dev/null
+++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form_error/error_utils.ts
@@ -0,0 +1,85 @@
+/*
+ * 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 * as t from 'io-ts';
+import { flow } from 'fp-ts/lib/function';
+import { isRight } from 'fp-ts/lib/Either';
+
+import { i18nTexts } from './i18n_texts';
+
+export interface PipelineError {
+ reason: string;
+ processorType?: string;
+}
+interface PipelineErrors {
+ errors: PipelineError[];
+}
+
+interface ErrorNode {
+ reason: string;
+ processor_type?: string;
+ suppressed?: ErrorNode[];
+}
+
+// This is a runtime type (RT) for an error node which is a recursive type
+const errorNodeRT = t.recursion('ErrorNode', (ErrorNode) =>
+ t.intersection([
+ t.interface({
+ reason: t.string,
+ }),
+ t.partial({
+ processor_type: t.string,
+ suppressed: t.array(ErrorNode),
+ }),
+ ])
+);
+
+// This is a runtime type for the attributes object we expect to receive from the server
+// for processor errors
+const errorAttributesObjectRT = t.interface({
+ attributes: t.interface({
+ error: t.interface({
+ root_cause: t.array(errorNodeRT),
+ }),
+ }),
+});
+
+const isProcessorsError = flow(errorAttributesObjectRT.decode, isRight);
+
+type ErrorAttributesObject = t.TypeOf;
+
+const flattenErrorsTree = (node: ErrorNode): PipelineError[] => {
+ const result: PipelineError[] = [];
+ const recurse = (_node: ErrorNode) => {
+ result.push({ reason: _node.reason, processorType: _node.processor_type });
+ if (_node.suppressed && Array.isArray(_node.suppressed)) {
+ _node.suppressed.forEach(recurse);
+ }
+ };
+ recurse(node);
+ return result;
+};
+
+export const toKnownError = (error: unknown): PipelineErrors => {
+ if (typeof error === 'object' && error != null && isProcessorsError(error)) {
+ const errorAttributes = error as ErrorAttributesObject;
+ const rootCause = errorAttributes.attributes.error.root_cause[0];
+ return { errors: flattenErrorsTree(rootCause) };
+ }
+
+ if (typeof error === 'string') {
+ return { errors: [{ reason: error }] };
+ }
+
+ if (
+ error instanceof Error ||
+ (typeof error === 'object' && error != null && (error as any).message)
+ ) {
+ return { errors: [{ reason: (error as any).message }] };
+ }
+
+ return { errors: [{ reason: i18nTexts.errors.unknownError }] };
+};
diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form_error/i18n_texts.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form_error/i18n_texts.ts
new file mode 100644
index 0000000000000..e354541db8e7b
--- /dev/null
+++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form_error/i18n_texts.ts
@@ -0,0 +1,38 @@
+/*
+ * 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 { i18n } from '@kbn/i18n';
+
+export const i18nTexts = {
+ title: i18n.translate('xpack.ingestPipelines.form.savePipelineError', {
+ defaultMessage: 'Unable to create pipeline',
+ }),
+ errors: {
+ processor: (processorType: string) =>
+ i18n.translate('xpack.ingestPipelines.form.savePipelineError.processorLabel', {
+ defaultMessage: '{type} processor',
+ values: { type: processorType },
+ }),
+ showErrors: (hiddenErrorsCount: number) =>
+ i18n.translate('xpack.ingestPipelines.form.savePipelineError.showAllButton', {
+ defaultMessage:
+ 'Show {hiddenErrorsCount, plural, one {# more error} other {# more errors}}',
+ values: {
+ hiddenErrorsCount,
+ },
+ }),
+ hideErrors: (hiddenErrorsCount: number) =>
+ i18n.translate('xpack.ingestPipelines.form.savePip10mbelineError.showFewerButton', {
+ defaultMessage: 'Hide {hiddenErrorsCount, plural, one {# error} other {# errors}}',
+ values: {
+ hiddenErrorsCount,
+ },
+ }),
+ unknownError: i18n.translate('xpack.ingestPipelines.form.unknownError', {
+ defaultMessage: 'An unknown error occurred.',
+ }),
+ },
+};
diff --git a/x-pack/plugins/ingest_manager/common/constants/datasource.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form_error/index.ts
similarity index 78%
rename from x-pack/plugins/ingest_manager/common/constants/datasource.ts
rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form_error/index.ts
index 08113cff53bda..656691f639498 100644
--- a/x-pack/plugins/ingest_manager/common/constants/datasource.ts
+++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form_error/index.ts
@@ -4,4 +4,4 @@
* you may not use this file except in compliance with the Elastic License.
*/
-export const DATASOURCE_SAVED_OBJECT_TYPE = 'ingest-datasources';
+export { PipelineFormError } from './pipeline_form_error';
diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form_error/pipeline_form_error.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form_error/pipeline_form_error.tsx
new file mode 100644
index 0000000000000..23fb9a1648434
--- /dev/null
+++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form_error/pipeline_form_error.tsx
@@ -0,0 +1,99 @@
+/*
+ * 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 React, { useState, useEffect } from 'react';
+
+import { EuiSpacer, EuiCallOut, EuiFlexGroup, EuiFlexItem, EuiButtonEmpty } from '@elastic/eui';
+import { useKibana } from '../../../../shared_imports';
+
+import { i18nTexts } from './i18n_texts';
+import { toKnownError, PipelineError } from './error_utils';
+
+interface Props {
+ error: unknown;
+}
+
+const numberOfErrorsToDisplay = 5;
+
+export const PipelineFormError: React.FunctionComponent = ({ error }) => {
+ const { services } = useKibana();
+ const [isShowingAllErrors, setIsShowingAllErrors] = useState(false);
+ const safeErrorResult = toKnownError(error);
+ const hasMoreErrors = safeErrorResult.errors.length > numberOfErrorsToDisplay;
+ const hiddenErrorsCount = safeErrorResult.errors.length - numberOfErrorsToDisplay;
+ const results = isShowingAllErrors
+ ? safeErrorResult.errors
+ : safeErrorResult.errors.slice(0, numberOfErrorsToDisplay);
+
+ const renderErrorListItem = ({ processorType, reason }: PipelineError) => {
+ return (
+ <>
+ {processorType ? <>{i18nTexts.errors.processor(processorType) + ':'} > : undefined}
+ {reason}
+ >
+ );
+ };
+
+ useEffect(() => {
+ services.notifications.toasts.addDanger({ title: i18nTexts.title });
+ }, [services, error]);
+ return (
+ <>
+
+ {results.length > 1 ? (
+
+ {results.map((e, idx) => (
+ - {renderErrorListItem(e)}
+ ))}
+
+ ) : (
+ renderErrorListItem(results[0])
+ )}
+ {hasMoreErrors ? (
+
+
+ {isShowingAllErrors ? (
+ setIsShowingAllErrors(false)}
+ color="danger"
+ iconSide="right"
+ iconType="arrowUp"
+ data-test-subj="hideErrorsButton"
+ >
+ {i18nTexts.errors.hideErrors(hiddenErrorsCount)}
+
+ ) : (
+ setIsShowingAllErrors(true)}
+ color="danger"
+ iconSide="right"
+ iconType="arrowDown"
+ data-test-subj="showErrorsButton"
+ >
+ {i18nTexts.errors.showErrors(hiddenErrorsCount)}
+
+ )}
+
+
+ ) : undefined}
+
+
+ >
+ );
+};
diff --git a/x-pack/plugins/ingest_pipelines/server/routes/api/create.ts b/x-pack/plugins/ingest_pipelines/server/routes/api/create.ts
index c1ab3852ee784..c2328bcc9d0ab 100644
--- a/x-pack/plugins/ingest_pipelines/server/routes/api/create.ts
+++ b/x-pack/plugins/ingest_pipelines/server/routes/api/create.ts
@@ -10,6 +10,7 @@ import { Pipeline } from '../../../common/types';
import { API_BASE_PATH } from '../../../common/constants';
import { RouteDependencies } from '../../types';
import { pipelineSchema } from './pipeline_schema';
+import { isObjectWithKeys } from './shared';
const bodySchema = schema.object({
name: schema.string(),
@@ -70,7 +71,12 @@ export const registerCreateRoute = ({
if (isEsError(error)) {
return res.customError({
statusCode: error.statusCode,
- body: error,
+ body: isObjectWithKeys(error.body)
+ ? {
+ message: error.message,
+ attributes: error.body,
+ }
+ : error,
});
}
diff --git a/x-pack/plugins/security_solution/server/endpoint/alerts/handlers/details/schemas.ts b/x-pack/plugins/ingest_pipelines/server/routes/api/shared/index.ts
similarity index 66%
rename from x-pack/plugins/security_solution/server/endpoint/alerts/handlers/details/schemas.ts
rename to x-pack/plugins/ingest_pipelines/server/routes/api/shared/index.ts
index 18dc5f703b412..1fa794a4fb996 100644
--- a/x-pack/plugins/security_solution/server/endpoint/alerts/handlers/details/schemas.ts
+++ b/x-pack/plugins/ingest_pipelines/server/routes/api/shared/index.ts
@@ -3,8 +3,5 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
-import { schema } from '@kbn/config-schema';
-export const alertDetailsReqSchema = schema.object({
- id: schema.string(),
-});
+export { isObjectWithKeys } from './is_object_with_keys';
diff --git a/x-pack/plugins/security_solution/common/endpoint_alerts/schema/index_pattern.ts b/x-pack/plugins/ingest_pipelines/server/routes/api/shared/is_object_with_keys.ts
similarity index 63%
rename from x-pack/plugins/security_solution/common/endpoint_alerts/schema/index_pattern.ts
rename to x-pack/plugins/ingest_pipelines/server/routes/api/shared/is_object_with_keys.ts
index 2809004f88c6e..0617bde26cfb6 100644
--- a/x-pack/plugins/security_solution/common/endpoint_alerts/schema/index_pattern.ts
+++ b/x-pack/plugins/ingest_pipelines/server/routes/api/shared/is_object_with_keys.ts
@@ -4,6 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { schema } from '@kbn/config-schema';
-
-export const indexPatternGetParamsSchema = schema.object({ datasetPath: schema.string() });
+export const isObjectWithKeys = (value: unknown) => {
+ return typeof value === 'object' && !!value && Object.keys(value).length > 0;
+};
diff --git a/x-pack/plugins/ingest_pipelines/server/routes/api/update.ts b/x-pack/plugins/ingest_pipelines/server/routes/api/update.ts
index 214b293a43c6c..cd0e3568f0f60 100644
--- a/x-pack/plugins/ingest_pipelines/server/routes/api/update.ts
+++ b/x-pack/plugins/ingest_pipelines/server/routes/api/update.ts
@@ -8,6 +8,7 @@ import { schema } from '@kbn/config-schema';
import { API_BASE_PATH } from '../../../common/constants';
import { RouteDependencies } from '../../types';
import { pipelineSchema } from './pipeline_schema';
+import { isObjectWithKeys } from './shared';
const bodySchema = schema.object(pipelineSchema);
@@ -52,7 +53,12 @@ export const registerUpdateRoute = ({
if (isEsError(error)) {
return res.customError({
statusCode: error.statusCode,
- body: error,
+ body: isObjectWithKeys(error.body)
+ ? {
+ message: error.message,
+ attributes: error.body,
+ }
+ : error,
});
}
diff --git a/x-pack/plugins/lens/public/app_plugin/app.test.tsx b/x-pack/plugins/lens/public/app_plugin/app.test.tsx
index cd6fbf96d6750..3bd12a87456a0 100644
--- a/x-pack/plugins/lens/public/app_plugin/app.test.tsx
+++ b/x-pack/plugins/lens/public/app_plugin/app.test.tsx
@@ -226,6 +226,7 @@ describe('Lens App', () => {
"query": "",
},
"savedQuery": undefined,
+ "showNoDataPopover": [Function],
},
],
]
diff --git a/x-pack/plugins/lens/public/app_plugin/app.tsx b/x-pack/plugins/lens/public/app_plugin/app.tsx
index 0ab547bed6d37..9b8b9a8531cf0 100644
--- a/x-pack/plugins/lens/public/app_plugin/app.tsx
+++ b/x-pack/plugins/lens/public/app_plugin/app.tsx
@@ -40,6 +40,7 @@ import {
} from '../../../../../src/plugins/data/public';
interface State {
+ indicateNoData: boolean;
isLoading: boolean;
isSaveModalVisible: boolean;
indexPatternsForTopNav: IndexPatternInstance[];
@@ -97,9 +98,27 @@ export function App({
toDate: currentRange.to,
},
filters: [],
+ indicateNoData: false,
};
});
+ const showNoDataPopover = useCallback(() => {
+ setState((prevState) => ({ ...prevState, indicateNoData: true }));
+ }, [setState]);
+
+ useEffect(() => {
+ if (state.indicateNoData) {
+ setState((prevState) => ({ ...prevState, indicateNoData: false }));
+ }
+ }, [
+ setState,
+ state.indicateNoData,
+ state.query,
+ state.filters,
+ state.dateRange,
+ state.indexPatternsForTopNav,
+ ]);
+
const { lastKnownDoc } = state;
const isSaveable =
@@ -458,6 +477,7 @@ export function App({
query={state.query}
dateRangeFrom={state.dateRange.fromDate}
dateRangeTo={state.dateRange.toDate}
+ indicateNoData={state.indicateNoData}
/>
@@ -472,6 +492,7 @@ export function App({
savedQuery: state.savedQuery,
doc: state.persistedDoc,
onError,
+ showNoDataPopover,
onChange: ({ filterableIndexPatterns, doc }) => {
if (!_.isEqual(state.persistedDoc, doc)) {
setState((s) => ({ ...s, lastKnownDoc: doc }));
diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/_index.scss b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/_index.scss
index 8f09a358dd5e4..5b968abd0c061 100644
--- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/_index.scss
+++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/_index.scss
@@ -1,4 +1,3 @@
-@import 'chart_switch';
@import 'config_panel';
@import 'dimension_popover';
@import 'layer_panel';
diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx
index e53e465c18950..7f4a48fa2fda2 100644
--- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx
+++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx
@@ -8,7 +8,6 @@ import React, { useMemo, memo } from 'react';
import { EuiFlexItem, EuiToolTip, EuiButton, EuiForm } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { Visualization } from '../../../types';
-import { ChartSwitch } from './chart_switch';
import { LayerPanel } from './layer_panel';
import { trackUiEvent } from '../../../lens_ui_telemetry';
import { generateId } from '../../../id_generator';
@@ -20,21 +19,8 @@ export const ConfigPanelWrapper = memo(function ConfigPanelWrapper(props: Config
const { visualizationState } = props;
return (
- <>
-
- {activeVisualization && visualizationState && (
-
- )}
- >
+ activeVisualization &&
+ visualizationState &&
);
});
diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx
index bd501db2b752a..36d5bfd965e26 100644
--- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx
+++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx
@@ -186,7 +186,7 @@ export function LayerPanel(
},
];
- if (activeVisualization.renderDimensionEditor) {
+ if (activeVisualization.renderDimensionEditor && group.enableDimensionEditor) {
tabs.push({
id: 'visualization',
name: i18n.translate('xpack.lens.editorFrame.formatStyleLabel', {
diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.tsx
index afb2719f28e89..0f74abe97c418 100644
--- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.tsx
+++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.tsx
@@ -19,6 +19,7 @@ interface DataPanelWrapperProps {
activeDatasource: string | null;
datasourceIsLoading: boolean;
dispatch: (action: Action) => void;
+ showNoDataPopover: () => void;
core: DatasourceDataPanelProps['core'];
query: Query;
dateRange: FramePublicAPI['dateRange'];
@@ -46,6 +47,7 @@ export const DataPanelWrapper = memo((props: DataPanelWrapperProps) => {
query: props.query,
dateRange: props.dateRange,
filters: props.filters,
+ showNoDataPopover: props.showNoDataPopover,
};
const [showDatasourceSwitcher, setDatasourceSwitcher] = useState(false);
diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx
index ff9e24f95d1e2..ad4f6e74c9e92 100644
--- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx
+++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx
@@ -56,6 +56,7 @@ function getDefaultProps() {
data: dataPluginMock.createStartContract(),
expressions: expressionsPluginMock.createStartContract(),
},
+ showNoDataPopover: jest.fn(),
};
}
diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx
index af3d0ed068d2f..bcceb1222ce03 100644
--- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx
+++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx
@@ -48,6 +48,7 @@ export interface EditorFrameProps {
filterableIndexPatterns: DatasourceMetaData['filterableIndexPatterns'];
doc: Document;
}) => void;
+ showNoDataPopover: () => void;
}
export function EditorFrame(props: EditorFrameProps) {
@@ -255,6 +256,7 @@ export function EditorFrame(props: EditorFrameProps) {
query={props.query}
dateRange={props.dateRange}
filters={props.filters}
+ showNoDataPopover={props.showNoDataPopover}
/>
}
configPanel={
diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_management.test.ts b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_management.test.ts
index e1151b92aac51..969467b5789ec 100644
--- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_management.test.ts
+++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_management.test.ts
@@ -35,6 +35,7 @@ describe('editor_frame state management', () => {
dateRange: { fromDate: 'now-7d', toDate: 'now' },
query: { query: '', language: 'lucene' },
filters: [],
+ showNoDataPopover: jest.fn(),
};
});
diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/_chart_switch.scss b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/chart_switch.scss
similarity index 86%
rename from x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/_chart_switch.scss
rename to x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/chart_switch.scss
index d7efab2405f3f..ae4a7861b1d90 100644
--- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/_chart_switch.scss
+++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/chart_switch.scss
@@ -1,6 +1,4 @@
.lnsChartSwitch__header {
- padding: $euiSizeS 0;
-
> * {
display: flex;
align-items: center;
@@ -9,7 +7,8 @@
.lnsChartSwitch__triggerButton {
@include euiTitle('xs');
- line-height: $euiSizeXXL;
+ background-color: $euiColorEmptyShade;
+ border-color: $euiColorLightShade;
}
.lnsChartSwitch__summaryIcon {
diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/chart_switch.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/chart_switch.test.tsx
similarity index 100%
rename from x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/chart_switch.test.tsx
rename to x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/chart_switch.test.tsx
diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/chart_switch.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/chart_switch.tsx
similarity index 98%
rename from x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/chart_switch.tsx
rename to x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/chart_switch.tsx
index e212cb70d1855..4c5a44ecc695e 100644
--- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/chart_switch.tsx
+++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/chart_switch.tsx
@@ -11,7 +11,7 @@ import {
EuiPopoverTitle,
EuiKeyPadMenu,
EuiKeyPadMenuItem,
- EuiButtonEmpty,
+ EuiButton,
} from '@elastic/eui';
import { flatten } from 'lodash';
import { i18n } from '@kbn/i18n';
@@ -72,6 +72,8 @@ function VisualizationSummary(props: Props) {
);
}
+import './chart_switch.scss';
+
export function ChartSwitch(props: Props) {
const [flyoutOpen, setFlyoutOpen] = useState(false);
@@ -198,20 +200,18 @@ export function ChartSwitch(props: Props) {
ownFocus
initialFocus=".lnsChartSwitch__popoverPanel"
panelClassName="lnsChartSwitch__popoverPanel"
- anchorClassName="eui-textTruncate"
panelPaddingSize="s"
button={
- setFlyoutOpen(!flyoutOpen)}
data-test-subj="lnsChartSwitchPopover"
- flush="left"
iconSide="right"
iconType="arrowDown"
color="text"
>
-
+
}
isOpen={flyoutOpen}
closePopover={() => setFlyoutOpen(false)}
diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/index.ts b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/index.ts
new file mode 100644
index 0000000000000..d23afd4129cbe
--- /dev/null
+++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/index.ts
@@ -0,0 +1,7 @@
+/*
+ * 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 { WorkspacePanel } from './workspace_panel';
diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.test.tsx
similarity index 97%
rename from x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel.test.tsx
rename to x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.test.tsx
index 49d12e9f41440..a9c638df8cad1 100644
--- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel.test.tsx
+++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.test.tsx
@@ -6,19 +6,19 @@
import React from 'react';
import { act } from 'react-dom/test-utils';
-import { ReactExpressionRendererProps } from '../../../../../../src/plugins/expressions/public';
-import { FramePublicAPI, TableSuggestion, Visualization } from '../../types';
+import { ReactExpressionRendererProps } from '../../../../../../../src/plugins/expressions/public';
+import { FramePublicAPI, TableSuggestion, Visualization } from '../../../types';
import {
createMockVisualization,
createMockDatasource,
createExpressionRendererMock,
DatasourceMock,
createMockFramePublicAPI,
-} from '../mocks';
+} from '../../mocks';
import { InnerWorkspacePanel, WorkspacePanelProps } from './workspace_panel';
import { mountWithIntl as mount } from 'test_utils/enzyme_helpers';
import { ReactWrapper } from 'enzyme';
-import { DragDrop, ChildDragDropProvider } from '../../drag_drop';
+import { DragDrop, ChildDragDropProvider } from '../../../drag_drop';
import { Ast } from '@kbn/interpreter/common';
import { coreMock } from 'src/core/public/mocks';
import {
@@ -26,12 +26,12 @@ import {
esFilters,
IFieldType,
IIndexPattern,
-} from '../../../../../../src/plugins/data/public';
-import { TriggerId, UiActionsStart } from '../../../../../../src/plugins/ui_actions/public';
-import { uiActionsPluginMock } from '../../../../../../src/plugins/ui_actions/public/mocks';
-import { TriggerContract } from '../../../../../../src/plugins/ui_actions/public/triggers';
-import { VIS_EVENT_TO_TRIGGER } from '../../../../../../src/plugins/visualizations/public/embeddable';
-import { dataPluginMock } from '../../../../../../src/plugins/data/public/mocks';
+} from '../../../../../../../src/plugins/data/public';
+import { TriggerId, UiActionsStart } from '../../../../../../../src/plugins/ui_actions/public';
+import { uiActionsPluginMock } from '../../../../../../../src/plugins/ui_actions/public/mocks';
+import { TriggerContract } from '../../../../../../../src/plugins/ui_actions/public/triggers';
+import { VIS_EVENT_TO_TRIGGER } from '../../../../../../../src/plugins/visualizations/public/embeddable';
+import { dataPluginMock } from '../../../../../../../src/plugins/data/public/mocks';
describe('workspace_panel', () => {
let mockVisualization: jest.Mocked;
diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx
similarity index 91%
rename from x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel.tsx
rename to x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx
index 670afe28293a4..beb6952556067 100644
--- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel.tsx
+++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx
@@ -20,23 +20,23 @@ import { CoreStart, CoreSetup } from 'kibana/public';
import {
ExpressionRendererEvent,
ReactExpressionRendererType,
-} from '../../../../../../src/plugins/expressions/public';
-import { Action } from './state_management';
+} from '../../../../../../../src/plugins/expressions/public';
+import { Action } from '../state_management';
import {
Datasource,
Visualization,
FramePublicAPI,
isLensBrushEvent,
isLensFilterEvent,
-} from '../../types';
-import { DragDrop, DragContext } from '../../drag_drop';
-import { getSuggestions, switchToSuggestion } from './suggestion_helpers';
-import { buildExpression } from './expression_helpers';
-import { debouncedComponent } from '../../debounced_component';
-import { trackUiEvent } from '../../lens_ui_telemetry';
-import { UiActionsStart } from '../../../../../../src/plugins/ui_actions/public';
-import { VIS_EVENT_TO_TRIGGER } from '../../../../../../src/plugins/visualizations/public';
-import { DataPublicPluginStart } from '../../../../../../src/plugins/data/public';
+} from '../../../types';
+import { DragDrop, DragContext } from '../../../drag_drop';
+import { getSuggestions, switchToSuggestion } from '../suggestion_helpers';
+import { buildExpression } from '../expression_helpers';
+import { debouncedComponent } from '../../../debounced_component';
+import { trackUiEvent } from '../../../lens_ui_telemetry';
+import { UiActionsStart } from '../../../../../../../src/plugins/ui_actions/public';
+import { VIS_EVENT_TO_TRIGGER } from '../../../../../../../src/plugins/visualizations/public';
+import { DataPublicPluginStart } from '../../../../../../../src/plugins/data/public';
import { WorkspacePanelWrapper } from './workspace_panel_wrapper';
export interface WorkspacePanelProps {
@@ -300,7 +300,10 @@ export function InnerWorkspacePanel({
dispatch={dispatch}
emptyExpression={expression === null}
visualizationState={visualizationState}
- activeVisualization={activeVisualization}
+ visualizationId={activeVisualizationId}
+ datasourceStates={datasourceStates}
+ datasourceMap={datasourceMap}
+ visualizationMap={visualizationMap}
>
{
dispatch={jest.fn()}
framePublicAPI={mockFrameAPI}
visualizationState={{}}
- activeVisualization={mockVisualization}
+ visualizationId="myVis"
+ visualizationMap={{ myVis: mockVisualization }}
+ datasourceMap={{}}
+ datasourceStates={{}}
emptyExpression={false}
>
@@ -51,7 +54,10 @@ describe('workspace_panel_wrapper', () => {
framePublicAPI={mockFrameAPI}
visualizationState={visState}
children={}
- activeVisualization={{ ...mockVisualization, renderToolbar: renderToolbarMock }}
+ visualizationId="myVis"
+ visualizationMap={{ myVis: { ...mockVisualization, renderToolbar: renderToolbarMock } }}
+ datasourceMap={{}}
+ datasourceStates={{}}
emptyExpression={false}
/>
);
diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel_wrapper.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx
similarity index 69%
rename from x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel_wrapper.tsx
rename to x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx
index 17461b9fc274f..60c31e5d090e5 100644
--- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel_wrapper.tsx
+++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx
@@ -14,29 +14,43 @@ import {
EuiFlexGroup,
EuiFlexItem,
} from '@elastic/eui';
-import { FramePublicAPI, Visualization } from '../../types';
-import { NativeRenderer } from '../../native_renderer';
-import { Action } from './state_management';
+import { Datasource, FramePublicAPI, Visualization } from '../../../types';
+import { NativeRenderer } from '../../../native_renderer';
+import { Action } from '../state_management';
+import { ChartSwitch } from './chart_switch';
export interface WorkspacePanelWrapperProps {
children: React.ReactNode | React.ReactNode[];
framePublicAPI: FramePublicAPI;
visualizationState: unknown;
- activeVisualization: Visualization | null;
dispatch: (action: Action) => void;
emptyExpression: boolean;
title?: string;
+ visualizationMap: Record;
+ visualizationId: string | null;
+ datasourceMap: Record;
+ datasourceStates: Record<
+ string,
+ {
+ isLoading: boolean;
+ state: unknown;
+ }
+ >;
}
export function WorkspacePanelWrapper({
children,
framePublicAPI,
visualizationState,
- activeVisualization,
dispatch,
title,
emptyExpression,
+ visualizationId,
+ visualizationMap,
+ datasourceMap,
+ datasourceStates,
}: WorkspacePanelWrapperProps) {
+ const activeVisualization = visualizationId ? visualizationMap[visualizationId] : null;
const setVisualizationState = useCallback(
(newState: unknown) => {
if (!activeVisualization) {
@@ -52,7 +66,19 @@ export function WorkspacePanelWrapper({
[dispatch]
);
return (
-
+
+
+
+
{activeVisualization && activeVisualization.renderToolbar && (
{
dateRange: { fromDate: '', toDate: '' },
query: { query: '', language: 'lucene' },
filters: [],
+ showNoDataPopover: jest.fn(),
});
instance.unmount();
})()
@@ -70,6 +71,7 @@ describe('editor_frame service', () => {
dateRange: { fromDate: '', toDate: '' },
query: { query: '', language: 'lucene' },
filters: [],
+ showNoDataPopover: jest.fn(),
});
instance.unmount();
diff --git a/x-pack/plugins/lens/public/editor_frame_service/service.tsx b/x-pack/plugins/lens/public/editor_frame_service/service.tsx
index f57acf3bef62d..47339373b6d1a 100644
--- a/x-pack/plugins/lens/public/editor_frame_service/service.tsx
+++ b/x-pack/plugins/lens/public/editor_frame_service/service.tsx
@@ -102,7 +102,10 @@ export class EditorFrameService {
]);
return {
- mount: (element, { doc, onError, dateRange, query, filters, savedQuery, onChange }) => {
+ mount: (
+ element,
+ { doc, onError, dateRange, query, filters, savedQuery, onChange, showNoDataPopover }
+ ) => {
domElement = element;
const firstDatasourceId = Object.keys(resolvedDatasources)[0];
const firstVisualizationId = Object.keys(resolvedVisualizations)[0];
@@ -127,6 +130,7 @@ export class EditorFrameService {
filters={filters}
savedQuery={savedQuery}
onChange={onChange}
+ showNoDataPopover={showNoDataPopover}
/>