[Fleet] Add single agent migration endpoint (#220601)

## Summary

Closes #217617 

Adds a new endpoint `POST kbn:/api/fleet/agents/{agentId}/migrate`
allowing a user to migrate a single agent to another cluster.

Required parameters are: `enrollment_token` and `uri`

- Adds `MIGRATE` as an action type and is reflected in UI
- Includes unit tests as well as integration tests 



### Checklist

Check the PR satisfies following conditions. 

Reviewers should verify this PR satisfies this list as well.

- [ ] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)
- [ ]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [ ] [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
- [ ] If a plugin configuration key changed, check if it needs to be
allowlisted in the cloud and added to the [docker
list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)
- [ ] This was checked for breaking HTTP API changes, and any breaking
changes have been approved by the breaking-change committee. The
`release_note:breaking` label should be applied in these situations.
- [ ] [Flaky Test
Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was
used on any tests changed
- [ ] The PR description includes the appropriate Release Notes section,
and the correct `release_note:*` label is applied per the
[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)

### Identify risks

N/A

# Release Note

- Added endpoint allowing a user to migrate an individual agent to
another cluster by specifying the URL and Enrollment Token. Note: tamper
protected and fleet agents can not be migrated and attempting to do so
will return a `403` status code.

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
Mason Herron 2025-05-28 11:04:13 -06:00 committed by GitHub
parent 5b2fa54b4e
commit ca2770f10f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 1238 additions and 5 deletions

View file

@ -20181,7 +20181,8 @@
"REQUEST_DIAGNOSTICS",
"UPDATE_TAGS",
"POLICY_CHANGE",
"INPUT_ACTION"
"INPUT_ACTION",
"MIGRATE"
],
"type": "string"
},
@ -22678,6 +22679,163 @@
]
}
},
"/api/fleet/agents/{agentId}/migrate": {
"post": {
"description": "Migrate a single agent to another cluster.<br/><br/>[Required authorization] Route required privileges: fleet-agents-all.",
"operationId": "post-fleet-agents-agentid-migrate",
"parameters": [
{
"description": "A required header to protect against CSRF attacks",
"in": "header",
"name": "kbn-xsrf",
"required": true,
"schema": {
"example": "true",
"type": "string"
}
},
{
"in": "path",
"name": "agentId",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"additionalProperties": false,
"properties": {
"enrollment_token": {
"type": "string"
},
"settings": {
"additionalProperties": false,
"properties": {
"ca_sha256": {
"type": "string"
},
"certificate_authorities": {
"type": "string"
},
"elastic_agent_cert": {
"type": "string"
},
"elastic_agent_cert_key": {
"type": "string"
},
"elastic_agent_cert_key_passphrase": {
"type": "string"
},
"headers": {
"additionalProperties": {
"type": "string"
},
"type": "object"
},
"insecure": {
"type": "boolean"
},
"proxy_disabled": {
"type": "boolean"
},
"proxy_headers": {
"additionalProperties": {
"type": "string"
},
"type": "object"
},
"proxy_url": {
"type": "string"
},
"replace_token": {
"type": "boolean"
},
"staging": {
"type": "boolean"
},
"tags": {
"items": {
"type": "string"
},
"type": "array"
}
},
"type": "object"
},
"uri": {
"format": "uri",
"type": "string"
}
},
"required": [
"uri",
"enrollment_token"
],
"type": "object"
}
}
}
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"additionalProperties": false,
"properties": {
"actionId": {
"type": "string"
}
},
"required": [
"actionId"
],
"type": "object"
}
}
}
},
"400": {
"content": {
"application/json": {
"schema": {
"additionalProperties": false,
"description": "Generic Error",
"properties": {
"attributes": {},
"error": {
"type": "string"
},
"errorType": {
"type": "string"
},
"message": {
"type": "string"
},
"statusCode": {
"type": "number"
}
},
"required": [
"message",
"attributes"
],
"type": "object"
}
}
}
}
},
"summary": "Migrate a single agent",
"tags": [
"Elastic Agents"
]
}
},
"/api/fleet/agents/{agentId}/reassign": {
"post": {
"description": "[Required authorization] Route required privileges: fleet-agents-all.",

View file

@ -20181,7 +20181,8 @@
"REQUEST_DIAGNOSTICS",
"UPDATE_TAGS",
"POLICY_CHANGE",
"INPUT_ACTION"
"INPUT_ACTION",
"MIGRATE"
],
"type": "string"
},
@ -22678,6 +22679,163 @@
]
}
},
"/api/fleet/agents/{agentId}/migrate": {
"post": {
"description": "Migrate a single agent to another cluster.<br/><br/>[Required authorization] Route required privileges: fleet-agents-all.",
"operationId": "post-fleet-agents-agentid-migrate",
"parameters": [
{
"description": "A required header to protect against CSRF attacks",
"in": "header",
"name": "kbn-xsrf",
"required": true,
"schema": {
"example": "true",
"type": "string"
}
},
{
"in": "path",
"name": "agentId",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"additionalProperties": false,
"properties": {
"enrollment_token": {
"type": "string"
},
"settings": {
"additionalProperties": false,
"properties": {
"ca_sha256": {
"type": "string"
},
"certificate_authorities": {
"type": "string"
},
"elastic_agent_cert": {
"type": "string"
},
"elastic_agent_cert_key": {
"type": "string"
},
"elastic_agent_cert_key_passphrase": {
"type": "string"
},
"headers": {
"additionalProperties": {
"type": "string"
},
"type": "object"
},
"insecure": {
"type": "boolean"
},
"proxy_disabled": {
"type": "boolean"
},
"proxy_headers": {
"additionalProperties": {
"type": "string"
},
"type": "object"
},
"proxy_url": {
"type": "string"
},
"replace_token": {
"type": "boolean"
},
"staging": {
"type": "boolean"
},
"tags": {
"items": {
"type": "string"
},
"type": "array"
}
},
"type": "object"
},
"uri": {
"format": "uri",
"type": "string"
}
},
"required": [
"uri",
"enrollment_token"
],
"type": "object"
}
}
}
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"additionalProperties": false,
"properties": {
"actionId": {
"type": "string"
}
},
"required": [
"actionId"
],
"type": "object"
}
}
}
},
"400": {
"content": {
"application/json": {
"schema": {
"additionalProperties": false,
"description": "Generic Error",
"properties": {
"attributes": {},
"error": {
"type": "string"
},
"errorType": {
"type": "string"
},
"message": {
"type": "string"
},
"statusCode": {
"type": "number"
}
},
"required": [
"message",
"attributes"
],
"type": "object"
}
}
}
}
},
"summary": "Migrate a single agent",
"tags": [
"Elastic Agents"
]
}
},
"/api/fleet/agents/{agentId}/reassign": {
"post": {
"description": "[Required authorization] Route required privileges: fleet-agents-all.",

View file

@ -23811,6 +23811,109 @@ paths:
summary: Create an agent action
tags:
- Elastic Agent actions
/api/fleet/agents/{agentId}/migrate:
post:
description: 'Migrate a single agent to another cluster.<br/><br/>[Required authorization] Route required privileges: fleet-agents-all.'
operationId: post-fleet-agents-agentid-migrate
parameters:
- description: A required header to protect against CSRF attacks
in: header
name: kbn-xsrf
required: true
schema:
example: 'true'
type: string
- in: path
name: agentId
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
additionalProperties: false
type: object
properties:
enrollment_token:
type: string
settings:
additionalProperties: false
type: object
properties:
ca_sha256:
type: string
certificate_authorities:
type: string
elastic_agent_cert:
type: string
elastic_agent_cert_key:
type: string
elastic_agent_cert_key_passphrase:
type: string
headers:
additionalProperties:
type: string
type: object
insecure:
type: boolean
proxy_disabled:
type: boolean
proxy_headers:
additionalProperties:
type: string
type: object
proxy_url:
type: string
replace_token:
type: boolean
staging:
type: boolean
tags:
items:
type: string
type: array
uri:
format: uri
type: string
required:
- uri
- enrollment_token
responses:
'200':
content:
application/json:
schema:
additionalProperties: false
type: object
properties:
actionId:
type: string
required:
- actionId
'400':
content:
application/json:
schema:
additionalProperties: false
description: Generic Error
type: object
properties:
attributes: {}
error:
type: string
errorType:
type: string
message:
type: string
statusCode:
type: number
required:
- message
- attributes
summary: Migrate a single agent
tags:
- Elastic Agents
/api/fleet/agents/{agentId}/reassign:
post:
description: '[Required authorization] Route required privileges: fleet-agents-all.'
@ -24236,6 +24339,7 @@ paths:
- UPDATE_TAGS
- POLICY_CHANGE
- INPUT_ACTION
- MIGRATE
type: string
version:
description: agent version number (UPGRADE action)

View file

@ -26053,6 +26053,109 @@ paths:
summary: Create an agent action
tags:
- Elastic Agent actions
/api/fleet/agents/{agentId}/migrate:
post:
description: 'Migrate a single agent to another cluster.<br/><br/>[Required authorization] Route required privileges: fleet-agents-all.'
operationId: post-fleet-agents-agentid-migrate
parameters:
- description: A required header to protect against CSRF attacks
in: header
name: kbn-xsrf
required: true
schema:
example: 'true'
type: string
- in: path
name: agentId
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
additionalProperties: false
type: object
properties:
enrollment_token:
type: string
settings:
additionalProperties: false
type: object
properties:
ca_sha256:
type: string
certificate_authorities:
type: string
elastic_agent_cert:
type: string
elastic_agent_cert_key:
type: string
elastic_agent_cert_key_passphrase:
type: string
headers:
additionalProperties:
type: string
type: object
insecure:
type: boolean
proxy_disabled:
type: boolean
proxy_headers:
additionalProperties:
type: string
type: object
proxy_url:
type: string
replace_token:
type: boolean
staging:
type: boolean
tags:
items:
type: string
type: array
uri:
format: uri
type: string
required:
- uri
- enrollment_token
responses:
'200':
content:
application/json:
schema:
additionalProperties: false
type: object
properties:
actionId:
type: string
required:
- actionId
'400':
content:
application/json:
schema:
additionalProperties: false
description: Generic Error
type: object
properties:
attributes: {}
error:
type: string
errorType:
type: string
message:
type: string
statusCode:
type: number
required:
- message
- attributes
summary: Migrate a single agent
tags:
- Elastic Agents
/api/fleet/agents/{agentId}/reassign:
post:
description: '[Required authorization] Route required privileges: fleet-agents-all.'
@ -26478,6 +26581,7 @@ paths:
- UPDATE_TAGS
- POLICY_CHANGE
- INPUT_ACTION
- MIGRATE
type: string
version:
description: agent version number (UPGRADE action)