mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[9.0] [Security Solution][Risk Score]Code changes for limiting the transformID length to 36 characters (#213405) (#215267)
# Backport This will backport the following commits from `main` to `9.0`: - [[Security Solution][Risk Score]Code changes for limiting the transformID length to 36 characters (#213405)](https://github.com/elastic/kibana/pull/213405) <!--- Backport version: 9.6.6 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport) <!--BACKPORT [{"author":{"name":"Abhishek Bhatia","email":"117628830+abhishekbhatia1710@users.noreply.github.com"},"sourceCommit":{"committedDate":"2025-03-20T05:53:55Z","message":"[Security Solution][Risk Score]Code changes for limiting the transformID length to 36 characters (#213405)\n\n## Summary\n\nThe code changes in this PR ensure that the transform ID is limited to\n36 characters when creating or updating the transform for risk-score.\n\nThis adjustment aligns with ES constraint on transform ID length.\n\n\n## Test Steps\n\n1. Create a new namespace with a very long name. Ex :\n`namespace_that_stretches_farther_than_the_universe_and_beyond_like_buzz`\n🚀\n2. Enable the Risk Score in the new namespace. It should successfully\nget enabled.\n3. Check the transform that was created (using dev tools)\n\n```\nGET _transform/risk_score_latest_transform_*?filter_path=transforms.id,transforms._meta.space_id\n```\n\nOutput \n\n\n\n\n### Checklist\n\nCheck the PR satisfies following conditions. \n\nReviewers should verify this PR satisfies this list as well.\n\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios\n- [x] If a plugin configuration key changed, check if it needs to be\nallowlisted in the cloud and added to the [docker\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)\n- [x] The PR description includes the appropriate Release Notes section,\nand the correct `release_note:*` label is applied per the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n\n---------\n\nCo-authored-by: Mark Hopkin <mark.hopkin@elastic.co>","sha":"a3f89ec2c25b1ca6a75a7bf41ac0360a3a887806","branchLabelMapping":{"^v9.1.0$":"main","^v8.19.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","v9.0.0","Team:Entity Analytics","backport:version","v9.1.0"],"title":"[Security Solution][Risk Score]Code changes for limiting the transformID length to 36 characters","number":213405,"url":"https://github.com/elastic/kibana/pull/213405","mergeCommit":{"message":"[Security Solution][Risk Score]Code changes for limiting the transformID length to 36 characters (#213405)\n\n## Summary\n\nThe code changes in this PR ensure that the transform ID is limited to\n36 characters when creating or updating the transform for risk-score.\n\nThis adjustment aligns with ES constraint on transform ID length.\n\n\n## Test Steps\n\n1. Create a new namespace with a very long name. Ex :\n`namespace_that_stretches_farther_than_the_universe_and_beyond_like_buzz`\n🚀\n2. Enable the Risk Score in the new namespace. It should successfully\nget enabled.\n3. Check the transform that was created (using dev tools)\n\n```\nGET _transform/risk_score_latest_transform_*?filter_path=transforms.id,transforms._meta.space_id\n```\n\nOutput \n\n\n\n\n### Checklist\n\nCheck the PR satisfies following conditions. \n\nReviewers should verify this PR satisfies this list as well.\n\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios\n- [x] If a plugin configuration key changed, check if it needs to be\nallowlisted in the cloud and added to the [docker\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)\n- [x] The PR description includes the appropriate Release Notes section,\nand the correct `release_note:*` label is applied per the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n\n---------\n\nCo-authored-by: Mark Hopkin <mark.hopkin@elastic.co>","sha":"a3f89ec2c25b1ca6a75a7bf41ac0360a3a887806"}},"sourceBranch":"main","suggestedTargetBranches":["9.0"],"targetPullRequestStates":[{"branch":"9.0","label":"v9.0.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/213405","number":213405,"mergeCommit":{"message":"[Security Solution][Risk Score]Code changes for limiting the transformID length to 36 characters (#213405)\n\n## Summary\n\nThe code changes in this PR ensure that the transform ID is limited to\n36 characters when creating or updating the transform for risk-score.\n\nThis adjustment aligns with ES constraint on transform ID length.\n\n\n## Test Steps\n\n1. Create a new namespace with a very long name. Ex :\n`namespace_that_stretches_farther_than_the_universe_and_beyond_like_buzz`\n🚀\n2. Enable the Risk Score in the new namespace. It should successfully\nget enabled.\n3. Check the transform that was created (using dev tools)\n\n```\nGET _transform/risk_score_latest_transform_*?filter_path=transforms.id,transforms._meta.space_id\n```\n\nOutput \n\n\n\n\n### Checklist\n\nCheck the PR satisfies following conditions. \n\nReviewers should verify this PR satisfies this list as well.\n\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios\n- [x] If a plugin configuration key changed, check if it needs to be\nallowlisted in the cloud and added to the [docker\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)\n- [x] The PR description includes the appropriate Release Notes section,\nand the correct `release_note:*` label is applied per the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n\n---------\n\nCo-authored-by: Mark Hopkin <mark.hopkin@elastic.co>","sha":"a3f89ec2c25b1ca6a75a7bf41ac0360a3a887806"}}]}] BACKPORT--> Co-authored-by: Abhishek Bhatia <117628830+abhishekbhatia1710@users.noreply.github.com>
This commit is contained in:
parent
12a8f3062c
commit
a043700f59
7 changed files with 40 additions and 5 deletions
|
@ -12,6 +12,7 @@ describe('getTransformOptions', () => {
|
|||
const options = getTransformOptions({
|
||||
dest: 'dest',
|
||||
source: ['source'],
|
||||
namespace: 'tests',
|
||||
});
|
||||
|
||||
expect(options).toMatchInlineSnapshot(`
|
||||
|
@ -19,6 +20,7 @@ describe('getTransformOptions', () => {
|
|||
"_meta": Object {
|
||||
"managed": true,
|
||||
"managed_by": "security-entity-analytics",
|
||||
"space_id": "tests",
|
||||
"version": 3,
|
||||
},
|
||||
"dest": Object {
|
||||
|
|
|
@ -164,9 +164,11 @@ export type TransformOptions = Omit<TransformPutTransformRequest, 'transform_id'
|
|||
export const getTransformOptions = ({
|
||||
dest,
|
||||
source,
|
||||
namespace,
|
||||
}: {
|
||||
dest: string;
|
||||
source: string[];
|
||||
namespace: string;
|
||||
}): Omit<TransformPutTransformRequest, 'transform_id'> => ({
|
||||
dest: {
|
||||
index: dest,
|
||||
|
@ -206,5 +208,6 @@ export const getTransformOptions = ({
|
|||
version: 3, // When this field is updated we automatically update the transform
|
||||
managed: true, // Metadata that identifies the transform. It has no functionality
|
||||
managed_by: 'security-entity-analytics', // Metadata that identifies the transform. It has no functionality
|
||||
space_id: namespace, // Metadata that identifies the space where the transform is running. Helps in debugging as the original transformid could be hashed if longer than 64 characters
|
||||
},
|
||||
});
|
||||
|
|
|
@ -45,6 +45,7 @@ const totalFieldsLimit = 1000;
|
|||
describe('RiskScoreDataClient', () => {
|
||||
let riskScoreDataClient: RiskScoreDataClient;
|
||||
let riskScoreDataClientWithNameSpace: RiskScoreDataClient;
|
||||
let riskScoreDataClientWithLongNameSpace: RiskScoreDataClient;
|
||||
let mockSavedObjectClient: ReturnType<typeof savedObjectsClientMock.create>;
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -60,6 +61,8 @@ describe('RiskScoreDataClient', () => {
|
|||
riskScoreDataClient = new RiskScoreDataClient(options);
|
||||
const optionsWithNamespace = { ...options, namespace: 'space-1' };
|
||||
riskScoreDataClientWithNameSpace = new RiskScoreDataClient(optionsWithNamespace);
|
||||
const optionsWithLongNamespace = { ...options, namespace: 'a_a-'.repeat(200) };
|
||||
riskScoreDataClientWithLongNameSpace = new RiskScoreDataClient(optionsWithLongNamespace);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -103,6 +106,10 @@ describe('RiskScoreDataClient', () => {
|
|||
assertIndex('space-1');
|
||||
assertTransform('space-1');
|
||||
|
||||
// Space with more than 36 characters
|
||||
await riskScoreDataClientWithLongNameSpace.init();
|
||||
assertTransform('a_a-'.repeat(200));
|
||||
|
||||
expect(
|
||||
(createOrUpdateComponentTemplate as jest.Mock).mock.lastCall[0].template.template
|
||||
).toMatchSnapshot();
|
||||
|
@ -445,7 +452,7 @@ const assertTransform = (namespace: string) => {
|
|||
field: '@timestamp',
|
||||
},
|
||||
},
|
||||
transform_id: `risk_score_latest_transform_${namespace}`,
|
||||
transform_id: transforms.getLatestTransformId(namespace),
|
||||
settings: {
|
||||
unattended: true,
|
||||
},
|
||||
|
@ -453,6 +460,7 @@ const assertTransform = (namespace: string) => {
|
|||
version: 3,
|
||||
managed: true,
|
||||
managed_by: 'security-entity-analytics',
|
||||
space_id: namespace,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -201,6 +201,7 @@ export class RiskScoreDataClient {
|
|||
...getTransformOptions({
|
||||
dest: getRiskScoreLatestIndex(namespace),
|
||||
source: [indexPatterns.alias],
|
||||
namespace: this.options.namespace,
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
@ -367,6 +368,7 @@ export class RiskScoreDataClient {
|
|||
...getTransformOptions({
|
||||
dest: getRiskScoreLatestIndex(namespace),
|
||||
source: [indexPatterns.alias],
|
||||
namespace: this.options.namespace,
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
|
|
@ -19,6 +19,7 @@ import {
|
|||
scheduleLatestTransformNow,
|
||||
scheduleTransformNow,
|
||||
upgradeLatestTransformIfNeeded,
|
||||
getLatestTransformId,
|
||||
} from './transforms';
|
||||
|
||||
const transformId = 'test_transform_id';
|
||||
|
@ -48,6 +49,7 @@ const timeSeriesIndex = getRiskScoreTimeSeriesIndex('tests');
|
|||
const transformConfig = getTransformOptions({
|
||||
dest: latestIndex,
|
||||
source: [timeSeriesIndex],
|
||||
namespace: 'tests',
|
||||
});
|
||||
|
||||
const updatedTransformsMock = {
|
||||
|
@ -206,4 +208,12 @@ describe('transforms utils', () => {
|
|||
expect(esClient.transform.putTransform).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('checkTransformNameLength', () => {
|
||||
it('should limit the length of tranformId to less than or equal 64 characters', async () => {
|
||||
const longTransformId = 'a_a-'.repeat(1000);
|
||||
const response = await getLatestTransformId(longTransformId);
|
||||
expect(response.length).toBeLessThanOrEqual(36);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -14,6 +14,7 @@ import type {
|
|||
TransformGetTransformStatsTransformStats,
|
||||
AcknowledgedResponseBase,
|
||||
} from '@elastic/elasticsearch/lib/api/types';
|
||||
import murmurhash from 'murmurhash';
|
||||
import {
|
||||
getRiskScoreLatestIndex,
|
||||
getRiskScoreTimeSeriesIndex,
|
||||
|
@ -116,8 +117,15 @@ export const reinstallTransform = async ({
|
|||
});
|
||||
};
|
||||
|
||||
export const getLatestTransformId = (namespace: string): string =>
|
||||
`risk_score_latest_transform_${namespace}`;
|
||||
export const getLatestTransformId = (namespace: string): string => {
|
||||
const maxTransformId = 64;
|
||||
const prefix = `risk_score_latest_transform_`;
|
||||
const fullName = `${prefix}${namespace}`;
|
||||
|
||||
const processedNamespace =
|
||||
fullName.length > maxTransformId ? murmurhash.v3(namespace).toString(16) : namespace;
|
||||
return `${prefix}${processedNamespace}`;
|
||||
};
|
||||
|
||||
const hasTransformStarted = (transformStats: TransformGetTransformStatsTransformStats): boolean => {
|
||||
return transformStats.state === 'indexing' || transformStats.state === 'started';
|
||||
|
@ -174,6 +182,7 @@ export const upgradeLatestTransformIfNeeded = async ({
|
|||
const newConfig = getTransformOptions({
|
||||
dest: latestIndex,
|
||||
source: [timeSeriesIndex],
|
||||
namespace,
|
||||
});
|
||||
|
||||
if (isTransformOutdated(response.transforms[0], newConfig)) {
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
import expect from '@kbn/expect';
|
||||
import { riskEngineConfigurationTypeName } from '@kbn/security-solution-plugin/server/lib/entity_analytics/risk_engine/saved_object';
|
||||
|
||||
import { getLatestTransformId } from '@kbn/security-solution-plugin/server/lib/entity_analytics/utils/transforms';
|
||||
import { riskEngineRouteHelpersFactory } from '../../utils';
|
||||
import { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
|
@ -70,7 +71,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
const indexTemplateName = '.risk-score.risk-score-default-index-template';
|
||||
const dataStreamName = 'risk-score.risk-score-default';
|
||||
const latestIndexName = 'risk-score.risk-score-latest-default';
|
||||
const transformId = 'risk_score_latest_transform_default';
|
||||
const transformId = getLatestTransformId('default');
|
||||
const defaultPipeline =
|
||||
'entity_analytics_create_eventIngest_from_timestamp-pipeline-default';
|
||||
|
||||
|
@ -350,7 +351,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
const indexTemplateName = `.risk-score.risk-score-${customSpaceName}-index-template`;
|
||||
const dataStreamName = `risk-score.risk-score-${customSpaceName}`;
|
||||
const latestIndexName = `risk-score.risk-score-latest-${customSpaceName}`;
|
||||
const transformId = `risk_score_latest_transform_${customSpaceName}`;
|
||||
const transformId = getLatestTransformId(customSpaceName);
|
||||
const defaultPipeline = `entity_analytics_create_eventIngest_from_timestamp-pipeline-${customSpaceName}`;
|
||||
|
||||
await riskEngineRoutesWithNamespace.init();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue