Skip to content

Commit

Permalink
[Security Solution + Fleet] Add FleetFilesClient to fleet and refac…
Browse files Browse the repository at this point in the history
…tor endpoint actions to use it (#157658)

## Summary

PR introduces a new Files service client to the Fleet server-side code
that will enable integration to work with Files received/sent to Hosts
without having to access `.fleet-*` indexes directly.

### Fleet changes

- Adds `FleetFilesClient` to Fleet's server-side code. Supports both
files that are received from the host as well as files that can be sent
to the host.
- exposes new `createFilesClient()` method from `FleetStartContract`
that enables fleet dependents to get a files client.


### Security Solution changes

- Refactors API routes to use new `FleetFilesClient`
- Deletes all file related services from server code
  • Loading branch information
paul-tavares authored May 22, 2023
1 parent 39dad65 commit 344adf2
Show file tree
Hide file tree
Showing 24 changed files with 1,124 additions and 724 deletions.
14 changes: 10 additions & 4 deletions src/plugins/files/server/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { KibanaRequest } from '@kbn/core/server';
import { DeeplyMockedKeys } from '@kbn/utility-types-jest';
import * as stream from 'stream';
import { clone } from 'lodash';
import { File } from '../common';
import { File, FileJSON } from '../common';
import { FileClient, FileServiceFactory, FileServiceStart, FilesSetup } from '.';

export const createFileServiceMock = (): DeeplyMockedKeys<FileServiceStart> => ({
Expand All @@ -34,7 +34,9 @@ export const createFileServiceFactoryMock = (): DeeplyMockedKeys<FileServiceFact
asScoped: jest.fn((_: KibanaRequest) => createFileServiceMock()),
});

export const createFileMock = (): DeeplyMockedKeys<File> => {
export const createFileMock = <Meta = unknown>(
fileDataOverride: Partial<FileJSON<Meta>> = {}
): DeeplyMockedKeys<File> => {
const fileMock: DeeplyMockedKeys<File> = {
id: '123',
data: {
Expand All @@ -49,6 +51,8 @@ export const createFileMock = (): DeeplyMockedKeys<File> => {
alt: undefined,
fileKind: 'none',
status: 'READY',

...fileDataOverride,
},
update: jest.fn(),
uploadContent: jest.fn(),
Expand All @@ -68,8 +72,10 @@ export const createFileMock = (): DeeplyMockedKeys<File> => {
return fileMock;
};

export const createFileClientMock = (): DeeplyMockedKeys<FileClient> => {
const fileMock = createFileMock();
export const createFileClientMock = <Meta = unknown>(
fileDataOverride: Partial<FileJSON<Meta>> = {}
): DeeplyMockedKeys<FileClient> => {
const fileMock = createFileMock(fileDataOverride);

return {
fileKind: 'none',
Expand Down
3 changes: 3 additions & 0 deletions x-pack/plugins/fleet/server/errors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,6 @@ export class ArtifactsElasticsearchError extends FleetError {
}
}
}

export class FleetFilesClientError extends FleetError {}
export class FleetFileNotFound extends FleetFilesClientError {}
8 changes: 8 additions & 0 deletions x-pack/plugins/fleet/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ export type { PackagePolicyClient } from './services/package_policy_service';

export { relativeDownloadUrlFromArtifact } from './services/artifacts/mappings';

export type {
FleetFileTransferDirection,
FleetFileClientInterface,
FleetFile,
HapiReadableStream,
FleetFileUpdatableFields,
} from './services/files/types';

export const plugin = (initializerContext: PluginInitializerContext) => {
return new FleetPlugin(initializerContext);
};
3 changes: 3 additions & 0 deletions x-pack/plugins/fleet/server/mocks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ import { packageServiceMock } from '../services/epm/package_service.mock';
// Export all mocks from artifacts
export * from '../services/artifacts/mocks';

// export all mocks from fleet files client
export * from '../services/files/mocks';

export interface MockedFleetAppContext extends FleetAppContext {
elasticsearch: ReturnType<typeof elasticsearchServiceMock.createStart>;
data: ReturnType<typeof dataPluginMock.createStartContract>;
Expand Down
28 changes: 28 additions & 0 deletions x-pack/plugins/fleet/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ import {
} from '../common';
import { parseExperimentalConfigValue } from '../common/experimental_features';

import { FleetFilesClient } from './services/files/client';

import type { FleetFileClientInterface, FleetFileTransferDirection } from './services/files/types';

import type { MessageSigningServiceInterface } from './services/security';
import {
getRouteRequiredAuthz,
Expand Down Expand Up @@ -217,6 +221,21 @@ export interface FleetStartContract {
*/
createArtifactsClient: (packageName: string) => FleetArtifactsClient;

/**
* Create a Fleet Files client instance
* @param packageName
* @param type
* @param maxSizeBytes
*/
createFilesClient: (
/** The integration package name */
packageName: string,
/** Type of file */
type: FleetFileTransferDirection,
/** Max size for files created when `type` is `to-host` */
maxSizeBytes?: number
) => FleetFileClientInterface;

messageSigningService: MessageSigningServiceInterface;
uninstallTokenService: UninstallTokenServiceInterface;
}
Expand Down Expand Up @@ -567,6 +586,15 @@ export class FleetPlugin
createArtifactsClient(packageName: string) {
return new FleetArtifactsClient(core.elasticsearch.client.asInternalUser, packageName);
},
createFilesClient: (packageName, type, maxFileBytes) => {
return new FleetFilesClient(
core.elasticsearch.client.asInternalUser,
this.initializerContext.logger.get('fleetFiles', packageName),
packageName,
type,
maxFileBytes
);
},
messageSigningService,
uninstallTokenService,
};
Expand Down
Loading

0 comments on commit 344adf2

Please sign in to comment.