Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Cloud Security] Agentless integration deletion flow #191557

Merged
Show file tree
Hide file tree
Changes from 55 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
a74316f
allow agentless deletion on agent and integration policy
Omolola-Akinleye Aug 27, 2024
b760084
ensure confirm state is only for agent-based policies and integrations
Omolola-Akinleye Aug 27, 2024
aa1cd50
add agentless agent deletion endpoint
Omolola-Akinleye Aug 27, 2024
f505334
uncomment creation of agentless agent
Omolola-Akinleye Aug 27, 2024
54e699c
fix type issues
Omolola-Akinleye Aug 27, 2024
e946f9c
fix typo
Omolola-Akinleye Aug 28, 2024
55f6abf
test deletion of the agentless agent only
Omolola-Akinleye Aug 29, 2024
9b665c5
enable button to delete agentless policies with agent
Omolola-Akinleye Aug 29, 2024
d53428b
move deletion of agentless agent before deleting integration
Omolola-Akinleye Aug 29, 2024
1ab7cc3
test with agent policy deletion
Omolola-Akinleye Sep 3, 2024
ad36872
fix types issue
Omolola-Akinleye Sep 3, 2024
8bb1eff
resolve merge conflicts
Omolola-Akinleye Sep 3, 2024
a27a9ef
fix translations
Omolola-Akinleye Sep 3, 2024
7aae9dc
move to delete agentless policies back down to avoid loading button b…
Omolola-Akinleye Sep 4, 2024
99cabd9
remove throw error on soClient deletion for agentless
Omolola-Akinleye Sep 5, 2024
bdb68de
update logging
Omolola-Akinleye Sep 6, 2024
c0eec90
update messaging for agentless deletion
Omolola-Akinleye Sep 7, 2024
4b60044
remove try/catch logic to fix SO client error
Omolola-Akinleye Sep 9, 2024
1eb25a9
fix save object 404 error
Omolola-Akinleye Sep 9, 2024
7c9b866
fix unit tests
Omolola-Akinleye Sep 10, 2024
12bbe24
fix api-integration tests
Omolola-Akinleye Sep 10, 2024
3ff29b9
uncomment agentless api creation
Omolola-Akinleye Sep 10, 2024
d10f369
change error notification messaging
Omolola-Akinleye Sep 10, 2024
13f42a0
disables fleet actions for agentless
Omolola-Akinleye Sep 10, 2024
48529a2
fix edit flow ftr
Omolola-Akinleye Sep 10, 2024
f8836ed
resolve merge conflicts
Omolola-Akinleye Sep 10, 2024
694b912
Merge remote-tracking branch 'upstream/main' into agentless-integrati…
Omolola-Akinleye Sep 11, 2024
4bbd39d
fix save and edit ftr test
Omolola-Akinleye Sep 11, 2024
891e5af
fix type build error
Omolola-Akinleye Sep 11, 2024
a63da94
fix build
Omolola-Akinleye Sep 11, 2024
0b03d5a
remove fleet actions agentless agent in agents page
Omolola-Akinleye Sep 11, 2024
1155b89
fix 404 so client error when deleting agent policy with an active agent
Omolola-Akinleye Sep 11, 2024
580d31f
remove irrevelant package policy action items for agentless integrations
Omolola-Akinleye Sep 12, 2024
cb7c49c
fix save object 404 error on agents page
Omolola-Akinleye Sep 12, 2024
2ab4f23
resolve merge conflict
Omolola-Akinleye Sep 13, 2024
5ecb5b1
fix hide multiple agent policies to support ess and serverless
Omolola-Akinleye Sep 16, 2024
b112729
fix error messaging
Omolola-Akinleye Sep 16, 2024
a111405
fix error messaging language
Omolola-Akinleye Sep 16, 2024
32726d3
edit deletion of agent policy messaging
Omolola-Akinleye Sep 16, 2024
d0018a7
Merge branch 'main' into agentless-integration-deletion-flow
Omolola-Akinleye Sep 16, 2024
19a7a4b
Merge branch 'main' into agentless-integration-deletion-flow
Omolola-Akinleye Sep 17, 2024
f62a02b
update tests
Omolola-Akinleye Sep 20, 2024
5cd8a9a
Merge remote-tracking branch 'upstream/main' into agentless-integrati…
Omolola-Akinleye Sep 20, 2024
7134d88
Merge branch 'agentless-integration-deletion-flow' of github.com:Omol…
Omolola-Akinleye Sep 20, 2024
6ee67f0
add unit test and update FTR for bug fix
Omolola-Akinleye Sep 20, 2024
6a1f968
address pr change and fix tests
Omolola-Akinleye Sep 23, 2024
b124f81
update delete messaging
Omolola-Akinleye Sep 23, 2024
0184def
Merge branch 'main' into agentless-integration-deletion-flow
Omolola-Akinleye Sep 23, 2024
7b040f5
remove flaky test in build
Omolola-Akinleye Sep 24, 2024
eff6ee9
Merge branch 'agentless-integration-deletion-flow' of github.com:Omol…
Omolola-Akinleye Sep 24, 2024
5997b7a
remove flaky test
Omolola-Akinleye Sep 24, 2024
e812c86
resolve merge conflict
Omolola-Akinleye Sep 24, 2024
9d6dcc1
fix unit test
Omolola-Akinleye Sep 25, 2024
bc99b1d
remove agentless policies from multi-select for agent-based integrations
Omolola-Akinleye Sep 25, 2024
2dd22da
Merge branch 'main' into agentless-integration-deletion-flow
Omolola-Akinleye Sep 30, 2024
b2e2a4e
fix error messaging
Omolola-Akinleye Oct 1, 2024
d8f91ce
Merge branch 'agentless-integration-deletion-flow' of github.com:Omol…
Omolola-Akinleye Oct 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,39 @@ describe('AgentPolicyActionMenu', () => {
const deleteButton = result.getByTestId('agentPolicyActionMenuDeleteButton');
expect(deleteButton).toHaveAttribute('disabled');
});

it('is disabled when agent policy support agentless is true', () => {
const testRenderer = createFleetTestRendererMock();
const agentlessPolicy: AgentPolicy = {
...baseAgentPolicy,
supports_agentless: true,
package_policies: [
{
id: 'test-package-policy',
is_managed: false,
created_at: new Date().toISOString(),
created_by: 'test',
enabled: true,
inputs: [],
name: 'test-package-policy',
namespace: 'default',
policy_id: 'test',
policy_ids: ['test'],
revision: 1,
updated_at: new Date().toISOString(),
updated_by: 'test',
},
],
};

const result = testRenderer.render(<AgentPolicyActionMenu agentPolicy={agentlessPolicy} />);

const agentActionsButton = result.getByTestId('agentActionsBtn');
agentActionsButton.click();

const deleteButton = result.getByTestId('agentPolicyActionMenuDeleteButton');
expect(deleteButton).not.toHaveAttribute('disabled');
});
});

describe('add agent', () => {
Expand Down Expand Up @@ -176,6 +209,39 @@ describe('AgentPolicyActionMenu', () => {
const addButton = result.getByTestId('agentPolicyActionMenuAddAgentButton');
expect(addButton).toHaveAttribute('disabled');
});

it('should remove add agent button when agent policy support agentless is true', () => {
const testRenderer = createFleetTestRendererMock();
const agentlessPolicy: AgentPolicy = {
...baseAgentPolicy,
supports_agentless: true,
package_policies: [
{
id: 'test-package-policy',
is_managed: false,
created_at: new Date().toISOString(),
created_by: 'test',
enabled: true,
inputs: [],
name: 'test-package-policy',
namespace: 'default',
policy_id: 'test',
policy_ids: ['test'],
revision: 1,
updated_at: new Date().toISOString(),
updated_by: 'test',
},
],
};

const result = testRenderer.render(<AgentPolicyActionMenu agentPolicy={agentlessPolicy} />);

const agentActionsButton = result.getByTestId('agentActionsBtn');
agentActionsButton.click();

const addAgentActionButton = result.queryByTestId('agentPolicyActionMenuAddAgentButton');
expect(addAgentActionButton).toBeNull();
});
});

