mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Fleet] Uninstalltoken saved object namespace agnostic and space aware (#190741)
This commit is contained in:
parent
3c2ce3c839
commit
2c50c4504c
9 changed files with 232 additions and 29 deletions
|
@ -544,6 +544,7 @@
|
|||
],
|
||||
"fleet-space-settings": [],
|
||||
"fleet-uninstall-tokens": [
|
||||
"namespaces",
|
||||
"policy_id",
|
||||
"token_plain"
|
||||
],
|
||||
|
|
|
@ -1812,6 +1812,9 @@
|
|||
"fleet-uninstall-tokens": {
|
||||
"dynamic": false,
|
||||
"properties": {
|
||||
"namespaces": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"policy_id": {
|
||||
"type": "keyword"
|
||||
},
|
||||
|
|
|
@ -110,7 +110,7 @@ describe('checking migration metadata changes on all registered SO types', () =>
|
|||
"fleet-proxy": "6cb688f0d2dd856400c1dbc998b28704ff70363d",
|
||||
"fleet-setup-lock": "0dc784792c79b5af5a6e6b5dcac06b0dbaa90bde",
|
||||
"fleet-space-settings": "b278e82a33978900e53a1253884b5bdbd929c9bb",
|
||||
"fleet-uninstall-tokens": "ed8aa37e3cdd69e4360709e64944bb81cae0c025",
|
||||
"fleet-uninstall-tokens": "371a691206845b364bcf6d3693ca7905ffdb71a4",
|
||||
"graph-workspace": "5cc6bb1455b078fd848c37324672163f09b5e376",
|
||||
"guided-onboarding-guide-state": "d338972ed887ac480c09a1a7fbf582d6a3827c91",
|
||||
"guided-onboarding-plugin-state": "bc109e5ef46ca594fdc179eda15f3095ca0a37a4",
|
||||
|
|
|
@ -11,6 +11,7 @@ export interface UninstallToken {
|
|||
policy_name: string | null;
|
||||
token: string;
|
||||
created_at: string;
|
||||
namespaces?: string[];
|
||||
}
|
||||
|
||||
export type UninstallTokenMetadata = Omit<UninstallToken, 'token'>;
|
||||
|
|
|
@ -89,4 +89,6 @@ export type FetchAllAgentPoliciesOptions = Pick<
|
|||
'perPage' | 'kuery' | 'sortField' | 'sortOrder'
|
||||
> & { fields?: string[] };
|
||||
|
||||
export type FetchAllAgentPolicyIdsOptions = Pick<ListWithKuery, 'perPage' | 'kuery'>;
|
||||
export type FetchAllAgentPolicyIdsOptions = Pick<ListWithKuery, 'perPage' | 'kuery'> & {
|
||||
spaceId?: string;
|
||||
};
|
||||
|
|
|
@ -986,7 +986,7 @@ export const getSavedObjectTypes = (
|
|||
name: MESSAGE_SIGNING_KEYS_SAVED_OBJECT_TYPE,
|
||||
indexPattern: INGEST_SAVED_OBJECT_INDEX,
|
||||
hidden: true,
|
||||
namespaceType: useSpaceAwareness ? 'single' : 'agnostic',
|
||||
namespaceType: 'agnostic',
|
||||
management: {
|
||||
importableAndExportable: false,
|
||||
},
|
||||
|
@ -999,7 +999,7 @@ export const getSavedObjectTypes = (
|
|||
name: UNINSTALL_TOKENS_SAVED_OBJECT_TYPE,
|
||||
indexPattern: INGEST_SAVED_OBJECT_INDEX,
|
||||
hidden: true,
|
||||
namespaceType: useSpaceAwareness ? 'single' : 'agnostic',
|
||||
namespaceType: 'agnostic',
|
||||
management: {
|
||||
importableAndExportable: false,
|
||||
},
|
||||
|
@ -1008,6 +1008,19 @@ export const getSavedObjectTypes = (
|
|||
properties: {
|
||||
policy_id: { type: 'keyword' },
|
||||
token_plain: { type: 'keyword' },
|
||||
namespaces: { type: 'keyword' },
|
||||
},
|
||||
},
|
||||
modelVersions: {
|
||||
'1': {
|
||||
changes: [
|
||||
{
|
||||
type: 'mappings_addition',
|
||||
addedMappings: {
|
||||
namespaces: { type: 'keyword' },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1615,7 +1615,7 @@ class AgentPolicyService {
|
|||
|
||||
public async fetchAllAgentPolicyIds(
|
||||
soClient: SavedObjectsClientContract,
|
||||
{ perPage = 1000, kuery = undefined }: FetchAllAgentPolicyIdsOptions = {}
|
||||
{ perPage = 1000, kuery = undefined, spaceId = undefined }: FetchAllAgentPolicyIdsOptions = {}
|
||||
): Promise<AsyncIterable<string[]>> {
|
||||
const savedObjectType = await getAgentPolicySavedObjectType();
|
||||
return createSoFindIterable<{}>({
|
||||
|
@ -1627,6 +1627,7 @@ class AgentPolicyService {
|
|||
sortOrder: 'asc',
|
||||
fields: ['id'],
|
||||
filter: kuery ? normalizeKuery(savedObjectType, kuery) : undefined,
|
||||
namespaces: spaceId ? [spaceId] : undefined,
|
||||
},
|
||||
resultsMapper: (data) => {
|
||||
return data.saved_objects.map((agentPolicySO) => {
|
||||
|
|
|
@ -9,7 +9,11 @@ import { createHash } from 'crypto';
|
|||
|
||||
import type { KibanaRequest } from '@kbn/core-http-server';
|
||||
|
||||
import type { SavedObjectsClientContract } from '@kbn/core/server';
|
||||
import {
|
||||
SECURITY_EXTENSION_ID,
|
||||
SPACES_EXTENSION_ID,
|
||||
type SavedObjectsClientContract,
|
||||
} from '@kbn/core/server';
|
||||
import type { EncryptedSavedObjectsClient } from '@kbn/encrypted-saved-objects-plugin/server';
|
||||
import { encryptedSavedObjectsMock } from '@kbn/encrypted-saved-objects-plugin/server/mocks';
|
||||
|
||||
|
@ -29,6 +33,7 @@ import { UNINSTALL_TOKENS_SAVED_OBJECT_TYPE } from '../../../constants';
|
|||
import { createAppContextStartContractMock, type MockedFleetAppContext } from '../../../mocks';
|
||||
import { appContextService } from '../../app_context';
|
||||
import { agentPolicyService } from '../../agent_policy';
|
||||
import { isSpaceAwarenessEnabled } from '../../spaces/helpers';
|
||||
|
||||
import { UninstallTokenService, type UninstallTokenServiceInterface } from '.';
|
||||
|
||||
|
@ -42,6 +47,8 @@ interface TokenSO {
|
|||
created_at: string;
|
||||
}
|
||||
|
||||
jest.mock('../../spaces/helpers');
|
||||
|
||||
describe('UninstallTokenService', () => {
|
||||
const now = new Date().toISOString();
|
||||
const aDayAgo = new Date(Date.now() - 24 * 3600 * 1000).toISOString();
|
||||
|
@ -194,7 +201,7 @@ describe('UninstallTokenService', () => {
|
|||
);
|
||||
}
|
||||
|
||||
function setupMocks(canEncrypt: boolean = true) {
|
||||
function setupMocks(canEncrypt: boolean = true, scoppedInSpace?: string) {
|
||||
mockContext = createAppContextStartContractMock();
|
||||
mockContext.encryptedSavedObjectsSetup = encryptedSavedObjectsMock.createSetup({
|
||||
canEncrypt,
|
||||
|
@ -204,13 +211,22 @@ describe('UninstallTokenService', () => {
|
|||
mockContext.encryptedSavedObjectsStart!.getClient() as jest.Mocked<EncryptedSavedObjectsClient>;
|
||||
soClientMock = appContextService
|
||||
.getSavedObjects()
|
||||
.getScopedClient({} as unknown as KibanaRequest) as jest.Mocked<SavedObjectsClientContract>;
|
||||
.getScopedClient({} as unknown as KibanaRequest, {
|
||||
excludedExtensions: [SECURITY_EXTENSION_ID, SPACES_EXTENSION_ID],
|
||||
}) as jest.Mocked<SavedObjectsClientContract>;
|
||||
agentPolicyService.deployPolicies = jest.fn();
|
||||
|
||||
getAgentPoliciesByIDsMock = jest.fn().mockResolvedValue([]);
|
||||
agentPolicyService.getByIDs = getAgentPoliciesByIDsMock;
|
||||
|
||||
uninstallTokenService = new UninstallTokenService(esoClientMock);
|
||||
if (scoppedInSpace) {
|
||||
soClientMock.getCurrentNamespace.mockReturnValue(scoppedInSpace);
|
||||
}
|
||||
|
||||
uninstallTokenService = new UninstallTokenService(
|
||||
esoClientMock,
|
||||
scoppedInSpace ? soClientMock : undefined
|
||||
);
|
||||
mockFind(canEncrypt);
|
||||
mockCreatePointInTimeFinder(canEncrypt);
|
||||
mockCreatePointInTimeFinderAsInternalUser();
|
||||
|
@ -240,6 +256,7 @@ describe('UninstallTokenService', () => {
|
|||
|
||||
beforeEach(() => {
|
||||
setupMocks(canEncrypt);
|
||||
jest.mocked(isSpaceAwarenessEnabled).mockResolvedValue(false);
|
||||
});
|
||||
|
||||
describe('get uninstall tokens', () => {
|
||||
|
@ -277,6 +294,78 @@ describe('UninstallTokenService', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('filter namespace with scopped service and space awareneness enabled', async () => {
|
||||
jest.mocked(isSpaceAwarenessEnabled).mockResolvedValue(true);
|
||||
setupMocks(canEncrypt, 'test');
|
||||
|
||||
const so = getDefaultSO(canEncrypt);
|
||||
mockCreatePointInTimeFinderAsInternalUser([so]);
|
||||
getAgentPoliciesByIDsMock.mockResolvedValue([
|
||||
{ id: so.attributes.policy_id, name: 'cheese' },
|
||||
] as Array<Partial<AgentPolicy>>);
|
||||
|
||||
const token = await uninstallTokenService.getToken(so.id);
|
||||
|
||||
const expectedItem: UninstallToken = {
|
||||
id: so.id,
|
||||
policy_id: so.attributes.policy_id,
|
||||
policy_name: 'cheese',
|
||||
token: getToken(so, canEncrypt),
|
||||
created_at: so.created_at,
|
||||
};
|
||||
|
||||
expect(token).toEqual(expectedItem);
|
||||
|
||||
expect(esoClientMock.createPointInTimeFinderDecryptedAsInternalUser).toHaveBeenCalledWith(
|
||||
{
|
||||
type: UNINSTALL_TOKENS_SAVED_OBJECT_TYPE,
|
||||
filter: `(${UNINSTALL_TOKENS_SAVED_OBJECT_TYPE}.attributes.namespaces:test) and (${UNINSTALL_TOKENS_SAVED_OBJECT_TYPE}.id: "${UNINSTALL_TOKENS_SAVED_OBJECT_TYPE}:${so.id}")`,
|
||||
perPage: SO_SEARCH_LIMIT,
|
||||
}
|
||||
);
|
||||
expect(getAgentPoliciesByIDsMock).toHaveBeenCalledWith(
|
||||
soClientMock,
|
||||
[so.attributes.policy_id],
|
||||
{ ignoreMissing: true }
|
||||
);
|
||||
});
|
||||
|
||||
it('do not filter namespace with scopped service and space awareneness disabled', async () => {
|
||||
jest.mocked(isSpaceAwarenessEnabled).mockResolvedValue(false);
|
||||
setupMocks(canEncrypt, 'test');
|
||||
|
||||
const so = getDefaultSO(canEncrypt);
|
||||
mockCreatePointInTimeFinderAsInternalUser([so]);
|
||||
getAgentPoliciesByIDsMock.mockResolvedValue([
|
||||
{ id: so.attributes.policy_id, name: 'cheese' },
|
||||
] as Array<Partial<AgentPolicy>>);
|
||||
|
||||
const token = await uninstallTokenService.getToken(so.id);
|
||||
|
||||
const expectedItem: UninstallToken = {
|
||||
id: so.id,
|
||||
policy_id: so.attributes.policy_id,
|
||||
policy_name: 'cheese',
|
||||
token: getToken(so, canEncrypt),
|
||||
created_at: so.created_at,
|
||||
};
|
||||
|
||||
expect(token).toEqual(expectedItem);
|
||||
|
||||
expect(esoClientMock.createPointInTimeFinderDecryptedAsInternalUser).toHaveBeenCalledWith(
|
||||
{
|
||||
type: UNINSTALL_TOKENS_SAVED_OBJECT_TYPE,
|
||||
filter: `${UNINSTALL_TOKENS_SAVED_OBJECT_TYPE}.id: "${UNINSTALL_TOKENS_SAVED_OBJECT_TYPE}:${so.id}"`,
|
||||
perPage: SO_SEARCH_LIMIT,
|
||||
}
|
||||
);
|
||||
expect(getAgentPoliciesByIDsMock).toHaveBeenCalledWith(
|
||||
soClientMock,
|
||||
[so.attributes.policy_id],
|
||||
{ ignoreMissing: true }
|
||||
);
|
||||
});
|
||||
|
||||
it('sets `policy_name` to `null` if linked policy does not exist', async () => {
|
||||
const so = getDefaultSO(canEncrypt);
|
||||
mockCreatePointInTimeFinderAsInternalUser([so]);
|
||||
|
@ -341,6 +430,72 @@ describe('UninstallTokenService', () => {
|
|||
expect(actualItems).toEqual(expectedItems);
|
||||
});
|
||||
|
||||
it('filter by namespace if service is scopped and space awareness is enabled', async () => {
|
||||
setupMocks(canEncrypt, 'test');
|
||||
jest.mocked(isSpaceAwarenessEnabled).mockResolvedValue(true);
|
||||
const so = getDefaultSO(canEncrypt);
|
||||
const so2 = getDefaultSO2(canEncrypt);
|
||||
getAgentPoliciesByIDsMock.mockResolvedValue([
|
||||
{ id: so2.attributes.policy_id, name: 'only I have a name' },
|
||||
] as Array<Partial<AgentPolicy>>);
|
||||
|
||||
const actualItems = (await uninstallTokenService.getTokenMetadata()).items;
|
||||
const expectedItems: UninstallTokenMetadata[] = [
|
||||
{
|
||||
id: so.id,
|
||||
policy_id: so.attributes.policy_id,
|
||||
policy_name: null,
|
||||
created_at: so.created_at,
|
||||
},
|
||||
{
|
||||
id: so2.id,
|
||||
policy_id: so2.attributes.policy_id,
|
||||
policy_name: 'only I have a name',
|
||||
created_at: so2.created_at,
|
||||
},
|
||||
];
|
||||
expect(actualItems).toEqual(expectedItems);
|
||||
|
||||
expect(soClientMock.createPointInTimeFinder).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
filter: `${UNINSTALL_TOKENS_SAVED_OBJECT_TYPE}.attributes.namespaces:test`,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('do not filter by namespace if service is scopped and space awareness is disabled', async () => {
|
||||
setupMocks(canEncrypt, 'test');
|
||||
jest.mocked(isSpaceAwarenessEnabled).mockResolvedValue(false);
|
||||
const so = getDefaultSO(canEncrypt);
|
||||
const so2 = getDefaultSO2(canEncrypt);
|
||||
getAgentPoliciesByIDsMock.mockResolvedValue([
|
||||
{ id: so2.attributes.policy_id, name: 'only I have a name' },
|
||||
] as Array<Partial<AgentPolicy>>);
|
||||
|
||||
const actualItems = (await uninstallTokenService.getTokenMetadata()).items;
|
||||
const expectedItems: UninstallTokenMetadata[] = [
|
||||
{
|
||||
id: so.id,
|
||||
policy_id: so.attributes.policy_id,
|
||||
policy_name: null,
|
||||
created_at: so.created_at,
|
||||
},
|
||||
{
|
||||
id: so2.id,
|
||||
policy_id: so2.attributes.policy_id,
|
||||
policy_name: 'only I have a name',
|
||||
created_at: so2.created_at,
|
||||
},
|
||||
];
|
||||
expect(actualItems).toEqual(expectedItems);
|
||||
|
||||
expect(soClientMock.createPointInTimeFinder).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
filter: undefined,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw error if created_at is missing', async () => {
|
||||
const defaultBuckets = getDefaultBuckets(canEncrypt);
|
||||
defaultBuckets[0].latest.hits.hits[0]._source.created_at = '';
|
||||
|
|
|
@ -22,17 +22,16 @@ import type {
|
|||
} from '@elastic/elasticsearch/lib/api/types';
|
||||
import type { EncryptedSavedObjectsClient } from '@kbn/encrypted-saved-objects-plugin/server';
|
||||
import type { KibanaRequest } from '@kbn/core-http-server';
|
||||
import { SECURITY_EXTENSION_ID } from '@kbn/core-saved-objects-server';
|
||||
import { SECURITY_EXTENSION_ID, SPACES_EXTENSION_ID } from '@kbn/core-saved-objects-server';
|
||||
import { asyncForEach, asyncMap } from '@kbn/std';
|
||||
|
||||
import type {
|
||||
AggregationsTermsInclude,
|
||||
AggregationsTermsExclude,
|
||||
} from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
|
||||
import { isResponseError } from '@kbn/es-errors';
|
||||
|
||||
import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common';
|
||||
import { DEFAULT_NAMESPACE_STRING } from '@kbn/core-saved-objects-utils-server';
|
||||
|
||||
import type { AgentPolicySOAttributes } from '../../../types';
|
||||
import { UninstallTokenError } from '../../../../common/errors';
|
||||
|
@ -45,11 +44,13 @@ import type {
|
|||
import { UNINSTALL_TOKENS_SAVED_OBJECT_TYPE, SO_SEARCH_LIMIT } from '../../../constants';
|
||||
import { appContextService } from '../../app_context';
|
||||
import { agentPolicyService, getAgentPolicySavedObjectType } from '../../agent_policy';
|
||||
import { isSpaceAwarenessEnabled } from '../../spaces/helpers';
|
||||
|
||||
interface UninstallTokenSOAttributes {
|
||||
policy_id: string;
|
||||
token: string;
|
||||
token_plain: string;
|
||||
namespaces?: string[];
|
||||
}
|
||||
|
||||
interface UninstallTokenSOAggregationBucket {
|
||||
|
@ -61,6 +62,14 @@ interface UninstallTokenSOAggregation {
|
|||
by_policy_id: AggregationsMultiBucketAggregateBase<UninstallTokenSOAggregationBucket>;
|
||||
}
|
||||
|
||||
function getNamespaceFiltering(namespace: string) {
|
||||
if (namespace === DEFAULT_NAMESPACE_STRING) {
|
||||
return `(${UNINSTALL_TOKENS_SAVED_OBJECT_TYPE}.attributes.namespaces:default) or (not ${UNINSTALL_TOKENS_SAVED_OBJECT_TYPE}.attributes.namespaces:*)`;
|
||||
}
|
||||
|
||||
return `${UNINSTALL_TOKENS_SAVED_OBJECT_TYPE}.attributes.namespaces:${namespace}`;
|
||||
}
|
||||
|
||||
export interface UninstallTokenInvalidError {
|
||||
error: UninstallTokenError;
|
||||
}
|
||||
|
@ -189,11 +198,15 @@ export class UninstallTokenService implements UninstallTokenServiceInterface {
|
|||
}
|
||||
|
||||
public async getToken(id: string): Promise<UninstallToken | null> {
|
||||
const namespacePrefix = this.soClient.getCurrentNamespace()
|
||||
? `${this.soClient.getCurrentNamespace()}:`
|
||||
: '';
|
||||
const filter = `${UNINSTALL_TOKENS_SAVED_OBJECT_TYPE}.id: "${namespacePrefix}${UNINSTALL_TOKENS_SAVED_OBJECT_TYPE}:${id}"`;
|
||||
const tokenObjects = await this.getDecryptedTokenObjects({ filter });
|
||||
const useSpaceAwareness = this.isScoped && (await isSpaceAwarenessEnabled());
|
||||
const namespaceFilter = useSpaceAwareness
|
||||
? getNamespaceFiltering(this.soClient.getCurrentNamespace() ?? DEFAULT_SPACE_ID)
|
||||
: undefined;
|
||||
|
||||
const filter = `${UNINSTALL_TOKENS_SAVED_OBJECT_TYPE}.id: "${UNINSTALL_TOKENS_SAVED_OBJECT_TYPE}:${id}"`;
|
||||
const tokenObjects = await this.getDecryptedTokenObjects({
|
||||
filter: namespaceFilter ? `(${namespaceFilter}) and (${filter})` : filter,
|
||||
});
|
||||
return tokenObjects.length === 1
|
||||
? this.convertTokenObjectToToken(
|
||||
await this.getPolicyIdNameDictionary([tokenObjects[0].attributes.policy_id]),
|
||||
|
@ -278,14 +291,12 @@ export class UninstallTokenService implements UninstallTokenServiceInterface {
|
|||
this.assertCreatedAt(_source.created_at);
|
||||
const policyId = _source[UNINSTALL_TOKENS_SAVED_OBJECT_TYPE].policy_id;
|
||||
|
||||
const namespacePrefix = this.soClient.getCurrentNamespace()
|
||||
? `${this.soClient.getCurrentNamespace()}:`
|
||||
: '';
|
||||
return {
|
||||
id: _id!.replace(`${namespacePrefix}${UNINSTALL_TOKENS_SAVED_OBJECT_TYPE}:`, ''),
|
||||
id: _id!.replace(`${UNINSTALL_TOKENS_SAVED_OBJECT_TYPE}:`, ''),
|
||||
policy_id: policyId,
|
||||
policy_name: policyIdNameDictionary[policyId] ?? null,
|
||||
created_at: _source.created_at,
|
||||
namespaces: _source.namespaces,
|
||||
};
|
||||
}
|
||||
);
|
||||
|
@ -375,9 +386,6 @@ export class UninstallTokenService implements UninstallTokenServiceInterface {
|
|||
{
|
||||
type: UNINSTALL_TOKENS_SAVED_OBJECT_TYPE,
|
||||
perPage: SO_SEARCH_LIMIT,
|
||||
namespaces: this.isScoped
|
||||
? [this.soClient.getCurrentNamespace() || DEFAULT_SPACE_ID]
|
||||
: undefined,
|
||||
...options,
|
||||
}
|
||||
);
|
||||
|
@ -415,6 +423,7 @@ export class UninstallTokenService implements UninstallTokenServiceInterface {
|
|||
policy_name: policyIdNameDictionary[attributes.policy_id] ?? null,
|
||||
token: attributes.token || attributes.token_plain,
|
||||
created_at: createdAt,
|
||||
namespaces: attributes.namespaces,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -423,9 +432,18 @@ export class UninstallTokenService implements UninstallTokenServiceInterface {
|
|||
exclude?: AggregationsTermsExclude
|
||||
): Promise<Array<SearchHit<any>>> {
|
||||
const bucketSize = 10000;
|
||||
|
||||
const useSpaceAwareness = await isSpaceAwarenessEnabled();
|
||||
|
||||
const filter =
|
||||
this.isScoped && useSpaceAwareness
|
||||
? getNamespaceFiltering(this.soClient.getCurrentNamespace() || DEFAULT_NAMESPACE_STRING)
|
||||
: undefined;
|
||||
|
||||
const query: SavedObjectsCreatePointInTimeFinderOptions = {
|
||||
type: UNINSTALL_TOKENS_SAVED_OBJECT_TYPE,
|
||||
perPage: 0,
|
||||
filter,
|
||||
aggs: {
|
||||
by_policy_id: {
|
||||
terms: {
|
||||
|
@ -574,7 +592,9 @@ export class UninstallTokenService implements UninstallTokenServiceInterface {
|
|||
}
|
||||
|
||||
private async getAllPolicyIds(): Promise<string[]> {
|
||||
const agentPolicyIdsFetcher = await agentPolicyService.fetchAllAgentPolicyIds(this.soClient);
|
||||
const agentPolicyIdsFetcher = await agentPolicyService.fetchAllAgentPolicyIds(this.soClient, {
|
||||
spaceId: '*',
|
||||
});
|
||||
const policyIds: string[] = [];
|
||||
for await (const agentPolicyId of agentPolicyIdsFetcher) {
|
||||
policyIds.push(...agentPolicyId);
|
||||
|
@ -595,20 +615,27 @@ export class UninstallTokenService implements UninstallTokenServiceInterface {
|
|||
const batchSize = config?.setup?.agentPolicySchemaUpgradeBatchSize ?? 100;
|
||||
|
||||
await asyncForEach(chunk(policyIds, batchSize), async (policyIdsBatch) => {
|
||||
const policies = await agentPolicyService.getByIDs(
|
||||
appContextService.getInternalUserSOClientWithoutSpaceExtension(),
|
||||
policyIds.map((id) => ({ id, spaceId: '*' }))
|
||||
);
|
||||
const policiesSpacesIndexedById = policies.reduce((acc, p) => {
|
||||
acc[p.id] = p.space_ids;
|
||||
return acc;
|
||||
}, {} as { [k: string]: string[] | undefined });
|
||||
await this.soClient.bulkCreate<Partial<UninstallTokenSOAttributes>>(
|
||||
policyIdsBatch.map((policyId) => ({
|
||||
type: UNINSTALL_TOKENS_SAVED_OBJECT_TYPE,
|
||||
initialNamespaces: this.soClient.getCurrentNamespace()
|
||||
? [this.soClient.getCurrentNamespace() as string]
|
||||
: undefined,
|
||||
attributes: this.isEncryptionAvailable
|
||||
? {
|
||||
policy_id: policyId,
|
||||
token: tokensMap[policyId],
|
||||
namespaces: policiesSpacesIndexedById[policyId],
|
||||
}
|
||||
: {
|
||||
policy_id: policyId,
|
||||
token_plain: tokensMap[policyId],
|
||||
namespaces: policiesSpacesIndexedById[policyId],
|
||||
},
|
||||
}))
|
||||
);
|
||||
|
@ -643,7 +670,7 @@ export class UninstallTokenService implements UninstallTokenServiceInterface {
|
|||
} as unknown as KibanaRequest;
|
||||
|
||||
this._soClient = appContextService.getSavedObjects().getScopedClient(fakeRequest, {
|
||||
excludedExtensions: [SECURITY_EXTENSION_ID],
|
||||
excludedExtensions: [SECURITY_EXTENSION_ID, SPACES_EXTENSION_ID],
|
||||
includedHiddenTypes: [UNINSTALL_TOKENS_SAVED_OBJECT_TYPE],
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue