Skip to content

Commit

Permalink
[Fleet] Do not allow namespace or dataset to be edited for input only…
Browse files Browse the repository at this point in the history
… package policies (#148737)

## 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.

<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">

Co-authored-by: Kyle Pollich <[email protected]>
  • Loading branch information
hop-dev and kpollich authored Jan 11, 2023
1 parent afbdfa5 commit ed71baf
Show file tree
Hide file tree
Showing 19 changed files with 482 additions and 131 deletions.
2 changes: 1 addition & 1 deletion x-pack/plugins/fleet/common/services/policy_template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 }>>([
Expand Down Expand Up @@ -42,7 +43,6 @@ export const DatasetComboBox: React.FC<{
setSelectedOptions([newOption]);
onChange(searchValue);
};

return (
<EuiComboBox
aria-label={i18n.translate('xpack.fleet.datasetCombo.ariaLabel', {
Expand All @@ -61,6 +61,7 @@ export const DatasetComboBox: React.FC<{
values: { searchValue: '{searchValue}' },
})}
isClearable={false}
isDisabled={isDisabled}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const PackagePolicyInputConfig: React.FunctionComponent<{
updatePackagePolicyInput: (updatedInput: Partial<NewPackagePolicyInput>) => void;
inputVarsValidationResults: PackagePolicyConfigValidationResults;
forceShowErrors?: boolean;
isEditPage?: boolean;
}> = memo(
({
hasInputStreams,
Expand All @@ -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);
Expand Down Expand Up @@ -121,6 +123,7 @@ export const PackagePolicyInputConfig: React.FunctionComponent<{
}}
errors={inputVarsValidationResults.vars?.[varName]}
forceShowErrors={forceShowErrors}
isEditPage={isEditPage}
/>
</EuiFlexItem>
);
Expand Down Expand Up @@ -178,6 +181,7 @@ export const PackagePolicyInputConfig: React.FunctionComponent<{
}}
errors={inputVarsValidationResults.vars?.[varName]}
forceShowErrors={forceShowErrors}
isEditPage={isEditPage}
/>
</EuiFlexItem>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export const PackagePolicyInputPanel: React.FunctionComponent<{
updatePackagePolicyInput: (updatedInput: Partial<NewPackagePolicyInput>) => void;
inputValidationResults: PackagePolicyInputValidationResults;
forceShowErrors?: boolean;
isEditPage?: boolean;
}> = memo(
({
packageInput,
Expand All @@ -91,6 +92,7 @@ export const PackagePolicyInputPanel: React.FunctionComponent<{
updatePackagePolicyInput,
inputValidationResults,
forceShowErrors,
isEditPage = false,
}) => {
const defaultDataStreamId = useDataStreamId();
// Showing streams toggle state
Expand Down Expand Up @@ -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>
Expand All @@ -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>
Expand Down Expand Up @@ -273,6 +275,7 @@ export const PackagePolicyInputPanel: React.FunctionComponent<{
inputValidationResults?.streams![packagePolicyInputStream!.data_stream!.dataset]
}
forceShowErrors={forceShowErrors}
isEditPage={isEditPage}
/>
{index !== inputStreams.length - 1 ? (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ interface Props {
updatePackagePolicyInputStream: (updatedStream: Partial<NewPackagePolicyInputStream>) => void;
inputStreamValidationResults: PackagePolicyConfigValidationResults;
forceShowErrors?: boolean;
isEditPage?: boolean;
}

export const PackagePolicyInputStreamConfig = memo<Props>(
Expand All @@ -70,6 +71,7 @@ export const PackagePolicyInputStreamConfig = memo<Props>(
updatePackagePolicyInputStream,
inputStreamValidationResults,
forceShowErrors,
isEditPage,
}) => {
const config = useConfig();
const isExperimentalDataStreamSettingsEnabled =
Expand Down Expand Up @@ -226,6 +228,7 @@ export const PackagePolicyInputStreamConfig = memo<Props>(
forceShowErrors={forceShowErrors}
packageType={packageInfo.type}
datasets={datasets}
isEditPage={isEditPage}
/>
</EuiFlexItem>
);
Expand Down Expand Up @@ -287,6 +290,7 @@ export const PackagePolicyInputStreamConfig = memo<Props>(
forceShowErrors={forceShowErrors}
packageType={packageInfo.type}
datasets={datasets}
isEditPage={isEditPage}
/>
</EuiFlexItem>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export const PackagePolicyInputVarField: React.FunctionComponent<{
frozen?: boolean;
packageType?: string;
datasets?: string[];
isEditPage?: boolean;
}> = memo(
({
varDef,
Expand All @@ -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;
Expand All @@ -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':
Expand Down Expand Up @@ -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]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export const StepConfigurePackagePolicy: React.FunctionComponent<{
validationResults: PackagePolicyValidationResults;
submitAttempted: boolean;
noTopRule?: boolean;
isEditPage?: boolean;
}> = ({
packageInfo,
showOnlyIntegration,
Expand All @@ -45,6 +46,7 @@ export const StepConfigurePackagePolicy: React.FunctionComponent<{
validationResults,
submitAttempted,
noTopRule = false,
isEditPage = false,
}) => {
const hasIntegrations = useMemo(() => doesPackageHaveIntegrations(packageInfo), [packageInfo]);
const packagePolicyTemplates = useMemo(
Expand Down Expand Up @@ -109,6 +111,7 @@ export const StepConfigurePackagePolicy: React.FunctionComponent<{
]
}
forceShowErrors={submitAttempted}
isEditPage={isEditPage}
/>
<EuiHorizontalRule margin="m" />
</EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand All @@ -101,7 +101,6 @@ describe('StepDefinePackagePolicy', () => {
updatePackagePolicy={mockUpdatePackagePolicy}
validationResults={validationResults}
submitAttempted={false}
isUpdate={isUpdate}
/>
));

Expand Down Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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">
Expand All @@ -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 }] : []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 */}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ export const EditPackagePolicyForm = memo<{
updatePackagePolicy={updatePackagePolicy}
validationResults={validationResults!}
submitAttempted={formState === 'INVALID'}
isUpdate={true}
isEditPage={true}
/>
)}

Expand All @@ -298,6 +298,7 @@ export const EditPackagePolicyForm = memo<{
updatePackagePolicy={updatePackagePolicy}
validationResults={validationResults!}
submitAttempted={formState === 'INVALID'}
isEditPage={true}
/>
)}

Expand Down
Loading

0 comments on commit ed71baf

Please sign in to comment.