mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Fleet] use @kbn/config-schema in Fleet API (Part 1) (#192883)
## Summary Relates https://github.com/elastic/kibana/issues/184685 Readd https://github.com/elastic/kibana/pull/192447 with fixes and tests to validate that the response schemas are correct. ### 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
This commit is contained in:
parent
6a79e2d0be
commit
406f07386c
25 changed files with 1603 additions and 241 deletions
|
@ -71,7 +71,7 @@ export interface FullAgentPolicyInputStream {
|
|||
id: string;
|
||||
data_stream: {
|
||||
dataset: string;
|
||||
type: string;
|
||||
type?: string;
|
||||
};
|
||||
[key: string]: any;
|
||||
}
|
||||
|
|
|
@ -90,6 +90,7 @@ export interface NewPackagePolicy {
|
|||
privileges?: {
|
||||
cluster?: string[];
|
||||
};
|
||||
[key: string]: any;
|
||||
};
|
||||
overrides?: { inputs?: { [key: string]: any } } | null;
|
||||
}
|
||||
|
|
|
@ -9,9 +9,20 @@ import { httpServerMock, httpServiceMock } from '@kbn/core/server/mocks';
|
|||
import type { KibanaRequest } from '@kbn/core/server';
|
||||
import type { RouteConfig } from '@kbn/core/server';
|
||||
|
||||
import type {
|
||||
ListResult,
|
||||
PostDeletePackagePoliciesResponse,
|
||||
UpgradePackagePolicyResponse,
|
||||
} from '../../../common';
|
||||
|
||||
import type { FleetAuthzRouter } from '../../services/security';
|
||||
|
||||
import { PACKAGE_POLICY_API_ROUTES } from '../../../common/constants';
|
||||
import type {
|
||||
DryRunPackagePolicy,
|
||||
UpgradePackagePolicyDryRunResponse,
|
||||
UpgradePackagePolicyDryRunResponseItem,
|
||||
} from '../../../common/types';
|
||||
import {
|
||||
agentPolicyService,
|
||||
appContextService,
|
||||
|
@ -21,10 +32,33 @@ import {
|
|||
import { createAppContextStartContractMock, xpackMocks } from '../../mocks';
|
||||
import type { PackagePolicyClient, FleetRequestHandlerContext } from '../..';
|
||||
import type { UpdatePackagePolicyRequestSchema } from '../../types/rest_spec';
|
||||
import type { AgentPolicy, FleetRequestHandler } from '../../types';
|
||||
import {
|
||||
PackagePolicyResponseSchema,
|
||||
type AgentPolicy,
|
||||
type FleetRequestHandler,
|
||||
BulkGetPackagePoliciesResponseBodySchema,
|
||||
DeletePackagePoliciesResponseBodySchema,
|
||||
DeleteOnePackagePolicyResponseSchema,
|
||||
UpgradePackagePoliciesResponseBodySchema,
|
||||
DryRunPackagePoliciesResponseBodySchema,
|
||||
OrphanedPackagePoliciesResponseSchema,
|
||||
CreatePackagePolicyResponseSchema,
|
||||
} from '../../types';
|
||||
import type { PackagePolicy } from '../../types';
|
||||
|
||||
import { getPackagePoliciesHandler } from './handlers';
|
||||
import { ListResponseSchema } from '../schema/utils';
|
||||
|
||||
import {
|
||||
bulkGetPackagePoliciesHandler,
|
||||
createPackagePolicyHandler,
|
||||
deleteOnePackagePolicyHandler,
|
||||
deletePackagePolicyHandler,
|
||||
dryRunUpgradePackagePolicyHandler,
|
||||
getOnePackagePolicyHandler,
|
||||
getOrphanedPackagePolicies,
|
||||
getPackagePoliciesHandler,
|
||||
upgradePackagePolicyHandler,
|
||||
} from './handlers';
|
||||
import { registerRoutes } from '.';
|
||||
|
||||
const packagePolicyServiceMock = packagePolicyService as jest.Mocked<PackagePolicyClient>;
|
||||
|
@ -79,35 +113,7 @@ jest.mock(
|
|||
delete: jest.fn(),
|
||||
get: jest.fn(),
|
||||
getByIDs: jest.fn(),
|
||||
list: jest.fn(async (_, __) => {
|
||||
return {
|
||||
total: 1,
|
||||
perPage: 10,
|
||||
page: 1,
|
||||
items: [
|
||||
{
|
||||
id: `123`,
|
||||
name: `Package Policy 123`,
|
||||
description: '',
|
||||
created_at: '2022-12-19T20:43:45.879Z',
|
||||
created_by: 'elastic',
|
||||
updated_at: '2022-12-19T20:43:45.879Z',
|
||||
updated_by: 'elastic',
|
||||
policy_id: `agent-policy-id-a`,
|
||||
policy_ids: [`agent-policy-id-a`],
|
||||
enabled: true,
|
||||
inputs: [],
|
||||
namespace: 'default',
|
||||
package: {
|
||||
name: 'a-package',
|
||||
title: 'package A',
|
||||
version: '1.0.0',
|
||||
},
|
||||
revision: 1,
|
||||
},
|
||||
],
|
||||
};
|
||||
}),
|
||||
list: jest.fn(),
|
||||
listIds: jest.fn(),
|
||||
update: jest.fn(),
|
||||
// @ts-ignore
|
||||
|
@ -131,6 +137,7 @@ jest.mock('../../services/agent_policy', () => {
|
|||
agentPolicyService: {
|
||||
get: jest.fn(),
|
||||
update: jest.fn(),
|
||||
list: jest.fn(),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
@ -140,9 +147,18 @@ jest.mock('../../services/epm/packages', () => {
|
|||
ensureInstalledPackage: jest.fn(() => Promise.resolve()),
|
||||
getPackageInfo: jest.fn(() => Promise.resolve()),
|
||||
getInstallation: jest.fn(),
|
||||
getInstallations: jest.fn().mockResolvedValue({
|
||||
saved_objects: [
|
||||
{
|
||||
attributes: { name: 'a-package', version: '1.0.0' },
|
||||
},
|
||||
],
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
let testPackagePolicy: PackagePolicy;
|
||||
|
||||
describe('When calling package policy', () => {
|
||||
let routerMock: jest.Mocked<FleetAuthzRouter>;
|
||||
let routeHandler: FleetRequestHandler<any, any, any>;
|
||||
|
@ -160,6 +176,65 @@ describe('When calling package policy', () => {
|
|||
context = xpackMocks.createRequestHandlerContext() as unknown as FleetRequestHandlerContext;
|
||||
(await context.fleet).packagePolicyService.asCurrentUser as jest.Mocked<PackagePolicyClient>;
|
||||
response = httpServerMock.createResponseFactory();
|
||||
testPackagePolicy = {
|
||||
agents: 100,
|
||||
created_at: '2022-12-19T20:43:45.879Z',
|
||||
created_by: 'elastic',
|
||||
description: '',
|
||||
enabled: true,
|
||||
id: '123',
|
||||
inputs: [
|
||||
{
|
||||
streams: [
|
||||
{
|
||||
id: '1',
|
||||
compiled_stream: {},
|
||||
enabled: true,
|
||||
keep_enabled: false,
|
||||
release: 'beta',
|
||||
vars: { var: { type: 'text', value: 'value', frozen: false } },
|
||||
config: { config: { type: 'text', value: 'value', frozen: false } },
|
||||
data_stream: { dataset: 'apache.access', type: 'logs', elasticsearch: {} },
|
||||
},
|
||||
],
|
||||
compiled_input: '',
|
||||
id: '1',
|
||||
enabled: true,
|
||||
type: 'logs',
|
||||
policy_template: '',
|
||||
keep_enabled: false,
|
||||
vars: { var: { type: 'text', value: 'value', frozen: false } },
|
||||
config: { config: { type: 'text', value: 'value', frozen: false } },
|
||||
},
|
||||
],
|
||||
vars: { var: { type: 'text', value: 'value', frozen: false } },
|
||||
name: 'Package Policy 123',
|
||||
namespace: 'default',
|
||||
package: {
|
||||
name: 'a-package',
|
||||
title: 'package A',
|
||||
version: '1.0.0',
|
||||
experimental_data_stream_features: [{ data_stream: 'logs', features: { tsdb: true } }],
|
||||
requires_root: false,
|
||||
},
|
||||
policy_id: 'agent-policy-id-a',
|
||||
policy_ids: ['agent-policy-id-a'],
|
||||
revision: 1,
|
||||
updated_at: '2022-12-19T20:43:45.879Z',
|
||||
updated_by: 'elastic',
|
||||
version: '1.0.0',
|
||||
secret_references: [
|
||||
{
|
||||
id: 'ref1',
|
||||
},
|
||||
],
|
||||
spaceIds: ['space1'],
|
||||
elasticsearch: {
|
||||
'index_template.mappings': {
|
||||
dynamic_templates: [],
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -187,7 +262,14 @@ describe('When calling package policy', () => {
|
|||
});
|
||||
};
|
||||
|
||||
const existingPolicy = {
|
||||
const existingPolicy: PackagePolicy = {
|
||||
id: '1',
|
||||
revision: 1,
|
||||
created_at: '',
|
||||
created_by: '',
|
||||
updated_at: '',
|
||||
updated_by: '',
|
||||
policy_ids: ['2'],
|
||||
name: 'endpoint-1',
|
||||
description: 'desc',
|
||||
policy_id: '2',
|
||||
|
@ -231,17 +313,10 @@ describe('When calling package policy', () => {
|
|||
beforeEach(() => {
|
||||
jest.spyOn(licenseService, 'hasAtLeast').mockClear();
|
||||
packagePolicyServiceMock.update.mockImplementation((soClient, esClient, policyId, newData) =>
|
||||
Promise.resolve(newData as PackagePolicy)
|
||||
Promise.resolve({ ...existingPolicy, ...newData } as PackagePolicy)
|
||||
);
|
||||
packagePolicyServiceMock.get.mockResolvedValue({
|
||||
id: '1',
|
||||
revision: 1,
|
||||
created_at: '',
|
||||
created_by: '',
|
||||
updated_at: '',
|
||||
updated_by: '',
|
||||
...existingPolicy,
|
||||
policy_ids: [existingPolicy.policy_id],
|
||||
inputs: [
|
||||
{
|
||||
...existingPolicy.inputs[0],
|
||||
|
@ -264,6 +339,8 @@ describe('When calling package policy', () => {
|
|||
expect(response.ok).toHaveBeenCalledWith({
|
||||
body: { item: existingPolicy },
|
||||
});
|
||||
const validationResp = PackagePolicyResponseSchema.validate(existingPolicy);
|
||||
expect(validationResp).toEqual(existingPolicy);
|
||||
});
|
||||
|
||||
it('should use request package policy props if provided by request', async () => {
|
||||
|
@ -300,9 +377,13 @@ describe('When calling package policy', () => {
|
|||
};
|
||||
const request = getUpdateKibanaRequest(newData as any);
|
||||
await routeHandler(context, request, response);
|
||||
const responseItem = { ...existingPolicy, ...newData };
|
||||
expect(response.ok).toHaveBeenCalledWith({
|
||||
body: { item: newData },
|
||||
body: { item: responseItem },
|
||||
});
|
||||
|
||||
const validationResp = PackagePolicyResponseSchema.validate(responseItem);
|
||||
expect(validationResp).toEqual(responseItem);
|
||||
});
|
||||
|
||||
it('should override props provided by request only', async () => {
|
||||
|
@ -435,43 +516,43 @@ describe('When calling package policy', () => {
|
|||
inputs,
|
||||
} as any);
|
||||
await routeHandler(context, request, response);
|
||||
expect(response.ok).toHaveBeenCalledWith({
|
||||
body: {
|
||||
item: {
|
||||
description: 'desc',
|
||||
enabled: true,
|
||||
inputs: [
|
||||
const responseItem = {
|
||||
...existingPolicy,
|
||||
inputs: [
|
||||
{
|
||||
type: 'input-logs',
|
||||
enabled: false,
|
||||
streams: [
|
||||
{
|
||||
type: 'input-logs',
|
||||
enabled: false,
|
||||
streams: [
|
||||
{
|
||||
enabled: false,
|
||||
data_stream: {
|
||||
type: 'logs',
|
||||
dataset: 'test.some_logs',
|
||||
},
|
||||
},
|
||||
],
|
||||
data_stream: {
|
||||
type: 'logs',
|
||||
dataset: 'test.some_logs',
|
||||
},
|
||||
},
|
||||
],
|
||||
name: 'endpoint-1',
|
||||
namespace: 'default',
|
||||
package: {
|
||||
name: 'endpoint',
|
||||
title: 'Elastic Endpoint',
|
||||
version: '0.5.0',
|
||||
},
|
||||
vars: expect.any(Object),
|
||||
policy_id: '2',
|
||||
},
|
||||
],
|
||||
};
|
||||
expect(response.ok).toHaveBeenCalledWith({
|
||||
body: {
|
||||
item: responseItem,
|
||||
},
|
||||
});
|
||||
|
||||
const validationResp = PackagePolicyResponseSchema.validate(responseItem);
|
||||
expect(validationResp).toEqual(responseItem);
|
||||
});
|
||||
});
|
||||
|
||||
describe('list api handler', () => {
|
||||
it('should return agent count when `withAgentCount` query param is used', async () => {
|
||||
packagePolicyServiceMock.list.mockResolvedValue({
|
||||
total: 1,
|
||||
perPage: 10,
|
||||
page: 1,
|
||||
items: [testPackagePolicy],
|
||||
});
|
||||
const request = httpServerMock.createKibanaRequest({
|
||||
query: {
|
||||
withAgentCount: true,
|
||||
|
@ -510,37 +591,334 @@ describe('When calling package policy', () => {
|
|||
});
|
||||
|
||||
await getPackagePoliciesHandler(context, request, response);
|
||||
|
||||
const responseBody: ListResult<PackagePolicy> = {
|
||||
page: 1,
|
||||
perPage: 10,
|
||||
total: 1,
|
||||
items: [testPackagePolicy],
|
||||
};
|
||||
expect(response.ok).toHaveBeenCalledWith({
|
||||
body: {
|
||||
page: 1,
|
||||
perPage: 10,
|
||||
total: 1,
|
||||
items: [
|
||||
{
|
||||
agents: 100,
|
||||
created_at: '2022-12-19T20:43:45.879Z',
|
||||
created_by: 'elastic',
|
||||
description: '',
|
||||
enabled: true,
|
||||
id: '123',
|
||||
inputs: [],
|
||||
name: 'Package Policy 123',
|
||||
namespace: 'default',
|
||||
package: {
|
||||
name: 'a-package',
|
||||
title: 'package A',
|
||||
version: '1.0.0',
|
||||
},
|
||||
policy_id: 'agent-policy-id-a',
|
||||
policy_ids: ['agent-policy-id-a'],
|
||||
revision: 1,
|
||||
updated_at: '2022-12-19T20:43:45.879Z',
|
||||
updated_by: 'elastic',
|
||||
},
|
||||
],
|
||||
body: responseBody,
|
||||
});
|
||||
|
||||
const validationResp = ListResponseSchema(PackagePolicyResponseSchema).validate(responseBody);
|
||||
expect(validationResp).toEqual(responseBody);
|
||||
});
|
||||
});
|
||||
|
||||
describe('bulk api handler', () => {
|
||||
it('should return valid response', async () => {
|
||||
const items: PackagePolicy[] = [testPackagePolicy];
|
||||
packagePolicyServiceMock.getByIDs.mockResolvedValue(items);
|
||||
const request = httpServerMock.createKibanaRequest({
|
||||
query: {},
|
||||
body: { ids: ['1'] },
|
||||
});
|
||||
await bulkGetPackagePoliciesHandler(context, request, response);
|
||||
expect(response.ok).toHaveBeenCalledWith({
|
||||
body: { items },
|
||||
});
|
||||
const validationResp = BulkGetPackagePoliciesResponseBodySchema.validate({ items });
|
||||
expect(validationResp).toEqual({ items });
|
||||
});
|
||||
});
|
||||
|
||||
describe('orphaned package policies api handler', () => {
|
||||
it('should return valid response', async () => {
|
||||
const items: PackagePolicy[] = [testPackagePolicy];
|
||||
const expectedResponse = {
|
||||
items,
|
||||
total: 1,
|
||||
};
|
||||
packagePolicyServiceMock.list.mockResolvedValue({
|
||||
items: [testPackagePolicy],
|
||||
total: 1,
|
||||
page: 1,
|
||||
perPage: 20,
|
||||
});
|
||||
mockedAgentPolicyService.list.mockResolvedValue({
|
||||
items: [],
|
||||
total: 0,
|
||||
page: 1,
|
||||
perPage: 20,
|
||||
});
|
||||
await getOrphanedPackagePolicies(context, {} as any, response);
|
||||
expect(response.ok).toHaveBeenCalledWith({
|
||||
body: expectedResponse,
|
||||
});
|
||||
const validationResp = OrphanedPackagePoliciesResponseSchema.validate(expectedResponse);
|
||||
expect(validationResp).toEqual(expectedResponse);
|
||||
});
|
||||
});
|
||||
|
||||
describe('get api handler', () => {
|
||||
it('should return valid response', async () => {
|
||||
packagePolicyServiceMock.get.mockResolvedValue(testPackagePolicy);
|
||||
const request = httpServerMock.createKibanaRequest({
|
||||
params: {
|
||||
packagePolicyId: '1',
|
||||
},
|
||||
});
|
||||
await getOnePackagePolicyHandler(context, request, response);
|
||||
expect(response.ok).toHaveBeenCalledWith({
|
||||
body: { item: testPackagePolicy },
|
||||
});
|
||||
const validationResp = PackagePolicyResponseSchema.validate(testPackagePolicy);
|
||||
expect(validationResp).toEqual(testPackagePolicy);
|
||||
});
|
||||
|
||||
it('should return valid response simplified format', async () => {
|
||||
packagePolicyServiceMock.get.mockResolvedValue(testPackagePolicy);
|
||||
const request = httpServerMock.createKibanaRequest({
|
||||
params: {
|
||||
packagePolicyId: '1',
|
||||
},
|
||||
query: {
|
||||
format: 'simplified',
|
||||
},
|
||||
});
|
||||
await getOnePackagePolicyHandler(context, request, response);
|
||||
const simplifiedPackagePolicy = {
|
||||
...testPackagePolicy,
|
||||
inputs: {
|
||||
logs: {
|
||||
enabled: true,
|
||||
streams: {
|
||||
'apache.access': {
|
||||
enabled: true,
|
||||
vars: {
|
||||
var: 'value',
|
||||
},
|
||||
},
|
||||
},
|
||||
vars: {
|
||||
var: 'value',
|
||||
},
|
||||
},
|
||||
},
|
||||
vars: {
|
||||
var: 'value',
|
||||
},
|
||||
};
|
||||
expect(response.ok).toHaveBeenCalledWith({
|
||||
body: { item: simplifiedPackagePolicy },
|
||||
});
|
||||
const validationResp = PackagePolicyResponseSchema.validate(simplifiedPackagePolicy);
|
||||
expect(validationResp).toEqual(simplifiedPackagePolicy);
|
||||
});
|
||||
});
|
||||
|
||||
describe('create api handler', () => {
|
||||
it('should return valid response', async () => {
|
||||
packagePolicyServiceMock.get.mockResolvedValue(testPackagePolicy);
|
||||
(
|
||||
(await context.fleet).packagePolicyService.asCurrentUser as jest.Mocked<PackagePolicyClient>
|
||||
).create.mockResolvedValue(testPackagePolicy);
|
||||
const request = httpServerMock.createKibanaRequest({
|
||||
body: testPackagePolicy,
|
||||
});
|
||||
const expectedResponse = { item: testPackagePolicy };
|
||||
await createPackagePolicyHandler(context, request, response);
|
||||
expect(response.ok).toHaveBeenCalledWith({
|
||||
body: expectedResponse,
|
||||
});
|
||||
const validationResp = CreatePackagePolicyResponseSchema.validate(expectedResponse);
|
||||
expect(validationResp).toEqual(expectedResponse);
|
||||
});
|
||||
});
|
||||
|
||||
describe('bulk delete api handler', () => {
|
||||
it('should return valid response', async () => {
|
||||
const responseBody: PostDeletePackagePoliciesResponse = [
|
||||
{
|
||||
id: '1',
|
||||
name: 'policy',
|
||||
success: true,
|
||||
policy_ids: ['1'],
|
||||
output_id: '1',
|
||||
package: {
|
||||
name: 'package',
|
||||
version: '1.0.0',
|
||||
title: 'Package',
|
||||
},
|
||||
statusCode: 409,
|
||||
body: {
|
||||
message: 'conflict',
|
||||
},
|
||||
},
|
||||
];
|
||||
packagePolicyServiceMock.delete.mockResolvedValue(responseBody);
|
||||
const request = httpServerMock.createKibanaRequest({
|
||||
body: {
|
||||
packagePolicyIds: ['1'],
|
||||
},
|
||||
});
|
||||
await deletePackagePolicyHandler(context, request, response);
|
||||
expect(response.ok).toHaveBeenCalledWith({
|
||||
body: responseBody,
|
||||
});
|
||||
const validationResp = DeletePackagePoliciesResponseBodySchema.validate(responseBody);
|
||||
expect(validationResp).toEqual(responseBody);
|
||||
});
|
||||
});
|
||||
|
||||
describe('delete api handler', () => {
|
||||
it('should return valid response', async () => {
|
||||
const responseBody = {
|
||||
id: '1',
|
||||
};
|
||||
packagePolicyServiceMock.delete.mockResolvedValue([
|
||||
{
|
||||
id: '1',
|
||||
name: 'policy',
|
||||
success: true,
|
||||
policy_ids: ['1'],
|
||||
output_id: '1',
|
||||
package: {
|
||||
name: 'package',
|
||||
version: '1.0.0',
|
||||
title: 'Package',
|
||||
},
|
||||
statusCode: 409,
|
||||
body: {
|
||||
message: 'conflict',
|
||||
},
|
||||
},
|
||||
]);
|
||||
const request = httpServerMock.createKibanaRequest({
|
||||
body: {
|
||||
force: false,
|
||||
},
|
||||
params: {
|
||||
packagePolicyId: '1',
|
||||
},
|
||||
});
|
||||
await deleteOnePackagePolicyHandler(context, request, response);
|
||||
expect(response.ok).toHaveBeenCalledWith({
|
||||
body: responseBody,
|
||||
});
|
||||
const validationResp = DeleteOnePackagePolicyResponseSchema.validate(responseBody);
|
||||
expect(validationResp).toEqual(responseBody);
|
||||
});
|
||||
});
|
||||
|
||||
describe('upgrade api handler', () => {
|
||||
it('should return valid response', async () => {
|
||||
const responseBody: UpgradePackagePolicyResponse = [
|
||||
{
|
||||
id: '1',
|
||||
name: 'policy',
|
||||
success: true,
|
||||
statusCode: 200,
|
||||
body: {
|
||||
message: 'success',
|
||||
},
|
||||
},
|
||||
];
|
||||
packagePolicyServiceMock.upgrade.mockResolvedValue(responseBody);
|
||||
const request = httpServerMock.createKibanaRequest({
|
||||
body: {
|
||||
packagePolicyIds: ['1'],
|
||||
},
|
||||
});
|
||||
await upgradePackagePolicyHandler(context, request, response);
|
||||
expect(response.ok).toHaveBeenCalledWith({
|
||||
body: responseBody,
|
||||
});
|
||||
const validationResp = UpgradePackagePoliciesResponseBodySchema.validate(responseBody);
|
||||
expect(validationResp).toEqual(responseBody);
|
||||
});
|
||||
});
|
||||
|
||||
describe('dry run upgrade api handler', () => {
|
||||
it('should return valid response', async () => {
|
||||
const dryRunPackagePolicy: DryRunPackagePolicy = {
|
||||
description: '',
|
||||
enabled: true,
|
||||
id: '123',
|
||||
inputs: [
|
||||
{
|
||||
streams: [
|
||||
{
|
||||
id: '1',
|
||||
enabled: true,
|
||||
keep_enabled: false,
|
||||
release: 'beta',
|
||||
vars: { var: { type: 'text', value: 'value', frozen: false } },
|
||||
config: { config: { type: 'text', value: 'value', frozen: false } },
|
||||
data_stream: { dataset: 'apache.access', type: 'logs', elasticsearch: {} },
|
||||
},
|
||||
],
|
||||
id: '1',
|
||||
enabled: true,
|
||||
type: 'logs',
|
||||
policy_template: '',
|
||||
keep_enabled: false,
|
||||
vars: { var: { type: 'text', value: 'value', frozen: false } },
|
||||
config: { config: { type: 'text', value: 'value', frozen: false } },
|
||||
},
|
||||
],
|
||||
vars: { var: { type: 'text', value: 'value', frozen: false } },
|
||||
name: 'Package Policy 123',
|
||||
namespace: 'default',
|
||||
package: {
|
||||
name: 'a-package',
|
||||
title: 'package A',
|
||||
version: '1.0.0',
|
||||
experimental_data_stream_features: [{ data_stream: 'logs', features: { tsdb: true } }],
|
||||
requires_root: false,
|
||||
},
|
||||
policy_id: 'agent-policy-id-a',
|
||||
policy_ids: ['agent-policy-id-a'],
|
||||
errors: [{ key: 'error', message: 'error' }],
|
||||
missingVars: ['var'],
|
||||
};
|
||||
const responseItem: UpgradePackagePolicyDryRunResponseItem = {
|
||||
hasErrors: false,
|
||||
name: 'policy',
|
||||
statusCode: 200,
|
||||
body: {
|
||||
message: 'success',
|
||||
},
|
||||
diff: [testPackagePolicy, dryRunPackagePolicy],
|
||||
agent_diff: [
|
||||
[
|
||||
{
|
||||
id: '1',
|
||||
name: 'input',
|
||||
revision: 1,
|
||||
type: 'logs',
|
||||
data_stream: { namespace: 'default' },
|
||||
use_output: 'default',
|
||||
package_policy_id: '1',
|
||||
streams: [
|
||||
{
|
||||
id: 'logfile-log.logs-d46700b2-47f8-4b1a-9153-14a717dc5edf',
|
||||
data_stream: {
|
||||
dataset: 'generic',
|
||||
},
|
||||
paths: ['/var/tmp'],
|
||||
ignore_older: '72h',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
const responseBody: UpgradePackagePolicyDryRunResponse = [responseItem, responseItem];
|
||||
packagePolicyServiceMock.getUpgradeDryRunDiff.mockResolvedValueOnce(responseBody[0]);
|
||||
packagePolicyServiceMock.getUpgradeDryRunDiff.mockResolvedValueOnce(responseBody[1]);
|
||||
const request = httpServerMock.createKibanaRequest({
|
||||
body: {
|
||||
packagePolicyIds: ['1', '2'],
|
||||
},
|
||||
});
|
||||
await dryRunUpgradePackagePolicyHandler(context, request, response);
|
||||
expect(response.ok).toHaveBeenCalledWith({
|
||||
body: responseBody,
|
||||
});
|
||||
const validationResp = DryRunPackagePoliciesResponseBodySchema.validate(responseBody);
|
||||
expect(validationResp).toEqual(responseBody);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import { schema } from '@kbn/config-schema';
|
||||
|
||||
import { getRouteRequiredAuthz } from '../../services/security';
|
||||
|
||||
|
@ -22,9 +23,21 @@ import {
|
|||
DryRunPackagePoliciesRequestSchema,
|
||||
DeleteOnePackagePolicyRequestSchema,
|
||||
BulkGetPackagePoliciesRequestSchema,
|
||||
PackagePolicyResponseSchema,
|
||||
BulkGetPackagePoliciesResponseBodySchema,
|
||||
DeletePackagePoliciesResponseBodySchema,
|
||||
DeleteOnePackagePolicyResponseSchema,
|
||||
UpgradePackagePoliciesResponseBodySchema,
|
||||
DryRunPackagePoliciesResponseBodySchema,
|
||||
OrphanedPackagePoliciesResponseSchema,
|
||||
CreatePackagePolicyResponseSchema,
|
||||
} from '../../types';
|
||||
import { calculateRouteAuthz } from '../../services/security/security';
|
||||
|
||||
import { genericErrorResponse, notFoundResponse } from '../schema/errors';
|
||||
|
||||
import { ListResponseSchema } from '../schema/utils';
|
||||
|
||||
import {
|
||||
getPackagePoliciesHandler,
|
||||
getOnePackagePolicyHandler,
|
||||
|
@ -48,11 +61,25 @@ export const registerRoutes = (router: FleetAuthzRouter) => {
|
|||
fleetAuthz,
|
||||
getRouteRequiredAuthz('get', PACKAGE_POLICY_API_ROUTES.LIST_PATTERN)
|
||||
).granted,
|
||||
description: 'List package policies',
|
||||
options: {
|
||||
tags: ['oas-tag:Fleet package policies'],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: { request: GetPackagePoliciesRequestSchema },
|
||||
validate: {
|
||||
request: GetPackagePoliciesRequestSchema,
|
||||
response: {
|
||||
200: {
|
||||
body: () => ListResponseSchema(PackagePolicyResponseSchema),
|
||||
},
|
||||
400: {
|
||||
body: genericErrorResponse,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
getPackagePoliciesHandler
|
||||
);
|
||||
|
@ -66,11 +93,28 @@ export const registerRoutes = (router: FleetAuthzRouter) => {
|
|||
fleetAuthz,
|
||||
getRouteRequiredAuthz('post', PACKAGE_POLICY_API_ROUTES.BULK_GET_PATTERN)
|
||||
).granted,
|
||||
description: 'Bulk get package policies',
|
||||
options: {
|
||||
tags: ['oas-tag:Fleet package policies'],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: { request: BulkGetPackagePoliciesRequestSchema },
|
||||
validate: {
|
||||
request: BulkGetPackagePoliciesRequestSchema,
|
||||
response: {
|
||||
200: {
|
||||
body: () => BulkGetPackagePoliciesResponseBodySchema,
|
||||
},
|
||||
400: {
|
||||
body: genericErrorResponse,
|
||||
},
|
||||
404: {
|
||||
body: notFoundResponse,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
bulkGetPackagePoliciesHandler
|
||||
);
|
||||
|
@ -84,11 +128,31 @@ export const registerRoutes = (router: FleetAuthzRouter) => {
|
|||
fleetAuthz,
|
||||
getRouteRequiredAuthz('get', PACKAGE_POLICY_API_ROUTES.INFO_PATTERN)
|
||||
).granted,
|
||||
description: 'Get package policy by ID',
|
||||
options: {
|
||||
tags: ['oas-tag:Fleet package policies'],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: { request: GetOnePackagePolicyRequestSchema },
|
||||
validate: {
|
||||
request: GetOnePackagePolicyRequestSchema,
|
||||
response: {
|
||||
200: {
|
||||
body: () =>
|
||||
schema.object({
|
||||
item: PackagePolicyResponseSchema,
|
||||
}),
|
||||
},
|
||||
400: {
|
||||
body: genericErrorResponse,
|
||||
},
|
||||
404: {
|
||||
body: notFoundResponse,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
getOnePackagePolicyHandler
|
||||
);
|
||||
|
@ -103,20 +167,48 @@ export const registerRoutes = (router: FleetAuthzRouter) => {
|
|||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: {},
|
||||
validate: {
|
||||
request: {},
|
||||
response: {
|
||||
200: {
|
||||
body: () => OrphanedPackagePoliciesResponseSchema,
|
||||
},
|
||||
400: {
|
||||
body: genericErrorResponse,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
getOrphanedPackagePolicies
|
||||
);
|
||||
|
||||
// Create
|
||||
// Authz check moved to service here: https://github.com/elastic/kibana/pull/140458
|
||||
router.versioned
|
||||
.post({
|
||||
path: PACKAGE_POLICY_API_ROUTES.CREATE_PATTERN,
|
||||
description: 'Create package policy',
|
||||
options: {
|
||||
tags: ['oas-tag:Fleet package policies'],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: { request: CreatePackagePolicyRequestSchema },
|
||||
validate: {
|
||||
request: CreatePackagePolicyRequestSchema,
|
||||
response: {
|
||||
200: {
|
||||
body: () => CreatePackagePolicyResponseSchema,
|
||||
},
|
||||
400: {
|
||||
body: genericErrorResponse,
|
||||
},
|
||||
409: {
|
||||
body: genericErrorResponse,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
createPackagePolicyHandler
|
||||
);
|
||||
|
@ -130,11 +222,31 @@ export const registerRoutes = (router: FleetAuthzRouter) => {
|
|||
fleetAuthz,
|
||||
getRouteRequiredAuthz('put', PACKAGE_POLICY_API_ROUTES.UPDATE_PATTERN)
|
||||
).granted,
|
||||
description: 'Update package policy by ID',
|
||||
options: {
|
||||
tags: ['oas-tag:Fleet package policies'],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: { request: UpdatePackagePolicyRequestSchema },
|
||||
validate: {
|
||||
request: UpdatePackagePolicyRequestSchema,
|
||||
response: {
|
||||
200: {
|
||||
body: () =>
|
||||
schema.object({
|
||||
item: PackagePolicyResponseSchema,
|
||||
}),
|
||||
},
|
||||
400: {
|
||||
body: genericErrorResponse,
|
||||
},
|
||||
403: {
|
||||
body: genericErrorResponse,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
updatePackagePolicyHandler
|
||||
|
@ -147,11 +259,25 @@ export const registerRoutes = (router: FleetAuthzRouter) => {
|
|||
fleetAuthz: {
|
||||
integrations: { writeIntegrationPolicies: true },
|
||||
},
|
||||
description: 'Bulk delete package policies',
|
||||
options: {
|
||||
tags: ['oas-tag:Fleet package policies'],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: { request: DeletePackagePoliciesRequestSchema },
|
||||
validate: {
|
||||
request: DeletePackagePoliciesRequestSchema,
|
||||
response: {
|
||||
200: {
|
||||
body: () => DeletePackagePoliciesResponseBodySchema,
|
||||
},
|
||||
400: {
|
||||
body: genericErrorResponse,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
deletePackagePolicyHandler
|
||||
);
|
||||
|
@ -162,11 +288,25 @@ export const registerRoutes = (router: FleetAuthzRouter) => {
|
|||
fleetAuthz: {
|
||||
integrations: { writeIntegrationPolicies: true },
|
||||
},
|
||||
description: 'Delete package policy by ID',
|
||||
options: {
|
||||
tags: ['oas-tag:Fleet package policies'],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: { request: DeleteOnePackagePolicyRequestSchema },
|
||||
validate: {
|
||||
request: DeleteOnePackagePolicyRequestSchema,
|
||||
response: {
|
||||
200: {
|
||||
body: () => DeleteOnePackagePolicyResponseSchema,
|
||||
},
|
||||
400: {
|
||||
body: genericErrorResponse,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
deleteOnePackagePolicyHandler
|
||||
);
|
||||
|
@ -178,11 +318,25 @@ export const registerRoutes = (router: FleetAuthzRouter) => {
|
|||
fleetAuthz: {
|
||||
integrations: { writeIntegrationPolicies: true },
|
||||
},
|
||||
description: 'Upgrade package policy to a newer package version',
|
||||
options: {
|
||||
tags: ['oas-tag:Fleet package policies'],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: { request: UpgradePackagePoliciesRequestSchema },
|
||||
validate: {
|
||||
request: UpgradePackagePoliciesRequestSchema,
|
||||
response: {
|
||||
200: {
|
||||
body: () => UpgradePackagePoliciesResponseBodySchema,
|
||||
},
|
||||
400: {
|
||||
body: genericErrorResponse,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
upgradePackagePolicyHandler
|
||||
);
|
||||
|
@ -194,11 +348,25 @@ export const registerRoutes = (router: FleetAuthzRouter) => {
|
|||
fleetAuthz: {
|
||||
integrations: { readIntegrationPolicies: true },
|
||||
},
|
||||
description: 'Dry run package policy upgrade',
|
||||
options: {
|
||||
tags: ['oas-tag:Fleet package policies'],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: { request: DryRunPackagePoliciesRequestSchema },
|
||||
validate: {
|
||||
request: DryRunPackagePoliciesRequestSchema,
|
||||
response: {
|
||||
200: {
|
||||
body: () => DryRunPackagePoliciesResponseBodySchema,
|
||||
},
|
||||
400: {
|
||||
body: genericErrorResponse,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
dryRunUpgradePackagePolicyHandler
|
||||
);
|
||||
|
|
33
x-pack/plugins/fleet/server/routes/schema/errors.ts
Normal file
33
x-pack/plugins/fleet/server/routes/schema/errors.ts
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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 { schema } from '@kbn/config-schema';
|
||||
|
||||
export const genericErrorResponse = () =>
|
||||
schema.object(
|
||||
{
|
||||
statusCode: schema.number(),
|
||||
error: schema.string(),
|
||||
message: schema.string(),
|
||||
},
|
||||
{
|
||||
meta: { description: 'Generic Error' },
|
||||
}
|
||||
);
|
||||
|
||||
export const notFoundResponse = () =>
|
||||
schema.object({
|
||||
message: schema.string(),
|
||||
});
|
||||
|
||||
export const internalErrorResponse = () =>
|
||||
schema.object(
|
||||
{
|
||||
message: schema.string(),
|
||||
},
|
||||
{ meta: { description: 'Internal Server Error' } }
|
||||
);
|
16
x-pack/plugins/fleet/server/routes/schema/utils.ts
Normal file
16
x-pack/plugins/fleet/server/routes/schema/utils.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* 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 { Type } from '@kbn/config-schema';
|
||||
import { schema } from '@kbn/config-schema';
|
||||
export const ListResponseSchema = (itemSchema: Type<any>) =>
|
||||
schema.object({
|
||||
items: schema.arrayOf(itemSchema),
|
||||
total: schema.number(),
|
||||
page: schema.number(),
|
||||
perPage: schema.number(),
|
||||
});
|
|
@ -4,12 +4,20 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import { savedObjectsClientMock } from '@kbn/core/server/mocks';
|
||||
import { httpServerMock, savedObjectsClientMock } from '@kbn/core/server/mocks';
|
||||
|
||||
import { agentPolicyService } from '../../services';
|
||||
import { getFleetServerPolicies } from '../../services/fleet_server';
|
||||
|
||||
import { getFleetServerOrAgentPolicies, getDownloadSource } from './enrollment_settings_handler';
|
||||
import type { FleetRequestHandlerContext } from '../../types';
|
||||
import { GetEnrollmentSettingsResponseSchema } from '../../types';
|
||||
import { xpackMocks } from '../../mocks';
|
||||
|
||||
import {
|
||||
getFleetServerOrAgentPolicies,
|
||||
getDownloadSource,
|
||||
getEnrollmentSettingsHandler,
|
||||
} from './enrollment_settings_handler';
|
||||
|
||||
jest.mock('../../services', () => ({
|
||||
agentPolicyService: {
|
||||
|
@ -42,6 +50,27 @@ jest.mock('../../services', () => ({
|
|||
|
||||
jest.mock('../../services/fleet_server', () => ({
|
||||
getFleetServerPolicies: jest.fn(),
|
||||
hasFleetServersForPolicies: jest.fn().mockResolvedValue(true),
|
||||
}));
|
||||
|
||||
jest.mock('../../services/fleet_server_host', () => ({
|
||||
getFleetServerHostsForAgentPolicy: jest.fn().mockResolvedValue({
|
||||
id: 'host-1',
|
||||
is_default: true,
|
||||
is_preconfigured: true,
|
||||
name: 'Host 1',
|
||||
host_urls: ['http://localhost:8220'],
|
||||
proxy_id: 'proxy-1',
|
||||
}),
|
||||
}));
|
||||
|
||||
jest.mock('../../services/fleet_proxies', () => ({
|
||||
getFleetProxy: jest.fn().mockResolvedValue({
|
||||
id: 'proxy-1',
|
||||
name: 'Proxy 1',
|
||||
url: 'https://proxy-1/',
|
||||
is_preconfigured: true,
|
||||
}),
|
||||
}));
|
||||
|
||||
describe('EnrollmentSettingsHandler utils', () => {
|
||||
|
@ -206,5 +235,74 @@ describe('EnrollmentSettingsHandler utils', () => {
|
|||
proxy_id: 'proxy-1',
|
||||
});
|
||||
});
|
||||
|
||||
describe('schema validation', () => {
|
||||
let context: FleetRequestHandlerContext;
|
||||
let response: ReturnType<typeof httpServerMock.createResponseFactory>;
|
||||
|
||||
beforeEach(() => {
|
||||
context = xpackMocks.createRequestHandlerContext() as unknown as FleetRequestHandlerContext;
|
||||
response = httpServerMock.createResponseFactory();
|
||||
});
|
||||
|
||||
it('should return valid enrollment settings', async () => {
|
||||
const fleetServerPolicies = [
|
||||
{
|
||||
id: 'fs-policy-1',
|
||||
name: 'FS Policy 1',
|
||||
is_managed: true,
|
||||
is_default_fleet_server: true,
|
||||
has_fleet_server: true,
|
||||
download_source_id: 'source-2',
|
||||
fleet_server_host_id: undefined,
|
||||
},
|
||||
];
|
||||
(getFleetServerPolicies as jest.Mock).mockResolvedValueOnce(fleetServerPolicies);
|
||||
const expectedResponse = {
|
||||
fleet_server: {
|
||||
has_active: true,
|
||||
host_proxy: {
|
||||
id: 'proxy-1',
|
||||
name: 'Proxy 1',
|
||||
is_preconfigured: true,
|
||||
url: 'https://proxy-1/',
|
||||
},
|
||||
|
||||
host: {
|
||||
host_urls: ['http://localhost:8220'],
|
||||
id: 'host-1',
|
||||
is_default: true,
|
||||
is_preconfigured: true,
|
||||
name: 'Host 1',
|
||||
proxy_id: 'proxy-1',
|
||||
},
|
||||
policies: [
|
||||
{
|
||||
download_source_id: 'source-2',
|
||||
fleet_server_host_id: undefined,
|
||||
has_fleet_server: true,
|
||||
id: 'fs-policy-1',
|
||||
is_default_fleet_server: true,
|
||||
is_managed: true,
|
||||
name: 'FS Policy 1',
|
||||
space_ids: undefined,
|
||||
},
|
||||
],
|
||||
},
|
||||
download_source: {
|
||||
host: 'https://source-1/',
|
||||
id: 'source-1',
|
||||
is_default: true,
|
||||
name: 'Source 1',
|
||||
},
|
||||
};
|
||||
await getEnrollmentSettingsHandler(context, {} as any, response);
|
||||
expect(response.ok).toHaveBeenCalledWith({
|
||||
body: expectedResponse,
|
||||
});
|
||||
const validationResp = GetEnrollmentSettingsResponseSchema.validate(expectedResponse);
|
||||
expect(validationResp).toEqual(expectedResponse);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -47,7 +47,6 @@ export const getEnrollmentSettingsHandler: FleetRequestHandler<
|
|||
fleet_server_host_id: undefined,
|
||||
download_source_id: undefined,
|
||||
};
|
||||
|
||||
// Check if there is any active fleet server enrolled into the fleet server policies policies
|
||||
if (fleetServerPolicies) {
|
||||
settingsResponse.fleet_server.policies = fleetServerPolicies;
|
||||
|
|
|
@ -15,9 +15,14 @@ import {
|
|||
GetEnrollmentSettingsRequestSchema,
|
||||
GetSpaceSettingsRequestSchema,
|
||||
PutSpaceSettingsRequestSchema,
|
||||
SpaceSettingsResponseSchema,
|
||||
SettingsResponseSchema,
|
||||
GetEnrollmentSettingsResponseSchema,
|
||||
} from '../../types';
|
||||
import type { FleetConfigType } from '../../config';
|
||||
|
||||
import { genericErrorResponse, notFoundResponse } from '../schema/errors';
|
||||
|
||||
import { getEnrollmentSettingsHandler } from './enrollment_settings_handler';
|
||||
|
||||
import {
|
||||
|
@ -45,7 +50,14 @@ export const registerRoutes = (router: FleetAuthzRouter, config: FleetConfigType
|
|||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: { request: GetSpaceSettingsRequestSchema },
|
||||
validate: {
|
||||
request: GetSpaceSettingsRequestSchema,
|
||||
response: {
|
||||
200: {
|
||||
body: () => SpaceSettingsResponseSchema,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
getSpaceSettingsHandler
|
||||
);
|
||||
|
@ -61,7 +73,14 @@ export const registerRoutes = (router: FleetAuthzRouter, config: FleetConfigType
|
|||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: { request: PutSpaceSettingsRequestSchema },
|
||||
validate: {
|
||||
request: PutSpaceSettingsRequestSchema,
|
||||
response: {
|
||||
200: {
|
||||
body: () => SpaceSettingsResponseSchema,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
putSpaceSettingsHandler
|
||||
);
|
||||
|
@ -74,11 +93,27 @@ export const registerRoutes = (router: FleetAuthzRouter, config: FleetConfigType
|
|||
fleet: { readSettings: true },
|
||||
},
|
||||
description: `Get settings`,
|
||||
options: {
|
||||
tags: ['oas-tag:Fleet internals'],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: { request: GetSettingsRequestSchema },
|
||||
validate: {
|
||||
request: GetSettingsRequestSchema,
|
||||
response: {
|
||||
200: {
|
||||
body: () => SettingsResponseSchema,
|
||||
},
|
||||
400: {
|
||||
body: genericErrorResponse,
|
||||
},
|
||||
404: {
|
||||
body: notFoundResponse,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
getSettingsHandler
|
||||
);
|
||||
|
@ -89,11 +124,27 @@ export const registerRoutes = (router: FleetAuthzRouter, config: FleetConfigType
|
|||
fleet: { allSettings: true },
|
||||
},
|
||||
description: `Update settings`,
|
||||
options: {
|
||||
tags: ['oas-tag:Fleet internals'],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: { request: PutSettingsRequestSchema },
|
||||
validate: {
|
||||
request: PutSettingsRequestSchema,
|
||||
response: {
|
||||
200: {
|
||||
body: () => SettingsResponseSchema,
|
||||
},
|
||||
400: {
|
||||
body: genericErrorResponse,
|
||||
},
|
||||
404: {
|
||||
body: notFoundResponse,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
putSettingsHandler
|
||||
);
|
||||
|
@ -104,11 +155,24 @@ export const registerRoutes = (router: FleetAuthzRouter, config: FleetConfigType
|
|||
return authz.fleet.addAgents || authz.fleet.addFleetServers;
|
||||
},
|
||||
description: `Get enrollment settings`,
|
||||
options: {
|
||||
tags: ['oas-tag:Fleet internals'],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: { request: GetEnrollmentSettingsRequestSchema },
|
||||
validate: {
|
||||
request: GetEnrollmentSettingsRequestSchema,
|
||||
response: {
|
||||
200: {
|
||||
body: () => GetEnrollmentSettingsResponseSchema,
|
||||
},
|
||||
400: {
|
||||
body: genericErrorResponse,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
getEnrollmentSettingsHandler
|
||||
);
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* 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 { httpServerMock } from '@kbn/core-http-server-mocks';
|
||||
|
||||
import { xpackMocks } from '../../mocks';
|
||||
import type { FleetRequestHandlerContext } from '../..';
|
||||
import { SettingsResponseSchema, SpaceSettingsResponseSchema } from '../../types';
|
||||
|
||||
import { getSettingsHandler, getSpaceSettingsHandler } from './settings_handler';
|
||||
|
||||
jest.mock('../../services/spaces/space_settings', () => ({
|
||||
getSpaceSettings: jest
|
||||
.fn()
|
||||
.mockResolvedValue({ allowed_namespace_prefixes: [], managed_by: 'kibana' }),
|
||||
saveSpaceSettings: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('../../services', () => ({
|
||||
settingsService: {
|
||||
getSettings: jest.fn().mockResolvedValue({
|
||||
id: '1',
|
||||
version: '1',
|
||||
preconfigured_fields: ['fleet_server_hosts'],
|
||||
secret_storage_requirements_met: true,
|
||||
output_secret_storage_requirements_met: true,
|
||||
has_seen_add_data_notice: true,
|
||||
fleet_server_hosts: ['http://localhost:8220'],
|
||||
prerelease_integrations_enabled: true,
|
||||
}),
|
||||
},
|
||||
appContextService: {
|
||||
getLogger: jest.fn().mockReturnValue({ error: jest.fn() }),
|
||||
getInternalUserSOClientWithoutSpaceExtension: jest.fn(),
|
||||
},
|
||||
agentPolicyService: {
|
||||
get: jest.fn(),
|
||||
getByIDs: jest.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
describe('SettingsHandler', () => {
|
||||
let context: FleetRequestHandlerContext;
|
||||
let response: ReturnType<typeof httpServerMock.createResponseFactory>;
|
||||
|
||||
beforeEach(() => {
|
||||
context = xpackMocks.createRequestHandlerContext() as unknown as FleetRequestHandlerContext;
|
||||
response = httpServerMock.createResponseFactory();
|
||||
});
|
||||
|
||||
it('should return valid space settings', async () => {
|
||||
await getSpaceSettingsHandler(context, {} as any, response);
|
||||
const expectedResponse = { item: { allowed_namespace_prefixes: [], managed_by: 'kibana' } };
|
||||
expect(response.ok).toHaveBeenCalledWith({
|
||||
body: expectedResponse,
|
||||
});
|
||||
const validationResp = SpaceSettingsResponseSchema.validate(expectedResponse);
|
||||
expect(validationResp).toEqual(expectedResponse);
|
||||
});
|
||||
|
||||
it('should return valid settings', async () => {
|
||||
await getSettingsHandler(context, {} as any, response);
|
||||
const expectedResponse = {
|
||||
item: {
|
||||
id: '1',
|
||||
version: '1',
|
||||
preconfigured_fields: ['fleet_server_hosts'],
|
||||
secret_storage_requirements_met: true,
|
||||
output_secret_storage_requirements_met: true,
|
||||
has_seen_add_data_notice: true,
|
||||
fleet_server_hosts: ['http://localhost:8220'],
|
||||
prerelease_integrations_enabled: true,
|
||||
},
|
||||
};
|
||||
expect(response.ok).toHaveBeenCalledWith({
|
||||
body: expectedResponse,
|
||||
});
|
||||
const validationResp = SettingsResponseSchema.validate(expectedResponse);
|
||||
expect(validationResp).toEqual(expectedResponse);
|
||||
});
|
||||
});
|
|
@ -25,6 +25,7 @@ import { hasFleetServers } from '../../services/fleet_server';
|
|||
import { createFleetAuthzMock } from '../../../common/mocks';
|
||||
|
||||
import { fleetSetupHandler, getFleetStatusHandler } from './handlers';
|
||||
import { FleetSetupResponseSchema, GetAgentsSetupResponseSchema } from '.';
|
||||
|
||||
jest.mock('../../services/setup', () => {
|
||||
return {
|
||||
|
@ -94,6 +95,8 @@ describe('FleetSetupHandler', () => {
|
|||
};
|
||||
expect(response.customError).toHaveBeenCalledTimes(0);
|
||||
expect(response.ok).toHaveBeenCalledWith({ body: expectedBody });
|
||||
const validationResp = FleetSetupResponseSchema.validate(expectedBody);
|
||||
expect(validationResp).toEqual(expectedBody);
|
||||
});
|
||||
|
||||
it('POST /setup fails w/500 on custom error', async () => {
|
||||
|
@ -209,6 +212,8 @@ describe('FleetStatusHandler', () => {
|
|||
};
|
||||
expect(response.customError).toHaveBeenCalledTimes(0);
|
||||
expect(response.ok).toHaveBeenCalledWith({ body: expectedBody });
|
||||
const validationResp = GetAgentsSetupResponseSchema.validate(expectedBody);
|
||||
expect(validationResp).toEqual(expectedBody);
|
||||
});
|
||||
|
||||
it('POST /status w/200 with fleet server standalone', async () => {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import { schema } from '@kbn/config-schema';
|
||||
|
||||
import type { FleetAuthzRouter } from '../../services/security';
|
||||
|
||||
|
@ -12,8 +13,28 @@ import { API_VERSIONS } from '../../../common/constants';
|
|||
|
||||
import type { FleetConfigType } from '../../../common/types';
|
||||
|
||||
import { genericErrorResponse, internalErrorResponse } from '../schema/errors';
|
||||
|
||||
import { getFleetStatusHandler, fleetSetupHandler } from './handlers';
|
||||
|
||||
export const FleetSetupResponseSchema = schema.object(
|
||||
{
|
||||
isInitialized: schema.boolean(),
|
||||
nonFatalErrors: schema.arrayOf(
|
||||
schema.object({
|
||||
name: schema.string(),
|
||||
message: schema.string(),
|
||||
})
|
||||
),
|
||||
},
|
||||
{
|
||||
meta: {
|
||||
description:
|
||||
"A summary of the result of Fleet's `setup` lifecycle. If `isInitialized` is true, Fleet is ready to accept agent enrollment. `nonFatalErrors` may include useful insight into non-blocking issues with Fleet setup.",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
export const registerFleetSetupRoute = (router: FleetAuthzRouter) => {
|
||||
router.versioned
|
||||
.post({
|
||||
|
@ -22,16 +43,59 @@ export const registerFleetSetupRoute = (router: FleetAuthzRouter) => {
|
|||
fleet: { setup: true },
|
||||
},
|
||||
description: `Initiate Fleet setup`,
|
||||
options: {
|
||||
tags: ['oas-tag:Fleet internals'],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: false,
|
||||
validate: {
|
||||
request: {},
|
||||
response: {
|
||||
200: {
|
||||
body: () => FleetSetupResponseSchema,
|
||||
},
|
||||
400: {
|
||||
body: genericErrorResponse,
|
||||
},
|
||||
500: {
|
||||
body: internalErrorResponse,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
fleetSetupHandler
|
||||
);
|
||||
};
|
||||
|
||||
export const GetAgentsSetupResponseSchema = schema.object(
|
||||
{
|
||||
isReady: schema.boolean(),
|
||||
missing_requirements: schema.arrayOf(
|
||||
schema.oneOf([
|
||||
schema.literal('security_required'),
|
||||
schema.literal('tls_required'),
|
||||
schema.literal('api_keys'),
|
||||
schema.literal('fleet_admin_user'),
|
||||
schema.literal('fleet_server'),
|
||||
])
|
||||
),
|
||||
missing_optional_features: schema.arrayOf(
|
||||
schema.oneOf([schema.literal('encrypted_saved_object_encryption_key_required')])
|
||||
),
|
||||
package_verification_key_id: schema.maybe(schema.string()),
|
||||
is_space_awareness_enabled: schema.maybe(schema.boolean()),
|
||||
is_secrets_storage_enabled: schema.maybe(schema.boolean()),
|
||||
},
|
||||
{
|
||||
meta: {
|
||||
description:
|
||||
'A summary of the agent setup status. `isReady` indicates whether the setup is ready. If the setup is not ready, `missing_requirements` lists which requirements are missing.',
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
// That route is used by agent to setup Fleet
|
||||
export const registerCreateFleetSetupRoute = (router: FleetAuthzRouter) => {
|
||||
router.versioned
|
||||
|
@ -40,11 +104,25 @@ export const registerCreateFleetSetupRoute = (router: FleetAuthzRouter) => {
|
|||
fleetAuthz: {
|
||||
fleet: { setup: true },
|
||||
},
|
||||
description: `Initiate agent setup`,
|
||||
options: {
|
||||
tags: ['oas-tag:Elastic Agents'],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: false,
|
||||
validate: {
|
||||
request: {},
|
||||
response: {
|
||||
200: {
|
||||
body: () => FleetSetupResponseSchema,
|
||||
},
|
||||
400: {
|
||||
body: genericErrorResponse,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
fleetSetupHandler
|
||||
);
|
||||
|
@ -57,11 +135,25 @@ export const registerGetFleetStatusRoute = (router: FleetAuthzRouter) => {
|
|||
fleetAuthz: {
|
||||
fleet: { setup: true },
|
||||
},
|
||||
description: `Get agent setup info`,
|
||||
options: {
|
||||
tags: ['oas-tag:Elastic Agents'],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: false,
|
||||
validate: {
|
||||
request: {},
|
||||
response: {
|
||||
200: {
|
||||
body: () => GetAgentsSetupResponseSchema,
|
||||
},
|
||||
400: {
|
||||
body: genericErrorResponse,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
getFleetStatusHandler
|
||||
);
|
||||
|
|
|
@ -27,7 +27,9 @@ export const registerRoutes = (router: FleetAuthzRouter) => {
|
|||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.internal.v1,
|
||||
validate: { request: PostStandaloneAgentAPIKeyRequestSchema },
|
||||
validate: {
|
||||
request: PostStandaloneAgentAPIKeyRequestSchema,
|
||||
},
|
||||
},
|
||||
createStandaloneAgentApiKeyHandler
|
||||
);
|
||||
|
|
|
@ -28,9 +28,11 @@ import type { FleetRequestHandlerContext } from '../..';
|
|||
import type { MockedFleetAppContext } from '../../mocks';
|
||||
import { createAppContextStartContractMock, xpackMocks } from '../../mocks';
|
||||
import { agentPolicyService, appContextService } from '../../services';
|
||||
import type {
|
||||
GetUninstallTokenRequestSchema,
|
||||
GetUninstallTokensMetadataRequestSchema,
|
||||
import {
|
||||
GetUninstallTokensMetadataResponseSchema,
|
||||
type GetUninstallTokenRequestSchema,
|
||||
type GetUninstallTokensMetadataRequestSchema,
|
||||
GetUninstallTokenResponseSchema,
|
||||
} from '../../types/rest_spec/uninstall_token';
|
||||
|
||||
import { createAgentPolicyMock } from '../../../common/mocks';
|
||||
|
@ -116,6 +118,10 @@ describe('uninstall token handlers', () => {
|
|||
expect(response.ok).toHaveBeenCalledWith({
|
||||
body: uninstallTokensResponseFixture,
|
||||
});
|
||||
const validateResp = GetUninstallTokensMetadataResponseSchema.validate(
|
||||
uninstallTokensResponseFixture
|
||||
);
|
||||
expect(validateResp).toEqual(uninstallTokensResponseFixture);
|
||||
});
|
||||
|
||||
it('should return internal error when uninstallTokenService throws error', async () => {
|
||||
|
@ -131,18 +137,19 @@ describe('uninstall token handlers', () => {
|
|||
});
|
||||
|
||||
describe('getUninstallTokenHandler', () => {
|
||||
const uninstallTokenFixture: UninstallToken = {
|
||||
id: 'id-1',
|
||||
policy_id: 'policy-id-1',
|
||||
policy_name: null,
|
||||
created_at: '2023-06-15T16:46:48.274Z',
|
||||
token: '123456789',
|
||||
};
|
||||
let uninstallTokenFixture: UninstallToken;
|
||||
|
||||
let getTokenMock: jest.Mock;
|
||||
let request: KibanaRequest<TypeOf<typeof GetUninstallTokenRequestSchema.params>>;
|
||||
|
||||
beforeEach(async () => {
|
||||
uninstallTokenFixture = {
|
||||
id: 'id-1',
|
||||
policy_id: 'policy-id-1',
|
||||
policy_name: null,
|
||||
created_at: '2023-06-15T16:46:48.274Z',
|
||||
token: '123456789',
|
||||
};
|
||||
const uninstallTokenService = (await context.fleet).uninstallTokenService.asCurrentUser;
|
||||
getTokenMock = uninstallTokenService.getToken as jest.Mock;
|
||||
|
||||
|
@ -165,6 +172,10 @@ describe('uninstall token handlers', () => {
|
|||
item: uninstallTokenFixture,
|
||||
},
|
||||
});
|
||||
const validateResp = GetUninstallTokenResponseSchema.validate({
|
||||
item: uninstallTokenFixture,
|
||||
});
|
||||
expect(validateResp).toEqual({ item: uninstallTokenFixture });
|
||||
});
|
||||
|
||||
it('should return internal error when uninstallTokenService throws error', async () => {
|
||||
|
|
|
@ -84,7 +84,6 @@ export const getUninstallTokenHandler: FleetRequestHandler<
|
|||
body: { message: `Uninstall Token not found with id ${uninstallTokenId}` },
|
||||
});
|
||||
}
|
||||
|
||||
const body: GetUninstallTokenResponse = {
|
||||
item: token,
|
||||
};
|
||||
|
|
|
@ -4,16 +4,21 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { UNINSTALL_TOKEN_ROUTES, API_VERSIONS } from '../../../common/constants';
|
||||
import type { FleetConfigType } from '../../config';
|
||||
|
||||
import type { FleetAuthzRouter } from '../../services/security';
|
||||
import {
|
||||
GetUninstallTokenRequestSchema,
|
||||
GetUninstallTokenResponseSchema,
|
||||
GetUninstallTokensMetadataRequestSchema,
|
||||
GetUninstallTokensMetadataResponseSchema,
|
||||
} from '../../types/rest_spec/uninstall_token';
|
||||
import { parseExperimentalConfigValue } from '../../../common/experimental_features';
|
||||
|
||||
import { genericErrorResponse } from '../schema/errors';
|
||||
|
||||
import { getUninstallTokenHandler, getUninstallTokensMetadataHandler } from './handlers';
|
||||
|
||||
export const registerRoutes = (router: FleetAuthzRouter, config: FleetConfigType) => {
|
||||
|
@ -26,11 +31,25 @@ export const registerRoutes = (router: FleetAuthzRouter, config: FleetConfigType
|
|||
fleetAuthz: {
|
||||
fleet: { allAgents: true },
|
||||
},
|
||||
description: 'List metadata for latest uninstall tokens per agent policy',
|
||||
options: {
|
||||
tags: ['oas-tag:Fleet uninstall tokens'],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: { request: GetUninstallTokensMetadataRequestSchema },
|
||||
validate: {
|
||||
request: GetUninstallTokensMetadataRequestSchema,
|
||||
response: {
|
||||
200: {
|
||||
body: () => GetUninstallTokensMetadataResponseSchema,
|
||||
},
|
||||
400: {
|
||||
body: genericErrorResponse,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
getUninstallTokensMetadataHandler
|
||||
);
|
||||
|
@ -41,11 +60,25 @@ export const registerRoutes = (router: FleetAuthzRouter, config: FleetConfigType
|
|||
fleetAuthz: {
|
||||
fleet: { allAgents: true },
|
||||
},
|
||||
description: 'Get one decrypted uninstall token by its ID',
|
||||
options: {
|
||||
tags: ['oas-tag:Fleet uninstall tokens'],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: { request: GetUninstallTokenRequestSchema },
|
||||
validate: {
|
||||
request: GetUninstallTokenRequestSchema,
|
||||
response: {
|
||||
200: {
|
||||
body: () => GetUninstallTokenResponseSchema,
|
||||
},
|
||||
400: {
|
||||
body: genericErrorResponse,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
getUninstallTokenHandler
|
||||
);
|
||||
|
|
|
@ -36,7 +36,15 @@ export async function getSettings(soClient: SavedObjectsClientContract): Promise
|
|||
return {
|
||||
id: settingsSo.id,
|
||||
version: settingsSo.version,
|
||||
...settingsSo.attributes,
|
||||
secret_storage_requirements_met: settingsSo.attributes.secret_storage_requirements_met,
|
||||
output_secret_storage_requirements_met:
|
||||
settingsSo.attributes.output_secret_storage_requirements_met,
|
||||
has_seen_add_data_notice: settingsSo.attributes.has_seen_add_data_notice,
|
||||
prerelease_integrations_enabled: settingsSo.attributes.prerelease_integrations_enabled,
|
||||
use_space_awareness_migration_status:
|
||||
settingsSo.attributes.use_space_awareness_migration_status,
|
||||
use_space_awareness_migration_started_at:
|
||||
settingsSo.attributes.use_space_awareness_migration_started_at,
|
||||
fleet_server_hosts: fleetServerHosts.items.flatMap((item) => item.host_urls),
|
||||
preconfigured_fields: getConfigFleetServerHosts() ? ['fleet_server_hosts'] : [],
|
||||
};
|
||||
|
|
|
@ -16,15 +16,24 @@ export const PackagePolicyNamespaceSchema = schema.string({
|
|||
return namespaceValidation.error;
|
||||
}
|
||||
},
|
||||
meta: {
|
||||
description:
|
||||
"The package policy namespace. Leave blank to inherit the agent policy's namespace.",
|
||||
},
|
||||
});
|
||||
|
||||
const ConfigRecordSchema = schema.recordOf(
|
||||
export const ConfigRecordSchema = schema.recordOf(
|
||||
schema.string(),
|
||||
schema.object({
|
||||
type: schema.maybe(schema.string()),
|
||||
value: schema.maybe(schema.any()),
|
||||
frozen: schema.maybe(schema.boolean()),
|
||||
})
|
||||
}),
|
||||
{
|
||||
meta: {
|
||||
description: 'Package variable (see integration documentation for more information)',
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const PackagePolicyStreamsSchema = {
|
||||
|
@ -50,33 +59,18 @@ const PackagePolicyStreamsSchema = {
|
|||
),
|
||||
}),
|
||||
vars: schema.maybe(ConfigRecordSchema),
|
||||
config: schema.maybe(
|
||||
schema.recordOf(
|
||||
schema.string(),
|
||||
schema.object({
|
||||
type: schema.maybe(schema.string()),
|
||||
value: schema.maybe(schema.any()),
|
||||
})
|
||||
)
|
||||
),
|
||||
config: schema.maybe(ConfigRecordSchema),
|
||||
compiled_stream: schema.maybe(schema.any()),
|
||||
};
|
||||
|
||||
const PackagePolicyInputsSchema = {
|
||||
export const PackagePolicyInputsSchema = {
|
||||
id: schema.maybe(schema.string()),
|
||||
type: schema.string(),
|
||||
policy_template: schema.maybe(schema.string()),
|
||||
enabled: schema.boolean(),
|
||||
keep_enabled: schema.maybe(schema.boolean()),
|
||||
vars: schema.maybe(ConfigRecordSchema),
|
||||
config: schema.maybe(
|
||||
schema.recordOf(
|
||||
schema.string(),
|
||||
schema.object({
|
||||
type: schema.maybe(schema.string()),
|
||||
value: schema.maybe(schema.any()),
|
||||
})
|
||||
)
|
||||
),
|
||||
config: schema.maybe(ConfigRecordSchema),
|
||||
streams: schema.arrayOf(schema.object(PackagePolicyStreamsSchema)),
|
||||
};
|
||||
|
||||
|
@ -92,44 +86,91 @@ const ExperimentalDataStreamFeatures = schema.arrayOf(
|
|||
})
|
||||
);
|
||||
|
||||
const PackagePolicyBaseSchema = {
|
||||
name: schema.string(),
|
||||
description: schema.maybe(schema.string()),
|
||||
namespace: schema.maybe(PackagePolicyNamespaceSchema),
|
||||
policy_id: schema.nullable(schema.maybe(schema.string())),
|
||||
policy_ids: schema.maybe(schema.arrayOf(schema.string())),
|
||||
output_id: schema.nullable(schema.maybe(schema.string())),
|
||||
enabled: schema.boolean(),
|
||||
is_managed: schema.maybe(schema.boolean()),
|
||||
package: schema.maybe(
|
||||
schema.object({
|
||||
name: schema.string(),
|
||||
title: schema.string(),
|
||||
version: schema.string(),
|
||||
experimental_data_stream_features: schema.maybe(ExperimentalDataStreamFeatures),
|
||||
requires_root: schema.maybe(schema.boolean()),
|
||||
export const PackagePolicyPackageSchema = schema.object({
|
||||
name: schema.string({
|
||||
meta: {
|
||||
description: 'Package name',
|
||||
},
|
||||
}),
|
||||
title: schema.maybe(schema.string()),
|
||||
version: schema.string({
|
||||
meta: {
|
||||
description: 'Package version',
|
||||
},
|
||||
}),
|
||||
experimental_data_stream_features: schema.maybe(ExperimentalDataStreamFeatures),
|
||||
requires_root: schema.maybe(schema.boolean()),
|
||||
});
|
||||
|
||||
export const PackagePolicyBaseSchema = {
|
||||
name: schema.string({
|
||||
meta: {
|
||||
description: 'Package policy name (should be unique)',
|
||||
},
|
||||
}),
|
||||
description: schema.maybe(
|
||||
schema.string({
|
||||
meta: {
|
||||
description: 'Package policy description',
|
||||
},
|
||||
})
|
||||
),
|
||||
namespace: schema.maybe(PackagePolicyNamespaceSchema),
|
||||
policy_id: schema.maybe(
|
||||
schema.oneOf([
|
||||
schema.literal(null),
|
||||
schema.string({
|
||||
meta: {
|
||||
description: 'Agent policy ID where that package policy will be added',
|
||||
deprecated: true,
|
||||
},
|
||||
}),
|
||||
])
|
||||
),
|
||||
policy_ids: schema.maybe(
|
||||
schema.arrayOf(
|
||||
schema.string({
|
||||
meta: {
|
||||
description: 'Agent policy IDs where that package policy will be added',
|
||||
},
|
||||
})
|
||||
)
|
||||
),
|
||||
output_id: schema.maybe(schema.oneOf([schema.literal(null), schema.string()])),
|
||||
enabled: schema.boolean(),
|
||||
is_managed: schema.maybe(schema.boolean()),
|
||||
package: schema.maybe(PackagePolicyPackageSchema),
|
||||
|
||||
inputs: schema.arrayOf(schema.object(PackagePolicyInputsSchema)),
|
||||
vars: schema.maybe(ConfigRecordSchema),
|
||||
overrides: schema.maybe(
|
||||
schema.nullable(
|
||||
schema.object({
|
||||
inputs: schema.maybe(
|
||||
schema.recordOf(schema.string(), schema.any(), {
|
||||
validate: (val) => {
|
||||
if (
|
||||
Object.keys(val).some(
|
||||
(key) => key.match(/^compiled_inputs(\.)?/) || key.match(/^compiled_stream(\.)?/)
|
||||
)
|
||||
) {
|
||||
return 'Overrides of compiled_inputs and compiled_stream are not allowed';
|
||||
}
|
||||
},
|
||||
})
|
||||
),
|
||||
})
|
||||
)
|
||||
schema.oneOf([
|
||||
schema.literal(null),
|
||||
schema.object(
|
||||
{
|
||||
inputs: schema.maybe(
|
||||
schema.recordOf(schema.string(), schema.any(), {
|
||||
validate: (val) => {
|
||||
if (
|
||||
Object.keys(val).some(
|
||||
(key) =>
|
||||
key.match(/^compiled_inputs(\.)?/) || key.match(/^compiled_stream(\.)?/)
|
||||
)
|
||||
) {
|
||||
return 'Overrides of compiled_inputs and compiled_stream are not allowed';
|
||||
}
|
||||
},
|
||||
})
|
||||
),
|
||||
},
|
||||
{
|
||||
meta: {
|
||||
description:
|
||||
'Override settings that are defined in the package policy. The override option should be used only in unusual circumstances and not as a routine procedure.',
|
||||
},
|
||||
}
|
||||
),
|
||||
])
|
||||
),
|
||||
};
|
||||
|
||||
|
@ -142,15 +183,7 @@ export const NewPackagePolicySchema = schema.object({
|
|||
const CreatePackagePolicyProps = {
|
||||
...PackagePolicyBaseSchema,
|
||||
enabled: schema.maybe(schema.boolean()),
|
||||
package: schema.maybe(
|
||||
schema.object({
|
||||
name: schema.string(),
|
||||
title: schema.maybe(schema.string()),
|
||||
version: schema.string(),
|
||||
experimental_data_stream_features: schema.maybe(ExperimentalDataStreamFeatures),
|
||||
requires_root: schema.maybe(schema.boolean()),
|
||||
})
|
||||
),
|
||||
package: schema.maybe(PackagePolicyPackageSchema),
|
||||
inputs: schema.arrayOf(
|
||||
schema.object({
|
||||
...PackagePolicyInputsSchema,
|
||||
|
@ -161,11 +194,24 @@ const CreatePackagePolicyProps = {
|
|||
|
||||
export const CreatePackagePolicyRequestBodySchema = schema.object({
|
||||
...CreatePackagePolicyProps,
|
||||
id: schema.maybe(schema.string()),
|
||||
force: schema.maybe(schema.boolean()),
|
||||
id: schema.maybe(
|
||||
schema.string({
|
||||
meta: {
|
||||
description: 'Package policy unique identifier',
|
||||
},
|
||||
})
|
||||
),
|
||||
force: schema.maybe(
|
||||
schema.boolean({
|
||||
meta: {
|
||||
description:
|
||||
'Force package policy creation even if package is not verified, or if the agent policy is managed.',
|
||||
},
|
||||
})
|
||||
),
|
||||
});
|
||||
|
||||
const SimplifiedVarsSchema = schema.recordOf(
|
||||
export const SimplifiedVarsSchema = schema.recordOf(
|
||||
schema.string(),
|
||||
schema.nullable(
|
||||
schema.oneOf([
|
||||
|
@ -180,6 +226,55 @@ const SimplifiedVarsSchema = schema.recordOf(
|
|||
isSecretRef: schema.boolean(),
|
||||
}),
|
||||
])
|
||||
),
|
||||
{
|
||||
meta: {
|
||||
description:
|
||||
'Input/stream level variable (see integration documentation for more information)',
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
export const SimplifiedPackagePolicyInputsSchema = schema.maybe(
|
||||
schema.recordOf(
|
||||
schema.string(),
|
||||
schema.object({
|
||||
enabled: schema.maybe(
|
||||
schema.boolean({
|
||||
meta: {
|
||||
description: 'enable or disable that input, (default to true)',
|
||||
},
|
||||
})
|
||||
),
|
||||
vars: schema.maybe(SimplifiedVarsSchema),
|
||||
streams: schema.maybe(
|
||||
schema.recordOf(
|
||||
schema.string(),
|
||||
schema.object({
|
||||
enabled: schema.maybe(
|
||||
schema.boolean({
|
||||
meta: {
|
||||
description: 'enable or disable that stream, (default to true)',
|
||||
},
|
||||
})
|
||||
),
|
||||
vars: schema.maybe(SimplifiedVarsSchema),
|
||||
}),
|
||||
{
|
||||
meta: {
|
||||
description:
|
||||
'Input streams (see integration documentation to know what streams are available)',
|
||||
},
|
||||
}
|
||||
)
|
||||
),
|
||||
}),
|
||||
{
|
||||
meta: {
|
||||
description:
|
||||
'Package policy inputs (see integration documentation to know what inputs are available)',
|
||||
},
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -188,26 +283,9 @@ export const SimplifiedPackagePolicyBaseSchema = schema.object({
|
|||
name: schema.string(),
|
||||
description: schema.maybe(schema.string()),
|
||||
namespace: schema.maybe(schema.string()),
|
||||
output_id: schema.nullable(schema.maybe(schema.string())),
|
||||
output_id: schema.maybe(schema.oneOf([schema.literal(null), schema.string()])),
|
||||
vars: schema.maybe(SimplifiedVarsSchema),
|
||||
inputs: schema.maybe(
|
||||
schema.recordOf(
|
||||
schema.string(),
|
||||
schema.object({
|
||||
enabled: schema.maybe(schema.boolean()),
|
||||
vars: schema.maybe(SimplifiedVarsSchema),
|
||||
streams: schema.maybe(
|
||||
schema.recordOf(
|
||||
schema.string(),
|
||||
schema.object({
|
||||
enabled: schema.maybe(schema.boolean()),
|
||||
vars: schema.maybe(SimplifiedVarsSchema),
|
||||
})
|
||||
)
|
||||
),
|
||||
})
|
||||
)
|
||||
),
|
||||
inputs: SimplifiedPackagePolicyInputsSchema,
|
||||
});
|
||||
|
||||
export const SimplifiedPackagePolicyPreconfiguredSchema = SimplifiedPackagePolicyBaseSchema.extends(
|
||||
|
@ -221,15 +299,10 @@ export const SimplifiedPackagePolicyPreconfiguredSchema = SimplifiedPackagePolic
|
|||
|
||||
export const SimplifiedCreatePackagePolicyRequestBodySchema =
|
||||
SimplifiedPackagePolicyBaseSchema.extends({
|
||||
policy_id: schema.nullable(schema.maybe(schema.string())),
|
||||
policy_id: schema.maybe(schema.oneOf([schema.literal(null), schema.string()])),
|
||||
policy_ids: schema.maybe(schema.arrayOf(schema.string())),
|
||||
force: schema.maybe(schema.boolean()),
|
||||
package: schema.object({
|
||||
name: schema.string(),
|
||||
version: schema.string(),
|
||||
experimental_data_stream_features: schema.maybe(ExperimentalDataStreamFeatures),
|
||||
requires_root: schema.maybe(schema.boolean()),
|
||||
}),
|
||||
package: PackagePolicyPackageSchema,
|
||||
});
|
||||
|
||||
export const UpdatePackagePolicyRequestBodySchema = schema.object({
|
||||
|
@ -261,15 +334,19 @@ export const PackagePolicySchema = schema.object({
|
|||
updated_by: schema.string(),
|
||||
created_at: schema.string(),
|
||||
created_by: schema.string(),
|
||||
elasticsearch: schema.maybe(
|
||||
schema.object({
|
||||
privileges: schema.maybe(
|
||||
schema.object({
|
||||
cluster: schema.maybe(schema.arrayOf(schema.string())),
|
||||
})
|
||||
),
|
||||
})
|
||||
),
|
||||
elasticsearch: schema
|
||||
.maybe(
|
||||
schema.object({
|
||||
privileges: schema.maybe(
|
||||
schema.object({
|
||||
cluster: schema.maybe(schema.arrayOf(schema.string())),
|
||||
})
|
||||
),
|
||||
})
|
||||
)
|
||||
.extendsDeep({
|
||||
unknowns: 'allow',
|
||||
}),
|
||||
inputs: schema.arrayOf(
|
||||
schema.object({
|
||||
...PackagePolicyInputsSchema,
|
||||
|
@ -284,3 +361,46 @@ export const PackagePolicySchema = schema.object({
|
|||
)
|
||||
),
|
||||
});
|
||||
|
||||
export const PackagePolicyResponseSchema = PackagePolicySchema.extends({
|
||||
vars: schema.maybe(schema.oneOf([ConfigRecordSchema, schema.maybe(SimplifiedVarsSchema)])),
|
||||
inputs: schema.oneOf([
|
||||
schema.arrayOf(
|
||||
schema.object({
|
||||
...PackagePolicyInputsSchema,
|
||||
compiled_input: schema.maybe(schema.any()),
|
||||
})
|
||||
),
|
||||
SimplifiedPackagePolicyInputsSchema,
|
||||
]),
|
||||
spaceIds: schema.maybe(schema.arrayOf(schema.string())),
|
||||
agents: schema.maybe(schema.number()),
|
||||
});
|
||||
|
||||
export const OrphanedPackagePoliciesResponseSchema = schema.object({
|
||||
items: schema.arrayOf(PackagePolicyResponseSchema),
|
||||
total: schema.number(),
|
||||
});
|
||||
|
||||
export const DryRunPackagePolicySchema = schema.object({
|
||||
...PackagePolicyBaseSchema,
|
||||
id: schema.maybe(schema.string()),
|
||||
force: schema.maybe(schema.boolean()),
|
||||
errors: schema.maybe(
|
||||
schema.arrayOf(
|
||||
schema.object({
|
||||
message: schema.string(),
|
||||
key: schema.maybe(schema.string()),
|
||||
})
|
||||
)
|
||||
),
|
||||
missingVars: schema.maybe(schema.arrayOf(schema.string())),
|
||||
});
|
||||
|
||||
export const PackagePolicyStatusResponseSchema = schema.object({
|
||||
id: schema.string(),
|
||||
success: schema.boolean(),
|
||||
name: schema.maybe(schema.string()),
|
||||
statusCode: schema.maybe(schema.number()),
|
||||
body: schema.maybe(schema.object({ message: schema.string() })),
|
||||
});
|
||||
|
|
|
@ -23,7 +23,10 @@ export const ListWithKuerySchema = schema.object({
|
|||
});
|
||||
|
||||
export const BulkRequestBodySchema = schema.object({
|
||||
ids: schema.arrayOf(schema.string(), { minSize: 1 }),
|
||||
ids: schema.arrayOf(schema.string(), {
|
||||
minSize: 1,
|
||||
meta: { description: 'list of package policy ids' },
|
||||
}),
|
||||
ignoreMissing: schema.maybe(schema.boolean()),
|
||||
});
|
||||
|
||||
|
|
|
@ -9,6 +9,10 @@ import { schema } from '@kbn/config-schema';
|
|||
|
||||
import {
|
||||
CreatePackagePolicyRequestBodySchema,
|
||||
DryRunPackagePolicySchema,
|
||||
PackagePolicyPackageSchema,
|
||||
PackagePolicyResponseSchema,
|
||||
PackagePolicyStatusResponseSchema,
|
||||
SimplifiedCreatePackagePolicyRequestBodySchema,
|
||||
UpdatePackagePolicyRequestBodySchema,
|
||||
} from '../models';
|
||||
|
@ -59,6 +63,10 @@ export const BulkGetPackagePoliciesRequestSchema = {
|
|||
}),
|
||||
};
|
||||
|
||||
export const BulkGetPackagePoliciesResponseBodySchema = schema.object({
|
||||
items: schema.arrayOf(PackagePolicyResponseSchema),
|
||||
});
|
||||
|
||||
export const GetOnePackagePolicyRequestSchema = {
|
||||
params: schema.object({
|
||||
packagePolicyId: schema.string(),
|
||||
|
@ -71,10 +79,14 @@ export const GetOnePackagePolicyRequestSchema = {
|
|||
};
|
||||
|
||||
export const CreatePackagePolicyRequestSchema = {
|
||||
body: schema.oneOf([
|
||||
CreatePackagePolicyRequestBodySchema,
|
||||
SimplifiedCreatePackagePolicyRequestBodySchema,
|
||||
]),
|
||||
body: schema.oneOf(
|
||||
[CreatePackagePolicyRequestBodySchema, SimplifiedCreatePackagePolicyRequestBodySchema],
|
||||
{
|
||||
meta: {
|
||||
description: 'You should use inputs as an object and not use the deprecated inputs array.',
|
||||
},
|
||||
}
|
||||
),
|
||||
query: schema.object({
|
||||
format: schema.maybe(
|
||||
schema.oneOf([schema.literal(inputsFormat.Simplified), schema.literal(inputsFormat.Legacy)])
|
||||
|
@ -82,6 +94,10 @@ export const CreatePackagePolicyRequestSchema = {
|
|||
}),
|
||||
};
|
||||
|
||||
export const CreatePackagePolicyResponseSchema = schema.object({
|
||||
item: PackagePolicyResponseSchema,
|
||||
});
|
||||
|
||||
export const UpdatePackagePolicyRequestSchema = {
|
||||
...GetOnePackagePolicyRequestSchema,
|
||||
body: schema.oneOf([
|
||||
|
@ -102,6 +118,25 @@ export const DeletePackagePoliciesRequestSchema = {
|
|||
}),
|
||||
};
|
||||
|
||||
export const DeletePackagePoliciesResponseBodySchema = schema.arrayOf(
|
||||
PackagePolicyStatusResponseSchema.extends({
|
||||
policy_id: schema.maybe(
|
||||
schema.oneOf([
|
||||
schema.literal(null),
|
||||
schema.string({
|
||||
meta: {
|
||||
description: 'Use `policy_ids` instead',
|
||||
deprecated: true,
|
||||
},
|
||||
}),
|
||||
])
|
||||
),
|
||||
policy_ids: schema.arrayOf(schema.string()),
|
||||
output_id: schema.maybe(schema.oneOf([schema.literal(null), schema.string()])),
|
||||
package: PackagePolicyPackageSchema,
|
||||
})
|
||||
);
|
||||
|
||||
export const DeleteOnePackagePolicyRequestSchema = {
|
||||
params: schema.object({
|
||||
packagePolicyId: schema.string(),
|
||||
|
@ -111,15 +146,104 @@ export const DeleteOnePackagePolicyRequestSchema = {
|
|||
}),
|
||||
};
|
||||
|
||||
export const DeleteOnePackagePolicyResponseSchema = schema.object({
|
||||
id: schema.string(),
|
||||
});
|
||||
|
||||
export const UpgradePackagePoliciesRequestSchema = {
|
||||
body: schema.object({
|
||||
packagePolicyIds: schema.arrayOf(schema.string()),
|
||||
}),
|
||||
};
|
||||
|
||||
export const UpgradePackagePoliciesResponseBodySchema = schema.arrayOf(
|
||||
PackagePolicyStatusResponseSchema
|
||||
);
|
||||
|
||||
export const DryRunPackagePoliciesRequestSchema = {
|
||||
body: schema.object({
|
||||
packagePolicyIds: schema.arrayOf(schema.string()),
|
||||
packageVersion: schema.maybe(schema.string()),
|
||||
}),
|
||||
};
|
||||
|
||||
export const DryRunPackagePoliciesResponseBodySchema = schema.arrayOf(
|
||||
schema.object({
|
||||
name: schema.maybe(schema.string()),
|
||||
statusCode: schema.maybe(schema.number()),
|
||||
body: schema.maybe(schema.object({ message: schema.string() })),
|
||||
hasErrors: schema.boolean(),
|
||||
diff: schema.maybe(
|
||||
schema.arrayOf(
|
||||
schema.oneOf([
|
||||
PackagePolicyResponseSchema.extends({
|
||||
id: schema.maybe(schema.string()),
|
||||
}),
|
||||
DryRunPackagePolicySchema,
|
||||
])
|
||||
)
|
||||
),
|
||||
agent_diff: schema.maybe(
|
||||
schema.arrayOf(
|
||||
schema.arrayOf(
|
||||
schema
|
||||
.object({
|
||||
id: schema.string(),
|
||||
name: schema.string(),
|
||||
revision: schema.number(),
|
||||
type: schema.string(),
|
||||
data_stream: schema.object({
|
||||
namespace: schema.string(),
|
||||
}),
|
||||
use_output: schema.string(),
|
||||
package_policy_id: schema.string(),
|
||||
meta: schema.maybe(
|
||||
schema.object({
|
||||
package: schema
|
||||
.object({
|
||||
name: schema.string(),
|
||||
version: schema.string(),
|
||||
})
|
||||
.extendsDeep({
|
||||
// equivalent of allowing extra keys like `[key: string]: any;`
|
||||
unknowns: 'allow',
|
||||
}),
|
||||
})
|
||||
),
|
||||
streams: schema.maybe(
|
||||
schema.arrayOf(
|
||||
schema
|
||||
.object({
|
||||
id: schema.string(),
|
||||
data_stream: schema.object({
|
||||
dataset: schema.string(),
|
||||
type: schema.maybe(schema.string()),
|
||||
}),
|
||||
})
|
||||
.extendsDeep({
|
||||
unknowns: 'allow',
|
||||
})
|
||||
)
|
||||
),
|
||||
processors: schema.maybe(
|
||||
schema.arrayOf(
|
||||
schema.object({
|
||||
add_fields: schema.object({
|
||||
target: schema.string(),
|
||||
fields: schema.recordOf(
|
||||
schema.string(),
|
||||
schema.oneOf([schema.string(), schema.number()])
|
||||
),
|
||||
}),
|
||||
})
|
||||
)
|
||||
),
|
||||
})
|
||||
.extendsDeep({
|
||||
unknowns: 'allow',
|
||||
})
|
||||
)
|
||||
)
|
||||
),
|
||||
})
|
||||
);
|
||||
|
|
|
@ -41,6 +41,30 @@ export const PutSettingsRequestSchema = {
|
|||
|
||||
export const GetSpaceSettingsRequestSchema = {};
|
||||
|
||||
export const SpaceSettingsResponseSchema = schema.object({
|
||||
item: schema.object({
|
||||
managed_by: schema.maybe(schema.string()),
|
||||
allowed_namespace_prefixes: schema.arrayOf(schema.string()),
|
||||
}),
|
||||
});
|
||||
|
||||
export const SettingsResponseSchema = schema.object({
|
||||
item: schema.object({
|
||||
has_seen_add_data_notice: schema.maybe(schema.boolean()),
|
||||
fleet_server_hosts: schema.maybe(schema.arrayOf(schema.string())),
|
||||
prerelease_integrations_enabled: schema.boolean(),
|
||||
id: schema.string(),
|
||||
version: schema.maybe(schema.string()),
|
||||
preconfigured_fields: schema.maybe(schema.arrayOf(schema.literal('fleet_server_hosts'))),
|
||||
secret_storage_requirements_met: schema.maybe(schema.boolean()),
|
||||
output_secret_storage_requirements_met: schema.maybe(schema.boolean()),
|
||||
use_space_awareness_migration_status: schema.maybe(
|
||||
schema.oneOf([schema.literal('pending'), schema.literal('success'), schema.literal('error')])
|
||||
),
|
||||
use_space_awareness_migration_started_at: schema.maybe(schema.string()),
|
||||
}),
|
||||
});
|
||||
|
||||
export const PutSpaceSettingsRequestSchema = {
|
||||
body: schema.object({
|
||||
allowed_namespace_prefixes: schema.maybe(
|
||||
|
@ -64,3 +88,70 @@ export const GetEnrollmentSettingsRequestSchema = {
|
|||
})
|
||||
),
|
||||
};
|
||||
|
||||
export const GetEnrollmentSettingsResponseSchema = schema.object({
|
||||
fleet_server: schema.object({
|
||||
policies: schema.arrayOf(
|
||||
schema.object({
|
||||
id: schema.string(),
|
||||
name: schema.string(),
|
||||
is_managed: schema.boolean(),
|
||||
is_default_fleet_server: schema.maybe(schema.boolean()),
|
||||
has_fleet_server: schema.maybe(schema.boolean()),
|
||||
fleet_server_host_id: schema.maybe(schema.oneOf([schema.literal(null), schema.string()])),
|
||||
download_source_id: schema.maybe(schema.oneOf([schema.literal(null), schema.string()])),
|
||||
space_ids: schema.maybe(schema.arrayOf(schema.string())),
|
||||
})
|
||||
),
|
||||
has_active: schema.boolean(),
|
||||
host: schema.maybe(
|
||||
schema.object({
|
||||
id: schema.string(),
|
||||
name: schema.string(),
|
||||
host_urls: schema.arrayOf(schema.string()),
|
||||
is_default: schema.boolean(),
|
||||
is_preconfigured: schema.boolean(),
|
||||
is_internal: schema.maybe(schema.boolean()),
|
||||
proxy_id: schema.maybe(schema.oneOf([schema.literal(null), schema.string()])),
|
||||
})
|
||||
),
|
||||
host_proxy: schema.maybe(
|
||||
schema.object({
|
||||
id: schema.string(),
|
||||
proxy_headers: schema.maybe(
|
||||
schema.recordOf(
|
||||
schema.string(),
|
||||
schema.oneOf([schema.string(), schema.number(), schema.boolean()])
|
||||
)
|
||||
),
|
||||
name: schema.string(),
|
||||
url: schema.string(),
|
||||
certificate_authorities: schema.maybe(
|
||||
schema.oneOf([schema.literal(null), schema.string()])
|
||||
),
|
||||
certificate: schema.maybe(schema.oneOf([schema.literal(null), schema.string()])),
|
||||
certificate_key: schema.maybe(schema.oneOf([schema.literal(null), schema.string()])),
|
||||
is_preconfigured: schema.boolean(),
|
||||
})
|
||||
),
|
||||
}),
|
||||
download_source: schema.maybe(
|
||||
schema.object({
|
||||
id: schema.string(),
|
||||
name: schema.string(),
|
||||
host: schema.string(),
|
||||
is_default: schema.boolean(),
|
||||
proxy_id: schema.maybe(
|
||||
schema.oneOf([
|
||||
schema.literal(null),
|
||||
schema.string({
|
||||
meta: {
|
||||
description:
|
||||
'The ID of the proxy to use for this download source. See the proxies API for more information.',
|
||||
},
|
||||
}),
|
||||
])
|
||||
),
|
||||
})
|
||||
),
|
||||
});
|
||||
|
|
|
@ -6,17 +6,48 @@
|
|||
*/
|
||||
import { schema } from '@kbn/config-schema';
|
||||
|
||||
import { ListResponseSchema } from '../../routes/schema/utils';
|
||||
|
||||
export const GetUninstallTokensMetadataRequestSchema = {
|
||||
query: schema.object({
|
||||
policyId: schema.maybe(schema.string({ maxLength: 50 })),
|
||||
policyId: schema.maybe(
|
||||
schema.string({
|
||||
maxLength: 50,
|
||||
meta: { description: 'Partial match filtering for policy IDs' },
|
||||
})
|
||||
),
|
||||
search: schema.maybe(schema.string({ maxLength: 50 })),
|
||||
perPage: schema.maybe(schema.number({ defaultValue: 20, min: 5 })),
|
||||
perPage: schema.maybe(
|
||||
schema.number({
|
||||
defaultValue: 20,
|
||||
min: 5,
|
||||
meta: { description: 'The number of items to return' },
|
||||
})
|
||||
),
|
||||
page: schema.maybe(schema.number({ defaultValue: 1, min: 1 })),
|
||||
}),
|
||||
};
|
||||
|
||||
const UninstallTokenMetadataSchema = schema.object({
|
||||
id: schema.string(),
|
||||
policy_id: schema.string(),
|
||||
policy_name: schema.maybe(schema.oneOf([schema.literal(null), schema.string()])),
|
||||
created_at: schema.string(),
|
||||
namespaces: schema.maybe(schema.arrayOf(schema.string())),
|
||||
});
|
||||
|
||||
export const GetUninstallTokensMetadataResponseSchema = ListResponseSchema(
|
||||
UninstallTokenMetadataSchema
|
||||
);
|
||||
|
||||
export const GetUninstallTokenRequestSchema = {
|
||||
params: schema.object({
|
||||
uninstallTokenId: schema.string(),
|
||||
}),
|
||||
};
|
||||
|
||||
export const GetUninstallTokenResponseSchema = schema.object({
|
||||
item: UninstallTokenMetadataSchema.extends({
|
||||
token: schema.string(),
|
||||
}),
|
||||
});
|
||||
|
|
|
@ -239,6 +239,8 @@ export interface SettingsSOAttributes {
|
|||
fleet_server_hosts?: string[];
|
||||
secret_storage_requirements_met?: boolean;
|
||||
output_secret_storage_requirements_met?: boolean;
|
||||
use_space_awareness_migration_status?: 'pending' | 'success' | 'error';
|
||||
use_space_awareness_migration_started_at?: string | null;
|
||||
}
|
||||
|
||||
export interface SpaceSettingsSOAttributes {
|
||||
|
|
|
@ -30,7 +30,6 @@ Object {
|
|||
"enabled": true,
|
||||
"name": "system-1",
|
||||
"namespace": "default",
|
||||
"output_id": null,
|
||||
"package": Object {
|
||||
"name": "system",
|
||||
"requires_root": true,
|
||||
|
|
|
@ -198,7 +198,7 @@ export default function (providerContext: FtrProviderContext) {
|
|||
},
|
||||
})
|
||||
.expect(200);
|
||||
expect(response.body.item.policy_id).to.eql(null);
|
||||
expect(response.body.item.policy_id).to.eql(undefined);
|
||||
expect(response.body.item.policy_ids).to.eql([]);
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue