mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 18:51:07 -04:00
[Fleet] enable feature flag enableSyncIntegrationsOnRemote (#220215)
## Summary Closes https://github.com/elastic/kibana/issues/217490 - Enable feature flag `enableSyncIntegrationsOnRemote` - Added check to hide sync integrations feature in serverless - Moved creating the follower index from Fleet setup to output create/update API and async task (create if does not exist) - Follower index is not hidden for now, because if hidden, it's not showing up on the CCR UI --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
013384e06d
commit
d65f9c5d25
18 changed files with 1276 additions and 147 deletions
|
@ -45110,6 +45110,339 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
"/api/fleet/remote_synced_integrations/status": {
|
||||
"get": {
|
||||
"description": "[Required authorization] Route required privileges: fleet-settings-read AND integrations-read.",
|
||||
"operationId": "get-fleet-remote-synced-integrations-status",
|
||||
"parameters": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"custom_assets": {
|
||||
"additionalProperties": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"error": {
|
||||
"type": "string"
|
||||
},
|
||||
"is_deleted": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"package_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"package_version": {
|
||||
"type": "string"
|
||||
},
|
||||
"sync_status": {
|
||||
"enum": [
|
||||
"completed",
|
||||
"synchronizing",
|
||||
"failed",
|
||||
"warning"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type",
|
||||
"name",
|
||||
"package_name",
|
||||
"package_version",
|
||||
"sync_status"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"error": {
|
||||
"type": "string"
|
||||
},
|
||||
"integrations": {
|
||||
"items": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"error": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"install_status": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"main": {
|
||||
"type": "string"
|
||||
},
|
||||
"remote": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"main"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"package_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"package_version": {
|
||||
"type": "string"
|
||||
},
|
||||
"sync_status": {
|
||||
"enum": [
|
||||
"completed",
|
||||
"synchronizing",
|
||||
"failed",
|
||||
"warning"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"warning": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"sync_status",
|
||||
"install_status"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"warning": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"integrations"
|
||||
],
|
||||
"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": "Get CCR Remote synced integrations status",
|
||||
"tags": [
|
||||
"CCR Remote synced integrations"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/fleet/remote_synced_integrations/{outputId}/remote_status": {
|
||||
"get": {
|
||||
"description": "[Required authorization] Route required privileges: fleet-settings-read AND integrations-read.",
|
||||
"operationId": "get-fleet-remote-synced-integrations-outputid-remote-status",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "path",
|
||||
"name": "outputId",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"custom_assets": {
|
||||
"additionalProperties": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"error": {
|
||||
"type": "string"
|
||||
},
|
||||
"is_deleted": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"package_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"package_version": {
|
||||
"type": "string"
|
||||
},
|
||||
"sync_status": {
|
||||
"enum": [
|
||||
"completed",
|
||||
"synchronizing",
|
||||
"failed",
|
||||
"warning"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type",
|
||||
"name",
|
||||
"package_name",
|
||||
"package_version",
|
||||
"sync_status"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"error": {
|
||||
"type": "string"
|
||||
},
|
||||
"integrations": {
|
||||
"items": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"error": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"install_status": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"main": {
|
||||
"type": "string"
|
||||
},
|
||||
"remote": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"main"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"package_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"package_version": {
|
||||
"type": "string"
|
||||
},
|
||||
"sync_status": {
|
||||
"enum": [
|
||||
"completed",
|
||||
"synchronizing",
|
||||
"failed",
|
||||
"warning"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"warning": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"sync_status",
|
||||
"install_status"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"warning": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"integrations"
|
||||
],
|
||||
"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": "Get CCR Remote synced integrations status by outputId",
|
||||
"tags": [
|
||||
"CCR Remote synced integrations"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/fleet/service_tokens": {
|
||||
"post": {
|
||||
"description": "[Required authorization] Route required privileges: fleet-agents-all.",
|
||||
|
@ -60516,6 +60849,9 @@
|
|||
{
|
||||
"name": "alerting"
|
||||
},
|
||||
{
|
||||
"name": "CCR Remote synced integrations"
|
||||
},
|
||||
{
|
||||
"name": "connectors"
|
||||
},
|
||||
|
|
|
@ -45110,6 +45110,339 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
"/api/fleet/remote_synced_integrations/status": {
|
||||
"get": {
|
||||
"description": "[Required authorization] Route required privileges: fleet-settings-read AND integrations-read.",
|
||||
"operationId": "get-fleet-remote-synced-integrations-status",
|
||||
"parameters": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"custom_assets": {
|
||||
"additionalProperties": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"error": {
|
||||
"type": "string"
|
||||
},
|
||||
"is_deleted": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"package_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"package_version": {
|
||||
"type": "string"
|
||||
},
|
||||
"sync_status": {
|
||||
"enum": [
|
||||
"completed",
|
||||
"synchronizing",
|
||||
"failed",
|
||||
"warning"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type",
|
||||
"name",
|
||||
"package_name",
|
||||
"package_version",
|
||||
"sync_status"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"error": {
|
||||
"type": "string"
|
||||
},
|
||||
"integrations": {
|
||||
"items": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"error": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"install_status": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"main": {
|
||||
"type": "string"
|
||||
},
|
||||
"remote": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"main"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"package_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"package_version": {
|
||||
"type": "string"
|
||||
},
|
||||
"sync_status": {
|
||||
"enum": [
|
||||
"completed",
|
||||
"synchronizing",
|
||||
"failed",
|
||||
"warning"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"warning": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"sync_status",
|
||||
"install_status"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"warning": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"integrations"
|
||||
],
|
||||
"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": "Get CCR Remote synced integrations status",
|
||||
"tags": [
|
||||
"CCR Remote synced integrations"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/fleet/remote_synced_integrations/{outputId}/remote_status": {
|
||||
"get": {
|
||||
"description": "[Required authorization] Route required privileges: fleet-settings-read AND integrations-read.",
|
||||
"operationId": "get-fleet-remote-synced-integrations-outputid-remote-status",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "path",
|
||||
"name": "outputId",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"custom_assets": {
|
||||
"additionalProperties": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"error": {
|
||||
"type": "string"
|
||||
},
|
||||
"is_deleted": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"package_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"package_version": {
|
||||
"type": "string"
|
||||
},
|
||||
"sync_status": {
|
||||
"enum": [
|
||||
"completed",
|
||||
"synchronizing",
|
||||
"failed",
|
||||
"warning"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type",
|
||||
"name",
|
||||
"package_name",
|
||||
"package_version",
|
||||
"sync_status"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"error": {
|
||||
"type": "string"
|
||||
},
|
||||
"integrations": {
|
||||
"items": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"error": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"install_status": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"main": {
|
||||
"type": "string"
|
||||
},
|
||||
"remote": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"main"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"package_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"package_version": {
|
||||
"type": "string"
|
||||
},
|
||||
"sync_status": {
|
||||
"enum": [
|
||||
"completed",
|
||||
"synchronizing",
|
||||
"failed",
|
||||
"warning"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"warning": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"sync_status",
|
||||
"install_status"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"warning": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"integrations"
|
||||
],
|
||||
"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": "Get CCR Remote synced integrations status by outputId",
|
||||
"tags": [
|
||||
"CCR Remote synced integrations"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/fleet/service_tokens": {
|
||||
"post": {
|
||||
"description": "[Required authorization] Route required privileges: fleet-agents-all.",
|
||||
|
@ -60107,6 +60440,9 @@
|
|||
{
|
||||
"name": "alerting"
|
||||
},
|
||||
{
|
||||
"name": "CCR Remote synced integrations"
|
||||
},
|
||||
{
|
||||
"name": "connectors"
|
||||
},
|
||||
|
|
|
@ -66,6 +66,7 @@ tags:
|
|||
Configure APM source maps. A source map allows minified files to be mapped back to original source code--allowing you to maintain the speed advantage of minified code, without losing the ability to quickly and easily debug your application.
|
||||
For best results, uploading source maps should become a part of your deployment procedure, and not something you only do when you see unhelpful errors. That's because uploading source maps after errors happen won't make old errors magically readable--errors must occur again for source mapping to occur.
|
||||
name: APM sourcemaps
|
||||
- name: CCR Remote synced integrations
|
||||
- name: connectors
|
||||
description: |
|
||||
Connectors provide a central place to store connection information for services and integrations with Elastic or third party systems. Alerting rules can use connectors to run actions when rule conditions are met.
|
||||
|
@ -39651,6 +39652,233 @@ paths:
|
|||
summary: Update a proxy
|
||||
tags:
|
||||
- Fleet proxies
|
||||
/api/fleet/remote_synced_integrations/{outputId}/remote_status:
|
||||
get:
|
||||
description: '[Required authorization] Route required privileges: fleet-settings-read AND integrations-read.'
|
||||
operationId: get-fleet-remote-synced-integrations-outputid-remote-status
|
||||
parameters:
|
||||
- in: path
|
||||
name: outputId
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
custom_assets:
|
||||
additionalProperties:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
is_deleted:
|
||||
type: boolean
|
||||
name:
|
||||
type: string
|
||||
package_name:
|
||||
type: string
|
||||
package_version:
|
||||
type: string
|
||||
sync_status:
|
||||
enum:
|
||||
- completed
|
||||
- synchronizing
|
||||
- failed
|
||||
- warning
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
required:
|
||||
- type
|
||||
- name
|
||||
- package_name
|
||||
- package_version
|
||||
- sync_status
|
||||
type: object
|
||||
error:
|
||||
type: string
|
||||
integrations:
|
||||
items:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
install_status:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
main:
|
||||
type: string
|
||||
remote:
|
||||
type: string
|
||||
required:
|
||||
- main
|
||||
package_name:
|
||||
type: string
|
||||
package_version:
|
||||
type: string
|
||||
sync_status:
|
||||
enum:
|
||||
- completed
|
||||
- synchronizing
|
||||
- failed
|
||||
- warning
|
||||
type: string
|
||||
updated_at:
|
||||
type: string
|
||||
warning:
|
||||
type: string
|
||||
required:
|
||||
- sync_status
|
||||
- install_status
|
||||
type: array
|
||||
warning:
|
||||
type: string
|
||||
required:
|
||||
- integrations
|
||||
'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: Get CCR Remote synced integrations status by outputId
|
||||
tags:
|
||||
- CCR Remote synced integrations
|
||||
/api/fleet/remote_synced_integrations/status:
|
||||
get:
|
||||
description: '[Required authorization] Route required privileges: fleet-settings-read AND integrations-read.'
|
||||
operationId: get-fleet-remote-synced-integrations-status
|
||||
parameters: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
custom_assets:
|
||||
additionalProperties:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
is_deleted:
|
||||
type: boolean
|
||||
name:
|
||||
type: string
|
||||
package_name:
|
||||
type: string
|
||||
package_version:
|
||||
type: string
|
||||
sync_status:
|
||||
enum:
|
||||
- completed
|
||||
- synchronizing
|
||||
- failed
|
||||
- warning
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
required:
|
||||
- type
|
||||
- name
|
||||
- package_name
|
||||
- package_version
|
||||
- sync_status
|
||||
type: object
|
||||
error:
|
||||
type: string
|
||||
integrations:
|
||||
items:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
install_status:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
main:
|
||||
type: string
|
||||
remote:
|
||||
type: string
|
||||
required:
|
||||
- main
|
||||
package_name:
|
||||
type: string
|
||||
package_version:
|
||||
type: string
|
||||
sync_status:
|
||||
enum:
|
||||
- completed
|
||||
- synchronizing
|
||||
- failed
|
||||
- warning
|
||||
type: string
|
||||
updated_at:
|
||||
type: string
|
||||
warning:
|
||||
type: string
|
||||
required:
|
||||
- sync_status
|
||||
- install_status
|
||||
type: array
|
||||
warning:
|
||||
type: string
|
||||
required:
|
||||
- integrations
|
||||
'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: Get CCR Remote synced integrations status
|
||||
tags:
|
||||
- CCR Remote synced integrations
|
||||
/api/fleet/service_tokens:
|
||||
post:
|
||||
description: '[Required authorization] Route required privileges: fleet-agents-all.'
|
||||
|
|
|
@ -80,6 +80,7 @@ tags:
|
|||
description: Cases documentation
|
||||
url: https://www.elastic.co/docs/explore-analyze/alerts-cases/cases
|
||||
x-displayName: Cases
|
||||
- name: CCR Remote synced integrations
|
||||
- name: connectors
|
||||
description: |
|
||||
Connectors provide a central place to store connection information for services and integrations with Elastic or third party systems. Alerting rules can use connectors to run actions when rule conditions are met.
|
||||
|
@ -41893,6 +41894,233 @@ paths:
|
|||
summary: Update a proxy
|
||||
tags:
|
||||
- Fleet proxies
|
||||
/api/fleet/remote_synced_integrations/{outputId}/remote_status:
|
||||
get:
|
||||
description: '[Required authorization] Route required privileges: fleet-settings-read AND integrations-read.'
|
||||
operationId: get-fleet-remote-synced-integrations-outputid-remote-status
|
||||
parameters:
|
||||
- in: path
|
||||
name: outputId
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
custom_assets:
|
||||
additionalProperties:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
is_deleted:
|
||||
type: boolean
|
||||
name:
|
||||
type: string
|
||||
package_name:
|
||||
type: string
|
||||
package_version:
|
||||
type: string
|
||||
sync_status:
|
||||
enum:
|
||||
- completed
|
||||
- synchronizing
|
||||
- failed
|
||||
- warning
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
required:
|
||||
- type
|
||||
- name
|
||||
- package_name
|
||||
- package_version
|
||||
- sync_status
|
||||
type: object
|
||||
error:
|
||||
type: string
|
||||
integrations:
|
||||
items:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
install_status:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
main:
|
||||
type: string
|
||||
remote:
|
||||
type: string
|
||||
required:
|
||||
- main
|
||||
package_name:
|
||||
type: string
|
||||
package_version:
|
||||
type: string
|
||||
sync_status:
|
||||
enum:
|
||||
- completed
|
||||
- synchronizing
|
||||
- failed
|
||||
- warning
|
||||
type: string
|
||||
updated_at:
|
||||
type: string
|
||||
warning:
|
||||
type: string
|
||||
required:
|
||||
- sync_status
|
||||
- install_status
|
||||
type: array
|
||||
warning:
|
||||
type: string
|
||||
required:
|
||||
- integrations
|
||||
'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: Get CCR Remote synced integrations status by outputId
|
||||
tags:
|
||||
- CCR Remote synced integrations
|
||||
/api/fleet/remote_synced_integrations/status:
|
||||
get:
|
||||
description: '[Required authorization] Route required privileges: fleet-settings-read AND integrations-read.'
|
||||
operationId: get-fleet-remote-synced-integrations-status
|
||||
parameters: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
custom_assets:
|
||||
additionalProperties:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
is_deleted:
|
||||
type: boolean
|
||||
name:
|
||||
type: string
|
||||
package_name:
|
||||
type: string
|
||||
package_version:
|
||||
type: string
|
||||
sync_status:
|
||||
enum:
|
||||
- completed
|
||||
- synchronizing
|
||||
- failed
|
||||
- warning
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
required:
|
||||
- type
|
||||
- name
|
||||
- package_name
|
||||
- package_version
|
||||
- sync_status
|
||||
type: object
|
||||
error:
|
||||
type: string
|
||||
integrations:
|
||||
items:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
install_status:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
main:
|
||||
type: string
|
||||
remote:
|
||||
type: string
|
||||
required:
|
||||
- main
|
||||
package_name:
|
||||
type: string
|
||||
package_version:
|
||||
type: string
|
||||
sync_status:
|
||||
enum:
|
||||
- completed
|
||||
- synchronizing
|
||||
- failed
|
||||
- warning
|
||||
type: string
|
||||
updated_at:
|
||||
type: string
|
||||
warning:
|
||||
type: string
|
||||
required:
|
||||
- sync_status
|
||||
- install_status
|
||||
type: array
|
||||
warning:
|
||||
type: string
|
||||
required:
|
||||
- integrations
|
||||
'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: Get CCR Remote synced integrations status
|
||||
tags:
|
||||
- CCR Remote synced integrations
|
||||
/api/fleet/service_tokens:
|
||||
post:
|
||||
description: '[Required authorization] Route required privileges: fleet-agents-all.'
|
||||
|
|
|
@ -11,7 +11,7 @@ const _allowedExperimentalValues = {
|
|||
showExperimentalShipperOptions: false,
|
||||
useSpaceAwareness: false,
|
||||
enableAutomaticAgentUpgrades: true,
|
||||
enableSyncIntegrationsOnRemote: false,
|
||||
enableSyncIntegrationsOnRemote: true,
|
||||
enableSSLSecrets: false,
|
||||
installedIntegrationsTabularUI: false,
|
||||
enabledUpgradeAgentlessDeploymentsTask: false,
|
||||
|
|
|
@ -106,6 +106,24 @@ Save the responses as they will be required in Cluster A (see next section).
|
|||
- Choose a name, put `localhost:9300` for "Seed nodes", and save (check "Yes, I have setup trust")
|
||||
- Make sure the connection status is "Connected"
|
||||
|
||||
- Equivalent Dev Tools API request
|
||||
```
|
||||
PUT /_cluster/settings
|
||||
{
|
||||
"persistent" : {
|
||||
"cluster" : {
|
||||
"remote" : {
|
||||
"local" : {
|
||||
"seeds" : [
|
||||
"localhost:9300"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Set up CCR
|
||||
|
||||
Please note that [CCR](https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-getting-started-tutorial.html) requires both clusters to have the same license. At the time of writing an `enterprise` license is needed.
|
||||
|
@ -114,6 +132,16 @@ On cluster 1, navigate to *Stack Management > Cross-Cluster Replication* and c
|
|||
- Leader index `fleet-synced-integrations`
|
||||
- Follower index `fleet-synced-integrations-ccr-remote1`
|
||||
|
||||
- Equivalent Dev Tools API request
|
||||
|
||||
```
|
||||
PUT /fleet-synced-integrations-ccr-local/_ccr/follow
|
||||
{
|
||||
"remote_cluster" : "local",
|
||||
"leader_index" : "fleet-synced-integrations"
|
||||
}
|
||||
```
|
||||
|
||||
### Set up local ES output
|
||||
This configuration is required to kick off the integration sync. The local host needs to match the remote ES output configured on A (see next section). Note that `kibana.dev.yml` is read by both kibana instances so it's better to add it in the UI to avoid conflicts.
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ export interface IsConvertedToSecret {
|
|||
}
|
||||
|
||||
export const OutputFormRemoteEsSection: React.FunctionComponent<Props> = (props) => {
|
||||
const { docLinks } = useStartServices();
|
||||
const { docLinks, cloud } = useStartServices();
|
||||
const { inputs, useSecretsStorage, onToggleSecretStorage } = props;
|
||||
const [isConvertedToSecret, setIsConvertedToSecret] = React.useState<IsConvertedToSecret>({
|
||||
serviceToken: false,
|
||||
|
@ -54,7 +54,8 @@ export const OutputFormRemoteEsSection: React.FunctionComponent<Props> = (props)
|
|||
sslKey: false,
|
||||
});
|
||||
const { enableSyncIntegrationsOnRemote, enableSSLSecrets } = ExperimentalFeaturesService.get();
|
||||
const enableSyncIntegrations = enableSyncIntegrationsOnRemote && licenseService.isEnterprise();
|
||||
const enableSyncIntegrations =
|
||||
enableSyncIntegrationsOnRemote && licenseService.isEnterprise() && !cloud?.isServerlessEnabled;
|
||||
|
||||
const [isRemoteClusterInstructionsOpen, setIsRemoteClusterInstructionsOpen] =
|
||||
React.useState(false);
|
||||
|
|
|
@ -11,7 +11,7 @@ import { EuiBasicTable, EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiIconTip } f
|
|||
import type { EuiBasicTableColumn } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { licenseService, useAuthz, useLink } from '../../../../hooks';
|
||||
import { licenseService, useAuthz, useLink, useStartServices } from '../../../../hooks';
|
||||
import type { Output } from '../../../../types';
|
||||
|
||||
import { OutputHealth } from '../edit_output_flyout/output_health';
|
||||
|
@ -57,7 +57,9 @@ export const OutputsTable: React.FunctionComponent<OutputsTableProps> = ({
|
|||
const authz = useAuthz();
|
||||
const { getHref } = useLink();
|
||||
const { enableSyncIntegrationsOnRemote } = ExperimentalFeaturesService.get();
|
||||
const enableSyncIntegrations = enableSyncIntegrationsOnRemote && licenseService.isEnterprise();
|
||||
const { cloud } = useStartServices();
|
||||
const enableSyncIntegrations =
|
||||
enableSyncIntegrationsOnRemote && licenseService.isEnterprise() && !cloud?.isServerlessEnabled;
|
||||
|
||||
const columns = useMemo((): Array<EuiBasicTableColumn<Output>> => {
|
||||
return [
|
||||
|
|
|
@ -15,81 +15,77 @@ import { GetRemoteSyncedIntegrationsStatusResponseSchema } from '../../types/mod
|
|||
|
||||
import { GetRemoteSyncedIntegrationsInfoRequestSchema } from '../../types';
|
||||
|
||||
import { canEnableSyncIntegrations } from '../../services/setup/fleet_synced_integrations';
|
||||
|
||||
import {
|
||||
getRemoteSyncedIntegrationsStatusHandler,
|
||||
getRemoteSyncedIntegrationsInfoHandler,
|
||||
} from './handler';
|
||||
|
||||
export const registerRoutes = (router: FleetAuthzRouter) => {
|
||||
if (canEnableSyncIntegrations()) {
|
||||
router.versioned
|
||||
.get({
|
||||
path: REMOTE_SYNCED_INTEGRATIONS_API_ROUTES.STATUS_PATTERN,
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: [
|
||||
FLEET_API_PRIVILEGES.SETTINGS.READ,
|
||||
FLEET_API_PRIVILEGES.INTEGRATIONS.READ,
|
||||
],
|
||||
},
|
||||
router.versioned
|
||||
.get({
|
||||
path: REMOTE_SYNCED_INTEGRATIONS_API_ROUTES.STATUS_PATTERN,
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: [
|
||||
FLEET_API_PRIVILEGES.SETTINGS.READ,
|
||||
FLEET_API_PRIVILEGES.INTEGRATIONS.READ,
|
||||
],
|
||||
},
|
||||
summary: `Get CCR Remote synced integrations status`,
|
||||
options: {
|
||||
tags: ['oas-tag:CCR Remote synced integrations'],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: {
|
||||
request: {},
|
||||
response: {
|
||||
200: {
|
||||
body: () => GetRemoteSyncedIntegrationsStatusResponseSchema,
|
||||
},
|
||||
400: {
|
||||
body: genericErrorResponse,
|
||||
},
|
||||
},
|
||||
summary: `Get CCR Remote synced integrations status`,
|
||||
options: {
|
||||
tags: ['oas-tag:CCR Remote synced integrations'],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: {
|
||||
request: {},
|
||||
response: {
|
||||
200: {
|
||||
body: () => GetRemoteSyncedIntegrationsStatusResponseSchema,
|
||||
},
|
||||
400: {
|
||||
body: genericErrorResponse,
|
||||
},
|
||||
},
|
||||
},
|
||||
getRemoteSyncedIntegrationsStatusHandler
|
||||
);
|
||||
},
|
||||
getRemoteSyncedIntegrationsStatusHandler
|
||||
);
|
||||
|
||||
router.versioned
|
||||
.get({
|
||||
path: REMOTE_SYNCED_INTEGRATIONS_API_ROUTES.INFO_PATTERN,
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: [
|
||||
FLEET_API_PRIVILEGES.SETTINGS.READ,
|
||||
FLEET_API_PRIVILEGES.INTEGRATIONS.READ,
|
||||
],
|
||||
},
|
||||
router.versioned
|
||||
.get({
|
||||
path: REMOTE_SYNCED_INTEGRATIONS_API_ROUTES.INFO_PATTERN,
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: [
|
||||
FLEET_API_PRIVILEGES.SETTINGS.READ,
|
||||
FLEET_API_PRIVILEGES.INTEGRATIONS.READ,
|
||||
],
|
||||
},
|
||||
summary: `Get CCR Remote synced integrations status by outputId`,
|
||||
options: {
|
||||
tags: ['oas-tag:CCR Remote synced integrations'],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: {
|
||||
request: GetRemoteSyncedIntegrationsInfoRequestSchema,
|
||||
response: {
|
||||
200: {
|
||||
body: () => GetRemoteSyncedIntegrationsStatusResponseSchema,
|
||||
},
|
||||
400: {
|
||||
body: genericErrorResponse,
|
||||
},
|
||||
},
|
||||
summary: `Get CCR Remote synced integrations status by outputId`,
|
||||
options: {
|
||||
tags: ['oas-tag:CCR Remote synced integrations'],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: {
|
||||
request: GetRemoteSyncedIntegrationsInfoRequestSchema,
|
||||
response: {
|
||||
200: {
|
||||
body: () => GetRemoteSyncedIntegrationsStatusResponseSchema,
|
||||
},
|
||||
400: {
|
||||
body: genericErrorResponse,
|
||||
},
|
||||
},
|
||||
},
|
||||
getRemoteSyncedIntegrationsInfoHandler
|
||||
);
|
||||
}
|
||||
},
|
||||
getRemoteSyncedIntegrationsInfoHandler
|
||||
);
|
||||
};
|
||||
|
|
|
@ -83,7 +83,10 @@ import {
|
|||
} from './secrets';
|
||||
import { findAgentlessPolicies } from './outputs/helpers';
|
||||
import { patchUpdateDataWithRequireEncryptedAADFields } from './outputs/so_helpers';
|
||||
import { canEnableSyncIntegrations } from './setup/fleet_synced_integrations';
|
||||
import {
|
||||
canEnableSyncIntegrations,
|
||||
createOrUpdateFleetSyncedIntegrationsIndex,
|
||||
} from './setup/fleet_synced_integrations';
|
||||
|
||||
type Nullable<T> = { [P in keyof T]: T[P] | null };
|
||||
|
||||
|
@ -368,15 +371,18 @@ async function updateAgentPoliciesDataOutputId(
|
|||
}
|
||||
}
|
||||
|
||||
function validateRemoteSyncIntegrationsCanBeEnabled(output: Partial<NewOutput>) {
|
||||
if (
|
||||
output.type === outputType.RemoteElasticsearch &&
|
||||
(output.sync_integrations === true || output.sync_uninstalled_integrations === true) &&
|
||||
!canEnableSyncIntegrations()
|
||||
) {
|
||||
async function remoteSyncIntegrationsCheck(
|
||||
esClient: ElasticsearchClient,
|
||||
output: Partial<NewOutput>
|
||||
) {
|
||||
const syncIntegrationsEnabled =
|
||||
output.type === outputType.RemoteElasticsearch && output.sync_integrations === true;
|
||||
if (syncIntegrationsEnabled && !canEnableSyncIntegrations()) {
|
||||
throw new OutputUnauthorizedError(
|
||||
'Remote sync integrations require at least an Enterprise license.'
|
||||
);
|
||||
} else if (syncIntegrationsEnabled) {
|
||||
await createOrUpdateFleetSyncedIntegrationsIndex(esClient);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -692,7 +698,7 @@ class OutputService {
|
|||
}
|
||||
}
|
||||
|
||||
validateRemoteSyncIntegrationsCanBeEnabled(output);
|
||||
await remoteSyncIntegrationsCheck(esClient, output);
|
||||
|
||||
const id = options?.id ? outputIdToUuid(options.id) : SavedObjectsUtils.generateId();
|
||||
|
||||
|
@ -1118,7 +1124,7 @@ class OutputService {
|
|||
updateData.shipper = null;
|
||||
}
|
||||
}
|
||||
validateRemoteSyncIntegrationsCanBeEnabled(data);
|
||||
await remoteSyncIntegrationsCheck(esClient, data);
|
||||
|
||||
// Store secret values if enabled; if not, store plain text values
|
||||
if (await isOutputSecretStorageEnabled(esClient, soClient)) {
|
||||
|
|
|
@ -24,10 +24,7 @@ import { getPreconfiguredDeleteUnenrolledAgentsSettingFromConfig } from './preco
|
|||
import { _runSetupWithLock, setupFleet } from './setup';
|
||||
import { isPackageInstalled } from './epm/packages/install';
|
||||
import { upgradeAgentPolicySchemaVersion } from './setup/upgrade_agent_policy_schema_version';
|
||||
import {
|
||||
createCCSIndexPatterns,
|
||||
createOrUpdateFleetSyncedIntegrationsIndex,
|
||||
} from './setup/fleet_synced_integrations';
|
||||
import { createCCSIndexPatterns } from './setup/fleet_synced_integrations';
|
||||
import { getSpaceAwareSaveobjectsClients } from './epm/kibana/assets/saved_objects';
|
||||
|
||||
jest.mock('./app_context');
|
||||
|
@ -107,7 +104,6 @@ describe('setupFleet', () => {
|
|||
(getPreconfiguredDeleteUnenrolledAgentsSettingFromConfig as jest.Mock).mockResolvedValue([]);
|
||||
(isPackageInstalled as jest.Mock).mockResolvedValue(true);
|
||||
(upgradeAgentPolicySchemaVersion as jest.Mock).mockResolvedValue(undefined);
|
||||
(createOrUpdateFleetSyncedIntegrationsIndex as jest.Mock).mockResolvedValue(undefined);
|
||||
(createCCSIndexPatterns as jest.Mock).mockResolvedValue(undefined);
|
||||
(getSpaceAwareSaveobjectsClients as jest.Mock).mockReturnValue({});
|
||||
});
|
||||
|
|
|
@ -66,10 +66,7 @@ import {
|
|||
} from './preconfiguration/delete_unenrolled_agent_setting';
|
||||
import { backfillPackagePolicySupportsAgentless } from './backfill_agentless';
|
||||
import { updateDeprecatedComponentTemplates } from './setup/update_deprecated_component_templates';
|
||||
import {
|
||||
createCCSIndexPatterns,
|
||||
createOrUpdateFleetSyncedIntegrationsIndex,
|
||||
} from './setup/fleet_synced_integrations';
|
||||
import { createCCSIndexPatterns } from './setup/fleet_synced_integrations';
|
||||
import { ensureCorrectAgentlessSettingsIds } from './agentless_settings_ids';
|
||||
import { getSpaceAwareSaveobjectsClients } from './epm/kibana/assets/saved_objects';
|
||||
|
||||
|
@ -281,9 +278,6 @@ async function createSetupSideEffects(
|
|||
logger.debug('Update deprecated _source.mode in component templates');
|
||||
await updateDeprecatedComponentTemplates(esClient);
|
||||
|
||||
logger.debug('Create or update fleet-synced-integrations index');
|
||||
await createOrUpdateFleetSyncedIntegrationsIndex(esClient);
|
||||
|
||||
logger.debug('Create CCS index patterns for remote clusters');
|
||||
const { savedObjectsImporter } = getSpaceAwareSaveobjectsClients();
|
||||
await createCCSIndexPatterns(esClient, soClient, savedObjectsImporter);
|
||||
|
|
|
@ -17,10 +17,14 @@ jest.mock('../app_context', () => ({
|
|||
getExperimentalFeatures: jest.fn().mockReturnValue({ enableSyncIntegrationsOnRemote: true }),
|
||||
getLogger: jest.fn().mockReturnValue({
|
||||
error: jest.fn(),
|
||||
debug: jest.fn(),
|
||||
}),
|
||||
getConfig: jest.fn().mockReturnValue({
|
||||
enableManagedLogsAndMetricsDataviews: true,
|
||||
}),
|
||||
getCloud: jest.fn().mockReturnValue({
|
||||
isServerlessEnabled: false,
|
||||
}),
|
||||
},
|
||||
}));
|
||||
|
||||
|
@ -147,32 +151,6 @@ describe('fleet_synced_integrations', () => {
|
|||
jest.spyOn(licenseService, 'isEnterprise').mockReturnValue(false);
|
||||
});
|
||||
|
||||
it('should not create index', async () => {
|
||||
mockExists.mockResolvedValue(false);
|
||||
jest.spyOn(licenseService, 'isEnterprise').mockReturnValue(false);
|
||||
|
||||
await createOrUpdateFleetSyncedIntegrationsIndex(esClientMock);
|
||||
|
||||
expect(esClientMock.indices.create).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not update index', async () => {
|
||||
mockExists.mockResolvedValue(true);
|
||||
mockGetMapping.mockResolvedValue({
|
||||
'fleet-synced-integrations': {
|
||||
mappings: {
|
||||
_meta: {
|
||||
version: '0.0',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await createOrUpdateFleetSyncedIntegrationsIndex(esClientMock);
|
||||
|
||||
expect(esClientMock.indices.putMapping).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not create index patterns for remote clusters', async () => {
|
||||
await createCCSIndexPatterns(esClientMock, soClientMock, soImporterMock);
|
||||
|
||||
|
|
|
@ -67,14 +67,12 @@ export const FLEET_SYNCED_INTEGRATIONS_INDEX_CONFIG = {
|
|||
|
||||
export const canEnableSyncIntegrations = () => {
|
||||
const { enableSyncIntegrationsOnRemote } = appContextService.getExperimentalFeatures();
|
||||
return enableSyncIntegrationsOnRemote && licenseService.isEnterprise();
|
||||
const isServerless = appContextService.getCloud()?.isServerlessEnabled;
|
||||
return enableSyncIntegrationsOnRemote && licenseService.isEnterprise() && !isServerless;
|
||||
};
|
||||
|
||||
export async function createOrUpdateFleetSyncedIntegrationsIndex(esClient: ElasticsearchClient) {
|
||||
if (!canEnableSyncIntegrations()) {
|
||||
return;
|
||||
}
|
||||
|
||||
appContextService.getLogger().debug('Create or update fleet-synced-integrations index');
|
||||
await createOrUpdateIndex(
|
||||
esClient,
|
||||
FLEET_SYNCED_INTEGRATIONS_INDEX_NAME,
|
||||
|
|
|
@ -39,6 +39,7 @@ export const getFollowerIndex = async (
|
|||
const indices = await esClient.indices.get(
|
||||
{
|
||||
index: FLEET_SYNCED_INTEGRATIONS_CCR_INDEX_PREFIX,
|
||||
expand_wildcards: 'all',
|
||||
},
|
||||
{ signal: abortController.signal }
|
||||
);
|
||||
|
|
|
@ -40,6 +40,10 @@ jest.mock('../../services/app_context', () => ({
|
|||
appContextService: {
|
||||
getExperimentalFeatures: jest.fn().mockReturnValue({ enableSyncIntegrationsOnRemote: true }),
|
||||
start: jest.fn(),
|
||||
getCloud: jest.fn().mockReturnValue({ isServerlessEnabled: false }),
|
||||
getLogger: jest.fn().mockReturnValue({
|
||||
debug: jest.fn(),
|
||||
}),
|
||||
},
|
||||
}));
|
||||
|
||||
|
@ -145,6 +149,15 @@ describe('SyncIntegrationsTask', () => {
|
|||
const [{ elasticsearch }] = await mockCore.getStartServices();
|
||||
esClient = elasticsearch.client.asInternalUser as ElasticsearchClientMock;
|
||||
esClient.indices.exists.mockResolvedValue(true);
|
||||
esClient.indices.getMapping.mockResolvedValue({
|
||||
'fleet-synced-integrations': {
|
||||
mappings: {
|
||||
_meta: {
|
||||
version: '1.0',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
esClient.cluster.getComponentTemplate.mockResolvedValue({
|
||||
component_templates: [
|
||||
{
|
||||
|
|
|
@ -24,6 +24,7 @@ import { getInstalledPackageSavedObjects } from '../../services/epm/packages/get
|
|||
import {
|
||||
FLEET_SYNCED_INTEGRATIONS_INDEX_NAME,
|
||||
canEnableSyncIntegrations,
|
||||
createOrUpdateFleetSyncedIntegrationsIndex,
|
||||
} from '../../services/setup/fleet_synced_integrations';
|
||||
|
||||
import { syncIntegrationsOnRemote } from './sync_integrations_on_remote';
|
||||
|
@ -31,7 +32,7 @@ import { getCustomAssets } from './custom_assets';
|
|||
import type { SyncIntegrationsData } from './model';
|
||||
|
||||
export const TYPE = 'fleet:sync-integrations-task';
|
||||
export const VERSION = '1.0.4';
|
||||
export const VERSION = '1.0.5';
|
||||
const TITLE = 'Fleet Sync Integrations Task';
|
||||
const SCOPE = ['fleet'];
|
||||
const INTERVAL = '5m';
|
||||
|
@ -122,14 +123,14 @@ export class SyncIntegrationsTask {
|
|||
|
||||
this.logger.info(`[runTask()] started`);
|
||||
|
||||
const [coreStart, _startDeps, { packageService }] = (await core.getStartServices()) as any;
|
||||
const esClient = coreStart.elasticsearch.client.asInternalUser;
|
||||
const soClient = new SavedObjectsClient(coreStart.savedObjects.createInternalRepository());
|
||||
|
||||
if (!canEnableSyncIntegrations()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const [coreStart, _startDeps, { packageService }] = (await core.getStartServices()) as any;
|
||||
const esClient = coreStart.elasticsearch.client.asInternalUser;
|
||||
const soClient = new SavedObjectsClient(coreStart.savedObjects.createInternalRepository());
|
||||
|
||||
try {
|
||||
// write integrations on main cluster
|
||||
await this.updateSyncedIntegrationsData(esClient, soClient);
|
||||
|
@ -155,15 +156,6 @@ export class SyncIntegrationsTask {
|
|||
}
|
||||
};
|
||||
|
||||
private syncedIntegrationsIndexExists = async (esClient: ElasticsearchClient) => {
|
||||
return await esClient.indices.exists(
|
||||
{
|
||||
index: FLEET_SYNCED_INTEGRATIONS_INDEX_NAME,
|
||||
},
|
||||
{ signal: this.abortController.signal }
|
||||
);
|
||||
};
|
||||
|
||||
private getSyncedIntegrationDoc = async (
|
||||
esClient: ElasticsearchClient
|
||||
): Promise<SyncIntegrationsData | undefined> => {
|
||||
|
@ -191,15 +183,6 @@ export class SyncIntegrationsTask {
|
|||
esClient: ElasticsearchClient,
|
||||
soClient: SavedObjectsClient
|
||||
) => {
|
||||
const indexExists = await this.syncedIntegrationsIndexExists(esClient);
|
||||
|
||||
if (!indexExists) {
|
||||
this.logger.info(
|
||||
`[SyncIntegrationsTask] index ${FLEET_SYNCED_INTEGRATIONS_INDEX_NAME} does not exist`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const outputs = await outputService.list(soClient);
|
||||
const remoteESOutputs = outputs.items.filter(
|
||||
(output) => output.type === outputType.RemoteElasticsearch
|
||||
|
@ -208,6 +191,10 @@ export class SyncIntegrationsTask {
|
|||
(output) => (output as NewRemoteElasticsearchOutput).sync_integrations
|
||||
);
|
||||
|
||||
if (isSyncEnabled) {
|
||||
await createOrUpdateFleetSyncedIntegrationsIndex(esClient);
|
||||
}
|
||||
|
||||
const previousSyncIntegrationsData = await this.getSyncedIntegrationDoc(esClient);
|
||||
|
||||
if (!isSyncEnabled) {
|
||||
|
|
|
@ -792,7 +792,7 @@ export default function (providerContext: FtrProviderContext) {
|
|||
}
|
||||
});
|
||||
|
||||
it('should not allow to update kibana_api_key on an existing remote_elasticsearch output if the license is not at least enterprise', async function () {
|
||||
it('should allow to update kibana_api_key on an existing remote_elasticsearch output', async function () {
|
||||
const res = await supertest
|
||||
.post(`/api/fleet/outputs`)
|
||||
.set('kbn-xsrf', 'xxxx')
|
||||
|
@ -804,7 +804,7 @@ export default function (providerContext: FtrProviderContext) {
|
|||
})
|
||||
.expect(200);
|
||||
const outputId = res.body.item.id;
|
||||
await supertest
|
||||
const updatedRes = await supertest
|
||||
.put(`/api/fleet/outputs/${outputId}`)
|
||||
.set('kbn-xsrf', 'xxxx')
|
||||
.send({
|
||||
|
@ -815,7 +815,8 @@ export default function (providerContext: FtrProviderContext) {
|
|||
kibana_url: 'https://testhost',
|
||||
kibana_api_key: 'bbbb',
|
||||
})
|
||||
.expect(400);
|
||||
.expect(200);
|
||||
expect(updatedRes.body.item.kibana_api_key).to.equal('bbbb');
|
||||
});
|
||||
|
||||
it('should bump all policies in all spaces if updating the default output', async () => {
|
||||
|
@ -1821,7 +1822,7 @@ export default function (providerContext: FtrProviderContext) {
|
|||
.expect(200);
|
||||
});
|
||||
|
||||
it('should not allow to create a new remote_elasticsearch output with kibana_api_key if the license is not at least enterprise', async function () {
|
||||
it('should allow to create a new remote_elasticsearch output with kibana_api_key field', async function () {
|
||||
await supertest
|
||||
.post(`/api/fleet/outputs`)
|
||||
.set('kbn-xsrf', 'xxxx')
|
||||
|
@ -1833,7 +1834,7 @@ export default function (providerContext: FtrProviderContext) {
|
|||
kibana_url: 'https://testhost',
|
||||
kibana_api_key: 'aaaa',
|
||||
})
|
||||
.expect(400);
|
||||
.expect(200);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue