Skip to content

Commit

Permalink
[Fleet] Remove field package_policies from agent policy (#138677)
Browse files Browse the repository at this point in the history
  • Loading branch information
nchaulet authored Aug 23, 2022
1 parent d4fad94 commit 368eba6
Show file tree
Hide file tree
Showing 41 changed files with 445 additions and 250 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ describe('getDeprecations', () => {
get: () =>
({
id: 'foo',
package_policies: [''],
package_policies: [{ package: { name: 'system' } }],
} as AgentPolicy),
},
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,10 @@ export const getCspAgentPolicies = async (
packagePolicies: PackagePolicy[],
agentPolicyService: AgentPolicyServiceInterface
): Promise<AgentPolicy[]> =>
agentPolicyService.getByIds(soClient, uniq(map(packagePolicies, 'policy_id')));
agentPolicyService.getByIds(soClient, uniq(map(packagePolicies, 'policy_id')), {
withPackagePolicies: true,
ignoreMissing: true,
});

export const getCspPackagePolicies = (
soClient: SavedObjectsClientContract,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,12 @@ const createBenchmarks = (
);
return Promise.all(
agentPolicies.flatMap((agentPolicy) => {
const cspPackagesOnAgent = agentPolicy.package_policies
.map((pckPolicyId) => {
if (typeof pckPolicyId === 'string') return cspPackagePoliciesMap.get(pckPolicyId);
})
.filter(isNonNullable);
const cspPackagesOnAgent =
agentPolicy.package_policies
?.map(({ id: pckPolicyId }) => {
return cspPackagePoliciesMap.get(pckPolicyId);
})
.filter(isNonNullable) ?? [];
const benchmarks = cspPackagesOnAgent.map(async (cspPackage) => {
const cspRulesStatus = await addPackagePolicyCspRules(soClient, cspPackage);
const agentPolicyStatus = {
Expand Down
2 changes: 2 additions & 0 deletions x-pack/plugins/fleet/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ export type {
UpgradePackagePolicyResponseItem,
UpgradePackagePolicyBaseResponse,
UpgradePackagePolicyDryRunResponseItem,
BulkGetPackagePoliciesResponse,
BulkGetAgentPoliciesResponse,
// Models
Agent,
AgentStatus,
Expand Down
6 changes: 3 additions & 3 deletions x-pack/plugins/fleet/common/services/limited_package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* 2.0.
*/

import type { PackageInfo, AgentPolicy, PackagePolicy } from '../types';
import type { PackageInfo, AgentPolicy } from '../types';

export const isPackageLimited = (packageInfo: PackageInfo): boolean => {
return (packageInfo.policy_templates || []).some(
Expand All @@ -17,10 +17,10 @@ export const doesAgentPolicyAlreadyIncludePackage = (
agentPolicy: AgentPolicy,
packageName: string
): boolean => {
if (agentPolicy.package_policies.length && typeof agentPolicy.package_policies[0] === 'string') {
if (!agentPolicy.package_policies) {
throw new Error('Unable to read full package policy information');
}
return (agentPolicy.package_policies as PackagePolicy[])
return agentPolicy.package_policies
.map((packagePolicy) => packagePolicy.package?.name || '')
.includes(packageName);
};
4 changes: 4 additions & 0 deletions x-pack/plugins/fleet/common/services/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ export const agentPolicyRouteService = {
return AGENT_POLICY_API_ROUTES.LIST_PATTERN;
},

getBulkGetPath: () => {
return AGENT_POLICY_API_ROUTES.BULK_GET_PATTERN;
},

getInfoPath: (agentPolicyId: string) => {
return AGENT_POLICY_API_ROUTES.INFO_PATTERN.replace('{agentPolicyId}', agentPolicyId);
},
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/fleet/common/types/models/agent_policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export interface NewAgentPolicy {
export interface AgentPolicy extends Omit<NewAgentPolicy, 'id'> {
id: string;
status: ValueOf<AgentPolicyStatus>;
package_policies: string[] | PackagePolicy[];
package_policies?: PackagePolicy[];
is_managed: boolean; // required for created policy
updated_at: string;
updated_by: string;
Expand Down
Binary file not shown.
6 changes: 6 additions & 0 deletions x-pack/plugins/fleet/cypress/tasks/fleet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,15 @@ import {
} from '../screens/fleet';

export function createAgentPolicy() {
cy.intercept({
url: '/api/fleet/agent_policies?sys_monitoring=true',
method: 'POST',
}).as('postAgentPolicy');
cy.getBySel(ADD_AGENT_BUTTON_TOP).click();
cy.getBySel(STANDALONE_TAB).click();
cy.getBySel(CREATE_POLICY_BUTTON).click();

cy.wait('@postAgentPolicy');
cy.getBySel(AGENT_FLYOUT_CLOSE_BUTTON).click();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import React, { memo } from 'react';

import type { AgentPolicy, PackagePolicy } from '../../../../../types';
import type { AgentPolicy } from '../../../../../types';
import { useBreadcrumbs } from '../../../../../hooks';

import { NoPackagePolicies } from './no_package_policies';
Expand All @@ -16,14 +16,14 @@ import { PackagePoliciesTable } from './package_policies_table';
export const PackagePoliciesView = memo<{ agentPolicy: AgentPolicy }>(({ agentPolicy }) => {
useBreadcrumbs('policy_details', { policyName: agentPolicy.name });

if (agentPolicy.package_policies.length === 0) {
if (!agentPolicy.package_policies || agentPolicy.package_policies.length === 0) {
return <NoPackagePolicies policyId={agentPolicy.id} />;
}

return (
<PackagePoliciesTable
agentPolicy={agentPolicy}
packagePolicies={(agentPolicy.package_policies || []) as PackagePolicy[]}
packagePolicies={agentPolicy.package_policies}
/>
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export const AgentPolicyListPage: React.FunctionComponent<{}> = () => {
sortField: sorting?.field,
sortOrder: sorting?.direction,
kuery: search,
full: true,
});

// Some policies retrieved, set up table props
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
import { i18n } from '@kbn/i18n';
import { FormattedMessage, FormattedRelative } from '@kbn/i18n-react';

import type { Agent, AgentPolicy, PackagePolicy, SimplifiedAgentStatus } from '../../../types';
import type { Agent, AgentPolicy, SimplifiedAgentStatus } from '../../../types';
import {
usePagination,
useAuthz,
Expand All @@ -35,8 +35,12 @@ import {
sendGetAgentTags,
} from '../../../hooks';
import { AgentEnrollmentFlyout, AgentPolicySummaryLine } from '../../../components';
import { AgentStatusKueryHelper, isAgentUpgradeable } from '../../../services';
import { AGENTS_PREFIX, FLEET_SERVER_PACKAGE, SO_SEARCH_LIMIT } from '../../../constants';
import {
AgentStatusKueryHelper,
isAgentUpgradeable,
policyHasFleetServer,
} from '../../../services';
import { AGENTS_PREFIX, SO_SEARCH_LIMIT } from '../../../constants';
import {
AgentReassignAgentPolicyModal,
AgentHealth,
Expand Down Expand Up @@ -389,10 +393,7 @@ export const AgentListPage: React.FunctionComponent<{}> = () => {
return false;
}

return agentPolicy.package_policies.some(
(ap: string | PackagePolicy) =>
typeof ap !== 'string' && ap.package?.name === FLEET_SERVER_PACKAGE
);
return policyHasFleetServer(agentPolicy);
}, [agentToUnenroll, agentPoliciesIndexedById]);

// Fleet server unhealthy status
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -717,11 +717,7 @@ On Windows, the module was tested with Nginx installed from the Chocolatey repos
namespace: 'default',
description: 'Default agent policy created by Kibana',
status: 'active',
package_policies: [
'4d09bd78-b0ad-4238-9fa3-d87d3c887c73',
'2babac18-eb8e-4ce4-b53b-4b7c5f507019',
'e8a37031-2907-44f6-89d2-98bd493f60dc',
],
package_policies: [],
is_managed: false,
monitoring_enabled: ['logs', 'metrics'],
revision: 6,
Expand All @@ -735,7 +731,7 @@ On Windows, the module was tested with Nginx installed from the Chocolatey repos
namespace: 'default',
description: 'Protect EU from COVID',
status: 'active',
package_policies: ['e8a37031-2907-44f6-89d2-98bd493f60cd'],
package_policies: [],
is_managed: false,
monitoring_enabled: ['logs', 'metrics'],
revision: 2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import type {
GetPackagePoliciesResponse,
} from '../../../../../types';
import { agentPolicyRouteService } from '../../../../../services';
import { AGENT_POLICY_SAVED_OBJECT_TYPE } from '../../../../../constants';
import { useGetPackagePolicies, useConditionalRequest } from '../../../../../hooks';
import type { SendConditionalRequestConfig } from '../../../../../hooks';

Expand Down Expand Up @@ -52,37 +51,31 @@ export const usePackagePoliciesWithAgentPolicy = (
resendRequest,
} = useGetPackagePolicies(query);

const agentPoliciesFilter = useMemo<string>(() => {
const agentPoliciesIds = useMemo<string[]>(() => {
if (!packagePoliciesData?.items.length) {
return '';
return [];
}

// Build a list of package_policies for which we need Agent Policies for. Since some package
// policies can exist within the same Agent Policy, we don't need to (in some cases) include
// the entire list of package_policy ids.
const includedAgentPolicies = new Set<string>();

return `${AGENT_POLICY_SAVED_OBJECT_TYPE}.package_policies: (${packagePoliciesData.items
.filter((packagePolicy) => {
if (includedAgentPolicies.has(packagePolicy.policy_id)) {
return false;
}
includedAgentPolicies.add(packagePolicy.policy_id);
return true;
})
.map((packagePolicy) => packagePolicy.id)
.join(' or ')}) `;
return Array.from(
new Set<string>(
packagePoliciesData.items.map((packagePolicy) => packagePolicy.policy_id)
).values()
);
}, [packagePoliciesData]);

const { data: agentPoliciesData, isLoading: isLoadingAgentPolicies } =
useConditionalRequest<GetAgentPoliciesResponse>({
path: agentPolicyRouteService.getListPath(),
method: 'get',
query: {
perPage: 100,
kuery: agentPoliciesFilter,
path: agentPolicyRouteService.getBulkGetPath(),
method: 'post',
body: {
ids: agentPoliciesIds,
full: true,
ignoreMissing: true,
},
shouldSendRequest: !!packagePoliciesData?.items.length,
shouldSendRequest: agentPoliciesIds.length > 0,
} as SendConditionalRequestConfig);

const [enrichedData, setEnrichedData] = useState<GetPackagePoliciesWithAgentPolicy | undefined>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ export const usePackageInstallations = () => {
const updatableIntegrations = useMemo<Map<string, UpdatableIntegration>>(
() =>
(agentPolicyData?.items || []).reduce((result, policy) => {
policy.package_policies.forEach((pkgPolicy: PackagePolicy | string) => {
if (typeof pkgPolicy === 'string' || !pkgPolicy.package) return false;
policy.package_policies?.forEach((pkgPolicy: PackagePolicy) => {
if (!pkgPolicy.package) return false;
const { name, version } = pkgPolicy.package;
const installedPackage = allInstalledPackages.find(
(installedPkg) =>
Expand Down
9 changes: 6 additions & 3 deletions x-pack/plugins/fleet/public/services/has_fleet_server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ import { FLEET_SERVER_PACKAGE } from '../constants';
import type { AgentPolicy, PackagePolicy } from '../types';

export function policyHasFleetServer(agentPolicy: AgentPolicy) {
return agentPolicy.package_policies?.some(
(ap: string | PackagePolicy) =>
typeof ap !== 'string' && ap.package?.name === FLEET_SERVER_PACKAGE
if (!agentPolicy.package_policies) {
return false;
}

return agentPolicy.package_policies.some(
(ap: PackagePolicy) => ap.package?.name === FLEET_SERVER_PACKAGE
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -248,9 +248,7 @@ describe('Fleet preconfiguration reset', () => {
it('Works if the preconfigured policies already exists with a missing package policy', async () => {
const soClient = kbnServer.coreStart.savedObjects.createInternalRepository();

await soClient.update('ingest-agent-policies', POLICY_ID, {
package_policies: [],
});
await soClient.update('ingest-agent-policies', POLICY_ID, {});

const resetAPI = getSupertestWithAdminUser(
kbnServer.root,
Expand All @@ -268,7 +266,6 @@ describe('Fleet preconfiguration reset', () => {
expect.arrayContaining([
expect.objectContaining({
name: 'Elastic Cloud agent policy 0001',
package_policies: expect.arrayContaining([expect.stringMatching(/.*/)]),
}),
expect.objectContaining({
name: 'Second preconfigured policy',
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/fleet/server/mocks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ export const createPackagePolicyServiceMock = (): jest.Mocked<PackagePolicyServi
getUpgradeDryRunDiff: jest.fn(),
getUpgradePackagePolicyInfo: jest.fn(),
enrichPolicyWithDefaultsFromPackage: jest.fn(),
findAllForAgentPolicy: jest.fn(),
};
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export const getAgentPoliciesHandler: FleetRequestHandler<
withPackagePolicies,
...restOfQuery,
});

const body: GetAgentPoliciesResponse = {
items,
total,
Expand Down
3 changes: 2 additions & 1 deletion x-pack/plugins/fleet/server/saved_objects/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import {
migrateAgentPolicyToV840,
migratePackagePolicyToV840,
} from './migrations/to_v8_4_0';
import { migrateAgentPolicyToV850 } from './migrations/to_v8_5_0';

/*
* Saved object types and mappings
Expand Down Expand Up @@ -91,7 +92,6 @@ const getSavedObjectTypes = (
is_default: { type: 'boolean' },
is_default_fleet_server: { type: 'boolean' },
status: { type: 'keyword' },
package_policies: { type: 'keyword' },
unenroll_timeout: { type: 'integer' },
updated_at: { type: 'date' },
updated_by: { type: 'keyword' },
Expand All @@ -107,6 +107,7 @@ const getSavedObjectTypes = (
'7.10.0': migrateAgentPolicyToV7100,
'7.12.0': migrateAgentPolicyToV7120,
'8.4.0': migrateAgentPolicyToV840,
'8.5.0': migrateAgentPolicyToV850,
},
},
[OUTPUT_SAVED_OBJECT_TYPE]: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ import type { SavedObjectMigrationFn } from '@kbn/core/server';
import type { AgentPolicy, PackagePolicy, Settings } from '../../types';

export const migrateAgentPolicyToV7100: SavedObjectMigrationFn<
Exclude<AgentPolicy, 'package_policies'> & {
package_configs: string[] | PackagePolicy[];
Omit<AgentPolicy, 'package_policies'> & {
package_configs: string[];
package_policies?: string[];
},
AgentPolicy
Omit<AgentPolicy, 'package_policies'> & {
package_policies?: string[];
}
> = (agentPolicyDoc) => {
agentPolicyDoc.attributes.package_policies = agentPolicyDoc.attributes.package_configs;
// @ts-expect-error
Expand Down
22 changes: 22 additions & 0 deletions x-pack/plugins/fleet/server/saved_objects/migrations/to_v8_5_0.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import type { SavedObjectMigrationFn } from '@kbn/core/server';

import type { AgentPolicy } from '../../types';

export const migrateAgentPolicyToV850: SavedObjectMigrationFn<
Exclude<AgentPolicy, 'download_source_id'> & {
package_policies: string[];
},
AgentPolicy
> = (agentPolicyDoc) => {
// @ts-expect-error
delete agentPolicyDoc.attributes.package_policies;

return agentPolicyDoc;
};
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@ describe('storedPackagePoliciesToAgentPermissions()', () => {
expect(permissions).toBeUndefined();
});

it('Throw an error for string package policies', async () => {
await expect(() => storedPackagePoliciesToAgentPermissions(soClient, ['foo'])).rejects.toThrow(
it('Throw an error if package policies is not an array', async () => {
await expect(() =>
storedPackagePoliciesToAgentPermissions(soClient, undefined)
).rejects.toThrow(
/storedPackagePoliciesToAgentPermissions should be called with a PackagePolicy/
);
});
Expand Down
Loading

0 comments on commit 368eba6

Please sign in to comment.