mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 18:51:07 -04:00
[Security Solution] Correct the license_uuid reference name in the Endpoint Policy (#167194)
## Summary
Correct the `license_uuid` field name in the Endpoint Policy. Before, it
was named `license_uid`, but the Endpoint expects `license_uuid`.
This PR in intended to be backported to `8.10.3` which brings up an
interesting problem since we already have a migration added to `main`
for the `8.11` release.
After talking with the kibana-core team, my approach is to add the
migration for this bug fix to this PR. Then, to keep the `modelVersions`
consistent, I will backport all `modelVersions` to `8.10.3` to keep the
migrations consistent. Keeping these consistent is important so that
both users upgrading from `8.10.x` in ESS and the Serverless line all
remain in sync. The end result is that the policies inside of of
`8.10.3` will have an extra field that will be unused until `8.11.0`
The following `8.10.3` backport for this will include the extra
migration and I will request reviews for it since it will be more than a
normal backport.
Policy:

### Checklist
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
2edc13c2c1
commit
9d6ec1a7cb
10 changed files with 261 additions and 13 deletions
|
@ -106,7 +106,7 @@ describe('checking migration metadata changes on all registered SO types', () =>
|
|||
"ingest-agent-policies": "f11cc19275f4c3e4ee7c5cd6423b6706b21b989d",
|
||||
"ingest-download-sources": "279a68147e62e4d8858c09ad1cf03bd5551ce58d",
|
||||
"ingest-outputs": "b4e636b13a5d0f89f0400fb67811d4cca4736eb0",
|
||||
"ingest-package-policies": "af9e8d523a6f3ae5b8c9adcfba391ff405dfa374",
|
||||
"ingest-package-policies": "8ec637429836f80f1fcc798bcee7c5916eceaed5",
|
||||
"ingest_manager_settings": "64955ef1b7a9ffa894d4bb9cf863b5602bfa6885",
|
||||
"inventory-view": "b8683c8e352a286b4aca1ab21003115a4800af83",
|
||||
"kql-telemetry": "93c1d16c1a0dfca9c8842062cf5ef8f62ae401ad",
|
||||
|
|
|
@ -36,6 +36,11 @@ import { migrateSyntheticsPackagePolicyToV8100 } from './migrations/synthetics/t
|
|||
|
||||
import { migratePackagePolicyEvictionsFromV8100 } from './migrations/security_solution/to_v8_10_0';
|
||||
|
||||
import {
|
||||
migratePackagePolicyEvictionsFromV81102,
|
||||
migratePackagePolicyToV81102,
|
||||
} from './migrations/security_solution/to_v8_11_0_2';
|
||||
|
||||
import {
|
||||
migrateAgentPolicyToV7100,
|
||||
migratePackagePolicyToV7100,
|
||||
|
@ -335,6 +340,17 @@ const getSavedObjectTypes = (): { [key: string]: SavedObjectsType } => ({
|
|||
forwardCompatibility: migratePackagePolicyEvictionsFromV8110,
|
||||
},
|
||||
},
|
||||
'3': {
|
||||
changes: [
|
||||
{
|
||||
type: 'data_backfill',
|
||||
backfillFn: migratePackagePolicyToV81102,
|
||||
},
|
||||
],
|
||||
schemas: {
|
||||
forwardCompatibility: migratePackagePolicyEvictionsFromV81102,
|
||||
},
|
||||
},
|
||||
},
|
||||
migrations: {
|
||||
'7.10.0': migratePackagePolicyToV7100,
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* 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 { SavedObjectUnsanitizedDoc } from '@kbn/core/server';
|
||||
|
||||
import type { SavedObjectModelTransformationContext } from '@kbn/core-saved-objects-server';
|
||||
|
||||
import type { PackagePolicy } from '../../../../common';
|
||||
|
||||
import { migratePackagePolicyToV81102 as migration } from './to_v8_11_0_2';
|
||||
import { migratePackagePolicyEvictionsFromV81102 as eviction } from './to_v8_11_0_2';
|
||||
|
||||
describe('8.11.0-2 Endpoint Package Policy migration', () => {
|
||||
const policyDoc = ({ meta = {} }) => {
|
||||
return {
|
||||
id: 'mock-saved-object-id',
|
||||
attributes: {
|
||||
name: 'Some Policy Name',
|
||||
package: {
|
||||
name: 'endpoint',
|
||||
title: '',
|
||||
version: '',
|
||||
},
|
||||
id: 'endpoint',
|
||||
policy_id: '',
|
||||
enabled: true,
|
||||
namespace: '',
|
||||
revision: 0,
|
||||
updated_at: '',
|
||||
updated_by: '',
|
||||
created_at: '',
|
||||
created_by: '',
|
||||
inputs: [
|
||||
{
|
||||
type: 'endpoint',
|
||||
enabled: true,
|
||||
streams: [],
|
||||
config: {
|
||||
policy: {
|
||||
value: {
|
||||
meta: {
|
||||
license: '',
|
||||
cloud: false,
|
||||
cluster_uuid: 'qwe',
|
||||
cluster_name: 'clusterName',
|
||||
...meta,
|
||||
},
|
||||
windows: {},
|
||||
mac: {},
|
||||
linux: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
type: ' nested',
|
||||
};
|
||||
};
|
||||
|
||||
it('adds a new field `license_uuid` that takes the value of `license_uid` if it exists', () => {
|
||||
const initialDoc = policyDoc({ meta: { license_uid: 'existing_uuid' } });
|
||||
|
||||
const migratedDoc = policyDoc({
|
||||
meta: { license_uid: 'existing_uuid', license_uuid: 'existing_uuid' },
|
||||
});
|
||||
|
||||
expect(migration(initialDoc, {} as SavedObjectModelTransformationContext)).toEqual({
|
||||
attributes: {
|
||||
inputs: migratedDoc.attributes.inputs,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('adds a new field `license_uuid` that takes an empty value if `existing_uid` does not exist', () => {
|
||||
const initialDoc = policyDoc({});
|
||||
|
||||
const migratedDoc = policyDoc({
|
||||
meta: { license_uuid: '' },
|
||||
});
|
||||
|
||||
expect(migration(initialDoc, {} as SavedObjectModelTransformationContext)).toEqual({
|
||||
attributes: {
|
||||
inputs: migratedDoc.attributes.inputs,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('removes `license_uuid` for backwards compatibility', () => {
|
||||
const initialDoc = policyDoc({
|
||||
meta: { license_uuid: 'existing_uuid' },
|
||||
});
|
||||
|
||||
const migratedDoc = policyDoc({});
|
||||
|
||||
expect(eviction(initialDoc.attributes)).toEqual(migratedDoc.attributes);
|
||||
});
|
||||
|
||||
it('does not modify non-endpoint package policies', () => {
|
||||
const doc: SavedObjectUnsanitizedDoc<PackagePolicy> = {
|
||||
id: 'mock-saved-object-id',
|
||||
attributes: {
|
||||
name: 'Some Policy Name',
|
||||
package: {
|
||||
name: 'notEndpoint',
|
||||
title: '',
|
||||
version: '',
|
||||
},
|
||||
id: 'notEndpoint',
|
||||
policy_id: '',
|
||||
enabled: true,
|
||||
namespace: '',
|
||||
revision: 0,
|
||||
updated_at: '',
|
||||
updated_by: '',
|
||||
created_at: '',
|
||||
created_by: '',
|
||||
inputs: [
|
||||
{
|
||||
type: 'notEndpoint',
|
||||
enabled: true,
|
||||
streams: [],
|
||||
config: {},
|
||||
},
|
||||
],
|
||||
},
|
||||
type: ' nested',
|
||||
};
|
||||
|
||||
expect(
|
||||
migration(
|
||||
doc,
|
||||
{} as SavedObjectModelTransformationContext
|
||||
) as SavedObjectUnsanitizedDoc<PackagePolicy>
|
||||
).toEqual({
|
||||
attributes: {
|
||||
name: 'Some Policy Name',
|
||||
package: {
|
||||
name: 'notEndpoint',
|
||||
title: '',
|
||||
version: '',
|
||||
},
|
||||
id: 'notEndpoint',
|
||||
policy_id: '',
|
||||
enabled: true,
|
||||
namespace: '',
|
||||
revision: 0,
|
||||
updated_at: '',
|
||||
updated_by: '',
|
||||
created_at: '',
|
||||
created_by: '',
|
||||
inputs: [
|
||||
{
|
||||
type: 'notEndpoint',
|
||||
enabled: true,
|
||||
streams: [],
|
||||
config: {},
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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 { SavedObjectUnsanitizedDoc } from '@kbn/core/server';
|
||||
|
||||
import type { SavedObjectModelDataBackfillFn } from '@kbn/core-saved-objects-server';
|
||||
|
||||
import { omit } from 'lodash';
|
||||
|
||||
import type { SavedObjectModelVersionForwardCompatibilityFn } from '@kbn/core-saved-objects-server';
|
||||
|
||||
import type { PackagePolicy } from '../../../../common';
|
||||
|
||||
export const migratePackagePolicyToV81102: SavedObjectModelDataBackfillFn<
|
||||
PackagePolicy,
|
||||
PackagePolicy
|
||||
> = (packagePolicyDoc) => {
|
||||
if (packagePolicyDoc.attributes.package?.name !== 'endpoint') {
|
||||
return { attributes: packagePolicyDoc.attributes };
|
||||
}
|
||||
|
||||
const updatedPackagePolicyDoc: SavedObjectUnsanitizedDoc<PackagePolicy> = packagePolicyDoc;
|
||||
|
||||
const input = updatedPackagePolicyDoc.attributes.inputs[0];
|
||||
|
||||
if (input && input.config) {
|
||||
const policy = input.config.policy.value;
|
||||
|
||||
const newMetaValues = {
|
||||
license_uuid: policy?.meta?.license_uid ? policy.meta.license_uid : '',
|
||||
};
|
||||
|
||||
policy.meta = policy?.meta ? { ...policy.meta, ...newMetaValues } : newMetaValues;
|
||||
}
|
||||
|
||||
return {
|
||||
attributes: {
|
||||
inputs: updatedPackagePolicyDoc.attributes.inputs,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const migratePackagePolicyEvictionsFromV81102: SavedObjectModelVersionForwardCompatibilityFn =
|
||||
(unknownAttributes) => {
|
||||
const attributes = unknownAttributes as PackagePolicy;
|
||||
if (attributes.package?.name !== 'endpoint') {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
const updatedAttributes = attributes;
|
||||
|
||||
const input = updatedAttributes.inputs[0];
|
||||
|
||||
if (input && input.config) {
|
||||
const policy = input.config.policy.value;
|
||||
|
||||
policy.meta = omit(policy.meta, ['license_uuid']);
|
||||
}
|
||||
|
||||
return updatedAttributes;
|
||||
};
|
|
@ -22,7 +22,7 @@ export const policyFactory = (
|
|||
return {
|
||||
meta: {
|
||||
license,
|
||||
license_uid: licenseUid,
|
||||
license_uuid: licenseUid,
|
||||
cluster_uuid: clusterUuid,
|
||||
cluster_name: clusterName,
|
||||
cloud,
|
||||
|
|
|
@ -196,7 +196,7 @@ export const eventsOnlyPolicy = (): PolicyConfig => ({
|
|||
meta: {
|
||||
license: '',
|
||||
cloud: false,
|
||||
license_uid: '',
|
||||
license_uuid: '',
|
||||
cluster_name: '',
|
||||
cluster_uuid: '',
|
||||
serverless: false,
|
||||
|
|
|
@ -942,7 +942,7 @@ export interface PolicyConfig {
|
|||
meta: {
|
||||
license: string;
|
||||
cloud: boolean;
|
||||
license_uid: string;
|
||||
license_uuid: string;
|
||||
cluster_uuid: string;
|
||||
cluster_name: string;
|
||||
serverless: boolean;
|
||||
|
|
|
@ -273,7 +273,7 @@ describe('policy details: ', () => {
|
|||
meta: {
|
||||
license: '',
|
||||
cloud: false,
|
||||
license_uid: '',
|
||||
license_uuid: '',
|
||||
cluster_name: '',
|
||||
cluster_uuid: '',
|
||||
serverless: false,
|
||||
|
|
|
@ -574,7 +574,7 @@ describe('ingest_integration tests ', () => {
|
|||
const infoResponse = {
|
||||
cluster_name: 'updated-name',
|
||||
cluster_uuid: 'updated-uuid',
|
||||
license_uid: 'updated-uid',
|
||||
license_uuid: 'updated-uuid',
|
||||
name: 'name',
|
||||
tagline: 'tagline',
|
||||
version: {
|
||||
|
@ -602,7 +602,7 @@ describe('ingest_integration tests ', () => {
|
|||
mockPolicy.meta.license = 'platinum'; // license is set to emit platinum
|
||||
mockPolicy.meta.cluster_name = 'updated-name';
|
||||
mockPolicy.meta.cluster_uuid = 'updated-uuid';
|
||||
mockPolicy.meta.license_uid = 'updated-uid';
|
||||
mockPolicy.meta.license_uuid = 'updated-uid';
|
||||
mockPolicy.meta.serverless = false;
|
||||
const logger = loggingSystemMock.create().get('ingest_integration.test');
|
||||
const callback = getPackagePolicyUpdateCallback(
|
||||
|
@ -621,7 +621,7 @@ describe('ingest_integration tests ', () => {
|
|||
policyConfig.inputs[0]!.config!.policy.value.meta.license = 'gold';
|
||||
policyConfig.inputs[0]!.config!.policy.value.meta.cluster_name = 'original-name';
|
||||
policyConfig.inputs[0]!.config!.policy.value.meta.cluster_uuid = 'original-uuid';
|
||||
policyConfig.inputs[0]!.config!.policy.value.meta.license_uid = 'original-uid';
|
||||
policyConfig.inputs[0]!.config!.policy.value.meta.license_uuid = 'original-uid';
|
||||
policyConfig.inputs[0]!.config!.policy.value.meta.serverless = true;
|
||||
const updatedPolicyConfig = await callback(
|
||||
policyConfig,
|
||||
|
@ -639,7 +639,7 @@ describe('ingest_integration tests ', () => {
|
|||
mockPolicy.meta.license = 'platinum'; // license is set to emit platinum
|
||||
mockPolicy.meta.cluster_name = 'updated-name';
|
||||
mockPolicy.meta.cluster_uuid = 'updated-uuid';
|
||||
mockPolicy.meta.license_uid = 'updated-uid';
|
||||
mockPolicy.meta.license_uuid = 'updated-uid';
|
||||
mockPolicy.meta.serverless = false;
|
||||
const logger = loggingSystemMock.create().get('ingest_integration.test');
|
||||
const callback = getPackagePolicyUpdateCallback(
|
||||
|
@ -657,7 +657,7 @@ describe('ingest_integration tests ', () => {
|
|||
policyConfig.inputs[0]!.config!.policy.value.meta.license = 'platinum';
|
||||
policyConfig.inputs[0]!.config!.policy.value.meta.cluster_name = 'updated-name';
|
||||
policyConfig.inputs[0]!.config!.policy.value.meta.cluster_uuid = 'updated-uuid';
|
||||
policyConfig.inputs[0]!.config!.policy.value.meta.license_uid = 'updated-uid';
|
||||
policyConfig.inputs[0]!.config!.policy.value.meta.license_uuid = 'updated-uid';
|
||||
policyConfig.inputs[0]!.config!.policy.value.meta.serverless = false;
|
||||
const updatedPolicyConfig = await callback(
|
||||
policyConfig,
|
||||
|
|
|
@ -59,7 +59,7 @@ const shouldUpdateMetaValues = (
|
|||
currentCloudInfo: boolean,
|
||||
currentClusterName: string,
|
||||
currentClusterUUID: string,
|
||||
currentLicenseUID: string,
|
||||
currentLicenseUUID: string,
|
||||
currentIsServerlessEnabled: boolean
|
||||
) => {
|
||||
return (
|
||||
|
@ -67,7 +67,7 @@ const shouldUpdateMetaValues = (
|
|||
endpointPackagePolicy.meta.cloud !== currentCloudInfo ||
|
||||
endpointPackagePolicy.meta.cluster_name !== currentClusterName ||
|
||||
endpointPackagePolicy.meta.cluster_uuid !== currentClusterUUID ||
|
||||
endpointPackagePolicy.meta.license_uid !== currentLicenseUID ||
|
||||
endpointPackagePolicy.meta.license_uuid !== currentLicenseUUID ||
|
||||
endpointPackagePolicy.meta.serverless !== currentIsServerlessEnabled
|
||||
);
|
||||
};
|
||||
|
@ -238,7 +238,7 @@ export const getPackagePolicyUpdateCallback = (
|
|||
newEndpointPackagePolicy.meta.cloud = cloud?.isCloudEnabled;
|
||||
newEndpointPackagePolicy.meta.cluster_name = esClientInfo.cluster_name;
|
||||
newEndpointPackagePolicy.meta.cluster_uuid = esClientInfo.cluster_uuid;
|
||||
newEndpointPackagePolicy.meta.license_uid = licenseService.getLicenseUID();
|
||||
newEndpointPackagePolicy.meta.license_uuid = licenseService.getLicenseUID();
|
||||
newEndpointPackagePolicy.meta.serverless = cloud?.isServerlessEnabled;
|
||||
|
||||
endpointIntegrationData.inputs[0].config.policy.value = newEndpointPackagePolicy;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue