diff --git a/oas_docs/output/kibana.serverless.yaml b/oas_docs/output/kibana.serverless.yaml index 7bc900794cd82..4efd89e46d394 100644 --- a/oas_docs/output/kibana.serverless.yaml +++ b/oas_docs/output/kibana.serverless.yaml @@ -45595,953 +45595,226 @@ paths: application/json: schema: anyOf: - - additionalProperties: false - type: object - properties: - allow_edit: - items: - type: string - maxItems: 1000 - type: array - ca_sha256: - nullable: true - type: string - ca_trusted_fingerprint: - nullable: true - type: string - config_yaml: - nullable: true - type: string - hosts: - items: - format: uri - type: string - maxItems: 10 - minItems: 1 - type: array - id: - type: string - is_default: - type: boolean - is_default_monitoring: - type: boolean - is_internal: - type: boolean - is_preconfigured: - type: boolean - name: - type: string - preset: - enum: - - balanced - - custom - - throughput - - scale - - latency - type: string - proxy_id: - nullable: true - type: string - secrets: - additionalProperties: false - type: object - properties: - ssl: - additionalProperties: false - type: object - properties: - key: - anyOf: - - additionalProperties: false - type: object - properties: - hash: - type: string - id: - type: string - required: - - id - - type: string - shipper: + - $ref: '#/components/schemas/Kibana_HTTP_APIs_update_output_elasticsearch' + - $ref: '#/components/schemas/Kibana_HTTP_APIs_update_output_remote_elasticsearch' + - $ref: '#/components/schemas/Kibana_HTTP_APIs_update_output_logstash' + - $ref: '#/components/schemas/Kibana_HTTP_APIs_update_output_kafka' + responses: + '200': + content: + application/json: + schema: + additionalProperties: false + type: object + properties: + item: + anyOf: + - $ref: '#/components/schemas/Kibana_HTTP_APIs_output_elasticsearch' + - $ref: '#/components/schemas/Kibana_HTTP_APIs_output_remote_elasticsearch' + - $ref: '#/components/schemas/Kibana_HTTP_APIs_output_logstash' + - $ref: '#/components/schemas/Kibana_HTTP_APIs_output_kafka' + required: + - item + description: 'OK: A successful request.' + '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 + description: A bad request. + summary: Update output + tags: + - Fleet outputs + x-metaTags: + - content: Kibana, Elastic Cloud Serverless + name: product_name + /api/fleet/outputs/{outputId}/health: + get: + description: |- + **Spaces method and path for this operation:** + +
get /s/{space_id}/api/fleet/outputs/{outputId}/health
+ + Refer to [Spaces](https://www.elastic.co/docs/deploy-manage/manage-spaces) for more information. + + [Required authorization] Route required privileges: fleet-settings-read. + operationId: get-fleet-outputs-outputid-health + parameters: + - in: path + name: outputId + required: true + schema: + type: string + responses: + '200': + content: + application/json: + schema: + additionalProperties: false + type: object + properties: + message: + description: long message if unhealthy + type: string + state: + description: state of output, HEALTHY or DEGRADED + type: string + timestamp: + description: timestamp of reported state + type: string + required: + - state + - message + - timestamp + description: 'OK: A successful request.' + '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 + description: A bad request. + summary: Get the latest output health + tags: + - Fleet outputs + x-metaTags: + - content: Kibana, Elastic Cloud Serverless + name: product_name + /api/fleet/package_policies: + get: + operationId: get-fleet-package-policies + parameters: + - in: query + name: page + required: false + schema: + type: number + - in: query + name: perPage + required: false + schema: + type: number + - in: query + name: sortField + required: false + schema: + type: string + - in: query + name: sortOrder + required: false + schema: + enum: + - desc + - asc + type: string + - in: query + name: showUpgradeable + required: false + schema: + type: boolean + - in: query + name: kuery + required: false + schema: + type: string + - in: query + name: format + required: false + schema: + enum: + - simplified + - legacy + type: string + - in: query + name: withAgentCount + required: false + schema: + type: boolean + responses: + '200': + content: + application/json: + schema: + additionalProperties: false + type: object + properties: + items: + items: additionalProperties: false - nullable: true type: object properties: - compression_level: - nullable: true - type: number - disk_queue_compression_enabled: - nullable: true - type: boolean - disk_queue_enabled: - default: false - nullable: true - type: boolean - disk_queue_encryption_enabled: - nullable: true - type: boolean - disk_queue_max_size: + additional_datastreams_permissions: + description: Additional datastream permissions, that will be added to the agent policy. + items: + type: string + maxItems: 1000 nullable: true + type: array + agents: type: number - disk_queue_path: + cloud_connector_id: + description: ID of the cloud connector associated with this package policy. nullable: true type: string - loadbalance: - nullable: true - type: boolean - max_batch_bytes: - nullable: true - type: number - mem_queue_events: - nullable: true - type: number - queue_flush_timeout: - nullable: true - type: number - required: - - disk_queue_path - - disk_queue_max_size - - disk_queue_encryption_enabled - - disk_queue_compression_enabled - - compression_level - - loadbalance - - mem_queue_events - - queue_flush_timeout - - max_batch_bytes - ssl: - additionalProperties: false - nullable: true - type: object - properties: - certificate: - type: string - certificate_authorities: - items: - type: string - maxItems: 10 - type: array - key: - type: string - verification_mode: - enum: - - full - - none - - certificate - - strict - type: string - type: - enum: - - elasticsearch - type: string - write_to_logs_streams: - nullable: true - type: boolean - - additionalProperties: false - type: object - properties: - allow_edit: - items: - type: string - maxItems: 1000 - type: array - ca_sha256: - nullable: true - type: string - ca_trusted_fingerprint: - nullable: true - type: string - config_yaml: - nullable: true - type: string - hosts: - items: - format: uri - type: string - maxItems: 10 - minItems: 1 - type: array - id: - type: string - is_default: - type: boolean - is_default_monitoring: - type: boolean - is_internal: - type: boolean - is_preconfigured: - type: boolean - kibana_api_key: - nullable: true - type: string - kibana_url: - nullable: true - type: string - name: - type: string - preset: - enum: - - balanced - - custom - - throughput - - scale - - latency - type: string - proxy_id: - nullable: true - type: string - secrets: - additionalProperties: false - type: object - properties: - service_token: - anyOf: - - additionalProperties: false - type: object - properties: - hash: - type: string - id: - type: string - required: - - id - - type: string - ssl: - additionalProperties: false - type: object - properties: - key: - anyOf: - - additionalProperties: false - type: object - properties: - hash: - type: string - id: - type: string - required: - - id - - type: string - service_token: - nullable: true - type: string - shipper: - additionalProperties: false - nullable: true - type: object - properties: - compression_level: - nullable: true - type: number - disk_queue_compression_enabled: - nullable: true - type: boolean - disk_queue_enabled: - default: false - nullable: true - type: boolean - disk_queue_encryption_enabled: - nullable: true - type: boolean - disk_queue_max_size: - nullable: true - type: number - disk_queue_path: + cloud_connector_name: + description: Transient field for cloud connector name during creation. + maxLength: 255 + minLength: 1 nullable: true type: string - loadbalance: - nullable: true - type: boolean - max_batch_bytes: - nullable: true - type: number - mem_queue_events: - nullable: true - type: number - queue_flush_timeout: - nullable: true - type: number - required: - - disk_queue_path - - disk_queue_max_size - - disk_queue_encryption_enabled - - disk_queue_compression_enabled - - compression_level - - loadbalance - - mem_queue_events - - queue_flush_timeout - - max_batch_bytes - ssl: - additionalProperties: false - nullable: true - type: object - properties: - certificate: + created_at: type: string - certificate_authorities: - items: - type: string - maxItems: 10 - type: array - key: + created_by: type: string - verification_mode: - enum: - - full - - none - - certificate - - strict + description: + description: Package policy description type: string - sync_integrations: - type: boolean - sync_uninstalled_integrations: - type: boolean - type: - enum: - - remote_elasticsearch - type: string - write_to_logs_streams: - nullable: true - type: boolean - - additionalProperties: false - type: object - properties: - allow_edit: - items: - type: string - maxItems: 1000 - type: array - ca_sha256: - nullable: true - type: string - ca_trusted_fingerprint: - nullable: true - type: string - config_yaml: - nullable: true - type: string - hosts: - items: - type: string - maxItems: 10 - minItems: 1 - type: array - id: - type: string - is_default: - type: boolean - is_default_monitoring: - type: boolean - is_internal: - type: boolean - is_preconfigured: - type: boolean - name: - type: string - proxy_id: - nullable: true - type: string - secrets: - additionalProperties: false - type: object - properties: - ssl: - additionalProperties: false + elasticsearch: + additionalProperties: true type: object properties: - key: - anyOf: - - additionalProperties: false - type: object - properties: - hash: - type: string - id: - type: string - required: - - id - - type: string - shipper: - additionalProperties: false - nullable: true - type: object - properties: - compression_level: - nullable: true - type: number - disk_queue_compression_enabled: - nullable: true - type: boolean - disk_queue_enabled: - default: false - nullable: true - type: boolean - disk_queue_encryption_enabled: - nullable: true - type: boolean - disk_queue_max_size: - nullable: true - type: number - disk_queue_path: - nullable: true - type: string - loadbalance: - nullable: true + privileges: + additionalProperties: true + type: object + properties: + cluster: + items: + type: string + maxItems: 100 + type: array + enabled: type: boolean - max_batch_bytes: - nullable: true - type: number - mem_queue_events: - nullable: true - type: number - queue_flush_timeout: - nullable: true - type: number - required: - - disk_queue_path - - disk_queue_max_size - - disk_queue_encryption_enabled - - disk_queue_compression_enabled - - compression_level - - loadbalance - - mem_queue_events - - queue_flush_timeout - - max_batch_bytes - ssl: - additionalProperties: false - nullable: true - type: object - properties: - certificate: - type: string - certificate_authorities: - items: - type: string - maxItems: 10 - type: array - key: - type: string - verification_mode: - enum: - - full - - none - - certificate - - strict - type: string - type: - enum: - - logstash - type: string - - additionalProperties: false - type: object - properties: - allow_edit: - items: - type: string - maxItems: 1000 - type: array - auth_type: - enum: - - none - - user_pass - - ssl - - kerberos - type: string - broker_timeout: - type: number - ca_sha256: - nullable: true - type: string - ca_trusted_fingerprint: - nullable: true - type: string - client_id: - type: string - compression: - enum: - - gzip - - snappy - - lz4 - - none - type: string - compression_level: - anyOf: - - items: {} - type: array - - type: boolean - - type: number - - type: object - - type: string - nullable: true - oneOf: - - type: number - - not: {} - config_yaml: - nullable: true - type: string - connection_type: - anyOf: - - items: {} - type: array - - type: boolean - - type: number - - type: object - - type: string - nullable: true - oneOf: - - enum: - - plaintext - - encryption - type: string - - not: {} - hash: - additionalProperties: false - type: object - properties: - hash: - type: string - random: - type: boolean - headers: - items: - additionalProperties: false - type: object - properties: - key: - type: string - value: - type: string - required: - - key - - value - maxItems: 100 - type: array - hosts: - items: - type: string - maxItems: 10 - minItems: 1 - type: array - id: - type: string - is_default: - default: false - type: boolean - is_default_monitoring: - default: false - type: boolean - is_internal: - type: boolean - is_preconfigured: - type: boolean - key: - type: string - name: - type: string - partition: - enum: - - random - - round_robin - - hash - type: string - password: - anyOf: - - items: {} - type: array - - type: boolean - - type: number - - type: object - - type: string - nullable: true - oneOf: - - not: {} - - anyOf: - - items: {} - type: array - - type: boolean - - type: number - - type: object - - type: string - nullable: true - oneOf: - - type: string - - not: {} - proxy_id: - nullable: true - type: string - random: - additionalProperties: false - type: object - properties: - group_events: - type: number - required_acks: - enum: - - 1 - - 0 - - -1 - type: integer - round_robin: - additionalProperties: false - type: object - properties: - group_events: - type: number - sasl: - additionalProperties: false - nullable: true - type: object - properties: - mechanism: - enum: - - PLAIN - - SCRAM-SHA-256 - - SCRAM-SHA-512 - type: string - secrets: - additionalProperties: false - type: object - properties: - password: - anyOf: - - additionalProperties: false - type: object - properties: - hash: - type: string - id: - type: string - required: - - id - - type: string - ssl: - additionalProperties: false - type: object - properties: - key: - anyOf: - - additionalProperties: false - type: object - properties: - hash: - type: string - id: - type: string - required: - - id - - type: string - required: - - key - shipper: - additionalProperties: false - nullable: true - type: object - properties: - compression_level: - nullable: true - type: number - disk_queue_compression_enabled: - nullable: true - type: boolean - disk_queue_enabled: - default: false - nullable: true - type: boolean - disk_queue_encryption_enabled: - nullable: true - type: boolean - disk_queue_max_size: - nullable: true - type: number - disk_queue_path: - nullable: true - type: string - loadbalance: - nullable: true - type: boolean - max_batch_bytes: - nullable: true - type: number - mem_queue_events: - nullable: true - type: number - queue_flush_timeout: - nullable: true - type: number - required: - - disk_queue_path - - disk_queue_max_size - - disk_queue_encryption_enabled - - disk_queue_compression_enabled - - compression_level - - loadbalance - - mem_queue_events - - queue_flush_timeout - - max_batch_bytes - ssl: - additionalProperties: false - nullable: true - type: object - properties: - certificate: - type: string - certificate_authorities: - items: - type: string - maxItems: 10 - type: array - key: - type: string - verification_mode: - enum: - - full - - none - - certificate - - strict - type: string - timeout: - type: number - topic: - type: string - type: - enum: - - kafka - type: string - username: - anyOf: - - items: {} - type: array - - type: boolean - - type: number - - type: object - - type: string - nullable: true - oneOf: - - type: string - - not: {} - version: - type: string - required: - - name - - compression_level - - connection_type - - username - - password - responses: - '200': - content: - application/json: - schema: - additionalProperties: false - type: object - properties: - item: - anyOf: - - $ref: '#/components/schemas/Kibana_HTTP_APIs_output_elasticsearch' - - $ref: '#/components/schemas/Kibana_HTTP_APIs_output_remote_elasticsearch' - - $ref: '#/components/schemas/Kibana_HTTP_APIs_output_logstash' - - $ref: '#/components/schemas/Kibana_HTTP_APIs_output_kafka' - required: - - item - description: 'OK: A successful request.' - '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 - description: A bad request. - summary: Update output - tags: - - Fleet outputs - x-metaTags: - - content: Kibana, Elastic Cloud Serverless - name: product_name - /api/fleet/outputs/{outputId}/health: - get: - description: |- - **Spaces method and path for this operation:** - -
get /s/{space_id}/api/fleet/outputs/{outputId}/health
- - Refer to [Spaces](https://www.elastic.co/docs/deploy-manage/manage-spaces) for more information. - - [Required authorization] Route required privileges: fleet-settings-read. - operationId: get-fleet-outputs-outputid-health - parameters: - - in: path - name: outputId - required: true - schema: - type: string - responses: - '200': - content: - application/json: - schema: - additionalProperties: false - type: object - properties: - message: - description: long message if unhealthy - type: string - state: - description: state of output, HEALTHY or DEGRADED - type: string - timestamp: - description: timestamp of reported state - type: string - required: - - state - - message - - timestamp - description: 'OK: A successful request.' - '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 - description: A bad request. - summary: Get the latest output health - tags: - - Fleet outputs - x-metaTags: - - content: Kibana, Elastic Cloud Serverless - name: product_name - /api/fleet/package_policies: - get: - operationId: get-fleet-package-policies - parameters: - - in: query - name: page - required: false - schema: - type: number - - in: query - name: perPage - required: false - schema: - type: number - - in: query - name: sortField - required: false - schema: - type: string - - in: query - name: sortOrder - required: false - schema: - enum: - - desc - - asc - type: string - - in: query - name: showUpgradeable - required: false - schema: - type: boolean - - in: query - name: kuery - required: false - schema: - type: string - - in: query - name: format - required: false - schema: - enum: - - simplified - - legacy - type: string - - in: query - name: withAgentCount - required: false - schema: - type: boolean - responses: - '200': - content: - application/json: - schema: - additionalProperties: false - type: object - properties: - items: - items: - additionalProperties: false - type: object - properties: - additional_datastreams_permissions: - description: Additional datastream permissions, that will be added to the agent policy. - items: - type: string - maxItems: 1000 - nullable: true - type: array - agents: - type: number - cloud_connector_id: - description: ID of the cloud connector associated with this package policy. - nullable: true - type: string - cloud_connector_name: - description: Transient field for cloud connector name during creation. - maxLength: 255 - minLength: 1 - nullable: true - type: string - created_at: - type: string - created_by: - type: string - description: - description: Package policy description - type: string - elasticsearch: - additionalProperties: true - type: object - properties: - privileges: - additionalProperties: true - type: object - properties: - cluster: - items: - type: string - maxItems: 100 - type: array - enabled: - type: boolean - id: - description: Package policy unique identifier. + id: + description: Package policy unique identifier. type: string inputs: anyOf: @@ -70955,6 +70228,9 @@ components: type: boolean name: type: string + otel_exporter_config_yaml: + nullable: true + type: string preset: enum: - balanced @@ -71172,6 +70448,9 @@ components: type: string name: type: string + otel_exporter_config_yaml: + nullable: true + type: string partition: enum: - random @@ -71403,6 +70682,9 @@ components: type: boolean name: type: string + otel_exporter_config_yaml: + nullable: true + type: string proxy_id: nullable: true type: string @@ -71547,6 +70829,9 @@ components: type: string name: type: string + otel_exporter_config_yaml: + nullable: true + type: string preset: enum: - balanced @@ -71715,6 +71000,9 @@ components: type: boolean name: type: string + otel_exporter_config_yaml: + nullable: true + type: string preset: enum: - balanced @@ -71932,6 +71220,9 @@ components: type: string name: type: string + otel_exporter_config_yaml: + nullable: true + type: string partition: enum: - random @@ -72163,6 +71454,9 @@ components: type: boolean name: type: string + otel_exporter_config_yaml: + nullable: true + type: string proxy_id: nullable: true type: string @@ -72307,6 +71601,9 @@ components: type: string name: type: string + otel_exporter_config_yaml: + nullable: true + type: string preset: enum: - balanced @@ -72934,18 +72231,200 @@ components: description: Human-readable notes about this processor step type: string from: - minLength: 1 - type: string + minLength: 1 + type: string + ignore_failure: + description: Continue pipeline execution if this processor fails + type: boolean + ignore_missing: + type: boolean + pattern: + minLength: 1 + type: string + replacement: + type: string + to: + minLength: 1 + type: string + where: + $ref: '#/components/schemas/Kibana_HTTP_APIs_Condition' + description: Conditional expression controlling whether this processor runs + required: + - action + - from + - pattern + - replacement + - additionalProperties: false + description: Redact processor - Mask sensitive data using Grok patterns + type: object + properties: + action: + enum: + - redact + type: string + customIdentifier: + description: Custom identifier to correlate this processor across outputs + minLength: 1 + type: string + description: + description: Human-readable notes about this processor step + type: string + from: + description: Source field to redact sensitive data from + minLength: 1 + type: string + ignore_failure: + description: Continue pipeline execution if this processor fails + type: boolean + ignore_missing: + description: Skip processing when source field is missing (defaults to true) + type: boolean + pattern_definitions: + additionalProperties: + type: string + description: Custom pattern definitions to use in the patterns + type: object + patterns: + description: Grok patterns to match sensitive data (for example, "%{IP:client}", "%{EMAILADDRESS:email}") + items: + description: A non-empty string. + minLength: 1 + type: string + minItems: 1 + type: array + prefix: + description: Prefix to prepend to the redacted pattern name (defaults to "<") + type: string + suffix: + description: Suffix to append to the redacted pattern name (defaults to ">") + type: string + where: + $ref: '#/components/schemas/Kibana_HTTP_APIs_Condition' + description: Conditional expression controlling whether this processor runs + required: + - action + - from + - patterns + - additionalProperties: false + type: object + properties: + action: + enum: + - uppercase + type: string + customIdentifier: + description: Custom identifier to correlate this processor across outputs + minLength: 1 + type: string + description: + description: Human-readable notes about this processor step + type: string + from: + minLength: 1 + type: string + ignore_failure: + description: Continue pipeline execution if this processor fails + type: boolean + ignore_missing: + type: boolean + to: + minLength: 1 + type: string + where: + $ref: '#/components/schemas/Kibana_HTTP_APIs_Condition' + description: Conditional expression controlling whether this processor runs + required: + - action + - from + - additionalProperties: false + type: object + properties: + action: + enum: + - lowercase + type: string + customIdentifier: + description: Custom identifier to correlate this processor across outputs + minLength: 1 + type: string + description: + description: Human-readable notes about this processor step + type: string + from: + minLength: 1 + type: string + ignore_failure: + description: Continue pipeline execution if this processor fails + type: boolean + ignore_missing: + type: boolean + to: + minLength: 1 + type: string + where: + $ref: '#/components/schemas/Kibana_HTTP_APIs_Condition' + description: Conditional expression controlling whether this processor runs + required: + - action + - from + - additionalProperties: false + type: object + properties: + action: + enum: + - trim + type: string + customIdentifier: + description: Custom identifier to correlate this processor across outputs + minLength: 1 + type: string + description: + description: Human-readable notes about this processor step + type: string + from: + minLength: 1 + type: string + ignore_failure: + description: Continue pipeline execution if this processor fails + type: boolean + ignore_missing: + type: boolean + to: + minLength: 1 + type: string + where: + $ref: '#/components/schemas/Kibana_HTTP_APIs_Condition' + description: Conditional expression controlling whether this processor runs + required: + - action + - from + - additionalProperties: false + type: object + properties: + action: + enum: + - join + type: string + customIdentifier: + description: Custom identifier to correlate this processor across outputs + minLength: 1 + type: string + delimiter: + type: string + description: + description: Human-readable notes about this processor step + type: string + from: + items: + minLength: 1 + type: string + minItems: 1 + type: array ignore_failure: description: Continue pipeline execution if this processor fails type: boolean ignore_missing: type: boolean - pattern: - minLength: 1 - type: string - replacement: - type: string to: minLength: 1 type: string @@ -72955,15 +72434,15 @@ components: required: - action - from - - pattern - - replacement + - delimiter + - to - additionalProperties: false - description: Redact processor - Mask sensitive data using Grok patterns + description: Split processor - Split a field value into an array using a separator type: object properties: action: enum: - - redact + - split type: string customIdentifier: description: Custom identifier to correlate this processor across outputs @@ -72973,33 +72452,25 @@ components: description: Human-readable notes about this processor step type: string from: - description: Source field to redact sensitive data from + description: Source field to split into an array minLength: 1 type: string ignore_failure: description: Continue pipeline execution if this processor fails type: boolean ignore_missing: - description: Skip processing when source field is missing (defaults to true) + description: Skip processing when source field is missing type: boolean - pattern_definitions: - additionalProperties: - type: string - description: Custom pattern definitions to use in the patterns - type: object - patterns: - description: Grok patterns to match sensitive data (for example, "%{IP:client}", "%{EMAILADDRESS:email}") - items: - description: A non-empty string. - minLength: 1 - type: string - minItems: 1 - type: array - prefix: - description: Prefix to prepend to the redacted pattern name (defaults to "<") + preserve_trailing: + description: Preserve empty trailing fields in the split result + type: boolean + separator: + description: Regex separator used to split the field value into an array + minLength: 1 type: string - suffix: - description: Suffix to append to the redacted pattern name (defaults to ">") + to: + description: Target field for the split array (defaults to source) + minLength: 1 type: string where: $ref: '#/components/schemas/Kibana_HTTP_APIs_Condition' @@ -73007,13 +72478,13 @@ components: required: - action - from - - patterns + - separator - additionalProperties: false type: object properties: action: enum: - - uppercase + - sort type: string customIdentifier: description: Custom identifier to correlate this processor across outputs @@ -73023,14 +72494,23 @@ components: description: Human-readable notes about this processor step type: string from: + description: Array field to sort minLength: 1 type: string ignore_failure: description: Continue pipeline execution if this processor fails type: boolean ignore_missing: + description: Skip processing when source field is missing type: boolean + order: + description: Sort order - "asc" (ascending) or "desc" (descending). Defaults to "asc" + enum: + - asc + - desc + type: string to: + description: Target field for the sorted array (defaults to source) minLength: 1 type: string where: @@ -73040,11 +72520,12 @@ components: - action - from - additionalProperties: false + description: Convert processor - Change the data type of a field value (integer, long, double, boolean, or string) type: object properties: action: enum: - - lowercase + - convert type: string customIdentifier: description: Custom identifier to correlate this processor across outputs @@ -73054,28 +72535,41 @@ components: description: Human-readable notes about this processor step type: string from: + description: Source field to convert to a different data type minLength: 1 type: string ignore_failure: description: Continue pipeline execution if this processor fails type: boolean ignore_missing: + description: Skip processing when source field is missing type: boolean to: + description: Target field for the converted value (defaults to source) minLength: 1 type: string + type: + description: 'Target data type: integer, long, double, boolean, or string' + enum: + - integer + - long + - double + - boolean + - string + type: string where: $ref: '#/components/schemas/Kibana_HTTP_APIs_Condition' description: Conditional expression controlling whether this processor runs required: - action - from + - type - additionalProperties: false type: object properties: action: enum: - - trim + - concat type: string customIdentifier: description: Custom identifier to correlate this processor across outputs @@ -73085,8 +72579,33 @@ components: description: Human-readable notes about this processor step type: string from: - minLength: 1 - type: string + items: + anyOf: + - type: object + properties: + type: + enum: + - field + type: string + value: + minLength: 1 + type: string + required: + - type + - value + - type: object + properties: + type: + enum: + - literal + type: string + value: + type: string + required: + - type + - value + minItems: 1 + type: array ignore_failure: description: Continue pipeline execution if this processor fails type: boolean @@ -73101,51 +72620,127 @@ components: required: - action - from + - to + - allOf: + - additionalProperties: false + type: object + properties: + action: + enum: + - network_direction + type: string + customIdentifier: + description: Custom identifier to correlate this processor across outputs + minLength: 1 + type: string + description: + description: Human-readable notes about this processor step + type: string + destination_ip: + minLength: 1 + type: string + ignore_failure: + description: Continue pipeline execution if this processor fails + type: boolean + ignore_missing: + type: boolean + source_ip: + minLength: 1 + type: string + target_field: + minLength: 1 + type: string + where: + $ref: '#/components/schemas/Kibana_HTTP_APIs_Condition' + description: Conditional expression controlling whether this processor runs + required: + - action + - source_ip + - destination_ip + - anyOf: + - additionalProperties: false + type: object + properties: + internal_networks: + items: + type: string + type: array + required: + - internal_networks + - additionalProperties: false + type: object + properties: + internal_networks_field: + minLength: 1 + type: string + required: + - internal_networks_field - additionalProperties: false + description: JsonExtract processor - Extract values from JSON strings using JSONPath-like selectors type: object properties: action: enum: - - join + - json_extract type: string customIdentifier: description: Custom identifier to correlate this processor across outputs minLength: 1 type: string - delimiter: - type: string description: description: Human-readable notes about this processor step type: string - from: + extractions: + description: List of extraction specifications items: - minLength: 1 - type: string + description: A single extraction specification + type: object + properties: + selector: + description: JSONPath-like selector to extract value (e.g., "user.id", "$.metadata.client.ip", "items[0].name") + minLength: 1 + type: string + target_field: + description: Target field to store the extracted value + minLength: 1 + type: string + type: + description: Data type for the extracted value. Defaults to "keyword". Ensures consistent types across transpilers. + enum: + - keyword + - integer + - long + - double + - boolean + type: string + required: + - selector + - target_field minItems: 1 type: array + field: + description: Source field containing the JSON string to parse + minLength: 1 + type: string ignore_failure: description: Continue pipeline execution if this processor fails type: boolean ignore_missing: + description: Skip processing when source field is missing type: boolean - to: - minLength: 1 - type: string where: $ref: '#/components/schemas/Kibana_HTTP_APIs_Condition' description: Conditional expression controlling whether this processor runs required: - action - - from - - delimiter - - to + - field + - extractions - additionalProperties: false - description: Split processor - Split a field value into an array using a separator type: object properties: action: enum: - - split + - enrich type: string customIdentifier: description: Custom identifier to correlate this processor across outputs @@ -73154,25 +72749,18 @@ components: description: description: Human-readable notes about this processor step type: string - from: - description: Source field to split into an array - minLength: 1 - type: string ignore_failure: description: Continue pipeline execution if this processor fails type: boolean ignore_missing: - description: Skip processing when source field is missing type: boolean - preserve_trailing: - description: Preserve empty trailing fields in the split result + override: type: boolean - separator: - description: Regex separator used to split the field value into an array + policy_name: + description: A non-empty string. minLength: 1 type: string to: - description: Target field for the split array (defaults to source) minLength: 1 type: string where: @@ -73180,14 +72768,16 @@ components: description: Conditional expression controlling whether this processor runs required: - action - - from - - separator + - policy_name + - to - additionalProperties: false + description: Manual ingest pipeline wrapper around native Elasticsearch processors type: object properties: action: + description: Manual ingest pipeline - executes raw Elasticsearch ingest processors enum: - - sort + - manual_ingest_pipeline type: string customIdentifier: description: Custom identifier to correlate this processor across outputs @@ -73196,329 +72786,787 @@ components: description: description: Human-readable notes about this processor step type: string - from: - description: Array field to sort - minLength: 1 - type: string ignore_failure: description: Continue pipeline execution if this processor fails type: boolean - ignore_missing: - description: Skip processing when source field is missing - type: boolean - order: - description: Sort order - "asc" (ascending) or "desc" (descending). Defaults to "asc" - enum: - - asc - - desc - type: string - to: - description: Target field for the sorted array (defaults to source) - minLength: 1 + on_failure: + description: Fallback processors to run when a processor fails + items: + additionalProperties: {} + type: object + type: array + processors: + description: List of raw Elasticsearch ingest processors to run + items: + additionalProperties: {} + type: object + type: array + tag: + description: Optional ingest processor tag for Elasticsearch type: string where: $ref: '#/components/schemas/Kibana_HTTP_APIs_Condition' description: Conditional expression controlling whether this processor runs required: - action - - from - - additionalProperties: false - description: Convert processor - Change the data type of a field value (integer, long, double, boolean, or string) + - processors + - $ref: '#/components/schemas/Kibana_HTTP_APIs_StreamlangConditionBlock' + Kibana_HTTP_APIs_StreamUpsertRequest: + anyOf: + - $ref: '#/components/schemas/Kibana_HTTP_APIs_WiredStreamUpsertRequest' + - $ref: '#/components/schemas/Kibana_HTTP_APIs_ClassicStreamUpsertRequest' + - $ref: '#/components/schemas/Kibana_HTTP_APIs_QueryStreamUpsertRequest' + Kibana_HTTP_APIs_update_output_elasticsearch: + additionalProperties: false + properties: + allow_edit: + items: + type: string + maxItems: 1000 + type: array + ca_sha256: + nullable: true + type: string + ca_trusted_fingerprint: + nullable: true + type: string + config_yaml: + nullable: true + type: string + hosts: + items: + format: uri + type: string + maxItems: 10 + minItems: 1 + type: array + id: + type: string + is_default: + type: boolean + is_default_monitoring: + type: boolean + is_internal: + type: boolean + is_preconfigured: + type: boolean + name: + type: string + otel_exporter_config_yaml: + nullable: true + type: string + preset: + enum: + - balanced + - custom + - throughput + - scale + - latency + type: string + proxy_id: + nullable: true + type: string + secrets: + additionalProperties: false + type: object + properties: + ssl: + additionalProperties: false + type: object + properties: + key: + anyOf: + - additionalProperties: false + type: object + properties: + hash: + type: string + id: + type: string + required: + - id + - type: string + shipper: + additionalProperties: false + nullable: true + type: object + properties: + compression_level: + nullable: true + type: number + disk_queue_compression_enabled: + nullable: true + type: boolean + disk_queue_enabled: + default: false + nullable: true + type: boolean + disk_queue_encryption_enabled: + nullable: true + type: boolean + disk_queue_max_size: + nullable: true + type: number + disk_queue_path: + nullable: true + type: string + loadbalance: + nullable: true + type: boolean + max_batch_bytes: + nullable: true + type: number + mem_queue_events: + nullable: true + type: number + queue_flush_timeout: + nullable: true + type: number + required: + - disk_queue_path + - disk_queue_max_size + - disk_queue_encryption_enabled + - disk_queue_compression_enabled + - compression_level + - loadbalance + - mem_queue_events + - queue_flush_timeout + - max_batch_bytes + ssl: + additionalProperties: false + nullable: true + type: object + properties: + certificate: + type: string + certificate_authorities: + items: + type: string + maxItems: 10 + type: array + key: + type: string + verification_mode: + enum: + - full + - none + - certificate + - strict + type: string + type: + enum: + - elasticsearch + type: string + write_to_logs_streams: + nullable: true + type: boolean + title: update_output_elasticsearch + type: object + Kibana_HTTP_APIs_update_output_kafka: + additionalProperties: false + properties: + allow_edit: + items: + type: string + maxItems: 1000 + type: array + auth_type: + enum: + - none + - user_pass + - ssl + - kerberos + type: string + broker_timeout: + type: number + ca_sha256: + nullable: true + type: string + ca_trusted_fingerprint: + nullable: true + type: string + client_id: + type: string + compression: + enum: + - gzip + - snappy + - lz4 + - none + type: string + compression_level: + anyOf: + - items: {} + type: array + - type: boolean + - type: number + - type: object + - type: string + nullable: true + oneOf: + - type: number + - not: {} + config_yaml: + nullable: true + type: string + connection_type: + anyOf: + - items: {} + type: array + - type: boolean + - type: number + - type: object + - type: string + nullable: true + oneOf: + - enum: + - plaintext + - encryption + type: string + - not: {} + hash: + additionalProperties: false + type: object + properties: + hash: + type: string + random: + type: boolean + headers: + items: + additionalProperties: false + type: object + properties: + key: + type: string + value: + type: string + required: + - key + - value + maxItems: 100 + type: array + hosts: + items: + type: string + maxItems: 10 + minItems: 1 + type: array + id: + type: string + is_default: + default: false + type: boolean + is_default_monitoring: + default: false + type: boolean + is_internal: + type: boolean + is_preconfigured: + type: boolean + key: + type: string + name: + type: string + otel_exporter_config_yaml: + nullable: true + type: string + partition: + enum: + - random + - round_robin + - hash + type: string + password: + anyOf: + - items: {} + type: array + - type: boolean + - type: number + - type: object + - type: string + nullable: true + oneOf: + - not: {} + - anyOf: + - items: {} + type: array + - type: boolean + - type: number + - type: object + - type: string + nullable: true + oneOf: + - type: string + - not: {} + proxy_id: + nullable: true + type: string + random: + additionalProperties: false + type: object + properties: + group_events: + type: number + required_acks: + enum: + - 1 + - 0 + - -1 + type: integer + round_robin: + additionalProperties: false + type: object + properties: + group_events: + type: number + sasl: + additionalProperties: false + nullable: true + type: object + properties: + mechanism: + enum: + - PLAIN + - SCRAM-SHA-256 + - SCRAM-SHA-512 + type: string + secrets: + additionalProperties: false + type: object + properties: + password: + anyOf: + - additionalProperties: false + type: object + properties: + hash: + type: string + id: + type: string + required: + - id + - type: string + ssl: + additionalProperties: false type: object properties: - action: - enum: - - convert - type: string - customIdentifier: - description: Custom identifier to correlate this processor across outputs - minLength: 1 - type: string - description: - description: Human-readable notes about this processor step - type: string - from: - description: Source field to convert to a different data type - minLength: 1 - type: string - ignore_failure: - description: Continue pipeline execution if this processor fails - type: boolean - ignore_missing: - description: Skip processing when source field is missing - type: boolean - to: - description: Target field for the converted value (defaults to source) - minLength: 1 - type: string - type: - description: 'Target data type: integer, long, double, boolean, or string' - enum: - - integer - - long - - double - - boolean - - string - type: string - where: - $ref: '#/components/schemas/Kibana_HTTP_APIs_Condition' - description: Conditional expression controlling whether this processor runs + key: + anyOf: + - additionalProperties: false + type: object + properties: + hash: + type: string + id: + type: string + required: + - id + - type: string required: - - action - - from - - type - - additionalProperties: false + - key + shipper: + additionalProperties: false + nullable: true + type: object + properties: + compression_level: + nullable: true + type: number + disk_queue_compression_enabled: + nullable: true + type: boolean + disk_queue_enabled: + default: false + nullable: true + type: boolean + disk_queue_encryption_enabled: + nullable: true + type: boolean + disk_queue_max_size: + nullable: true + type: number + disk_queue_path: + nullable: true + type: string + loadbalance: + nullable: true + type: boolean + max_batch_bytes: + nullable: true + type: number + mem_queue_events: + nullable: true + type: number + queue_flush_timeout: + nullable: true + type: number + required: + - disk_queue_path + - disk_queue_max_size + - disk_queue_encryption_enabled + - disk_queue_compression_enabled + - compression_level + - loadbalance + - mem_queue_events + - queue_flush_timeout + - max_batch_bytes + ssl: + additionalProperties: false + nullable: true + type: object + properties: + certificate: + type: string + certificate_authorities: + items: + type: string + maxItems: 10 + type: array + key: + type: string + verification_mode: + enum: + - full + - none + - certificate + - strict + type: string + timeout: + type: number + topic: + type: string + type: + enum: + - kafka + type: string + username: + anyOf: + - items: {} + type: array + - type: boolean + - type: number + - type: object + - type: string + nullable: true + oneOf: + - type: string + - not: {} + version: + type: string + required: + - name + - compression_level + - connection_type + - username + - password + title: update_output_kafka + type: object + Kibana_HTTP_APIs_update_output_logstash: + additionalProperties: false + properties: + allow_edit: + items: + type: string + maxItems: 1000 + type: array + ca_sha256: + nullable: true + type: string + ca_trusted_fingerprint: + nullable: true + type: string + config_yaml: + nullable: true + type: string + hosts: + items: + type: string + maxItems: 10 + minItems: 1 + type: array + id: + type: string + is_default: + type: boolean + is_default_monitoring: + type: boolean + is_internal: + type: boolean + is_preconfigured: + type: boolean + name: + type: string + otel_exporter_config_yaml: + nullable: true + type: string + proxy_id: + nullable: true + type: string + secrets: + additionalProperties: false + type: object + properties: + ssl: + additionalProperties: false type: object properties: - action: - enum: - - concat - type: string - customIdentifier: - description: Custom identifier to correlate this processor across outputs - minLength: 1 - type: string - description: - description: Human-readable notes about this processor step - type: string - from: - items: - anyOf: - - type: object - properties: - type: - enum: - - field - type: string - value: - minLength: 1 - type: string - required: - - type - - value - - type: object - properties: - type: - enum: - - literal - type: string - value: - type: string - required: - - type - - value - minItems: 1 - type: array - ignore_failure: - description: Continue pipeline execution if this processor fails - type: boolean - ignore_missing: - type: boolean - to: - minLength: 1 - type: string - where: - $ref: '#/components/schemas/Kibana_HTTP_APIs_Condition' - description: Conditional expression controlling whether this processor runs - required: - - action - - from - - to - - allOf: + key: + anyOf: + - additionalProperties: false + type: object + properties: + hash: + type: string + id: + type: string + required: + - id + - type: string + shipper: + additionalProperties: false + nullable: true + type: object + properties: + compression_level: + nullable: true + type: number + disk_queue_compression_enabled: + nullable: true + type: boolean + disk_queue_enabled: + default: false + nullable: true + type: boolean + disk_queue_encryption_enabled: + nullable: true + type: boolean + disk_queue_max_size: + nullable: true + type: number + disk_queue_path: + nullable: true + type: string + loadbalance: + nullable: true + type: boolean + max_batch_bytes: + nullable: true + type: number + mem_queue_events: + nullable: true + type: number + queue_flush_timeout: + nullable: true + type: number + required: + - disk_queue_path + - disk_queue_max_size + - disk_queue_encryption_enabled + - disk_queue_compression_enabled + - compression_level + - loadbalance + - mem_queue_events + - queue_flush_timeout + - max_batch_bytes + ssl: + additionalProperties: false + nullable: true + type: object + properties: + certificate: + type: string + certificate_authorities: + items: + type: string + maxItems: 10 + type: array + key: + type: string + verification_mode: + enum: + - full + - none + - certificate + - strict + type: string + type: + enum: + - logstash + type: string + title: update_output_logstash + type: object + Kibana_HTTP_APIs_update_output_remote_elasticsearch: + additionalProperties: false + properties: + allow_edit: + items: + type: string + maxItems: 1000 + type: array + ca_sha256: + nullable: true + type: string + ca_trusted_fingerprint: + nullable: true + type: string + config_yaml: + nullable: true + type: string + hosts: + items: + format: uri + type: string + maxItems: 10 + minItems: 1 + type: array + id: + type: string + is_default: + type: boolean + is_default_monitoring: + type: boolean + is_internal: + type: boolean + is_preconfigured: + type: boolean + kibana_api_key: + nullable: true + type: string + kibana_url: + nullable: true + type: string + name: + type: string + otel_exporter_config_yaml: + nullable: true + type: string + preset: + enum: + - balanced + - custom + - throughput + - scale + - latency + type: string + proxy_id: + nullable: true + type: string + secrets: + additionalProperties: false + type: object + properties: + service_token: + anyOf: - additionalProperties: false type: object properties: - action: - enum: - - network_direction - type: string - customIdentifier: - description: Custom identifier to correlate this processor across outputs - minLength: 1 - type: string - description: - description: Human-readable notes about this processor step - type: string - destination_ip: - minLength: 1 - type: string - ignore_failure: - description: Continue pipeline execution if this processor fails - type: boolean - ignore_missing: - type: boolean - source_ip: - minLength: 1 + hash: type: string - target_field: - minLength: 1 + id: type: string - where: - $ref: '#/components/schemas/Kibana_HTTP_APIs_Condition' - description: Conditional expression controlling whether this processor runs required: - - action - - source_ip - - destination_ip - - anyOf: - - additionalProperties: false - type: object - properties: - internal_networks: - items: - type: string - type: array - required: - - internal_networks + - id + - type: string + ssl: + additionalProperties: false + type: object + properties: + key: + anyOf: - additionalProperties: false type: object properties: - internal_networks_field: - minLength: 1 + hash: + type: string + id: type: string required: - - internal_networks_field - - additionalProperties: false - description: JsonExtract processor - Extract values from JSON strings using JSONPath-like selectors - type: object - properties: - action: - enum: - - json_extract - type: string - customIdentifier: - description: Custom identifier to correlate this processor across outputs - minLength: 1 - type: string - description: - description: Human-readable notes about this processor step - type: string - extractions: - description: List of extraction specifications - items: - description: A single extraction specification - type: object - properties: - selector: - description: JSONPath-like selector to extract value (e.g., "user.id", "$.metadata.client.ip", "items[0].name") - minLength: 1 - type: string - target_field: - description: Target field to store the extracted value - minLength: 1 - type: string - type: - description: Data type for the extracted value. Defaults to "keyword". Ensures consistent types across transpilers. - enum: - - keyword - - integer - - long - - double - - boolean - type: string - required: - - selector - - target_field - minItems: 1 - type: array - field: - description: Source field containing the JSON string to parse - minLength: 1 - type: string - ignore_failure: - description: Continue pipeline execution if this processor fails - type: boolean - ignore_missing: - description: Skip processing when source field is missing - type: boolean - where: - $ref: '#/components/schemas/Kibana_HTTP_APIs_Condition' - description: Conditional expression controlling whether this processor runs - required: - - action - - field - - extractions - - additionalProperties: false - type: object - properties: - action: - enum: - - enrich - type: string - customIdentifier: - description: Custom identifier to correlate this processor across outputs - minLength: 1 - type: string - description: - description: Human-readable notes about this processor step - type: string - ignore_failure: - description: Continue pipeline execution if this processor fails - type: boolean - ignore_missing: - type: boolean - override: - type: boolean - policy_name: - description: A non-empty string. - minLength: 1 - type: string - to: - minLength: 1 - type: string - where: - $ref: '#/components/schemas/Kibana_HTTP_APIs_Condition' - description: Conditional expression controlling whether this processor runs - required: - - action - - policy_name - - to - - additionalProperties: false - description: Manual ingest pipeline wrapper around native Elasticsearch processors - type: object - properties: - action: - description: Manual ingest pipeline - executes raw Elasticsearch ingest processors - enum: - - manual_ingest_pipeline - type: string - customIdentifier: - description: Custom identifier to correlate this processor across outputs - minLength: 1 - type: string - description: - description: Human-readable notes about this processor step - type: string - ignore_failure: - description: Continue pipeline execution if this processor fails - type: boolean - on_failure: - description: Fallback processors to run when a processor fails - items: - additionalProperties: {} - type: object - type: array - processors: - description: List of raw Elasticsearch ingest processors to run - items: - additionalProperties: {} - type: object - type: array - tag: - description: Optional ingest processor tag for Elasticsearch - type: string - where: - $ref: '#/components/schemas/Kibana_HTTP_APIs_Condition' - description: Conditional expression controlling whether this processor runs - required: - - action - - processors - - $ref: '#/components/schemas/Kibana_HTTP_APIs_StreamlangConditionBlock' - Kibana_HTTP_APIs_StreamUpsertRequest: - anyOf: - - $ref: '#/components/schemas/Kibana_HTTP_APIs_WiredStreamUpsertRequest' - - $ref: '#/components/schemas/Kibana_HTTP_APIs_ClassicStreamUpsertRequest' - - $ref: '#/components/schemas/Kibana_HTTP_APIs_QueryStreamUpsertRequest' + - id + - type: string + service_token: + nullable: true + type: string + shipper: + additionalProperties: false + nullable: true + type: object + properties: + compression_level: + nullable: true + type: number + disk_queue_compression_enabled: + nullable: true + type: boolean + disk_queue_enabled: + default: false + nullable: true + type: boolean + disk_queue_encryption_enabled: + nullable: true + type: boolean + disk_queue_max_size: + nullable: true + type: number + disk_queue_path: + nullable: true + type: string + loadbalance: + nullable: true + type: boolean + max_batch_bytes: + nullable: true + type: number + mem_queue_events: + nullable: true + type: number + queue_flush_timeout: + nullable: true + type: number + required: + - disk_queue_path + - disk_queue_max_size + - disk_queue_encryption_enabled + - disk_queue_compression_enabled + - compression_level + - loadbalance + - mem_queue_events + - queue_flush_timeout + - max_batch_bytes + ssl: + additionalProperties: false + nullable: true + type: object + properties: + certificate: + type: string + certificate_authorities: + items: + type: string + maxItems: 10 + type: array + key: + type: string + verification_mode: + enum: + - full + - none + - certificate + - strict + type: string + sync_integrations: + type: boolean + sync_uninstalled_integrations: + type: boolean + type: + enum: + - remote_elasticsearch + type: string + write_to_logs_streams: + nullable: true + type: boolean + title: update_output_remote_elasticsearch + type: object Kibana_HTTP_APIs_WiredStreamUpsertRequest: additionalProperties: false type: object diff --git a/oas_docs/output/kibana.yaml b/oas_docs/output/kibana.yaml index 71c905c5f34a9..2f77d56a3b9d4 100644 --- a/oas_docs/output/kibana.yaml +++ b/oas_docs/output/kibana.yaml @@ -48170,953 +48170,226 @@ paths: application/json: schema: anyOf: - - additionalProperties: false - type: object - properties: - allow_edit: - items: - type: string - maxItems: 1000 - type: array - ca_sha256: - nullable: true - type: string - ca_trusted_fingerprint: - nullable: true - type: string - config_yaml: - nullable: true - type: string - hosts: - items: - format: uri - type: string - maxItems: 10 - minItems: 1 - type: array - id: - type: string - is_default: - type: boolean - is_default_monitoring: - type: boolean - is_internal: - type: boolean - is_preconfigured: - type: boolean - name: - type: string - preset: - enum: - - balanced - - custom - - throughput - - scale - - latency - type: string - proxy_id: - nullable: true - type: string - secrets: - additionalProperties: false - type: object - properties: - ssl: - additionalProperties: false - type: object - properties: - key: - anyOf: - - additionalProperties: false - type: object - properties: - hash: - type: string - id: - type: string - required: - - id - - type: string - shipper: - additionalProperties: false - nullable: true - type: object - properties: - compression_level: - nullable: true - type: number - disk_queue_compression_enabled: - nullable: true - type: boolean - disk_queue_enabled: - default: false - nullable: true - type: boolean - disk_queue_encryption_enabled: - nullable: true - type: boolean - disk_queue_max_size: - nullable: true - type: number - disk_queue_path: - nullable: true - type: string - loadbalance: - nullable: true - type: boolean - max_batch_bytes: - nullable: true - type: number - mem_queue_events: - nullable: true - type: number - queue_flush_timeout: - nullable: true - type: number - required: - - disk_queue_path - - disk_queue_max_size - - disk_queue_encryption_enabled - - disk_queue_compression_enabled - - compression_level - - loadbalance - - mem_queue_events - - queue_flush_timeout - - max_batch_bytes - ssl: + - $ref: '#/components/schemas/Kibana_HTTP_APIs_update_output_elasticsearch' + - $ref: '#/components/schemas/Kibana_HTTP_APIs_update_output_remote_elasticsearch' + - $ref: '#/components/schemas/Kibana_HTTP_APIs_update_output_logstash' + - $ref: '#/components/schemas/Kibana_HTTP_APIs_update_output_kafka' + responses: + '200': + content: + application/json: + schema: + additionalProperties: false + type: object + properties: + item: + anyOf: + - $ref: '#/components/schemas/Kibana_HTTP_APIs_output_elasticsearch' + - $ref: '#/components/schemas/Kibana_HTTP_APIs_output_remote_elasticsearch' + - $ref: '#/components/schemas/Kibana_HTTP_APIs_output_logstash' + - $ref: '#/components/schemas/Kibana_HTTP_APIs_output_kafka' + required: + - item + description: 'OK: A successful request.' + '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 + description: A bad request. + summary: Update output + tags: + - Fleet outputs + x-metaTags: + - content: Kibana + name: product_name + /api/fleet/outputs/{outputId}/health: + get: + description: |- + **Spaces method and path for this operation:** + +
get /s/{space_id}/api/fleet/outputs/{outputId}/health
+ + Refer to [Spaces](https://www.elastic.co/docs/deploy-manage/manage-spaces) for more information. + + [Required authorization] Route required privileges: fleet-settings-read. + operationId: get-fleet-outputs-outputid-health + parameters: + - in: path + name: outputId + required: true + schema: + type: string + responses: + '200': + content: + application/json: + schema: + additionalProperties: false + type: object + properties: + message: + description: long message if unhealthy + type: string + state: + description: state of output, HEALTHY or DEGRADED + type: string + timestamp: + description: timestamp of reported state + type: string + required: + - state + - message + - timestamp + description: 'OK: A successful request.' + '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 + description: A bad request. + summary: Get the latest output health + tags: + - Fleet outputs + x-metaTags: + - content: Kibana + name: product_name + /api/fleet/package_policies: + get: + operationId: get-fleet-package-policies + parameters: + - in: query + name: page + required: false + schema: + type: number + - in: query + name: perPage + required: false + schema: + type: number + - in: query + name: sortField + required: false + schema: + type: string + - in: query + name: sortOrder + required: false + schema: + enum: + - desc + - asc + type: string + - in: query + name: showUpgradeable + required: false + schema: + type: boolean + - in: query + name: kuery + required: false + schema: + type: string + - in: query + name: format + required: false + schema: + enum: + - simplified + - legacy + type: string + - in: query + name: withAgentCount + required: false + schema: + type: boolean + responses: + '200': + content: + application/json: + schema: + additionalProperties: false + type: object + properties: + items: + items: additionalProperties: false - nullable: true type: object properties: - certificate: - type: string - certificate_authorities: + additional_datastreams_permissions: + description: Additional datastream permissions, that will be added to the agent policy. items: type: string - maxItems: 10 - type: array - key: - type: string - verification_mode: - enum: - - full - - none - - certificate - - strict - type: string - type: - enum: - - elasticsearch - type: string - write_to_logs_streams: - nullable: true - type: boolean - - additionalProperties: false - type: object - properties: - allow_edit: - items: - type: string - maxItems: 1000 - type: array - ca_sha256: - nullable: true - type: string - ca_trusted_fingerprint: - nullable: true - type: string - config_yaml: - nullable: true - type: string - hosts: - items: - format: uri - type: string - maxItems: 10 - minItems: 1 - type: array - id: - type: string - is_default: - type: boolean - is_default_monitoring: - type: boolean - is_internal: - type: boolean - is_preconfigured: - type: boolean - kibana_api_key: - nullable: true - type: string - kibana_url: - nullable: true - type: string - name: - type: string - preset: - enum: - - balanced - - custom - - throughput - - scale - - latency - type: string - proxy_id: - nullable: true - type: string - secrets: - additionalProperties: false - type: object - properties: - service_token: - anyOf: - - additionalProperties: false - type: object - properties: - hash: - type: string - id: - type: string - required: - - id - - type: string - ssl: - additionalProperties: false - type: object - properties: - key: - anyOf: - - additionalProperties: false - type: object - properties: - hash: - type: string - id: - type: string - required: - - id - - type: string - service_token: - nullable: true - type: string - shipper: - additionalProperties: false - nullable: true - type: object - properties: - compression_level: - nullable: true - type: number - disk_queue_compression_enabled: - nullable: true - type: boolean - disk_queue_enabled: - default: false - nullable: true - type: boolean - disk_queue_encryption_enabled: - nullable: true - type: boolean - disk_queue_max_size: + maxItems: 1000 nullable: true + type: array + agents: type: number - disk_queue_path: + cloud_connector_id: + description: ID of the cloud connector associated with this package policy. nullable: true type: string - loadbalance: - nullable: true - type: boolean - max_batch_bytes: - nullable: true - type: number - mem_queue_events: - nullable: true - type: number - queue_flush_timeout: + cloud_connector_name: + description: Transient field for cloud connector name during creation. + maxLength: 255 + minLength: 1 nullable: true - type: number - required: - - disk_queue_path - - disk_queue_max_size - - disk_queue_encryption_enabled - - disk_queue_compression_enabled - - compression_level - - loadbalance - - mem_queue_events - - queue_flush_timeout - - max_batch_bytes - ssl: - additionalProperties: false - nullable: true - type: object - properties: - certificate: type: string - certificate_authorities: - items: - type: string - maxItems: 10 - type: array - key: + created_at: type: string - verification_mode: - enum: - - full - - none - - certificate - - strict + created_by: type: string - sync_integrations: - type: boolean - sync_uninstalled_integrations: - type: boolean - type: - enum: - - remote_elasticsearch - type: string - write_to_logs_streams: - nullable: true - type: boolean - - additionalProperties: false - type: object - properties: - allow_edit: - items: - type: string - maxItems: 1000 - type: array - ca_sha256: - nullable: true - type: string - ca_trusted_fingerprint: - nullable: true - type: string - config_yaml: - nullable: true - type: string - hosts: - items: - type: string - maxItems: 10 - minItems: 1 - type: array - id: - type: string - is_default: - type: boolean - is_default_monitoring: - type: boolean - is_internal: - type: boolean - is_preconfigured: - type: boolean - name: - type: string - proxy_id: - nullable: true - type: string - secrets: - additionalProperties: false - type: object - properties: - ssl: - additionalProperties: false + description: + description: Package policy description + type: string + elasticsearch: + additionalProperties: true type: object properties: - key: - anyOf: - - additionalProperties: false - type: object - properties: - hash: - type: string - id: - type: string - required: - - id - - type: string - shipper: - additionalProperties: false - nullable: true - type: object - properties: - compression_level: - nullable: true - type: number - disk_queue_compression_enabled: - nullable: true - type: boolean - disk_queue_enabled: - default: false - nullable: true - type: boolean - disk_queue_encryption_enabled: - nullable: true - type: boolean - disk_queue_max_size: - nullable: true - type: number - disk_queue_path: - nullable: true - type: string - loadbalance: - nullable: true + privileges: + additionalProperties: true + type: object + properties: + cluster: + items: + type: string + maxItems: 100 + type: array + enabled: type: boolean - max_batch_bytes: - nullable: true - type: number - mem_queue_events: - nullable: true - type: number - queue_flush_timeout: - nullable: true - type: number - required: - - disk_queue_path - - disk_queue_max_size - - disk_queue_encryption_enabled - - disk_queue_compression_enabled - - compression_level - - loadbalance - - mem_queue_events - - queue_flush_timeout - - max_batch_bytes - ssl: - additionalProperties: false - nullable: true - type: object - properties: - certificate: - type: string - certificate_authorities: - items: - type: string - maxItems: 10 - type: array - key: - type: string - verification_mode: - enum: - - full - - none - - certificate - - strict - type: string - type: - enum: - - logstash - type: string - - additionalProperties: false - type: object - properties: - allow_edit: - items: - type: string - maxItems: 1000 - type: array - auth_type: - enum: - - none - - user_pass - - ssl - - kerberos - type: string - broker_timeout: - type: number - ca_sha256: - nullable: true - type: string - ca_trusted_fingerprint: - nullable: true - type: string - client_id: - type: string - compression: - enum: - - gzip - - snappy - - lz4 - - none - type: string - compression_level: - anyOf: - - items: {} - type: array - - type: boolean - - type: number - - type: object - - type: string - nullable: true - oneOf: - - type: number - - not: {} - config_yaml: - nullable: true - type: string - connection_type: - anyOf: - - items: {} - type: array - - type: boolean - - type: number - - type: object - - type: string - nullable: true - oneOf: - - enum: - - plaintext - - encryption - type: string - - not: {} - hash: - additionalProperties: false - type: object - properties: - hash: - type: string - random: - type: boolean - headers: - items: - additionalProperties: false - type: object - properties: - key: - type: string - value: - type: string - required: - - key - - value - maxItems: 100 - type: array - hosts: - items: - type: string - maxItems: 10 - minItems: 1 - type: array - id: - type: string - is_default: - default: false - type: boolean - is_default_monitoring: - default: false - type: boolean - is_internal: - type: boolean - is_preconfigured: - type: boolean - key: - type: string - name: - type: string - partition: - enum: - - random - - round_robin - - hash - type: string - password: - anyOf: - - items: {} - type: array - - type: boolean - - type: number - - type: object - - type: string - nullable: true - oneOf: - - not: {} - - anyOf: - - items: {} - type: array - - type: boolean - - type: number - - type: object - - type: string - nullable: true - oneOf: - - type: string - - not: {} - proxy_id: - nullable: true - type: string - random: - additionalProperties: false - type: object - properties: - group_events: - type: number - required_acks: - enum: - - 1 - - 0 - - -1 - type: integer - round_robin: - additionalProperties: false - type: object - properties: - group_events: - type: number - sasl: - additionalProperties: false - nullable: true - type: object - properties: - mechanism: - enum: - - PLAIN - - SCRAM-SHA-256 - - SCRAM-SHA-512 - type: string - secrets: - additionalProperties: false - type: object - properties: - password: - anyOf: - - additionalProperties: false - type: object - properties: - hash: - type: string - id: - type: string - required: - - id - - type: string - ssl: - additionalProperties: false - type: object - properties: - key: - anyOf: - - additionalProperties: false - type: object - properties: - hash: - type: string - id: - type: string - required: - - id - - type: string - required: - - key - shipper: - additionalProperties: false - nullable: true - type: object - properties: - compression_level: - nullable: true - type: number - disk_queue_compression_enabled: - nullable: true - type: boolean - disk_queue_enabled: - default: false - nullable: true - type: boolean - disk_queue_encryption_enabled: - nullable: true - type: boolean - disk_queue_max_size: - nullable: true - type: number - disk_queue_path: - nullable: true - type: string - loadbalance: - nullable: true - type: boolean - max_batch_bytes: - nullable: true - type: number - mem_queue_events: - nullable: true - type: number - queue_flush_timeout: - nullable: true - type: number - required: - - disk_queue_path - - disk_queue_max_size - - disk_queue_encryption_enabled - - disk_queue_compression_enabled - - compression_level - - loadbalance - - mem_queue_events - - queue_flush_timeout - - max_batch_bytes - ssl: - additionalProperties: false - nullable: true - type: object - properties: - certificate: - type: string - certificate_authorities: - items: - type: string - maxItems: 10 - type: array - key: - type: string - verification_mode: - enum: - - full - - none - - certificate - - strict - type: string - timeout: - type: number - topic: - type: string - type: - enum: - - kafka - type: string - username: - anyOf: - - items: {} - type: array - - type: boolean - - type: number - - type: object - - type: string - nullable: true - oneOf: - - type: string - - not: {} - version: - type: string - required: - - name - - compression_level - - connection_type - - username - - password - responses: - '200': - content: - application/json: - schema: - additionalProperties: false - type: object - properties: - item: - anyOf: - - $ref: '#/components/schemas/Kibana_HTTP_APIs_output_elasticsearch' - - $ref: '#/components/schemas/Kibana_HTTP_APIs_output_remote_elasticsearch' - - $ref: '#/components/schemas/Kibana_HTTP_APIs_output_logstash' - - $ref: '#/components/schemas/Kibana_HTTP_APIs_output_kafka' - required: - - item - description: 'OK: A successful request.' - '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 - description: A bad request. - summary: Update output - tags: - - Fleet outputs - x-metaTags: - - content: Kibana - name: product_name - /api/fleet/outputs/{outputId}/health: - get: - description: |- - **Spaces method and path for this operation:** - -
get /s/{space_id}/api/fleet/outputs/{outputId}/health
- - Refer to [Spaces](https://www.elastic.co/docs/deploy-manage/manage-spaces) for more information. - - [Required authorization] Route required privileges: fleet-settings-read. - operationId: get-fleet-outputs-outputid-health - parameters: - - in: path - name: outputId - required: true - schema: - type: string - responses: - '200': - content: - application/json: - schema: - additionalProperties: false - type: object - properties: - message: - description: long message if unhealthy - type: string - state: - description: state of output, HEALTHY or DEGRADED - type: string - timestamp: - description: timestamp of reported state - type: string - required: - - state - - message - - timestamp - description: 'OK: A successful request.' - '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 - description: A bad request. - summary: Get the latest output health - tags: - - Fleet outputs - x-metaTags: - - content: Kibana - name: product_name - /api/fleet/package_policies: - get: - operationId: get-fleet-package-policies - parameters: - - in: query - name: page - required: false - schema: - type: number - - in: query - name: perPage - required: false - schema: - type: number - - in: query - name: sortField - required: false - schema: - type: string - - in: query - name: sortOrder - required: false - schema: - enum: - - desc - - asc - type: string - - in: query - name: showUpgradeable - required: false - schema: - type: boolean - - in: query - name: kuery - required: false - schema: - type: string - - in: query - name: format - required: false - schema: - enum: - - simplified - - legacy - type: string - - in: query - name: withAgentCount - required: false - schema: - type: boolean - responses: - '200': - content: - application/json: - schema: - additionalProperties: false - type: object - properties: - items: - items: - additionalProperties: false - type: object - properties: - additional_datastreams_permissions: - description: Additional datastream permissions, that will be added to the agent policy. - items: - type: string - maxItems: 1000 - nullable: true - type: array - agents: - type: number - cloud_connector_id: - description: ID of the cloud connector associated with this package policy. - nullable: true - type: string - cloud_connector_name: - description: Transient field for cloud connector name during creation. - maxLength: 255 - minLength: 1 - nullable: true - type: string - created_at: - type: string - created_by: - type: string - description: - description: Package policy description - type: string - elasticsearch: - additionalProperties: true - type: object - properties: - privileges: - additionalProperties: true - type: object - properties: - cluster: - items: - type: string - maxItems: 100 - type: array - enabled: - type: boolean - id: - description: Package policy unique identifier. + id: + description: Package policy unique identifier. type: string inputs: anyOf: @@ -82011,6 +81284,9 @@ components: type: boolean name: type: string + otel_exporter_config_yaml: + nullable: true + type: string preset: enum: - balanced @@ -82228,6 +81504,9 @@ components: type: string name: type: string + otel_exporter_config_yaml: + nullable: true + type: string partition: enum: - random @@ -82459,6 +81738,9 @@ components: type: boolean name: type: string + otel_exporter_config_yaml: + nullable: true + type: string proxy_id: nullable: true type: string @@ -82603,6 +81885,9 @@ components: type: string name: type: string + otel_exporter_config_yaml: + nullable: true + type: string preset: enum: - balanced @@ -82771,6 +82056,9 @@ components: type: boolean name: type: string + otel_exporter_config_yaml: + nullable: true + type: string preset: enum: - balanced @@ -82988,6 +82276,9 @@ components: type: string name: type: string + otel_exporter_config_yaml: + nullable: true + type: string partition: enum: - random @@ -83219,6 +82510,9 @@ components: type: boolean name: type: string + otel_exporter_config_yaml: + nullable: true + type: string proxy_id: nullable: true type: string @@ -83363,6 +82657,9 @@ components: type: string name: type: string + otel_exporter_config_yaml: + nullable: true + type: string preset: enum: - balanced @@ -84575,6 +83872,757 @@ components: - $ref: '#/components/schemas/Kibana_HTTP_APIs_WiredStreamUpsertRequest' - $ref: '#/components/schemas/Kibana_HTTP_APIs_ClassicStreamUpsertRequest' - $ref: '#/components/schemas/Kibana_HTTP_APIs_QueryStreamUpsertRequest' + Kibana_HTTP_APIs_update_output_elasticsearch: + additionalProperties: false + properties: + allow_edit: + items: + type: string + maxItems: 1000 + type: array + ca_sha256: + nullable: true + type: string + ca_trusted_fingerprint: + nullable: true + type: string + config_yaml: + nullable: true + type: string + hosts: + items: + format: uri + type: string + maxItems: 10 + minItems: 1 + type: array + id: + type: string + is_default: + type: boolean + is_default_monitoring: + type: boolean + is_internal: + type: boolean + is_preconfigured: + type: boolean + name: + type: string + otel_exporter_config_yaml: + nullable: true + type: string + preset: + enum: + - balanced + - custom + - throughput + - scale + - latency + type: string + proxy_id: + nullable: true + type: string + secrets: + additionalProperties: false + type: object + properties: + ssl: + additionalProperties: false + type: object + properties: + key: + anyOf: + - additionalProperties: false + type: object + properties: + hash: + type: string + id: + type: string + required: + - id + - type: string + shipper: + additionalProperties: false + nullable: true + type: object + properties: + compression_level: + nullable: true + type: number + disk_queue_compression_enabled: + nullable: true + type: boolean + disk_queue_enabled: + default: false + nullable: true + type: boolean + disk_queue_encryption_enabled: + nullable: true + type: boolean + disk_queue_max_size: + nullable: true + type: number + disk_queue_path: + nullable: true + type: string + loadbalance: + nullable: true + type: boolean + max_batch_bytes: + nullable: true + type: number + mem_queue_events: + nullable: true + type: number + queue_flush_timeout: + nullable: true + type: number + required: + - disk_queue_path + - disk_queue_max_size + - disk_queue_encryption_enabled + - disk_queue_compression_enabled + - compression_level + - loadbalance + - mem_queue_events + - queue_flush_timeout + - max_batch_bytes + ssl: + additionalProperties: false + nullable: true + type: object + properties: + certificate: + type: string + certificate_authorities: + items: + type: string + maxItems: 10 + type: array + key: + type: string + verification_mode: + enum: + - full + - none + - certificate + - strict + type: string + type: + enum: + - elasticsearch + type: string + write_to_logs_streams: + nullable: true + type: boolean + title: update_output_elasticsearch + type: object + Kibana_HTTP_APIs_update_output_kafka: + additionalProperties: false + properties: + allow_edit: + items: + type: string + maxItems: 1000 + type: array + auth_type: + enum: + - none + - user_pass + - ssl + - kerberos + type: string + broker_timeout: + type: number + ca_sha256: + nullable: true + type: string + ca_trusted_fingerprint: + nullable: true + type: string + client_id: + type: string + compression: + enum: + - gzip + - snappy + - lz4 + - none + type: string + compression_level: + anyOf: + - items: {} + type: array + - type: boolean + - type: number + - type: object + - type: string + nullable: true + oneOf: + - type: number + - not: {} + config_yaml: + nullable: true + type: string + connection_type: + anyOf: + - items: {} + type: array + - type: boolean + - type: number + - type: object + - type: string + nullable: true + oneOf: + - enum: + - plaintext + - encryption + type: string + - not: {} + hash: + additionalProperties: false + type: object + properties: + hash: + type: string + random: + type: boolean + headers: + items: + additionalProperties: false + type: object + properties: + key: + type: string + value: + type: string + required: + - key + - value + maxItems: 100 + type: array + hosts: + items: + type: string + maxItems: 10 + minItems: 1 + type: array + id: + type: string + is_default: + default: false + type: boolean + is_default_monitoring: + default: false + type: boolean + is_internal: + type: boolean + is_preconfigured: + type: boolean + key: + type: string + name: + type: string + otel_exporter_config_yaml: + nullable: true + type: string + partition: + enum: + - random + - round_robin + - hash + type: string + password: + anyOf: + - items: {} + type: array + - type: boolean + - type: number + - type: object + - type: string + nullable: true + oneOf: + - not: {} + - anyOf: + - items: {} + type: array + - type: boolean + - type: number + - type: object + - type: string + nullable: true + oneOf: + - type: string + - not: {} + proxy_id: + nullable: true + type: string + random: + additionalProperties: false + type: object + properties: + group_events: + type: number + required_acks: + enum: + - 1 + - 0 + - -1 + type: integer + round_robin: + additionalProperties: false + type: object + properties: + group_events: + type: number + sasl: + additionalProperties: false + nullable: true + type: object + properties: + mechanism: + enum: + - PLAIN + - SCRAM-SHA-256 + - SCRAM-SHA-512 + type: string + secrets: + additionalProperties: false + type: object + properties: + password: + anyOf: + - additionalProperties: false + type: object + properties: + hash: + type: string + id: + type: string + required: + - id + - type: string + ssl: + additionalProperties: false + type: object + properties: + key: + anyOf: + - additionalProperties: false + type: object + properties: + hash: + type: string + id: + type: string + required: + - id + - type: string + required: + - key + shipper: + additionalProperties: false + nullable: true + type: object + properties: + compression_level: + nullable: true + type: number + disk_queue_compression_enabled: + nullable: true + type: boolean + disk_queue_enabled: + default: false + nullable: true + type: boolean + disk_queue_encryption_enabled: + nullable: true + type: boolean + disk_queue_max_size: + nullable: true + type: number + disk_queue_path: + nullable: true + type: string + loadbalance: + nullable: true + type: boolean + max_batch_bytes: + nullable: true + type: number + mem_queue_events: + nullable: true + type: number + queue_flush_timeout: + nullable: true + type: number + required: + - disk_queue_path + - disk_queue_max_size + - disk_queue_encryption_enabled + - disk_queue_compression_enabled + - compression_level + - loadbalance + - mem_queue_events + - queue_flush_timeout + - max_batch_bytes + ssl: + additionalProperties: false + nullable: true + type: object + properties: + certificate: + type: string + certificate_authorities: + items: + type: string + maxItems: 10 + type: array + key: + type: string + verification_mode: + enum: + - full + - none + - certificate + - strict + type: string + timeout: + type: number + topic: + type: string + type: + enum: + - kafka + type: string + username: + anyOf: + - items: {} + type: array + - type: boolean + - type: number + - type: object + - type: string + nullable: true + oneOf: + - type: string + - not: {} + version: + type: string + required: + - name + - compression_level + - connection_type + - username + - password + title: update_output_kafka + type: object + Kibana_HTTP_APIs_update_output_logstash: + additionalProperties: false + properties: + allow_edit: + items: + type: string + maxItems: 1000 + type: array + ca_sha256: + nullable: true + type: string + ca_trusted_fingerprint: + nullable: true + type: string + config_yaml: + nullable: true + type: string + hosts: + items: + type: string + maxItems: 10 + minItems: 1 + type: array + id: + type: string + is_default: + type: boolean + is_default_monitoring: + type: boolean + is_internal: + type: boolean + is_preconfigured: + type: boolean + name: + type: string + otel_exporter_config_yaml: + nullable: true + type: string + proxy_id: + nullable: true + type: string + secrets: + additionalProperties: false + type: object + properties: + ssl: + additionalProperties: false + type: object + properties: + key: + anyOf: + - additionalProperties: false + type: object + properties: + hash: + type: string + id: + type: string + required: + - id + - type: string + shipper: + additionalProperties: false + nullable: true + type: object + properties: + compression_level: + nullable: true + type: number + disk_queue_compression_enabled: + nullable: true + type: boolean + disk_queue_enabled: + default: false + nullable: true + type: boolean + disk_queue_encryption_enabled: + nullable: true + type: boolean + disk_queue_max_size: + nullable: true + type: number + disk_queue_path: + nullable: true + type: string + loadbalance: + nullable: true + type: boolean + max_batch_bytes: + nullable: true + type: number + mem_queue_events: + nullable: true + type: number + queue_flush_timeout: + nullable: true + type: number + required: + - disk_queue_path + - disk_queue_max_size + - disk_queue_encryption_enabled + - disk_queue_compression_enabled + - compression_level + - loadbalance + - mem_queue_events + - queue_flush_timeout + - max_batch_bytes + ssl: + additionalProperties: false + nullable: true + type: object + properties: + certificate: + type: string + certificate_authorities: + items: + type: string + maxItems: 10 + type: array + key: + type: string + verification_mode: + enum: + - full + - none + - certificate + - strict + type: string + type: + enum: + - logstash + type: string + title: update_output_logstash + type: object + Kibana_HTTP_APIs_update_output_remote_elasticsearch: + additionalProperties: false + properties: + allow_edit: + items: + type: string + maxItems: 1000 + type: array + ca_sha256: + nullable: true + type: string + ca_trusted_fingerprint: + nullable: true + type: string + config_yaml: + nullable: true + type: string + hosts: + items: + format: uri + type: string + maxItems: 10 + minItems: 1 + type: array + id: + type: string + is_default: + type: boolean + is_default_monitoring: + type: boolean + is_internal: + type: boolean + is_preconfigured: + type: boolean + kibana_api_key: + nullable: true + type: string + kibana_url: + nullable: true + type: string + name: + type: string + otel_exporter_config_yaml: + nullable: true + type: string + preset: + enum: + - balanced + - custom + - throughput + - scale + - latency + type: string + proxy_id: + nullable: true + type: string + secrets: + additionalProperties: false + type: object + properties: + service_token: + anyOf: + - additionalProperties: false + type: object + properties: + hash: + type: string + id: + type: string + required: + - id + - type: string + ssl: + additionalProperties: false + type: object + properties: + key: + anyOf: + - additionalProperties: false + type: object + properties: + hash: + type: string + id: + type: string + required: + - id + - type: string + service_token: + nullable: true + type: string + shipper: + additionalProperties: false + nullable: true + type: object + properties: + compression_level: + nullable: true + type: number + disk_queue_compression_enabled: + nullable: true + type: boolean + disk_queue_enabled: + default: false + nullable: true + type: boolean + disk_queue_encryption_enabled: + nullable: true + type: boolean + disk_queue_max_size: + nullable: true + type: number + disk_queue_path: + nullable: true + type: string + loadbalance: + nullable: true + type: boolean + max_batch_bytes: + nullable: true + type: number + mem_queue_events: + nullable: true + type: number + queue_flush_timeout: + nullable: true + type: number + required: + - disk_queue_path + - disk_queue_max_size + - disk_queue_encryption_enabled + - disk_queue_compression_enabled + - compression_level + - loadbalance + - mem_queue_events + - queue_flush_timeout + - max_batch_bytes + ssl: + additionalProperties: false + nullable: true + type: object + properties: + certificate: + type: string + certificate_authorities: + items: + type: string + maxItems: 10 + type: array + key: + type: string + verification_mode: + enum: + - full + - none + - certificate + - strict + type: string + sync_integrations: + type: boolean + sync_uninstalled_integrations: + type: boolean + type: + enum: + - remote_elasticsearch + type: string + write_to_logs_streams: + nullable: true + type: boolean + title: update_output_remote_elasticsearch + type: object Kibana_HTTP_APIs_WiredStreamUpsertRequest: additionalProperties: false type: object diff --git a/packages/kbn-api-contracts/allowlist.json b/packages/kbn-api-contracts/allowlist.json index de213ad39bb82..916f53a8c1aab 100644 --- a/packages/kbn-api-contracts/allowlist.json +++ b/packages/kbn-api-contracts/allowlist.json @@ -9,6 +9,13 @@ "approvedBy": "@elastic/terraform-provider", "prUrl": "https://github.com/elastic/kibana/pull/258986" }, + { + "path": "/api/fleet/outputs/{outputId}", + "method": "put", + "reason": "PUT request body uses UpdateOutputSchema with meta IDs, changing inline anyOf members to $ref components. Data shape is identical; adds otel_exporter_config_yaml field.", + "approvedBy": "elastic/fleet", + "prUrl": "https://github.com/elastic/kibana/pull/259308" + }, { "path": "/api/fleet/agent_policies", "method": "get", diff --git a/packages/kbn-check-saved-objects-cli/current_fields.json b/packages/kbn-check-saved-objects-cli/current_fields.json index 1c1107206a89c..e0cb20ebb5338 100644 --- a/packages/kbn-check-saved-objects-cli/current_fields.json +++ b/packages/kbn-check-saved-objects-cli/current_fields.json @@ -859,6 +859,7 @@ "is_preconfigured", "key", "name", + "otel_exporter_config_yaml", "output_id", "partition", "password", diff --git a/packages/kbn-check-saved-objects-cli/current_mappings.json b/packages/kbn-check-saved-objects-cli/current_mappings.json index 9d5ce9704d874..ef0384038bc90 100644 --- a/packages/kbn-check-saved-objects-cli/current_mappings.json +++ b/packages/kbn-check-saved-objects-cli/current_mappings.json @@ -2849,6 +2849,9 @@ "name": { "type": "keyword" }, + "otel_exporter_config_yaml": { + "type": "text" + }, "output_id": { "index": false, "type": "keyword" diff --git a/packages/kbn-check-saved-objects-cli/src/migrations/__fixtures__/ingest-outputs/10.9.0.json b/packages/kbn-check-saved-objects-cli/src/migrations/__fixtures__/ingest-outputs/10.9.0.json new file mode 100644 index 0000000000000..7e0d38967ea81 --- /dev/null +++ b/packages/kbn-check-saved-objects-cli/src/migrations/__fixtures__/ingest-outputs/10.9.0.json @@ -0,0 +1,22 @@ +{ + "10.8.0": [ + { + "name": "default", + "type": "elasticsearch", + "is_default": true, + "is_default_monitoring": true, + "hosts": ["https://localhost:9200"], + "preset": "balanced" + } + ], + "10.9.0": [ + { + "name": "default", + "type": "elasticsearch", + "is_default": true, + "is_default_monitoring": true, + "hosts": ["https://localhost:9200"], + "preset": "balanced" + } + ] +} diff --git a/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts b/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts index 453fe5b5e8c54..1dcb59486a566 100644 --- a/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts +++ b/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts @@ -134,7 +134,7 @@ describe('checking migration metadata changes on all registered SO types', () => "infrastructure-ui-source": "498c2ba7abd4329a0d8b40efd98b4b16991107512d38141707f9f2e10521b367", "ingest-agent-policies": "ce61ba4808deecd27dce770799be59f212ebe1c0d76bcc4298aafa4cfce7aa15", "ingest-download-sources": "c87e062ef293585e85fccec0c865d7cef48e0ff9a919d7781d5f7627d275484b", - "ingest-outputs": "4f3451469b080548fd0f2ca414a81d91bd0d5690c34378376433ab1ae960ce5c", + "ingest-outputs": "b5c8354ebfb71f5d50322c19787bbee2c5bb8fff5bfff46dc5683d19e94797a3", "ingest-package-policies": "7817460ef093393f7fce067f91186003e41246a69f32344b1cd68fe19f43a24e", "ingest_manager_settings": "6cd91fe6c52c516676d99021f51a4b3a162686880198ba3c556983f5fffbb5a3", "integration-config": "b5fba732f6835532e971c81f5703c3c2018fa93686e83a5c2dd9c56cb4e10578", @@ -851,8 +851,9 @@ describe('checking migration metadata changes on all registered SO types', () => "ingest-download-sources|10.1.0: 7fce3be244f92bb99b17c8757c39a49aec078ff90cae70971e42e202a574348c", "================================================================================================", "ingest-outputs|global: 3e72116f17fda6ec9c5269cb42eb42e3f686b313", - "ingest-outputs|mappings: a88cd423056155f954a3877a082c0f8d1273468a", + "ingest-outputs|mappings: bdde67dc29cfd86a1195ed34a4417073728691c4", "ingest-outputs|schemas: da39a3ee5e6b4b0d3255bfef95601890afd80709", + "ingest-outputs|10.9.0: 50a325af05e7b9b3f7383f1e525388c9cecf00a14b9924409a262f6c3058840b", "ingest-outputs|10.8.0: 7fce3be244f92bb99b17c8757c39a49aec078ff90cae70971e42e202a574348c", "ingest-outputs|10.7.0: 2f5dfca42d489deaa60da45c020e92fdae21e5e3d0e5e60153c0d18039715bd7", "ingest-outputs|10.6.0: f224697a876b316945536829900df70c8c6af40c28ccd1b1be4854a1df7442dc", @@ -1485,7 +1486,7 @@ describe('checking migration metadata changes on all registered SO types', () => "infrastructure-ui-source": "10.0.0", "ingest-agent-policies": "10.10.0", "ingest-download-sources": "10.1.0", - "ingest-outputs": "10.8.0", + "ingest-outputs": "10.9.0", "ingest-package-policies": "10.22.0", "ingest_manager_settings": "10.8.0", "integration-config": "10.2.0", @@ -1650,7 +1651,7 @@ describe('checking migration metadata changes on all registered SO types', () => "infrastructure-ui-source": "7.16.2", "ingest-agent-policies": "10.10.0", "ingest-download-sources": "10.1.0", - "ingest-outputs": "10.8.0", + "ingest-outputs": "10.9.0", "ingest-package-policies": "10.22.0", "ingest_manager_settings": "10.8.0", "integration-config": "10.2.0", diff --git a/x-pack/platform/plugins/shared/encrypted_saved_objects/integration_tests/ci_checks/check_registered_types.test.ts b/x-pack/platform/plugins/shared/encrypted_saved_objects/integration_tests/ci_checks/check_registered_types.test.ts index 6abffbc8f98e2..83559a4bdbdd8 100644 --- a/x-pack/platform/plugins/shared/encrypted_saved_objects/integration_tests/ci_checks/check_registered_types.test.ts +++ b/x-pack/platform/plugins/shared/encrypted_saved_objects/integration_tests/ci_checks/check_registered_types.test.ts @@ -140,6 +140,7 @@ describe('checking changes on all registered encrypted SO types', () => { "fleet-fleet-server-host|1", "fleet-uninstall-tokens|1", "ingest-download-sources|1", + "ingest-outputs|9", "ingest-outputs|8", "ingest-outputs|7", "ingest-outputs|6", diff --git a/x-pack/platform/plugins/shared/fleet/common/types/models/output.ts b/x-pack/platform/plugins/shared/fleet/common/types/models/output.ts index ae4cb15e060b5..e37ae965e3dea 100644 --- a/x-pack/platform/plugins/shared/fleet/common/types/models/output.ts +++ b/x-pack/platform/plugins/shared/fleet/common/types/models/output.ts @@ -54,6 +54,7 @@ interface NewBaseOutput { export interface NewElasticsearchOutput extends NewBaseOutput { type: OutputType['Elasticsearch']; + otel_exporter_config_yaml?: string | null; } export interface NewRemoteElasticsearchOutput extends NewBaseOutput { diff --git a/x-pack/platform/plugins/shared/fleet/cypress/e2e/fleet_settings_outputs.cy.ts b/x-pack/platform/plugins/shared/fleet/cypress/e2e/fleet_settings_outputs.cy.ts index 66801b8e692d0..dd34b996e411e 100644 --- a/x-pack/platform/plugins/shared/fleet/cypress/e2e/fleet_settings_outputs.cy.ts +++ b/x-pack/platform/plugins/shared/fleet/cypress/e2e/fleet_settings_outputs.cy.ts @@ -37,11 +37,15 @@ import { login } from '../tasks/login'; import { visit } from '../tasks/common'; export const fillYamlConfigBox = (query: string) => { - cy.get('[data-test-subj="kibanaCodeEditor"] textarea').type(query, { force: true }); + cy.get( + '[data-test-subj="settingsOutputsFlyout.yamlConfigInput"] [data-test-subj="kibanaCodeEditor"] textarea' + ).type(query, { force: true }); }; export const clearYamlConfigBox = () => { - cy.get('[data-test-subj="kibanaCodeEditor"] textarea').clear({ force: true }); + cy.get( + '[data-test-subj="settingsOutputsFlyout.yamlConfigInput"] [data-test-subj="kibanaCodeEditor"] textarea' + ).clear({ force: true }); }; describe('Outputs', () => { diff --git a/x-pack/platform/plugins/shared/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/index.test.tsx b/x-pack/platform/plugins/shared/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/index.test.tsx index eb20419b35629..82aa3bdef78f7 100644 --- a/x-pack/platform/plugins/shared/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/index.test.tsx +++ b/x-pack/platform/plugins/shared/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/index.test.tsx @@ -481,6 +481,137 @@ describe('EditOutputFlyout', () => { }); }); + describe('OpenTelemetry Exporter section', () => { + it('should show the OTel exporter configuration section for ES output', async () => { + const { utils } = renderFlyout({ + type: 'elasticsearch', + name: 'elasticsearch output', + id: 'output123', + is_default: false, + is_default_monitoring: false, + }); + + expect(utils.queryByText('OpenTelemetry exporter')).not.toBeNull(); + + // Expand the accordion to reveal the YAML editor + fireEvent.click(utils.getByText('OpenTelemetry exporter')); + expect(utils.queryByLabelText('Advanced YAML configuration')).not.toBeNull(); + }); + + it('should not show the OTel exporter section for logstash output', async () => { + const { utils } = renderFlyout({ + type: 'logstash', + name: 'logstash output', + id: 'output123', + is_default: false, + is_default_monitoring: false, + }); + + expect(utils.queryByText('OpenTelemetry exporter')).toBeNull(); + expect(utils.queryByLabelText('Advanced YAML Configuration')).toBeNull(); + }); + + it('should not show the OTel exporter section for kafka output', async () => { + const { utils } = renderFlyout({ + type: 'kafka', + name: 'kafka output', + id: 'output123', + is_default: false, + is_default_monitoring: false, + }); + + expect(utils.queryByText('OpenTelemetry exporter')).toBeNull(); + expect(utils.queryByLabelText('Advanced YAML Configuration')).toBeNull(); + }); + + it('should not show the OTel exporter section for remote ES output', async () => { + jest.spyOn(licenseService, 'isEnterprise').mockReturnValue(true); + jest + .spyOn(ExperimentalFeaturesService, 'get') + .mockReturnValue({ enableSyncIntegrationsOnRemote: true } as any); + + const { utils } = renderFlyout({ + type: 'remote_elasticsearch', + name: 'remote es output', + id: 'outputR', + is_default: false, + is_default_monitoring: false, + }); + + expect(utils.queryByText('OpenTelemetry exporter')).toBeNull(); + expect(utils.queryByLabelText('Advanced YAML Configuration')).toBeNull(); + }); + + it('should include otel_exporter_config_yaml in the save payload when creating an ES output', async () => { + jest.spyOn(ExperimentalFeaturesService, 'get').mockReturnValue({} as any); + mockedUseFleetStatus.mockReturnValue({ + isLoading: false, + isReady: true, + isSecretsStorageEnabled: true, + } as any); + + const { utils } = renderFlyout({ + type: 'elasticsearch', + name: 'elasticsearch output', + id: 'output123', + is_default: false, + is_default_monitoring: false, + hosts: ['http://localhost:9200'], + otel_exporter_config_yaml: 'flush_interval: 10s', + }); + + // Change a field so the Save button becomes enabled + fireEvent.change(utils.getByDisplayValue('elasticsearch output'), { + target: { value: 'updated output name' }, + }); + + fireEvent.click(utils.getByText('Save and apply settings')); + + await waitFor(() => { + expect(mockSendPutOutput).toHaveBeenCalledWith( + 'output123', + expect.objectContaining({ + otel_exporter_config_yaml: 'flush_interval: 10s', + }) + ); + }); + }); + + it('should send null otel_exporter_config_yaml when the field is empty', async () => { + jest.spyOn(ExperimentalFeaturesService, 'get').mockReturnValue({} as any); + mockedUseFleetStatus.mockReturnValue({ + isLoading: false, + isReady: true, + isSecretsStorageEnabled: true, + } as any); + + const { utils } = renderFlyout({ + type: 'elasticsearch', + name: 'elasticsearch output', + id: 'output123', + is_default: false, + is_default_monitoring: false, + hosts: ['http://localhost:9200'], + }); + + // Change a field so the Save button becomes enabled + fireEvent.change(utils.getByDisplayValue('elasticsearch output'), { + target: { value: 'updated output name' }, + }); + + fireEvent.click(utils.getByText('Save and apply settings')); + + await waitFor(() => { + expect(mockSendPutOutput).toHaveBeenCalledWith( + 'output123', + expect.objectContaining({ + otel_exporter_config_yaml: null, + }) + ); + }); + }); + }); + it('should not display remote ES output in type lists if serverless', async () => { jest.spyOn(ExperimentalFeaturesService, 'get').mockReturnValue({} as any); mockUseStartServices.mockReset(); diff --git a/x-pack/platform/plugins/shared/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/index.tsx b/x-pack/platform/plugins/shared/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/index.tsx index 76d0496677280..53f9056dee410 100644 --- a/x-pack/platform/plugins/shared/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/index.tsx +++ b/x-pack/platform/plugins/shared/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/index.tsx @@ -32,6 +32,7 @@ import { EuiAccordion, EuiCode, useGeneratedHtmlId, + EuiPanel, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -330,7 +331,6 @@ export const EditOutputFlyout: React.FunctionComponent = {renderOutputTypeSection(inputs.typeInput.value)} - {isRemoteESOutput ? null : ( = )} + = )} - - @@ -560,26 +559,81 @@ export const EditOutputFlyout: React.FunctionComponent = {...inputs.additionalYamlConfigInput.formRowProps} fullWidth > - { - if (outputYmlIncludesReservedPerformanceKey(value, load)) { - inputs.presetInput.setValue('custom'); - } +
+ { + if (outputYmlIncludesReservedPerformanceKey(value, load)) { + inputs.presetInput.setValue('custom'); + } - inputs.additionalYamlConfigInput.setValue(value); - }} - disabled={inputs.additionalYamlConfigInput.props.disabled} - placeholder={i18n.translate( - 'xpack.fleet.settings.editOutputFlyout.yamlConfigInputPlaceholder', - { - defaultMessage: - '# YAML settings here will be added to the output section of each agent policy.', - } - )} - /> + inputs.additionalYamlConfigInput.setValue(value); + }} + disabled={inputs.additionalYamlConfigInput.props.disabled} + placeholder={i18n.translate( + 'xpack.fleet.settings.editOutputFlyout.yamlConfigInputPlaceholder', + { + defaultMessage: + '# YAML settings here will be added to the output section of each agent policy.', + } + )} + /> +
+ {isESOutput && ( + <> + + +

+ +

+ + } + paddingSize="none" + > + + + } + helpText={ + + } + {...inputs.otelExporterConfigInput.formRowProps} + > + inputs.otelExporterConfigInput.setValue(value)} + disabled={inputs.otelExporterConfigInput.props.disabled} + placeholder={i18n.translate( + 'xpack.fleet.settings.editOutputFlyout.otelExporterConfigPlaceholder', + { + defaultMessage: + '# YAML settings defined here will be added to the exporter section of OTel policies.', + } + )} + /> + + +
+ + )} + + {output?.id && output.type === 'remote_elasticsearch' ? ( diff --git a/x-pack/platform/plugins/shared/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/use_output_form.tsx b/x-pack/platform/plugins/shared/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/use_output_form.tsx index 8e0926c556d78..5c5106d9cbdde 100644 --- a/x-pack/platform/plugins/shared/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/use_output_form.tsx +++ b/x-pack/platform/plugins/shared/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/use_output_form.tsx @@ -95,6 +95,7 @@ export interface OutputFormInputsType { logstashHostsInput: ReturnType; presetInput: ReturnType; additionalYamlConfigInput: ReturnType; + otelExporterConfigInput: ReturnType; defaultOutputInput: ReturnType; defaultMonitoringOutputInput: ReturnType; caTrustedFingerprintInput: ReturnType; @@ -213,7 +214,11 @@ export function useOutputForm(onSucess: () => void, output?: Output, defaultOutp const allowEdit = output?.allow_edit ?? []; function isDisabled( - field: keyof Output | keyof KafkaOutput | keyof NewRemoteElasticsearchOutput + field: + | keyof Output + | keyof KafkaOutput + | keyof NewRemoteElasticsearchOutput + | keyof NewElasticsearchOutput ) { if (!authz.fleet.allSettings) { return true; @@ -236,6 +241,12 @@ export function useOutputForm(onSucess: () => void, output?: Output, defaultOutp isDisabled('config_yaml') ); + const otelExporterConfigInput = useInput( + (output as NewElasticsearchOutput)?.otel_exporter_config_yaml ?? '', + validateYamlConfig, + isDisabled('otel_exporter_config_yaml') + ); + const defaultOutputInput = useSwitchInput( output?.is_default ?? false, isDisabled('is_default') || output?.is_default @@ -604,6 +615,7 @@ export function useOutputForm(onSucess: () => void, output?: Output, defaultOutp logstashHostsInput, presetInput, additionalYamlConfigInput, + otelExporterConfigInput, defaultOutputInput, defaultMonitoringOutputInput, caTrustedFingerprintInput, @@ -670,6 +682,7 @@ export function useOutputForm(onSucess: () => void, output?: Output, defaultOutp const kafkaHeadersValid = kafkaHeadersInput.validate(); const logstashHostsValid = logstashHostsInput.validate(); const additionalYamlConfigValid = additionalYamlConfigInput.validate(); + const otelExporterConfigValid = otelExporterConfigInput.validate(); const caTrustedFingerprintValid = caTrustedFingerprintInput.validate(); const serviceTokenValid = serviceTokenInput.validate(); const serviceTokenSecretValid = serviceTokenSecretInput.validate(); @@ -738,6 +751,7 @@ export function useOutputForm(onSucess: () => void, output?: Output, defaultOutp return ( elasticsearchUrlsValid && additionalYamlConfigValid && + otelExporterConfigValid && nameInputValid && caTrustedFingerprintValid && diskQueuePathValid @@ -757,6 +771,7 @@ export function useOutputForm(onSucess: () => void, output?: Output, defaultOutp kafkaHeadersInput, logstashHostsInput, additionalYamlConfigInput, + otelExporterConfigInput, caTrustedFingerprintInput, serviceTokenInput, serviceTokenSecretInput, @@ -1034,6 +1049,7 @@ export function useOutputForm(onSucess: () => void, output?: Output, defaultOutp is_default_monitoring: defaultMonitoringOutputInput.value, preset: presetInput.value, config_yaml: additionalYamlConfigInput.value, + otel_exporter_config_yaml: otelExporterConfigInput.value || null, ca_trusted_fingerprint: caTrustedFingerprintInput.value, proxy_id: proxyIdValue, write_to_logs_streams: writeToStreams.value, @@ -1136,22 +1152,23 @@ export function useOutputForm(onSucess: () => void, output?: Output, defaultOutp kafkaBrokerTimeoutInput.value, kafkaBrokerReachabilityTimeoutInput.value, kafkaBrokerAckReliabilityInput.value, - logstashEnableSSLInput.value, logstashHostsInput.value, + logstashEnableSSLInput.value, sslCertificateInput.value, sslKeyInput.value, sslCertificateAuthoritiesInput.value, sslKeySecretInput.value, - elasticsearchUrlInput.value, - presetInput.value, serviceTokenInput.value, serviceTokenSecretInput.value, + elasticsearchUrlInput.value, + presetInput.value, kibanaAPIKeyInput.value, syncIntegrationsInput.value, - syncUninstalledIntegrationsInput.value, kibanaURLInput.value, - caTrustedFingerprintInput.value, + syncUninstalledIntegrationsInput.value, writeToStreams.value, + otelExporterConfigInput.value, + caTrustedFingerprintInput.value, confirm, notifications.toasts, ]); diff --git a/x-pack/platform/plugins/shared/fleet/server/saved_objects/index.ts b/x-pack/platform/plugins/shared/fleet/server/saved_objects/index.ts index aa11bc04f1c8a..1b25eddde7a4e 100644 --- a/x-pack/platform/plugins/shared/fleet/server/saved_objects/index.ts +++ b/x-pack/platform/plugins/shared/fleet/server/saved_objects/index.ts @@ -627,6 +627,7 @@ export const getSavedObjectTypes = ( service_token: { type: 'keyword', index: false }, config: { type: 'flattened' }, config_yaml: { type: 'text' }, + otel_exporter_config_yaml: { type: 'text' }, is_preconfigured: { type: 'boolean', index: false }, is_internal: { type: 'boolean', index: false }, ssl: { type: 'binary' }, @@ -834,6 +835,26 @@ export const getSavedObjectTypes = ( }, ], }, + '9': { + changes: [ + { + type: 'mappings_addition', + addedMappings: { + otel_exporter_config_yaml: { type: 'text' }, + }, + }, + ], + schemas: { + forwardCompatibility: (unknownAttributes: unknown) => { + const { otel_exporter_config_yaml: _, ...rest } = unknownAttributes as Record< + string, + unknown + >; + return rest; + }, + create: schema.object({}, { unknowns: 'allow' }), + }, + }, }, migrations: { '7.13.0': migrateOutputToV7130, diff --git a/x-pack/platform/plugins/shared/fleet/server/services/agent_policies/full_agent_policy.test.ts b/x-pack/platform/plugins/shared/fleet/server/services/agent_policies/full_agent_policy.test.ts index 2a61c717db02b..dc358d672395c 100644 --- a/x-pack/platform/plugins/shared/fleet/server/services/agent_policies/full_agent_policy.test.ts +++ b/x-pack/platform/plugins/shared/fleet/server/services/agent_policies/full_agent_policy.test.ts @@ -1832,11 +1832,10 @@ describe('getFullAgentPolicy', () => { await getFullAgentPolicy(createSavedObjectClientMock(), 'agent-policy'); expect(mockedGenerateOtelcolConfig).toHaveBeenCalled(); - const callArgs = mockedGenerateOtelcolConfig.mock.calls[0]; + const callArgs = mockedGenerateOtelcolConfig.mock.calls[0][0]; expect(callArgs).toBeDefined(); - // Third argument should be the packageInfoCache Map - expect(callArgs[2]).toBeInstanceOf(Map); - const packageInfoCache = callArgs[2] as Map; + expect(callArgs.packageInfoCache).toBeInstanceOf(Map); + const packageInfoCache = callArgs.packageInfoCache as Map; expect(packageInfoCache.has('otelpackage-1.0.0')).toBe(true); expect(packageInfoCache.get('otelpackage-1.0.0')).toEqual(packageInfo); }); @@ -1962,6 +1961,139 @@ describe('getFullAgentPolicy', () => { expect(mockedGenerateOtelcolConfig).not.toHaveBeenCalled(); }); + + it('should pass the resolved proxy to generateOtelcolConfig when dataOutput has a proxy_id', async () => { + const proxy = { + id: 'proxy-1', + name: 'my-proxy', + url: 'http://proxy.example.com:3128', + proxy_headers: { 'X-Custom': 'value' }, + is_preconfigured: false, + }; + + mockedFetchRelatedSavedObjects.mockResolvedValue({ + outputs: [ + { + id: 'test-id', + is_default: true, + is_default_monitoring: true, + name: 'default', + type: 'elasticsearch', + hosts: ['http://127.0.0.1:9201'], + proxy_id: 'proxy-1', + }, + ], + proxies: [proxy], + dataOutput: { + id: 'test-id', + is_default: true, + is_default_monitoring: true, + name: 'default', + type: 'elasticsearch', + hosts: ['http://127.0.0.1:9201'], + proxy_id: 'proxy-1', + }, + monitoringOutput: { + id: 'test-id', + is_default: true, + is_default_monitoring: true, + name: 'default', + type: 'elasticsearch', + hosts: ['http://127.0.0.1:9201'], + }, + downloadSource: { + id: 'default-download-source-id', + is_default: true, + name: 'Default host', + host: 'http://default-registry.co', + }, + downloadSourceProxy: undefined, + fleetServerHost: { + name: 'default Fleet Server', + id: '93f74c0-e876-11ea-b7d3-8b2acec6f75c', + is_default: true, + host_urls: ['http://fleetserver:8220'], + is_preconfigured: false, + }, + }); + + mockAgentPolicy({ package_policies: [] }); + + await getFullAgentPolicy(createSavedObjectClientMock(), 'agent-policy'); + + expect(mockedGenerateOtelcolConfig).toHaveBeenCalled(); + const callArgs = mockedGenerateOtelcolConfig.mock.calls[0][0]; + // proxy should be the resolved proxy + expect(callArgs.proxy).toEqual(proxy); + }); + + it('should pass undefined proxy to generateOtelcolConfig when dataOutput has no proxy_id', async () => { + mockAgentPolicy({ package_policies: [] }); + + await getFullAgentPolicy(createSavedObjectClientMock(), 'agent-policy'); + + expect(mockedGenerateOtelcolConfig).toHaveBeenCalled(); + const callArgs = mockedGenerateOtelcolConfig.mock.calls[0][0]; + // proxy should be undefined when no proxy_id + expect(callArgs.proxy).toBeUndefined(); + }); + + it('should pass undefined proxy to generateOtelcolConfig when proxy_id does not match any proxy', async () => { + mockedFetchRelatedSavedObjects.mockResolvedValue({ + outputs: [ + { + id: 'test-id', + is_default: true, + is_default_monitoring: true, + name: 'default', + type: 'elasticsearch', + hosts: ['http://127.0.0.1:9201'], + proxy_id: 'nonexistent-proxy', + }, + ], + proxies: [], + dataOutput: { + id: 'test-id', + is_default: true, + is_default_monitoring: true, + name: 'default', + type: 'elasticsearch', + hosts: ['http://127.0.0.1:9201'], + proxy_id: 'nonexistent-proxy', + }, + monitoringOutput: { + id: 'test-id', + is_default: true, + is_default_monitoring: true, + name: 'default', + type: 'elasticsearch', + hosts: ['http://127.0.0.1:9201'], + }, + downloadSource: { + id: 'default-download-source-id', + is_default: true, + name: 'Default host', + host: 'http://default-registry.co', + }, + downloadSourceProxy: undefined, + fleetServerHost: { + name: 'default Fleet Server', + id: '93f74c0-e876-11ea-b7d3-8b2acec6f75c', + is_default: true, + host_urls: ['http://fleetserver:8220'], + is_preconfigured: false, + }, + }); + + mockAgentPolicy({ package_policies: [] }); + + await getFullAgentPolicy(createSavedObjectClientMock(), 'agent-policy'); + + expect(mockedGenerateOtelcolConfig).toHaveBeenCalled(); + const callArgs = mockedGenerateOtelcolConfig.mock.calls[0][0]; + // proxy should be undefined when proxy_id doesn't match + expect(callArgs.proxy).toBeUndefined(); + }); }); }); diff --git a/x-pack/platform/plugins/shared/fleet/server/services/agent_policies/full_agent_policy.ts b/x-pack/platform/plugins/shared/fleet/server/services/agent_policies/full_agent_policy.ts index 45fc09c82c997..5d01ac4abf678 100644 --- a/x-pack/platform/plugins/shared/fleet/server/services/agent_policies/full_agent_policy.ts +++ b/x-pack/platform/plugins/shared/fleet/server/services/agent_policies/full_agent_policy.ts @@ -163,7 +163,16 @@ export async function getFullAgentPolicy( let otelcolConfig; if (experimentalFeature.enableOtelIntegrations) { - otelcolConfig = generateOtelcolConfig(agentInputs, dataOutput, packageInfoCache); + const dataOutputProxy = dataOutput?.proxy_id + ? proxies.find((p) => p.id === dataOutput.proxy_id) + : undefined; + otelcolConfig = generateOtelcolConfig({ + inputs: agentInputs, + dataOutput, + packageInfoCache, + proxy: dataOutputProxy, + logger, + }); } const inputs = agentInputs diff --git a/x-pack/platform/plugins/shared/fleet/server/services/agent_policies/otel_collector.test.ts b/x-pack/platform/plugins/shared/fleet/server/services/agent_policies/otel_collector.test.ts index 08c098d0502c6..eee7546d475fa 100644 --- a/x-pack/platform/plugins/shared/fleet/server/services/agent_policies/otel_collector.test.ts +++ b/x-pack/platform/plugins/shared/fleet/server/services/agent_policies/otel_collector.test.ts @@ -244,17 +244,17 @@ describe('generateOtelcolConfig', () => { it('should be empty if there is no input', () => { const inputs: FullAgentPolicyInput[] = []; - expect(generateOtelcolConfig(inputs, defaultOutput)).toEqual({}); + expect(generateOtelcolConfig({ inputs, dataOutput: defaultOutput })).toEqual({}); }); it('should be empty if there is no otel config', () => { const inputs: FullAgentPolicyInput[] = [logInput]; - expect(generateOtelcolConfig(inputs, defaultOutput)).toEqual({}); + expect(generateOtelcolConfig({ inputs, dataOutput: defaultOutput })).toEqual({}); }); it('should return the otel config when there is one', () => { const inputs: FullAgentPolicyInput[] = [otelInput1]; - expect(generateOtelcolConfig(inputs, defaultOutput)).toEqual({ + expect(generateOtelcolConfig({ inputs, dataOutput: defaultOutput })).toEqual({ receivers: { 'httpcheck/test-1-stream-id-1': { targets: [ @@ -307,7 +307,9 @@ describe('generateOtelcolConfig', () => { it('should use the output id when it is not the default', () => { const inputs: FullAgentPolicyInput[] = [otelInput1]; - expect(generateOtelcolConfig(inputs, { ...defaultOutput, is_default: false })).toEqual({ + expect( + generateOtelcolConfig({ inputs, dataOutput: { ...defaultOutput, is_default: false } }) + ).toEqual({ receivers: { 'httpcheck/test-1-stream-id-1': { targets: [ @@ -360,7 +362,7 @@ describe('generateOtelcolConfig', () => { it('should return the otel config if there is any', () => { const inputs: FullAgentPolicyInput[] = [logInput, otelInput1]; - expect(generateOtelcolConfig(inputs, defaultOutput)).toEqual({ + expect(generateOtelcolConfig({ inputs, dataOutput: defaultOutput })).toEqual({ receivers: { 'httpcheck/test-1-stream-id-1': { targets: [ @@ -413,7 +415,7 @@ describe('generateOtelcolConfig', () => { it('should also work for templates', () => { const inputs: TemplateAgentPolicyInput[] = [otelInputTemplate]; - expect(generateOtelcolConfig(inputs)).toEqual({ + expect(generateOtelcolConfig({ inputs })).toEqual({ receivers: { 'httpcheck/test-1-stream-id-1': { targets: [ @@ -453,7 +455,7 @@ describe('generateOtelcolConfig', () => { it('should merge otel configs', () => { const inputs: FullAgentPolicyInput[] = [logInput, otelInput1, otelInput2]; - expect(generateOtelcolConfig(inputs, defaultOutput)).toEqual({ + expect(generateOtelcolConfig({ inputs, dataOutput: defaultOutput })).toEqual({ receivers: { 'httpcheck/test-1-stream-id-1': { targets: [ @@ -533,7 +535,7 @@ describe('generateOtelcolConfig', () => { it('should keep components with the same type', () => { const inputs: FullAgentPolicyInput[] = [otelInputMultipleComponentsSameType]; - expect(generateOtelcolConfig(inputs, defaultOutput)).toEqual({ + expect(generateOtelcolConfig({ inputs, dataOutput: defaultOutput })).toEqual({ receivers: { 'httpcheck/1/test-3-stream-id-1': { targets: [ @@ -600,7 +602,7 @@ describe('generateOtelcolConfig', () => { it('should add elasticapm connector and processor for traces input with use_apm enabled', () => { const inputs: FullAgentPolicyInput[] = [otelTracesInputWithAPM]; - expect(generateOtelcolConfig(inputs, defaultOutput)).toEqual({ + expect(generateOtelcolConfig({ inputs, dataOutput: defaultOutput })).toEqual({ receivers: { 'zipkin/test-traces-stream-id-1': { endpoint: 'localhost:9411', @@ -703,7 +705,7 @@ describe('generateOtelcolConfig', () => { ], }; - const result = generateOtelcolConfig([inputA, inputB], defaultOutput); + const result = generateOtelcolConfig({ inputs: [inputA, inputB], dataOutput: defaultOutput }); expect(result.connectors?.['elasticapm/ns-a']).toEqual({}); expect(result.connectors?.['elasticapm/ns-b']).toEqual({}); @@ -780,7 +782,7 @@ describe('generateOtelcolConfig', () => { ], }; - const result = generateOtelcolConfig([inputA, inputB], defaultOutput); + const result = generateOtelcolConfig({ inputs: [inputA, inputB], dataOutput: defaultOutput }); expect(result.connectors?.['elasticapm/ns-shared']).toEqual({}); expect(result.connectors?.['elasticapm/policy-a-stream-id-1']).toBeUndefined(); @@ -940,7 +942,7 @@ describe('generateOtelcolConfig', () => { })) ?? [], }; const inputs: FullAgentPolicyInput[] = [inputWithUseApm]; - const result = generateOtelcolConfig(inputs, defaultOutput, packageInfoCache); + const result = generateOtelcolConfig({ inputs, dataOutput: defaultOutput, packageInfoCache }); expect(result.connectors?.['elasticapm/default']).toEqual({}); expect(result.processors?.['elasticapm/default']).toEqual({}); @@ -963,7 +965,7 @@ describe('generateOtelcolConfig', () => { it('should generate transform with multiple signal type statements when dynamic_signal_types is true', () => { const inputs: FullAgentPolicyInput[] = [otelInputWithMultipleSignalTypes]; - const result = generateOtelcolConfig(inputs, defaultOutput, packageInfoCache); + const result = generateOtelcolConfig({ inputs, dataOutput: defaultOutput, packageInfoCache }); // dynamic_signal_types: data_stream.dataset is NOT set — deferred to ES exporter routing expect(result.processors?.['transform/test-multi-signal-stream-id-1-routing']).toEqual({ @@ -1015,7 +1017,7 @@ describe('generateOtelcolConfig', () => { it('should generate transform with multiple signal type statements when dynamic_signal_types is true and pipelines have simple names', () => { const inputs: FullAgentPolicyInput[] = [otelInputWithMultipleSignalTypes2]; - const result = generateOtelcolConfig(inputs, defaultOutput, packageInfoCache); + const result = generateOtelcolConfig({ inputs, dataOutput: defaultOutput, packageInfoCache }); // dynamic_signal_types: data_stream.dataset is NOT set — deferred to ES exporter routing expect(result.processors?.['transform/test-multi-signal-stream-id-1-routing']).toEqual({ @@ -1091,7 +1093,7 @@ describe('generateOtelcolConfig', () => { }; const inputs: FullAgentPolicyInput[] = [otelInputWithSubsetSignalTypes]; - const result = generateOtelcolConfig(inputs, defaultOutput, packageInfoCache); + const result = generateOtelcolConfig({ inputs, dataOutput: defaultOutput, packageInfoCache }); // dynamic_signal_types: data_stream.dataset is NOT set — deferred to ES exporter routing expect(result.processors?.['transform/test-multi-signal-stream-id-1-routing']).toEqual({ @@ -1143,7 +1145,11 @@ describe('generateOtelcolConfig', () => { ]); const inputs: FullAgentPolicyInput[] = [otelInputWithMultipleSignalTypes]; - const result = generateOtelcolConfig(inputs, defaultOutput, packageInfoCacheNoDynamic); + const result = generateOtelcolConfig({ + inputs, + dataOutput: defaultOutput, + packageInfoCache: packageInfoCacheNoDynamic, + }); // Should generate single signal type transform (uses stream.data_stream.type) expect(result.processors?.['transform/test-multi-signal-stream-id-1-routing']).toEqual({ @@ -1205,7 +1211,11 @@ describe('generateOtelcolConfig', () => { ]); const inputs: FullAgentPolicyInput[] = [otelInputWithMetricsType]; - const result = generateOtelcolConfig(inputs, defaultOutput, packageInfoCacheNoDynamicVar); + const result = generateOtelcolConfig({ + inputs, + dataOutput: defaultOutput, + packageInfoCache: packageInfoCacheNoDynamicVar, + }); // Should use the stream's data_stream.type (metrics) expect(result.processors?.['transform/test-multi-signal-stream-id-1-routing']).toEqual({ @@ -1253,7 +1263,10 @@ describe('generateOtelcolConfig', () => { }; it('generates OTel config for integration package with otelcol input', () => { - const result = generateOtelcolConfig([otelIntegrationInput], defaultOutput); + const result = generateOtelcolConfig({ + inputs: [otelIntegrationInput], + dataOutput: defaultOutput, + }); expect(result.receivers).toHaveProperty('otlp/integration-otel-stream-id-1'); expect(result.exporters).toHaveProperty('elasticsearch/default'); @@ -1304,12 +1317,10 @@ describe('generateOtelcolConfig', () => { ], } as any; - const result = generateOtelcolConfig( - [templateInput], - undefined, - undefined, - integrationPackageInfo - ); + const result = generateOtelcolConfig({ + inputs: [templateInput], + defaultPackageInfo: integrationPackageInfo, + }); // With dynamic_signal_types, routing transforms are generated per signal type const routingKey = Object.keys(result.processors ?? {}).find((k) => @@ -1357,12 +1368,10 @@ describe('generateOtelcolConfig', () => { ], } as any; - const result = generateOtelcolConfig( - [templateInput], - undefined, - undefined, - integrationPackageInfo - ); + const result = generateOtelcolConfig({ + inputs: [templateInput], + defaultPackageInfo: integrationPackageInfo, + }); const routingKey = Object.keys(result.processors ?? {}).find((k) => k.startsWith('transform/') @@ -1437,12 +1446,11 @@ describe('generateOtelcolConfig', () => { ], }; - const result = generateOtelcolConfig( - [inputWithMeta], - undefined, - packageInfoCacheWithDynamic, - defaultPkgInfoNoDynamic - ); + const result = generateOtelcolConfig({ + inputs: [inputWithMeta], + packageInfoCache: packageInfoCacheWithDynamic, + defaultPackageInfo: defaultPkgInfoNoDynamic, + }); const routingKey = Object.keys(result.processors ?? {}).find((k) => k.startsWith('transform/') @@ -1520,7 +1528,7 @@ describe('generateOtelcolConfig', () => { }; const cache = new Map([['mixed_pkg-1.0.0', mixedPackageInfo]]); - const result = generateOtelcolConfig([nonDynamicInput], undefined, cache); + const result = generateOtelcolConfig({ inputs: [nonDynamicInput], packageInfoCache: cache }); const routingKey = Object.keys(result.processors ?? {}).find((k) => k.startsWith('transform/') @@ -1597,7 +1605,10 @@ describe('generateOtelcolConfig', () => { }; const cache = new Map([['combined_pkg-1.0.0', mixedInputsPackageInfo]]); - const result2 = generateOtelcolConfig([nonDynamicOtelInput], undefined, cache); + const result2 = generateOtelcolConfig({ + inputs: [nonDynamicOtelInput], + packageInfoCache: cache, + }); const routingKey2 = Object.keys(result2.processors ?? {}).find((k) => k.startsWith('transform/') @@ -1676,20 +1687,32 @@ describe('generateOtelcolConfig', () => { it('renames the pipeline key when data_stream.type differs from the package default', () => { const input = makeInput('traces', 'logs/otlp'); - const result = generateOtelcolConfig([input], defaultOutput, packageInfoCacheNonDynamic); + const result = generateOtelcolConfig({ + inputs: [input], + dataOutput: defaultOutput, + packageInfoCache: packageInfoCacheNonDynamic, + }); expect(result.service?.pipelines).toHaveProperty('traces/otlp/test-otel-stream-id-1'); expect(result.service?.pipelines).not.toHaveProperty('logs/otlp/test-otel-stream-id-1'); }); it('passes through unchanged when data_stream.type already matches the pipeline key', () => { const input = makeInput('logs', 'logs/otlp'); - const result = generateOtelcolConfig([input], defaultOutput, packageInfoCacheNonDynamic); + const result = generateOtelcolConfig({ + inputs: [input], + dataOutput: defaultOutput, + packageInfoCache: packageInfoCacheNonDynamic, + }); expect(result.service?.pipelines).toHaveProperty('logs/otlp/test-otel-stream-id-1'); }); it('does not rename for dynamic_signal_types packages', () => { const input = makeInput('traces', 'logs/otlp'); - const result = generateOtelcolConfig([input], defaultOutput, packageInfoCacheDynamic); + const result = generateOtelcolConfig({ + inputs: [input], + dataOutput: defaultOutput, + packageInfoCache: packageInfoCacheDynamic, + }); expect(result.service?.pipelines).toHaveProperty('logs/otlp/test-otel-stream-id-1'); expect(result.service?.pipelines).not.toHaveProperty('traces/otlp/test-otel-stream-id-1'); }); @@ -1758,7 +1781,11 @@ describe('generateOtelcolConfig', () => { }; const cache = new Map([['mixed_pkg-1.0.0', mixedPackageInfo]]); - const result = generateOtelcolConfig([nonDynamicInput], defaultOutput, cache); + const result = generateOtelcolConfig({ + inputs: [nonDynamicInput], + dataOutput: defaultOutput, + packageInfoCache: cache, + }); expect(result.service?.pipelines).toHaveProperty('traces/otlp/non-dynamic-otel-stream-id-1'); expect(result.service?.pipelines).not.toHaveProperty( @@ -1790,9 +1817,267 @@ describe('generateOtelcolConfig', () => { }, ], }; - const result = generateOtelcolConfig([input], defaultOutput, packageInfoCacheNonDynamic); + const result = generateOtelcolConfig({ + inputs: [input], + dataOutput: defaultOutput, + packageInfoCache: packageInfoCacheNonDynamic, + }); expect(result.service?.pipelines).toHaveProperty('logs/otlp/test-otel-stream-id-1'); expect(result.service?.pipelines).toHaveProperty('metrics/otlp/test-otel-stream-id-1'); }); }); + describe('beatsauth extension generation', () => { + const inputs: FullAgentPolicyInput[] = [otelInput1]; + + it('should include beatsauth extension with ssl fields when output has ssl config', () => { + const outputWithSSL: Output = { + ...defaultOutput, + ca_trusted_fingerprint: 'abc123fingerprint', + ssl: { + certificate_authorities: ['-----BEGIN CERTIFICATE-----\nMIIC...'], + certificate: '-----BEGIN CERTIFICATE-----\nMIID...', + key: '-----BEGIN PRIVATE KEY-----\nMIIE...', + verification_mode: 'full', + }, + }; + + const result = generateOtelcolConfig({ inputs, dataOutput: outputWithSSL }); + + expect(result.extensions?.['beatsauth/default']).toEqual({ + ssl: { + ca_trusted_fingerprint: 'abc123fingerprint', + certificate_authorities: ['-----BEGIN CERTIFICATE-----\nMIIC...'], + certificate: '-----BEGIN CERTIFICATE-----\nMIID...', + key: '-----BEGIN PRIVATE KEY-----\nMIIE...', + verification_mode: 'full', + }, + }); + expect(result.exporters?.['elasticsearch/default']).toEqual({ + endpoints: ['http://localhost:9200'], + auth: { authenticator: 'beatsauth/default' }, + }); + expect(result.service?.extensions).toContain('beatsauth/default'); + }); + + it('should include ca_trusted_fingerprint only when that is the only ssl field set', () => { + const outputWithFingerprint: Output = { + ...defaultOutput, + ca_trusted_fingerprint: 'myfingerprint', + }; + + const result = generateOtelcolConfig({ inputs, dataOutput: outputWithFingerprint }); + + expect(result.extensions?.['beatsauth/default']).toEqual({ + ssl: { ca_trusted_fingerprint: 'myfingerprint' }, + }); + }); + + it('should include ca_sha256 in beatsauth ssl config', () => { + const outputWithCaSha: Output = { + ...defaultOutput, + ca_sha256: 'sha256value', + }; + + const result = generateOtelcolConfig({ inputs, dataOutput: outputWithCaSha }); + + expect(result.extensions?.['beatsauth/default']).toEqual({ + ssl: { ca_sha256: 'sha256value' }, + }); + }); + + it('should include proxy fields when proxy is passed', () => { + const proxy = { + id: 'proxy-1', + name: 'my-proxy', + url: 'http://proxy.example.com:3128', + proxy_headers: { 'X-Custom-Header': 'value' }, + is_preconfigured: false, + }; + + const result = generateOtelcolConfig({ inputs, dataOutput: defaultOutput, proxy }); + + expect(result.extensions?.['beatsauth/default']).toEqual({ + proxy_url: 'http://proxy.example.com:3128', + proxy_headers: { 'X-Custom-Header': 'value' }, + }); + expect(result.service?.extensions).toContain('beatsauth/default'); + }); + + it('should include proxy url but not proxy_headers when headers are not set', () => { + const proxy = { + id: 'proxy-1', + name: 'my-proxy', + url: 'http://proxy.example.com:3128', + is_preconfigured: false, + }; + + const result = generateOtelcolConfig({ inputs, dataOutput: defaultOutput, proxy }); + + expect(result.extensions?.['beatsauth/default']).toEqual({ + proxy_url: 'http://proxy.example.com:3128', + }); + }); + + it('should combine ssl and proxy fields in beatsauth when both are configured', () => { + const outputWithSSL: Output = { + ...defaultOutput, + ca_trusted_fingerprint: 'combinedfingerprint', + ssl: { + certificate_authorities: ['-----BEGIN CERTIFICATE-----\nCA...'], + }, + }; + const proxy = { + id: 'proxy-1', + name: 'my-proxy', + url: 'http://proxy.example.com:3128', + proxy_headers: { 'Proxy-Auth': 'token' }, + is_preconfigured: false, + }; + + const result = generateOtelcolConfig({ inputs, dataOutput: outputWithSSL, proxy }); + + expect(result.extensions?.['beatsauth/default']).toEqual({ + ssl: { + ca_trusted_fingerprint: 'combinedfingerprint', + certificate_authorities: ['-----BEGIN CERTIFICATE-----\nCA...'], + }, + proxy_url: 'http://proxy.example.com:3128', + proxy_headers: { 'Proxy-Auth': 'token' }, + }); + }); + + it('should omit beatsauth from extensions and exporter auth when output has no ssl or proxy fields', () => { + const result = generateOtelcolConfig({ inputs, dataOutput: defaultOutput }); + + expect(result.extensions?.['beatsauth/default']).toBeUndefined(); + expect(result.exporters?.['elasticsearch/default']).not.toHaveProperty('auth'); + expect(result.service?.extensions ?? []).not.toContain('beatsauth/default'); + }); + + it('should use secrets.ssl.key when present, ignoring plain ssl.key', () => { + const outputWithSecretKey: Output = { + ...defaultOutput, + ssl: { + key: 'plain-key-should-be-ignored', + }, + secrets: { + ssl: { key: { id: 'secret-id-abc123' } }, + }, + }; + + const result = generateOtelcolConfig({ inputs, dataOutput: outputWithSecretKey }); + + expect(result.extensions?.['beatsauth/default']).toEqual({ + secrets: { ssl: { key: { id: 'secret-id-abc123' } } }, + }); + }); + + it('should include secrets.ssl.key in beatsauth when only secret key is set', () => { + const outputWithSecretOnly: Output = { + ...defaultOutput, + secrets: { + ssl: { key: { id: 'my-secret-id' } }, + }, + }; + + const result = generateOtelcolConfig({ inputs, dataOutput: outputWithSecretOnly }); + + expect(result.extensions?.['beatsauth/default']).toEqual({ + secrets: { ssl: { key: { id: 'my-secret-id' } } }, + }); + }); + }); + + describe('otel_exporter_config_yaml merging', () => { + const inputs: FullAgentPolicyInput[] = [otelInput1]; + + it('should merge user YAML into the exporter config', () => { + const outputWithExporterYaml: Output = { + ...defaultOutput, + otel_exporter_config_yaml: 'flush_interval: 10s', + }; + + const result = generateOtelcolConfig({ inputs, dataOutput: outputWithExporterYaml }); + + expect(result.exporters?.['elasticsearch/default']).toEqual( + expect.objectContaining({ flush_interval: '10s' }) + ); + }); + + it('should not allow user YAML to override endpoints', () => { + const outputWithOverrides: Output = { + ...defaultOutput, + otel_exporter_config_yaml: 'endpoints:\n - http://evil.com', + }; + + const result = generateOtelcolConfig({ inputs, dataOutput: outputWithOverrides }); + + expect(result.exporters?.['elasticsearch/default']).toEqual( + expect.objectContaining({ + endpoints: defaultOutput.hosts, + }) + ); + }); + + it('should handle null otel_exporter_config_yaml gracefully', () => { + const outputWithNull: Output = { + ...defaultOutput, + otel_exporter_config_yaml: null, + }; + + const result = generateOtelcolConfig({ inputs, dataOutput: outputWithNull }); + + expect(result.exporters?.['elasticsearch/default']).toEqual({ + endpoints: defaultOutput.hosts, + }); + }); + + it('should handle undefined otel_exporter_config_yaml gracefully', () => { + const result = generateOtelcolConfig({ inputs, dataOutput: defaultOutput }); + + expect(result.exporters?.['elasticsearch/default']).toEqual({ + endpoints: defaultOutput.hosts, + }); + }); + + it('should handle malformed YAML without throwing', () => { + const outputWithBadYaml: Output = { + ...defaultOutput, + otel_exporter_config_yaml: ': invalid yaml', + }; + + expect(() => generateOtelcolConfig({ inputs, dataOutput: outputWithBadYaml })).not.toThrow(); + + const result = generateOtelcolConfig({ inputs, dataOutput: outputWithBadYaml }); + expect(result.exporters?.['elasticsearch/default']).toEqual({ + endpoints: defaultOutput.hosts, + }); + }); + + it('should ignore non-object YAML (scalar)', () => { + const outputWithScalarYaml: Output = { + ...defaultOutput, + otel_exporter_config_yaml: 'just a string', + }; + + const result = generateOtelcolConfig({ inputs, dataOutput: outputWithScalarYaml }); + + expect(result.exporters?.['elasticsearch/default']).toEqual({ + endpoints: defaultOutput.hosts, + }); + }); + + it('should ignore non-object YAML (array)', () => { + const outputWithArrayYaml: Output = { + ...defaultOutput, + otel_exporter_config_yaml: '- a\n- b', + }; + + const result = generateOtelcolConfig({ inputs, dataOutput: outputWithArrayYaml }); + + expect(result.exporters?.['elasticsearch/default']).toEqual({ + endpoints: defaultOutput.hosts, + }); + }); + }); }); diff --git a/x-pack/platform/plugins/shared/fleet/server/services/agent_policies/otel_collector.ts b/x-pack/platform/plugins/shared/fleet/server/services/agent_policies/otel_collector.ts index 067c1217e3e94..99675d2d0b660 100644 --- a/x-pack/platform/plugins/shared/fleet/server/services/agent_policies/otel_collector.ts +++ b/x-pack/platform/plugins/shared/fleet/server/services/agent_policies/otel_collector.ts @@ -5,7 +5,11 @@ * 2.0. */ -import type { Output, TemplateAgentPolicyInput } from '../../types'; +import { load } from 'js-yaml'; + +import type { Logger } from '@kbn/logging'; + +import type { FleetProxy, Output, TemplateAgentPolicyInput } from '../../types'; import type { FullAgentPolicyInput, FullAgentPolicyInputStream, @@ -27,12 +31,21 @@ import { pkgToPkgKey } from '../epm/registry'; import { hasDynamicSignalTypes } from '../../../common/services'; // Generate OTel Collector policy -export function generateOtelcolConfig( - inputs: FullAgentPolicyInput[] | TemplateAgentPolicyInput[], - dataOutput?: Output, - packageInfoCache?: Map, - defaultPackageInfo?: PackageInfo -): OTelCollectorConfig { +export function generateOtelcolConfig({ + inputs, + dataOutput, + packageInfoCache, + proxy, + logger, + defaultPackageInfo, +}: { + inputs: FullAgentPolicyInput[] | TemplateAgentPolicyInput[]; + dataOutput?: Output; + packageInfoCache?: Map; + proxy?: FleetProxy; + logger?: Logger; + defaultPackageInfo?: PackageInfo; +}): OTelCollectorConfig { const otelConfigs: OTelCollectorConfig[] = inputs .filter((input) => input.type === OTEL_COLLECTOR_INPUT_TYPE) .flatMap((input) => { @@ -149,7 +162,7 @@ export function generateOtelcolConfig( } const config = mergeOtelcolConfigs(otelConfigs); - return attachOtelcolExporter(config, dataOutput); + return attachOtelcolExporter(config, dataOutput, proxy, logger); } function buildDataStreamStatements( @@ -400,24 +413,67 @@ function mergeOtelcolConfigs(otelConfigs: OTelCollectorConfig[]): OTelCollectorC }); } +function buildBeatsauthConfig(output: Output, proxy?: FleetProxy): Record { + const config: Record = {}; + + const ssl: Record = {}; + if (output.ca_trusted_fingerprint) ssl.ca_trusted_fingerprint = output.ca_trusted_fingerprint; + if (output.ca_sha256) ssl.ca_sha256 = output.ca_sha256; + if (output.ssl?.certificate_authorities?.length) + ssl.certificate_authorities = output.ssl.certificate_authorities; + if (output.ssl?.certificate) ssl.certificate = output.ssl.certificate; + // Prefer the secrets-stored key over the plain-text key, mirroring full_agent_policy.ts behaviour + if (output.ssl?.key && !output.secrets?.ssl?.key) ssl.key = output.ssl.key; + if (output.ssl?.verification_mode) ssl.verification_mode = output.ssl.verification_mode; + if (Object.keys(ssl).length > 0) config.ssl = ssl; + + // If the SSL key is stored as a Kibana secret, include it under the secrets namespace + if (output.secrets?.ssl?.key) { + config.secrets = { ssl: { key: output.secrets.ssl.key } }; + } + + if (proxy) { + config.proxy_url = proxy.url; + if (proxy.proxy_headers) config.proxy_headers = proxy.proxy_headers; + } + + return config; +} + function attachOtelcolExporter( config: OTelCollectorConfig, - dataOutput?: Output + dataOutput?: Output, + proxy?: FleetProxy, + logger?: Logger ): OTelCollectorConfig { if (!dataOutput) { return config; } - const exporter = generateOtelcolExporter(dataOutput); + const { extensions, exporters } = generateOtelcolExporter(dataOutput, proxy, logger); config.connectors = { ...config.connectors, forward: {}, }; + if (Object.keys(extensions).length > 0) { + config.extensions = { + ...config.extensions, + ...extensions, + }; + } config.exporters = { ...config.exporters, - ...exporter, + ...exporters, }; + const extensionIDs = Object.keys(extensions); + if (extensionIDs.length > 0) { + config.service = { + ...config.service, + extensions: [...(config.service?.extensions ?? []), ...extensionIDs], + }; + } + if (config.service?.pipelines) { const signalTypes = new Set(); Object.entries(config.service.pipelines).forEach(([id, pipeline]) => { @@ -431,7 +487,7 @@ function attachOtelcolExporter( signalTypes.forEach((id) => { config.service!.pipelines![id] = { receivers: ['forward'], - exporters: Object.keys(exporter), + exporters: Object.keys(exporters), }; }); } @@ -439,15 +495,60 @@ function attachOtelcolExporter( return config; } -function generateOtelcolExporter(dataOutput: Output): Record { +function parseOtelExporterConfigYaml( + yaml: string | null | undefined, + logger?: Logger +): Record { + if (!yaml) return {}; + try { + const parsed = load(yaml); + if (parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)) { + return parsed as Record; + } + logger?.warn( + 'otel_exporter_config_yaml did not parse to an object, skipping extra exporter config' + ); + return {}; + } catch (e) { + // Malformed YAML — skip extra config rather than crashing policy generation. + // The UI validates YAML before saving; this path is only reachable via direct API writes. + logger?.warn( + `Failed to parse otel_exporter_config_yaml, skipping extra exporter config: ${e.message}` + ); + return {}; + } +} + +function generateOtelcolExporter( + dataOutput: Output, + proxy?: FleetProxy, + logger?: Logger +): { + extensions: Record; + exporters: Record; +} { switch (dataOutput.type) { - case outputType.Elasticsearch: + case outputType.Elasticsearch: { const outputID = getOutputIdForAgentPolicy(dataOutput); + const beatsauthConfig = buildBeatsauthConfig(dataOutput, proxy); + const hasBeatsauthConfig = Object.keys(beatsauthConfig).length > 0; + const beatsauthID = `beatsauth/${outputID}`; + const extraExporterConfig = parseOtelExporterConfigYaml( + dataOutput.otel_exporter_config_yaml, + logger + ); return { - [`elasticsearch/${outputID}`]: { - endpoints: dataOutput.hosts, + extensions: hasBeatsauthConfig ? { [beatsauthID]: beatsauthConfig } : {}, + exporters: { + [`elasticsearch/${outputID}`]: { + ...extraExporterConfig, + // endpoints and auth always take precedence over user-supplied YAML + endpoints: dataOutput.hosts, + ...(hasBeatsauthConfig ? { auth: { authenticator: beatsauthID } } : {}), + }, }, }; + } default: throw new FleetError( `output type ${dataOutput.type} not supported when policy contains OTel inputs` diff --git a/x-pack/platform/plugins/shared/fleet/server/services/epm/packages/get_template_inputs.ts b/x-pack/platform/plugins/shared/fleet/server/services/epm/packages/get_template_inputs.ts index d3a7d8f5e7544..8854d544f8dd6 100644 --- a/x-pack/platform/plugins/shared/fleet/server/services/epm/packages/get_template_inputs.ts +++ b/x-pack/platform/plugins/shared/fleet/server/services/epm/packages/get_template_inputs.ts @@ -171,9 +171,9 @@ export async function getTemplateInputs( } } } - + const logger = appContextService.getLogger(); const assetsMap = await getAgentTemplateAssetsMap({ - logger: appContextService.getLogger(), + logger, packageInfo, savedObjectsClient: soClient, ignoreUnverified, @@ -222,7 +222,11 @@ export async function getTemplateInputs( let otelcolConfig; if (experimentalFeature.enableOtelIntegrations) { - otelcolConfig = generateOtelcolConfig(inputs, undefined, undefined, packageInfo); + otelcolConfig = generateOtelcolConfig({ + inputs, + logger, + defaultPackageInfo: packageInfo, + }); } // filter out the otelcol inputs, they will be added at the root of the config const filteredInputs = inputs.filter((input) => input.type !== OTEL_COLLECTOR_INPUT_TYPE); diff --git a/x-pack/platform/plugins/shared/fleet/server/types/models/output.ts b/x-pack/platform/plugins/shared/fleet/server/types/models/output.ts index 476f6d3ddd583..183c05d1859d8 100644 --- a/x-pack/platform/plugins/shared/fleet/server/types/models/output.ts +++ b/x-pack/platform/plugins/shared/fleet/server/types/models/output.ts @@ -70,6 +70,7 @@ const BaseSchema = { ca_sha256: schema.maybe(schema.oneOf([schema.literal(null), schema.string()])), ca_trusted_fingerprint: schema.maybe(schema.oneOf([schema.literal(null), schema.string()])), config_yaml: schema.maybe(schema.oneOf([schema.literal(null), schema.string()])), + otel_exporter_config_yaml: schema.maybe(schema.oneOf([schema.literal(null), schema.string()])), ssl: schema.maybe( schema.oneOf([ schema.literal(null), @@ -362,8 +363,11 @@ export const OutputResponseSchema = schema.object({ }); export const UpdateOutputSchema = schema.oneOf([ - schema.object({ ...ElasticSearchUpdateSchema }), - schema.object({ ...RemoteElasticSearchUpdateSchema }), - schema.object({ ...LogstashUpdateSchema }), - schema.object({ ...KafkaUpdateSchema }), + schema.object({ ...ElasticSearchUpdateSchema }, { meta: { id: 'update_output_elasticsearch' } }), + schema.object( + { ...RemoteElasticSearchUpdateSchema }, + { meta: { id: 'update_output_remote_elasticsearch' } } + ), + schema.object({ ...LogstashUpdateSchema }, { meta: { id: 'update_output_logstash' } }), + schema.object({ ...KafkaUpdateSchema }, { meta: { id: 'update_output_kafka' } }), ]); diff --git a/x-pack/platform/plugins/shared/fleet/server/types/rest_spec/settings.ts b/x-pack/platform/plugins/shared/fleet/server/types/rest_spec/settings.ts index 1bc279689a737..029d907c215c5 100644 --- a/x-pack/platform/plugins/shared/fleet/server/types/rest_spec/settings.ts +++ b/x-pack/platform/plugins/shared/fleet/server/types/rest_spec/settings.ts @@ -53,6 +53,7 @@ const EnrollmentSettingsOutputSchema = schema.object({ ca_sha256: schema.maybe(schema.oneOf([schema.literal(null), schema.string()])), ca_trusted_fingerprint: schema.maybe(schema.oneOf([schema.literal(null), schema.string()])), config_yaml: schema.maybe(schema.oneOf([schema.literal(null), schema.string()])), + otel_exporter_config_yaml: schema.maybe(schema.oneOf([schema.literal(null), schema.string()])), proxy_id: schema.maybe(schema.oneOf([schema.literal(null), schema.string()])), allow_edit: schema.maybe(schema.arrayOf(schema.string(), { maxSize: 100 })), preset: schema.maybe( diff --git a/x-pack/platform/plugins/shared/fleet/server/types/so_attributes.ts b/x-pack/platform/plugins/shared/fleet/server/types/so_attributes.ts index 842c5978ccac9..4fdbb040c9cb7 100644 --- a/x-pack/platform/plugins/shared/fleet/server/types/so_attributes.ts +++ b/x-pack/platform/plugins/shared/fleet/server/types/so_attributes.ts @@ -183,6 +183,7 @@ export interface OutputSoBaseAttributes { is_internal?: boolean; is_preconfigured?: boolean; config_yaml?: string | null; + otel_exporter_config_yaml?: string | null; proxy_id?: string | null; shipper?: ShipperOutput | null; allow_edit?: string[];