[Fleet] Add force option to DELETE package endpoint. (#95051)
* Add force option to DELETE package endpoint. * Add integration test. * Adjust openapi spec. * Run EPM tests before fleet setup tests. * Run package delete tests first in EPM tests
This commit is contained in:
parent
0551472cd9
commit
2e5b5debb5
|
@ -1633,7 +1633,21 @@
|
|||
{
|
||||
"$ref": "#/paths/~1setup/post/parameters/0"
|
||||
}
|
||||
]
|
||||
],
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"force": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/agents/{agentId}": {
|
||||
|
|
|
@ -1038,6 +1038,14 @@ paths:
|
|||
operationId: post-epm-delete-pkgkey
|
||||
parameters:
|
||||
- $ref: '#/paths/~1setup/post/parameters/0'
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
force:
|
||||
type: boolean
|
||||
'/agents/{agentId}':
|
||||
parameters:
|
||||
- schema:
|
||||
|
|
|
@ -89,3 +89,11 @@ delete:
|
|||
operationId: post-epm-delete-pkgkey
|
||||
parameters:
|
||||
- $ref: ../components/headers/kbn_xsrf.yaml
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
force:
|
||||
type: boolean
|
||||
|
|
|
@ -310,13 +310,20 @@ export const installPackageByUploadHandler: RequestHandler<
|
|||
};
|
||||
|
||||
export const deletePackageHandler: RequestHandler<
|
||||
TypeOf<typeof DeletePackageRequestSchema.params>
|
||||
TypeOf<typeof DeletePackageRequestSchema.params>,
|
||||
undefined,
|
||||
TypeOf<typeof DeletePackageRequestSchema.body>
|
||||
> = async (context, request, response) => {
|
||||
try {
|
||||
const { pkgkey } = request.params;
|
||||
const savedObjectsClient = context.core.savedObjects.client;
|
||||
const esClient = context.core.elasticsearch.client.asCurrentUser;
|
||||
const res = await removeInstallation({ savedObjectsClient, pkgkey, esClient });
|
||||
const res = await removeInstallation({
|
||||
savedObjectsClient,
|
||||
pkgkey,
|
||||
esClient,
|
||||
force: request.body?.force,
|
||||
});
|
||||
const body: DeletePackageResponse = {
|
||||
response: res,
|
||||
};
|
||||
|
|
|
@ -32,13 +32,14 @@ export async function removeInstallation(options: {
|
|||
savedObjectsClient: SavedObjectsClientContract;
|
||||
pkgkey: string;
|
||||
esClient: ElasticsearchClient;
|
||||
force?: boolean;
|
||||
}): Promise<AssetReference[]> {
|
||||
const { savedObjectsClient, pkgkey, esClient } = options;
|
||||
const { savedObjectsClient, pkgkey, esClient, force } = options;
|
||||
// TODO: the epm api should change to /name/version so we don't need to do this
|
||||
const { pkgName, pkgVersion } = splitPkgKey(pkgkey);
|
||||
const installation = await getInstallation({ savedObjectsClient, pkgName });
|
||||
if (!installation) throw Boom.badRequest(`${pkgName} is not installed`);
|
||||
if (installation.removable === false)
|
||||
if (installation.removable === false && !force)
|
||||
throw Boom.badRequest(`${pkgName} is installed by default and cannot be removed`);
|
||||
|
||||
const { total } = await packagePolicyService.list(savedObjectsClient, {
|
||||
|
|
|
@ -65,4 +65,9 @@ export const DeletePackageRequestSchema = {
|
|||
params: schema.object({
|
||||
pkgkey: schema.string(),
|
||||
}),
|
||||
body: schema.nullable(
|
||||
schema.object({
|
||||
force: schema.boolean(),
|
||||
})
|
||||
),
|
||||
};
|
||||
|
|
54
x-pack/test/fleet_api_integration/apis/epm/delete.ts
Normal file
54
x-pack/test/fleet_api_integration/apis/epm/delete.ts
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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 { FtrProviderContext } from '../../../api_integration/ftr_provider_context';
|
||||
import { skipIfNoDockerRegistry } from '../../helpers';
|
||||
|
||||
export default function (providerContext: FtrProviderContext) {
|
||||
const { getService } = providerContext;
|
||||
const supertest = getService('supertest');
|
||||
const requiredPackage = 'system-0.11.0';
|
||||
|
||||
const installPackage = async (pkgkey: string) => {
|
||||
await supertest
|
||||
.post(`/api/fleet/epm/packages/${pkgkey}`)
|
||||
.set('kbn-xsrf', 'xxxx')
|
||||
.send({ force: true });
|
||||
};
|
||||
|
||||
const deletePackage = async (pkgkey: string) => {
|
||||
await supertest
|
||||
.delete(`/api/fleet/epm/packages/${pkgkey}`)
|
||||
.set('kbn-xsrf', 'xxxx')
|
||||
.send({ force: true });
|
||||
};
|
||||
|
||||
describe('delete and force delete scenarios', async () => {
|
||||
skipIfNoDockerRegistry(providerContext);
|
||||
before(async () => {
|
||||
await installPackage(requiredPackage);
|
||||
});
|
||||
after(async () => {
|
||||
await deletePackage(requiredPackage);
|
||||
});
|
||||
|
||||
it('should return 400 if trying to uninstall a required package', async function () {
|
||||
await supertest
|
||||
.delete(`/api/fleet/epm/packages/${requiredPackage}`)
|
||||
.set('kbn-xsrf', 'xxxx')
|
||||
.expect(400);
|
||||
});
|
||||
|
||||
it('should return 200 if trying to force uninstall a required package', async function () {
|
||||
await supertest
|
||||
.delete(`/api/fleet/epm/packages/${requiredPackage}`)
|
||||
.set('kbn-xsrf', 'xxxx')
|
||||
.send({ force: true })
|
||||
.expect(200);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
export default function loadTests({ loadTestFile }) {
|
||||
describe('EPM Endpoints', () => {
|
||||
loadTestFile(require.resolve('./delete'));
|
||||
loadTestFile(require.resolve('./list'));
|
||||
loadTestFile(require.resolve('./setup'));
|
||||
loadTestFile(require.resolve('./get'));
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
export default function ({ loadTestFile }) {
|
||||
describe('Fleet Endpoints', function () {
|
||||
this.tags('ciGroup10');
|
||||
// EPM
|
||||
loadTestFile(require.resolve('./epm/index'));
|
||||
|
||||
// Fleet setup
|
||||
loadTestFile(require.resolve('./fleet_setup'));
|
||||
|
||||
|
@ -30,9 +33,6 @@ export default function ({ loadTestFile }) {
|
|||
// Enrollment API keys
|
||||
loadTestFile(require.resolve('./enrollment_api_keys/crud'));
|
||||
|
||||
// EPM
|
||||
loadTestFile(require.resolve('./epm/index'));
|
||||
|
||||
// Package policies
|
||||
loadTestFile(require.resolve('./package_policy/create'));
|
||||
loadTestFile(require.resolve('./package_policy/update'));
|
||||
|
|
Loading…
Reference in a new issue