From f2bf8c9ea70f9128b1c9130faa28a608b196f8fa Mon Sep 17 00:00:00 2001 From: Sandra Gonzales Date: Mon, 2 Nov 2020 13:11:53 -0500 Subject: [PATCH] [Fleet] add force flag to upgrade agents api (#82178) * add force flag to upgrade agents api * use 1.0.0 as version that wont match to see if test passes --- .../server/routes/agent/upgrade_handler.ts | 8 +- .../server/services/agents/upgrade.ts | 6 +- .../server/types/rest_spec/agent.ts | 2 + .../apis/fleet/agents/upgrade.ts | 86 +++++++++++++++++++ 4 files changed, 98 insertions(+), 4 deletions(-) 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 60dc7c6ee5f2b..6224c44a329c6 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 @@ -26,7 +26,7 @@ export const postAgentUpgradeHandler: RequestHandler< TypeOf > = async (context, request, response) => { const soClient = context.core.savedObjects.client; - const { version, source_uri: sourceUri } = request.body; + const { version, source_uri: sourceUri, force } = request.body; const kibanaVersion = appContextService.getKibanaVersion(); try { checkVersionIsSame(version, kibanaVersion); @@ -53,7 +53,7 @@ export const postAgentUpgradeHandler: RequestHandler< } const agent = savedObjectToAgent(agentSO); - if (!isAgentUpgradeable(agent, kibanaVersion)) { + if (!force && !isAgentUpgradeable(agent, kibanaVersion)) { return response.customError({ statusCode: 400, body: { @@ -83,7 +83,7 @@ export const postBulkAgentsUpgradeHandler: RequestHandler< TypeOf > = async (context, request, response) => { const soClient = context.core.savedObjects.client; - const { version, source_uri: sourceUri, agents } = request.body; + const { version, source_uri: sourceUri, agents, force } = request.body; const kibanaVersion = appContextService.getKibanaVersion(); try { checkVersionIsSame(version, kibanaVersion); @@ -102,12 +102,14 @@ export const postBulkAgentsUpgradeHandler: RequestHandler< agentIds: agents, sourceUri, version, + force, }); } else { await AgentService.sendUpgradeAgentsActions(soClient, { kuery: agents, sourceUri, version, + force, }); } diff --git a/x-pack/plugins/ingest_manager/server/services/agents/upgrade.ts b/x-pack/plugins/ingest_manager/server/services/agents/upgrade.ts index 2e77f069b0956..cf83a938d3c39 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/upgrade.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/upgrade.ts @@ -64,11 +64,13 @@ export async function sendUpgradeAgentsActions( agentIds: string[]; sourceUri: string | undefined; version: string; + force?: boolean; } | { kuery: string; sourceUri: string | undefined; version: string; + force?: boolean; } ) { const kibanaVersion = appContextService.getKibanaVersion(); @@ -82,7 +84,9 @@ export async function sendUpgradeAgentsActions( showInactive: false, }) ).agents; - const agentsToUpdate = agents.filter((agent) => isAgentUpgradeable(agent, kibanaVersion)); + const agentsToUpdate = options.force + ? agents + : agents.filter((agent) => isAgentUpgradeable(agent, kibanaVersion)); const now = new Date().toISOString(); const data = { version: options.version, diff --git a/x-pack/plugins/ingest_manager/server/types/rest_spec/agent.ts b/x-pack/plugins/ingest_manager/server/types/rest_spec/agent.ts index 4fd1f3f3e1573..6de94cd9c936d 100644 --- a/x-pack/plugins/ingest_manager/server/types/rest_spec/agent.ts +++ b/x-pack/plugins/ingest_manager/server/types/rest_spec/agent.ts @@ -188,6 +188,7 @@ export const PostAgentUpgradeRequestSchema = { body: schema.object({ source_uri: schema.maybe(schema.string()), version: schema.string(), + force: schema.maybe(schema.boolean()), }), }; @@ -196,6 +197,7 @@ export const PostBulkAgentUpgradeRequestSchema = { agents: schema.oneOf([schema.arrayOf(schema.string()), schema.string()]), source_uri: schema.maybe(schema.string()), version: schema.string(), + force: schema.maybe(schema.boolean()), }), }; 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 c5426168eb78f..12d7780ad50d4 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 @@ -70,6 +70,25 @@ export default function (providerContext: FtrProviderContext) { }) .expect(400); }); + it('should respond 200 if upgrading agent with version the same as snapshot version and force flag is passed', async () => { + const kibanaVersion = await kibanaServer.version.get(); + const kibanaVersionSnapshot = makeSnapshotVersion(kibanaVersion); + await kibanaServer.savedObjects.update({ + id: 'agent1', + type: AGENT_SAVED_OBJECT_TYPE, + attributes: { + local_metadata: { elastic: { agent: { upgradeable: true, version: kibanaVersion } } }, + }, + }); + await supertest + .post(`/api/fleet/agents/agent1/upgrade`) + .set('kbn-xsrf', 'xxx') + .send({ + version: kibanaVersionSnapshot, + force: true, + }) + .expect(200); + }); it('should respond 200 if upgrading agent with version less than kibana snapshot version', async () => { const kibanaVersion = await kibanaServer.version.get(); const kibanaVersionSnapshot = makeSnapshotVersion(kibanaVersion); @@ -340,5 +359,72 @@ export default function (providerContext: FtrProviderContext) { expect(typeof agent2data.body.item.upgrade_started_at).to.be('undefined'); expect(typeof agent3data.body.item.upgrade_started_at).to.be('undefined'); }); + it('should upgrade a non upgradeable agent during bulk_upgrade with force flag', 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 kibanaServer.savedObjects.update({ + id: 'agent2', + type: AGENT_SAVED_OBJECT_TYPE, + attributes: { + local_metadata: { + elastic: { agent: { upgradeable: true, version: semver.inc(kibanaVersion, 'patch') } }, + }, + }, + }); + await kibanaServer.savedObjects.update({ + id: 'agent3', + type: AGENT_SAVED_OBJECT_TYPE, + attributes: { + local_metadata: { elastic: { agent: { upgradeable: false, version: '0.0.0' } } }, + }, + }); + await supertest + .post(`/api/fleet/agents/bulk_upgrade`) + .set('kbn-xsrf', 'xxx') + .send({ + agents: ['agent1', 'agent2', 'agent3'], + version: kibanaVersion, + force: true, + }); + const [agent1data, agent2data, agent3data] = await Promise.all([ + supertest.get(`/api/fleet/agents/agent1`).set('kbn-xsrf', 'xxx'), + supertest.get(`/api/fleet/agents/agent2`).set('kbn-xsrf', 'xxx'), + supertest.get(`/api/fleet/agents/agent3`).set('kbn-xsrf', 'xxx'), + ]); + expect(typeof agent1data.body.item.upgrade_started_at).to.be('string'); + expect(typeof agent2data.body.item.upgrade_started_at).to.be('string'); + expect(typeof agent3data.body.item.upgrade_started_at).to.be('string'); + }); + it('should respond 400 if trying to bulk upgrade to a version that does not match installed kibana version', async () => { + await kibanaServer.savedObjects.update({ + id: 'agent1', + type: AGENT_SAVED_OBJECT_TYPE, + attributes: { + local_metadata: { elastic: { agent: { upgradeable: true, version: '0.0.0' } } }, + }, + }); + await kibanaServer.savedObjects.update({ + id: 'agent2', + type: AGENT_SAVED_OBJECT_TYPE, + attributes: { + local_metadata: { elastic: { agent: { upgradeable: true, version: '0.0.0' } } }, + }, + }); + await supertest + .post(`/api/fleet/agents/bulk_upgrade`) + .set('kbn-xsrf', 'xxx') + .send({ + agents: ['agent1', 'agent2'], + version: '1.0.0', + force: true, + }) + .expect(400); + }); }); }