describe('add fleet server', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,82 +100,106 @@ export const AgentPolicyActionMenu = memo<{
</EuiContextMenuItem>
);

const menuItems = agentPolicy?.is_managed
? [viewPolicyItem]
: [
const deletePolicyItem = (
<AgentPolicyDeleteProvider
hasFleetServer={policyHasFleetServer(agentPolicy as AgentPolicy)}
key="deletePolicy"
agentPolicy={agentPolicy}
packagePolicies={agentPolicy.package_policies}
>
{(deleteAgentPolicyPrompt) => (
<EuiContextMenuItem
icon="plusInCircle"
disabled={
(isFleetServerPolicy && !authz.fleet.addFleetServers) ||
(!isFleetServerPolicy && !authz.fleet.addAgents)
data-test-subj="agentPolicyActionMenuDeleteButton"
disabled={!authz.fleet.allAgentPolicies || hasManagedPackagePolicy}
toolTipContent={
hasManagedPackagePolicy ? (
<FormattedMessage
id="xpack.fleet.policyForm.deletePolicyActionText.disabled"
defaultMessage="Agent policy with managed package policies cannot be deleted."
data-test-subj="agentPolicyActionMenuDeleteButtonDisabledTooltip"
/>
) : undefined
}
data-test-subj="agentPolicyActionMenuAddAgentButton"
onClick={() => {
setIsContextMenuOpen(false);
setIsEnrollmentFlyoutOpen(true);
}}
key="enrollAgents"
>
{isFleetServerPolicy ? (
<FormattedMessage
id="xpack.fleet.agentPolicyActionMenu.addFleetServerActionText"
defaultMessage="Add Fleet Server"
/>
) : (
<FormattedMessage
id="xpack.fleet.agentPolicyActionMenu.enrollAgentActionText"
defaultMessage="Add agent"
/>
)}
</EuiContextMenuItem>,
viewPolicyItem,
<EuiContextMenuItem
disabled={!authz.integrations.writeIntegrationPolicies}
icon="copy"
icon="trash"
onClick={() => {
setIsContextMenuOpen(false);
copyAgentPolicyPrompt(agentPolicy, onCopySuccess);
deleteAgentPolicyPrompt(agentPolicy.id);
}}
key="copyPolicy"
>
<FormattedMessage
id="xpack.fleet.agentPolicyActionMenu.copyPolicyActionText"
defaultMessage="Duplicate policy"
id="xpack.fleet.agentPolicyActionMenu.deletePolicyActionText"
defaultMessage="Delete policy"
/>
</EuiContextMenuItem>,
<AgentPolicyDeleteProvider
hasFleetServer={policyHasFleetServer(agentPolicy as AgentPolicy)}
key="deletePolicy"
packagePolicies={agentPolicy.package_policies}
>
{(deleteAgentPolicyPrompt) => (
<EuiContextMenuItem
data-test-subj="agentPolicyActionMenuDeleteButton"
disabled={!authz.fleet.allAgentPolicies || hasManagedPackagePolicy}
toolTipContent={
hasManagedPackagePolicy ? (
<FormattedMessage
id="xpack.fleet.policyForm.deletePolicyActionText.disabled"
defaultMessage="Agent policy with managed package policies cannot be deleted."
data-test-subj="agentPolicyActionMenuDeleteButtonDisabledTooltip"
/>
) : undefined
}
icon="trash"
onClick={() => {
deleteAgentPolicyPrompt(agentPolicy.id);
}}
>
<FormattedMessage
id="xpack.fleet.agentPolicyActionMenu.deletePolicyActionText"
defaultMessage="Delete policy"
/>
</EuiContextMenuItem>
)}
</AgentPolicyDeleteProvider>,
];
</EuiContextMenuItem>
)}
</AgentPolicyDeleteProvider>
);

const copyPolicyItem = (
<EuiContextMenuItem
data-test-subj="agentPolicyActionMenuCopyButton"
disabled={!authz.integrations.writeIntegrationPolicies}
icon="copy"
onClick={() => {
setIsContextMenuOpen(false);
copyAgentPolicyPrompt(agentPolicy, onCopySuccess);
}}
key="copyPolicy"
>
<FormattedMessage
id="xpack.fleet.agentPolicyActionMenu.copyPolicyActionText"
defaultMessage="Duplicate policy"
/>
</EuiContextMenuItem>
);

const managedMenuItems = [viewPolicyItem];
const agentBasedMenuItems = [
<EuiContextMenuItem
icon="plusInCircle"
disabled={
(isFleetServerPolicy && !authz.fleet.addFleetServers) ||
(!isFleetServerPolicy && !authz.fleet.addAgents)
}
data-test-subj="agentPolicyActionMenuAddAgentButton"
onClick={() => {
setIsContextMenuOpen(false);
setIsEnrollmentFlyoutOpen(true);
}}
key="enrollAgents"
>
{isFleetServerPolicy ? (
<FormattedMessage
id="xpack.fleet.agentPolicyActionMenu.addFleetServerActionText"
defaultMessage="Add Fleet Server"
/>
) : (
<FormattedMessage
id="xpack.fleet.agentPolicyActionMenu.enrollAgentActionText"
defaultMessage="Add agent"
/>
)}
</EuiContextMenuItem>,
viewPolicyItem,
copyPolicyItem,
deletePolicyItem,
];
const agentlessMenuItems = [viewPolicyItem, deletePolicyItem];

let menuItems;

if (agentPolicy?.is_managed) {
menuItems = managedMenuItems;
} else if (agentPolicy?.supports_agentless) {
menuItems = agentlessMenuItems;
} else {
menuItems = agentBasedMenuItems;
}

if (authz.fleet.allAgents && !agentPolicy?.is_managed) {
if (
authz.fleet.allAgents &&
!agentPolicy?.is_managed &&
!agentPolicy?.supports_agentless
) {
menuItems.push(
<EuiContextMenuItem
icon="refresh"
Expand All @@ -193,7 +217,12 @@ export const AgentPolicyActionMenu = memo<{
);
}

if (authz.fleet.allAgents && agentTamperProtectionEnabled && !agentPolicy?.is_managed) {
if (
authz.fleet.allAgents &&
agentTamperProtectionEnabled &&
!agentPolicy?.is_managed &&
!agentPolicy?.supports_agentless
) {
menuItems.push(
<EuiContextMenuItem
icon="minusInCircle"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ export const AgentPolicyAdvancedOptionsContent: React.FunctionComponent<Props> =
const licenseService = useLicense();
const [isUninstallCommandFlyoutOpen, setIsUninstallCommandFlyoutOpen] = useState(false);
const policyHasElasticDefend = useMemo(() => hasElasticDefend(agentPolicy), [agentPolicy]);
const isManagedorAgentlessPolicy =
agentPolicy.is_managed === true || agentPolicy?.supports_agentless === true;

const AgentTamperProtectionSectionContent = useMemo(
() => (
Expand Down Expand Up @@ -196,7 +198,12 @@ export const AgentPolicyAdvancedOptionsContent: React.FunctionComponent<Props> =
);

const AgentTamperProtectionSection = useMemo(() => {
if (agentTamperProtectionEnabled && licenseService.isPlatinum() && !agentPolicy.is_managed) {
if (
agentTamperProtectionEnabled &&
licenseService.isPlatinum() &&
!agentPolicy.is_managed &&
!agentPolicy.supports_agentless
seanrathier marked this conversation as resolved.
Show resolved Hide resolved
) {
if (AgentTamperProtectionWrapper) {
return (
<Suspense fallback={null}>
Expand All @@ -214,6 +221,7 @@ export const AgentPolicyAdvancedOptionsContent: React.FunctionComponent<Props> =
agentPolicy.is_managed,
AgentTamperProtectionWrapper,
AgentTamperProtectionSectionContent,
agentPolicy.supports_agentless,
]);

return (
Expand Down Expand Up @@ -405,7 +413,7 @@ export const AgentPolicyAdvancedOptionsContent: React.FunctionComponent<Props> =
>
<EuiSpacer size="l" />
<EuiCheckboxGroup
disabled={disabled || agentPolicy.is_managed === true}
disabled={disabled || isManagedorAgentlessPolicy}
options={[
{
id: `${dataTypes.Logs}_${monitoringCheckboxIdSuffix}`,
Expand Down Expand Up @@ -541,7 +549,7 @@ export const AgentPolicyAdvancedOptionsContent: React.FunctionComponent<Props> =
>
<EuiFieldNumber
fullWidth
disabled={disabled || agentPolicy.is_managed === true}
disabled={disabled || isManagedorAgentlessPolicy}
value={agentPolicy.inactivity_timeout || ''}
min={0}
onChange={(e) => {
Expand Down Expand Up @@ -582,7 +590,7 @@ export const AgentPolicyAdvancedOptionsContent: React.FunctionComponent<Props> =
isInvalid={Boolean(touchedFields.fleet_server_host_id && validation.fleet_server_host_id)}
>
<EuiSuperSelect
disabled={disabled || agentPolicy.is_managed === true}
disabled={disabled || isManagedorAgentlessPolicy}
valueOfSelected={agentPolicy.fleet_server_host_id || DEFAULT_SELECT_VALUE}
fullWidth
isLoading={isLoadingFleetServerHostsOption}
Expand Down Expand Up @@ -623,7 +631,7 @@ export const AgentPolicyAdvancedOptionsContent: React.FunctionComponent<Props> =
isDisabled={disabled}
>
<EuiSuperSelect
disabled={disabled || agentPolicy.is_managed === true}
disabled={disabled || isManagedorAgentlessPolicy}
valueOfSelected={agentPolicy.data_output_id || DEFAULT_SELECT_VALUE}
fullWidth
isLoading={isLoadingOptions}
Expand Down Expand Up @@ -664,7 +672,7 @@ export const AgentPolicyAdvancedOptionsContent: React.FunctionComponent<Props> =
isDisabled={disabled}
>
<EuiSuperSelect
disabled={disabled || agentPolicy.is_managed === true}
disabled={disabled || isManagedorAgentlessPolicy}
valueOfSelected={agentPolicy.monitoring_output_id || DEFAULT_SELECT_VALUE}
fullWidth
isLoading={isLoadingOptions}
Expand Down Expand Up @@ -706,7 +714,7 @@ export const AgentPolicyAdvancedOptionsContent: React.FunctionComponent<Props> =
isDisabled={disabled}
>
<EuiSuperSelect
disabled={disabled}
disabled={disabled || agentPolicy?.supports_agentless === true}
valueOfSelected={agentPolicy.download_source_id || DEFAULT_SELECT_VALUE}
fullWidth
isLoading={isLoadingDownloadSources}
Expand Down Expand Up @@ -739,7 +747,7 @@ export const AgentPolicyAdvancedOptionsContent: React.FunctionComponent<Props> =
>
<EuiFormRow fullWidth isDisabled={disabled}>
<EuiRadioGroup
disabled={disabled}
disabled={disabled || agentPolicy?.supports_agentless === true}
options={[
{
id: 'hostname',
Expand Down Expand Up @@ -834,7 +842,7 @@ export const AgentPolicyAdvancedOptionsContent: React.FunctionComponent<Props> =
>
<EuiFieldNumber
fullWidth
disabled={disabled || agentPolicy.is_managed === true}
disabled={disabled || isManagedorAgentlessPolicy}
value={agentPolicy.unenroll_timeout || ''}
min={0}
onChange={(e) => {
Expand Down
Loading