mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Fleet] Do not allow namespace or dataset to be edited for input only package policies (#148422)
## Summary Part of #145529. Input packages will create component and index templates on package policy creation. These changes make it so that to change the namespace or dataset of an input only package the user must create a new package policy, this is because by changing these the user is sending the data to a new destination which semantically is a different policy. ❓ Question: what do we publicly call package policies? Here is the new text I have added: <img width="674" alt="Screenshot 2023-01-04 at 21 05 15" src="https://user-images.githubusercontent.com/3315046/210650968-79460ff4-dd52-47bd-beb6-a0ace608bcbb.png">
This commit is contained in:
parent
0707da5be1
commit
f1ede739a3
13 changed files with 252 additions and 35 deletions
|
@ -20,7 +20,7 @@ const DATA_STREAM_DATASET_VAR: RegistryVarsEntry = {
|
|||
type: 'text',
|
||||
title: 'Dataset name',
|
||||
description:
|
||||
"Set the name for your dataset. Changing the dataset will send the data to a different index. You can't use `-` in the name of a dataset and only valid characters for [Elasticsearch index names](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-index_.html).\n",
|
||||
"Set the name for your dataset. Once selected a dataset cannot be changed without creating a new integration policy. You can't use `-` in the name of a dataset and only valid characters for [Elasticsearch index names](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-index_.html) are permitted.\n",
|
||||
multi: false,
|
||||
required: true,
|
||||
show_user: true,
|
||||
|
|
|
@ -13,7 +13,8 @@ export const DatasetComboBox: React.FC<{
|
|||
value: any;
|
||||
onChange: (newValue: any) => void;
|
||||
datasets: string[];
|
||||
}> = ({ value, onChange, datasets }) => {
|
||||
isDisabled?: boolean;
|
||||
}> = ({ value, onChange, datasets, isDisabled }) => {
|
||||
const datasetOptions = datasets.map((dataset: string) => ({ label: dataset })) ?? [];
|
||||
const defaultOption = 'generic';
|
||||
const [selectedOptions, setSelectedOptions] = useState<Array<{ label: string }>>([
|
||||
|
@ -42,7 +43,6 @@ export const DatasetComboBox: React.FC<{
|
|||
setSelectedOptions([newOption]);
|
||||
onChange(searchValue);
|
||||
};
|
||||
|
||||
return (
|
||||
<EuiComboBox
|
||||
aria-label={i18n.translate('xpack.fleet.datasetCombo.ariaLabel', {
|
||||
|
@ -61,6 +61,7 @@ export const DatasetComboBox: React.FC<{
|
|||
values: { searchValue: '{searchValue}' },
|
||||
})}
|
||||
isClearable={false}
|
||||
isDisabled={isDisabled}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -29,6 +29,7 @@ export const PackagePolicyInputConfig: React.FunctionComponent<{
|
|||
updatePackagePolicyInput: (updatedInput: Partial<NewPackagePolicyInput>) => void;
|
||||
inputVarsValidationResults: PackagePolicyConfigValidationResults;
|
||||
forceShowErrors?: boolean;
|
||||
isEditPage?: boolean;
|
||||
}> = memo(
|
||||
({
|
||||
hasInputStreams,
|
||||
|
@ -37,6 +38,7 @@ export const PackagePolicyInputConfig: React.FunctionComponent<{
|
|||
updatePackagePolicyInput,
|
||||
inputVarsValidationResults,
|
||||
forceShowErrors,
|
||||
isEditPage = false,
|
||||
}) => {
|
||||
// Showing advanced options toggle state
|
||||
const [isShowingAdvanced, setIsShowingAdvanced] = useState<boolean>(false);
|
||||
|
@ -121,6 +123,7 @@ export const PackagePolicyInputConfig: React.FunctionComponent<{
|
|||
}}
|
||||
errors={inputVarsValidationResults.vars?.[varName]}
|
||||
forceShowErrors={forceShowErrors}
|
||||
isEditPage={isEditPage}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
);
|
||||
|
@ -178,6 +181,7 @@ export const PackagePolicyInputConfig: React.FunctionComponent<{
|
|||
}}
|
||||
errors={inputVarsValidationResults.vars?.[varName]}
|
||||
forceShowErrors={forceShowErrors}
|
||||
isEditPage={isEditPage}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
);
|
||||
|
|
|
@ -80,6 +80,7 @@ export const PackagePolicyInputPanel: React.FunctionComponent<{
|
|||
updatePackagePolicyInput: (updatedInput: Partial<NewPackagePolicyInput>) => void;
|
||||
inputValidationResults: PackagePolicyInputValidationResults;
|
||||
forceShowErrors?: boolean;
|
||||
isEditPage?: boolean;
|
||||
}> = memo(
|
||||
({
|
||||
packageInput,
|
||||
|
@ -91,6 +92,7 @@ export const PackagePolicyInputPanel: React.FunctionComponent<{
|
|||
updatePackagePolicyInput,
|
||||
inputValidationResults,
|
||||
forceShowErrors,
|
||||
isEditPage = false,
|
||||
}) => {
|
||||
const defaultDataStreamId = useDataStreamId();
|
||||
// Showing streams toggle state
|
||||
|
@ -213,7 +215,6 @@ export const PackagePolicyInputPanel: React.FunctionComponent<{
|
|||
|
||||
{/* Header rule break */}
|
||||
{isShowingStreams ? <EuiSpacer size="l" /> : null}
|
||||
|
||||
{/* Input level policy */}
|
||||
{isShowingStreams && packageInput.vars && packageInput.vars.length ? (
|
||||
<Fragment>
|
||||
|
@ -224,6 +225,7 @@ export const PackagePolicyInputPanel: React.FunctionComponent<{
|
|||
updatePackagePolicyInput={updatePackagePolicyInput}
|
||||
inputVarsValidationResults={{ vars: inputValidationResults?.vars }}
|
||||
forceShowErrors={forceShowErrors}
|
||||
isEditPage={isEditPage}
|
||||
/>
|
||||
{hasInputStreams ? <ShortenedHorizontalRule margin="m" /> : <EuiSpacer size="l" />}
|
||||
</Fragment>
|
||||
|
@ -273,6 +275,7 @@ export const PackagePolicyInputPanel: React.FunctionComponent<{
|
|||
inputValidationResults?.streams![packagePolicyInputStream!.data_stream!.dataset]
|
||||
}
|
||||
forceShowErrors={forceShowErrors}
|
||||
isEditPage={isEditPage}
|
||||
/>
|
||||
{index !== inputStreams.length - 1 ? (
|
||||
<>
|
||||
|
|
|
@ -58,6 +58,7 @@ interface Props {
|
|||
updatePackagePolicyInputStream: (updatedStream: Partial<NewPackagePolicyInputStream>) => void;
|
||||
inputStreamValidationResults: PackagePolicyConfigValidationResults;
|
||||
forceShowErrors?: boolean;
|
||||
isEditPage?: boolean;
|
||||
}
|
||||
|
||||
export const PackagePolicyInputStreamConfig = memo<Props>(
|
||||
|
@ -70,6 +71,7 @@ export const PackagePolicyInputStreamConfig = memo<Props>(
|
|||
updatePackagePolicyInputStream,
|
||||
inputStreamValidationResults,
|
||||
forceShowErrors,
|
||||
isEditPage,
|
||||
}) => {
|
||||
const config = useConfig();
|
||||
const isExperimentalDataStreamSettingsEnabled =
|
||||
|
@ -226,6 +228,7 @@ export const PackagePolicyInputStreamConfig = memo<Props>(
|
|||
forceShowErrors={forceShowErrors}
|
||||
packageType={packageInfo.type}
|
||||
datasets={datasets}
|
||||
isEditPage={isEditPage}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
);
|
||||
|
@ -287,6 +290,7 @@ export const PackagePolicyInputStreamConfig = memo<Props>(
|
|||
forceShowErrors={forceShowErrors}
|
||||
packageType={packageInfo.type}
|
||||
datasets={datasets}
|
||||
isEditPage={isEditPage}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
);
|
||||
|
|
|
@ -40,6 +40,7 @@ export const PackagePolicyInputVarField: React.FunctionComponent<{
|
|||
frozen?: boolean;
|
||||
packageType?: string;
|
||||
datasets?: string[];
|
||||
isEditPage?: boolean;
|
||||
}> = memo(
|
||||
({
|
||||
varDef,
|
||||
|
@ -50,6 +51,7 @@ export const PackagePolicyInputVarField: React.FunctionComponent<{
|
|||
frozen,
|
||||
packageType,
|
||||
datasets = [],
|
||||
isEditPage = false,
|
||||
}) => {
|
||||
const [isDirty, setIsDirty] = useState<boolean>(false);
|
||||
const { multi, required, type, title, name, description } = varDef;
|
||||
|
@ -68,9 +70,15 @@ export const PackagePolicyInputVarField: React.FunctionComponent<{
|
|||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'data_stream.dataset' && packageType === 'input') {
|
||||
return <DatasetComboBox datasets={datasets} value={value} onChange={onChange} />;
|
||||
return (
|
||||
<DatasetComboBox
|
||||
datasets={datasets}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
isDisabled={isEditPage}
|
||||
/>
|
||||
);
|
||||
}
|
||||
switch (type) {
|
||||
case 'textarea':
|
||||
|
@ -152,7 +160,19 @@ export const PackagePolicyInputVarField: React.FunctionComponent<{
|
|||
/>
|
||||
);
|
||||
}
|
||||
}, [isInvalid, multi, onChange, type, value, fieldLabel, frozen, datasets, name, packageType]);
|
||||
}, [
|
||||
multi,
|
||||
name,
|
||||
packageType,
|
||||
type,
|
||||
value,
|
||||
onChange,
|
||||
frozen,
|
||||
datasets,
|
||||
isEditPage,
|
||||
isInvalid,
|
||||
fieldLabel,
|
||||
]);
|
||||
|
||||
// Boolean cannot be optional by default set to false
|
||||
const isOptional = useMemo(() => type !== 'bool' && !required, [required, type]);
|
||||
|
|
|
@ -37,6 +37,7 @@ export const StepConfigurePackagePolicy: React.FunctionComponent<{
|
|||
validationResults: PackagePolicyValidationResults;
|
||||
submitAttempted: boolean;
|
||||
noTopRule?: boolean;
|
||||
isEditPage?: boolean;
|
||||
}> = ({
|
||||
packageInfo,
|
||||
showOnlyIntegration,
|
||||
|
@ -45,6 +46,7 @@ export const StepConfigurePackagePolicy: React.FunctionComponent<{
|
|||
validationResults,
|
||||
submitAttempted,
|
||||
noTopRule = false,
|
||||
isEditPage = false,
|
||||
}) => {
|
||||
const hasIntegrations = useMemo(() => doesPackageHaveIntegrations(packageInfo), [packageInfo]);
|
||||
const packagePolicyTemplates = useMemo(
|
||||
|
@ -109,6 +111,7 @@ export const StepConfigurePackagePolicy: React.FunctionComponent<{
|
|||
]
|
||||
}
|
||||
forceShowErrors={submitAttempted}
|
||||
isEditPage={isEditPage}
|
||||
/>
|
||||
<EuiHorizontalRule margin="m" />
|
||||
</EuiFlexItem>
|
||||
|
|
|
@ -92,7 +92,7 @@ describe('StepDefinePackagePolicy', () => {
|
|||
|
||||
let testRenderer: TestRenderer;
|
||||
let renderResult: ReturnType<typeof testRenderer.render>;
|
||||
const render = ({ isUpdate } = { isUpdate: false }) =>
|
||||
const render = () =>
|
||||
(renderResult = testRenderer.render(
|
||||
<StepDefinePackagePolicy
|
||||
agentPolicy={agentPolicy}
|
||||
|
@ -101,7 +101,6 @@ describe('StepDefinePackagePolicy', () => {
|
|||
updatePackagePolicy={mockUpdatePackagePolicy}
|
||||
validationResults={validationResults}
|
||||
submitAttempted={false}
|
||||
isUpdate={isUpdate}
|
||||
/>
|
||||
));
|
||||
|
||||
|
@ -165,7 +164,7 @@ describe('StepDefinePackagePolicy', () => {
|
|||
describe('update', () => {
|
||||
describe('when package vars are introduced in a new package version', () => {
|
||||
it('should display new package vars', () => {
|
||||
render({ isUpdate: true });
|
||||
render();
|
||||
|
||||
waitFor(async () => {
|
||||
expect(renderResult.getByDisplayValue('showUserVarVal')).toBeInTheDocument();
|
||||
|
|
|
@ -50,23 +50,21 @@ export const StepDefinePackagePolicy: React.FunctionComponent<{
|
|||
agentPolicy?: AgentPolicy;
|
||||
packageInfo: PackageInfo;
|
||||
packagePolicy: NewPackagePolicy;
|
||||
integrationToEnable?: string;
|
||||
updatePackagePolicy: (fields: Partial<NewPackagePolicy>) => void;
|
||||
validationResults: PackagePolicyValidationResults;
|
||||
submitAttempted: boolean;
|
||||
isUpdate?: boolean;
|
||||
isEditPage?: boolean;
|
||||
noAdvancedToggle?: boolean;
|
||||
}> = memo(
|
||||
({
|
||||
agentPolicy,
|
||||
packageInfo,
|
||||
packagePolicy,
|
||||
integrationToEnable,
|
||||
isUpdate,
|
||||
updatePackagePolicy,
|
||||
validationResults,
|
||||
submitAttempted,
|
||||
noAdvancedToggle = false,
|
||||
isEditPage = false,
|
||||
}) => {
|
||||
const { docLinks } = useStartServices();
|
||||
|
||||
|
@ -251,7 +249,6 @@ export const StepDefinePackagePolicy: React.FunctionComponent<{
|
|||
)}
|
||||
|
||||
{/* Advanced options content */}
|
||||
{/* Todo: Populate list of existing namespaces */}
|
||||
{isShowingAdvanced ? (
|
||||
<EuiFlexItem>
|
||||
<EuiFlexGroup direction="column" gutterSize="m">
|
||||
|
@ -266,27 +263,35 @@ export const StepDefinePackagePolicy: React.FunctionComponent<{
|
|||
/>
|
||||
}
|
||||
helpText={
|
||||
<FormattedMessage
|
||||
id="xpack.fleet.createPackagePolicy.stepConfigure.packagePolicyNamespaceHelpLabel"
|
||||
defaultMessage="Change the default namespace inherited from the selected Agent policy. This setting changes the name of the integration's data stream. {learnMore}."
|
||||
values={{
|
||||
learnMore: (
|
||||
<EuiLink
|
||||
href={docLinks.links.fleet.datastreamsNamingScheme}
|
||||
target="_blank"
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.fleet.createPackagePolicy.stepConfigure.packagePolicyNamespaceHelpLearnMoreLabel',
|
||||
{ defaultMessage: 'Learn more' }
|
||||
)}
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
isEditPage && packageInfo.type === 'input' ? (
|
||||
<FormattedMessage
|
||||
id="xpack.fleet.createPackagePolicy.stepConfigure.packagePolicyInputOnlyEditNamespaceHelpLabel"
|
||||
defaultMessage="The namespace cannot be changed for this integration. Create a new integration policy to use a different namespace."
|
||||
/>
|
||||
) : (
|
||||
<FormattedMessage
|
||||
id="xpack.fleet.createPackagePolicy.stepConfigure.packagePolicyNamespaceHelpLabel"
|
||||
defaultMessage="Change the default namespace inherited from the selected Agent policy. This setting changes the name of the integration's data stream. {learnMore}."
|
||||
values={{
|
||||
learnMore: (
|
||||
<EuiLink
|
||||
href={docLinks.links.fleet.datastreamsNamingScheme}
|
||||
target="_blank"
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.fleet.createPackagePolicy.stepConfigure.packagePolicyNamespaceHelpLearnMoreLabel',
|
||||
{ defaultMessage: 'Learn more' }
|
||||
)}
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
>
|
||||
<EuiComboBox
|
||||
noSuggestions
|
||||
isDisabled={isEditPage && packageInfo.type === 'input'}
|
||||
singleSelection={true}
|
||||
selectedOptions={
|
||||
packagePolicy.namespace ? [{ label: packagePolicy.namespace }] : []
|
||||
|
|
|
@ -284,7 +284,6 @@ export const CreatePackagePolicySinglePage: CreatePackagePolicyParams = ({
|
|||
updatePackagePolicy={updatePackagePolicy}
|
||||
validationResults={validationResults!}
|
||||
submitAttempted={formState === 'INVALID'}
|
||||
integrationToEnable={integrationInfo?.name}
|
||||
/>
|
||||
|
||||
{/* Only show the out-of-box configuration step if a UI extension is NOT registered */}
|
||||
|
|
|
@ -286,7 +286,7 @@ export const EditPackagePolicyForm = memo<{
|
|||
updatePackagePolicy={updatePackagePolicy}
|
||||
validationResults={validationResults!}
|
||||
submitAttempted={formState === 'INVALID'}
|
||||
isUpdate={true}
|
||||
isEditPage={true}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
@ -298,6 +298,7 @@ export const EditPackagePolicyForm = memo<{
|
|||
updatePackagePolicy={updatePackagePolicy}
|
||||
validationResults={validationResults!}
|
||||
submitAttempted={formState === 'INVALID'}
|
||||
isEditPage={true}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ import {
|
|||
packagePolicyService,
|
||||
_applyIndexPrivileges,
|
||||
_compilePackagePolicyInputs,
|
||||
_validateRestrictedFieldsNotModifiedOrThrow,
|
||||
} from './package_policy';
|
||||
import { appContextService } from './app_context';
|
||||
|
||||
|
@ -4578,3 +4579,130 @@ describe('_applyIndexPrivileges()', () => {
|
|||
expect(streamOut).toEqual(expectedStream);
|
||||
});
|
||||
});
|
||||
|
||||
describe('_validateRestrictedFieldsNotModifiedOrThrow()', () => {
|
||||
const pkgInfo = {
|
||||
name: 'custom_logs',
|
||||
title: 'Custom Logs',
|
||||
version: '1.0.0',
|
||||
type: 'input',
|
||||
} as any as PackageInfo;
|
||||
|
||||
const createInputPkgPolicy = (opts: { namespace: string; dataset: string }) => {
|
||||
const { namespace, dataset } = opts;
|
||||
return {
|
||||
id: 'id-1234',
|
||||
version: 'WzI1MywxXQ==',
|
||||
name: 'custom_logs-1',
|
||||
namespace,
|
||||
description: '',
|
||||
enabled: true,
|
||||
policy_id: '1234',
|
||||
revision: 1,
|
||||
created_at: '2023-01-04T14:51:53.061Z',
|
||||
created_by: 'elastic',
|
||||
updated_at: '2023-01-04T14:51:53.061Z',
|
||||
updated_by: 'elastic',
|
||||
vars: {},
|
||||
inputs: [
|
||||
{
|
||||
type: 'logfile',
|
||||
policy_template: 'logs',
|
||||
enabled: true,
|
||||
streams: [
|
||||
{
|
||||
enabled: true,
|
||||
data_stream: {
|
||||
type: 'logs',
|
||||
dataset: 'custom_logs.logs',
|
||||
},
|
||||
vars: {
|
||||
'data_stream.dataset': {
|
||||
type: 'text',
|
||||
value: dataset,
|
||||
},
|
||||
},
|
||||
id: 'logfile-custom_logs.logs-1',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
package: {
|
||||
name: 'custom_logs',
|
||||
title: 'Custom Logs',
|
||||
version: '1.0.0',
|
||||
},
|
||||
};
|
||||
};
|
||||
it('should not throw if restricted fields are not modified', () => {
|
||||
const oldPackagePolicy = createInputPkgPolicy({
|
||||
namespace: 'default',
|
||||
dataset: 'custom_logs.logs',
|
||||
});
|
||||
expect(() =>
|
||||
_validateRestrictedFieldsNotModifiedOrThrow({
|
||||
oldPackagePolicy,
|
||||
packagePolicyUpdate: oldPackagePolicy,
|
||||
pkgInfo,
|
||||
})
|
||||
).not.toThrow();
|
||||
});
|
||||
|
||||
it('should throw if namespace is modified', () => {
|
||||
const oldPackagePolicy = createInputPkgPolicy({
|
||||
namespace: 'default',
|
||||
dataset: 'custom_logs.logs',
|
||||
});
|
||||
const newPackagePolicy = createInputPkgPolicy({
|
||||
namespace: 'new-namespace',
|
||||
dataset: 'custom_logs.logs',
|
||||
});
|
||||
expect(() =>
|
||||
_validateRestrictedFieldsNotModifiedOrThrow({
|
||||
oldPackagePolicy,
|
||||
packagePolicyUpdate: newPackagePolicy,
|
||||
pkgInfo,
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
`"Package policy namespace cannot be modified for input only packages, please create a new package policy."`
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw if dataset is modified', () => {
|
||||
const oldPackagePolicy = createInputPkgPolicy({
|
||||
namespace: 'default',
|
||||
dataset: 'custom_logs.logs',
|
||||
});
|
||||
const newPackagePolicy = createInputPkgPolicy({
|
||||
namespace: 'default',
|
||||
dataset: 'new-dataset',
|
||||
});
|
||||
expect(() =>
|
||||
_validateRestrictedFieldsNotModifiedOrThrow({
|
||||
oldPackagePolicy,
|
||||
packagePolicyUpdate: newPackagePolicy,
|
||||
pkgInfo,
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
`"Package policy dataset cannot be modified for input only packages, please create a new package policy."`
|
||||
);
|
||||
});
|
||||
|
||||
it('should not throw if dataset is modified but package is integration package', () => {
|
||||
const oldPackagePolicy = createInputPkgPolicy({
|
||||
namespace: 'default',
|
||||
dataset: 'custom_logs.logs',
|
||||
});
|
||||
const newPackagePolicy = createInputPkgPolicy({
|
||||
namespace: 'default',
|
||||
dataset: 'new-dataset',
|
||||
});
|
||||
expect(() =>
|
||||
_validateRestrictedFieldsNotModifiedOrThrow({
|
||||
oldPackagePolicy,
|
||||
packagePolicyUpdate: newPackagePolicy,
|
||||
pkgInfo: { ...pkgInfo, type: 'integration' },
|
||||
})
|
||||
).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -519,7 +519,11 @@ class PackagePolicyClientImpl implements PackagePolicyClient {
|
|||
pkgVersion: packagePolicy.package.version,
|
||||
prerelease: true,
|
||||
});
|
||||
|
||||
_validateRestrictedFieldsNotModifiedOrThrow({
|
||||
pkgInfo,
|
||||
oldPackagePolicy,
|
||||
packagePolicyUpdate,
|
||||
});
|
||||
validatePackagePolicyOrThrow(packagePolicy, pkgInfo);
|
||||
|
||||
inputs = await _compilePackagePolicyInputs(pkgInfo, packagePolicy.vars || {}, inputs);
|
||||
|
@ -1950,6 +1954,52 @@ export function preconfigurePackageInputs(
|
|||
return resultingPackagePolicy;
|
||||
}
|
||||
|
||||
// input only packages cannot have their namespace or dataset modified
|
||||
export function _validateRestrictedFieldsNotModifiedOrThrow(opts: {
|
||||
pkgInfo: PackageInfo;
|
||||
oldPackagePolicy: PackagePolicy;
|
||||
packagePolicyUpdate: UpdatePackagePolicy;
|
||||
}) {
|
||||
const { pkgInfo, oldPackagePolicy, packagePolicyUpdate } = opts;
|
||||
|
||||
if (pkgInfo.type !== 'input') return;
|
||||
|
||||
const { namespace, inputs } = packagePolicyUpdate;
|
||||
if (namespace && namespace !== oldPackagePolicy.namespace) {
|
||||
throw new PackagePolicyValidationError(
|
||||
i18n.translate('xpack.fleet.updatePackagePolicy.namespaceCannotBeModified', {
|
||||
defaultMessage:
|
||||
'Package policy namespace cannot be modified for input only packages, please create a new package policy.',
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if (inputs) {
|
||||
for (const input of inputs) {
|
||||
const oldInput = oldPackagePolicy.inputs.find((i) => i.id === input.id);
|
||||
if (oldInput) {
|
||||
for (const stream of input.streams || []) {
|
||||
const oldStream = oldInput.streams.find(
|
||||
(s) => s.data_stream.dataset === stream.data_stream.dataset
|
||||
);
|
||||
if (
|
||||
oldStream &&
|
||||
oldStream?.vars?.['data_stream.dataset'] &&
|
||||
oldStream?.vars['data_stream.dataset'] !== stream?.vars?.['data_stream.dataset']
|
||||
) {
|
||||
throw new PackagePolicyValidationError(
|
||||
i18n.translate('xpack.fleet.updatePackagePolicy.datasetCannotBeModified', {
|
||||
defaultMessage:
|
||||
'Package policy dataset cannot be modified for input only packages, please create a new package policy.',
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function validateIsNotHostedPolicy(
|
||||
soClient: SavedObjectsClientContract,
|
||||
id: string,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue