Skip to content

Commit

Permalink
[Fleet] Append space ID to security solution tag (elastic#170789)
Browse files Browse the repository at this point in the history
## Summary

Fixes elastic#166798

Appends the current space ID to the ID of the security solution tag.

Note: If there are integrations suffering from the above bug (might be
"stuck" in `installing` status, showing concurrent installation errors,
etc), they should be reinstalled via the API in their corresponding
space, e.g.

```
# In Kibana dev tools for the space in which the integration is installed
POST kbn:/api/fleet/epm/packages/cisco_asa/2.27.1
{
  "force": true
}
```

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
kpollich and kibanamachine authored Nov 10, 2023
1 parent 5e661d0 commit dd2fda2
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -688,55 +688,108 @@ describe('tagKibanaAssets', () => {
);
});

it('should respect SecuritySolution tags', async () => {
savedObjectTagClient.get.mockRejectedValue(new Error('not found'));
savedObjectTagClient.create.mockImplementation(({ name }: { name: string }) =>
Promise.resolve({ id: name.toLowerCase(), name })
);
const kibanaAssets = {
dashboard: [
{ id: 'dashboard1', type: 'dashboard' },
{ id: 'dashboard2', type: 'dashboard' },
{ id: 'search_id1', type: 'search' },
{ id: 'search_id2', type: 'search' },
],
} as any;
const assetTags = [
{
text: 'Security Solution',
asset_types: ['dashboard'],
},
];
await tagKibanaAssets({
savedObjectTagAssignmentService,
savedObjectTagClient,
kibanaAssets,
pkgTitle: 'TestPackage',
pkgName: 'test-pkg',
spaceId: 'default',
importedAssets: [],
assetTags,
describe('Security Solution tag', () => {
it('creates tag in default space', async () => {
savedObjectTagClient.get.mockRejectedValue(new Error('not found'));
savedObjectTagClient.create.mockImplementation(({ name }: { name: string }) =>
Promise.resolve({ id: name.toLowerCase(), name })
);
const kibanaAssets = {
dashboard: [
{ id: 'dashboard1', type: 'dashboard' },
{ id: 'dashboard2', type: 'dashboard' },
{ id: 'search_id1', type: 'search' },
{ id: 'search_id2', type: 'search' },
],
} as any;
const assetTags = [
{
text: 'Security Solution',
asset_types: ['dashboard'],
},
];
await tagKibanaAssets({
savedObjectTagAssignmentService,
savedObjectTagClient,
kibanaAssets,
pkgTitle: 'TestPackage',
pkgName: 'test-pkg',
spaceId: 'default',
importedAssets: [],
assetTags,
});
expect(savedObjectTagClient.create).toHaveBeenCalledWith(
managedTagPayloadArg1,
managedTagPayloadArg2
);
expect(savedObjectTagClient.create).toHaveBeenCalledWith(
{
color: '#4DD2CA',
description: '',
name: 'TestPackage',
},
{ id: 'fleet-pkg-test-pkg-default', overwrite: true, refresh: false }
);
expect(savedObjectTagClient.create).toHaveBeenCalledWith(
{
color: expect.any(String),
description: 'Tag defined in package-spec',
name: 'Security Solution',
},
{ id: 'security-solution-default', overwrite: true, refresh: false }
);
});

it('creates tag in non-default space', async () => {
savedObjectTagClient.get.mockRejectedValue(new Error('not found'));
savedObjectTagClient.create.mockImplementation(({ name }: { name: string }) =>
Promise.resolve({ id: name.toLowerCase(), name })
);
const kibanaAssets = {
dashboard: [
{ id: 'dashboard1', type: 'dashboard' },
{ id: 'dashboard2', type: 'dashboard' },
{ id: 'search_id1', type: 'search' },
{ id: 'search_id2', type: 'search' },
],
} as any;
const assetTags = [
{
text: 'Security Solution',
asset_types: ['dashboard'],
},
];
await tagKibanaAssets({
savedObjectTagAssignmentService,
savedObjectTagClient,
kibanaAssets,
pkgTitle: 'TestPackage',
pkgName: 'test-pkg',
spaceId: 'my-secondary-space',
importedAssets: [],
assetTags,
});
expect(savedObjectTagClient.create).toHaveBeenCalledWith(managedTagPayloadArg1, {
...managedTagPayloadArg2,
id: 'fleet-managed-my-secondary-space',
});
expect(savedObjectTagClient.create).toHaveBeenCalledWith(
{
color: expect.any(String),
description: '',
name: 'TestPackage',
},
{ id: 'fleet-pkg-test-pkg-my-secondary-space', overwrite: true, refresh: false }
);
expect(savedObjectTagClient.create).toHaveBeenCalledWith(
{
color: expect.anything(),
description: 'Tag defined in package-spec',
name: 'Security Solution',
},
{ id: 'security-solution-my-secondary-space', overwrite: true, refresh: false }
);
});
expect(savedObjectTagClient.create).toHaveBeenCalledWith(
managedTagPayloadArg1,
managedTagPayloadArg2
);
expect(savedObjectTagClient.create).toHaveBeenCalledWith(
{
color: '#4DD2CA',
description: '',
name: 'TestPackage',
},
{ id: 'fleet-pkg-test-pkg-default', overwrite: true, refresh: false }
);
expect(savedObjectTagClient.create).toHaveBeenCalledWith(
{
color: expect.any(String),
description: 'Tag defined in package-spec',
name: 'Security Solution',
},
{ id: 'security-solution-default', overwrite: true, refresh: false }
);
});

it('should only call savedObjectTagClient.create for basic tags if there are no assetTags to assign', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const PACKAGE_TAG_COLOR = '#4DD2CA';
const MANAGED_TAG_NAME = 'Managed';
const LEGACY_MANAGED_TAG_ID = 'managed';
const SECURITY_SOLUTION_TAG_NAME = 'Security Solution';
const SECURITY_SOLUTION_TAG_ID = 'security-solution-default';
const SECURITY_SOLUTION_TAG_ID_BASE = 'security-solution';

// the tag service only accepts 6-digits hex colors
const TAG_COLORS = [
Expand Down Expand Up @@ -65,8 +65,10 @@ const getLegacyPackageTagId = (pkgName: string) => pkgName;
In that case return id `security-solution-default`
*/
export const getPackageSpecTagId = (spaceId: string, pkgName: string, tagName: string) => {
if (tagName.toLowerCase() === SECURITY_SOLUTION_TAG_NAME.toLowerCase())
return SECURITY_SOLUTION_TAG_ID;
if (tagName.toLowerCase() === SECURITY_SOLUTION_TAG_NAME.toLowerCase()) {
return `${SECURITY_SOLUTION_TAG_ID_BASE}-${spaceId}`;
}

// UUID v5 needs a namespace (uuid.DNS) to generate a predictable uuid
const uniqueId = uuidv5(`${tagName.toLowerCase()}`, uuidv5.DNS);
return `fleet-shared-tag-${pkgName}-${uniqueId}-${spaceId}`;
Expand Down

0 comments on commit dd2fda2

Please sign in to comment.