diff --git a/x-pack/plugins/ingest_manager/common/openapi/spec_oas3.json b/x-pack/plugins/ingest_manager/common/openapi/spec_oas3.json index a780ae5599793..329137b063e66 100644 --- a/x-pack/plugins/ingest_manager/common/openapi/spec_oas3.json +++ b/x-pack/plugins/ingest_manager/common/openapi/spec_oas3.json @@ -3520,6 +3520,172 @@ } } }, + "/fleet/agents/{agentId}/upgrade": { + "parameters": [ + { + "schema": { + "type": "string" + }, + "name": "agentId", + "in": "path", + "required": true + } + ], + "post": { + "summary": "Fleet - Agent - Upgrade", + "tags": [], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpgradeAgent" + }, + "examples": { + "success": { + "value": {} + } + } + } + } + }, + "400": { + "description": "BAD REQUEST", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpgradeAgent" + }, + "examples": { + "bad request not upgradeable": { + "value": { + "statusCode": 400, + "error": "Bad Request", + "message": "agent d133b07d-5c2b-42f0-8e6b-bbae53bdce88 is not upgradeable" + } + }, + "bad request kibana version": { + "value": { + "statusCode": 400, + "error": "Bad Request", + "message": "cannot upgrade agent to 8.0.0 because it is different than the installed kibana version 7.9.10" + } + }, + "bad request agent unenrolling": { + "value": { + "statusCode": 400, + "error": "Bad Request", + "message": "cannot upgrade an unenrolling or unenrolled agent" + } + } + } + } + } + } + }, + "operationId": "post-fleet-agents-upgrade", + "parameters": [ + { + "$ref": "#/components/parameters/xsrfHeader" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpgradeAgent" + }, + "examples":{ + "version":{ + "value": { + "version": "8.0.0" + } + }, + "version and source_uri":{ + "value": { + "version": "8.0.0", + "source_uri": "http://localhost:8000" + } + } + } + } + } + } + } + }, + "/fleet/agents/bulk_upgrade": { + "post": { + "summary": "Fleet - Agent - Bulk Upgrade", + "tags": [], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BulkUpgradeAgents" + }, + "examples": { + "success": { + "value": {} + } + } + } + } + }, + "400": { + "description": "BAD REQUEST", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpgradeAgent" + }, + "examples": { + "bad request kibana version": { + "value": { + "statusCode": 400, + "error": "Bad Request", + "message": "cannot upgrade agent to 8.0.0 because it is different than the installed kibana version 7.9.10" + } + } + } + } + } + } + }, + "operationId": "post-fleet-agents-bulk-upgrade", + "parameters": [ + { + "$ref": "#/components/parameters/xsrfHeader" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BulkUpgradeAgents" + }, + "examples":{ + "version":{ + "value": { + "version": "8.0.0" + } + }, + "version and source_uri":{ + "value": { + "version": "8.0.0", + "source_uri": "http://localhost:8000" + } + } + } + } + } + } + } + }, "/fleet/agent-status": { "get": { "summary": "Fleet - Agent - Status for policy", @@ -4226,8 +4392,88 @@ "type": "string", "title": "EnrollmentApiKey", "format": "byte" + }, + "UpgradeAgent":{ + "title": "UpgradeAgent", + "oneOf": [ + { + "type": "object", + "properties": { + "version": { + "type": "string" + } + }, + "required": ["version"] + }, + { + "type": "object", + "properties": { + "version": { + "type": "string" + }, + "source_uri": { + "type": "string" + } + }, + "required": ["version"] + } + ] + }, + "BulkUpgradeAgents":{ + "title": "BulkUpgradeAgents", + "oneOf": [ + { + "type": "object", + "properties": { + "version": { + "type": "string" + }, + "agents":{ + "type": "array", + "items":{ + "type": "string" + } + } + }, + "required": ["version", "agents"] + }, + { + "type": "object", + "properties": { + "version": { + "type": "string" + }, + "source_uri": { + "type": "string" + }, + "agents":{ + "type": "array", + "items":{ + "type": "string" + } + } + }, + "required": ["version", "agents"] + }, + { + "type": "object", + "properties": { + "version": { + "type": "string" + }, + "source_uri": { + "type": "string" + }, + "agents":{ + "type": "string" + } + }, + "required": ["version", "agents"] + } + ] } }, + "parameters": { "pageSizeParam": { "name": "perPage", diff --git a/x-pack/plugins/ingest_manager/server/routes/agent/upgrade_handler.ts b/x-pack/plugins/ingest_manager/server/routes/agent/upgrade_handler.ts index c4aa33999cf22..9c6b50b6d8f09 100644 --- a/x-pack/plugins/ingest_manager/server/routes/agent/upgrade_handler.ts +++ b/x-pack/plugins/ingest_manager/server/routes/agent/upgrade_handler.ts @@ -16,6 +16,8 @@ import * as AgentService from '../../services/agents'; import { appContextService } from '../../services'; import { defaultIngestErrorHandler } from '../../errors'; import { AGENT_SAVED_OBJECT_TYPE } from '../../constants'; +import { savedObjectToAgent } from '../../services/agents/saved_objects'; +import { isAgentUpgradeable } from '../../../common/services'; export const postAgentUpgradeHandler: RequestHandler< TypeOf, @@ -35,15 +37,25 @@ export const postAgentUpgradeHandler: RequestHandler< }, }); } - const agent = await soClient.get( + const agentSO = await soClient.get( AGENT_SAVED_OBJECT_TYPE, request.params.agentId ); - if (agent.attributes.unenrollment_started_at || agent.attributes.unenrolled_at) { + if (agentSO.attributes.unenrollment_started_at || agentSO.attributes.unenrolled_at) { return response.customError({ statusCode: 400, body: { - message: `cannot upgrade an unenrolling or unenrolled agent`, + message: 'cannot upgrade an unenrolling or unenrolled agent', + }, + }); + } + + const agent = savedObjectToAgent(agentSO); + if (!isAgentUpgradeable(agent, kibanaVersion)) { + return response.customError({ + statusCode: 400, + body: { + message: `agent ${request.params.agentId} is not upgradeable`, }, }); } diff --git a/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/upgrade.ts b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/upgrade.ts index 04e32b2b80f56..ed0d6ff97e986 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/upgrade.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/upgrade.ts @@ -29,6 +29,13 @@ export default function (providerContext: FtrProviderContext) { it('should respond 200 to upgrade agent and update the agent SO', async () => { const kibanaVersion = await kibanaServer.version.get(); + await kibanaServer.savedObjects.update({ + id: 'agent1', + type: AGENT_SAVED_OBJECT_TYPE, + attributes: { + local_metadata: { elastic: { agent: { upgradeable: true, version: '0.0.0' } } }, + }, + }); await supertest .post(`/api/ingest_manager/fleet/agents/agent1/upgrade`) .set('kbn-xsrf', 'xxx') @@ -45,6 +52,13 @@ export default function (providerContext: FtrProviderContext) { }); it('should respond 200 to upgrade agent and update the agent SO without source_uri', async () => { const kibanaVersion = await kibanaServer.version.get(); + await kibanaServer.savedObjects.update({ + id: 'agent1', + type: AGENT_SAVED_OBJECT_TYPE, + attributes: { + local_metadata: { elastic: { agent: { upgradeable: true, version: '0.0.0' } } }, + }, + }); await supertest .post(`/api/ingest_manager/fleet/agents/agent1/upgrade`) .set('kbn-xsrf', 'xxx') @@ -102,8 +116,21 @@ export default function (providerContext: FtrProviderContext) { .expect(400); }); + it('should respond 400 if trying to upgrade an agent that is not upgradeable', async () => { + const kibanaVersion = await kibanaServer.version.get(); + const res = await supertest + .post(`/api/ingest_manager/fleet/agents/agent1/upgrade`) + .set('kbn-xsrf', 'xxx') + .send({ + version: kibanaVersion, + }) + .expect(400); + expect(res.body.message).to.equal('agent agent1 is not upgradeable'); + }); + it('should respond 200 to bulk upgrade agents and update the agent SOs', async () => { const kibanaVersion = await kibanaServer.version.get(); + await supertest .post(`/api/ingest_manager/fleet/agents/bulk_upgrade`) .set('kbn-xsrf', 'xxx')