From fd73a325c256e2bb1ab2603ff0f8b97517cbfc5a Mon Sep 17 00:00:00 2001 From: svalenciah19 Date: Thu, 26 Jun 2025 12:53:50 -0500 Subject: [PATCH 1/8] Upgrade elastic-operator to version 3.0.0 --- packs/elastic-operator-3.0.0/README.md | 43 + .../charts/eck-operator-3.0.0.tgz | Bin 0 -> 136588 bytes .../charts/eck-operator/.helmignore | 24 + .../charts/eck-operator/Chart.lock | 6 + .../charts/eck-operator/Chart.yaml | 26 + .../charts/eck-operator/LICENSE | 93 + .../charts/eck-operator/README.md | 20 + .../charts/eck-operator-crds/.helmignore | 23 + .../charts/eck-operator-crds/Chart.yaml | 21 + .../charts/eck-operator-crds/README.md | 16 + .../eck-operator-crds/templates/NOTES.txt | 1 + .../eck-operator-crds/templates/_helpers.tpl | 62 + .../eck-operator-crds/templates/all-crds.yaml | 10726 ++++++++++++++++ .../charts/eck-operator-crds/values.yaml | 7 + .../profile-disable-automounting-api.yaml | 29 + .../charts/eck-operator/profile-global.yaml | 6 + .../charts/eck-operator/profile-istio.yaml | 11 + .../eck-operator/profile-restricted.yaml | 12 + .../profile-soft-multi-tenancy.yaml | 18 + .../charts/eck-operator/templates/NOTES.txt | 2 + .../eck-operator/templates/_helpers.tpl | 381 + .../eck-operator/templates/cluster-roles.yaml | 121 + .../eck-operator/templates/configmap.yaml | 81 + .../templates/managed-namespaces.yaml | 13 + .../templates/managed-ns-network-policy.yaml | 228 + .../templates/metrics-service.yaml | 22 + .../templates/operator-namespace.yaml | 9 + .../templates/operator-network-policy.yaml | 59 + .../charts/eck-operator/templates/pdb.yaml | 19 + .../eck-operator/templates/podMonitor.yaml | 42 + .../eck-operator/templates/role-bindings.yaml | 98 + .../templates/service-account.yaml | 15 + .../templates/service-monitor.yaml | 34 + .../eck-operator/templates/statefulset.yaml | 162 + .../templates/validate-chart.yaml | 29 + .../eck-operator/templates/webhook.yaml | 473 + .../charts/eck-operator/values.yaml | 372 + packs/elastic-operator-3.0.0/logo.png | Bin 0 -> 5810 bytes packs/elastic-operator-3.0.0/pack.json | 39 + packs/elastic-operator-3.0.0/values.yaml | 389 + 40 files changed, 13732 insertions(+) create mode 100644 packs/elastic-operator-3.0.0/README.md create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator-3.0.0.tgz create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/.helmignore create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/Chart.lock create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/Chart.yaml create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/LICENSE create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/README.md create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/.helmignore create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/Chart.yaml create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/README.md create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/templates/NOTES.txt create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/templates/_helpers.tpl create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/values.yaml create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/profile-disable-automounting-api.yaml create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/profile-global.yaml create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/profile-istio.yaml create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/profile-restricted.yaml create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/profile-soft-multi-tenancy.yaml create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/templates/NOTES.txt create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/templates/_helpers.tpl create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/templates/cluster-roles.yaml create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/templates/configmap.yaml create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/templates/managed-namespaces.yaml create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/templates/managed-ns-network-policy.yaml create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/templates/metrics-service.yaml create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/templates/operator-namespace.yaml create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/templates/operator-network-policy.yaml create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/templates/pdb.yaml create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/templates/podMonitor.yaml create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/templates/role-bindings.yaml create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/templates/service-account.yaml create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/templates/service-monitor.yaml create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/templates/statefulset.yaml create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/templates/validate-chart.yaml create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/templates/webhook.yaml create mode 100644 packs/elastic-operator-3.0.0/charts/eck-operator/values.yaml create mode 100644 packs/elastic-operator-3.0.0/logo.png create mode 100644 packs/elastic-operator-3.0.0/pack.json create mode 100644 packs/elastic-operator-3.0.0/values.yaml diff --git a/packs/elastic-operator-3.0.0/README.md b/packs/elastic-operator-3.0.0/README.md new file mode 100644 index 00000000..ee0b2ca6 --- /dev/null +++ b/packs/elastic-operator-3.0.0/README.md @@ -0,0 +1,43 @@ +# Elastic Cloud on Kubernetes (ECK) + +Elastic Cloud on Kubernetes automates the deployment, provisioning, management, and orchestration of Elasticsearch, Kibana, APM Server, Enterprise Search, Beats, Elastic Agent, Elastic Maps Server, and Logstash on Kubernetes based on the operator pattern. + +Current features: + +* Elasticsearch, Kibana, APM Server, Enterprise Search, and Beats deployments +* TLS Certificates management +* Safe Elasticsearch cluster configuration & topology changes +* Persistent volumes usage +* Custom node configuration and attributes +* Secure settings keystore updates + +Supported versions: + +* Kubernetes 1.25-1.29 +* Elasticsearch, Kibana, APM Server: 6.8+, 7.1+, 8+ +* Enterprise Search: 7.7+, 8+ +* Beats: 7.0+, 8+ +* Elastic Agent: 7.10+ (standalone), 7.14+, 8+ (Fleet) +* Elastic Maps Server: 7.11+, 8+ +* Logstash 8.7+ + +Check the [Quickstart](https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-quickstart.html) to deploy your first cluster with ECK. + +For general questions, please see the Elastic [forums](https://discuss.elastic.co/c/eck). + +# ECK Operator Helm Chart + +A Helm chart to install the ECK Operator: the official Kubernetes operator from Elastic to orchestrate Elasticsearch, Kibana, APM Server, Enterprise Search, and Beats on Kubernetes. + +For more information about the ECK Operator, see: +- [Documentation](https://www.elastic.co/guide/en/cloud-on-k8s/current/index.html) +- [GitHub repo](https://github.com/elastic/cloud-on-k8s) + + +## Requirements + +- Supported Kubernetes versions are listed in the documentation: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s_supported_versions.html + +## Usage + +Refer to the documentation at https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-install-helm.html \ No newline at end of file diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator-3.0.0.tgz b/packs/elastic-operator-3.0.0/charts/eck-operator-3.0.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..4181d912c0cfdce6329948bbcf15fc7857c37bc9 GIT binary patch literal 136588 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

& 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%0Asgzz?u{K^{7~9q{A@mQG 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

amL)GiFco%zWAX-1-jkK~1T(9w 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.21.0-0' +maintainers: +- email: eck@elastic.co + name: Elastic +name: eck-operator +type: application +version: 3.0.0 diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/LICENSE b/packs/elastic-operator-3.0.0/charts/eck-operator/LICENSE new file mode 100644 index 00000000..92503a72 --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/LICENSE @@ -0,0 +1,93 @@ +Elastic License 2.0 + +URL: https://www.elastic.co/licensing/elastic-license + +## Acceptance + +By using the software, you agree to all of the terms and conditions below. + +## Copyright License + +The licensor grants you a non-exclusive, royalty-free, worldwide, +non-sublicensable, non-transferable license to use, copy, distribute, make +available, and prepare derivative works of the software, in each case subject to +the limitations and conditions below. + +## Limitations + +You may not provide the software to third parties as a hosted or managed +service, where the service provides users with access to any substantial set of +the features or functionality of the software. + +You may not move, change, disable, or circumvent the license key functionality +in the software, and you may not remove or obscure any functionality in the +software that is protected by the license key. + +You may not alter, remove, or obscure any licensing, copyright, or other notices +of the licensor in the software. Any use of the licensor’s trademarks is subject +to applicable law. + +## Patents + +The licensor grants you a license, under any patent claims the licensor can +license, or becomes able to license, to make, have made, use, sell, offer for +sale, import and have imported the software, in each case subject to the +limitations and conditions in this license. This license does not cover any +patent claims that you cause to be infringed by modifications or additions to +the software. If you or your company make any written claim that the software +infringes or contributes to infringement of any patent, your patent license for +the software granted under these terms ends immediately. If your company makes +such a claim, your patent license ends immediately for work on behalf of your +company. + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you +also gets a copy of these terms. + +If you modify the software, you must include in any modified copies of the +software prominent notices stating that you have modified the software. + +## No Other Rights + +These terms do not imply any licenses other than those expressly granted in +these terms. + +## Termination + +If you use the software in violation of these terms, such use is not licensed, +and your licenses will automatically terminate. If the licensor provides you +with a notice of your violation, and you cease all violation of this license no +later than 30 days after you receive that notice, your licenses will be +reinstated retroactively. However, if you violate these terms after such +reinstatement, any additional violation of these terms will cause your licenses +to terminate automatically and permanently. + +## No Liability + +*As far as the law allows, the software comes as is, without any warranty or +condition, and the licensor will not be liable to you for any damages arising +out of these terms or the use or nature of the software, under any kind of +legal claim.* + +## Definitions + +The **licensor** is the entity offering these terms, and the **software** is the +software the licensor makes available under these terms, including any portion +of it. + +**you** refers to the individual or entity agreeing to these terms. + +**your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control over, +are under the control of, or are under common control with that +organization. **control** means ownership of substantially all the assets of an +entity, or the power to direct its management and policies by vote, contract, or +otherwise. Control can be direct or indirect. + +**your licenses** are all the licenses granted to you for the software under +these terms. + +**use** means anything you do with the software requiring one of your licenses. + +**trademark** means trademarks, service marks, and similar rights. \ No newline at end of file diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/README.md b/packs/elastic-operator-3.0.0/charts/eck-operator/README.md new file mode 100644 index 00000000..86452e3d --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/README.md @@ -0,0 +1,20 @@ +# ECK Operator Helm Chart + +[![Artifact HUB](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/elastic)](https://artifacthub.io/packages/helm/elastic/eck-operator) + +A Helm chart to install the ECK Operator: the official Kubernetes operator from Elastic to orchestrate Elasticsearch, Kibana, APM Server, Enterprise Search, and Beats on Kubernetes. + +For more information about the ECK Operator, see: +- [Documentation](https://www.elastic.co/guide/en/cloud-on-k8s/current/index.html) +- [GitHub repo](https://github.com/elastic/cloud-on-k8s) + + +## Requirements + +- Supported Kubernetes versions are listed in the documentation: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s_supported_versions.html +- Helm >= 3.2.0 + + +## Usage + +Refer to the documentation at https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-install-helm.html diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/.helmignore b/packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/Chart.yaml b/packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/Chart.yaml new file mode 100644 index 00000000..390b73f1 --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/Chart.yaml @@ -0,0 +1,21 @@ +apiVersion: v2 +appVersion: 3.0.0 +description: ECK operator Custom Resource Definitions +home: https://github.com/elastic/cloud-on-k8s +icon: https://helm.elastic.co/icons/eck.png +keywords: +- Logstash +- Elasticsearch +- Kibana +- APM Server +- Beats +- Enterprise Search +- Elastic Stack +- Operator +kubeVersion: '>=1.21.0-0' +maintainers: +- email: eck@elastic.co + name: Elastic +name: eck-operator-crds +type: application +version: 3.0.0 diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/README.md b/packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/README.md new file mode 100644 index 00000000..698d6dd4 --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/README.md @@ -0,0 +1,16 @@ +# ECK Operator CRDs Helm Chart + +[![Artifact HUB](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/elastic)](https://artifacthub.io/packages/helm/elastic/eck-operator-crds) + +A Helm chart to install the Kubernetes Custom Resource Definitions (CRD) required by the ECK Operator: the official Kubernetes operator from Elastic to orchestrate Elasticsearch, Kibana, APM Server, Enterprise Search, and Beats on Kubernetes. This chart is usually automatically installed by the [ECK Operator Helm Chart](https://artifacthub.io/packages/helm/elastic/eck-operator) when installed using the default settings. Refer to the [installation documentation](https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-install-helm.html) for more information. + + +## Requirements + +- Supported Kubernetes versions are listed in the documentation: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s_supported_versions.html +- Helm >= 3.2.0 + + +## Usage + +Refer to the documentation at https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-install-helm.html diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/templates/NOTES.txt b/packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/templates/NOTES.txt new file mode 100644 index 00000000..1478c82b --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/templates/NOTES.txt @@ -0,0 +1 @@ +ECK Custom Resource Definitions installed. diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/templates/_helpers.tpl b/packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/templates/_helpers.tpl new file mode 100644 index 00000000..548f1bc6 --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "eck-operator-crds.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "eck-operator-crds.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "eck-operator-crds.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "eck-operator-crds.labels" -}} +helm.sh/chart: {{ include "eck-operator-crds.chart" . }} +{{ include "eck-operator-crds.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "eck-operator-crds.selectorLabels" -}} +app.kubernetes.io/name: {{ include "eck-operator-crds.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Determine effective Kubernetes version +*/}} +{{- define "eck-operator-crds.effectiveKubeVersion" -}} +{{- if .Values.global.manifestGen -}} +{{- semver .Values.global.kubeVersion -}} +{{- else -}} +{{- .Capabilities.KubeVersion.Version -}} +{{- end -}} +{{- end -}} diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml b/packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml new file mode 100644 index 00000000..52a4b26a --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml @@ -0,0 +1,10726 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.2 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: agents.agent.k8s.elastic.co +spec: + group: agent.k8s.elastic.co + names: + categories: + - elastic + kind: Agent + listKind: AgentList + plural: agents + shortNames: + - agent + singular: agent + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: available + type: integer + - description: Expected nodes + jsonPath: .status.expectedNodes + name: expected + type: integer + - description: Agent version + jsonPath: .status.version + name: version + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: Agent is the Schema for the Agents API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: AgentSpec defines the desired state of the Agent + properties: + config: + description: Config holds the Agent configuration. At most one of + [`Config`, `ConfigRef`] can be specified. + type: object + x-kubernetes-preserve-unknown-fields: true + configRef: + description: |- + ConfigRef contains a reference to an existing Kubernetes Secret holding the Agent configuration. + Agent settings must be specified as yaml, under a single "agent.yml" entry. At most one of [`Config`, `ConfigRef`] + can be specified. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + daemonSet: + description: |- + DaemonSet specifies the Agent should be deployed as a DaemonSet, and allows providing its spec. + Cannot be used along with `deployment` or `statefulSet`. + properties: + podTemplate: + description: PodTemplateSpec describes the data a pod should have + when created from a template + type: object + x-kubernetes-preserve-unknown-fields: true + updateStrategy: + description: DaemonSetUpdateStrategy is a struct used to control + the update strategy for a DaemonSet. + properties: + rollingUpdate: + description: Rolling update config params. Present only if + type = "RollingUpdate". + properties: + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of nodes with an existing available DaemonSet pod that + can have an updated DaemonSet pod during during an update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up to a minimum of 1. + Default value is 0. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their a new pod created before the old pod is marked as deleted. + The update starts by launching new pods on 30% of nodes. Once an updated + pod is available (Ready for at least minReadySeconds) the old DaemonSet pod + on that node is marked deleted. If the old pod becomes unavailable for any + reason (Ready transitions to false, is evicted, or is drained) an updated + pod is immediatedly created on that node without considering surge limits. + Allowing surge implies the possibility that the resources consumed by the + daemonset on any given node can double if the readiness check fails, and + so resource intensive daemonsets should take into account that they may + cause evictions during disruption. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of DaemonSet pods that can be unavailable during the + update. Value can be an absolute number (ex: 5) or a percentage of total + number of DaemonSet pods at the start of the update (ex: 10%). Absolute + number is calculated from percentage by rounding up. + This cannot be 0 if MaxSurge is 0 + Default value is 1. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their pods stopped for an update at any given time. The update + starts by stopping at most 30% of those DaemonSet pods and then brings + up new DaemonSet pods in their place. Once the new pods are available, + it then proceeds onto other DaemonSet pods, thus ensuring that at least + 70% of original number of DaemonSet pods are available at all times during + the update. + x-kubernetes-int-or-string: true + type: object + type: + description: Type of daemon set update. Can be "RollingUpdate" + or "OnDelete". Default is RollingUpdate. + type: string + type: object + type: object + deployment: + description: |- + Deployment specifies the Agent should be deployed as a Deployment, and allows providing its spec. + Cannot be used along with `daemonSet` or `statefulSet`. + properties: + podTemplate: + description: PodTemplateSpec describes the data a pod should have + when created from a template + type: object + x-kubernetes-preserve-unknown-fields: true + replicas: + format: int32 + type: integer + strategy: + description: DeploymentStrategy describes how to replace existing + pods with new ones. + properties: + rollingUpdate: + description: |- + Rolling update config params. Present only if DeploymentStrategyType = + RollingUpdate. + properties: + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be scheduled above the desired number of + pods. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 25%. + Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when + the rolling update starts, such that the total number of old and new pods do not exceed + 130% of desired pods. Once old pods have been killed, + new ReplicaSet can be scaled up further, ensuring that total number of pods running + at any time during the update is at most 130% of desired pods. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 25%. + Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods + immediately when the rolling update starts. Once new pods are ready, old ReplicaSet + can be scaled down further, followed by scaling up the new ReplicaSet, ensuring + that the total number of pods available at all times during the update is at + least 70% of desired pods. + x-kubernetes-int-or-string: true + type: object + type: + description: Type of deployment. Can be "Recreate" or "RollingUpdate". + Default is RollingUpdate. + type: string + type: object + type: object + elasticsearchRefs: + description: |- + ElasticsearchRefs is a reference to a list of Elasticsearch clusters running in the same Kubernetes cluster. + Due to existing limitations, only a single ES cluster is currently supported. + items: + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + outputName: + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + type: array + fleetServerEnabled: + description: FleetServerEnabled determines whether this Agent will + launch Fleet Server. Don't set unless `mode` is set to `fleet`. + type: boolean + fleetServerRef: + description: |- + FleetServerRef is a reference to Fleet Server that this Agent should connect to to obtain it's configuration. + Don't set unless `mode` is set to `fleet`. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + http: + description: HTTP holds the HTTP layer configuration for the Agent + in Fleet mode with Fleet Server enabled. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic is + distributed to Service endpoints. Implementations can use this field as a + hint, but are not required to guarantee strict adherence. If the field is + not set, the implementation will apply its default routing strategy. If set + to "PreferClose", implementations should prioritize endpoints that are + topologically close (e.g., same zone). + This is a beta field and requires enabling ServiceTrafficDistribution feature. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the Agent Docker image to deploy. Version has + to match the Agent in the image. + type: string + kibanaRef: + description: |- + KibanaRef is a reference to Kibana where Fleet should be set up and this Agent should be enrolled. Don't set + unless `mode` is set to `fleet`. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + mode: + description: |- + Mode specifies the source of configuration for the Agent. The configuration can be specified locally through + `config` or `configRef` (`standalone` mode), or come from Fleet during runtime (`fleet` mode). + Defaults to `standalone` mode. + enum: + - standalone + - fleet + type: string + policyID: + description: |- + PolicyID determines into which Agent Policy this Agent will be enrolled. + This field will become mandatory in a future release, default policies are deprecated since 8.1.0. + type: string + revisionHistoryLimit: + description: RevisionHistoryLimit is the number of revisions to retain + to allow rollback in the underlying DaemonSet or Deployment or StatefulSet. + format: int32 + type: integer + secureSettings: + description: |- + SecureSettings is a list of references to Kubernetes Secrets containing sensitive configuration options for the Agent. + Secrets data can be then referenced in the Agent config using the Secret's keys or as specified in `Entries` field of + each SecureSetting. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + serviceAccountName: + description: |- + ServiceAccountName is used to check access from the current resource to an Elasticsearch resource in a different namespace. + Can only be used if ECK is enforcing RBAC on references. + type: string + statefulSet: + description: |- + StatefulSet specifies the Agent should be deployed as a StatefulSet, and allows providing its spec. + Cannot be used along with `daemonSet` or `deployment`. + properties: + podManagementPolicy: + default: Parallel + description: |- + PodManagementPolicy controls how pods are created during initial scale up, + when replacing pods on nodes, or when scaling down. The default policy is + `Parallel`, where pods are created in parallel to match the desired scale + without waiting, and on scale down will delete all pods at once. + The alternative policy is `OrderedReady`, the default for vanilla kubernetes + StatefulSets, where pods are created in increasing order in increasing order + (pod-0, then pod-1, etc.) and the controller will wait until each pod is ready before + continuing. When scaling down, the pods are removed in the opposite order. + enum: + - OrderedReady + - Parallel + type: string + podTemplate: + description: PodTemplateSpec describes the data a pod should have + when created from a template + type: object + x-kubernetes-preserve-unknown-fields: true + replicas: + format: int32 + type: integer + serviceName: + type: string + volumeClaimTemplates: + description: |- + VolumeClaimTemplates is a list of persistent volume claims to be used by each Pod. + Every claim in this list must have a matching volumeMount in one of the containers defined in the PodTemplate. + Items defined here take precedence over any default claims added by the operator with the same name. + items: + description: PersistentVolumeClaim is a user's request for and + claim to a persistent volume + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + spec defines the desired characteristics of a volume requested by a pod author. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes + to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to + the PersistentVolume backing this claim. + type: string + type: object + type: object + type: array + type: object + version: + description: Version of the Agent. + type: string + required: + - version + type: object + status: + description: AgentStatus defines the observed state of the Agent + properties: + availableNodes: + format: int32 + type: integer + elasticsearchAssociationsStatus: + additionalProperties: + description: AssociationStatus is the status of an association resource. + type: string + description: |- + AssociationStatusMap is the map of association's namespaced name string to its AssociationStatus. For resources that + have a single Association of a given type (for ex. single ES reference), this map contains a single entry. + type: object + expectedNodes: + format: int32 + type: integer + fleetServerAssociationStatus: + description: AssociationStatus is the status of an association resource. + type: string + health: + type: string + kibanaAssociationStatus: + description: AssociationStatus is the status of an association resource. + type: string + observedGeneration: + description: |- + ObservedGeneration is the most recent generation observed for this Elastic Agent. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + If the generation observed in status diverges from the generation in metadata, the Elastic + Agent controller has not yet processed the changes contained in the Elastic Agent specification. + format: int64 + type: integer + version: + description: |- + Version of the stack resource currently running. During version upgrades, multiple versions may run + in parallel: this value specifies the lowest version currently running. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.2 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: apmservers.apm.k8s.elastic.co +spec: + group: apm.k8s.elastic.co + names: + categories: + - elastic + kind: ApmServer + listKind: ApmServerList + plural: apmservers + shortNames: + - apm + singular: apmserver + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: nodes + type: integer + - description: APM version + jsonPath: .status.version + name: version + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1 + schema: + openAPIV3Schema: + description: ApmServer represents an APM Server resource in a Kubernetes cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ApmServerSpec holds the specification of an APM Server. + properties: + config: + description: 'Config holds the APM Server configuration. See: https://www.elastic.co/guide/en/apm/server/current/configuring-howto-apm-server.html' + type: object + x-kubernetes-preserve-unknown-fields: true + count: + description: Count of APM Server instances to deploy. + format: int32 + type: integer + elasticsearchRef: + description: ElasticsearchRef is a reference to the output Elasticsearch + cluster running in the same Kubernetes cluster. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + http: + description: HTTP holds the HTTP layer configuration for the APM Server + resource. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic is + distributed to Service endpoints. Implementations can use this field as a + hint, but are not required to guarantee strict adherence. If the field is + not set, the implementation will apply its default routing strategy. If set + to "PreferClose", implementations should prioritize endpoints that are + topologically close (e.g., same zone). + This is a beta field and requires enabling ServiceTrafficDistribution feature. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the APM Server Docker image to deploy. + type: string + kibanaRef: + description: |- + KibanaRef is a reference to a Kibana instance running in the same Kubernetes cluster. + It allows APM agent central configuration management in Kibana. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + podTemplate: + description: PodTemplate provides customisation options (labels, annotations, + affinity rules, resource requests, and so on) for the APM Server + pods. + type: object + x-kubernetes-preserve-unknown-fields: true + revisionHistoryLimit: + description: RevisionHistoryLimit is the number of revisions to retain + to allow rollback in the underlying Deployment. + format: int32 + type: integer + secureSettings: + description: SecureSettings is a list of references to Kubernetes + secrets containing sensitive configuration options for APM Server. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + serviceAccountName: + description: |- + ServiceAccountName is used to check access from the current resource to a resource (for ex. Elasticsearch) in a different namespace. + Can only be used if ECK is enforcing RBAC on references. + type: string + version: + description: Version of the APM Server. + type: string + required: + - version + type: object + status: + description: ApmServerStatus defines the observed state of ApmServer + properties: + availableNodes: + description: AvailableNodes is the number of available replicas in + the deployment. + format: int32 + type: integer + count: + description: Count corresponds to Scale.Status.Replicas, which is + the actual number of observed instances of the scaled object. + format: int32 + type: integer + elasticsearchAssociationStatus: + description: ElasticsearchAssociationStatus is the status of any auto-linking + to Elasticsearch clusters. + type: string + health: + description: Health of the deployment. + type: string + kibanaAssociationStatus: + description: KibanaAssociationStatus is the status of any auto-linking + to Kibana. + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the status is based upon. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + If the generation observed in status diverges from the generation in metadata, the APM Server + controller has not yet processed the changes contained in the APM Server specification. + format: int64 + type: integer + secretTokenSecret: + description: SecretTokenSecretName is the name of the Secret that + contains the secret token + type: string + selector: + description: Selector is the label selector used to find all pods. + type: string + service: + description: ExternalService is the name of the service the agents + should connect to. + type: string + version: + description: |- + Version of the stack resource currently running. During version upgrades, multiple versions may run + in parallel: this value specifies the lowest version currently running. + type: string + type: object + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.count + statusReplicasPath: .status.count + status: {} + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: nodes + type: integer + - description: APM version + jsonPath: .spec.version + name: version + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: ApmServer represents an APM Server resource in a Kubernetes cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ApmServerSpec holds the specification of an APM Server. + properties: + config: + description: 'Config holds the APM Server configuration. See: https://www.elastic.co/guide/en/apm/server/current/configuring-howto-apm-server.html' + type: object + x-kubernetes-preserve-unknown-fields: true + count: + description: Count of APM Server instances to deploy. + format: int32 + type: integer + elasticsearchRef: + description: ElasticsearchRef is a reference to the output Elasticsearch + cluster running in the same Kubernetes cluster. + properties: + name: + description: Name of the Kubernetes object. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + required: + - name + type: object + http: + description: HTTP holds the HTTP layer configuration for the APM Server + resource. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic is + distributed to Service endpoints. Implementations can use this field as a + hint, but are not required to guarantee strict adherence. If the field is + not set, the implementation will apply its default routing strategy. If set + to "PreferClose", implementations should prioritize endpoints that are + topologically close (e.g., same zone). + This is a beta field and requires enabling ServiceTrafficDistribution feature. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the APM Server Docker image to deploy. + type: string + podTemplate: + description: PodTemplate provides customisation options (labels, annotations, + affinity rules, resource requests, and so on) for the APM Server + pods. + type: object + x-kubernetes-preserve-unknown-fields: true + secureSettings: + description: SecureSettings is a list of references to Kubernetes + secrets containing sensitive configuration options for APM Server. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + version: + description: Version of the APM Server. + type: string + type: object + status: + description: ApmServerStatus defines the observed state of ApmServer + properties: + associationStatus: + description: Association is the status of any auto-linking to Elasticsearch + clusters. + type: string + availableNodes: + format: int32 + type: integer + health: + description: ApmServerHealth expresses the status of the Apm Server + instances. + type: string + secretTokenSecret: + description: SecretTokenSecretName is the name of the Secret that + contains the secret token + type: string + service: + description: ExternalService is the name of the service the agents + should connect to. + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} + - name: v1alpha1 + schema: + openAPIV3Schema: + description: to not break compatibility when upgrading from previous versions + of the CRD + type: object + served: false + storage: false +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.2 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: beats.beat.k8s.elastic.co +spec: + group: beat.k8s.elastic.co + names: + categories: + - elastic + kind: Beat + listKind: BeatList + plural: beats + shortNames: + - beat + singular: beat + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: available + type: integer + - description: Expected nodes + jsonPath: .status.expectedNodes + name: expected + type: integer + - description: Beat type + jsonPath: .spec.type + name: type + type: string + - description: Beat version + jsonPath: .status.version + name: version + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: Beat is the Schema for the Beats API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: BeatSpec defines the desired state of a Beat. + properties: + config: + description: Config holds the Beat configuration. At most one of [`Config`, + `ConfigRef`] can be specified. + type: object + x-kubernetes-preserve-unknown-fields: true + configRef: + description: |- + ConfigRef contains a reference to an existing Kubernetes Secret holding the Beat configuration. + Beat settings must be specified as yaml, under a single "beat.yml" entry. At most one of [`Config`, `ConfigRef`] + can be specified. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + daemonSet: + description: |- + DaemonSet specifies the Beat should be deployed as a DaemonSet, and allows providing its spec. + Cannot be used along with `deployment`. If both are absent a default for the Type is used. + properties: + podTemplate: + description: PodTemplateSpec describes the data a pod should have + when created from a template + type: object + x-kubernetes-preserve-unknown-fields: true + updateStrategy: + description: DaemonSetUpdateStrategy is a struct used to control + the update strategy for a DaemonSet. + properties: + rollingUpdate: + description: Rolling update config params. Present only if + type = "RollingUpdate". + properties: + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of nodes with an existing available DaemonSet pod that + can have an updated DaemonSet pod during during an update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up to a minimum of 1. + Default value is 0. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their a new pod created before the old pod is marked as deleted. + The update starts by launching new pods on 30% of nodes. Once an updated + pod is available (Ready for at least minReadySeconds) the old DaemonSet pod + on that node is marked deleted. If the old pod becomes unavailable for any + reason (Ready transitions to false, is evicted, or is drained) an updated + pod is immediatedly created on that node without considering surge limits. + Allowing surge implies the possibility that the resources consumed by the + daemonset on any given node can double if the readiness check fails, and + so resource intensive daemonsets should take into account that they may + cause evictions during disruption. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of DaemonSet pods that can be unavailable during the + update. Value can be an absolute number (ex: 5) or a percentage of total + number of DaemonSet pods at the start of the update (ex: 10%). Absolute + number is calculated from percentage by rounding up. + This cannot be 0 if MaxSurge is 0 + Default value is 1. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their pods stopped for an update at any given time. The update + starts by stopping at most 30% of those DaemonSet pods and then brings + up new DaemonSet pods in their place. Once the new pods are available, + it then proceeds onto other DaemonSet pods, thus ensuring that at least + 70% of original number of DaemonSet pods are available at all times during + the update. + x-kubernetes-int-or-string: true + type: object + type: + description: Type of daemon set update. Can be "RollingUpdate" + or "OnDelete". Default is RollingUpdate. + type: string + type: object + type: object + deployment: + description: |- + Deployment specifies the Beat should be deployed as a Deployment, and allows providing its spec. + Cannot be used along with `daemonSet`. If both are absent a default for the Type is used. + properties: + podTemplate: + description: PodTemplateSpec describes the data a pod should have + when created from a template + type: object + x-kubernetes-preserve-unknown-fields: true + replicas: + format: int32 + type: integer + strategy: + description: DeploymentStrategy describes how to replace existing + pods with new ones. + properties: + rollingUpdate: + description: |- + Rolling update config params. Present only if DeploymentStrategyType = + RollingUpdate. + properties: + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be scheduled above the desired number of + pods. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 25%. + Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when + the rolling update starts, such that the total number of old and new pods do not exceed + 130% of desired pods. Once old pods have been killed, + new ReplicaSet can be scaled up further, ensuring that total number of pods running + at any time during the update is at most 130% of desired pods. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 25%. + Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods + immediately when the rolling update starts. Once new pods are ready, old ReplicaSet + can be scaled down further, followed by scaling up the new ReplicaSet, ensuring + that the total number of pods available at all times during the update is at + least 70% of desired pods. + x-kubernetes-int-or-string: true + type: object + type: + description: Type of deployment. Can be "Recreate" or "RollingUpdate". + Default is RollingUpdate. + type: string + type: object + type: object + elasticsearchRef: + description: ElasticsearchRef is a reference to an Elasticsearch cluster + running in the same Kubernetes cluster. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + image: + description: Image is the Beat Docker image to deploy. Version and + Type have to match the Beat in the image. + type: string + kibanaRef: + description: |- + KibanaRef is a reference to a Kibana instance running in the same Kubernetes cluster. + It allows automatic setup of dashboards and visualizations. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + monitoring: + description: |- + Monitoring enables you to collect and ship logs and metrics for this Beat. + Metricbeat and/or Filebeat sidecars are configured and send monitoring data to an + Elasticsearch monitoring cluster running in the same Kubernetes cluster. + properties: + logs: + description: Logs holds references to Elasticsearch clusters which + receive log data from an associated resource. + properties: + elasticsearchRefs: + description: |- + ElasticsearchRefs is a reference to a list of monitoring Elasticsearch clusters running in the same Kubernetes cluster. + Due to existing limitations, only a single Elasticsearch cluster is currently supported. + items: + description: |- + ObjectSelector defines a reference to a Kubernetes object which can be an Elastic resource managed by the operator + or a Secret describing an external Elastic resource not managed by the operator. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If + empty, defaults to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + type: array + type: object + metrics: + description: Metrics holds references to Elasticsearch clusters + which receive monitoring data from this resource. + properties: + elasticsearchRefs: + description: |- + ElasticsearchRefs is a reference to a list of monitoring Elasticsearch clusters running in the same Kubernetes cluster. + Due to existing limitations, only a single Elasticsearch cluster is currently supported. + items: + description: |- + ObjectSelector defines a reference to a Kubernetes object which can be an Elastic resource managed by the operator + or a Secret describing an external Elastic resource not managed by the operator. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If + empty, defaults to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + type: array + type: object + type: object + revisionHistoryLimit: + description: RevisionHistoryLimit is the number of revisions to retain + to allow rollback in the underlying DaemonSet or Deployment. + format: int32 + type: integer + secureSettings: + description: |- + SecureSettings is a list of references to Kubernetes Secrets containing sensitive configuration options for the Beat. + Secrets data can be then referenced in the Beat config using the Secret's keys or as specified in `Entries` field of + each SecureSetting. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + serviceAccountName: + description: |- + ServiceAccountName is used to check access from the current resource to Elasticsearch resource in a different namespace. + Can only be used if ECK is enforcing RBAC on references. + type: string + type: + description: |- + Type is the type of the Beat to deploy (filebeat, metricbeat, heartbeat, auditbeat, journalbeat, packetbeat, and so on). + Any string can be used, but well-known types will have the image field defaulted and have the appropriate + Elasticsearch roles created automatically. It also allows for dashboard setup when combined with a `KibanaRef`. + maxLength: 20 + pattern: '[a-zA-Z0-9-]+' + type: string + version: + description: Version of the Beat. + type: string + required: + - type + - version + type: object + status: + description: BeatStatus defines the observed state of a Beat. + properties: + availableNodes: + format: int32 + type: integer + elasticsearchAssociationStatus: + description: AssociationStatus is the status of an association resource. + type: string + expectedNodes: + format: int32 + type: integer + health: + type: string + kibanaAssociationStatus: + description: AssociationStatus is the status of an association resource. + type: string + monitoringAssociationStatus: + additionalProperties: + description: AssociationStatus is the status of an association resource. + type: string + description: |- + AssociationStatusMap is the map of association's namespaced name string to its AssociationStatus. For resources that + have a single Association of a given type (for ex. single ES reference), this map contains a single entry. + type: object + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the status is based upon. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + If the generation observed in status diverges from the generation in metadata, the Beats + controller has not yet processed the changes contained in the Beats specification. + format: int64 + type: integer + version: + description: |- + Version of the stack resource currently running. During version upgrades, multiple versions may run + in parallel: this value specifies the lowest version currently running. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.2 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: elasticmapsservers.maps.k8s.elastic.co +spec: + group: maps.k8s.elastic.co + names: + categories: + - elastic + kind: ElasticMapsServer + listKind: ElasticMapsServerList + plural: elasticmapsservers + shortNames: + - ems + singular: elasticmapsserver + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: nodes + type: integer + - description: ElasticMapsServer version + jsonPath: .status.version + name: version + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: ElasticMapsServer represents an Elastic Map Server resource in + a Kubernetes cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MapsSpec holds the specification of an Elastic Maps Server + instance. + properties: + config: + description: 'Config holds the ElasticMapsServer configuration. See: + https://www.elastic.co/guide/en/kibana/current/maps-connect-to-ems.html#elastic-maps-server-configuration' + type: object + x-kubernetes-preserve-unknown-fields: true + configRef: + description: |- + ConfigRef contains a reference to an existing Kubernetes Secret holding the Elastic Maps Server configuration. + Configuration settings are merged and have precedence over settings specified in `config`. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + count: + description: Count of Elastic Maps Server instances to deploy. + format: int32 + type: integer + elasticsearchRef: + description: ElasticsearchRef is a reference to an Elasticsearch cluster + running in the same Kubernetes cluster. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + http: + description: HTTP holds the HTTP layer configuration for Elastic Maps + Server. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic is + distributed to Service endpoints. Implementations can use this field as a + hint, but are not required to guarantee strict adherence. If the field is + not set, the implementation will apply its default routing strategy. If set + to "PreferClose", implementations should prioritize endpoints that are + topologically close (e.g., same zone). + This is a beta field and requires enabling ServiceTrafficDistribution feature. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the Elastic Maps Server Docker image to deploy. + type: string + podTemplate: + description: PodTemplate provides customisation options (labels, annotations, + affinity rules, resource requests, and so on) for the Elastic Maps + Server pods + type: object + x-kubernetes-preserve-unknown-fields: true + revisionHistoryLimit: + description: RevisionHistoryLimit is the number of revisions to retain + to allow rollback in the underlying Deployment. + format: int32 + type: integer + serviceAccountName: + description: |- + ServiceAccountName is used to check access from the current resource to a resource (for ex. Elasticsearch) in a different namespace. + Can only be used if ECK is enforcing RBAC on references. + type: string + version: + description: Version of Elastic Maps Server. + type: string + required: + - version + type: object + status: + description: MapsStatus defines the observed state of Elastic Maps Server + properties: + associationStatus: + description: AssociationStatus is the status of an association resource. + type: string + availableNodes: + description: AvailableNodes is the number of available replicas in + the deployment. + format: int32 + type: integer + count: + description: Count corresponds to Scale.Status.Replicas, which is + the actual number of observed instances of the scaled object. + format: int32 + type: integer + health: + description: Health of the deployment. + type: string + observedGeneration: + description: |- + ObservedGeneration is the most recent generation observed for this Elastic Maps Server. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + If the generation observed in status diverges from the generation in metadata, the Elastic + Maps controller has not yet processed the changes contained in the Elastic Maps specification. + format: int64 + type: integer + selector: + description: Selector is the label selector used to find all pods. + type: string + version: + description: |- + Version of the stack resource currently running. During version upgrades, multiple versions may run + in parallel: this value specifies the lowest version currently running. + type: string + type: object + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.count + statusReplicasPath: .status.count + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.2 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: elasticsearchautoscalers.autoscaling.k8s.elastic.co +spec: + group: autoscaling.k8s.elastic.co + names: + categories: + - elastic + kind: ElasticsearchAutoscaler + listKind: ElasticsearchAutoscalerList + plural: elasticsearchautoscalers + shortNames: + - esa + singular: elasticsearchautoscaler + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.elasticsearchRef.name + name: Target + type: string + - jsonPath: .status.conditions[?(@.type=='Active')].status + name: Active + type: string + - jsonPath: .status.conditions[?(@.type=='Healthy')].status + name: Healthy + type: string + - jsonPath: .status.conditions[?(@.type=='Limited')].status + name: Limited + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: ElasticsearchAutoscaler represents an ElasticsearchAutoscaler + resource in a Kubernetes cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ElasticsearchAutoscalerSpec holds the specification of an + Elasticsearch autoscaler resource. + properties: + elasticsearchRef: + description: ElasticsearchRef is a reference to an Elasticsearch cluster + that exists in the same namespace. + properties: + name: + description: Name is the name of the Elasticsearch resource to + scale automatically. + minLength: 1 + type: string + type: object + policies: + items: + description: AutoscalingPolicySpec holds a named autoscaling policy + and the associated resources limits (cpu, memory, storage). + properties: + deciders: + additionalProperties: + additionalProperties: + type: string + description: |- + DeciderSettings allow the user to tweak autoscaling deciders. + The map data structure complies with the format expected by Elasticsearch. + type: object + description: Deciders allow the user to override default settings + for autoscaling deciders. + type: object + name: + description: Name identifies the autoscaling policy in the autoscaling + specification. + type: string + resources: + description: |- + AutoscalingResources model the limits, submitted by the user, for the supported resources in an autoscaling policy. + Only the node count range is mandatory. For other resources, a limit range is required only + if the Elasticsearch autoscaling capacity API returns a requirement for a given resource. + For example, the memory limit range is only required if the autoscaling API response contains a memory requirement. + If there is no limit range for a resource, and if that resource is not mandatory, then the resources in the NodeSets + managed by the autoscaling policy are left untouched. + properties: + cpu: + description: QuantityRange models a resource limit range + for resources which can be expressed with resource.Quantity. + properties: + max: + anyOf: + - type: integer + - type: string + description: Max represents the upper limit for the + resources managed by the autoscaler. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + min: + anyOf: + - type: integer + - type: string + description: Min represents the lower limit for the + resources managed by the autoscaler. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + requestsToLimitsRatio: + anyOf: + - type: integer + - type: string + description: RequestsToLimitsRatio allows to customize + Kubernetes resource Limit based on the Request. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + required: + - max + - min + type: object + memory: + description: QuantityRange models a resource limit range + for resources which can be expressed with resource.Quantity. + properties: + max: + anyOf: + - type: integer + - type: string + description: Max represents the upper limit for the + resources managed by the autoscaler. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + min: + anyOf: + - type: integer + - type: string + description: Min represents the lower limit for the + resources managed by the autoscaler. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + requestsToLimitsRatio: + anyOf: + - type: integer + - type: string + description: RequestsToLimitsRatio allows to customize + Kubernetes resource Limit based on the Request. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + required: + - max + - min + type: object + nodeCount: + description: NodeCountRange is used to model the minimum + and the maximum number of nodes over all the NodeSets + managed by the same autoscaling policy. + properties: + max: + description: Max represents the maximum number of nodes + in a tier. + format: int32 + type: integer + min: + description: Min represents the minimum number of nodes + in a tier. + format: int32 + type: integer + required: + - max + - min + type: object + storage: + description: QuantityRange models a resource limit range + for resources which can be expressed with resource.Quantity. + properties: + max: + anyOf: + - type: integer + - type: string + description: Max represents the upper limit for the + resources managed by the autoscaler. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + min: + anyOf: + - type: integer + - type: string + description: Min represents the lower limit for the + resources managed by the autoscaler. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + requestsToLimitsRatio: + anyOf: + - type: integer + - type: string + description: RequestsToLimitsRatio allows to customize + Kubernetes resource Limit based on the Request. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + required: + - max + - min + type: object + required: + - nodeCount + type: object + roles: + description: An autoscaling policy must target a unique set + of roles. + items: + type: string + type: array + required: + - resources + type: object + type: array + pollingPeriod: + description: PollingPeriod is the period at which to synchronize with + the Elasticsearch autoscaling API. + type: string + required: + - elasticsearchRef + - policies + type: object + status: + properties: + conditions: + description: Conditions holds the current service state of the autoscaling + controller. + items: + description: |- + Condition represents Elasticsearch resource's condition. + **This API is in technical preview and may be changed or removed in a future release.** + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + status: + type: string + type: + description: ConditionType defines the condition of an Elasticsearch + resource. + type: string + required: + - status + - type + type: object + type: array + observedGeneration: + description: ObservedGeneration is the last observed generation by + the controller. + format: int64 + type: integer + policies: + description: AutoscalingPolicyStatuses is used to expose state messages + to user or external system. + items: + properties: + lastModificationTime: + description: LastModificationTime is the last time the resources + have been updated, used by the cooldown algorithm. + format: date-time + type: string + name: + description: Name is the name of the autoscaling policy + type: string + nodeSets: + description: NodeSetNodeCount holds the number of nodes for + each nodeSet. + items: + description: NodeSetNodeCount models the number of nodes expected + in a given NodeSet. + properties: + name: + description: Name of the Nodeset. + type: string + nodeCount: + description: NodeCount is the number of nodes, as computed + by the autoscaler, expected in this NodeSet. + format: int32 + type: integer + required: + - name + - nodeCount + type: object + type: array + resources: + description: |- + ResourcesSpecification holds the resource values common to all the nodeSets managed by a same autoscaling policy. + Only the resources managed by the autoscaling controller are saved in the Status. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: ResourceList is a set of (resource name, quantity) + pairs. + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: ResourceList is a set of (resource name, quantity) + pairs. + type: object + type: object + state: + description: PolicyStates may contain various messages regarding + the current state of this autoscaling policy. + items: + properties: + messages: + items: + type: string + type: array + type: + type: string + required: + - messages + - type + type: object + type: array + required: + - name + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.2 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: elasticsearches.elasticsearch.k8s.elastic.co +spec: + group: elasticsearch.k8s.elastic.co + names: + categories: + - elastic + kind: Elasticsearch + listKind: ElasticsearchList + plural: elasticsearches + shortNames: + - es + singular: elasticsearch + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: nodes + type: integer + - description: Elasticsearch version + jsonPath: .status.version + name: version + type: string + - jsonPath: .status.phase + name: phase + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1 + schema: + openAPIV3Schema: + description: Elasticsearch represents an Elasticsearch resource in a Kubernetes + cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ElasticsearchSpec holds the specification of an Elasticsearch + cluster. + properties: + auth: + description: Auth contains user authentication and authorization security + settings for Elasticsearch. + properties: + disableElasticUser: + description: DisableElasticUser disables the default elastic user + that is created by ECK. + type: boolean + fileRealm: + description: FileRealm to propagate to the Elasticsearch cluster. + items: + description: FileRealmSource references users to create in the + Elasticsearch cluster. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + type: array + roles: + description: Roles to propagate to the Elasticsearch cluster. + items: + description: RoleSource references roles to create in the Elasticsearch + cluster. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + type: array + type: object + http: + description: HTTP holds HTTP layer settings for Elasticsearch. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic is + distributed to Service endpoints. Implementations can use this field as a + hint, but are not required to guarantee strict adherence. If the field is + not set, the implementation will apply its default routing strategy. If set + to "PreferClose", implementations should prioritize endpoints that are + topologically close (e.g., same zone). + This is a beta field and requires enabling ServiceTrafficDistribution feature. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the Elasticsearch Docker image to deploy. + type: string + monitoring: + description: |- + Monitoring enables you to collect and ship log and monitoring data of this Elasticsearch cluster. + See https://www.elastic.co/guide/en/elasticsearch/reference/current/monitor-elasticsearch-cluster.html. + Metricbeat and Filebeat are deployed in the same Pod as sidecars and each one sends data to one or two different + Elasticsearch monitoring clusters running in the same Kubernetes cluster. + properties: + logs: + description: Logs holds references to Elasticsearch clusters which + receive log data from an associated resource. + properties: + elasticsearchRefs: + description: |- + ElasticsearchRefs is a reference to a list of monitoring Elasticsearch clusters running in the same Kubernetes cluster. + Due to existing limitations, only a single Elasticsearch cluster is currently supported. + items: + description: |- + ObjectSelector defines a reference to a Kubernetes object which can be an Elastic resource managed by the operator + or a Secret describing an external Elastic resource not managed by the operator. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If + empty, defaults to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + type: array + type: object + metrics: + description: Metrics holds references to Elasticsearch clusters + which receive monitoring data from this resource. + properties: + elasticsearchRefs: + description: |- + ElasticsearchRefs is a reference to a list of monitoring Elasticsearch clusters running in the same Kubernetes cluster. + Due to existing limitations, only a single Elasticsearch cluster is currently supported. + items: + description: |- + ObjectSelector defines a reference to a Kubernetes object which can be an Elastic resource managed by the operator + or a Secret describing an external Elastic resource not managed by the operator. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If + empty, defaults to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + type: array + type: object + type: object + nodeSets: + description: NodeSets allow specifying groups of Elasticsearch nodes + sharing the same configuration and Pod templates. + items: + description: NodeSet is the specification for a group of Elasticsearch + nodes sharing the same configuration and a Pod template. + properties: + config: + description: Config holds the Elasticsearch configuration. + type: object + x-kubernetes-preserve-unknown-fields: true + count: + description: |- + Count of Elasticsearch nodes to deploy. + If the node set is managed by an autoscaling policy the initial value is automatically set by the autoscaling controller. + format: int32 + type: integer + name: + description: Name of this set of nodes. Becomes a part of the + Elasticsearch node.name setting. + maxLength: 23 + pattern: '[a-zA-Z0-9-]+' + type: string + podTemplate: + description: PodTemplate provides customisation options (labels, + annotations, affinity rules, resource requests, and so on) + for the Pods belonging to this NodeSet. + type: object + x-kubernetes-preserve-unknown-fields: true + volumeClaimTemplates: + description: |- + VolumeClaimTemplates is a list of persistent volume claims to be used by each Pod in this NodeSet. + Every claim in this list must have a matching volumeMount in one of the containers defined in the PodTemplate. + Items defined here take precedence over any default claims added by the operator with the same name. + items: + description: PersistentVolumeClaim is a user's request for + and claim to a persistent volume + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + spec defines the desired characteristics of a volume requested by a pod author. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes + to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to + the PersistentVolume backing this claim. + type: string + type: object + type: object + type: array + required: + - name + type: object + minItems: 1 + type: array + podDisruptionBudget: + description: |- + PodDisruptionBudget provides access to the default Pod disruption budget for the Elasticsearch cluster. + The default budget doesn't allow any Pod to be removed in case the cluster is not green or if there is only one node of type `data` or `master`. + In all other cases the default PodDisruptionBudget sets `minUnavailable` equal to the total number of nodes minus 1. + To disable, set `PodDisruptionBudget` to the empty value (`{}` in YAML). + properties: + metadata: + description: |- + ObjectMeta is the metadata of the PDB. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the PDB. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + An eviction is allowed if at most "maxUnavailable" pods selected by + "selector" are unavailable after the eviction, i.e. even in absence of + the evicted pod. For example, one can prevent all voluntary evictions + by specifying 0. This is a mutually exclusive setting with "minAvailable". + x-kubernetes-int-or-string: true + minAvailable: + anyOf: + - type: integer + - type: string + description: |- + An eviction is allowed if at least "minAvailable" pods selected by + "selector" will still be available after the eviction, i.e. even in the + absence of the evicted pod. So for example you can prevent all voluntary + evictions by specifying "100%". + x-kubernetes-int-or-string: true + selector: + description: |- + Label query over pods whose evictions are managed by the disruption + budget. + A null selector will match no pods, while an empty ({}) selector will select + all pods within the namespace. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + unhealthyPodEvictionPolicy: + description: |- + UnhealthyPodEvictionPolicy defines the criteria for when unhealthy pods + should be considered for eviction. Current implementation considers healthy pods, + as pods that have status.conditions item with type="Ready",status="True". + + Valid policies are IfHealthyBudget and AlwaysAllow. + If no policy is specified, the default behavior will be used, + which corresponds to the IfHealthyBudget policy. + + IfHealthyBudget policy means that running pods (status.phase="Running"), + but not yet healthy can be evicted only if the guarded application is not + disrupted (status.currentHealthy is at least equal to status.desiredHealthy). + Healthy pods will be subject to the PDB for eviction. + + AlwaysAllow policy means that all running pods (status.phase="Running"), + but not yet healthy are considered disrupted and can be evicted regardless + of whether the criteria in a PDB is met. This means perspective running + pods of a disrupted application might not get a chance to become healthy. + Healthy pods will be subject to the PDB for eviction. + + Additional policies may be added in the future. + Clients making eviction decisions should disallow eviction of unhealthy pods + if they encounter an unrecognized policy in this field. + + This field is beta-level. The eviction API uses this field when + the feature gate PDBUnhealthyPodEvictionPolicy is enabled (enabled by default). + type: string + type: object + type: object + remoteClusterServer: + description: |- + RemoteClusterServer specifies if the remote cluster server should be enabled. + This must be enabled if this cluster is a remote cluster which is expected to be accessed using API key authentication. + properties: + enabled: + type: boolean + type: object + remoteClusters: + description: RemoteClusters enables you to establish uni-directional + connections to a remote Elasticsearch cluster. + items: + description: RemoteCluster declares a remote Elasticsearch cluster + connection. + properties: + apiKey: + description: 'APIKey can be used to enable remote cluster access + using Cross-Cluster API keys: https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-cross-cluster-api-key.html' + properties: + access: + description: Access is the name of the API Key. It is automatically + generated if not set or empty. + properties: + replication: + properties: + names: + items: + type: string + type: array + required: + - names + type: object + search: + properties: + allow_restricted_indices: + type: boolean + field_security: + properties: + except: + items: + type: string + type: array + grant: + items: + type: string + type: array + required: + - except + - grant + type: object + names: + items: + type: string + type: array + query: + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - names + type: object + type: object + required: + - access + type: object + elasticsearchRef: + description: ElasticsearchRef is a reference to an Elasticsearch + cluster running within the same k8s cluster. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, + defaults to the current namespace. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + name: + description: |- + Name is the name of the remote cluster as it is set in the Elasticsearch settings. + The name is expected to be unique for each remote clusters. + minLength: 1 + type: string + required: + - name + type: object + type: array + revisionHistoryLimit: + description: RevisionHistoryLimit is the number of revisions to retain + to allow rollback in the underlying StatefulSets. + format: int32 + type: integer + secureSettings: + description: SecureSettings is a list of references to Kubernetes + secrets containing sensitive configuration options for Elasticsearch. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + serviceAccountName: + description: |- + ServiceAccountName is used to check access from the current resource to a resource (for ex. a remote Elasticsearch cluster) in a different namespace. + Can only be used if ECK is enforcing RBAC on references. + type: string + transport: + description: Transport holds transport layer settings for Elasticsearch. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic is + distributed to Service endpoints. Implementations can use this field as a + hint, but are not required to guarantee strict adherence. If the field is + not set, the implementation will apply its default routing strategy. If set + to "PreferClose", implementations should prioritize endpoints that are + topologically close (e.g., same zone). + This is a beta field and requires enabling ServiceTrafficDistribution feature. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS on the transport + layer. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the CA certificate + and private key for generating node certificates. + The referenced secret should contain the following: + + - `ca.crt`: The CA certificate in PEM format. + - `ca.key`: The private key for the CA certificate in PEM format. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + certificateAuthorities: + description: |- + CertificateAuthorities is a reference to a config map that contains one or more x509 certificates for + trusted authorities in PEM format. The certificates need to be in a file called `ca.crt`. + properties: + configMapName: + type: string + type: object + otherNameSuffix: + description: |- + OtherNameSuffix when defined will be prefixed with the Pod name and used as the common name, + and the first DNSName, as well as an OtherName required by Elasticsearch in the Subject Alternative Name + extension of each Elasticsearch node's transport TLS certificate. + Example: if set to "node.cluster.local", the generated certificate will have its otherName set to ".node.cluster.local". + type: string + selfSignedCertificates: + description: SelfSignedCertificates allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that provisioning of the + self-signed certificates should be disabled. + type: boolean + type: object + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs to + include in the generated node transport TLS certificates. + items: + description: SubjectAlternativeName represents a SAN entry + in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + updateStrategy: + description: UpdateStrategy specifies how updates to the cluster should + be performed. + properties: + changeBudget: + description: ChangeBudget defines the constraints to consider + when applying changes to the Elasticsearch cluster. + properties: + maxSurge: + description: |- + MaxSurge is the maximum number of new Pods that can be created exceeding the original number of Pods defined in + the specification. MaxSurge is only taken into consideration when scaling up. Setting a negative value will + disable the restriction. Defaults to unbounded if not specified. + format: int32 + type: integer + maxUnavailable: + description: |- + MaxUnavailable is the maximum number of Pods that can be unavailable (not ready) during the update due to + circumstances under the control of the operator. Setting a negative value will disable this restriction. + Defaults to 1 if not specified. + format: int32 + type: integer + type: object + type: object + version: + description: Version of Elasticsearch. + type: string + volumeClaimDeletePolicy: + description: |- + VolumeClaimDeletePolicy sets the policy for handling deletion of PersistentVolumeClaims for all NodeSets. + Possible values are DeleteOnScaledownOnly and DeleteOnScaledownAndClusterDeletion. Defaults to DeleteOnScaledownAndClusterDeletion. + enum: + - DeleteOnScaledownOnly + - DeleteOnScaledownAndClusterDeletion + type: string + required: + - nodeSets + - version + type: object + status: + description: ElasticsearchStatus represents the observed state of Elasticsearch. + properties: + availableNodes: + description: AvailableNodes is the number of available instances. + format: int32 + type: integer + conditions: + description: |- + Conditions holds the current service state of an Elasticsearch cluster. + **This API is in technical preview and may be changed or removed in a future release.** + items: + description: |- + Condition represents Elasticsearch resource's condition. + **This API is in technical preview and may be changed or removed in a future release.** + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + status: + type: string + type: + description: ConditionType defines the condition of an Elasticsearch + resource. + type: string + required: + - status + - type + type: object + type: array + health: + description: ElasticsearchHealth is the health of the cluster as returned + by the health API. + type: string + inProgressOperations: + description: |- + InProgressOperations represents changes being applied by the operator to the Elasticsearch cluster. + **This API is in technical preview and may be changed or removed in a future release.** + properties: + downscale: + description: |- + DownscaleOperation provides details about in progress downscale operations. + **This API is in technical preview and may be changed or removed in a future release.** + properties: + lastUpdatedTime: + format: date-time + type: string + nodes: + description: Nodes which are scheduled to be removed from + the cluster. + items: + description: |- + DownscaledNode provides an overview of in progress changes applied by the operator to remove Elasticsearch nodes from the cluster. + **This API is in technical preview and may be changed or removed in a future release.** + properties: + explanation: + description: |- + Explanation provides details about an in progress node shutdown. It is only available for clusters managed with the + Elasticsearch shutdown API. + type: string + name: + description: Name of the Elasticsearch node that should + be removed. + type: string + shutdownStatus: + description: |- + Shutdown status as returned by the Elasticsearch shutdown API. + If the Elasticsearch shutdown API is not available, the shutdown status is then inferred from the remaining + shards on the nodes, as observed by the operator. + type: string + required: + - name + - shutdownStatus + type: object + type: array + stalled: + description: |- + Stalled represents a state where no progress can be made. + It is only available for clusters managed with the Elasticsearch shutdown API. + type: boolean + type: object + upgrade: + description: |- + UpgradeOperation provides an overview of the pending or in progress changes applied by the operator to update the Elasticsearch nodes in the cluster. + **This API is in technical preview and may be changed or removed in a future release.** + properties: + lastUpdatedTime: + format: date-time + type: string + nodes: + description: Nodes that must be restarted for upgrade. + items: + description: |- + UpgradedNode provides details about the status of nodes which are expected to be updated. + **This API is in technical preview and may be changed or removed in a future release.** + properties: + message: + description: Optional message to explain why a node + may not be immediately restarted for upgrade. + type: string + name: + description: Name of the Elasticsearch node that should + be upgraded. + type: string + predicate: + description: Predicate is the name of the predicate + currently preventing this node from being deleted + for an upgrade. + type: string + status: + description: |- + Status states if the node is either in the process of being deleted for an upgrade, + or blocked by a predicate or another condition stated in the message field. + type: string + required: + - name + - status + type: object + type: array + type: object + upscale: + description: |- + UpscaleOperation provides an overview of in progress changes applied by the operator to add Elasticsearch nodes to the cluster. + **This API is in technical preview and may be changed or removed in a future release.** + properties: + lastUpdatedTime: + format: date-time + type: string + nodes: + description: Nodes expected to be added by the operator. + items: + properties: + message: + description: Optional message to explain why a node + may not be immediately added. + type: string + name: + description: Name of the Elasticsearch node that should + be added to the cluster. + type: string + status: + description: NewNodeStatus states if a new node is being + created, or if the upscale is delayed. + type: string + required: + - name + - status + type: object + type: array + type: object + required: + - downscale + - upgrade + - upscale + type: object + monitoringAssociationStatus: + additionalProperties: + description: AssociationStatus is the status of an association resource. + type: string + description: |- + AssociationStatusMap is the map of association's namespaced name string to its AssociationStatus. For resources that + have a single Association of a given type (for ex. single ES reference), this map contains a single entry. + type: object + observedGeneration: + description: |- + ObservedGeneration is the most recent generation observed for this Elasticsearch cluster. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + If the generation observed in status diverges from the generation in metadata, the Elasticsearch + controller has not yet processed the changes contained in the Elasticsearch specification. + format: int64 + type: integer + phase: + description: ElasticsearchOrchestrationPhase is the phase Elasticsearch + is in from the controller point of view. + type: string + version: + description: |- + Version of the stack resource currently running. During version upgrades, multiple versions may run + in parallel: this value specifies the lowest version currently running. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: nodes + type: integer + - description: Elasticsearch version + jsonPath: .spec.version + name: version + type: string + - jsonPath: .status.phase + name: phase + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: Elasticsearch represents an Elasticsearch resource in a Kubernetes + cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ElasticsearchSpec holds the specification of an Elasticsearch + cluster. + properties: + http: + description: HTTP holds HTTP layer settings for Elasticsearch. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic is + distributed to Service endpoints. Implementations can use this field as a + hint, but are not required to guarantee strict adherence. If the field is + not set, the implementation will apply its default routing strategy. If set + to "PreferClose", implementations should prioritize endpoints that are + topologically close (e.g., same zone). + This is a beta field and requires enabling ServiceTrafficDistribution feature. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the Elasticsearch Docker image to deploy. + type: string + nodeSets: + description: NodeSets allow specifying groups of Elasticsearch nodes + sharing the same configuration and Pod templates. + items: + description: NodeSet is the specification for a group of Elasticsearch + nodes sharing the same configuration and a Pod template. + properties: + config: + description: Config holds the Elasticsearch configuration. + type: object + count: + description: Count of Elasticsearch nodes to deploy. + format: int32 + minimum: 1 + type: integer + name: + description: Name of this set of nodes. Becomes a part of the + Elasticsearch node.name setting. + maxLength: 23 + pattern: '[a-zA-Z0-9-]+' + type: string + podTemplate: + description: PodTemplate provides customisation options (labels, + annotations, affinity rules, resource requests, and so on) + for the Pods belonging to this NodeSet. + type: object + volumeClaimTemplates: + description: |- + VolumeClaimTemplates is a list of persistent volume claims to be used by each Pod in this NodeSet. + Every claim in this list must have a matching volumeMount in one of the containers defined in the PodTemplate. + Items defined here take precedence over any default claims added by the operator with the same name. + items: + description: PersistentVolumeClaim is a user's request for + and claim to a persistent volume + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + spec defines the desired characteristics of a volume requested by a pod author. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes + to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to + the PersistentVolume backing this claim. + type: string + type: object + type: object + type: array + required: + - count + - name + type: object + minItems: 1 + type: array + podDisruptionBudget: + description: |- + PodDisruptionBudget provides access to the default pod disruption budget for the Elasticsearch cluster. + The default budget selects all cluster pods and sets `maxUnavailable` to 1. To disable, set `PodDisruptionBudget` + to the empty value (`{}` in YAML). + properties: + metadata: + description: |- + ObjectMeta is the metadata of the PDB. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the PDB. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + An eviction is allowed if at most "maxUnavailable" pods selected by + "selector" are unavailable after the eviction, i.e. even in absence of + the evicted pod. For example, one can prevent all voluntary evictions + by specifying 0. This is a mutually exclusive setting with "minAvailable". + x-kubernetes-int-or-string: true + minAvailable: + anyOf: + - type: integer + - type: string + description: |- + An eviction is allowed if at least "minAvailable" pods selected by + "selector" will still be available after the eviction, i.e. even in the + absence of the evicted pod. So for example you can prevent all voluntary + evictions by specifying "100%". + x-kubernetes-int-or-string: true + selector: + description: |- + Label query over pods whose evictions are managed by the disruption + budget. + A null selector selects no pods. + An empty selector ({}) also selects no pods, which differs from standard behavior of selecting all pods. + In policy/v1, an empty selector will select all pods in the namespace. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + unhealthyPodEvictionPolicy: + description: |- + UnhealthyPodEvictionPolicy defines the criteria for when unhealthy pods + should be considered for eviction. Current implementation considers healthy pods, + as pods that have status.conditions item with type="Ready",status="True". + + Valid policies are IfHealthyBudget and AlwaysAllow. + If no policy is specified, the default behavior will be used, + which corresponds to the IfHealthyBudget policy. + + IfHealthyBudget policy means that running pods (status.phase="Running"), + but not yet healthy can be evicted only if the guarded application is not + disrupted (status.currentHealthy is at least equal to status.desiredHealthy). + Healthy pods will be subject to the PDB for eviction. + + AlwaysAllow policy means that all running pods (status.phase="Running"), + but not yet healthy are considered disrupted and can be evicted regardless + of whether the criteria in a PDB is met. This means perspective running + pods of a disrupted application might not get a chance to become healthy. + Healthy pods will be subject to the PDB for eviction. + + Additional policies may be added in the future. + Clients making eviction decisions should disallow eviction of unhealthy pods + if they encounter an unrecognized policy in this field. + + This field is beta-level. The eviction API uses this field when + the feature gate PDBUnhealthyPodEvictionPolicy is enabled (enabled by default). + type: string + type: object + type: object + secureSettings: + description: SecureSettings is a list of references to Kubernetes + secrets containing sensitive configuration options for Elasticsearch. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + updateStrategy: + description: UpdateStrategy specifies how updates to the cluster should + be performed. + properties: + changeBudget: + description: ChangeBudget defines the constraints to consider + when applying changes to the Elasticsearch cluster. + properties: + maxSurge: + description: |- + MaxSurge is the maximum number of new pods that can be created exceeding the original number of pods defined in + the specification. MaxSurge is only taken into consideration when scaling up. Setting a negative value will + disable the restriction. Defaults to unbounded if not specified. + format: int32 + type: integer + maxUnavailable: + description: |- + MaxUnavailable is the maximum number of pods that can be unavailable (not ready) during the update due to + circumstances under the control of the operator. Setting a negative value will disable this restriction. + Defaults to 1 if not specified. + format: int32 + type: integer + type: object + type: object + version: + description: Version of Elasticsearch. + type: string + required: + - nodeSets + type: object + status: + description: ElasticsearchStatus defines the observed state of Elasticsearch + properties: + availableNodes: + format: int32 + type: integer + health: + description: ElasticsearchHealth is the health of the cluster as returned + by the health API. + type: string + phase: + description: ElasticsearchOrchestrationPhase is the phase Elasticsearch + is in from the controller point of view. + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} + - name: v1alpha1 + schema: + openAPIV3Schema: + description: to not break compatibility when upgrading from previous versions + of the CRD + type: object + served: false + storage: false +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.2 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: enterprisesearches.enterprisesearch.k8s.elastic.co +spec: + group: enterprisesearch.k8s.elastic.co + names: + categories: + - elastic + kind: EnterpriseSearch + listKind: EnterpriseSearchList + plural: enterprisesearches + shortNames: + - ent + singular: enterprisesearch + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: nodes + type: integer + - description: Enterprise Search version + jsonPath: .status.version + name: version + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1 + schema: + openAPIV3Schema: + description: EnterpriseSearch is a Kubernetes CRD to represent Enterprise + Search. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: EnterpriseSearchSpec holds the specification of an Enterprise + Search resource. + properties: + config: + description: Config holds the Enterprise Search configuration. + type: object + x-kubernetes-preserve-unknown-fields: true + configRef: + description: |- + ConfigRef contains a reference to an existing Kubernetes Secret holding the Enterprise Search configuration. + Configuration settings are merged and have precedence over settings specified in `config`. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + count: + description: Count of Enterprise Search instances to deploy. + format: int32 + type: integer + elasticsearchRef: + description: ElasticsearchRef is a reference to the Elasticsearch + cluster running in the same Kubernetes cluster. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + http: + description: HTTP holds the HTTP layer configuration for Enterprise + Search resource. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic is + distributed to Service endpoints. Implementations can use this field as a + hint, but are not required to guarantee strict adherence. If the field is + not set, the implementation will apply its default routing strategy. If set + to "PreferClose", implementations should prioritize endpoints that are + topologically close (e.g., same zone). + This is a beta field and requires enabling ServiceTrafficDistribution feature. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the Enterprise Search Docker image to deploy. + type: string + podTemplate: + description: |- + PodTemplate provides customisation options (labels, annotations, affinity rules, resource requests, and so on) + for the Enterprise Search pods. + type: object + x-kubernetes-preserve-unknown-fields: true + revisionHistoryLimit: + description: RevisionHistoryLimit is the number of revisions to retain + to allow rollback in the underlying Deployment. + format: int32 + type: integer + serviceAccountName: + description: |- + ServiceAccountName is used to check access from the current resource to a resource (for ex. Elasticsearch) in a different namespace. + Can only be used if ECK is enforcing RBAC on references. + type: string + version: + description: Version of Enterprise Search. + type: string + type: object + status: + description: EnterpriseSearchStatus defines the observed state of EnterpriseSearch + properties: + associationStatus: + description: Association is the status of any auto-linking to Elasticsearch + clusters. + type: string + availableNodes: + description: AvailableNodes is the number of available replicas in + the deployment. + format: int32 + type: integer + count: + description: Count corresponds to Scale.Status.Replicas, which is + the actual number of observed instances of the scaled object. + format: int32 + type: integer + health: + description: Health of the deployment. + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the status is based upon. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + If the generation observed in status diverges from the generation in metadata, the Enterprise Search + controller has not yet processed the changes contained in the Enterprise Search specification. + format: int64 + type: integer + selector: + description: Selector is the label selector used to find all pods. + type: string + service: + description: ExternalService is the name of the service associated + to the Enterprise Search Pods. + type: string + version: + description: |- + Version of the stack resource currently running. During version upgrades, multiple versions may run + in parallel: this value specifies the lowest version currently running. + type: string + type: object + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.count + statusReplicasPath: .status.count + status: {} + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: nodes + type: integer + - description: Enterprise Search version + jsonPath: .status.version + name: version + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: EnterpriseSearch is a Kubernetes CRD to represent Enterprise + Search. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: EnterpriseSearchSpec holds the specification of an Enterprise + Search resource. + properties: + config: + description: Config holds the Enterprise Search configuration. + type: object + x-kubernetes-preserve-unknown-fields: true + configRef: + description: |- + ConfigRef contains a reference to an existing Kubernetes Secret holding the Enterprise Search configuration. + Configuration settings are merged and have precedence over settings specified in `config`. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + count: + description: Count of Enterprise Search instances to deploy. + format: int32 + type: integer + elasticsearchRef: + description: ElasticsearchRef is a reference to the Elasticsearch + cluster running in the same Kubernetes cluster. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + http: + description: HTTP holds the HTTP layer configuration for Enterprise + Search resource. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic is + distributed to Service endpoints. Implementations can use this field as a + hint, but are not required to guarantee strict adherence. If the field is + not set, the implementation will apply its default routing strategy. If set + to "PreferClose", implementations should prioritize endpoints that are + topologically close (e.g., same zone). + This is a beta field and requires enabling ServiceTrafficDistribution feature. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the Enterprise Search Docker image to deploy. + type: string + podTemplate: + description: |- + PodTemplate provides customisation options (labels, annotations, affinity rules, resource requests, and so on) + for the Enterprise Search pods. + type: object + x-kubernetes-preserve-unknown-fields: true + serviceAccountName: + description: |- + ServiceAccountName is used to check access from the current resource to a resource (for ex. Elasticsearch) in a different namespace. + Can only be used if ECK is enforcing RBAC on references. + type: string + version: + description: Version of Enterprise Search. + type: string + type: object + status: + description: EnterpriseSearchStatus defines the observed state of EnterpriseSearch + properties: + associationStatus: + description: Association is the status of any auto-linking to Elasticsearch + clusters. + type: string + availableNodes: + description: AvailableNodes is the number of available replicas in + the deployment. + format: int32 + type: integer + count: + description: Count corresponds to Scale.Status.Replicas, which is + the actual number of observed instances of the scaled object. + format: int32 + type: integer + health: + description: Health of the deployment. + type: string + selector: + description: Selector is the label selector used to find all pods. + type: string + service: + description: ExternalService is the name of the service associated + to the Enterprise Search Pods. + type: string + version: + description: |- + Version of the stack resource currently running. During version upgrades, multiple versions may run + in parallel: this value specifies the lowest version currently running. + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.2 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: kibanas.kibana.k8s.elastic.co +spec: + group: kibana.k8s.elastic.co + names: + categories: + - elastic + kind: Kibana + listKind: KibanaList + plural: kibanas + shortNames: + - kb + singular: kibana + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: nodes + type: integer + - description: Kibana version + jsonPath: .status.version + name: version + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1 + schema: + openAPIV3Schema: + description: Kibana represents a Kibana resource in a Kubernetes cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: KibanaSpec holds the specification of a Kibana instance. + properties: + config: + description: 'Config holds the Kibana configuration. See: https://www.elastic.co/guide/en/kibana/current/settings.html' + type: object + x-kubernetes-preserve-unknown-fields: true + count: + description: Count of Kibana instances to deploy. + format: int32 + type: integer + elasticsearchRef: + description: ElasticsearchRef is a reference to an Elasticsearch cluster + running in the same Kubernetes cluster. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + enterpriseSearchRef: + description: |- + EnterpriseSearchRef is a reference to an EnterpriseSearch running in the same Kubernetes cluster. + Kibana provides the default Enterprise Search UI starting version 7.14. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + http: + description: HTTP holds the HTTP layer configuration for Kibana. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic is + distributed to Service endpoints. Implementations can use this field as a + hint, but are not required to guarantee strict adherence. If the field is + not set, the implementation will apply its default routing strategy. If set + to "PreferClose", implementations should prioritize endpoints that are + topologically close (e.g., same zone). + This is a beta field and requires enabling ServiceTrafficDistribution feature. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the Kibana Docker image to deploy. + type: string + monitoring: + description: |- + Monitoring enables you to collect and ship log and monitoring data of this Kibana. + See https://www.elastic.co/guide/en/kibana/current/xpack-monitoring.html. + Metricbeat and Filebeat are deployed in the same Pod as sidecars and each one sends data to one or two different + Elasticsearch monitoring clusters running in the same Kubernetes cluster. + properties: + logs: + description: Logs holds references to Elasticsearch clusters which + receive log data from an associated resource. + properties: + elasticsearchRefs: + description: |- + ElasticsearchRefs is a reference to a list of monitoring Elasticsearch clusters running in the same Kubernetes cluster. + Due to existing limitations, only a single Elasticsearch cluster is currently supported. + items: + description: |- + ObjectSelector defines a reference to a Kubernetes object which can be an Elastic resource managed by the operator + or a Secret describing an external Elastic resource not managed by the operator. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If + empty, defaults to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + type: array + type: object + metrics: + description: Metrics holds references to Elasticsearch clusters + which receive monitoring data from this resource. + properties: + elasticsearchRefs: + description: |- + ElasticsearchRefs is a reference to a list of monitoring Elasticsearch clusters running in the same Kubernetes cluster. + Due to existing limitations, only a single Elasticsearch cluster is currently supported. + items: + description: |- + ObjectSelector defines a reference to a Kubernetes object which can be an Elastic resource managed by the operator + or a Secret describing an external Elastic resource not managed by the operator. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If + empty, defaults to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + type: array + type: object + type: object + podTemplate: + description: PodTemplate provides customisation options (labels, annotations, + affinity rules, resource requests, and so on) for the Kibana pods + type: object + x-kubernetes-preserve-unknown-fields: true + revisionHistoryLimit: + description: RevisionHistoryLimit is the number of revisions to retain + to allow rollback in the underlying Deployment. + format: int32 + type: integer + secureSettings: + description: SecureSettings is a list of references to Kubernetes + secrets containing sensitive configuration options for Kibana. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + serviceAccountName: + description: |- + ServiceAccountName is used to check access from the current resource to a resource (for ex. Elasticsearch) in a different namespace. + Can only be used if ECK is enforcing RBAC on references. + type: string + version: + description: Version of Kibana. + type: string + required: + - version + type: object + status: + description: KibanaStatus defines the observed state of Kibana + properties: + associationStatus: + description: |- + AssociationStatus is the status of any auto-linking to Elasticsearch clusters. + This field is deprecated and will be removed in a future release. Use ElasticsearchAssociationStatus instead. + type: string + availableNodes: + description: AvailableNodes is the number of available replicas in + the deployment. + format: int32 + type: integer + count: + description: Count corresponds to Scale.Status.Replicas, which is + the actual number of observed instances of the scaled object. + format: int32 + type: integer + elasticsearchAssociationStatus: + description: ElasticsearchAssociationStatus is the status of any auto-linking + to Elasticsearch clusters. + type: string + enterpriseSearchAssociationStatus: + description: EnterpriseSearchAssociationStatus is the status of any + auto-linking to Enterprise Search. + type: string + health: + description: Health of the deployment. + type: string + monitoringAssociationStatus: + additionalProperties: + description: AssociationStatus is the status of an association resource. + type: string + description: MonitoringAssociationStatus is the status of any auto-linking + to monitoring Elasticsearch clusters. + type: object + observedGeneration: + description: |- + ObservedGeneration is the most recent generation observed for this Kibana instance. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + If the generation observed in status diverges from the generation in metadata, the Kibana + controller has not yet processed the changes contained in the Kibana specification. + format: int64 + type: integer + selector: + description: Selector is the label selector used to find all pods. + type: string + version: + description: |- + Version of the stack resource currently running. During version upgrades, multiple versions may run + in parallel: this value specifies the lowest version currently running. + type: string + type: object + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.count + statusReplicasPath: .status.count + status: {} + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: nodes + type: integer + - description: Kibana version + jsonPath: .spec.version + name: version + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: Kibana represents a Kibana resource in a Kubernetes cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: KibanaSpec holds the specification of a Kibana instance. + properties: + config: + description: 'Config holds the Kibana configuration. See: https://www.elastic.co/guide/en/kibana/current/settings.html' + type: object + x-kubernetes-preserve-unknown-fields: true + count: + description: Count of Kibana instances to deploy. + format: int32 + type: integer + elasticsearchRef: + description: ElasticsearchRef is a reference to an Elasticsearch cluster + running in the same Kubernetes cluster. + properties: + name: + description: Name of the Kubernetes object. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + required: + - name + type: object + http: + description: HTTP holds the HTTP layer configuration for Kibana. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic is + distributed to Service endpoints. Implementations can use this field as a + hint, but are not required to guarantee strict adherence. If the field is + not set, the implementation will apply its default routing strategy. If set + to "PreferClose", implementations should prioritize endpoints that are + topologically close (e.g., same zone). + This is a beta field and requires enabling ServiceTrafficDistribution feature. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the Kibana Docker image to deploy. + type: string + podTemplate: + description: PodTemplate provides customisation options (labels, annotations, + affinity rules, resource requests, and so on) for the Kibana pods + type: object + x-kubernetes-preserve-unknown-fields: true + secureSettings: + description: SecureSettings is a list of references to Kubernetes + secrets containing sensitive configuration options for Kibana. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + version: + description: Version of Kibana. + type: string + type: object + status: + description: KibanaStatus defines the observed state of Kibana + properties: + associationStatus: + description: AssociationStatus is the status of an association resource. + type: string + availableNodes: + format: int32 + type: integer + health: + description: KibanaHealth expresses the status of the Kibana instances. + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} + - name: v1alpha1 + schema: + openAPIV3Schema: + description: to not break compatibility when upgrading from previous versions + of the CRD + type: object + served: false + storage: false +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.2 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: logstashes.logstash.k8s.elastic.co +spec: + group: logstash.k8s.elastic.co + names: + categories: + - elastic + kind: Logstash + listKind: LogstashList + plural: logstashes + shortNames: + - ls + singular: logstash + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Health + jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: available + type: integer + - description: Expected nodes + jsonPath: .status.expectedNodes + name: expected + type: integer + - jsonPath: .metadata.creationTimestamp + name: age + type: date + - description: Logstash version + jsonPath: .status.version + name: version + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: Logstash is the Schema for the logstashes API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: LogstashSpec defines the desired state of Logstash + properties: + config: + description: Config holds the Logstash configuration. At most one + of [`Config`, `ConfigRef`] can be specified. + type: object + x-kubernetes-preserve-unknown-fields: true + configRef: + description: |- + ConfigRef contains a reference to an existing Kubernetes Secret holding the Logstash configuration. + Logstash settings must be specified as yaml, under a single "logstash.yml" entry. At most one of [`Config`, `ConfigRef`] + can be specified. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + count: + format: int32 + type: integer + elasticsearchRefs: + description: ElasticsearchRefs are references to Elasticsearch clusters + running in the same Kubernetes cluster. + items: + description: ElasticsearchCluster is a named reference to an Elasticsearch + cluster which can be used in a Logstash pipeline. + properties: + clusterName: + description: |- + ClusterName is an alias for the cluster to be used to refer to the Elasticsearch cluster in Logstash + configuration files, and will be used to identify "named clusters" in Logstash + minLength: 1 + type: string + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + required: + - clusterName + type: object + type: array + image: + description: Image is the Logstash Docker image to deploy. Version + and Type have to match the Logstash in the image. + type: string + monitoring: + description: |- + Monitoring enables you to collect and ship log and monitoring data of this Logstash. + Metricbeat and Filebeat are deployed in the same Pod as sidecars and each one sends data to one or two different + Elasticsearch monitoring clusters running in the same Kubernetes cluster. + properties: + logs: + description: Logs holds references to Elasticsearch clusters which + receive log data from an associated resource. + properties: + elasticsearchRefs: + description: |- + ElasticsearchRefs is a reference to a list of monitoring Elasticsearch clusters running in the same Kubernetes cluster. + Due to existing limitations, only a single Elasticsearch cluster is currently supported. + items: + description: |- + ObjectSelector defines a reference to a Kubernetes object which can be an Elastic resource managed by the operator + or a Secret describing an external Elastic resource not managed by the operator. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If + empty, defaults to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + type: array + type: object + metrics: + description: Metrics holds references to Elasticsearch clusters + which receive monitoring data from this resource. + properties: + elasticsearchRefs: + description: |- + ElasticsearchRefs is a reference to a list of monitoring Elasticsearch clusters running in the same Kubernetes cluster. + Due to existing limitations, only a single Elasticsearch cluster is currently supported. + items: + description: |- + ObjectSelector defines a reference to a Kubernetes object which can be an Elastic resource managed by the operator + or a Secret describing an external Elastic resource not managed by the operator. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If + empty, defaults to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + type: array + type: object + type: object + pipelines: + description: Pipelines holds the Logstash Pipelines. At most one of + [`Pipelines`, `PipelinesRef`] can be specified. + items: + type: object + type: array + x-kubernetes-preserve-unknown-fields: true + pipelinesRef: + description: |- + PipelinesRef contains a reference to an existing Kubernetes Secret holding the Logstash Pipelines. + Logstash pipelines must be specified as yaml, under a single "pipelines.yml" entry. At most one of [`Pipelines`, `PipelinesRef`] + can be specified. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + podTemplate: + description: PodTemplate provides customisation options for the Logstash + pods. + type: object + x-kubernetes-preserve-unknown-fields: true + revisionHistoryLimit: + description: RevisionHistoryLimit is the number of revisions to retain + to allow rollback in the underlying StatefulSet. + format: int32 + type: integer + secureSettings: + description: |- + SecureSettings is a list of references to Kubernetes Secrets containing sensitive configuration options for the Logstash. + Secrets data can be then referenced in the Logstash config using the Secret's keys or as specified in `Entries` field of + each SecureSetting. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + serviceAccountName: + description: |- + ServiceAccountName is used to check access from the current resource to Elasticsearch resource in a different namespace. + Can only be used if ECK is enforcing RBAC on references. + type: string + services: + description: |- + Services contains details of services that Logstash should expose - similar to the HTTP layer configuration for the + rest of the stack, but also applicable for more use cases than the metrics API, as logstash may need to + be opened up for other services: Beats, TCP, UDP, etc, inputs. + items: + properties: + name: + type: string + service: + description: Service defines the template for the associated + Kubernetes Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by + this service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic is + distributed to Service endpoints. Implementations can use this field as a + hint, but are not required to guarantee strict adherence. If the field is + not set, the implementation will apply its default routing strategy. If set + to "PreferClose", implementations should prioritize endpoints that are + topologically close (e.g., same zone). + This is a beta field and requires enabling ServiceTrafficDistribution feature. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + type: array + updateStrategy: + description: UpdateStrategy is a StatefulSetUpdateStrategy. The default + type is "RollingUpdate". + properties: + rollingUpdate: + description: RollingUpdate is used to communicate parameters when + Type is RollingUpdateStatefulSetStrategyType. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding up. This can not be 0. + Defaults to 1. This field is alpha-level and is only honored by servers that enable the + MaxUnavailableStatefulSet feature. The field applies to all pods in the range 0 to + Replicas-1. That means if there is any unavailable pod in the range 0 to Replicas-1, it + will be counted towards MaxUnavailable. + x-kubernetes-int-or-string: true + partition: + description: |- + Partition indicates the ordinal at which the StatefulSet should be partitioned + for updates. During a rolling update, all pods from ordinal Replicas-1 to + Partition are updated. All pods from ordinal Partition-1 to 0 remain untouched. + This is helpful in being able to do a canary based deployment. The default value is 0. + format: int32 + type: integer + type: object + type: + description: |- + Type indicates the type of the StatefulSetUpdateStrategy. + Default is RollingUpdate. + type: string + type: object + version: + description: Version of the Logstash. + type: string + volumeClaimTemplates: + description: |- + VolumeClaimTemplates is a list of persistent volume claims to be used by each Pod. + Every claim in this list must have a matching volumeMount in one of the containers defined in the PodTemplate. + Items defined here take precedence over any default claims added by the operator with the same name. + items: + description: PersistentVolumeClaim is a user's request for and claim + to a persistent volume + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + spec defines the desired characteristics of a volume requested by a pod author. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes to consider + for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the + PersistentVolume backing this claim. + type: string + type: object + status: + description: |- + status represents the current information/status of a persistent volume claim. + Read-only. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the actual access modes the volume backing the PVC has. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + allocatedResourceStatuses: + additionalProperties: + description: |- + When a controller receives persistentvolume claim update with ClaimResourceStatus for a resource + that it does not recognizes, then it should ignore that update and let other controllers + handle it. + type: string + description: "allocatedResourceStatuses stores status of + resource being resized for the given PVC.\nKey names follow + standard Kubernetes label syntax. Valid values are either:\n\t* + Un-prefixed keys:\n\t\t- storage - the capacity of the + volume.\n\t* Custom resources must use implementation-defined + prefixed names such as \"example.com/my-custom-resource\"\nApart + from above values - keys that are unprefixed or have kubernetes.io + prefix are considered\nreserved and hence may not be used.\n\nClaimResourceStatus + can be in any of following states:\n\t- ControllerResizeInProgress:\n\t\tState + set when resize controller starts resizing the volume + in control-plane.\n\t- ControllerResizeFailed:\n\t\tState + set when resize has failed in resize controller with a + terminal error.\n\t- NodeResizePending:\n\t\tState set + when resize controller has finished resizing the volume + but further resizing of\n\t\tvolume is needed on the node.\n\t- + NodeResizeInProgress:\n\t\tState set when kubelet starts + resizing the volume.\n\t- NodeResizeFailed:\n\t\tState + set when resizing has failed in kubelet with a terminal + error. Transient errors don't set\n\t\tNodeResizeFailed.\nFor + example: if expanding a PVC for more capacity - this field + can be one of the following states:\n\t- pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeFailed\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizePending\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeFailed\"\nWhen this field is not set, it + means that no resize operation is in progress for the + given PVC.\n\nA controller that receives PVC update with + previously unknown resourceName or ClaimResourceStatus\nshould + ignore the update for the purpose it was designed. For + example - a controller that\nonly is responsible for resizing + capacity of the volume, should ignore PVC updates that + change other valid\nresources associated with PVC.\n\nThis + is an alpha field and requires enabling RecoverVolumeExpansionFailure + feature." + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: "allocatedResources tracks the resources allocated + to a PVC including its capacity.\nKey names follow standard + Kubernetes label syntax. Valid values are either:\n\t* + Un-prefixed keys:\n\t\t- storage - the capacity of the + volume.\n\t* Custom resources must use implementation-defined + prefixed names such as \"example.com/my-custom-resource\"\nApart + from above values - keys that are unprefixed or have kubernetes.io + prefix are considered\nreserved and hence may not be used.\n\nCapacity + reported here may be larger than the actual capacity when + a volume expansion operation\nis requested.\nFor storage + quota, the larger value from allocatedResources and PVC.spec.resources + is used.\nIf allocatedResources is not set, PVC.spec.resources + alone is used for quota calculation.\nIf a volume expansion + capacity request is lowered, allocatedResources is only\nlowered + if there are no expansion operations in progress and if + the actual volume capacity\nis equal or lower than the + requested capacity.\n\nA controller that receives PVC + update with previously unknown resourceName\nshould ignore + the update for the purpose it was designed. For example + - a controller that\nonly is responsible for resizing + capacity of the volume, should ignore PVC updates that + change other valid\nresources associated with PVC.\n\nThis + is an alpha field and requires enabling RecoverVolumeExpansionFailure + feature." + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: capacity represents the actual resources of + the underlying volume. + type: object + conditions: + description: |- + conditions is the current Condition of persistent volume claim. If underlying persistent volume is being + resized then the Condition will be set to 'Resizing'. + items: + description: PersistentVolumeClaimCondition contains details + about state of pvc + properties: + lastProbeTime: + description: lastProbeTime is the time we probed the + condition. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime is the time the condition + transitioned from one status to another. + format: date-time + type: string + message: + description: message is the human-readable message + indicating details about last transition. + type: string + reason: + description: |- + reason is a unique, this should be a short, machine understandable string that gives the reason + for condition's last transition. If it reports "Resizing" that means the underlying + persistent volume is being resized. + type: string + status: + description: |- + Status is the status of the condition. + Can be True, False, Unknown. + More info: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#:~:text=state%20of%20pvc-,conditions.status,-(string)%2C%20required + type: string + type: + description: |- + Type is the type of the condition. + More info: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#:~:text=set%20to%20%27ResizeStarted%27.-,PersistentVolumeClaimCondition,-contains%20details%20about + type: string + required: + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentVolumeAttributesClassName: + description: |- + currentVolumeAttributesClassName is the current name of the VolumeAttributesClass the PVC is using. + When unset, there is no VolumeAttributeClass applied to this PersistentVolumeClaim + This is a beta field and requires enabling VolumeAttributesClass feature (off by default). + type: string + modifyVolumeStatus: + description: |- + ModifyVolumeStatus represents the status object of ControllerModifyVolume operation. + When this is unset, there is no ModifyVolume operation being attempted. + This is a beta field and requires enabling VolumeAttributesClass feature (off by default). + properties: + status: + description: "status is the status of the ControllerModifyVolume + operation. It can be in any of following states:\n + - Pending\n Pending indicates that the PersistentVolumeClaim + cannot be modified due to unmet requirements, such + as\n the specified VolumeAttributesClass not existing.\n + - InProgress\n InProgress indicates that the volume + is being modified.\n - Infeasible\n Infeasible indicates + that the request has been rejected as invalid by the + CSI driver. To\n\t resolve the error, a valid VolumeAttributesClass + needs to be specified.\nNote: New statuses can be + added in the future. Consumers should check for unknown + statuses and fail appropriately." + type: string + targetVolumeAttributesClassName: + description: targetVolumeAttributesClassName is the + name of the VolumeAttributesClass the PVC currently + being reconciled + type: string + required: + - status + type: object + phase: + description: phase represents the current phase of PersistentVolumeClaim. + type: string + type: object + type: object + type: array + required: + - version + type: object + status: + description: LogstashStatus defines the observed state of Logstash + properties: + availableNodes: + format: int32 + type: integer + elasticsearchAssociationsStatus: + additionalProperties: + description: AssociationStatus is the status of an association resource. + type: string + description: ElasticsearchAssociationStatus is the status of any auto-linking + to Elasticsearch clusters. + type: object + expectedNodes: + format: int32 + type: integer + health: + type: string + monitoringAssociationStatus: + additionalProperties: + description: AssociationStatus is the status of an association resource. + type: string + description: MonitoringAssociationStatus is the status of any auto-linking + to monitoring Elasticsearch clusters. + type: object + observedGeneration: + description: |- + ObservedGeneration is the most recent generation observed for this Logstash instance. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + If the generation observed in status diverges from the generation in metadata, the Logstash + controller has not yet processed the changes contained in the Logstash specification. + format: int64 + type: integer + selector: + type: string + version: + description: |- + Version of the stack resource currently running. During version upgrades, multiple versions may run + in parallel: this value specifies the lowest version currently running. + type: string + required: + - selector + type: object + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.count + statusReplicasPath: .status.expectedNodes + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.2 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: stackconfigpolicies.stackconfigpolicy.k8s.elastic.co +spec: + group: stackconfigpolicy.k8s.elastic.co + names: + categories: + - elastic + kind: StackConfigPolicy + listKind: StackConfigPolicyList + plural: stackconfigpolicies + shortNames: + - scp + singular: stackconfigpolicy + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Resources configured + jsonPath: .status.readyCount + name: Ready + type: string + - jsonPath: .status.phase + name: Phase + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: StackConfigPolicy represents a StackConfigPolicy resource in + a Kubernetes cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + properties: + elasticsearch: + properties: + clusterSettings: + description: ClusterSettings holds the Elasticsearch cluster settings + (/_cluster/settings) + type: object + x-kubernetes-preserve-unknown-fields: true + config: + description: Config holds the settings that go into elasticsearch.yml. + type: object + x-kubernetes-preserve-unknown-fields: true + indexLifecyclePolicies: + description: IndexLifecyclePolicies holds the Index Lifecycle + policies settings (/_ilm/policy) + type: object + x-kubernetes-preserve-unknown-fields: true + indexTemplates: + description: IndexTemplates holds the Index and Component Templates + settings + properties: + componentTemplates: + description: ComponentTemplates holds the Component Templates + settings (/_component_template) + type: object + x-kubernetes-preserve-unknown-fields: true + composableIndexTemplates: + description: ComposableIndexTemplates holds the Index Templates + settings (/_index_template) + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + x-kubernetes-preserve-unknown-fields: true + ingestPipelines: + description: IngestPipelines holds the Ingest Pipelines settings + (/_ingest/pipeline) + type: object + x-kubernetes-preserve-unknown-fields: true + secretMounts: + description: SecretMounts are additional Secrets that need to + be mounted into the Elasticsearch pods. + items: + description: SecretMount contains information about additional + secrets to be mounted to the elasticsearch pods + properties: + mountPath: + description: MountPath denotes the path to which the secret + should be mounted to inside the elasticsearch pod + type: string + secretName: + description: SecretName denotes the name of the secret that + needs to be mounted to the elasticsearch pod + type: string + type: object + type: array + x-kubernetes-preserve-unknown-fields: true + secureSettings: + description: SecureSettings are additional Secrets that contain + data to be configured to Elasticsearch's keystore. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + x-kubernetes-preserve-unknown-fields: true + securityRoleMappings: + description: SecurityRoleMappings holds the Role Mappings settings + (/_security/role_mapping) + type: object + x-kubernetes-preserve-unknown-fields: true + snapshotLifecyclePolicies: + description: SnapshotLifecyclePolicies holds the Snapshot Lifecycle + Policies settings (/_slm/policy) + type: object + x-kubernetes-preserve-unknown-fields: true + snapshotRepositories: + description: SnapshotRepositories holds the Snapshot Repositories + settings (/_snapshot) + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + kibana: + properties: + config: + description: Config holds the settings that go into kibana.yml. + type: object + x-kubernetes-preserve-unknown-fields: true + secureSettings: + description: SecureSettings are additional Secrets that contain + data to be configured to Kibana's keystore. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + x-kubernetes-preserve-unknown-fields: true + type: object + resourceSelector: + description: |- + A label selector is a label query over a set of resources. The result of matchLabels and + matchExpressions are ANDed. An empty label selector matches all objects. A null + label selector matches no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + secureSettings: + description: 'Deprecated: SecureSettings only applies to Elasticsearch + and is deprecated. It must be set per application instead.' + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + type: object + status: + properties: + details: + additionalProperties: + additionalProperties: + description: ResourcePolicyStatus models the status of the policy + for one resource to be configured. + properties: + currentVersion: + description: |- + CurrentVersion denotes the current version of filesettings applied to the Elasticsearch cluster + This field does not apply to Kibana resources + format: int64 + type: integer + error: + properties: + message: + type: string + version: + format: int64 + type: integer + type: object + expectedVersion: + description: |- + ExpectedVersion denotes the expected version of filesettings that should be applied to the Elasticsearch cluster + This field does not apply to Kibana resources + format: int64 + type: integer + phase: + type: string + type: object + type: object + description: Details holds the status details for each resource to + be configured. + type: object + errors: + description: Errors is the number of resources which have an incorrect + configuration + type: integer + observedGeneration: + description: ObservedGeneration is the most recent generation observed + for this StackConfigPolicy. + format: int64 + type: integer + phase: + description: Phase is the phase of the StackConfigPolicy. + type: string + ready: + description: Ready is the number of resources successfully configured. + type: integer + readyCount: + description: ReadyCount is a human representation of the number of + resources successfully configured. + type: string + resources: + description: Resources is the number of resources to be configured. + type: integer + resourcesStatuses: + additionalProperties: + description: ResourcePolicyStatus models the status of the policy + for one resource to be configured. + properties: + currentVersion: + description: |- + CurrentVersion denotes the current version of filesettings applied to the Elasticsearch cluster + This field does not apply to Kibana resources + format: int64 + type: integer + error: + properties: + message: + type: string + version: + format: int64 + type: integer + type: object + expectedVersion: + description: |- + ExpectedVersion denotes the expected version of filesettings that should be applied to the Elasticsearch cluster + This field does not apply to Kibana resources + format: int64 + type: integer + phase: + type: string + type: object + description: |- + ResourcesStatuses holds the status for each resource to be configured. + Deprecated: Details is used to store the status of resources from ECK 2.11 + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/values.yaml b/packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/values.yaml new file mode 100644 index 00000000..f3fd8bd5 --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/charts/eck-operator-crds/values.yaml @@ -0,0 +1,7 @@ +# Globals meant for internal use only +global: + # manifestGen specifies whether the chart is running under manifest generator. + # This is used for tasks specific to generating the all-in-one.yaml file. + manifestGen: false + # kubeVersion is the effective Kubernetes version we target when generating the all-in-one.yaml. + kubeVersion: 1.21.0 diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/profile-disable-automounting-api.yaml b/packs/elastic-operator-3.0.0/charts/eck-operator/profile-disable-automounting-api.yaml new file mode 100644 index 00000000..50f97157 --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/profile-disable-automounting-api.yaml @@ -0,0 +1,29 @@ +automountServiceAccountToken: false + +serviceAccount: + automountServiceAccountToken: false + +volumeMounts: +- mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: serviceaccount-token + readOnly: true + +volumes: +- name: serviceaccount-token + projected: + defaultMode: 0444 + sources: + - serviceAccountToken: + expirationSeconds: 3607 + path: token + - configMap: + name: kube-root-ca.crt + items: + - key: ca.crt + path: ca.crt + - downwardAPI: + items: + - path: namespace + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/profile-global.yaml b/packs/elastic-operator-3.0.0/charts/eck-operator/profile-global.yaml new file mode 100644 index 00000000..286f8c9e --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/profile-global.yaml @@ -0,0 +1,6 @@ +managedNamespaces: [] + +createClusterScopedResources: true + +webhook: + enabled: true diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/profile-istio.yaml b/packs/elastic-operator-3.0.0/charts/eck-operator/profile-istio.yaml new file mode 100644 index 00000000..c968ba02 --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/profile-istio.yaml @@ -0,0 +1,11 @@ +managedNamespaces: [] + +createClusterScopedResources: true + +webhook: + enabled: true + +podAnnotations: + sidecar.istio.io/inject: "true" + traffic.sidecar.istio.io/includeInboundPorts: "*" + traffic.sidecar.istio.io/excludeInboundPorts: "9443" diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/profile-restricted.yaml b/packs/elastic-operator-3.0.0/charts/eck-operator/profile-restricted.yaml new file mode 100644 index 00000000..640d00f3 --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/profile-restricted.yaml @@ -0,0 +1,12 @@ +managedNamespaces: ["elastic-system"] + +createClusterScopedResources: false + +config: + # no RBAC access to cluster-wide storage classes, hence disable storage class validation + validateStorageClass: false + +installCRDs: false + +webhook: + enabled: false diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/profile-soft-multi-tenancy.yaml b/packs/elastic-operator-3.0.0/charts/eck-operator/profile-soft-multi-tenancy.yaml new file mode 100644 index 00000000..8ac79514 --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/profile-soft-multi-tenancy.yaml @@ -0,0 +1,18 @@ +managedNamespaces: ["team-a", "team-b"] + +createClusterScopedResources: true + +refs: + enforceRBAC: true + +webhook: + enabled: true + namespaceSelector: + matchExpressions: + - key: "eck.k8s.elastic.co/tenant" + operator: In + values: ["team-a", "team-b"] + + +softMultiTenancy: + enabled: true diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/templates/NOTES.txt b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/NOTES.txt new file mode 100644 index 00000000..e25ea9ea --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/NOTES.txt @@ -0,0 +1,2 @@ +1. Inspect the operator logs by running the following command: + kubectl logs -n {{ .Release.Namespace }} sts/{{ .Release.Name }} diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/templates/_helpers.tpl b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/_helpers.tpl new file mode 100644 index 00000000..dc2f7cb3 --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/_helpers.tpl @@ -0,0 +1,381 @@ +{{/* +Expand the name of the chart. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "eck-operator.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "eck-operator.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "eck-operator.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "eck-operator.labels" -}} +{{- include "eck-operator.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +helm.sh/chart: {{ include "eck-operator.chart" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "eck-operator.selectorLabels" -}} +{{- if .Values.global.manifestGen -}} +control-plane: elastic-operator +{{- else -}} +app.kubernetes.io/name: {{ include "eck-operator.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "eck-operator.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "eck-operator.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Determine effective Kubernetes version +*/}} +{{- define "eck-operator.effectiveKubeVersion" -}} +{{- if .Values.global.manifestGen -}} +{{- semver .Values.global.kubeVersion -}} +{{- else -}} +{{- .Capabilities.KubeVersion.Version -}} +{{- end -}} +{{- end -}} + +{{/* +Determine the name for the webhook +*/}} +{{- define "eck-operator.webhookName" -}} +{{- if .Values.global.manifestGen -}} +elastic-webhook.k8s.elastic.co +{{- else -}} +{{- $name := include "eck-operator.name" . -}} +{{ printf "%s.%s.k8s.elastic.co" $name .Release.Namespace }} +{{- end -}} +{{- end -}} + +{{/* +Determine the name for the webhook secret +*/}} +{{- define "eck-operator.webhookSecretName" -}} +{{- if .Values.global.manifestGen -}} +elastic-webhook-server-cert +{{- else if .Values.webhook.certsSecret -}} +{{- .Values.webhook.certsSecret }} +{{- else -}} +{{- $name := include "eck-operator.name" . -}} +{{ printf "%s-webhook-cert" $name | trunc 63 }} +{{- end -}} +{{- end -}} + +{{/* +Determine the name for the webhook service +*/}} +{{- define "eck-operator.webhookServiceName" -}} +{{- if .Values.global.manifestGen -}} +elastic-webhook-server +{{- else -}} +{{- $name := include "eck-operator.name" . -}} +{{ printf "%s-webhook" $name | trunc 63 }} +{{- end -}} +{{- end -}} + +{{/* +Determine the metrics port +*/}} +{{- define "eck-operator.metrics.port" -}} +{{- if .Values.config.metrics.port -}} +{{- .Values.config.metrics.port -}} +{{- else if .Values.config.metricsPort -}} +{{- .Values.config.metricsPort -}} +{{- else -}} +0 +{{- end -}} +{{- end -}} + +{{/* +RBAC permissions +NOTE - any changes made to RBAC permissions below require +updating docs/operating-eck/eck-permissions.asciidoc file. +*/}} +{{- define "eck-operator.rbacRules" -}} +- apiGroups: + - "authorization.k8s.io" + resources: + - subjectaccessreviews + verbs: + - create +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create +- apiGroups: + - coordination.k8s.io + resources: + - leases + resourceNames: + - elastic-operator-leader + verbs: + - get + - watch + - update +- apiGroups: + - "" + resources: + - endpoints + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - pods + - events + - persistentvolumeclaims + - secrets + - services + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - apps + resources: + - deployments + - statefulsets + - daemonsets + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - elasticsearch.k8s.elastic.co + resources: + - elasticsearches + - elasticsearches/status + - elasticsearches/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - autoscaling.k8s.elastic.co + resources: + - elasticsearchautoscalers + - elasticsearchautoscalers/status + - elasticsearchautoscalers/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - kibana.k8s.elastic.co + resources: + - kibanas + - kibanas/status + - kibanas/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - apm.k8s.elastic.co + resources: + - apmservers + - apmservers/status + - apmservers/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - enterprisesearch.k8s.elastic.co + resources: + - enterprisesearches + - enterprisesearches/status + - enterprisesearches/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - beat.k8s.elastic.co + resources: + - beats + - beats/status + - beats/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - agent.k8s.elastic.co + resources: + - agents + - agents/status + - agents/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - maps.k8s.elastic.co + resources: + - elasticmapsservers + - elasticmapsservers/status + - elasticmapsservers/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - stackconfigpolicy.k8s.elastic.co + resources: + - stackconfigpolicies + - stackconfigpolicies/status + - stackconfigpolicies/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - logstash.k8s.elastic.co + resources: + - logstashes + - logstashes/status + - logstashes/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +{{- end -}} + +{{/* +RBAC permissions on non-namespaced resources +*/}} +{{- define "eck-operator.clusterWideRbacRules" -}} +- apiGroups: + - storage.k8s.io + resources: + - storageclasses + verbs: + - get + - list + - watch +- apiGroups: + - admissionregistration.k8s.io + resources: + - validatingwebhookconfigurations + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +{{- end -}} + +{{/* +RBAC permissions to read node labels +*/}} +{{- define "eck-operator.readNodeLabelsRbacRule" -}} +- apiGroups: + - "" + resources: + - nodes + verbs: + - get + - list + - watch +{{- end -}} diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/templates/cluster-roles.yaml b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/cluster-roles.yaml new file mode 100644 index 00000000..dbd0fba3 --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/cluster-roles.yaml @@ -0,0 +1,121 @@ +{{- if and (not .Values.createClusterScopedResources) (.Values.config.metrics.secureMode.enabled) -}} +{{ fail "createClusterScopedResources is required to set config.metrics.secureMode.enabled to true" }} +{{- end }} +{{- if .Values.createClusterScopedResources -}} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "eck-operator.fullname" . }} + labels: + {{- include "eck-operator.labels" . | nindent 4 }} +rules: +{{ template "eck-operator.rbacRules" . | toYaml | indent 2 }} +{{ template "eck-operator.clusterWideRbacRules" . | toYaml | indent 2 }} +{{ if .Values.config.exposedNodeLabels }} +{{ template "eck-operator.readNodeLabelsRbacRule" . | toYaml | indent 2 }} +{{ end -}} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: "{{ include "eck-operator.name" . }}-view" + labels: + rbac.authorization.k8s.io/aggregate-to-view: "true" + rbac.authorization.k8s.io/aggregate-to-edit: "true" + rbac.authorization.k8s.io/aggregate-to-admin: "true" + {{- include "eck-operator.labels" . | nindent 4 }} +rules: + - apiGroups: ["elasticsearch.k8s.elastic.co"] + resources: ["elasticsearches"] + verbs: ["get", "list", "watch"] + - apiGroups: ["autoscaling.k8s.elastic.co"] + resources: ["elasticsearchautoscalers"] + verbs: ["get", "list", "watch"] + - apiGroups: ["apm.k8s.elastic.co"] + resources: ["apmservers"] + verbs: ["get", "list", "watch"] + - apiGroups: ["kibana.k8s.elastic.co"] + resources: ["kibanas"] + verbs: ["get", "list", "watch"] + - apiGroups: ["enterprisesearch.k8s.elastic.co"] + resources: ["enterprisesearches"] + verbs: ["get", "list", "watch"] + - apiGroups: ["beat.k8s.elastic.co"] + resources: ["beats"] + verbs: ["get", "list", "watch"] + - apiGroups: ["agent.k8s.elastic.co"] + resources: ["agents"] + verbs: ["get", "list", "watch"] + - apiGroups: ["maps.k8s.elastic.co"] + resources: ["elasticmapsservers"] + verbs: ["get", "list", "watch"] + - apiGroups: ["stackconfigpolicy.k8s.elastic.co"] + resources: ["stackconfigpolicies"] + verbs: ["get", "list", "watch"] + - apiGroups: ["logstash.k8s.elastic.co"] + resources: ["logstashes"] + verbs: ["get", "list", "watch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: "{{ include "eck-operator.name" . }}-edit" + labels: + rbac.authorization.k8s.io/aggregate-to-edit: "true" + rbac.authorization.k8s.io/aggregate-to-admin: "true" + {{- include "eck-operator.labels" . | nindent 4 }} +rules: + - apiGroups: ["elasticsearch.k8s.elastic.co"] + resources: ["elasticsearches"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["autoscaling.k8s.elastic.co"] + resources: ["elasticsearchautoscalers"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["apm.k8s.elastic.co"] + resources: ["apmservers"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["kibana.k8s.elastic.co"] + resources: ["kibanas"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["enterprisesearch.k8s.elastic.co"] + resources: ["enterprisesearches"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["beat.k8s.elastic.co"] + resources: ["beats"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["agent.k8s.elastic.co"] + resources: ["agents"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["maps.k8s.elastic.co"] + resources: ["elasticmapsservers"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["stackconfigpolicy.k8s.elastic.co"] + resources: ["stackconfigpolicies"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["logstash.k8s.elastic.co"] + resources: ["logstashes"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] +{{- if .Values.config.metrics.secureMode.enabled }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "eck-operator.labels" . | nindent 4 }} + name: "{{ include "eck-operator.fullname" . }}-metrics-auth-role" +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +{{- end }} +{{- end -}} diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/templates/configmap.yaml b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/configmap.yaml new file mode 100644 index 00000000..01708b52 --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/configmap.yaml @@ -0,0 +1,81 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "eck-operator.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "eck-operator.labels" . | nindent 4 }} +data: + eck.yaml: |- + {{- $metricsPort := int (include "eck-operator.metrics.port" .)}} + log-verbosity: {{ int .Values.config.logVerbosity }} + {{- if and .Values.config.metrics.secureMode.enabled (eq $metricsPort 0) }} + {{- fail "config.metrics.port must be greater than 0 when config.metrics.secureMode.enabled is true" }} + {{- end }} + metrics-port: {{ $metricsPort }} + metrics-secure: {{ .Values.config.metrics.secureMode.enabled }} + container-registry: {{ .Values.config.containerRegistry }} + {{- with .Values.config.containerSuffix }} + container-suffix: {{ . }} + {{- end }} + {{- with .Values.config.containerRepository }} + container-repository: {{ . }} + {{- end }} + max-concurrent-reconciles: {{ int .Values.config.maxConcurrentReconciles }} + {{- with .Values.config.passwordHashCacheSize }} + password-hash-cache-size: {{ int . }} + {{- end }} + ca-cert-validity: {{ .Values.config.caValidity }} + ca-cert-rotate-before: {{ .Values.config.caRotateBefore }} + {{- with .Values.config.caDir }} + ca-dir: {{ . }} + {{- end }} + cert-validity: {{ .Values.config.certificatesValidity }} + cert-rotate-before: {{ .Values.config.certificatesRotateBefore }} + disable-config-watch: {{ .Values.config.disableConfigWatch }} + {{- with .Values.config.exposedNodeLabels }} + exposed-node-labels: [{{ join "," . }}] + {{- end }} + {{- with .Values.config.ipFamily }} + ip-family: {{ . }} + {{- end }} + set-default-security-context: {{ .Values.config.setDefaultSecurityContext }} + kube-client-timeout: {{ .Values.config.kubeClientTimeout }} + {{- with .Values.config.kubeClientQPS }} + kube-client-qps: {{ int . }} + {{- end }} + elasticsearch-client-timeout: {{ .Values.config.elasticsearchClientTimeout }} + disable-telemetry: {{ .Values.telemetry.disabled }} + distribution-channel: {{ .Values.telemetry.distributionChannel }} + {{- with .Values.telemetry.interval }} + telemetry-interval: {{ . }} + {{- end }} + validate-storage-class: {{ .Values.config.validateStorageClass }} + {{- if .Values.tracing.enabled }} + enable-tracing: true + {{- end }} + {{- if .Values.refs.enforceRBAC }} + enforce-rbac-on-refs: true + {{- end }} + enable-webhook: {{ .Values.webhook.enabled }} + {{- if .Values.webhook.enabled }} + webhook-name: {{ include "eck-operator.webhookName" . }} + {{- if not .Values.webhook.manageCerts }} + manage-webhook-certs: false + webhook-cert-dir: {{ .Values.webhook.certsDir }} + {{- end }} + webhook-port: {{ .Values.webhook.port }} + {{- end }} + {{- with .Values.managedNamespaces }} + namespaces: [{{ join "," . }}] + {{- end }} + operator-namespace: {{ .Release.Namespace }} + enable-leader-election: {{ .Values.config.enableLeaderElection }} + elasticsearch-observation-interval: {{ .Values.config.elasticsearchObservationInterval }} + {{- if not .Values.config.containerSuffix }} + ubi-only: {{ .Values.config.ubiOnly }} + {{- end }} + {{- with .Values.webhook.certsSecret }} + webhook-secret: {{ . }} + {{- end }} diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/templates/managed-namespaces.yaml b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/managed-namespaces.yaml new file mode 100644 index 00000000..91deaf21 --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/managed-namespaces.yaml @@ -0,0 +1,13 @@ +{{- if .Values.softMultiTenancy.enabled -}} +{{- range .Values.managedNamespaces }} +{{- $namespace := . }} +--- +apiVersion: v1 +kind: Namespace +metadata: + name: {{ $namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} + eck.k8s.elastic.co/tenant: {{ $namespace }} +{{- end -}} +{{- end -}} diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/templates/managed-ns-network-policy.yaml b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/managed-ns-network-policy.yaml new file mode 100644 index 00000000..23fc1e3a --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/managed-ns-network-policy.yaml @@ -0,0 +1,228 @@ +{{- if .Values.softMultiTenancy.enabled -}} +{{- $fullName := include "eck-operator.fullname" . -}} +{{- $name := include "eck-operator.name" . -}} +{{- range .Values.managedNamespaces -}} +{{- $namespace := . }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: "{{ $name }}-elasticsearch" + namespace: {{ $namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +spec: + podSelector: + matchLabels: + common.k8s.elastic.co/type: "elasticsearch" + egress: + # Transport port + - ports: + - port: 9300 + to: + # Elasticsearch within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} + podSelector: + matchLabels: + common.k8s.elastic.co/type: "elasticsearch" + # DNS + - ports: + - port: 53 + protocol: UDP + to: [] + ingress: + # HTTP Port + - ports: + - port: 9200 + from: + # Operator + - namespaceSelector: + matchLabels: + name: "{{ $.Release.Namespace }}" + podSelector: + matchLabels: + {{- include "eck-operator.selectorLabels" $ | nindent 14 }} + # Within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} + # Transport port + - ports: + - port: 9300 + from: + # Within namespace (from other Elasticsearch nodes) + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} + podSelector: + matchLabels: + common.k8s.elastic.co/type: "elasticsearch" +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: "{{ $name }}-kibana" + namespace: {{ $namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +spec: + podSelector: + matchLabels: + common.k8s.elastic.co/type: "kibana" + egress: + # Elasticsearch HTTP port + - ports: + - port: 9200 + to: + # Elasticsearch within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} + podSelector: + matchLabels: + common.k8s.elastic.co/type: "elasticsearch" + # DNS + - ports: + - port: 53 + protocol: UDP + to: [] + ingress: + # HTTP Port + - ports: + - port: 5601 + from: + # Within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: "{{ $name }}-apm-server" + namespace: {{ $namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +spec: + podSelector: + matchLabels: + common.k8s.elastic.co/type: "apm-server" + egress: + # Elasticsearch HTTP port + - ports: + - port: 9200 + to: + # Elasticsearch within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} + podSelector: + matchLabels: + common.k8s.elastic.co/type: "elasticsearch" + # Kibana HTTP port + - ports: + - port: 5601 + to: + # Kibana within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} + podSelector: + matchLabels: + common.k8s.elastic.co/type: "kibana" + # DNS + - ports: + - port: 53 + protocol: UDP + to: [] + ingress: + # HTTP Port + - ports: + - port: 8200 + from: + # Within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: "{{ $name }}-enterprise-search" + namespace: {{ $namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +spec: + podSelector: + matchLabels: + common.k8s.elastic.co/type: "enterprise-search" + egress: + # Elasticsearch HTTP port + - ports: + - port: 9200 + to: + # Elasticsearch within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} + podSelector: + matchLabels: + common.k8s.elastic.co/type: "elasticsearch" + # DNS + - ports: + - port: 53 + protocol: UDP + to: [] + ingress: + # HTTP Port + - ports: + - port: 3002 + from: + # Within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: "{{ $name }}-beats" + namespace: {{ $namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +spec: + podSelector: + matchLabels: + common.k8s.elastic.co/type: "beat" + egress: + # Elasticsearch HTTP port + - ports: + - port: 9200 + to: + # Elasticsearch within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} + podSelector: + matchLabels: + common.k8s.elastic.co/type: "elasticsearch" + # Kibana HTTP port + - ports: + - port: 5601 + to: + # Kibana within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} + podSelector: + matchLabels: + common.k8s.elastic.co/type: "kibana" + # DNS + - ports: + - port: 53 + protocol: UDP + to: [] +{{- end }} +{{- end -}} diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/templates/metrics-service.yaml b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/metrics-service.yaml new file mode 100644 index 00000000..53bdc02b --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/metrics-service.yaml @@ -0,0 +1,22 @@ +{{- if .Values.config.metrics.secureMode.enabled }} +{{- $metricsPort := int (include "eck-operator.metrics.port" .)}} +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: {{ include "eck-operator.name" . }}-metrics-service + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} + helm.sh/chart: {{ include "eck-operator.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + name: "{{ include "eck-operator.fullname" . }}-metrics" + namespace: {{ .Release.Namespace }} +spec: + ports: + - name: https + port: {{ $metricsPort }} + protocol: TCP + targetPort: metrics + selector: + {{- include "eck-operator.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/templates/operator-namespace.yaml b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/operator-namespace.yaml new file mode 100644 index 00000000..07123b70 --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/operator-namespace.yaml @@ -0,0 +1,9 @@ +{{- if (and .Values.global.manifestGen .Values.global.createOperatorNamespace) -}} +--- +apiVersion: v1 +kind: Namespace +metadata: + name: {{ .Release.Namespace }} + labels: + name: {{ .Release.Namespace }} +{{- end -}} diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/templates/operator-network-policy.yaml b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/operator-network-policy.yaml new file mode 100644 index 00000000..ad74156d --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/operator-network-policy.yaml @@ -0,0 +1,59 @@ +{{- if .Values.softMultiTenancy.enabled -}} +{{- $kubeAPIServerIP := (required "kubeAPIServerIP is required" .Values.kubeAPIServerIP) -}} +{{- $metricsPort := int (include "eck-operator.metrics.port" .)}} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "eck-operator.fullname" . }} + namespace: {{ .Release.Namespace}} + labels: + {{- include "eck-operator.labels" . | nindent 4 }} +spec: + podSelector: + matchLabels: + {{- include "eck-operator.selectorLabels" . | nindent 6 }} + egress: + # DNS + - ports: + - port: 53 + protocol: UDP + to: [] + # API server + - ports: + - port: 443 + to: + - ipBlock: + cidr: "{{ $kubeAPIServerIP }}/32" + # Elasticsearch + - ports: + - port: 9200 + to: + - namespaceSelector: + matchExpressions: + - key: "eck.k8s.elastic.co/tenant" + operator: In + values: + {{- range .Values.managedNamespaces }} + - {{ . }} + {{- end }} + podSelector: + matchLabels: + common.k8s.elastic.co/type: "elasticsearch" +{{- if or .Values.webhook.enabled (gt $metricsPort 0) }} + ingress: +{{- if .Values.webhook.enabled }} + - ports: + - port: {{ .Values.webhook.port }} + from: + - ipBlock: + cidr: "{{ $kubeAPIServerIP }}/32" +{{- end }} +{{- if gt $metricsPort 0 }} + # Metrics + - ports: + - port: {{ $metricsPort }} + from: [] +{{- end }} +{{- end }} +{{- end -}} diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/templates/pdb.yaml b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/pdb.yaml new file mode 100644 index 00000000..f0dddde9 --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/pdb.yaml @@ -0,0 +1,19 @@ +{{- if .Values.podDisruptionBudget.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "eck-operator.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "eck-operator.labels" . | indent 4 }} +spec: + {{- with .Values.podDisruptionBudget.minAvailable }} + minAvailable: {{ . }} + {{- end }} + {{- with .Values.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} + selector: + matchLabels: + {{- include "eck-operator.selectorLabels" . | indent 6 }} +{{- end -}} diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/templates/podMonitor.yaml b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/podMonitor.yaml new file mode 100644 index 00000000..8e073cd3 --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/podMonitor.yaml @@ -0,0 +1,42 @@ +{{- $metricsPort := int (include "eck-operator.metrics.port" .)}} +{{- if and .Values.config.metrics.secureMode.enabled (eq $metricsPort 0) }} +{{- fail "config.metrics.port must be greater than 0 when config.metrics.secureMode.enabled is true" }} +{{- end }} +{{- if and .Values.podMonitor.enabled (gt $metricsPort 0) }} +{{- if and .Values.podMonitor.enabled .Values.config.metrics.secureMode.enabled }} +{{- fail "podMonitor and config.metrics.secureMode are mutually exclusive" }} +{{- end }} +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: {{ include "eck-operator.fullname" . }} + namespace: {{ ternary .Values.podMonitor.namespace .Release.Namespace (not (and (.Values.podMonitor) (empty .Values.podMonitor.namespace))) }} + labels: {{- include "eck-operator.labels" . | nindent 4 }} + {{- with .Values.podMonitor.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.podMonitor.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .Values.podMonitor.podTargetLabels }} + podTargetLabels: {{- toYaml . | nindent 4 }} + {{- end }} + podMetricsEndpoints: + - port: metrics + path: /metrics + {{- with .Values.podMonitor.interval }} + interval: {{ . }} + {{- end }} + {{- with .Values.podMonitor.scrapeTimeout }} + scrapeTimeout: {{ . }} + {{- end }} + {{- with .Values.podMonitor.podMetricsEndpointConfig }} + {{- toYaml . | nindent 6 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: {{- include "eck-operator.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/templates/role-bindings.yaml b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/role-bindings.yaml new file mode 100644 index 00000000..0db9f278 --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/role-bindings.yaml @@ -0,0 +1,98 @@ +{{- $operatorNSIsManaged := has .Release.Namespace .Values.managedNamespaces -}} +{{- $fullName := include "eck-operator.fullname" . -}} +{{- $svcAccount := include "eck-operator.serviceAccountName" . }} +{{- $enableSecureMetrics := .Values.config.metrics.secureMode.enabled -}} + +{{- if not .Values.createClusterScopedResources }} +{{- range .Values.managedNamespaces }} +{{- $namespace := . }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: "{{ $fullName }}" + namespace: {{ $namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +rules: +{{ template "eck-operator.rbacRules" $ | toYaml | indent 2 }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: "{{ $fullName }}" + namespace: {{ $namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: "{{ $fullName }}" +subjects: +- kind: ServiceAccount + name: {{ $svcAccount }} + namespace: {{ $.Release.Namespace }} +{{- end }} {{- /* end of range over managed namespaces */}} +{{- /* If createClusterScopedResources is false and operator namespace is not in the managed namespaces list, create additional role binding */}} +{{- if not $operatorNSIsManaged }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ $fullName }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +rules: +{{ template "eck-operator.rbacRules" $ | toYaml | indent 2 }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: "{{ $fullName }}" + namespace: {{ $.Release.Namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: "{{ $fullName }}" +subjects: +- kind: ServiceAccount + name: {{ $svcAccount }} + namespace: {{ $.Release.Namespace }} +{{- end }} {{- /* end of operator role binding if operator namespace is not managed */}} +{{- else }} {{- /* we can create cluster-scoped resources so just create a cluster role binding */}} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ $fullName }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ $fullName }} +subjects: +- kind: ServiceAccount + name: {{ $svcAccount }} + namespace: {{ $.Release.Namespace }} +{{- if $enableSecureMetrics }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} + name: "{{ include "eck-operator.fullname" . }}-metrics-auth-rolebinding" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: "{{ include "eck-operator.fullname" . }}-metrics-auth-role" +subjects: +- kind: ServiceAccount + name: {{ $svcAccount }} + namespace: {{ $.Release.Namespace }} +{{- end }} +{{- end }} diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/templates/service-account.yaml b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/service-account.yaml new file mode 100644 index 00000000..f91acdcc --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/service-account.yaml @@ -0,0 +1,15 @@ +{{- if .Values.serviceAccount.create }} +--- +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ include "eck-operator.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "eck-operator.labels" . | nindent 4 }} +{{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- end }} diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/templates/service-monitor.yaml b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/service-monitor.yaml new file mode 100644 index 00000000..0d4a3d9c --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/service-monitor.yaml @@ -0,0 +1,34 @@ +{{- if and .Values.config.metrics.secureMode.enabled .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "eck-operator.fullname" . }} + namespace: {{ ternary .Values.serviceMonitor.namespace .Release.Namespace (not (and (.Values.serviceMonitor) (empty .Values.serviceMonitor.namespace))) }} + labels: {{- include "eck-operator.labels" . | nindent 4 }} +spec: + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "eck-operator.name" . }}-metrics-service + app.kubernetes.io/instance: {{ .Release.Name }} + endpoints: + - port: https + path: /metrics + scheme: https + interval: 30s + tlsConfig: + {{- $insecureSkipVerify := (ternary .Values.config.metrics.secureMode.tls.insecureSkipVerify .Values.serviceMonitor.insecureSkipVerify (hasKey .Values.config.metrics.secureMode.tls "insecureSkipVerify")) }} + insecureSkipVerify: {{ $insecureSkipVerify }} + {{- if (not $insecureSkipVerify) }} + {{- $caMountDirectory := or (.Values.config.metrics.secureMode.tls.caMountDirectory) (.Values.serviceMonitor.caMountDirectory) -}} + {{- $leading_path := trimSuffix "/" $caMountDirectory }} + {{- $caSecret := or (.Values.config.metrics.secureMode.tls.caSecret) (.Values.serviceMonitor.caSecret) -}} + {{- with $caSecret }} + caFile: "{{ $leading_path }}/{{ . }}/ca.crt" + {{- end }} + serverName: "{{ include "eck-operator.fullname" . }}-metrics.{{ .Release.Namespace }}.svc" + {{- end }} + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token +{{- end }} diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/templates/statefulset.yaml b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/statefulset.yaml new file mode 100644 index 00000000..bcc27b97 --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/statefulset.yaml @@ -0,0 +1,162 @@ +--- +{{- $metricsPort := int (include "eck-operator.metrics.port" .)}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "eck-operator.fullname" . }} + namespace: {{ .Release.Namespace }} + {{- with .Values.statefulsetAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "eck-operator.labels" . | nindent 4 }} + {{- with .Values.statefulsetLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "eck-operator.selectorLabels" . | nindent 6 }} + serviceName: {{ include "eck-operator.fullname" . }} + replicas: {{ .Values.replicaCount }} + template: + metadata: + annotations: + # Rename the fields "error" to "error.message" and "source" to "event.source" + # This is to avoid a conflict with the ECS "error" and "source" documents. + "co.elastic.logs/raw": "[{\"type\":\"container\",\"json.keys_under_root\":true,\"paths\":[\"/var/log/containers/*${data.kubernetes.container.id}.log\"],\"processors\":[{\"convert\":{\"mode\":\"rename\",\"ignore_missing\":true,\"fields\":[{\"from\":\"error\",\"to\":\"_error\"}]}},{\"convert\":{\"mode\":\"rename\",\"ignore_missing\":true,\"fields\":[{\"from\":\"_error\",\"to\":\"error.message\"}]}},{\"convert\":{\"mode\":\"rename\",\"ignore_missing\":true,\"fields\":[{\"from\":\"source\",\"to\":\"_source\"}]}},{\"convert\":{\"mode\":\"rename\",\"ignore_missing\":true,\"fields\":[{\"from\":\"_source\",\"to\":\"event.source\"}]}}]}]" + "checksum/config": {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "eck-operator.selectorLabels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + terminationGracePeriodSeconds: 10 + serviceAccountName: {{ include "eck-operator.serviceAccountName" . }} + automountServiceAccountToken: {{ .Values.automountServiceAccountToken }} + {{- with .Values.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + {{- with .Values.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - image: "{{ .Values.image.repository }}{{- if .Values.config.ubiOnly -}}-ubi{{- end -}}{{- if .Values.image.fips -}}-fips{{- end -}}:{{ default .Chart.AppVersion .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + name: manager + args: + - "manager" + - "--config=/conf/eck.yaml" + {{- with .Values.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + env: + - name: OPERATOR_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + {{- if .Values.webhook.enabled }} + - name: WEBHOOK_SECRET + value: {{ include "eck-operator.webhookSecretName" . }} + {{- end }} + {{- with .Values.env }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.tracing.enabled -}} + {{- range $name, $value := .Values.tracing.config }} + - name: {{ $name }} + value: {{ $value }} + {{- end }} + {{- end }} + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if or .Values.webhook.enabled (gt $metricsPort 0) }} + ports: + {{- if (gt $metricsPort 0) }} + - containerPort: {{ $metricsPort }} + name: metrics + protocol: TCP + {{- end }} + {{- if .Values.webhook.enabled }} + - containerPort: {{ .Values.webhook.port }} + name: https-webhook + protocol: TCP + {{- end }} + {{- end }} + volumeMounts: + - mountPath: "/conf" + name: conf + readOnly: true + {{- if .Values.webhook.enabled }} + - mountPath: {{ .Values.webhook.certsDir }} + name: cert + readOnly: true + {{- end }} + {{- if .Values.config.metrics.secureMode.tls.certificateSecret }} + - mountPath: "/tmp/k8s-metrics-server/serving-certs" + name: tls-certificate + readOnly: true + {{- end }} + {{- with .Values.volumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + volumes: + - name: conf + configMap: + name: {{ include "eck-operator.fullname" . }} + {{- if .Values.webhook.enabled }} + - name: cert + secret: + defaultMode: 420 + secretName: {{ include "eck-operator.webhookSecretName" . }} + {{- end }} + {{- if .Values.config.metrics.secureMode.tls.certificateSecret }} + - name: tls-certificate + secret: + defaultMode: 420 + secretName: {{ .Values.config.metrics.secureMode.tls.certificateSecret }} + {{- end }} + {{- with .Values.volumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.hostNetwork }} + hostNetwork: true + {{- end }} + {{- if .Values.dnsPolicy }} + dnsPolicy: {{ .Values.dnsPolicy }} + {{- else if .Values.hostNetwork }} + dnsPolicy: ClusterFirstWithHostNet + {{- end }} + {{- with .Values.dnsConfig }} + dnsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/templates/validate-chart.yaml b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/validate-chart.yaml new file mode 100644 index 00000000..326b70bc --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/validate-chart.yaml @@ -0,0 +1,29 @@ +{{- if .Values.softMultiTenancy.enabled -}} + {{- if has .Release.Namespace .Values.managedNamespaces -}} + {{- fail "Operator namespace cannot be in managed namespaces when soft multi-tenancy is enabled" -}} + {{- end -}} + + {{- if empty .Values.managedNamespaces -}} + {{- fail "Managed namespaces must be defined when soft multi-tenancy is enabled" -}} + {{- end -}} + + {{- if empty .Values.kubeAPIServerIP -}} + {{- fail "Soft multi-tenancy requires kubeAPIServerIP to be defined" -}} + {{- end -}} +{{- end -}} + +{{- if (not .Values.createClusterScopedResources) -}} + {{- if .Values.webhook.enabled -}} + {{- fail "Webhook cannot be enabled when cluster-scoped resource creation is disabled" -}} + {{- end -}} + + {{- if .Values.config.validateStorageClass -}} + {{- fail "Storage class validation cannot be enabled when cluster-scoped resource creation is disabled" -}} + {{- end -}} +{{- end -}} + +{{- if (not .Values.config.enableLeaderElection) -}} + {{- if gt (int .Values.replicaCount) 1 -}} + {{- fail "Leader election must be enabled with more than one replica" -}} + {{- end -}} +{{- end -}} diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/templates/webhook.yaml b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/webhook.yaml new file mode 100644 index 00000000..8f41e7d0 --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/templates/webhook.yaml @@ -0,0 +1,473 @@ +{{- if .Values.webhook.enabled -}} +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: {{ include "eck-operator.webhookName" . }} + labels: + {{- include "eck-operator.labels" . | nindent 4 }} +{{- with .Values.webhook.certManagerCert }} + annotations: + cert-manager.io/inject-ca-from: "{{ $.Release.Namespace }}/{{ . }}" +{{- end }} +webhooks: +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-agent-k8s-elastic-co-v1alpha1-agent + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-agent-validation-v1alpha1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - agent.k8s.elastic.co + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - agents +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-apm-k8s-elastic-co-v1-apmserver + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-apm-validation-v1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - apm.k8s.elastic.co + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - apmservers +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-apm-k8s-elastic-co-v1beta1-apmserver + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-apm-validation-v1beta1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - apm.k8s.elastic.co + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - apmservers +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-beat-k8s-elastic-co-v1beta1-beat + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-beat-validation-v1beta1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - beat.k8s.elastic.co + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - beats +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-enterprisesearch-k8s-elastic-co-v1-enterprisesearch + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-ent-validation-v1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - enterprisesearch.k8s.elastic.co + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - enterprisesearches +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-enterprisesearch-k8s-elastic-co-v1beta1-enterprisesearch + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-ent-validation-v1beta1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - enterprisesearch.k8s.elastic.co + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - enterprisesearches +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-elasticsearch-k8s-elastic-co-v1-elasticsearch + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-es-validation-v1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - elasticsearch.k8s.elastic.co + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - elasticsearches +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-elasticsearch-k8s-elastic-co-v1beta1-elasticsearch + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-es-validation-v1beta1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - elasticsearch.k8s.elastic.co + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - elasticsearches +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-ems-k8s-elastic-co-v1alpha1-mapsservers + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-ems-validation-v1alpha1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - maps.k8s.elastic.co + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - mapsservers +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-kibana-k8s-elastic-co-v1-kibana + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-kb-validation-v1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - kibana.k8s.elastic.co + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - kibanas +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-kibana-k8s-elastic-co-v1beta1-kibana + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-kb-validation-v1beta1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - kibana.k8s.elastic.co + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - kibanas +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-autoscaling-k8s-elastic-co-v1alpha1-elasticsearchautoscaler + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-esa-validation-v1alpha1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - autoscaling.k8s.elastic.co + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - elasticsearchautoscalers +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-scp-k8s-elastic-co-v1alpha1-stackconfigpolicies + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-scp-validation-v1alpha1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - stackconfigpolicy.k8s.elastic.co + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - stackconfigpolicies +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-logstash-k8s-elastic-co-v1alpha1-logstash + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-logstash-validation-v1alpha1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - logstash.k8s.elastic.co + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - logstashes +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "eck-operator.labels" . | nindent 4 }} +spec: + ports: + - name: https + port: 443 + targetPort: {{ .Values.webhook.port }} + selector: + {{- include "eck-operator.selectorLabels" . | nindent 4 }} +{{- if .Values.webhook.manageCerts }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "eck-operator.webhookSecretName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "eck-operator.labels" . | nindent 4 }} +{{- end }} +{{- end -}} diff --git a/packs/elastic-operator-3.0.0/charts/eck-operator/values.yaml b/packs/elastic-operator-3.0.0/charts/eck-operator/values.yaml new file mode 100644 index 00000000..431b8faa --- /dev/null +++ b/packs/elastic-operator-3.0.0/charts/eck-operator/values.yaml @@ -0,0 +1,372 @@ +# nameOverride is the short name for the deployment. Leave empty to let Helm generate a name using chart values. +nameOverride: "elastic-operator" + +# fullnameOverride is the full name for the deployment. Leave empty to let Helm generate a name using chart values. +fullnameOverride: "elastic-operator" + +# managedNamespaces is the set of namespaces that the operator manages. Leave empty to manage all namespaces. +managedNamespaces: [] + +# installCRDs determines whether Custom Resource Definitions (CRD) are installed by the chart. +# Note that CRDs are global resources and require cluster admin privileges to install. +# If you are sharing a cluster with other users who may want to install ECK on their own namespaces, setting this to true can have unintended consequences. +# 1. Upgrades will overwrite the global CRDs and could disrupt the other users of ECK who may be running a different version. +# 2. Uninstalling the chart will delete the CRDs and potentially cause Elastic resources deployed by other users to be removed as well. +installCRDs: true + +# replicaCount is the number of operator pods to run. +replicaCount: 1 + +image: + # repository is the container image prefixed by the registry name. + repository: docker.elastic.co/eck/eck-operator + # pullPolicy is the container image pull policy. + pullPolicy: IfNotPresent + # tag is the container image tag. If not defined, defaults to chart appVersion. + tag: null + # fips specifies whether the operator will use a FIPS compliant container image for its own StatefulSet image. + # This setting does not apply to Elastic Stack applications images. + # Can be combined with config.ubiOnly. + fips: false + +# priorityClassName defines the PriorityClass to be used by the operator pods. +priorityClassName: "" + +# imagePullSecrets defines the secrets to use when pulling the operator container image. +imagePullSecrets: [] + +# resources define the container resource limits for the operator. +resources: + limits: + cpu: 1 + memory: 1Gi + requests: + cpu: 100m + memory: 150Mi + +# statefulsetAnnotations define the annotations that should be added to the operator StatefulSet. +statefulsetAnnotations: {} + +# statefulsetLabels define additional labels that should be added to the operator StatefulSet. +statefulsetLabels: {} + +# podAnnotations define the annotations that should be added to the operator pod. +podAnnotations: {} + +## podLabels define additional labels that should be added to the operator pod. +podLabels: {} + +# podSecurityContext defines the pod security context for the operator pod. +podSecurityContext: + runAsNonRoot: true + +# securityContext defines the security context of the operator container. +securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + +# nodeSelector defines the node selector for the operator pod. +nodeSelector: {} + +# tolerations defines the node tolerations for the operator pod. +tolerations: [] + +# affinity defines the node affinity rules for the operator pod. +affinity: {} + +# podDisruptionBudget configures the minimum or the maxium available pods for voluntary disruptions, +# set to either an integer (e.g. 1) or a percentage value (e.g. 25%). +podDisruptionBudget: + enabled: false + minAvailable: 1 + # maxUnavailable: 3 + +# additional environment variables for the operator container. +env: [] + +# additional volume mounts for the operator container. +volumeMounts: [] + +# additional volumes to add to the operator pod. +volumes: [] + +# createClusterScopedResources determines whether cluster-scoped resources (ClusterRoles, ClusterRoleBindings) should be created. +createClusterScopedResources: true + +# Automount API credentials for the Service Account into the pod. +automountServiceAccountToken: true + +serviceAccount: + # create specifies whether a service account should be created for the operator. + create: true + # Specifies whether a service account should automount API credentials. + automountServiceAccountToken: true + # annotations to add to the service account + annotations: {} + # name of the service account to use. If not set and create is true, a name is generated using the fullname template. + name: "" + +tracing: + # enabled specifies whether APM tracing is enabled for the operator. + enabled: false + # config is a map of APM Server configuration variables that should be set in the environment. + config: + ELASTIC_APM_SERVER_URL: http://localhost:8200 + ELASTIC_APM_SERVER_TIMEOUT: 30s + +refs: + # enforceRBAC specifies whether RBAC should be enforced for cross-namespace associations between resources. + enforceRBAC: false + +webhook: + # enabled determines whether the webhook is installed. + enabled: true + # caBundle is the PEM-encoded CA trust bundle for the webhook certificate. Only required if manageCerts is false and certManagerCert is null. + caBundle: Cg== + # certManagerCert is the name of the cert-manager certificate to use with the webhook. + certManagerCert: null + # certsDir is the directory to mount the certificates. + certsDir: "/tmp/k8s-webhook-server/serving-certs" + # failurePolicy of the webhook. + failurePolicy: Ignore + # manageCerts determines whether the operator manages the webhook certificates automatically. + manageCerts: true + # namespaceSelector corresponds to the namespaceSelector property of the webhook. + # Setting this restricts the webhook to act only on objects submitted to namespaces that match the selector. + namespaceSelector: {} + # objectSelector corresponds to the objectSelector property of the webhook. + # Setting this restricts the webhook to act only on objects that match the selector. + objectSelector: {} + # port is the port that the validating webhook binds to. + port: 9443 + # secret specifies the Kubernetes secret to be mounted into the path designated by the certsDir value to be used for webhook certificates. + certsSecret: "" + +# hostNetwork allows a Pod to use the Node network namespace. +# This is required to allow for communication with the kube API when using some alternate CNIs in conjunction with webhook enabled. +# If hostNetwork is enabled, dnsPolicy defaults to ClusterFirstWithHostNet unless explicitly set. +# CAUTION: Proceed at your own risk. This setting has security concerns such as allowing malicious users to access workloads running on the host. +hostNetwork: false + +# dnsPolicy defines the DNS policy for the operator pod. +# Check https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy for more details. +dnsPolicy: "" + +# dnsConfig defines the DNS configuration for the operator pod. +# Check https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-dns-config for more details. +# dnsConfig: +# nameservers: +# - 169.254.20.10 +# searches: +# - svc.cluster.local +# options: +# - name: ndots +# value: "2" +dnsConfig: {} + +softMultiTenancy: + # enabled determines whether the operator is installed with soft multi-tenancy extensions. + # This requires network policies to be enabled on the Kubernetes cluster. + enabled: false + +# kubeAPIServerIP is required when softMultiTenancy is enabled. +kubeAPIServerIP: null + +telemetry: + # disabled determines whether the operator periodically updates ECK telemetry data for Kibana to consume. + disabled: false + # distributionChannel denotes which distribution channel was used to install the operator. + distributionChannel: "helm" + +# config values for the operator. +config: + # logVerbosity defines the logging level. Valid values are as follows: + # -2: Errors only + # -1: Errors and warnings + # 0: Errors, warnings, and information + # number greater than 0: Errors, warnings, information, and debug details. + logVerbosity: "0" + + # (Deprecated: use metrics.port: will be removed in v2.14.0) metricsPort defines the port to expose operator metrics. Set to 0 to disable metrics reporting. + metricsPort: 0 + + metrics: + # port defines the port to expose operator metrics. Set to 0 to disable metrics reporting. + port: "0" + # secureMode contains the options for enabling and configuring RBAC and TLS/HTTPs for the metrics endpoint. + secureMode: + # secureMode.enabled specifies whether to enable RBAC and TLS/HTTPs for the metrics endpoint. + # * This option makes most sense when using a ServiceMonitor to scrape the metrics and is therefore mutually exclusive with the podMonitor.enabled option. + # * This option also requires using cluster scoped resources (ClusterRole, ClusterRoleBinding) to + # grant access to the /metrics endpoint. (createClusterScopedResources: true is required) + # + enabled: false + tls: + # certificateSecret is the name of the tls secret containing the custom TLS certificate and key for the secure metrics endpoint. + # + # * This is an optional setting and is only required if you are using a custom TLS certificate. A self-signed certificate will be generated by default. + # * TLS secret key must be named tls.crt. + # * TLS key's secret key must be named tls.key. + # * It is assumed to be in the same namespace as the ServiceMonitor. + # + # example: kubectl create secret tls eck-metrics-tls-certificate -n elastic-system \ + # --cert=/path/to/tls.crt --key=/path/to/tls.key + certificateSecret: "" + + # containerRegistry to use for pulling Elasticsearch and other application container images. + containerRegistry: docker.elastic.co + + # containerRepository to use for pulling Elasticsearch and other application container images. + # containerRepository: "" + + # containerSuffix suffix to be appended to container images by default. Cannot be combined with -ubiOnly flag + # containerSuffix: "" + + # maxConcurrentReconciles is the number of concurrent reconciliation operations to perform per controller. + maxConcurrentReconciles: "3" + + # caValidity defines the validity period of the CA certificates generated by the operator. + caValidity: 8760h + + # caRotateBefore defines when to rotate a CA certificate that is due to expire. + caRotateBefore: 24h + + # caDir defines the directory containing a CA certificate (tls.crt) and its associated private key (tls.key) to be used for all managed resources. + # Setting this makes caRotateBefore and caValidity values ineffective. + caDir: "" + + # certificatesValidity defines the validity period of certificates generated by the operator. + certificatesValidity: 8760h + + # certificatesRotateBefore defines when to rotate a certificate that is due to expire. + certificatesRotateBefore: 24h + + # disableConfigWatch specifies whether the operator watches the configuration file for changes. + disableConfigWatch: false + + # exposedNodeLabels is an array of regular expressions of node labels which are allowed to be copied as annotations on Elasticsearch Pods. + exposedNodeLabels: [ "topology.kubernetes.io/.*", "failure-domain.beta.kubernetes.io/.*" ] + + # ipFamily specifies the IP family to use. Possible values: IPv4, IPv6 and "" (auto-detect) + ipFamily: "" + + # setDefaultSecurityContext determines whether a default security context is set on application containers created by the operator. + # *note* that the default option now is "auto-detect" to attempt to set this properly automatically when both running + # in an openshift cluster, and a standard kubernetes cluster. Valid values are as follows: + # "auto-detect" : auto detect + # "true" : set pod security context when creating resources. + # "false" : do not set pod security context when creating resources. + setDefaultSecurityContext: "auto-detect" + + # kubeClientTimeout sets the request timeout for Kubernetes API calls made by the operator. + kubeClientTimeout: 60s + + # elasticsearchClientTimeout sets the request timeout for Elasticsearch API calls made by the operator. + elasticsearchClientTimeout: 180s + + # validateStorageClass specifies whether storage classes volume expansion support should be verified. + # Can be disabled if cluster-wide storage class RBAC access is not available. + validateStorageClass: true + + # enableLeaderElection specifies whether leader election should be enabled + enableLeaderElection: true + + # Interval between observations of Elasticsearch health, non-positive values disable asynchronous observation. + elasticsearchObservationInterval: 10s + + # ubiOnly specifies whether the operator will use only UBI container images to deploy Elastic Stack applications as well as for its own StatefulSet image. UBI images are only available from 7.10.0 onward. + # Cannot be combined with the containerSuffix value. + ubiOnly: false + +# Prometheus PodMonitor configuration +# Reference: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#podmonitor +podMonitor: + + # enabled determines whether a podMonitor should deployed to scrape the eck metrics. + # This requires the prometheus operator and the config.metrics.port not to be 0 + enabled: false + + # labels adds additional labels to the podMonitor + labels: {} + + # annotations adds additional annotations to the podMonitor + annotations: {} + + # namespace determines in which namespace the podMonitor will be deployed. + # If not set the podMonitor will be created in the namespace where the Helm release is installed into + # namespace: monitoring + + # interval specifies the interval at which metrics should be scraped + interval: 5m + + # scrapeTimeout specifies the timeout after which the scrape is ended + scrapeTimeout: 30s + + # podTargetLabels transfers labels on the Kubernetes Pod onto the target. + podTargetLabels: [] + + # podMetricsEndpointConfig allows to add an extended configuration to the podMonitor + podMetricsEndpointConfig: {} + # honorTimestamps: true + +# Prometheus ServiceMonitor configuration +# Only used when config.enableSecureMetrics is true +# Reference: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#servicemonitor +serviceMonitor: + # This option requires the following settings within Prometheus to function: + # 1. RBAC settings for the Prometheus instance to access the metrics endpoint. + # + # - nonResourceURLs: + # - /metrics + # verbs: + # - get + # + # 2. If using the Prometheus Operator and your Prometheus instance is not in the same namespace as the operator you will need + # the Prometheus Operator configured with the following Helm values: + # + # prometheus: + # prometheusSpec: + # serviceMonitorNamespaceSelector: {} + # serviceMonitorSelectorNilUsesHelmValues: false + # + # allows to disable the serviceMonitor, enabled by default for backwards compatibility + enabled: true + # namespace determines in which namespace the serviceMonitor will be deployed. + # If not set the serviceMonitor will be created in the namespace where the Helm release is installed into + # namespace: monitoring + # caSecret is the name of the secret containing the custom CA certificate used to generate the custom TLS certificate for the secure metrics endpoint. + # + # * This *must* be the name of the secret containing the CA certificate used to sign the custom TLS certificate for the metrics endpoint. + # * This secret *must* be in the same namespace as the Prometheus instance that will scrape the metrics. + # * If using the Prometheus operator this secret must be within the `spec.secrets` field of the `Prometheus` custom resource such that it is mounted into the Prometheus pod at `caMountDirectory`, which defaults to /etc/prometheus/secrets/{secret-name}. + # * This is an optional setting and is only required if you are using a custom TLS certificate. + # * Key must be named ca.crt. + # + # example: kubectl create secret generic eck-metrics-tls-ca -n monitoring \ + # --from-file=ca.crt=/path/to/ca.pem + caSecret: "" + # caMountDirectory is the directory at which the CA certificate is mounted within the Prometheus pod. + # + # * You should only need to adjust this if you are *not* using the Prometheus operator. + caMountDirectory: "/etc/prometheus/secrets/" + # insecureSkipVerify specifies whether to skip verification of the TLS certificate for the secure metrics endpoint. + # + # * If this setting is set to false, then the following settings are required: + # - certificateSecret + # - caSecret + insecureSkipVerify: true + +# Globals meant for internal use only +global: + # manifestGen specifies whether the chart is running under manifest generator. + # This is used for tasks specific to generating the all-in-one.yaml file. + manifestGen: false + # createOperatorNamespace defines whether the operator namespace manifest should be generated when in manifestGen mode. + # Usually we do want that to happen (e.g. all-in-one.yaml) but, sometimes we don't (e.g. E2E tests). + createOperatorNamespace: true + # kubeVersion is the effective Kubernetes version we target when generating the all-in-one.yaml. + kubeVersion: 1.21.0 diff --git a/packs/elastic-operator-3.0.0/logo.png b/packs/elastic-operator-3.0.0/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..fa70b78daa45585ec0f802dfe637e4ce2172d6f8 GIT binary patch literal 5810 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 Date: Tue, 15 Jul 2025 15:27:30 -0500 Subject: [PATCH 2/8] Upgrade elastic-stack to version 0.15.0 --- packs/elastic-stack-0.15.0/README.md | 63 +++ .../charts/eck-stack-0.15.0.tgz | Bin 0 -> 44500 bytes .../charts/eck-stack/.helmignore | 25 ++ .../charts/eck-stack/Chart.lock | 27 ++ .../charts/eck-stack/Chart.yaml | 39 ++ .../charts/eck-stack/README.md | 93 +++++ .../eck-stack/charts/eck-agent/.helmignore | 24 ++ .../eck-stack/charts/eck-agent/Chart.yaml | 10 + .../charts/eck-stack/charts/eck-agent/LICENSE | 93 +++++ .../eck-agent/examples/fleet-agents.yaml | 24 ++ .../examples/system-integration.yaml | 133 ++++++ .../charts/eck-agent/templates/NOTES.txt | 6 + .../charts/eck-agent/templates/_helpers.tpl | 51 +++ .../templates/cluster-role-binding.yaml | 33 ++ .../eck-agent/templates/cluster-role.yaml | 22 + .../eck-agent/templates/elastic-agent.yaml | 18 + .../templates/elastic-agent.yaml.bak | 89 ++++ .../eck-agent/templates/service-account.yaml | 22 + .../eck-stack/charts/eck-agent/values.yaml | 245 +++++++++++ .../charts/eck-apm-server/.helmignore | 24 ++ .../charts/eck-apm-server/Chart.yaml | 10 + .../eck-stack/charts/eck-apm-server/LICENSE | 93 +++++ .../jaeger-with-http-configuration.yaml | 29 ++ .../charts/eck-apm-server/templates/NOTES.txt | 6 + .../eck-apm-server/templates/_helpers.tpl | 51 +++ .../eck-apm-server/templates/apmserver.yaml | 53 +++ .../charts/eck-apm-server/values.yaml | 97 +++++ .../eck-stack/charts/eck-beats/.helmignore | 24 ++ .../eck-stack/charts/eck-beats/Chart.yaml | 10 + .../charts/eck-stack/charts/eck-beats/LICENSE | 93 +++++ .../eck-beats/examples/auditbeat_hosts.yaml | 110 +++++ .../examples/filebeat_no_autodiscover.yaml | 52 +++ .../examples/heartbeat_es_kb_health.yaml | 23 ++ .../eck-beats/examples/metricbeat_hosts.yaml | 158 +++++++ .../examples/packetbeat_dns_http.yaml | 37 ++ .../charts/eck-beats/templates/NOTES.txt | 6 + .../charts/eck-beats/templates/_helpers.tpl | 51 +++ .../charts/eck-beats/templates/beats.yaml | 75 ++++ .../templates/cluster-role-binding.yaml | 35 ++ .../eck-beats/templates/cluster-role.yaml | 22 + .../eck-beats/templates/service-account.yaml | 23 ++ .../eck-stack/charts/eck-beats/values.yaml | 169 ++++++++ .../charts/eck-elasticsearch/.helmignore | 24 ++ .../charts/eck-elasticsearch/Chart.yaml | 10 + .../charts/eck-elasticsearch/LICENSE | 93 +++++ .../examples/hot-warm-cold.yaml | 198 +++++++++ .../ingress/elasticsearch-ingress-aks.yaml | 26 ++ .../elasticsearch-ingress-eks-alb.yaml | 37 ++ .../elasticsearch-ingress-eks-nlb.yaml | 27 ++ .../ingress/elasticsearch-ingress-gke.yaml | 36 ++ .../eck-elasticsearch/templates/NOTES.txt | 6 + .../eck-elasticsearch/templates/_helpers.tpl | 51 +++ .../templates/elasticsearch.yaml | 74 ++++ .../eck-elasticsearch/templates/ingress.yaml | 48 +++ .../charts/eck-elasticsearch/values.yaml | 387 ++++++++++++++++++ .../charts/eck-enterprise-search/.helmignore | 24 ++ .../charts/eck-enterprise-search/Chart.yaml | 9 + .../examples/with-custom-configuration.yaml | 19 + .../templates/_helpers.tpl | 62 +++ .../templates/enterprisesearch.yaml | 62 +++ .../charts/eck-enterprise-search/values.yaml | 96 +++++ .../charts/eck-fleet-server/.helmignore | 24 ++ .../charts/eck-fleet-server/Chart.yaml | 11 + .../eck-stack/charts/eck-fleet-server/LICENSE | 93 +++++ .../examples/fleet-server.yaml | 17 + .../eck-fleet-server/templates/NOTES.txt | 6 + .../eck-fleet-server/templates/_helpers.tpl | 51 +++ .../templates/cluster-role-binding.yaml | 33 ++ .../templates/cluster-role.yaml | 22 + .../templates/fleet-server.yaml | 23 ++ .../templates/fleet-server.yaml.bak | 64 +++ .../templates/service-account.yaml | 22 + .../charts/eck-fleet-server/values.yaml | 129 ++++++ .../charts/eck-fleet-server/values.yaml.bak | 157 +++++++ .../eck-stack/charts/eck-kibana/.helmignore | 24 ++ .../eck-stack/charts/eck-kibana/Chart.yaml | 10 + .../eck-stack/charts/eck-kibana/LICENSE | 93 +++++ .../examples/http-configuration.yaml | 36 ++ .../examples/ingress/kibana-aks.yaml | 28 ++ .../examples/ingress/kibana-eks.yaml | 48 +++ .../examples/ingress/kibana-gke.yaml | 32 ++ .../charts/eck-kibana/templates/NOTES.txt | 6 + .../charts/eck-kibana/templates/_helpers.tpl | 51 +++ .../charts/eck-kibana/templates/ingress.yaml | 48 +++ .../charts/eck-kibana/templates/kibana.yaml | 61 +++ .../eck-stack/charts/eck-kibana/values.yaml | 179 ++++++++ .../eck-stack/charts/eck-logstash/.helmignore | 24 ++ .../eck-stack/charts/eck-logstash/Chart.yaml | 10 + .../eck-stack/charts/eck-logstash/LICENSE | 93 +++++ .../eck-logstash/examples/basic-eck.yaml | 44 ++ .../charts/eck-logstash/examples/es-role.yaml | 25 ++ .../eck-logstash/examples/monitored.yaml | 49 +++ .../charts/eck-logstash/examples/multi.yaml | 78 ++++ .../charts/eck-logstash/examples/volumes.yaml | 107 +++++ .../charts/eck-logstash/templates/NOTES.txt | 6 + .../eck-logstash/templates/_helpers.tpl | 51 +++ .../eck-logstash/templates/logstash.yaml | 58 +++ .../eck-stack/charts/eck-logstash/values.yaml | 115 ++++++ .../examples/agent/fleet-agents.yaml | 122 ++++++ .../eck-stack/examples/apm-server/basic.yaml | 52 +++ .../jaeger-with-http-configuration.yaml | 60 +++ .../examples/beats/metricbeat_hosts.yaml | 217 ++++++++++ .../examples/custom-elasticsearch-kibana.yaml | 78 ++++ .../examples/elasticsearch/hot-warm-cold.yaml | 199 +++++++++ .../ingress/elasticsearch-ingress-gke.yaml | 40 ++ .../examples/enterprise-search/basic.yaml | 42 ++ .../with-custom-configuration.yaml | 52 +++ .../examples/kibana/http-configuration.yaml | 23 ++ .../examples/kibana/ingress/kibana-gke.yaml | 82 ++++ .../examples/logstash/basic-eck.yaml | 114 ++++++ .../charts/eck-stack/templates/NOTES.txt | 10 + .../charts/eck-stack/templates/_helpers.tpl | 48 +++ .../charts/eck-stack/values.yaml | 50 +++ packs/elastic-stack-0.15.0/logo.png | Bin 0 -> 5810 bytes packs/elastic-stack-0.15.0/pack.json | 36 ++ packs/elastic-stack-0.15.0/presets.yaml | 260 ++++++++++++ packs/elastic-stack-0.15.0/values.yaml | 71 ++++ 117 files changed, 7041 insertions(+) create mode 100644 packs/elastic-stack-0.15.0/README.md create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack-0.15.0.tgz create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/.helmignore create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/Chart.lock create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/Chart.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/README.md create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/.helmignore create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/Chart.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/LICENSE create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/examples/fleet-agents.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/examples/system-integration.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/NOTES.txt create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/_helpers.tpl create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/cluster-role-binding.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/cluster-role.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/elastic-agent.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/elastic-agent.yaml.bak create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/service-account.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/values.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/.helmignore create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/Chart.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/LICENSE create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/examples/jaeger-with-http-configuration.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/templates/NOTES.txt create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/templates/_helpers.tpl create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/templates/apmserver.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/values.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/.helmignore create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/Chart.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/LICENSE create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/examples/auditbeat_hosts.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/examples/filebeat_no_autodiscover.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/examples/heartbeat_es_kb_health.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/examples/metricbeat_hosts.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/examples/packetbeat_dns_http.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/templates/NOTES.txt create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/templates/_helpers.tpl create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/templates/beats.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/templates/cluster-role-binding.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/templates/cluster-role.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/templates/service-account.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/values.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/.helmignore create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/Chart.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/LICENSE create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/examples/hot-warm-cold.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-aks.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-eks-alb.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-eks-nlb.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-gke.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/templates/NOTES.txt create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/templates/_helpers.tpl create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/templates/elasticsearch.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/templates/ingress.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/values.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-enterprise-search/.helmignore create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-enterprise-search/Chart.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-enterprise-search/examples/with-custom-configuration.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-enterprise-search/templates/_helpers.tpl create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-enterprise-search/templates/enterprisesearch.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-enterprise-search/values.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/.helmignore create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/Chart.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/LICENSE create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/examples/fleet-server.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/NOTES.txt create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/_helpers.tpl create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/cluster-role-binding.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/cluster-role.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/fleet-server.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/fleet-server.yaml.bak create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/service-account.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/values.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/values.yaml.bak create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/.helmignore create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/Chart.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/LICENSE create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/examples/http-configuration.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-aks.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-eks.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-gke.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/templates/NOTES.txt create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/templates/_helpers.tpl create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/templates/ingress.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/templates/kibana.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/values.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/.helmignore create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/Chart.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/LICENSE create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/examples/basic-eck.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/examples/es-role.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/examples/monitored.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/examples/multi.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/examples/volumes.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/templates/NOTES.txt create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/templates/_helpers.tpl create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/templates/logstash.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/values.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/examples/agent/fleet-agents.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/examples/apm-server/basic.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/examples/apm-server/jaeger-with-http-configuration.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/examples/beats/metricbeat_hosts.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/examples/custom-elasticsearch-kibana.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/examples/elasticsearch/hot-warm-cold.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/examples/elasticsearch/ingress/elasticsearch-ingress-gke.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/examples/enterprise-search/basic.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/examples/enterprise-search/with-custom-configuration.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/examples/kibana/http-configuration.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/examples/kibana/ingress/kibana-gke.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/examples/logstash/basic-eck.yaml create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/templates/NOTES.txt create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/templates/_helpers.tpl create mode 100644 packs/elastic-stack-0.15.0/charts/eck-stack/values.yaml create mode 100644 packs/elastic-stack-0.15.0/logo.png create mode 100644 packs/elastic-stack-0.15.0/pack.json create mode 100644 packs/elastic-stack-0.15.0/presets.yaml create mode 100644 packs/elastic-stack-0.15.0/values.yaml diff --git a/packs/elastic-stack-0.15.0/README.md b/packs/elastic-stack-0.15.0/README.md new file mode 100644 index 00000000..e14e757b --- /dev/null +++ b/packs/elastic-stack-0.15.0/README.md @@ -0,0 +1,63 @@ +# Elastic Cloud on Kubernetes (ECK) + +Elastic Cloud on Kubernetes automates the deployment, provisioning, management, and orchestration of Elasticsearch, Kibana, APM Server, Enterprise Search, Beats, Elastic Agent, Elastic Maps Server, and Logstash on Kubernetes based on the operator pattern. + +Current features: + +* Elasticsearch, Kibana, APM Server, Enterprise Search, and Beats deployments +* TLS Certificates management +* Safe Elasticsearch cluster configuration & topology changes +* Persistent volumes usage +* Custom node configuration and attributes +* Secure settings keystore updates + +Supported versions: + +* Kubernetes 1.25-1.29 +* Elasticsearch, Kibana, APM Server: 6.8+, 7.1+, 8+, 9+ +* Enterprise Search: 7.7+, 8+ +* Beats: 7.0+, 8+, 9+ +* Elastic Agent: 7.10+ (standalone), 7.14+, 8+ (Fleet), 9+ +* Elastic Maps Server: 7.11+, 8+ +* Logstash 8.7+, 9+ + +Check the [Quickstart](https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-quickstart.html) to deploy your first cluster with ECK. + +For general questions, please see the Elastic [forums](https://discuss.elastic.co/c/eck). + +# ECK-Stack + +ECK Stack is a Helm chart to assist in the deployment of Elastic Stack components, which are +managed by the [ECK Operator](https://www.elastic.co/guide/en/cloud-on-k8s/current/index.html) + +## Supported Elastic Stack Resources + +The following Elastic Stack resources are currently supported. + +- Elasticsearch +- Kibana +- Elastic Agent +- Fleet Server +- Beats +- Logstash +- APM Server + +Additional resources will be supported in future releases of this Helm Chart. + +## Prerequisites + +- Kubernetes 1.27+ +- Elastic ECK Operator + +## Configuration + +The following table lists the configurable parameters of the eck-stack chart and their default values. + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `eck-elasticsearch.enabled` | If `true`, create an Elasticsearch resource (using the eck-elasticsearch Chart) | `true` | +| `eck-kibana.enabled` | If `true`, create a Kibana resource (using the eck-kibana Chart) | `true` | +| `eck-agent.enabled` | If `true`, create an Elastic Agent resource (using the eck-agent Chart) | `false` | +| `eck-fleet-server.enabled` | If `true`, create a Fleet Server resource (using the eck-fleet-server Chart) | `false` | +| `eck-logstash.enabled` | If `true`, create a Logstash resource (using the eck-logstash Chart) | `false` | +| `eck-apm-server.enabled` | If `true`, create a standalone Elastic APM Server resource (using the eck-apm-server Chart) | `false` | diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack-0.15.0.tgz b/packs/elastic-stack-0.15.0/charts/eck-stack-0.15.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..0a422b628f2e5653b218b2f82a362e314e5d1f4a GIT binary patch literal 44500 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%0A*{; z&UzH${h2mE<L|g_4C7+%klcq)bGhrdC(E0A=p$Jnh0Sjg z>#e4kPLl-mL<9bv4fsY=Y6h&?ypb6IH6@=3y&Fu;SS|N(O#n42Q}8cq9CF{rt(I$2 zU&hg#BsOcT>*)U&OfhV+9W4bK{~3GMP{~?5dZRa}oCYnvet%=NTzU8N@KApQT|N-J zr&j4%Tg#C z@?hgX3Vj6}i7Xt;h(qBo(V<8tk>K?39<=gSp}A&I=&72q;^b`)=($ z1Sg)M+3NXQP=e5Eq z@iSaBwy-VC^&A&91fmupO^pWOzYiw?RT@Ao$(4P6w$~&C@59iby8rj1FsR8EG#u#v zkyMX14rp;>G+VqObjQhoV_5?U3exWh6X)h+al8qywXy;oVob2vG3D=s#cmai13!T3%5f`5dZasme6xZ#4eHVfYPbJe)V& woB(cTV~6)?jR?71u>hN%VH$(I5@%;lEoUFBB@hxA7ziXkV~qr+3<>tX0Ljbhvj6}9 literal 0 HcmV?d00001 diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/.helmignore b/packs/elastic-stack-0.15.0/charts/eck-stack/.helmignore new file mode 100644 index 00000000..9e40bf01 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/.helmignore @@ -0,0 +1,25 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests +charts/*/templates/tests \ No newline at end of file diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/Chart.lock b/packs/elastic-stack-0.15.0/charts/eck-stack/Chart.lock new file mode 100644 index 00000000..93ab1387 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/Chart.lock @@ -0,0 +1,27 @@ +dependencies: +- name: eck-elasticsearch + repository: "" + version: 0.15.0 +- name: eck-kibana + repository: "" + version: 0.15.0 +- name: eck-agent + repository: "" + version: 0.15.0 +- name: eck-fleet-server + repository: "" + version: 0.15.0 +- name: eck-beats + repository: "" + version: 0.15.0 +- name: eck-logstash + repository: "" + version: 0.15.0 +- name: eck-apm-server + repository: "" + version: 0.15.0 +- name: eck-enterprise-search + repository: "" + version: 0.15.0 +digest: sha256:e3edcb01dcac7f46ad7790ce69d59578cff5571e88997f53752728c37f60668d +generated: "2025-04-15T13:08:24.212207004Z" diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/Chart.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/Chart.yaml new file mode 100644 index 00000000..58306d2d --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/Chart.yaml @@ -0,0 +1,39 @@ +apiVersion: v2 +dependencies: +- condition: eck-elasticsearch.enabled + name: eck-elasticsearch + repository: "" + version: 0.15.0 +- condition: eck-kibana.enabled + name: eck-kibana + repository: "" + version: 0.15.0 +- condition: eck-agent.enabled + name: eck-agent + repository: "" + version: 0.15.0 +- condition: eck-fleet-server.enabled + name: eck-fleet-server + repository: "" + version: 0.15.0 +- condition: eck-beats.enabled + name: eck-beats + repository: "" + version: 0.15.0 +- condition: eck-logstash.enabled + name: eck-logstash + repository: "" + version: 0.15.0 +- condition: eck-apm-server.enabled + name: eck-apm-server + repository: "" + version: 0.15.0 +- condition: eck-enterprise-search.enabled + name: eck-enterprise-search + repository: "" + version: 0.15.0 +description: Elastic Stack managed by the ECK Operator +kubeVersion: '>= 1.21.0-0' +name: eck-stack +type: application +version: 0.15.0 diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/README.md b/packs/elastic-stack-0.15.0/charts/eck-stack/README.md new file mode 100644 index 00000000..f301bd12 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/README.md @@ -0,0 +1,93 @@ +# ECK-Stack + +ECK Stack is a Helm chart to assist in the deployment of Elastic Stack components, which are +managed by the [ECK Operator](https://www.elastic.co/guide/en/cloud-on-k8s/current/index.html) + +## Supported Elastic Stack Resources + +The following Elastic Stack resources are currently supported. + +- Elasticsearch +- Kibana +- Elastic Agent +- Fleet Server +- Beats +- Logstash +- APM Server + +Additional resources will be supported in future releases of this Helm Chart. + +## Prerequisites + +- Kubernetes 1.21+ +- Elastic ECK Operator + +## Installing the Chart + +### Installing the ECK Operator + +Before using this chart, the Elastic ECK Operator is required to be installed within the Kubernetes cluster. +Full installation instructions can be found within [our documentation](https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-installing-eck.html) + +To install the ECK Operator using Helm. + +```sh +# Add the Elastic Helm Repository +helm repo add elastic https://helm.elastic.co && helm repo update + +# Install the ECK Operator cluster-wide +helm install elastic-operator elastic/eck-operator -n elastic-system --create-namespace +``` + +Additional ECK Operator Helm installation options can be found within [our documentation](https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-install-helm.html) + +### Installing the ECK Stack Chart + +The following will install the ECK-Stack chart using the default values, which will deploy an Elasticsearch [Quickstart Cluster](https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-deploy-elasticsearch.html), and a Kibana [Quickstart Instance](https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-deploy-kibana.html) + +```sh +# Add the Elastic Helm Repository +helm repo add elastic https://helm.elastic.co && helm repo update + +# Install the ECK-Stack helm chart +# This will setup a 'quickstart' Elasticsearch and Kibana resource in the 'elastic-stack' namespace +helm install my-release elastic/eck-stack -n elastic-stack --create-namespace +``` + +More information on the different ways to use the ECK Stack chart to deploy Elastic Stack resources +can be found in [our documentation](https://www.elastic.co/guide/en/cloud-on-k8s/current/index.html). + +## Uninstalling the Chart + +To uninstall/delete the `my-release` deployment from the 'elastic-stack' namespace: + +```console +helm delete my-release -n elastic-stack +``` + +The command removes all the Elastic Stack resources associated with the chart and deletes the release. + +## Configuration + +The following table lists the configurable parameters of the eck-stack chart and their default values. + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `eck-elasticsearch.enabled` | If `true`, create an Elasticsearch resource (using the eck-elasticsearch Chart) | `true` | +| `eck-kibana.enabled` | If `true`, create a Kibana resource (using the eck-kibana Chart) | `true` | +| `eck-agent.enabled` | If `true`, create an Elastic Agent resource (using the eck-agent Chart) | `false` | +| `eck-fleet-server.enabled` | If `true`, create a Fleet Server resource (using the eck-fleet-server Chart) | `false` | +| `eck-logstash.enabled` | If `true`, create a Logstash resource (using the eck-logstash Chart) | `false` | +| `eck-apm-server.enabled` | If `true`, create a standalone Elastic APM Server resource (using the eck-apm-server Chart) | `false` | + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. + +Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example, + +```console +helm install my-release -f values.yaml . +``` + +## Contributing + +This chart is maintained at [github.com/elastic/cloud-on-k8s](https://github.com/elastic/cloud-on-k8s/tree/main/deploy/eck-stack). diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/.helmignore b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/.helmignore new file mode 100644 index 00000000..f1568daf --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/Chart.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/Chart.yaml new file mode 100644 index 00000000..60b138b2 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/Chart.yaml @@ -0,0 +1,10 @@ +apiVersion: v2 +description: Elastic Agent managed by the ECK operator +icon: https://images.contentstack.io/v3/assets/bltefdd0b53724fa2ce/blt77c2da6e0198746e/620ac24e6662ca0a6f617114/icon-agent-32-color.svg +kubeVersion: '>= 1.21.0-0' +name: eck-agent +sources: +- https://github.com/elastic/cloud-on-k8s +- https://github.com/elastic/elastic-agent +type: application +version: 0.15.0 diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/LICENSE b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/LICENSE new file mode 100644 index 00000000..92503a72 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/LICENSE @@ -0,0 +1,93 @@ +Elastic License 2.0 + +URL: https://www.elastic.co/licensing/elastic-license + +## Acceptance + +By using the software, you agree to all of the terms and conditions below. + +## Copyright License + +The licensor grants you a non-exclusive, royalty-free, worldwide, +non-sublicensable, non-transferable license to use, copy, distribute, make +available, and prepare derivative works of the software, in each case subject to +the limitations and conditions below. + +## Limitations + +You may not provide the software to third parties as a hosted or managed +service, where the service provides users with access to any substantial set of +the features or functionality of the software. + +You may not move, change, disable, or circumvent the license key functionality +in the software, and you may not remove or obscure any functionality in the +software that is protected by the license key. + +You may not alter, remove, or obscure any licensing, copyright, or other notices +of the licensor in the software. Any use of the licensor’s trademarks is subject +to applicable law. + +## Patents + +The licensor grants you a license, under any patent claims the licensor can +license, or becomes able to license, to make, have made, use, sell, offer for +sale, import and have imported the software, in each case subject to the +limitations and conditions in this license. This license does not cover any +patent claims that you cause to be infringed by modifications or additions to +the software. If you or your company make any written claim that the software +infringes or contributes to infringement of any patent, your patent license for +the software granted under these terms ends immediately. If your company makes +such a claim, your patent license ends immediately for work on behalf of your +company. + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you +also gets a copy of these terms. + +If you modify the software, you must include in any modified copies of the +software prominent notices stating that you have modified the software. + +## No Other Rights + +These terms do not imply any licenses other than those expressly granted in +these terms. + +## Termination + +If you use the software in violation of these terms, such use is not licensed, +and your licenses will automatically terminate. If the licensor provides you +with a notice of your violation, and you cease all violation of this license no +later than 30 days after you receive that notice, your licenses will be +reinstated retroactively. However, if you violate these terms after such +reinstatement, any additional violation of these terms will cause your licenses +to terminate automatically and permanently. + +## No Liability + +*As far as the law allows, the software comes as is, without any warranty or +condition, and the licensor will not be liable to you for any damages arising +out of these terms or the use or nature of the software, under any kind of +legal claim.* + +## Definitions + +The **licensor** is the entity offering these terms, and the **software** is the +software the licensor makes available under these terms, including any portion +of it. + +**you** refers to the individual or entity agreeing to these terms. + +**your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control over, +are under the control of, or are under common control with that +organization. **control** means ownership of substantially all the assets of an +entity, or the power to direct its management and policies by vote, contract, or +otherwise. Control can be direct or indirect. + +**your licenses** are all the licenses granted to you for the software under +these terms. + +**use** means anything you do with the software requiring one of your licenses. + +**trademark** means trademarks, service marks, and similar rights. \ No newline at end of file diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/examples/fleet-agents.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/examples/fleet-agents.yaml new file mode 100644 index 00000000..dcd425df --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/examples/fleet-agents.yaml @@ -0,0 +1,24 @@ +# The following example should only be used in conjunction with the 'eck-fleet-server' Helm Chart, +# and shows how the Agents can be deployed as a daemonset, and controlled by Fleet Server. +# +version: 9.0.0 + +# This must match the name of an Agent policy. +policyID: eck-agent +# This must match the name of the fleet server installed from eck-fleet-server chart. +fleetServerRef: + name: eck-fleet-server +kibanaRef: + name: eck-kibana +mode: fleet +# elasticsearchRefs must be empty when fleet mode is enabled. +elasticsearchRefs: [] +daemonSet: + podTemplate: + spec: + serviceAccountName: elastic-agent + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + automountServiceAccountToken: true + securityContext: + runAsUser: 0 diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/examples/system-integration.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/examples/system-integration.yaml new file mode 100644 index 00000000..d622c5da --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/examples/system-integration.yaml @@ -0,0 +1,133 @@ +# The following example should only be used in Agent "standalone" mode, +# and should not be used when Agent is used with Fleet Server. +# +version: 9.0.0 +elasticsearchRefs: +- name: eck-elasticsearch +daemonSet: + podTemplate: + spec: + containers: + - name: agent + securityContext: + runAsUser: 0 + volumeMounts: + - name: agent-data + mountPath: /usr/share/elastic-agent/data/elastic-agent-08e204/run +config: + id: 488e0b80-3634-11eb-8208-57893829af4e + revision: 2 + agent: + monitoring: + enabled: true + use_output: default + logs: true + metrics: true + inputs: + - id: 4917ade0-3634-11eb-8208-57893829af4e + name: system-1 + revision: 1 + type: system/metrics + use_output: default + meta: + package: + name: system + version: 9.0.0 + data_stream: + namespace: default + streams: + - id: system/metrics-system.cpu + data_stream: + dataset: system.cpu + type: metrics + metricsets: + - cpu + cpu.metrics: + - percentages + - normalized_percentages + period: 10s + - id: system/metrics-system.diskio + data_stream: + dataset: system.diskio + type: metrics + metricsets: + - diskio + diskio.include_devices: null + period: 10s + - id: system/metrics-system.filesystem + data_stream: + dataset: system.filesystem + type: metrics + metricsets: + - filesystem + period: 1m + processors: + - drop_event.when.regexp: + system.filesystem.mount_point: ^/(sys|cgroup|proc|dev|etc|host|lib|snap)($|/) + - id: system/metrics-system.fsstat + data_stream: + dataset: system.fsstat + type: metrics + metricsets: + - fsstat + period: 1m + processors: + - drop_event.when.regexp: + system.fsstat.mount_point: ^/(sys|cgroup|proc|dev|etc|host|lib|snap)($|/) + - id: system/metrics-system.load + data_stream: + dataset: system.load + type: metrics + metricsets: + - load + period: 10s + - id: system/metrics-system.memory + data_stream: + dataset: system.memory + type: metrics + metricsets: + - memory + period: 10s + - id: system/metrics-system.network + data_stream: + dataset: system.network + type: metrics + metricsets: + - network + period: 10s + network.interfaces: null + - id: system/metrics-system.process + data_stream: + dataset: system.process + type: metrics + metricsets: + - process + period: 10s + process.include_top_n.by_cpu: 5 + process.include_top_n.by_memory: 5 + process.cmdline.cache.enabled: true + process.cgroups.enabled: false + process.include_cpu_ticks: false + processes: + - .* + - id: system/metrics-system.process_summary + data_stream: + dataset: system.process_summary + type: metrics + metricsets: + - process_summary + period: 10s + - id: system/metrics-system.socket_summary + data_stream: + dataset: system.socket_summary + type: metrics + metricsets: + - socket_summary + period: 10s + - id: system/metrics-system.uptime + data_stream: + dataset: system.uptime + type: metrics + metricsets: + - uptime + period: 10s diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/NOTES.txt b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/NOTES.txt new file mode 100644 index 00000000..cfd41883 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/NOTES.txt @@ -0,0 +1,6 @@ + +1. Check Elastic Agent status + $ kubectl get agent {{ include "elasticagent.fullname" . }} -n {{ .Release.Namespace }} + +2. Check Elastic Agent pod status + $ kubectl get pods --namespace={{ .Release.Namespace }} -l agent.k8s.elastic.co/name={{ include "elasticagent.fullname" . }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/_helpers.tpl b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/_helpers.tpl new file mode 100644 index 00000000..748ca7dd --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "elasticagent.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "elasticagent.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "elasticagent.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "elasticagent.labels" -}} +helm.sh/chart: {{ include "elasticagent.chart" . }} +{{ include "elasticagent.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.labels }} +{{ toYaml .Values.labels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "elasticagent.selectorLabels" -}} +app.kubernetes.io/name: {{ include "elasticagent.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/cluster-role-binding.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/cluster-role-binding.yaml new file mode 100644 index 00000000..762a59dc --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/cluster-role-binding.yaml @@ -0,0 +1,33 @@ +{{- with .Values.clusterRoleBinding }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .name }} + labels: + {{- include "elasticagent.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or $.Values.annotations .annotations }} + annotations: + {{- with $.Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +{{- with .subjects }} +subjects: +{{- range . }} + - kind: {{ .kind }} + name: {{ .name }} + namespace: {{ .namespace | default $.Release.Namespace | quote }} +{{- end }} +{{- end }} +roleRef: + kind: {{ .roleRef.kind }} + name: {{ .roleRef.name }} + apiGroup: {{ .roleRef.apiGroup }} +{{- end }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/cluster-role.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/cluster-role.yaml new file mode 100644 index 00000000..5d97ec7a --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/cluster-role.yaml @@ -0,0 +1,22 @@ +{{- with .Values.clusterRole }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ .name }} + labels: + {{- include "elasticagent.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or $.Values.annotations .annotations }} + annotations: + {{- with $.Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +rules: {{- toYaml .rules | nindent 2 }} +{{- end }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/elastic-agent.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/elastic-agent.yaml new file mode 100644 index 00000000..cb87484e --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/elastic-agent.yaml @@ -0,0 +1,18 @@ +--- +apiVersion: agent.k8s.elastic.co/v1alpha1 +kind: Agent +metadata: + name: {{ include "elasticagent.fullname" . }} + labels: + {{- include "elasticagent.labels" $ | nindent 4 }} + annotations: + eck.k8s.elastic.co/license: basic + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + version: {{ required "An Elastic Agent version is required" .Values.version }} + {{- if and (not (hasKey .Values.spec "daemonSet")) (not (hasKey .Values.spec "deployment")) (not (hasKey .Values.spec "statefulSet")) }} + {{ fail "At least one of daemonSet or deployment or statefulSet is required" }} + {{- end }} + {{- toYaml .Values.spec | nindent 2 }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/elastic-agent.yaml.bak b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/elastic-agent.yaml.bak new file mode 100644 index 00000000..9017e5bb --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/elastic-agent.yaml.bak @@ -0,0 +1,89 @@ +--- +apiVersion: agent.k8s.elastic.co/v1alpha1 +kind: Agent +metadata: + name: {{ include "elasticagent.fullname" . }} + labels: + {{- include "elasticagent.labels" $ | nindent 4 }} + annotations: + eck.k8s.elastic.co/license: basic + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + version: {{ required "An Elastic Agent version is required" (or ((.Values.spec).version) (.Values.version)) }} + {{- $daemonSet := (or (hasKey (.Values.spec) "daemonSet") (hasKey .Values "daemonSet")) }} + {{- $deployment := (or (hasKey (.Values.spec) "deployment") (hasKey .Values "deployment")) }} + {{- $statefulSet := (or (hasKey (.Values.spec) "statefulSet") (hasKey .Values "statefulSet")) }} + {{- if and (not $daemonSet) (not $deployment) (not $statefulSet) }} + {{ fail "At least one of daemonSet, deployment or statefulSet is required" }} + {{- end }} + {{- if $daemonSet }} + {{- $ds := or ((.Values.spec).daemonSet) (.Values.daemonSet) }} + daemonSet: + {{- /* This is required to render the empty daemonset ( {} ) properly */}} + {{- $ds | default dict | toYaml | nindent 4 }} + {{- end }} + {{- if $deployment }} + {{- $deploy := or ((.Values.spec).deployment) (.Values.deployment) }} + deployment: + {{- /* This is required to render the empty deployment ( {} ) properly */}} + {{- $deploy | default dict | toYaml | nindent 4 }} + {{- end }} + {{- if $statefulSet }} + {{- $sts := or ((.Values.spec).statefulSet) (.Values.statefulSet) }} + statefulSet: + {{- /* This is required to render the empty statefulSet ( {} ) properly */}} + {{- $sts | default dict | toYaml | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).image) (.Values.image) }} + image: {{ . }} + {{- end }} + {{- with or ((.Values.spec).elasticsearchRefs) (.Values.elasticsearchRefs) }} + elasticsearchRefs: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).kibanaRef) (.Values.kibanaRef) }} + kibanaRef: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).fleetServerRef) (.Values.fleetServerRef) }} + fleetServerRef: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- $config := or ((.Values.spec).config) (.Values.config) }} + {{- $configRef := or ((.Values.spec).configRef) (.Values.configRef) }} + {{- if and $config $configRef }} + {{ fail "Only one of config and configRef can be specified" }} + {{- end }} + {{- with $config }} + config: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $configRef }} + configRef: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).mode) (.Values.mode) }} + mode: {{ . }} + {{- end }} + {{- with or ((.Values.spec).fleetServerEnabled) (.Values.fleetServerEnabled) }} + fleetServerEnabled: {{ . }} + {{- end }} + {{- with or ((.Values.spec).http) (.Values.http) }} + http: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).policyID) (.Values.policyID) }} + policyID: {{ . }} + {{- end }} + {{- with or ((.Values.spec).secureSettings) (.Values.secureSettings) }} + secureSettings: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).revisionHistoryLimit) (.Values.revisionHistoryLimit) }} + revisionHistoryLimit: {{ . }} + {{- end }} + {{- with or (((.Values.spec).serviceAccount).name) ((.Values.serviceAccount).name) }} + serviceAccountName: {{ . }} + {{- end }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/service-account.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/service-account.yaml new file mode 100644 index 00000000..e8bdf0b5 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/templates/service-account.yaml @@ -0,0 +1,22 @@ +{{- with .Values.serviceAccount }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .name }} + namespace: {{ .namespace | default $.Release.Namespace | quote }} + labels: + {{- include "elasticagent.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or $.Values.annotations .annotations }} + annotations: + {{- with $.Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/values.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/values.yaml new file mode 100644 index 00000000..f9803cb7 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-agent/values.yaml @@ -0,0 +1,245 @@ +--- +# Default values for eck-agent. +# This is a YAML-formatted file. + +# Overridable names of the Elastic Agent resource. +# By default, this is the Release name set for the chart, +# followed by 'eck-agent'. +# +# nameOverride will override the name of the Chart with the name set here, +# so nameOverride: quickstart, would convert to '{{ Release.name }}-quickstart' +# +# nameOverride: "quickstart" +# +# fullnameOverride will override both the release name, and the chart name, +# and will name the Fleet Agent resource exactly as specified. +# +# fullnameOverride: "quickstart" + +# Version of Elastic Agent. +# +version: 9.0.0 + +# Labels that will be applied to Elastic Agent. +# +labels: {} + +# Annotations that will be applied to Elastic Agent. +# +annotations: {} + +# Elastic Agent image to deploy. +# +# image: docker.elastic.co/beats/elastic-agent:9.0.0 + +# ** Deprecation Notice ** +# The previous versions of this Helm Chart simply used the `spec` field here +# and allowed the user to specify any fields below `spec` that were templated directly +# into the final Kibana manifest. This is no longer the preferred way to specify these +# fields and each field that is supported underneath `spec` is now directly specified +# in this values file. Currently both patterns are supported for backwards compatibility +# but we plan to remove the `spec` field in the future. +# spec: {} + +# Referenced resources are below and depending on the setup, at least one is required for a functional Agent. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-setting-referenced-resources +# +# Reference to ECK-managed Kibana instance. +# +# kibanaRef: +# name: quickstart + # Optional namespace reference to Kibana instance. + # If not specified, then the namespace of the Agent instance + # will be assumed. + # + # namespace: default + +# Reference to ECK-managed Elasticsearch instance. +# +elasticsearchRefs: +- name: eck-elasticsearch + # Optional namespace reference to Elasticsearch instance. + # If not specified, then the namespace of the Agent instance + # will be assumed. + # + # namespace: default + +# Reference to ECK-managed Fleet Server instance. +# +# fleetServerRef: +# name: eck-fleet-server + # Optional namespace reference to Fleet Server instance. + # If not specified, then the namespace of the Agent instance + # will be assumed. + # + # namespace: default + +# The Elastic Agent configuration, the ECK equivalent to agent.yml +# NOTE: The `config` and `configRef` fields are mutually exclusive. Only one of them should be defined at a time, +# as using both may cause conflicts. +# +# Configuration of Agent, specifically used in Agent standalone mode. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-configuration.html +# +config: null + +# Reference a configuration in a Secret. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-configuration.html +# +# configRef: +# secretName: "" + +# The mode of Agent to use. Only set to "fleet" when Fleet Server is enabled. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-fleet-mode-and-fleet-server +# +# mode: "fleet" + +# fleetServerEnabled determines whether the Agent will be run as the Fleet Server. +# +# NOTE: Both `mode: fleet` and `fleetServerEnabled: true` need to be set for Fleet Server to be enabled. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-fleet-mode-and-fleet-server +# +fleetServerEnabled: false + +# The HTTP layer configuration for the Fleet Server Service. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-customize-fleet-server-service +# +# http: + +# policyID determines into which Agent Policy this Agent will be enrolled. +# policyID: eck-agent + +# DaemonSet, StatefulSet, or Deployment specification for Agent. +# At least one is required of [daemonSet, deployment, statefulSet]. +# No default is currently set, refer to https://github.com/elastic/cloud-on-k8s/issues/7429. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-chose-the-deployment-model +# +# deployment: +# podTemplate: +# spec: +# containers: +# - name: agent +# securityContext: +# runAsUser: 0 +# daemonSet: +# podTemplate: +# spec: +# containers: +# - name: agent +# securityContext: +# runAsUser: 0 +# statefulSet: +# podTemplate: +# spec: +# containers: +# - name: agent +# securityContext: +# runAsUser: 0 + +# SecureSettings is a list of references to Kubernetes Secrets containing sensitive configuration options for Elastic Agent. +secureSettings: [] +# - secretName: my-secret-with-secure-settings + +# Number of revisions to retain to allow rollback in the underlying Deployment. +# If not set Kubernetes sets this to 10 by default. +# +# revisionHistoryLimit: 2 + +# ServiceAccount to be used by Elastic Agent. Some Elastic Agent features, such as the Kubernetes integration, +# require that Agent Pods interact with Kubernetes APIs. This functionality requires specific permissions +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-role-based-access-control +# +serviceAccount: + name: elastic-agent + # { .Release.Namespace } is used here by default, but can be specified. + # namespace: optional-namespace + +# ClusterRoleBinding to be used by Elastic Agent. Similar to ServiceAccount, this is required in some scenarios. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-role-based-access-control +# +clusterRoleBinding: + name: elastic-agent + subjects: + - kind: ServiceAccount + name: elastic-agent + # { .Release.Namespace } is used here by default, but can be specified. + # namespace: default + roleRef: + kind: ClusterRole + name: elastic-agent + apiGroup: rbac.authorization.k8s.io + +# ClusterRole to be used by Elastic Agent. Similar to ServiceAccount, this is required in some scenarios. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-role-based-access-control +# +clusterRole: + name: elastic-agent + rules: + - apiGroups: [""] + resources: + - pods + - nodes + - namespaces + - events + - services + - configmaps + verbs: + - get + - watch + - list + - apiGroups: ["coordination.k8s.io"] + resources: + - leases + verbs: + - get + - create + - update + - nonResourceURLs: + - "/metrics" + verbs: + - get + - apiGroups: ["extensions"] + resources: + - replicasets + verbs: + - "get" + - "list" + - "watch" + - apiGroups: + - "apps" + resources: + - statefulsets + - deployments + - replicasets + - daemonsets + verbs: + - "get" + - "list" + - "watch" + - apiGroups: + - "" + resources: + - nodes/stats + verbs: + - get + - nonResourceURLs: + - "/metrics" + verbs: + - get + - apiGroups: + - "batch" + resources: + - jobs + - cronjobs + verbs: + - "get" + - "list" + - "watch" + - apiGroups: + - "storage.k8s.io" + resources: + - storageclasses + verbs: + - "get" + - "list" + - "watch" diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/.helmignore b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/.helmignore new file mode 100644 index 00000000..f1568daf --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/Chart.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/Chart.yaml new file mode 100644 index 00000000..a7809bb2 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/Chart.yaml @@ -0,0 +1,10 @@ +apiVersion: v2 +description: Elastic APM Server managed by the ECK operator +icon: https://helm.elastic.co/icons/apm.png +kubeVersion: '>= 1.21.0-0' +name: eck-apm-server +sources: +- https://github.com/elastic/cloud-on-k8s +- https://github.com/elastic/apm-server +type: application +version: 0.15.0 diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/LICENSE b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/LICENSE new file mode 100644 index 00000000..92503a72 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/LICENSE @@ -0,0 +1,93 @@ +Elastic License 2.0 + +URL: https://www.elastic.co/licensing/elastic-license + +## Acceptance + +By using the software, you agree to all of the terms and conditions below. + +## Copyright License + +The licensor grants you a non-exclusive, royalty-free, worldwide, +non-sublicensable, non-transferable license to use, copy, distribute, make +available, and prepare derivative works of the software, in each case subject to +the limitations and conditions below. + +## Limitations + +You may not provide the software to third parties as a hosted or managed +service, where the service provides users with access to any substantial set of +the features or functionality of the software. + +You may not move, change, disable, or circumvent the license key functionality +in the software, and you may not remove or obscure any functionality in the +software that is protected by the license key. + +You may not alter, remove, or obscure any licensing, copyright, or other notices +of the licensor in the software. Any use of the licensor’s trademarks is subject +to applicable law. + +## Patents + +The licensor grants you a license, under any patent claims the licensor can +license, or becomes able to license, to make, have made, use, sell, offer for +sale, import and have imported the software, in each case subject to the +limitations and conditions in this license. This license does not cover any +patent claims that you cause to be infringed by modifications or additions to +the software. If you or your company make any written claim that the software +infringes or contributes to infringement of any patent, your patent license for +the software granted under these terms ends immediately. If your company makes +such a claim, your patent license ends immediately for work on behalf of your +company. + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you +also gets a copy of these terms. + +If you modify the software, you must include in any modified copies of the +software prominent notices stating that you have modified the software. + +## No Other Rights + +These terms do not imply any licenses other than those expressly granted in +these terms. + +## Termination + +If you use the software in violation of these terms, such use is not licensed, +and your licenses will automatically terminate. If the licensor provides you +with a notice of your violation, and you cease all violation of this license no +later than 30 days after you receive that notice, your licenses will be +reinstated retroactively. However, if you violate these terms after such +reinstatement, any additional violation of these terms will cause your licenses +to terminate automatically and permanently. + +## No Liability + +*As far as the law allows, the software comes as is, without any warranty or +condition, and the licensor will not be liable to you for any damages arising +out of these terms or the use or nature of the software, under any kind of +legal claim.* + +## Definitions + +The **licensor** is the entity offering these terms, and the **software** is the +software the licensor makes available under these terms, including any portion +of it. + +**you** refers to the individual or entity agreeing to these terms. + +**your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control over, +are under the control of, or are under common control with that +organization. **control** means ownership of substantially all the assets of an +entity, or the power to direct its management and policies by vote, contract, or +otherwise. Control can be direct or indirect. + +**your licenses** are all the licenses granted to you for the software under +these terms. + +**use** means anything you do with the software requiring one of your licenses. + +**trademark** means trademarks, service marks, and similar rights. \ No newline at end of file diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/examples/jaeger-with-http-configuration.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/examples/jaeger-with-http-configuration.yaml new file mode 100644 index 00000000..fc9271f6 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/examples/jaeger-with-http-configuration.yaml @@ -0,0 +1,29 @@ +--- +# Version of APM Server. +# +version: 9.0.0 + +# Count of APM Server replicas to create. +# +count: 1 + +config: + name: elastic-apm + apm-server.jaeger.grpc.enabled: true + apm-server.jaeger.grpc.host: "0.0.0.0:14250" + +# Reference to ECK-managed Elasticsearch resource. +# +elasticsearchRef: + name: eck-elasticsearch +http: + service: + spec: + ports: + - name: http + port: 8200 + targetPort: 8200 + - name: grpc + port: 14250 + targetPort: 14250 + diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/templates/NOTES.txt b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/templates/NOTES.txt new file mode 100644 index 00000000..42ab52cb --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/templates/NOTES.txt @@ -0,0 +1,6 @@ + +1. Check APM Server status + $ kubectl get apmserver {{ include "apm-server.fullname" . }} -n {{ .Release.Namespace }} + +2. Check APM Server pod status + $ kubectl get pods --namespace={{ .Release.Namespace }} -l apm.k8s.elastic.co/name={{ include "apm-server.fullname" . }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/templates/_helpers.tpl b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/templates/_helpers.tpl new file mode 100644 index 00000000..d06ca3f4 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "apm-server.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "apm-server.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "apm-server.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "apm-server.labels" -}} +helm.sh/chart: {{ include "apm-server.chart" . }} +{{ include "apm-server.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.labels }} +{{ toYaml .Values.labels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "apm-server.selectorLabels" -}} +app.kubernetes.io/name: {{ include "apm-server.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/templates/apmserver.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/templates/apmserver.yaml new file mode 100644 index 00000000..f3dd5ba9 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/templates/apmserver.yaml @@ -0,0 +1,53 @@ +--- +apiVersion: apm.k8s.elastic.co/v1 +kind: ApmServer +metadata: + name: {{ include "apm-server.fullname" . }} + labels: + {{- include "apm-server.labels" . | nindent 4 }} + annotations: + eck.k8s.elastic.co/license: basic + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + version: {{ required "An APM Server version is required" .Values.version }} + count: {{ required "A pod count is required" .Values.count }} + {{- with .Values.image }} + image: {{ . }} + {{- end }} + {{- with .Values.serviceAccountName }} + serviceAccountName: {{ . }} + {{- end }} + {{- with .Values.revisionHistoryLimit }} + revisionHistoryLimit: {{ . }} + {{- end }} + + {{- with .Values.config }} + config: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.http }} + http: + {{- toYaml . | nindent 4 }} + {{- end }} + + {{- with .Values.elasticsearchRef }} + elasticsearchRef: + {{- toYaml . | nindent 4 }} + {{- end }} + + {{- with .Values.kibanaRef }} + kibanaRef: + {{- toYaml . | nindent 4 }} + {{- end }} + + {{- with .Values.podTemplate }} + podTemplate: + {{- toYaml . | nindent 4 }} + {{- end }} + + {{- with .Values.secureSettings }} + secureSettings: + {{- toYaml . | nindent 2 }} + {{- end }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/values.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/values.yaml new file mode 100644 index 00000000..7909214f --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-apm-server/values.yaml @@ -0,0 +1,97 @@ +--- +# Default values for eck-apm-server. +# This is a YAML-formatted file. + +# Overridable names of the APM Server resource. +# By default, this is the Release name set for the chart, +# followed by 'eck-apm-server'. +# +# nameOverride will override the name of the Chart with the name set here, +# so nameOverride: quickstart, would convert to '{{ Release.name }}-quickstart' +# +# nameOverride: "quickstart" +# +# fullnameOverride will override both the release name, and the chart name, +# and will name the APM Server resource exactly as specified. +# +# fullnameOverride: "quickstart" + +# Version of APM Server. +# +version: 9.0.0 + +# APM Server Docker image to deploy +# +# image: + +# Used to check access from the current resource to a resource (for ex. a remote Elasticsearch cluster) in a different namespace. +# Can only be used if ECK is enforcing RBAC on references. +# +# serviceAccountName: "" + +# Labels that will be applied to APM Server. +# +labels: {} + +# Annotations that will be applied to APM Server. +# +annotations: {} + +# Count of APM Server replicas to create. +# +count: 1 + +# The APM Server configuration, the ECK equivalent to apm-server.yml +# ref: https://www.elastic.co/guide/en/apm/server/current/configuring-howto-apm-server.html +# +config: {} + +# Settings to control how APM Server will be accessed. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-accessing-elastic-services.html +# +http: {} + # service: + # metadata: + # labels: + # my-custom: label + # spec: + # ports: + # - name: http + # port: 8200 + # targetPort: 8200 + +# Reference to ECK-managed Elasticsearch resource. +# +elasticsearchRef: {} + # name: eck-elasticsearch + # Optional namespace reference to Elasticsearch resource. + # If not specified, then the namespace of the APM Server resource + # will be assumed. + # + # namespace: default + +# Optional reference to ECK-managed Kibana resource which allows ECK to +# automatically configure the Kibana endpoint as described in +# https://www.elastic.co/guide/en/apm/server/current/setup-kibana-endpoint.html +# +# kibanaRef: +# name: eck-kibana +# # Optional namespace reference to Kibana resource. +# # If not specified, then the namespace of the APM Server resource +# # will be assumed. +# # +# # namespace: default + +# Set podTemplate to customize the pod used by APM Server +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-customize-pods.html +# +podTemplate: {} + +# Number of revisions to retain to allow rollback in the underlying Deployment. +# If not set Kubernetes sets this to 10 by default. +# +# revisionHistoryLimit: 2 + +# SecureSettings is a list of references to Kubernetes Secrets containing sensitive configuration options for APM Server. +secureSettings: [] +# - secretName: my-secret-with-secure-settings diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/.helmignore b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/.helmignore new file mode 100644 index 00000000..f1568daf --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/Chart.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/Chart.yaml new file mode 100644 index 00000000..9c8fc4b5 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/Chart.yaml @@ -0,0 +1,10 @@ +apiVersion: v2 +description: Elastic Beats managed by the ECK operator +icon: https://helm.elastic.co/icons/beats.png +kubeVersion: '>= 1.20.0-0' +name: eck-beats +sources: +- https://github.com/elastic/cloud-on-k8s +- https://github.com/elastic/beats +type: application +version: 0.15.0 diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/LICENSE b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/LICENSE new file mode 100644 index 00000000..92503a72 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/LICENSE @@ -0,0 +1,93 @@ +Elastic License 2.0 + +URL: https://www.elastic.co/licensing/elastic-license + +## Acceptance + +By using the software, you agree to all of the terms and conditions below. + +## Copyright License + +The licensor grants you a non-exclusive, royalty-free, worldwide, +non-sublicensable, non-transferable license to use, copy, distribute, make +available, and prepare derivative works of the software, in each case subject to +the limitations and conditions below. + +## Limitations + +You may not provide the software to third parties as a hosted or managed +service, where the service provides users with access to any substantial set of +the features or functionality of the software. + +You may not move, change, disable, or circumvent the license key functionality +in the software, and you may not remove or obscure any functionality in the +software that is protected by the license key. + +You may not alter, remove, or obscure any licensing, copyright, or other notices +of the licensor in the software. Any use of the licensor’s trademarks is subject +to applicable law. + +## Patents + +The licensor grants you a license, under any patent claims the licensor can +license, or becomes able to license, to make, have made, use, sell, offer for +sale, import and have imported the software, in each case subject to the +limitations and conditions in this license. This license does not cover any +patent claims that you cause to be infringed by modifications or additions to +the software. If you or your company make any written claim that the software +infringes or contributes to infringement of any patent, your patent license for +the software granted under these terms ends immediately. If your company makes +such a claim, your patent license ends immediately for work on behalf of your +company. + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you +also gets a copy of these terms. + +If you modify the software, you must include in any modified copies of the +software prominent notices stating that you have modified the software. + +## No Other Rights + +These terms do not imply any licenses other than those expressly granted in +these terms. + +## Termination + +If you use the software in violation of these terms, such use is not licensed, +and your licenses will automatically terminate. If the licensor provides you +with a notice of your violation, and you cease all violation of this license no +later than 30 days after you receive that notice, your licenses will be +reinstated retroactively. However, if you violate these terms after such +reinstatement, any additional violation of these terms will cause your licenses +to terminate automatically and permanently. + +## No Liability + +*As far as the law allows, the software comes as is, without any warranty or +condition, and the licensor will not be liable to you for any damages arising +out of these terms or the use or nature of the software, under any kind of +legal claim.* + +## Definitions + +The **licensor** is the entity offering these terms, and the **software** is the +software the licensor makes available under these terms, including any portion +of it. + +**you** refers to the individual or entity agreeing to these terms. + +**your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control over, +are under the control of, or are under common control with that +organization. **control** means ownership of substantially all the assets of an +entity, or the power to direct its management and policies by vote, contract, or +otherwise. Control can be direct or indirect. + +**your licenses** are all the licenses granted to you for the software under +these terms. + +**use** means anything you do with the software requiring one of your licenses. + +**trademark** means trademarks, service marks, and similar rights. \ No newline at end of file diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/examples/auditbeat_hosts.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/examples/auditbeat_hosts.yaml new file mode 100644 index 00000000..1e585b97 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/examples/auditbeat_hosts.yaml @@ -0,0 +1,110 @@ +name: auditbeat +version: 9.0.0 +type: auditbeat +elasticsearchRef: + name: eck-elasticsearch +kibanaRef: + name: eck-kibana +config: + auditbeat.modules: + - module: file_integrity + paths: + - /hostfs/bin + - /hostfs/usr/bin + - /hostfs/sbin + - /hostfs/usr/sbin + - /hostfs/etc + exclude_files: + - '(?i)\.sw[nop]$' + - '~$' + - '/\.git($|/)' + scan_at_start: true + scan_rate_per_sec: 50 MiB + max_file_size: 100 MiB + hash_types: [sha1] + recursive: true + - module: auditd + audit_rules: | + # Executions + -a always,exit -F arch=b64 -S execve,execveat -k exec + + # Unauthorized access attempts (amd64 only) + -a always,exit -F arch=b64 -S open,creat,truncate,ftruncate,openat,open_by_handle_at -F exit=-EACCES -k access + -a always,exit -F arch=b64 -S open,creat,truncate,ftruncate,openat,open_by_handle_at -F exit=-EPERM -k access + + processors: + - add_cloud_metadata: {} + - add_host_metadata: {} + - add_process_metadata: + match_pids: ['process.pid'] +daemonSet: + podTemplate: + spec: + hostPID: true # Required by auditd module + dnsPolicy: ClusterFirstWithHostNet + hostNetwork: true # Allows to provide richer host metadata + automountServiceAccountToken: true # some older Beat versions are depending on this settings presence in k8s context + securityContext: + runAsUser: 0 + volumes: + - name: bin + hostPath: + path: /bin + - name: usrbin + hostPath: + path: /usr/bin + - name: sbin + hostPath: + path: /sbin + - name: usrsbin + hostPath: + path: /usr/sbin + - name: etc + hostPath: + path: /etc + - name: run-containerd + hostPath: + path: /run/containerd + type: DirectoryOrCreate + # Uncomment the below when running on GKE. See https://github.com/elastic/beats/issues/8523 for more context. + #- name: run + # hostPath: + # path: /run + #initContainers: + #- name: cos-init + # image: docker.elastic.co/beats/auditbeat:8.3.3 + # volumeMounts: + # - name: run + # mountPath: /run + # command: ['sh', '-c', 'export SYSTEMD_IGNORE_CHROOT=1 && systemctl stop systemd-journald-audit.socket && systemctl mask systemd-journald-audit.socket && systemctl restart systemd-journald'] + containers: + - name: auditbeat + securityContext: + capabilities: + add: + # Capabilities needed for auditd module + - 'AUDIT_READ' + - 'AUDIT_WRITE' + - 'AUDIT_CONTROL' + volumeMounts: + - name: bin + mountPath: /hostfs/bin + readOnly: true + - name: sbin + mountPath: /hostfs/sbin + readOnly: true + - name: usrbin + mountPath: /hostfs/usr/bin + readOnly: true + - name: usrsbin + mountPath: /hostfs/usr/sbin + readOnly: true + - name: etc + mountPath: /hostfs/etc + readOnly: true + # Directory with root filesystems of containers executed with containerd, this can be + # different with other runtimes. This volume is needed to monitor the file integrity + # of files in containers. + - name: run-containerd + mountPath: /run/containerd + readOnly: true diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/examples/filebeat_no_autodiscover.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/examples/filebeat_no_autodiscover.yaml new file mode 100644 index 00000000..a6e5f408 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/examples/filebeat_no_autodiscover.yaml @@ -0,0 +1,52 @@ +name: filebeat +version: 9.0.0 +type: filebeat +elasticsearchRef: + name: eck-elasticsearch +kibanaRef: + name: eck-kibana +config: + filebeat.inputs: + - type: filestream + paths: + - /var/log/containers/*.log + parsers: + - container: ~ + prospector: + scanner: + fingerprint.enabled: true + symlinks: true + file_identity.fingerprint: ~ + processors: + - add_host_metadata: {} + - add_cloud_metadata: {} +daemonSet: + podTemplate: + spec: + automountServiceAccountToken: true + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirstWithHostNet + hostNetwork: true # Allows to provide richer host metadata + containers: + - name: filebeat + securityContext: + runAsUser: 0 + # If using Red Hat OpenShift uncomment this: + #privileged: true + volumeMounts: + - name: varlogcontainers + mountPath: /var/log/containers + - name: varlogpods + mountPath: /var/log/pods + - name: varlibdockercontainers + mountPath: /var/lib/docker/containers + volumes: + - name: varlogcontainers + hostPath: + path: /var/log/containers + - name: varlogpods + hostPath: + path: /var/log/pods + - name: varlibdockercontainers + hostPath: + path: /var/lib/docker/containers diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/examples/heartbeat_es_kb_health.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/examples/heartbeat_es_kb_health.yaml new file mode 100644 index 00000000..ed27331e --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/examples/heartbeat_es_kb_health.yaml @@ -0,0 +1,23 @@ +name: heartbeat +version: 9.0.0 +type: heartbeat +elasticsearchRef: + name: eck-elasticsearch +config: + heartbeat.monitors: + - type: tcp + schedule: '@every 5s' + # This should directly match the name of the Elasticsearch instance + # with "-es-http" appended to the name. + hosts: ["elasticsearch-es-http.default.svc:9200"] + - type: tcp + schedule: '@every 5s' + # This should directly match the names of the Kibana instance + # with "-kb-http" appended to the name. + hosts: ["eck-kibana-kb-http.default.svc:5601"] +deployment: + replicas: 1 + podTemplate: + spec: + securityContext: + runAsUser: 0 diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/examples/metricbeat_hosts.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/examples/metricbeat_hosts.yaml new file mode 100644 index 00000000..39c05263 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/examples/metricbeat_hosts.yaml @@ -0,0 +1,158 @@ +name: metricbeat +type: metricbeat +version: 9.0.0 +elasticsearchRef: + name: eck-elasticsearch +kibanaRef: + name: eck-kibana +config: + metricbeat: + autodiscover: + providers: + - hints: + default_config: {} + enabled: "true" + node: ${NODE_NAME} + type: kubernetes + modules: + - module: system + period: 10s + metricsets: + - cpu + - load + - memory + - network + - process + - process_summary + process: + include_top_n: + by_cpu: 5 + by_memory: 5 + processes: + - .* + - module: system + period: 1m + metricsets: + - filesystem + - fsstat + processors: + - drop_event: + when: + regexp: + system: + filesystem: + mount_point: ^/(sys|cgroup|proc|dev|etc|host|lib)($|/) + - module: kubernetes + period: 10s + node: ${NODE_NAME} + hosts: + - https://${NODE_NAME}:10250 + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + ssl: + verification_mode: none + metricsets: + - node + - system + - pod + - container + - volume + processors: + - add_cloud_metadata: {} + - add_host_metadata: {} +daemonSet: + podTemplate: + spec: + serviceAccountName: metricbeat + automountServiceAccountToken: true # some older Beat versions are depending on this settings presence in k8s context + containers: + - args: + - -e + - -c + - /etc/beat.yml + - --system.hostfs=/hostfs + name: metricbeat + volumeMounts: + - mountPath: /hostfs/sys/fs/cgroup + name: cgroup + - mountPath: /var/run/docker.sock + name: dockersock + - mountPath: /hostfs/proc + name: proc + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + dnsPolicy: ClusterFirstWithHostNet + hostNetwork: true # Allows to provide richer host metadata + securityContext: + runAsUser: 0 + terminationGracePeriodSeconds: 30 + volumes: + - hostPath: + path: /sys/fs/cgroup + name: cgroup + - hostPath: + path: /var/run/docker.sock + name: dockersock + - hostPath: + path: /proc + name: proc + +clusterRole: + # permissions needed for metricbeat + # source: https://www.elastic.co/guide/en/beats/metricbeat/current/metricbeat-module-kubernetes.html + name: metricbeat + rules: + - apiGroups: + - "" + resources: + - nodes + - namespaces + - events + - pods + verbs: + - get + - list + - watch + - apiGroups: + - "extensions" + resources: + - replicasets + verbs: + - get + - list + - watch + - apiGroups: + - apps + resources: + - statefulsets + - deployments + - replicasets + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - nodes/stats + verbs: + - get + - nonResourceURLs: + - /metrics + verbs: + - get + +serviceAccount: + name: metricbeat + +clusterRoleBinding: + name: metricbeat + subjects: + - kind: ServiceAccount + name: metricbeat + roleRef: + kind: ClusterRole + name: metricbeat + apiGroup: rbac.authorization.k8s.io diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/examples/packetbeat_dns_http.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/examples/packetbeat_dns_http.yaml new file mode 100644 index 00000000..d74f732b --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/examples/packetbeat_dns_http.yaml @@ -0,0 +1,37 @@ +name: packetbeat +type: packetbeat +version: 9.0.0 +elasticsearchRef: + name: eck-elasticsearch +kibanaRef: + name: eck-kibana +config: + packetbeat.interfaces.device: any + packetbeat.protocols: + - type: dns + ports: [53] + include_authorities: true + include_additionals: true + - type: http + ports: [80, 8000, 8080, 9200] + packetbeat.flows: + timeout: 30s + period: 10s + processors: + - add_cloud_metadata: {} + - add_host_metadata: {} +daemonSet: + podTemplate: + spec: + terminationGracePeriodSeconds: 30 + hostNetwork: true + automountServiceAccountToken: true # some older Beat versions are depending on this settings presence in k8s context + dnsPolicy: ClusterFirstWithHostNet + containers: + - name: packetbeat + securityContext: + runAsUser: 0 + capabilities: + add: + - NET_ADMIN + volumes: [] diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/templates/NOTES.txt b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/templates/NOTES.txt new file mode 100644 index 00000000..10d2dac5 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/templates/NOTES.txt @@ -0,0 +1,6 @@ + +1. Check Beat status + $ kubectl get beat {{ include "beat.fullname" . }} -n {{ .Release.Namespace }} + +2. Check Beat pod status + $ kubectl get pods --namespace={{ .Release.Namespace }} -l beat.k8s.elastic.co/name={{ include "beat.fullname" . }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/templates/_helpers.tpl b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/templates/_helpers.tpl new file mode 100644 index 00000000..5e20af14 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "beat.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "beat.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "beat.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "beat.labels" -}} +helm.sh/chart: {{ include "beat.chart" . }} +{{ include "beat.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.labels }} +{{ toYaml .Values.labels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "beat.selectorLabels" -}} +app.kubernetes.io/name: {{ include "beat.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/templates/beats.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/templates/beats.yaml new file mode 100644 index 00000000..a70ac9a6 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/templates/beats.yaml @@ -0,0 +1,75 @@ +--- +apiVersion: beat.k8s.elastic.co/v1beta1 +kind: Beat +metadata: + name: {{ include "beat.fullname" . }} + labels: + {{- include "beat.labels" . | nindent 4 }} + annotations: + eck.k8s.elastic.co/license: basic + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + version: {{ required "A Beat version is required" (or ((.Values.spec).version) (.Values.version)) }} + {{- $daemonSet := (or (hasKey (.Values.spec) "daemonSet") (hasKey .Values "daemonSet")) }} + {{- $deployment := (or (hasKey (.Values.spec) "deployment") (hasKey .Values "deployment")) }} + {{- if and (not $daemonSet) (not $deployment) }} + {{ fail "At least one of daemonSet or deployment is required for a functional Beat" }} + {{- end }} + {{- if not (or ((.Values.spec).type) (.Values.type)) }}{{ fail "A Beat type is required" }}{{- end }} + type: {{ or ((.Values.spec).type) (.Values.type) }} + {{- if $daemonSet }} + {{- $ds := or ((.Values.spec).daemonSet) (.Values.daemonSet) }} + daemonSet: + {{- /* This is required to render the empty daemonset ( {} ) properly */}} + {{- $ds | default dict | toYaml | nindent 4 }} + {{- end }} + {{- if $deployment }} + {{- $deploy := or ((.Values.spec).deployment) (.Values.deployment) }} + deployment: + {{- /* This is required to render the empty deployment ( {} ) properly */}} + {{- $deploy | default dict | toYaml | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).image) (.Values.image) }} + image: {{ . }} + {{- end }} + {{- with or ((.Values.spec).elasticsearchRef) (.Values.elasticsearchRef) }} + elasticsearchRef: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).kibanaRef) (.Values.kibanaRef) }} + kibanaRef: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- $config := or ((.Values.spec).config) (.Values.config) }} + {{- $configRef := or ((.Values.spec).configRef) (.Values.configRef) }} + {{- if and $config $configRef }} + {{ fail "Only one of config and configRef can be specified" }} + {{- end }} + {{- with $config }} + config: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $configRef }} + configRef: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).http) (.Values.http) }} + http: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).monitoring) (.Values.monitoring) }} + monitoring: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).secureSettings) (.Values.secureSettings) }} + secureSettings: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).revisionHistoryLimit) (.Values.revisionHistoryLimit) }} + revisionHistoryLimit: {{ . }} + {{- end }} + {{- with or (((.Values.spec).serviceAccount).name) ((.Values.serviceAccount).name) }} + serviceAccountName: {{ . }} + {{- end }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/templates/cluster-role-binding.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/templates/cluster-role-binding.yaml new file mode 100644 index 00000000..d8fca15f --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/templates/cluster-role-binding.yaml @@ -0,0 +1,35 @@ +{{- with .Values.clusterRoleBinding }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .name }} + labels: + {{- include "beat.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or $.Values.annotations .annotations }} + annotations: + {{- with $.Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +{{- with .subjects }} +subjects: +{{- range . }} + - kind: {{ .kind }} + name: {{ .name }} + namespace: {{ .namespace | default $.Release.Namespace | quote }} +{{- end }} +{{- end }} +{{- with .roleRef }} +roleRef: + kind: {{ .kind }} + name: {{ .name }} + apiGroup: {{ .apiGroup }} +{{- end }} +{{- end }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/templates/cluster-role.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/templates/cluster-role.yaml new file mode 100644 index 00000000..66406f63 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/templates/cluster-role.yaml @@ -0,0 +1,22 @@ +{{- with .Values.clusterRole }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ .name }} + labels: + {{- include "beat.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or $.Values.annotations .annotations }} + annotations: + {{- with $.Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +rules: {{- toYaml .rules | nindent 2 }} +{{- end }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/templates/service-account.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/templates/service-account.yaml new file mode 100644 index 00000000..08f21f7e --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/templates/service-account.yaml @@ -0,0 +1,23 @@ + +{{- with .Values.serviceAccount }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .name }} + namespace: {{ .namespace | default $.Release.Namespace | quote }} + labels: + {{- include "beat.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or $.Values.annotations .annotations }} + annotations: + {{- with $.Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/values.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/values.yaml new file mode 100644 index 00000000..036167bf --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-beats/values.yaml @@ -0,0 +1,169 @@ +--- +# Default values for eck-beats. +# This is a YAML-formatted file. + +# Overridable names of the Beats resource. +# By default, this is the Release name set for the chart, +# followed by 'eck-beats'. +# +# nameOverride will override the name of the Chart with the name set here, +# so nameOverride: quickstart, would convert to '{{ Release.name }}-quickstart' +# +# nameOverride: "quickstart" +# +# fullnameOverride will override both the release name, and the chart name, +# and will name the Beats resource exactly as specified. +# +# fullnameOverride: "quickstart" + +# Version of Elastic Beats. +# +version: 9.0.0 + +# Labels that will be applied to Elastic Beats. +# +labels: {} + +# Annotations that will be applied to Elastic Beats. +# +annotations: {} + +# ** Deprecation Notice ** +# The previous versions of this Helm Chart simply used the `spec` field here +# and allowed the user to specify any fields below spec that were templated directly +# into the final Beats manifest. This is no longer the preferred way to specify these +# fields and each field that is supported underneath `spec` is now directly specified +# in this values file. Currently both patterns are supported for backwards compatibility +# but we plan to remove the `spec` field in the future. +# spec: {} + +# Type of Elastic Beats. Standard types of Beat are [filebeat,metricbeat,heartbeat,auditbeat,packetbeat,journalbeat]. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-beat-configuration.html#k8s-beat-deploy-elastic-beat +# +# Note: This is required to be set, or the release install will fail. +# +type: "" + +# Beats image to deploy. +# +# image: docker.elastic.co/beats/metricbeat:9.0.0 + +# Referenced resources are below and depending on the setup, at least elasticsearchRef is required for a functional Beat. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-beat-configuration.html#k8s-beat-connect-es +# +# Reference to ECK-managed Kibana instance. +# +# kibanaRef: +# name: quickstart + # Optional namespace reference to Kibana instance. + # If not specified, then the namespace of the Beats instance + # will be assumed. + # + # namespace: default + +# Reference to ECK-managed Elasticsearch instance. +# *Note* If Beat's output is intended to go to Elasticsearch and not something like Logstash, +# this elasticsearchRef must be updated to the name of the Elasticsearch instance. +# +elasticsearchRef: {} + # name: elasticsearch + # Optional namespace reference to Elasticsearch instance. + # If not specified, then the namespace of the Beats instance + # will be assumed. + # + # namespace: default + +# Daemonset, or Deployment specification for the type of Beat specified. +# At least one is required of [daemonSet, deployment]. +# No default is currently set, refer to https://github.com/elastic/cloud-on-k8s/issues/7429. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-beat-configuration.html#k8s-beat-chose-the-deployment-model +# +# deployment: +# podTemplate: +# spec: +# securityContext: +# runAsUser: 0 +# daemonSet: +# podTemplate: +# spec: +# securityContext: +# runAsUser: 0 + +# Configuration of Beat, which is dependent on the `type` of Beat specified. +# NOTE: The `config` and `configRef` fields are mutually exclusive. Only one of them should be defined at a time, +# as using both may cause conflicts. +# +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-beat-configuration.html#k8s-beat-custom-configuration +# +config: {} + +# Reference a configuration in a Secret. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-beat-configuration.html#k8s-beat-custom-configuration +# +# configRef: +# secretName: "" + +# The HTTP layer configuration for the Beats Service. +# +# http: + +# Settings for configuring stack monitoring. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-stack-monitoring.html +# +# monitoring: {} + # metrics: + # elasticsearchRefs: + # - name: monitoring + # namespace: observability + # logs: + # elasticsearchRefs: + # - name: monitoring + # namespace: observability + +# SecureSettings is a list of references to Kubernetes Secrets containing sensitive configuration options for Elastic Beats. +secureSettings: [] +# - secretName: my-secret-with-secure-settings + +# Number of revisions to retain to allow rollback in the underlying Deployment. +# If not set Kubernetes sets this to 10 by default. +# +# revisionHistoryLimit: 2 + +# ServiceAccount to be used by Elastic Beats. Some Beats features (such as autodiscover or Kubernetes module metricsets) +# require that Beat Pods interact with Kubernetes APIs. This functionality requires specific permissions +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-beat-configuration.html#k8s-beat-role-based-access-control-for-beats +# +serviceAccount: {} +# name: elastic-beat-filebeat-quickstart +# namespace: optional-namespace + +# ClusterRoleBinding to be used by Elastic Beats. Similar to ServiceAccount, this is required in some scenarios. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-beat-configuration.html#k8s-beat-role-based-access-control-for-beats +# +clusterRoleBinding: {} +# name: elastic-beat-autodiscover-binding +# subjects: +# - kind: ServiceAccount +# name: elastic-beat-filebeat-quickstart +# namespace: default +# roleRef: +# kind: ClusterRole +# name: elastic-beat-autodiscover +# apiGroup: rbac.authorization.k8s.io + +# ClusterRole to be used by Elastic Beats. Similar to ServiceAccount, this is required in some scenarios. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-beat-configuration.html#k8s-beat-role-based-access-control-for-beats +# +clusterRole: {} +# name: elastic-beat-autodiscover +# rules: +# - apiGroups: [""] +# resources: +# - events +# - pods +# - namespaces +# - nodes +# verbs: +# - get +# - watch +# - list diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/.helmignore b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/.helmignore new file mode 100644 index 00000000..f1568daf --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/Chart.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/Chart.yaml new file mode 100644 index 00000000..a9f28ec9 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/Chart.yaml @@ -0,0 +1,10 @@ +apiVersion: v2 +description: Elasticsearch managed by the ECK operator +icon: https://helm.elastic.co/icons/elasticsearch.png +kubeVersion: '>= 1.21.0-0' +name: eck-elasticsearch +sources: +- https://github.com/elastic/cloud-on-k8s +- https://github.com/elastic/elasticsearch/ +type: application +version: 0.15.0 diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/LICENSE b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/LICENSE new file mode 100644 index 00000000..92503a72 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/LICENSE @@ -0,0 +1,93 @@ +Elastic License 2.0 + +URL: https://www.elastic.co/licensing/elastic-license + +## Acceptance + +By using the software, you agree to all of the terms and conditions below. + +## Copyright License + +The licensor grants you a non-exclusive, royalty-free, worldwide, +non-sublicensable, non-transferable license to use, copy, distribute, make +available, and prepare derivative works of the software, in each case subject to +the limitations and conditions below. + +## Limitations + +You may not provide the software to third parties as a hosted or managed +service, where the service provides users with access to any substantial set of +the features or functionality of the software. + +You may not move, change, disable, or circumvent the license key functionality +in the software, and you may not remove or obscure any functionality in the +software that is protected by the license key. + +You may not alter, remove, or obscure any licensing, copyright, or other notices +of the licensor in the software. Any use of the licensor’s trademarks is subject +to applicable law. + +## Patents + +The licensor grants you a license, under any patent claims the licensor can +license, or becomes able to license, to make, have made, use, sell, offer for +sale, import and have imported the software, in each case subject to the +limitations and conditions in this license. This license does not cover any +patent claims that you cause to be infringed by modifications or additions to +the software. If you or your company make any written claim that the software +infringes or contributes to infringement of any patent, your patent license for +the software granted under these terms ends immediately. If your company makes +such a claim, your patent license ends immediately for work on behalf of your +company. + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you +also gets a copy of these terms. + +If you modify the software, you must include in any modified copies of the +software prominent notices stating that you have modified the software. + +## No Other Rights + +These terms do not imply any licenses other than those expressly granted in +these terms. + +## Termination + +If you use the software in violation of these terms, such use is not licensed, +and your licenses will automatically terminate. If the licensor provides you +with a notice of your violation, and you cease all violation of this license no +later than 30 days after you receive that notice, your licenses will be +reinstated retroactively. However, if you violate these terms after such +reinstatement, any additional violation of these terms will cause your licenses +to terminate automatically and permanently. + +## No Liability + +*As far as the law allows, the software comes as is, without any warranty or +condition, and the licensor will not be liable to you for any damages arising +out of these terms or the use or nature of the software, under any kind of +legal claim.* + +## Definitions + +The **licensor** is the entity offering these terms, and the **software** is the +software the licensor makes available under these terms, including any portion +of it. + +**you** refers to the individual or entity agreeing to these terms. + +**your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control over, +are under the control of, or are under common control with that +organization. **control** means ownership of substantially all the assets of an +entity, or the power to direct its management and policies by vote, contract, or +otherwise. Control can be direct or indirect. + +**your licenses** are all the licenses granted to you for the software under +these terms. + +**use** means anything you do with the software requiring one of your licenses. + +**trademark** means trademarks, service marks, and similar rights. \ No newline at end of file diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/examples/hot-warm-cold.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/examples/hot-warm-cold.yaml new file mode 100644 index 00000000..4eb99e60 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/examples/hot-warm-cold.yaml @@ -0,0 +1,198 @@ +--- +nodeSets: +- name: masters + count: 1 + config: + node.roles: ["master"] + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + spec: + containers: + - name: elasticsearch + resources: + limits: + memory: 8Gi + cpu: 2 + # Affinity/Anti-affinity settings for controlling the 'spreading' of Elasticsearch + # pods across existing hosts. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html#k8s-affinity-options + # + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: beta.kubernetes.io/instance-type + # operator: In + # # This should be adjusted to the instance type according to your setup + # # + # values: + # - highio + # Volume Claim settings. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-volume-claim-templates.html + # + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Ti + # Adjust to your storage class name + # + # storageClassName: local-storage +- name: hot + count: 1 + config: + node.roles: ["data_hot", "data_content", "ingest"] + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + spec: + containers: + - name: elasticsearch + resources: + limits: + memory: 16Gi + cpu: 4 + # Affinity/Anti-affinity settings for controlling the 'spreading' of Elasticsearch + # pods across existing hosts. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html#k8s-affinity-options + # + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: beta.kubernetes.io/instance-type + # operator: In + # # This should be adjusted to the instance type according to your setup + # # + # values: + # - highio + # Volume Claim settings. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-volume-claim-templates.html + # + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Ti + # Adjust to your storage class name + # + # storageClassName: local-storage +- name: warm + count: 1 + config: + node.roles: ["data_warm"] + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + spec: + containers: + - name: elasticsearch + resources: + limits: + memory: 16Gi + cpu: 2 + # Affinity/Anti-affinity settings for controlling the 'spreading' of Elasticsearch + # pods across existing hosts. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html#k8s-affinity-options + # + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: beta.kubernetes.io/instance-type + # operator: In + # # This should be adjusted to the instance type according to your setup + # # + # values: + # - highstorage + # Volume Claim settings. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-volume-claim-templates.html + # + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Ti + # Adjust to your storage class name + # + # storageClassName: local-storage +- name: cold + count: 1 + config: + node.roles: ["data_cold"] + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + spec: + containers: + - name: elasticsearch + resources: + limits: + memory: 8Gi + cpu: 2 + # Affinity/Anti-affinity settings for controlling the 'spreading' of Elasticsearch + # pods across existing hosts. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html#k8s-affinity-options + # + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: beta.kubernetes.io/instance-type + # operator: In + # # This should be adjusted to the instance type according to your setup + # # + # values: + # - highstorage + # Volume Claim settings. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-volume-claim-templates.html + # + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 20Ti + # Adjust to your storage class name + # + # storageClassName: local-storage diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-aks.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-aks.yaml new file mode 100644 index 00000000..0ca310c3 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-aks.yaml @@ -0,0 +1,26 @@ +--- +# The following is an example of an Elasticsearch resource that is configured to use an Ingress resource in an AKS cluster. +# +ingress: + enabled: true + className: webapprouting.kubernetes.azure.com + annotations: + # This is required for AKS Loadbalancing to understand that it's communicating with + # an HTTPS backend. + nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" + labels: + my: label + pathType: Prefix + hosts: + - host: "elasticsearch.company.dev" + path: "/" +nodeSets: +- name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-eks-alb.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-eks-alb.yaml new file mode 100644 index 00000000..d3cc4041 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-eks-alb.yaml @@ -0,0 +1,37 @@ +--- +# The following is an example of an Elasticsearch resource that is configured to use an Ingress resource in an EKS cluster +# which provisions an application load balancer. +# +ingress: + enabled: true + className: alb + annotations: + alb.ingress.kubernetes.io/scheme: "internet-facing" + alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]' + alb.ingress.kubernetes.io/backend-protocol: "HTTPS" + alb.ingress.kubernetes.io/target-type: "ip" + # To use an ALB with ECK, you must provide a valid ACM certificate ARN or use certificate discovery. + # There are 2 options for EKS: + # 1. Create a valid ACM certificate, and uncomment the following annotation and update it to the correct ARN. + # 2. Create a valid ACM certificate and ensure that the hosts[0].host matches the certificate's Common Name (CN) and + # certificate discovery *should* find the certificate automatically and use it. + # + # ref: https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.8/guide/ingress/cert_discovery/ + # + # alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:us-east-1:00000000000:certificate/b65be571-8220-4f2e-8cb1-94194535d877" + labels: + my: label + pathType: Prefix + hosts: + - host: "elasticsearch.company.dev" + path: "/" +nodeSets: +- name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-eks-nlb.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-eks-nlb.yaml new file mode 100644 index 00000000..3809e871 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-eks-nlb.yaml @@ -0,0 +1,27 @@ +--- +# The following is an example of an Elasticsearch resource that is configured to deploy a +# network load balancer (NLB) in an EKS cluster. To provision an NLB "ingress" for the +# Elasticsearch cluster, you are required to set annotations on the service, +# and not an Ingress resource. +ingress: + enabled: false +http: + service: + metadata: + annotations: + service.beta.kubernetes.io/aws-load-balancer-type: external + service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip + service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing + service.beta.kubernetes.io/aws-load-balancer-backend-protocol: ssl + spec: + type: LoadBalancer +nodeSets: +- name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-gke.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-gke.yaml new file mode 100644 index 00000000..3adbd29c --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-gke.yaml @@ -0,0 +1,36 @@ +--- +# The following is an example of an Elasticsearch resource that is configured to use an Ingress resource in a GKE cluster. +# +ingress: + enabled: true + annotations: + my: annotation + labels: + my: label + pathType: Prefix + hosts: + - host: "elasticsearch.company.dev" + path: "/" +http: + service: + metadata: + annotations: + # This is required for `ClusterIP` services (which are the default ECK service type) to be used with Ingress in GKE clusters. + cloud.google.com/neg: '{"ingress": true}' + # This is required to enable the GKE Ingress Controller to use HTTPS as the backend protocol. + cloud.google.com/app-protocols: '{"https":"HTTPS"}' +nodeSets: +- name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false + # Enable anonymous access to allow GCLB health probes to succeed + xpack.security.authc: + anonymous: + username: anon + roles: monitoring_user diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/templates/NOTES.txt b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/templates/NOTES.txt new file mode 100644 index 00000000..f6ab0020 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/templates/NOTES.txt @@ -0,0 +1,6 @@ + +1. Check Elasticsearch resource status + $ kubectl get es {{ include "elasticsearch.fullname" . }} -n {{ .Release.Namespace }} + +2. Check Elasticsearch pod status + $ kubectl get pods --namespace={{ .Release.Namespace }} -l elasticsearch.k8s.elastic.co/cluster-name={{ include "elasticsearch.fullname" . }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/templates/_helpers.tpl b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/templates/_helpers.tpl new file mode 100644 index 00000000..8fbf57b3 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "elasticsearch.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "elasticsearch.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "elasticsearch.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "elasticsearch.labels" -}} +helm.sh/chart: {{ include "elasticsearch.chart" . }} +{{ include "elasticsearch.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.labels }} +{{ toYaml .Values.labels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "elasticsearch.selectorLabels" -}} +app.kubernetes.io/name: {{ include "elasticsearch.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/templates/elasticsearch.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/templates/elasticsearch.yaml new file mode 100644 index 00000000..20929eb6 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/templates/elasticsearch.yaml @@ -0,0 +1,74 @@ +--- +apiVersion: elasticsearch.k8s.elastic.co/v1 +kind: Elasticsearch +metadata: + name: {{ include "elasticsearch.fullname" . }} + labels: + {{- include "elasticsearch.labels" . | nindent 4 }} + annotations: + eck.k8s.elastic.co/license: basic + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .Values.auth }} + auth: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.updateStrategy }} + updateStrategy: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.secureSettings }} + secureSettings: + {{- toYaml . | nindent 2 }} + {{- end }} + {{- with .Values.transport }} + transport: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.http }} + http: + {{- toYaml . | nindent 4 }} + {{- end }} + version: {{ required "An Elasticsearch version is required" .Values.version }} + {{- with .Values.monitoring }} + monitoring: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.remoteClusters }} + remoteClusters: + {{- toYaml . | nindent 2 }} + {{- end }} + {{- with .Values.volumeClaimDeletePolicy }} + volumeClaimDeletePolicy: + {{- if and (not (eq . "DeleteOnScaledownOnly")) (not (eq . "DeleteOnScaledownAndClusterDeletion")) }} + {{ fail "volumeClaimDeletePolicy can only be one of 'DeleteOnScaledownOnly' or 'DeleteOnScaledownAndClusterDeletion'" }} + {{- end }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if eq (len .Values.nodeSets) 0 }} + {{ fail "At least one nodeSet is required" }} + {{- end }} + nodeSets: + {{ toYaml .Values.nodeSets | nindent 4 }} + {{- with .Values.image }} + image: {{ . }} + {{- end }} + {{- with .Values.podDisruptionBudget }} + {{- if .disabled }} + podDisruptionBudget: {} + {{- else }} + {{- with .spec }} + podDisruptionBudget: + spec: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- end }} + {{- end }} + {{- with .Values.serviceAccountName }} + serviceAccountName: {{ . }} + {{- end }} + {{- with .Values.revisionHistoryLimit }} + revisionHistoryLimit: {{ . }} + {{- end }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/templates/ingress.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/templates/ingress.yaml new file mode 100644 index 00000000..99aa1813 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/templates/ingress.yaml @@ -0,0 +1,48 @@ +{{- if .Values.ingress.enabled -}} +{{- $pathType := .Values.ingress.pathType | default "Prefix" -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "elasticsearch.fullname" . }} + labels: + {{- include "elasticsearch.labels" . | nindent 4 }} + {{- with .Values.ingress.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.ingress.annotations }} + annotations: + {{- with .Values.ingress.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +spec: + {{- if .Values.ingress.className }} + ingressClassName: {{ .Values.ingress.className | quote }} + {{- end }} + {{- if .Values.ingress.tls.enabled }} + tls: + - hosts: + {{- range .Values.ingress.hosts }} + - {{ .host | quote }} + {{- end }} + {{- if .Values.ingress.tls.secretName }} + secretName: {{ .Values.ingress.tls.secretName }} + {{- else }} + secretName: {{ include "elasticsearch.fullname" . }}-es-http-certs-internal + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + {{- $hostPath := .path | default "/" }} + - host: {{ .host | quote }} + http: + paths: + - path: {{ $hostPath }} + pathType: {{ $pathType }} + backend: + service: + name: {{ include "elasticsearch.fullname" $ }}-es-http + port: + number: 9200 + {{- end }} +{{ end }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/values.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/values.yaml new file mode 100644 index 00000000..37417f4e --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-elasticsearch/values.yaml @@ -0,0 +1,387 @@ +--- +# Default values for eck-elasticsearch. +# This is a YAML-formatted file. + +# Overridable names of the Elasticsearch resource. +# By default, this is the Release name set for the chart, +# followed by 'eck-elasticsearch'. +# +# nameOverride will override the name of the Chart with the name set here, +# so nameOverride: quickstart, would convert to '{{ Release.name }}-quickstart' +# +# nameOverride: "quickstart" +# +# fullnameOverride will override both the release name, and the chart name, +# and will name the Elasticsearch resource exactly as specified. +# +# fullnameOverride: "quickstart" + +# Version of Elasticsearch. +# +version: 9.0.0 + +# Elasticsearch Docker image to deploy +# +# image: + +# Labels that will be applied to Elasticsearch. +# +labels: {} + +# Annotations that will be applied to Elasticsearch. +# +annotations: {} + +# Settings for configuring Elasticsearch users and roles. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-users-and-roles.html +# +auth: {} + +# Settings for configuring stack monitoring. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-stack-monitoring.html +# +monitoring: {} + # metrics: + # elasticsearchRefs: + # - name: monitoring + # namespace: observability + # logs: + # elasticsearchRefs: + # - name: monitoring + # namespace: observability + +# Control the Elasticsearch transport module used for internal communication between nodes. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-transport-settings.html +# +transport: {} + # service: + # metadata: + # labels: + # my-custom: label + # spec: + # type: LoadBalancer + # tls: + # subjectAltNames: + # - ip: 1.2.3.4 + # - dns: hulk.example.com + # certificate: + # secretName: custom-ca + +# Settings to control how Elasticsearch will be accessed. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-accessing-elastic-services.html +# +http: {} + # service: + # metadata: + # labels: + # my-custom: label + # spec: + # type: LoadBalancer + # tls: + # selfSignedCertificate: + # # To fully disable TLS for the HTTP layer of Elasticsearch, simply + # # set the below field to 'true', removing all other fields. + # disabled: false + # subjectAltNames: + # - ip: 1.2.3.4 + # - dns: hulk.example.com + # certificate: + # secretName: custom-ca + +# Control Elasticsearch Secure Settings. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-es-secure-settings.html#k8s-es-secure-settings +# +secureSettings: [] + # - secretName: one-secure-settings-secret + # Projection of secret keys to specific paths + # - secretName: gcs-secure-settings + # entries: + # - key: gcs.client.default.credentials_file + # - key: gcs_client_1 + # path: gcs.client.client_1.credentials_file + # - key: gcs_client_2 + # path: gcs.client.client_2.credentials_file + +# Settings for limiting the number of simultaneous changes to an Elasticsearch resource. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-update-strategy.html +# +updateStrategy: {} + # changeBudget: + # maxSurge: 3 + # maxUnavailable: 1 + +# Controlling of connectivity between remote clusters within the same kubernetes cluster. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-remote-clusters.html +# +remoteClusters: {} + # - name: cluster-two + # elasticsearchRef: + # name: cluster-two + # namespace: ns-two + +# VolumeClaimDeletePolicy sets the policy for handling deletion of PersistentVolumeClaims for all NodeSets. +# Possible values are DeleteOnScaledownOnly and DeleteOnScaledownAndClusterDeletion. +# By default, if not set or empty, the operator sets DeleteOnScaledownAndClusterDeletion. +# +volumeClaimDeletePolicy: "" + +# Settings to limit the disruption when pods need to be rescheduled for some reason such as upgrades or routine maintenance. +# By default, if not set, the operator sets a budget that doesn't allow any pod to be removed in case the cluster is not green or if there is only one node of type `data` or `master`. +# In all other cases the default PodDisruptionBudget sets `minUnavailable` equal to the total number of nodes minus 1. +# To completely disable the pod disruption budget set `disabled` to true. +# +# podDisruptionBudget: +# spec: +# minAvailable: 2 +# selector: +# matchLabels: +# elasticsearch.k8s.elastic.co/cluster-name: quickstart +# disabled: true + +# Used to check access from the current resource to a resource (for ex. a remote Elasticsearch cluster) in a different namespace. +# Can only be used if ECK is enforcing RBAC on references. +# +# serviceAccountName: "" + +# Number of revisions to retain to allow rollback in the underlying StatefulSets. +# By default, if not set, Kubernetes sets 10. +# +# revisionHistoryLimit: 2 + +# Node configuration settings. +# The node roles which can be configured here are: +# - "master" +# - "data_hot" +# - "data_cold" +# - "data_frozen" +# - "data_content" +# - "ml" +# - "ingest" +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-node-configuration.html +# +nodeSets: +- name: default + count: 1 + config: + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + # The following spec is exactly the Kubernetes Core V1 PodTemplateSpec. Any fields within the PodTemplateSpec + # are supported within the 'spec' field below. Please see below documentation for the exhaustive list of fields. + # + # https://v1-24.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#podtemplatespec-v1-core + # + # Only the commonly overridden/used fields will be noted below. + # + spec: + + # If specified, the pod's scheduling constraints + # https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html + # https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: topology.kubernetes.io/zone + # operator: In + # values: + # - antarctica-east1 + # - antarctica-west1 + + # Containers array. Should only be used to customize the 'elasticsearch' container using the following fields. + containers: + - name: elasticsearch + + # List of environment variables to set in the 'elasticsearch' container. + # https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/ + # env: + # - name: "my-env-var" + # value: "my-value" + + # Compute Resources required by this container. + resources: + # Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, + # it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. + # + # Defaults used by the ECK Operator, if not specified, are below + limits: + # cpu: 1 + memory: 2Gi + requests: + # cpu: 1 + memory: 2Gi + + # Example increasing both the requests and limits values: + # limits: + # cpu: 4 + # memory: 8Gi + # requests: + # cpu: 1 + # memory: 8Gi + + # SecurityContext defines the security options the container should be run with. + # If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + # + # These typically are set automatically by the ECK Operator, and should only be adjusted + # with the full knowledge of the effects of each field. + # + # securityContext: + + # Whether this container has a read-only root filesystem. Default is false. + # readOnlyRootFilesystem: false + + # The GID to run the entrypoint of the container process. Uses runtime default if unset. + # runAsGroup: 1000 + + # Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure + # that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. + # runAsNonRoot: true + + # The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. + # runAsUser: 1000 + + # ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. + # https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod + # imagePullSecrets: + # - name: "image-pull-secret" + + # List of initialization containers belonging to the pod. + # + # Common initContainers include setting sysctl, or in 7.x versions of Elasticsearch, + # installing Elasticsearch plugins. + # + # https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + # initContainers: + # - command: + # - sh + # - "-c" + # - sysctl -w vm.max_map_count=262144 + # name: sysctl + # securityContext: + # privileged: true + # - command: + # - sh + # - "-c" + # - bin/elasticsearch-plugin remove --purge analysis-icu ; bin/elasticsearch-plugin install --batch analysis-icu + # name: install-plugins + # securityContext: + # privileged: true + + + # NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. + # https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + # https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html + # nodeSelector: + # diskType: ssd + # environment: production + + # If specified, indicates the pod's priority. "system-node-critical" and "system-cluster-critical" are two special keywords which indicate the highest priorities with the former being the highest priority. + # Any other name must be defined by creating a PriorityClass object with that name. If not specified, the pod priority will be default or zero if there is no default. + # https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/ + # priorityClassName: "" + + # SecurityContext holds pod-level security attributes and common container settings. Optional: Defaults to empty. See type description for default values of each field. + # See previously defined 'securityContext' within 'podTemplate' for all available fields. + # securityContext: {} + + # ServiceAccountName is the name of the ServiceAccount to use to run this pod. + # https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + # serviceAccountName: "" + + # Optional duration in seconds to wait for the Elasticsearch pod to terminate gracefully. + # terminationGracePeriodSeconds: 30s + + # If specified, the pod's tolerations that will apply to all containers within the pod. + # https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/ + # tolerations: + # - key: "node-role.kubernetes.io/elasticsearch" + # effect: "NoSchedule" + # operator: "Exists" + + # TopologySpreadConstraints describes how a group of pods ought to spread across topology domains. + # Scheduler will schedule pods in a way which abides by the constraints. All topologySpreadConstraints are ANDed. + # + # These settings are generally applied within each `nodeSets[].podTemplate` field to apply to a specific Elasticsearch nodeset. + # + # https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html + # topologySpreadConstraints: {} + + # List of volumes that can be mounted by containers belonging to the pod. + # https://kubernetes.io/docs/concepts/storage/volumes + # volumes: [] + +# Settings for controlling Elasticsearch ingress. Enabling ingress will expose your Elasticsearch instance +# to the public internet, and as such is disabled by default. +# +# Each Cloud Service Provider has different requirements for setting up Ingress. Some links to common documentation are: +# - AWS: https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html +# - GCP: https://cloud.google.com/kubernetes-engine/docs/concepts/ingress +# - Azure: https://learn.microsoft.com/en-us/azure/aks/app-routing +# - Nginx: https://kubernetes.github.io/ingress-nginx/ +# +ingress: + enabled: false + + # Annotations that will be applied to the Ingress resource. Note that some ingress controllers are controlled via annotations. + # + # Nginx Annotations: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/ + # + # Common annotations: + # kubernetes.io/ingress.class: gce # Configures the Ingress resource to use the GCE ingress controller and create an external Application Load Balancer. + # kubernetes.io/ingress.class: gce-internal # Configures the Ingress resource to use the GCE ingress controller and create an internal Application Load Balancer. + # kubernetes.io/ingress.class: nginx # Configures the Ingress resource to use the NGINX ingress controller. + # + annotations: {} + + # Labels that will be applied to the Ingress resource. + # + labels: {} + + # Some ingress controllers require the use of a specific class name to route traffic to the correct controller, notably AKS and EKS, which + # replaces the use of the 'kubernetes.io/ingress.class' annotation. + # + # className: webapprouting.kubernetes.azure.com | alb + + # Ingress paths are required to have a corresponding path type. Defaults to 'Prefix'. + # + # There are 3 supported path types: + # - ImplementationSpecific + # - Prefix + # - Exact + # + # ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#path-types + # + pathType: Prefix + + # Hosts are a list of hosts included in the Ingress definition, with a corresponding path at which the default Elasticsearch service + # will be exposed. Each host in the list should be a fully qualified DNS name that will resolve to the exposed Ingress object. + # + # ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#name-based-virtual-hosting + # + hosts: + - host: chart-example.local + path: / + + # TLS defines whether TLS will be enabled on the Ingress resource. + # + # *NOTE* Many Cloud Service Providers handle TLS in a custom manner, and as such, it is recommended to consult their documentation. + # Notably GKE and Nginx Ingress Controllers seems to respect the Ingress TLS settings, AKS and EKS ignore it. + # + # - AKS: https://learn.microsoft.com/en-us/azure/aks/app-routing-dns-ssl + # - GKE: https://cloud.google.com/kubernetes-engine/docs/concepts/ingress#options_for_providing_ssl_certificates + # - EKS: https://aws.amazon.com/blogs/containers/serve-distinct-domains-with-tls-powered-by-acm-on-amazon-eks/ + # - Nginx: https://kubernetes.github.io/ingress-nginx/user-guide/tls/ + # + # Kubernetes ingress TLS documentation: + # ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#tls + # + tls: + enabled: false + # Optional Kubernetes secret name that contains a base64 encoded PEM certificate and private key that corresponds to the above 'hosts' definitions. + # If tls is enabled, but this field is not set, the self-signed certificate and key created by the ECK operator will be used. + # secretName: chart-example-tls diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-enterprise-search/.helmignore b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-enterprise-search/.helmignore new file mode 100644 index 00000000..f1568daf --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-enterprise-search/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-enterprise-search/Chart.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-enterprise-search/Chart.yaml new file mode 100644 index 00000000..2ab8f772 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-enterprise-search/Chart.yaml @@ -0,0 +1,9 @@ +apiVersion: v2 +description: Elastic Enterprise Search managed by the ECK operator +icon: https://github.com/elastic/ent-search/blob/main/public/app-search-favicon-196x196.png +kubeVersion: '>= 1.21.0-0' +name: eck-enterprise-search +sources: +- https://github.com/elastic/cloud-on-k8s +type: application +version: 0.15.0 diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-enterprise-search/examples/with-custom-configuration.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-enterprise-search/examples/with-custom-configuration.yaml new file mode 100644 index 00000000..4216a112 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-enterprise-search/examples/with-custom-configuration.yaml @@ -0,0 +1,19 @@ +config: + # define the exposed URL at which users will reach Enterprise Search + ent_search.external_url: https://my-custom-domain:3002 + # define the exposed URL at which users will reach Kibana + kibana.host: https://kibana.my-custom-domain:5601 + # configure app search document size limit + app_search.engine.document_size.limit: 100kb + +http: + service: + metadata: + labels: + my-custom: label + tls: + certificate: + secretName: my-cert + +elasticsearchRef: + name: eck-elasticsearch diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-enterprise-search/templates/_helpers.tpl b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-enterprise-search/templates/_helpers.tpl new file mode 100644 index 00000000..21025dc7 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-enterprise-search/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "eck-enterprise-search.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "eck-enterprise-search.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "eck-enterprise-search.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "eck-enterprise-search.labels" -}} +helm.sh/chart: {{ include "eck-enterprise-search.chart" . }} +{{ include "eck-enterprise-search.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "eck-enterprise-search.selectorLabels" -}} +app.kubernetes.io/name: {{ include "eck-enterprise-search.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "eck-enterprise-search.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "eck-enterprise-search.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-enterprise-search/templates/enterprisesearch.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-enterprise-search/templates/enterprisesearch.yaml new file mode 100644 index 00000000..af224e35 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-enterprise-search/templates/enterprisesearch.yaml @@ -0,0 +1,62 @@ +--- +apiVersion: enterprisesearch.k8s.elastic.co/v1 +kind: EnterpriseSearch +metadata: + name: {{ include "eck-enterprise-search.fullname" . }} + labels: + {{- include "eck-enterprise-search.labels" . | nindent 4 }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + eck.k8s.elastic.co/license: basic + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + version: {{ required "An Enterprise Search version is required" .Values.version }} + count: {{ required "A pod count is required" .Values.count }} + + {{- /* + This is complicated, but seems required to catch both the situations where the key does not exist (commented out), and the key exists but is an empty map. + */ -}} + {{- if and (or (and (hasKey .Values "configRef") (eq 0 (len .Values.configRef))) (not (hasKey .Values "configRef"))) (or (and (hasKey .Values "elasticsearchRef") (eq 0 (len .Values.elasticsearchRef))) (not (hasKey .Values "elasticsearchRef"))) }} + {{ fail "At least one of configRef or elasticsearchRef is required" }} + {{- end }} + + {{- with .Values.image }} + image: {{ . }} + {{- end }} + + {{- with .Values.serviceAccountName }} + serviceAccountName: {{ . }} + {{- end }} + + {{- with .Values.revisionHistoryLimit }} + revisionHistoryLimit: {{ . }} + {{- end }} + + {{- with .Values.config }} + config: + {{- toYaml . | nindent 4 }} + {{- end }} + + {{- with .Values.http }} + http: + {{- toYaml . | nindent 4 }} + {{- end }} + + {{- with .Values.elasticsearchRef }} + elasticsearchRef: + {{- toYaml . | nindent 4 }} + {{- end }} + + {{- with .Values.podTemplate }} + podTemplate: + {{- toYaml . | nindent 4 }} + {{- end }} + + {{- with .Values.configRef }} + configRef: + {{- toYaml . | nindent 2 }} + {{- end }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-enterprise-search/values.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-enterprise-search/values.yaml new file mode 100644 index 00000000..a7e48587 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-enterprise-search/values.yaml @@ -0,0 +1,96 @@ +--- +# Default values for eck-enterprise-search. +# This is a YAML-formatted file. + +# Overridable names of the Enterprise Search resource. +# By default, this is the Release name set for the chart, +# followed by 'eck-enterprise-search'. +# +# nameOverride will override the name of the Chart with the name set here, +# so nameOverride: quickstart, would convert to '{{ Release.name }}-quickstart' +# +# nameOverride: "quickstart" +# +# fullnameOverride will override both the release name, and the chart name, +# and will name the Enterprise Search resource exactly as specified. +# +# fullnameOverride: "quickstart" + +# Version of Enterprise Search. +# +version: 8.18.0 + +# Enterprise Search Docker image to deploy +# +# image: + +# Used to check access from the current resource to a resource (for ex. a remote Elasticsearch cluster) in a different namespace. +# Can only be used if ECK is enforcing RBAC on references. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-restrict-cross-namespace-associations.html +# +# serviceAccountName: "" + +# Labels that will be applied to Enterprise Search. +# +labels: {} + +# Annotations that will be applied to Enterprise Search. +# +annotations: {} + +# Count of Enterprise Search replicas to create. +# +count: 1 + +# The Enterprise Search configuration, the ECK equivalent to enterprise-search.yml +# ref: https://www.elastic.co/guide/en/enterprise-search/current/configuration.html#configuration-configure +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-enterprise-search-configuration.html +# +# At a minimum, you must specify the external URL and Kibana host. +# +config: {} + # define the exposed URL at which users will reach Enterprise Search + # ent_search.external_url: https://my-custom-domain:3002 + # define the exposed URL at which users will reach Kibana + # kibana.host: https://kibana.my-custom-domain:5601 + +# Settings to control how Enterprise Search will be accessed. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-accessing-elastic-services.html +# +http: {} + # tls: + # certificate: + # secretName: my-cert + # service: + # metadata: + # labels: + # my-custom: label + +# Reference to ECK-managed Elasticsearch resource. +# +elasticsearchRef: {} + # name: eck-elasticsearch + # Optional namespace reference to Elasticsearch resource. + # If not specified, then the namespace of the Enterprise Search resource + # will be assumed. + # + # namespace: default + +# Set podTemplate to customize the pod used by Enterprise Search +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-customize-pods.html +# +podTemplate: {} + +# Number of revisions to retain to allow rollback in the underlying Deployment. +# If not set Kubernetes sets this to 10 by default. +# +# revisionHistoryLimit: 2 + +# If you would prefer your sensitive data to be stored in a Secret, you can specify the name of the Secret reference. +# In addition, if you do not want to use the `elasticsearchRef` mechanism or if you want to connect to an Elasticsearch +# cluster not managed by ECK, you can manually configure Enterprise Search to access any available Elasticsearch cluster: +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-enterprise-search-configuration.html#k8s-enterprise-search-secret-configuration +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-enterprise-search-configuration.html#k8s-enterprise-search-connect-non-eck-es +# +configRef: {} + # secretName: enterprise-search-config diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/.helmignore b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/.helmignore new file mode 100644 index 00000000..f1568daf --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/Chart.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/Chart.yaml new file mode 100644 index 00000000..24567868 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +description: Elastic Fleet Server as an Agent managed by the ECK operator +kubeVersion: '>= 1.21.0-0' +name: eck-fleet-server +sources: +- https://github.com/elastic/cloud-on-k8s +- https://github.com/elastic/elastic-agent +- https://github.com/elastic/fleet-server +- https://www.elastic.co/guide/en/fleet/current/fleet-overview.html +type: application +version: 0.15.0 diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/LICENSE b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/LICENSE new file mode 100644 index 00000000..92503a72 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/LICENSE @@ -0,0 +1,93 @@ +Elastic License 2.0 + +URL: https://www.elastic.co/licensing/elastic-license + +## Acceptance + +By using the software, you agree to all of the terms and conditions below. + +## Copyright License + +The licensor grants you a non-exclusive, royalty-free, worldwide, +non-sublicensable, non-transferable license to use, copy, distribute, make +available, and prepare derivative works of the software, in each case subject to +the limitations and conditions below. + +## Limitations + +You may not provide the software to third parties as a hosted or managed +service, where the service provides users with access to any substantial set of +the features or functionality of the software. + +You may not move, change, disable, or circumvent the license key functionality +in the software, and you may not remove or obscure any functionality in the +software that is protected by the license key. + +You may not alter, remove, or obscure any licensing, copyright, or other notices +of the licensor in the software. Any use of the licensor’s trademarks is subject +to applicable law. + +## Patents + +The licensor grants you a license, under any patent claims the licensor can +license, or becomes able to license, to make, have made, use, sell, offer for +sale, import and have imported the software, in each case subject to the +limitations and conditions in this license. This license does not cover any +patent claims that you cause to be infringed by modifications or additions to +the software. If you or your company make any written claim that the software +infringes or contributes to infringement of any patent, your patent license for +the software granted under these terms ends immediately. If your company makes +such a claim, your patent license ends immediately for work on behalf of your +company. + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you +also gets a copy of these terms. + +If you modify the software, you must include in any modified copies of the +software prominent notices stating that you have modified the software. + +## No Other Rights + +These terms do not imply any licenses other than those expressly granted in +these terms. + +## Termination + +If you use the software in violation of these terms, such use is not licensed, +and your licenses will automatically terminate. If the licensor provides you +with a notice of your violation, and you cease all violation of this license no +later than 30 days after you receive that notice, your licenses will be +reinstated retroactively. However, if you violate these terms after such +reinstatement, any additional violation of these terms will cause your licenses +to terminate automatically and permanently. + +## No Liability + +*As far as the law allows, the software comes as is, without any warranty or +condition, and the licensor will not be liable to you for any damages arising +out of these terms or the use or nature of the software, under any kind of +legal claim.* + +## Definitions + +The **licensor** is the entity offering these terms, and the **software** is the +software the licensor makes available under these terms, including any portion +of it. + +**you** refers to the individual or entity agreeing to these terms. + +**your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control over, +are under the control of, or are under common control with that +organization. **control** means ownership of substantially all the assets of an +entity, or the power to direct its management and policies by vote, contract, or +otherwise. Control can be direct or indirect. + +**your licenses** are all the licenses granted to you for the software under +these terms. + +**use** means anything you do with the software requiring one of your licenses. + +**trademark** means trademarks, service marks, and similar rights. \ No newline at end of file diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/examples/fleet-server.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/examples/fleet-server.yaml new file mode 100644 index 00000000..2e0ad3f0 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/examples/fleet-server.yaml @@ -0,0 +1,17 @@ +version: 9.0.0 +deployment: + replicas: 1 + podTemplate: + spec: + serviceAccountName: fleet-server + automountServiceAccountToken: true +elasticsearchRefs: +- name: eck-elasticsearch +kibanaRef: + name: eck-kibana +http: + service: + spec: + type: ClusterIP +serviceAccount: + name: fleet-server diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/NOTES.txt b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/NOTES.txt new file mode 100644 index 00000000..eb3c879d --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/NOTES.txt @@ -0,0 +1,6 @@ + +1. Check Fleet Server status + $ kubectl get agent {{ include "fleet-server.fullname" . }} -n {{ .Release.Namespace }} + +2. Check Fleet Server pod status + $ kubectl get pods --namespace={{ .Release.Namespace }} -l fleet-server.k8s.elastic.co/name={{ include "fleet-server.fullname" . }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/_helpers.tpl b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/_helpers.tpl new file mode 100644 index 00000000..173f5089 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "fleet-server.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "fleet-server.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "fleet-server.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "fleet-server.labels" -}} +helm.sh/chart: {{ include "fleet-server.chart" . }} +{{ include "fleet-server.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.labels }} +{{ toYaml .Values.labels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "fleet-server.selectorLabels" -}} +app.kubernetes.io/name: {{ include "fleet-server.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/cluster-role-binding.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/cluster-role-binding.yaml new file mode 100644 index 00000000..e5fee457 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/cluster-role-binding.yaml @@ -0,0 +1,33 @@ +{{- with .Values.clusterRoleBinding }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .name }} + labels: + {{- include "fleet-server.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or $.Values.annotations .annotations }} + annotations: + {{- with $.Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +{{- with .subjects }} +subjects: +{{- range . }} + - kind: {{ .kind }} + name: {{ .name }} + namespace: {{ .namespace | default $.Release.Namespace | quote }} +{{- end }} +{{- end }} +roleRef: + kind: {{ .roleRef.kind }} + name: {{ .roleRef.name }} + apiGroup: {{ .roleRef.apiGroup }} +{{- end }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/cluster-role.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/cluster-role.yaml new file mode 100644 index 00000000..f067b628 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/cluster-role.yaml @@ -0,0 +1,22 @@ +{{- with .Values.clusterRole }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ .name }} + labels: + {{- include "fleet-server.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or $.Values.annotations .annotations }} + annotations: + {{- with $.Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +rules: {{- toYaml .rules | nindent 2 }} +{{- end }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/fleet-server.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/fleet-server.yaml new file mode 100644 index 00000000..d9eed10e --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/fleet-server.yaml @@ -0,0 +1,23 @@ +--- +apiVersion: agent.k8s.elastic.co/v1alpha1 +kind: Agent +metadata: + name: {{ include "fleet-server.fullname" . }} + labels: + {{- include "fleet-server.labels" . | nindent 4 }} + annotations: + eck.k8s.elastic.co/license: basic + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + version: {{ required "A Fleet Server version is required" .Values.version }} + mode: fleet + fleetServerEnabled: true + {{- if (hasKey .Values.spec "mode") }} + {{- fail "spec.mode cannot be changed" }} + {{- end }} + {{- if (hasKey .Values.spec "fleetServerEnabled") }} + {{- fail "spec.fleetServerEnabled cannot be changed" }} + {{- end }} + {{- toYaml .Values.spec | nindent 2 }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/fleet-server.yaml.bak b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/fleet-server.yaml.bak new file mode 100644 index 00000000..2eb3b0d3 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/fleet-server.yaml.bak @@ -0,0 +1,64 @@ +--- +apiVersion: agent.k8s.elastic.co/v1alpha1 +kind: Agent +metadata: + name: {{ include "fleet-server.fullname" . }} + labels: + {{- include "fleet-server.labels" . | nindent 4 }} + annotations: + eck.k8s.elastic.co/license: basic + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + version: {{ required "A Fleet Server version is required" (or ((.Values.spec).version) (.Values.version)) }} + mode: fleet + fleetServerEnabled: true + {{- if (or (hasKey (.Values.spec) "mode") (hasKey .Values "mode")) }} + {{- fail "mode cannot be changed" }} + {{- end }} + {{- if (or (hasKey (.Values.spec) "fleetServerEnabled") (hasKey .Values "fleetServerEnabled"))}} + {{- fail "fleetServerEnabled cannot be changed" }} + {{- end }} + + {{- $statefulSet := (or (hasKey (.Values.spec) "statefulSet") (hasKey .Values "statefulSet")) }} + {{- $deployment := (or (hasKey (.Values.spec) "deployment") (hasKey .Values "deployment")) }} + {{- if and (not $statefulSet) (not $deployment) }} + {{ fail "At least one of statefulSet or deployment is required" }} + {{- end }} + {{- if $statefulSet }} + {{- $ss := or ((.Values.spec).statefulSet) (.Values.statefulSet) }} + statefulSet: + {{- /* This is required to render the empty statefulSet ( {} ) properly */}} + {{- $ss | default dict | toYaml | nindent 4 }} + {{- end }} + {{- if $deployment }} + {{- $deploy := or ((.Values.spec).deployment) (.Values.deployment) }} + deployment: + {{- /* This is required to render the empty deployment ( {} ) properly */}} + {{- $deploy | default dict | toYaml | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).image) (.Values.image) }} + image: {{ . }} + {{- end }} + {{- with or ((.Values.spec).elasticsearchRefs) (.Values.elasticsearchRefs) }} + elasticsearchRefs: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).kibanaRef) (.Values.kibanaRef) }} + kibanaRef: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).policyID) (.Values.policyID) }} + policyID: {{ . }} + {{- end }} + {{- with or ((.Values.spec).http) (.Values.http) }} + http: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).revisionHistoryLimit) (.Values.revisionHistoryLimit) }} + revisionHistoryLimit: {{ . }} + {{- end }} + {{- with or (((.Values.spec).serviceAccount).name) ((.Values.serviceAccount).name) }} + serviceAccountName: {{ . }} + {{- end }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/service-account.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/service-account.yaml new file mode 100644 index 00000000..0f8901d9 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/templates/service-account.yaml @@ -0,0 +1,22 @@ +{{- with .Values.serviceAccount }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .name }} + namespace: {{ .namespace | default $.Release.Namespace | quote }} + labels: + {{- include "fleet-server.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or $.Values.annotations .annotations }} + annotations: + {{- with $.Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/values.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/values.yaml new file mode 100644 index 00000000..3a9e61c3 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/values.yaml @@ -0,0 +1,129 @@ +--- +# Default values for eck-fleet-server. +# This is a YAML-formatted file. + +# Overridable names of the Fleet Server resource. +# By default, this is the Release name set for the chart, +# followed by 'eck-fleet-server'. +# +# nameOverride will override the name of the Chart with the name set here, +# so nameOverride: quickstart, would convert to '{{ Release.name }}-quickstart' +# +# nameOverride: "quickstart" +# +# fullnameOverride will override both the release name, and the chart name, +# and will name the Fleet Server resource exactly as specified. +# +# fullnameOverride: "quickstart" + +# Version of Elastic Fleet Server. +# +version: 9.0.0 + +# Labels that will be applied to Elastic Fleet Server. +# +labels: {} + +# Annotations that will be applied to Elastic Fleet Server. +# +annotations: {} + +spec: + # policyID determines into which Agent Policy this Fleet Server will be enrolled. + policyID: eck-fleet-server + + # Referenced resources are below and both elasticsearchRefs and kibanaRef are required for a functional Fleet Server. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-beat-configuration.html#k8s-beat-connect-es + # + # Reference to ECK-managed Kibana resource. + # + kibanaRef: + name: eck-kibana + # Optional namespace reference to Kibana resource. + # If not specified, then the namespace of the Fleet Server resource + # will be assumed. + # + # namespace: default + + # References to ECK-managed Elasticsearch resource. + # This is required for fleet server. + # + elasticsearchRefs: + - name: eck-elasticsearch + # Optional namespace reference to Elasticsearch resource. + # If not specified, then the namespace of the Fleet Server resource + # will be assumed. + # + # namespace: default + + # Daemonset, or Deployment specification for the type of Fleet Server specified. + # At least one is required of [daemonSet, deployment]. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-beat-configuration.html#k8s-beat-chose-the-deployment-model + # + deployment: + replicas: 1 + podTemplate: + spec: + serviceAccountName: fleet-server + automountServiceAccountToken: true + securityContext: + runAsUser: 0 + +# ServiceAccount to be used by Elastic Fleet Server. Some Fleet Server features (such as autodiscover or Kubernetes module metricsets) +# require that Fleet Server Pods interact with Kubernetes APIs. This functionality requires specific permissions +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-role-based-access-control +# +serviceAccount: + name: fleet-server + # namespace: optional-namespace + +# ClusterRoleBinding to be used by Elastic Fleet Server. Similar to ServiceAccount, this is required in some scenarios. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-role-based-access-control +# +clusterRoleBinding: + name: fleet-server + subjects: + - kind: ServiceAccount + name: fleet-server + # namespace: default + roleRef: + kind: ClusterRole + name: fleet-server + apiGroup: rbac.authorization.k8s.io + +# ClusterRole to be used by Elastic Fleet Server. Similar to ServiceAccount, this is required in some scenarios. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-role-based-access-control +# +clusterRole: + name: fleet-server + rules: + - apiGroups: [""] + resources: + - pods + - namespaces + - nodes + verbs: + - get + - watch + - list + - apiGroups: ["apps"] + resources: + - replicasets + verbs: + - get + - watch + - list + - apiGroups: ["batch"] + resources: + - jobs + verbs: + - get + - watch + - list + - apiGroups: ["coordination.k8s.io"] + resources: + - leases + verbs: + - get + - create + - update diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/values.yaml.bak b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/values.yaml.bak new file mode 100644 index 00000000..61af1fca --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-fleet-server/values.yaml.bak @@ -0,0 +1,157 @@ +--- +# Default values for eck-fleet-server. +# This is a YAML-formatted file. + +# Overridable names of the Fleet Server resource. +# By default, this is the Release name set for the chart, +# followed by 'eck-fleet-server'. +# +# nameOverride will override the name of the Chart with the name set here, +# so nameOverride: quickstart, would convert to '{{ Release.name }}-quickstart' +# +# nameOverride: "quickstart" +# +# fullnameOverride will override both the release name, and the chart name, +# and will name the Fleet Server resource exactly as specified. +# +# fullnameOverride: "quickstart" + +# Version of Elastic Fleet Server. +# +version: 9.0.0 + +# Labels that will be applied to Elastic Fleet Server. +# +labels: {} + +# Annotations that will be applied to Elastic Fleet Server. +# +annotations: {} + +# Elastic Fleet Server Agent image to deploy. +# +# image: docker.elastic.co/beats/elastic-agent:9.0.0 + +# ** Deprecation Notice ** +# The previous versions of this Helm Chart simply used the `spec` field here +# and allowed the user to specify any fields below `spec` that were templated directly +# into the final Agent/Fleet Server manifest. This is no longer the preferred way to specify these +# fields and each field that is supported underneath `spec` is now directly specified +# in this values file. Currently both patterns are supported for backwards compatibility +# but we plan to remove the `spec` field in the future. +# spec: {} + +# Referenced resources are below and both elasticsearchRefs and kibanaRef are required for a functional Fleet Server. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-setting-referenced-resources +# +# Reference to ECK-managed Kibana instance. +# This is required for Fleet Server. +# +# kibanaRef: +# name: quickstart + # Optional namespace reference to Kibana instance. + # If not specified, then the namespace of the Fleet Server resource + # will be assumed. + # + # namespace: default + +# Reference to ECK-managed Elasticsearch instance. +# This is required for Fleet Server. +# +elasticsearchRefs: [] +# - name: eck-elasticsearch + # Optional namespace reference to Elasticsearch instance. + # If not specified, then the namespace of the Fleet Server resource + # will be assumed. + # + # namespace: default + +# policyID determines into which Agent Policy this Fleet Server will be enrolled. +policyID: eck-fleet-server + +# The HTTP layer configuration for the Fleet Server Service. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-customize-fleet-server-service +# +# http: + +# Deployment or StatefulSet specification for Fleet Server. +# At least one is required of [deployment, statefulSet]. +# No default is currently set, refer to https://github.com/elastic/cloud-on-k8s/issues/7429. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-chose-the-deployment-model +# +# deployment: +# replicas: 1 +# podTemplate: +# spec: +# serviceAccountName: fleet-server +# automountServiceAccountToken: true +# +# statefulSet: +# podTemplate: +# spec: +# serviceAccountName: fleet-server +# automountServiceAccountToken: true + +# Number of revisions to retain to allow rollback in the underlying Deployment. +# If not set Kubernetes sets this to 10 by default. +# +# revisionHistoryLimit: 2 + +# ServiceAccount to be used by Elastic Fleet Server. Some Fleet Server features (such as autodiscover or Kubernetes module metricsets) +# require that Fleet Server Pods interact with Kubernetes APIs. This functionality requires specific permissions +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-role-based-access-control +# +serviceAccount: + name: fleet-server + # namespace: optional-namespace + +# ClusterRoleBinding to be used by Elastic Fleet Server. Similar to ServiceAccount, this is required in some scenarios. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-role-based-access-control +# +clusterRoleBinding: + name: fleet-server + subjects: + - kind: ServiceAccount + name: fleet-server + # namespace: default + roleRef: + kind: ClusterRole + name: fleet-server + apiGroup: rbac.authorization.k8s.io + +# ClusterRole to be used by Elastic Fleet Server. Similar to ServiceAccount, this is required in some scenarios. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-role-based-access-control +# +clusterRole: + name: fleet-server + rules: + - apiGroups: [""] + resources: + - pods + - namespaces + - nodes + verbs: + - get + - watch + - list + - apiGroups: ["apps"] + resources: + - replicasets + verbs: + - get + - watch + - list + - apiGroups: ["batch"] + resources: + - jobs + verbs: + - get + - watch + - list + - apiGroups: ["coordination.k8s.io"] + resources: + - leases + verbs: + - get + - create + - update diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/.helmignore b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/.helmignore new file mode 100644 index 00000000..f1568daf --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/Chart.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/Chart.yaml new file mode 100644 index 00000000..3c45bfd1 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/Chart.yaml @@ -0,0 +1,10 @@ +apiVersion: v2 +description: Kibana managed by the ECK operator +icon: https://helm.elastic.co/icons/kibana.png +kubeVersion: '>= 1.21.0-0' +name: eck-kibana +sources: +- https://github.com/elastic/cloud-on-k8s +- https://github.com/elastic/kibana +type: application +version: 0.15.0 diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/LICENSE b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/LICENSE new file mode 100644 index 00000000..92503a72 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/LICENSE @@ -0,0 +1,93 @@ +Elastic License 2.0 + +URL: https://www.elastic.co/licensing/elastic-license + +## Acceptance + +By using the software, you agree to all of the terms and conditions below. + +## Copyright License + +The licensor grants you a non-exclusive, royalty-free, worldwide, +non-sublicensable, non-transferable license to use, copy, distribute, make +available, and prepare derivative works of the software, in each case subject to +the limitations and conditions below. + +## Limitations + +You may not provide the software to third parties as a hosted or managed +service, where the service provides users with access to any substantial set of +the features or functionality of the software. + +You may not move, change, disable, or circumvent the license key functionality +in the software, and you may not remove or obscure any functionality in the +software that is protected by the license key. + +You may not alter, remove, or obscure any licensing, copyright, or other notices +of the licensor in the software. Any use of the licensor’s trademarks is subject +to applicable law. + +## Patents + +The licensor grants you a license, under any patent claims the licensor can +license, or becomes able to license, to make, have made, use, sell, offer for +sale, import and have imported the software, in each case subject to the +limitations and conditions in this license. This license does not cover any +patent claims that you cause to be infringed by modifications or additions to +the software. If you or your company make any written claim that the software +infringes or contributes to infringement of any patent, your patent license for +the software granted under these terms ends immediately. If your company makes +such a claim, your patent license ends immediately for work on behalf of your +company. + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you +also gets a copy of these terms. + +If you modify the software, you must include in any modified copies of the +software prominent notices stating that you have modified the software. + +## No Other Rights + +These terms do not imply any licenses other than those expressly granted in +these terms. + +## Termination + +If you use the software in violation of these terms, such use is not licensed, +and your licenses will automatically terminate. If the licensor provides you +with a notice of your violation, and you cease all violation of this license no +later than 30 days after you receive that notice, your licenses will be +reinstated retroactively. However, if you violate these terms after such +reinstatement, any additional violation of these terms will cause your licenses +to terminate automatically and permanently. + +## No Liability + +*As far as the law allows, the software comes as is, without any warranty or +condition, and the licensor will not be liable to you for any damages arising +out of these terms or the use or nature of the software, under any kind of +legal claim.* + +## Definitions + +The **licensor** is the entity offering these terms, and the **software** is the +software the licensor makes available under these terms, including any portion +of it. + +**you** refers to the individual or entity agreeing to these terms. + +**your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control over, +are under the control of, or are under common control with that +organization. **control** means ownership of substantially all the assets of an +entity, or the power to direct its management and policies by vote, contract, or +otherwise. Control can be direct or indirect. + +**your licenses** are all the licenses granted to you for the software under +these terms. + +**use** means anything you do with the software requiring one of your licenses. + +**trademark** means trademarks, service marks, and similar rights. \ No newline at end of file diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/examples/http-configuration.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/examples/http-configuration.yaml new file mode 100644 index 00000000..ba0498b4 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/examples/http-configuration.yaml @@ -0,0 +1,36 @@ +--- +# Version of Kibana. +# +version: 9.0.0 + +# Labels that will be applied to Kibana. +# +labels: {} + # key: value + +# Annotations that will be applied to Kibana. +# +annotations: {} + # key: value + +# Count of Kibana replicas to create. +# +count: 1 + +# Reference to ECK-managed Elasticsearch resource, ideally from {{ "elasticsearch.fullname" }} +# +elasticsearchRef: + name: eck-elasticsearch + # namespace: default +http: + service: + spec: + # Type of service to deploy for Kibana. + # This deploys a load balancer in a cloud service provider, where supported. + # + type: LoadBalancer + # tls: + # selfSignedCertificate: + # subjectAltNames: + # - ip: 1.2.3.4 + # - dns: kibana.example.com diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-aks.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-aks.yaml new file mode 100644 index 00000000..b7363dd0 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-aks.yaml @@ -0,0 +1,28 @@ +# The following is an example of a Kibana resource that is configured to use an Ingress resource in an AKS cluster. +# + +# Name of the Kibana instance. +# +fullnameOverride: kibana + +# Reference to ECK-managed Elasticsearch instance, ideally from {{ "elasticsearch.fullname" }} +# +elasticsearchRef: + name: elasticsearch +config: + server: + publicBaseUrl: "https://kibana.company.dev" + +ingress: + enabled: true + className: webapprouting.kubernetes.azure.com + annotations: + # This is required for AKS Loadbalancing to understand that it's communicating with + # an HTTPS backend. + nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" + labels: + my: label + pathType: Prefix + hosts: + - host: "kibana.company.dev" + path: "/" diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-eks.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-eks.yaml new file mode 100644 index 00000000..c5f2f43b --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-eks.yaml @@ -0,0 +1,48 @@ +# The following is an example of a Kibana resource that is configured to use an Ingress resource in an EKS cluster. +# + +# Name of the Kibana instance. +# +fullnameOverride: kibana + +# Reference to ECK-managed Elasticsearch instance, ideally from {{ "elasticsearch.fullname" }} +# +elasticsearchRef: + name: elasticsearch +config: + server: + publicBaseUrl: "https://kibana.company.dev" + +ingress: + enabled: true + className: alb + annotations: + alb.ingress.kubernetes.io/scheme: "internet-facing" + alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]' + alb.ingress.kubernetes.io/backend-protocol: "HTTPS" + alb.ingress.kubernetes.io/target-type: "ip" + # To use an ALB with ECK, you must provide a valid ACM certificate ARN or use certificate discovery. + # There are 2 options for EKS: + # 1. Create a valid ACM certificate, and uncomment the following annotation and update it to the correct ARN. + # 2. Create a valid ACM certificate and ensure that the hosts[0].host matches the certificate's Common Name (CN) and + # certificate discovery *should* find the certificate automatically and use it. + # + # ref: https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.8/guide/ingress/cert_discovery/ + # + # alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:us-east-1:00000000000:certificate/b65be571-8220-4f2e-8cb1-94194535d877" + labels: + my: label + pathType: Prefix + hosts: + - host: "kibana.company.dev" + path: "/" +nodeSets: +- name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-gke.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-gke.yaml new file mode 100644 index 00000000..68307851 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-gke.yaml @@ -0,0 +1,32 @@ +# The following is an example of a Kibana resource that is configured to use an Ingress resource in a GKE cluster. +# + +# Name of the Kibana instance. +# +fullnameOverride: kibana + +# Reference to ECK-managed Elasticsearch instance, ideally from {{ "elasticsearch.fullname" }} +# +elasticsearchRef: + name: elasticsearch +config: + server: + publicBaseUrl: "https://kibana.company.dev" +http: + service: + metadata: + annotations: + # This is required for `ClusterIP` services (which are the default ECK service type) to be used with Ingress in GKE clusters. + cloud.google.com/neg: '{"ingress": true}' + # This is required to enable the GKE Ingress Controller to use HTTPS as the backend protocol. + cloud.google.com/app-protocols: '{"https":"HTTPS"}' + # cloud.google.com/backend-config: '{"default": "kibana"}' + +ingress: + enabled: true + pathType: Prefix + hosts: + - host: "kibana.company.dev" + path: "/" + tls: + enabled: true diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/templates/NOTES.txt b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/templates/NOTES.txt new file mode 100644 index 00000000..9652161c --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/templates/NOTES.txt @@ -0,0 +1,6 @@ + +1. Check Kibana status + $ kubectl get kibana {{ include "kibana.fullname" . }} -n {{ .Release.Namespace }} + +2. Check Kibana pod status + $ kubectl get pods --namespace={{ .Release.Namespace }} -l kibana.k8s.elastic.co/name={{ include "kibana.fullname" . }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/templates/_helpers.tpl b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/templates/_helpers.tpl new file mode 100644 index 00000000..eba5497d --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "kibana.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "kibana.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "kibana.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "kibana.labels" -}} +helm.sh/chart: {{ include "kibana.chart" . }} +{{ include "kibana.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.labels }} +{{ toYaml .Values.labels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "kibana.selectorLabels" -}} +app.kubernetes.io/name: {{ include "kibana.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/templates/ingress.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/templates/ingress.yaml new file mode 100644 index 00000000..171463c0 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/templates/ingress.yaml @@ -0,0 +1,48 @@ +{{- if .Values.ingress.enabled -}} +{{- $pathType := .Values.ingress.pathType | default "Prefix" -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "kibana.fullname" . }} + labels: + {{- include "kibana.labels" . | nindent 4 }} + {{- with .Values.ingress.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.ingress.annotations }} + annotations: + {{- with .Values.ingress.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +spec: + {{- if .Values.ingress.className }} + ingressClassName: {{ .Values.ingress.className | quote }} + {{- end }} + {{- if .Values.ingress.tls.enabled }} + tls: + - hosts: + {{- range .Values.ingress.hosts }} + - {{ .host | quote }} + {{- end }} + {{- if .Values.ingress.tls.secretName }} + secretName: {{ .Values.ingress.tls.secretName }} + {{- else }} + secretName: {{ include "kibana.fullname" . }}-kb-http-certs-internal + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + {{- $hostPath := .path | default "/" }} + - host: {{ .host | quote }} + http: + paths: + - path: {{ $hostPath }} + pathType: {{ $pathType }} + backend: + service: + name: {{ include "kibana.fullname" $ }}-kb-http + port: + number: 5601 + {{- end }} +{{ end }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/templates/kibana.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/templates/kibana.yaml new file mode 100644 index 00000000..2d07efaa --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/templates/kibana.yaml @@ -0,0 +1,61 @@ +--- +apiVersion: kibana.k8s.elastic.co/v1 +kind: Kibana +metadata: + name: {{ include "kibana.fullname" . }} + labels: + {{- include "kibana.labels" . | nindent 4 }} + annotations: + eck.k8s.elastic.co/license: basic + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + version: {{ required "A Kibana version is required" .Values.version }} + {{- /* + The following templates with 'or' are to allow both .spec.field and .field to be set for backwards + compatibility purposes. See https://github.com/elastic/cloud-on-k8s/pull/8192 for details. + */ -}} + {{- with or ((.Values.spec).image) (.Values.image) }} + image: {{ . }} + {{- end }} + {{- with or ((.Values.spec).count) (.Values.count) }} + count: {{ . }} + {{- end }} + {{- $esRef := or ((.Values.spec).elasticsearchRef) (.Values.elasticsearchRef) }} + {{- if not ($esRef).name }} + {{ fail "An elasticsearchRef is required" }} + {{- end }} + elasticsearchRef: + {{- toYaml $esRef | nindent 4 }} + {{- $entsearchRef := or ((.Values.spec).enterpriseSearchRef) (.Values.enterpriseSearchRef) }} + {{- if $entsearchRef }} + enterpriseSearchRef: + {{- toYaml $entsearchRef | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).config) (.Values.config) }} + config: + {{ toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).http) (.Values.http) }} + http: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).podTemplate) (.Values.podTemplate) }} + podTemplate: + {{ toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).revisionHistoryLimit) (.Values.revisionHistoryLimit) }} + revisionHistoryLimit: {{ . }} + {{- end }} + {{- with or ((.Values.spec).secureSettings) (.Values.secureSettings) }} + secureSettings: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).serviceAccountName) (.Values.serviceAccountName) }} + serviceAccountName: {{ . }} + {{- end }} + {{- with or ((.Values.spec).monitoring) (.Values.monitoring) }} + monitoring: + {{- toYaml . | nindent 4 }} + {{- end }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/values.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/values.yaml new file mode 100644 index 00000000..a406b07d --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-kibana/values.yaml @@ -0,0 +1,179 @@ +--- +# Default values for eck-kibana. +# This is a YAML-formatted file. + +# Overridable names of the Kibana resource. +# By default, this is the Release name set for the chart, +# followed by 'eck-kibana'. +# +# nameOverride will override the name of the Chart with the name set here, +# so nameOverride: quickstart, would convert to '{{ Release.name }}-quickstart' +# +# nameOverride: "quickstart" +# +# fullnameOverride will override both the release name, and the chart name, +# and will name the Kibana resource exactly as specified. +# +# fullnameOverride: "quickstart" + +# Version of Kibana. +# +version: 9.0.0 + +# Kibana Docker image to deploy +# +# image: docker.elastic.co/kibana/kibana:9.0.0 + +# Labels that will be applied to Kibana. +# +labels: {} + +# Annotations that will be applied to Kibana. +# +annotations: {} + +# ** Deprecation Notice ** +# The previous versions of this Helm Chart simply used the `spec` field here +# and allowed the user to specify any fields below spec that were templated directly +# into the final Kibana manifest. This is no long the preferred way to specify these +# fields and each field that is supported underneath `spec` is now directly specified +# in this values file. Currently both patterns are supported for backwards compatibility +# but we plan to remove the `spec` field in the future. +# spec: {} + +# Count of Kibana replicas to create. +# +count: 1 + +# Reference to ECK-managed Elasticsearch resource. +# +elasticsearchRef: {} + # name: eck-elasticsearch + # Optional namespace reference to Elasticsearch resource. + # If not specified, then the namespace of the Kibana resource + # will be assumed. + # + # namespace: default + +# Reference to an EnterpriseSearch running in the same Kubernetes cluster +# +# enterpriseSearchRef: + +# The Kibana configuration (kibana.yml) +# ref: https://www.elastic.co/guide/en/kibana/current/settings.html +# +config: null + +# The HTTP layer configuration for Kibana. +# +# http: + +# PodTemplate provides customisation options (labels, annotations, affinity rules, +# resource requests, and so on) for the Kibana pods +# +# podTemplate: + +# Number of revisions to retain to allow rollback in the underlying deployment. +# By default, if not set, Kubernetes sets 10. +# +# revisionHistoryLimit: 2 + +# Control Kibana Secure Settings. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-kibana-secure-settings.html +# +secureSettings: [] + +# Used to check access from the current resource to a resource (for ex. Elasticsearch) in a different namespace. +# Can only be used if ECK is enforcing RBAC on references. +# +# serviceAccountName: "" + +# Settings for configuring stack monitoring. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-stack-monitoring.html +# +monitoring: {} + # metrics: + # elasticsearchRefs: + # - name: monitoring + # namespace: observability + # logs: + # elasticsearchRefs: + # - name: monitoring + # namespace: observability + +# Settings for controlling Kibana ingress. Enabling ingress will expose your Kibana instance +# to the public internet, and as such is disabled by default. +# +# *NOTE* when configuring Kibana Ingress, ensure that `config.server.publicBaseUrl` setting for +# Kibana is also set, as it is required when exposing Kibana behind a load balancer/ingress. +# Also of note are `server.basePath`, and `server.rewriteBasePath` settings in the Kibana configuration. +# +# ref: https://www.elastic.co/guide/en/kibana/current/settings.html +# +# Each Cloud Service Provider has different requirements for setting up Ingress. Some links to common documentation are: +# - AWS: https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html +# - GCP: https://cloud.google.com/kubernetes-engine/docs/concepts/ingress +# - Azure: https://learn.microsoft.com/en-us/azure/aks/app-routing +# - Nginx: https://kubernetes.github.io/ingress-nginx/ +# +ingress: + enabled: false + + # Annotations that will be applied to the Ingress resource. Note that some ingress controllers are controlled via annotations. + # + # Nginx Annotations: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/ + # + # Common annotations: + # kubernetes.io/ingress.class: gce # Configures the Ingress resource to use the GCE ingress controller and create an external Application Load Balancer. + # kubernetes.io/ingress.class: gce-internal # Configures the Ingress resource to use the GCE ingress controller and create an internal Application Load Balancer. + # kubernetes.io/ingress.class: nginx # Configures the Ingress resource to use the NGINX ingress controller. + # + annotations: {} + + # Labels that will be applied to the Ingress resource. + # + labels: {} + + # Some ingress controllers require the use of a specific class name to route traffic to the correct controller, notably AKS and EKS, which + # replaces the use of the 'kubernetes.io/ingress.class' annotation. + # + # className: webapprouting.kubernetes.azure.com | alb + + # Ingress paths are required to have a corresponding path type. Defaults to 'Prefix'. + # + # There are 3 supported path types: + # - ImplementationSpecific + # - Prefix + # - Exact + # + # ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#path-types + # + pathType: Prefix + + # Hosts are a list of hosts included in the Ingress definition, with a corresponding path at which the Kibana service + # will be exposed. Each host in the list should be a fully qualified DNS name that will resolve to the exposed Ingress object. + # + # ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#name-based-virtual-hosting + # + hosts: + - host: chart-example.local + path: / + + # TLS defines whether TLS will be enabled on the Ingress resource. + # + # *NOTE* Many Cloud Service Providers handle TLS in a custom manner, and as such, it is recommended to consult their documentation. + # Notably GKE and Nginx Ingress Controllers seems to respect the Ingress TLS settings, AKS and EKS ignore it. + # + # - AKS: https://learn.microsoft.com/en-us/azure/aks/app-routing-dns-ssl + # - GKE: https://cloud.google.com/kubernetes-engine/docs/concepts/ingress#options_for_providing_ssl_certificates + # - EKS: https://aws.amazon.com/blogs/containers/serve-distinct-domains-with-tls-powered-by-acm-on-amazon-eks/ + # - Nginx: https://kubernetes.github.io/ingress-nginx/user-guide/tls/ + # + # Kubernetes ingress TLS documentation: + # ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#tls + # + tls: + enabled: false + # Optional Kubernetes secret name that contains a base64 encoded PEM certificate and private key that corresponds to the above 'hosts' definitions. + # If tls is enabled, but this field is not set, the self-signed certificate and key created by the ECK operator will be used. + # secretName: chart-example-tls diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/.helmignore b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/.helmignore new file mode 100644 index 00000000..f1568daf --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/Chart.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/Chart.yaml new file mode 100644 index 00000000..177a5d28 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/Chart.yaml @@ -0,0 +1,10 @@ +apiVersion: v2 +description: Logstash managed by the ECK operator +icon: https://helm.elastic.co/icons/logstash.png +kubeVersion: '>= 1.21.0-0' +name: eck-logstash +sources: +- https://github.com/elastic/cloud-on-k8s +- https://github.com/elastic/logstash +type: application +version: 0.15.0 diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/LICENSE b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/LICENSE new file mode 100644 index 00000000..92503a72 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/LICENSE @@ -0,0 +1,93 @@ +Elastic License 2.0 + +URL: https://www.elastic.co/licensing/elastic-license + +## Acceptance + +By using the software, you agree to all of the terms and conditions below. + +## Copyright License + +The licensor grants you a non-exclusive, royalty-free, worldwide, +non-sublicensable, non-transferable license to use, copy, distribute, make +available, and prepare derivative works of the software, in each case subject to +the limitations and conditions below. + +## Limitations + +You may not provide the software to third parties as a hosted or managed +service, where the service provides users with access to any substantial set of +the features or functionality of the software. + +You may not move, change, disable, or circumvent the license key functionality +in the software, and you may not remove or obscure any functionality in the +software that is protected by the license key. + +You may not alter, remove, or obscure any licensing, copyright, or other notices +of the licensor in the software. Any use of the licensor’s trademarks is subject +to applicable law. + +## Patents + +The licensor grants you a license, under any patent claims the licensor can +license, or becomes able to license, to make, have made, use, sell, offer for +sale, import and have imported the software, in each case subject to the +limitations and conditions in this license. This license does not cover any +patent claims that you cause to be infringed by modifications or additions to +the software. If you or your company make any written claim that the software +infringes or contributes to infringement of any patent, your patent license for +the software granted under these terms ends immediately. If your company makes +such a claim, your patent license ends immediately for work on behalf of your +company. + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you +also gets a copy of these terms. + +If you modify the software, you must include in any modified copies of the +software prominent notices stating that you have modified the software. + +## No Other Rights + +These terms do not imply any licenses other than those expressly granted in +these terms. + +## Termination + +If you use the software in violation of these terms, such use is not licensed, +and your licenses will automatically terminate. If the licensor provides you +with a notice of your violation, and you cease all violation of this license no +later than 30 days after you receive that notice, your licenses will be +reinstated retroactively. However, if you violate these terms after such +reinstatement, any additional violation of these terms will cause your licenses +to terminate automatically and permanently. + +## No Liability + +*As far as the law allows, the software comes as is, without any warranty or +condition, and the licensor will not be liable to you for any damages arising +out of these terms or the use or nature of the software, under any kind of +legal claim.* + +## Definitions + +The **licensor** is the entity offering these terms, and the **software** is the +software the licensor makes available under these terms, including any portion +of it. + +**you** refers to the individual or entity agreeing to these terms. + +**your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control over, +are under the control of, or are under common control with that +organization. **control** means ownership of substantially all the assets of an +entity, or the power to direct its management and policies by vote, contract, or +otherwise. Control can be direct or indirect. + +**your licenses** are all the licenses granted to you for the software under +these terms. + +**use** means anything you do with the software requiring one of your licenses. + +**trademark** means trademarks, service marks, and similar rights. \ No newline at end of file diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/examples/basic-eck.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/examples/basic-eck.yaml new file mode 100644 index 00000000..ed29db80 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/examples/basic-eck.yaml @@ -0,0 +1,44 @@ +--- +# values corresponding to config/recipes/logstash/logstash-eck.yaml +version: 9.0.0 + +elasticsearchRefs: + - clusterName: eck + name: elasticsearch + +pipelines: + - pipeline.id: main + config.string: | + input { + beats { + port => 5044 + } + } + filter { + grok { + match => { "message" => "%{HTTPD_COMMONLOG}"} + } + geoip { + source => "[source][address]" + target => "[source]" + } + } + output { + elasticsearch { + hosts => [ "${ECK_ES_HOSTS}" ] + user => "${ECK_ES_USER}" + password => "${ECK_ES_PASSWORD}" + ssl_certificate_authorities => "${ECK_ES_SSL_CERTIFICATE_AUTHORITY}" + } + } + +services: + - name: beats + service: + spec: + type: ClusterIP + ports: + - port: 5044 + name: "filebeat" + protocol: TCP + targetPort: 5044 diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/examples/es-role.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/examples/es-role.yaml new file mode 100644 index 00000000..b0451e25 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/examples/es-role.yaml @@ -0,0 +1,25 @@ +--- +# values corresponding to config/recipes/logstash/logstash-es-role.yaml +version: 9.0.0 + +elasticsearchRefs: + - clusterName: eck + name: elasticsearch + +pipelines: + - pipeline.id: main + config.string: | + input { exec { command => "uptime" interval => 10 } } + output { + elasticsearch { + hosts => [ "${ECK_ES_HOSTS}" ] + ssl_enabled => true + ssl_certificate_authorities => "${ECK_ES_SSL_CERTIFICATE_AUTHORITY}" + user => "${ECK_ES_USER}" + password => "${ECK_ES_PASSWORD}" + index => "my-index" + data_stream => false + ilm_enabled => false + manage_template => false + } + } diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/examples/monitored.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/examples/monitored.yaml new file mode 100644 index 00000000..b5102ce9 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/examples/monitored.yaml @@ -0,0 +1,49 @@ +--- +# values corresponding to config/recipes/logstash/logstash-monitored.yaml +version: 9.0.0 + +monitoring: + metrics: + elasticsearchRefs: + - name: elasticsearch-monitoring + +pipelines: + - pipeline.id: main + config.string: | + input { + beats { + port => 5044 + } + } + filter { + grok { + match => { "message" => "%{HTTPD_COMMONLOG}"} + } + geoip { + source => "[source][address]" + target => "[source]" + } + } + output { + elasticsearch { + hosts => [ "${ECK_ES_HOSTS}" ] + user => "${ECK_ES_USER}" + password => "${ECK_ES_PASSWORD}" + ssl_certificate_authorities => "${ECK_ES_SSL_CERTIFICATE_AUTHORITY}" + } + } + +elasticsearchRefs: + - clusterName: eck + name: elasticsearch + +services: + - name: beats + service: + spec: + type: ClusterIP + ports: + - port: 5044 + name: "filebeat" + protocol: TCP + targetPort: 5044 diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/examples/multi.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/examples/multi.yaml new file mode 100644 index 00000000..aeecbd2d --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/examples/multi.yaml @@ -0,0 +1,78 @@ +--- +# values corresponding to config/recipes/logstash/logstash-multi.yaml +version: 9.0.0 + +pipelines: + - pipeline.id: main + config.string: | + input { + beats { + port => 5044 + } + } + filter { + grok { + match => { "message" => "%{HTTPD_COMMONLOG}"} + } + geoip { + source => "[source][address]" + target => "[source]" + } + } + output { + pipeline { + send_to => 'prod' + } + pipeline { + send_to => 'qa' + } + } + - pipeline.id: production + config.string: | + input { + pipeline { + address => 'prod' + } + } + output { + elasticsearch { + hosts => [ "${PROD_ES_ES_HOSTS}" ] + user => "${PROD_ES_ES_USER}" + password => "${PROD_ES_ES_PASSWORD}" + ssl_certificate_authorities => "${PROD_ES_ES_SSL_CERTIFICATE_AUTHORITY}" + } + } + - pipeline.id: qa + config.string: | + input { + pipeline { + address => 'qa' + } + } + output { + elasticsearch { + hosts => [ "${QA_ES_ES_HOSTS}" ] + user => "${QA_ES_ES_USER}" + password => "${QA_ES_ES_PASSWORD}" + ssl_certificate_authorities => "${QA_ES_ES_SSL_CERTIFICATE_AUTHORITY}" + } + } + +elasticsearchRefs: + - clusterName: prod-es + name: production + - clusterName: qa-es + name: qa + namespace: qa + +services: + - name: beats + service: + spec: + type: ClusterIP + ports: + - port: 5044 + name: "filebeat" + protocol: TCP + targetPort: 5044 + diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/examples/volumes.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/examples/volumes.yaml new file mode 100644 index 00000000..6209f3df --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/examples/volumes.yaml @@ -0,0 +1,107 @@ +--- +# values corresponding to config/recipes/logstash/logstash-volumes.yaml +version: 9.0.0 + +config: + log.level: info + queue.type: persisted + path.queue: /usr/share/logstash/pq + +podTemplate: + spec: + containers: + - name: logstash + volumeMounts: + - mountPath: /usr/share/logstash/pq + name: pq + readOnly: false + - mountPath: /usr/share/logstash/dlq + name: dlq + readOnly: false + +pipelines: + - pipeline.id: dlq_read + dead_letter_queue.enable: false + config.string: | + input { + dead_letter_queue { + path => "/usr/share/logstash/dlq" + commit_offsets => true + pipeline_id => "beats" + clean_consumed => true + } + } + filter { + mutate { + remove_field => "[geoip][location]" + } + } + output { + elasticsearch { + hosts => [ "${ECK_ES_HOSTS}" ] + user => "${ECK_ES_USER}" + password => "${ECK_ES_PASSWORD}" + ssl_certificate_authorities => "${ECK_ES_SSL_CERTIFICATE_AUTHORITY}" + } + } + - pipeline.id: beats + dead_letter_queue.enable: true + path.dead_letter_queue: /usr/share/logstash/dlq + config.string: | + input { + beats { + port => 5044 + } + } + filter { + grok { + match => { "message" => "%{HTTPD_COMMONLOG}"} + } + geoip { + source => "[source][address]" + target => "[source]" + } + } + output { + elasticsearch { + hosts => [ "${ECK_ES_HOSTS}" ] + user => "${ECK_ES_USER}" + password => "${ECK_ES_PASSWORD}" + ssl_certificate_authorities => "${ECK_ES_SSL_CERTIFICATE_AUTHORITY}" + } + } + +volumeClaimTemplates: + - metadata: + name: pq + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + - metadata: + name: dlq + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi + + +elasticsearchRefs: + - clusterName: eck + name: elasticsearch + +services: + - name: beats + service: + spec: + type: ClusterIP + ports: + - port: 5044 + name: "filebeat" + protocol: TCP + targetPort: 5044 + diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/templates/NOTES.txt b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/templates/NOTES.txt new file mode 100644 index 00000000..c2f255af --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/templates/NOTES.txt @@ -0,0 +1,6 @@ + +1. Check Logstash status + $ kubectl get logstash {{ include "logstash.fullname" . }} -n {{ .Release.Namespace }} + +2. Check Logstash pod status + $ kubectl get pods --namespace={{ .Release.Namespace }} -l logstash.k8s.elastic.co/name={{ include "logstash.fullname" . }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/templates/_helpers.tpl b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/templates/_helpers.tpl new file mode 100644 index 00000000..7efd669f --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "logstash.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "logstash.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "logstash.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "logstash.labels" -}} +helm.sh/chart: {{ include "logstash.chart" . }} +{{ include "logstash.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.labels }} +{{ toYaml .Values.labels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "logstash.selectorLabels" -}} +app.kubernetes.io/name: {{ include "logstash.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/templates/logstash.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/templates/logstash.yaml new file mode 100644 index 00000000..8ba52ef6 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/templates/logstash.yaml @@ -0,0 +1,58 @@ +--- +apiVersion: logstash.k8s.elastic.co/v1alpha1 +kind: Logstash +metadata: + name: {{ include "logstash.fullname" . }} + labels: + {{- include "logstash.labels" . | nindent 4 }} + annotations: + eck.k8s.elastic.co/license: basic + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + version: {{ required "A Logstash version is required" .Values.version }} + count: {{ required "A pod count is required" .Values.count }} + {{- with .Values.image }} + image: {{ . }} + {{- end }} + {{- with .Values.serviceAccountName }} + serviceAccountName: {{ . }} + {{- end }} + {{- with .Values.revisionHistoryLimit }} + revisionHistoryLimit: {{ . }} + {{- end }} + + {{- if and .Values.config .Values.configRef }} + {{- fail "config and configRef are mutually exclusive!" }} + {{- end }} + {{- with .Values.config }} + config: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.configRef }} + configRef: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.podTemplate }} + podTemplate: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.monitoring }} + monitoring: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if and .Values.pipelines .Values.pipelinesRef }} + {{- fail "pipelines and pipelinesRef are mutually exclusive!" }} + {{- end }} + {{- with .Values.pipelinesRef }} + pipelinesRef: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.pipelines }} + pipelines: {{ toYaml .Values.pipelines | nindent 4 }} + {{- end }} + volumeClaimTemplates: {{ toYaml .Values.volumeClaimTemplates | nindent 4 }} + elasticsearchRefs: {{ toYaml .Values.elasticsearchRefs | nindent 4 }} + services: {{ toYaml .Values.services | nindent 4 }} + secureSettings: {{ toYaml .Values.secureSettings | nindent 4 }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/values.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/values.yaml new file mode 100644 index 00000000..cd75fcc6 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/charts/eck-logstash/values.yaml @@ -0,0 +1,115 @@ +--- +# Default values for eck-logstash. +# This is a YAML-formatted file. + +# Overridable names of the Logstash resource. +# By default, this is the Release name set for the chart, +# followed by 'eck-logstash'. +# +# nameOverride will override the name of the Chart with the name set here, +# so nameOverride: quickstart, would convert to '{{ Release.name }}-quickstart' +# +# nameOverride: "quickstart" +# +# fullnameOverride will override both the release name, and the chart name, +# and will name the Logstash resource exactly as specified. +# +# fullnameOverride: "quickstart" + +# Version of Logstash. +# +version: 9.0.0 + +# Logstash Docker image to deploy +# +# image: + +# Used to check access from the current resource to a resource (for ex. a remote Elasticsearch cluster) in a different namespace. +# Can only be used if ECK is enforcing RBAC on references. +# +# serviceAccountName: "" + +# Labels that will be applied to Logstash. +# +labels: {} + +# Annotations that will be applied to Logstash. +# +annotations: {} + +# Number of revisions to retain to allow rollback in the underlying StatefulSets. +# By default, if not set, Kubernetes sets 10. +# +# revisionHistoryLimit: 2 + +# Controlling the number of pods. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-logstash-scaling-logstash.html +# +count: 1 + +# The logstash configuration, the ECK equivalent to logstash.yml +# +# NOTE: The `config` and `configRef` fields are mutually exclusive. Only one of them should be defined at a time, +# as using both may cause conflicts. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-logstash-configuration.html#k8s-logstash-configuring-logstash +# +config: {} + +# Reference a configuration in a Secret. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-logstash-configuration.html#k8s-logstash-configuring-logstash +# +# configRef: +# secretName: '' + +# Set podTemplate to customize the pod used by Logstash +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-customize-pods.html +# +podTemplate: {} + +# Settings for configuring stack monitoring. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-stack-monitoring.html +# +monitoring: {} + # metrics: + # elasticsearchRefs: + # - name: monitoring + # namespace: observability + # logs: + # elasticsearchRefs: + # - name: monitoring + # namespace: observability + +# The Logstash pipelines, the ECK equivalent to pipelines.yml +# +# NOTE: The `pipelines` and `pipelinesRef` fields are mutually exclusive. Only one of them should be defined at a time, +# as using both may cause conflicts. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-logstash-configuration.html#k8s-logstash-pipelines +# +pipelines: [] + +# Reference a pipelines configuration in a Secret. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-logstash-configuration.html#k8s-logstash-pipelines +# +# pipelinesRef: +# secretName: '' + +# volumeClaimTemplates +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-logstash-configuration.html#k8s-volume-claim-settings +# +volumeClaimTemplates: [] + +# ElasticsearchRefs are references to Elasticsearch clusters running in the same Kubernetes cluster. +# Ensure that the 'clusterName' field matches what is referenced in the pipeline. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-logstash-configuration.html#k8s-logstash-pipelines-es +# +elasticsearchRefs: [] +# - namespace: '' +# name: '' +# clusterName: '' +# serviceName: '' +# secretName: '' + +services: [] + +# SecureSettings is a list of references to Kubernetes Secrets containing sensitive configuration options for the Logstash +secureSettings: [] diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/examples/agent/fleet-agents.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/examples/agent/fleet-agents.yaml new file mode 100644 index 00000000..4358b6f6 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/examples/agent/fleet-agents.yaml @@ -0,0 +1,122 @@ +--- +eck-elasticsearch: + enabled: true + + # Name of the Elasticsearch instance. + # + fullnameOverride: elasticsearch + + nodeSets: + - name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false + +eck-kibana: + enabled: true + + # Name of the Kibana instance. + # + fullnameOverride: kibana + + # Reference to ECK-managed Elasticsearch instance, ideally from {{ "elasticsearch.fullname" }} + # + elasticsearchRef: + name: elasticsearch + + config: + # Note that these are specific to the namespace into which this example is installed, and are + # using `elastic-stack` as configured here and detailed in the README when installing: + # + # `helm install es-kb-quickstart elastic/eck-stack -n elastic-stack` + # + # If installed outside of the `elastic-stack` namespace, the following 2 lines need modification. + xpack.fleet.agents.elasticsearch.hosts: ["https://elasticsearch-es-http.elastic-stack.svc:9200"] + xpack.fleet.agents.fleet_server.hosts: ["https://fleet-server-agent-http.elastic-stack.svc:8220"] + xpack.fleet.packages: + - name: system + version: latest + - name: elastic_agent + version: latest + - name: fleet_server + version: latest + - name: kubernetes + version: latest + xpack.fleet.agentPolicies: + - name: Fleet Server on ECK policy + id: eck-fleet-server + namespace: default + is_managed: true + monitoring_enabled: + - logs + - metrics + package_policies: + - name: fleet_server-1 + id: fleet_server-1 + package: + name: fleet_server + - name: Elastic Agent on ECK policy + id: eck-agent + namespace: default + is_managed: true + monitoring_enabled: + - logs + - metrics + unenroll_timeout: 900 + package_policies: + - package: + name: system + name: system-1 + - package: + name: kubernetes + name: kubernetes-1 + +eck-agent: + enabled: true + + # Agent policy to be used. + policyID: eck-agent + # Reference to ECK-managed Kibana instance. + # + kibanaRef: + name: kibana + elasticsearchRefs: [] + # Reference to ECK-managed Fleet instance. + # + fleetServerRef: + name: fleet-server + + mode: fleet + daemonSet: + podTemplate: + spec: + serviceAccountName: elastic-agent + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + automountServiceAccountToken: true + securityContext: + runAsUser: 0 + +eck-fleet-server: + enabled: true + + fullnameOverride: "fleet-server" + + deployment: + replicas: 1 + podTemplate: + spec: + serviceAccountName: fleet-server + automountServiceAccountToken: true + + # Agent policy to be used. + policyID: eck-fleet-server + kibanaRef: + name: kibana + elasticsearchRefs: + - name: elasticsearch diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/examples/apm-server/basic.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/examples/apm-server/basic.yaml new file mode 100644 index 00000000..227b5825 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/examples/apm-server/basic.yaml @@ -0,0 +1,52 @@ +--- +eck-elasticsearch: + enabled: true + + # Name of the Elasticsearch instance. + # + fullnameOverride: elasticsearch + + nodeSets: + - name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false + +eck-kibana: + enabled: true + + # Name of the Kibana instance. + # + fullnameOverride: kibana + + spec: + config: + xpack.fleet.packages: + - name: apm + version: latest + +eck-apm-server: + enabled: true + + # Count of APM Server replicas to create. + # + count: 1 + + # Reference to ECK-managed Elasticsearch resource. + # + elasticsearchRef: + name: elasticsearch + kibanaRef: + name: kibana + http: + service: + spec: + ports: + - name: http + port: 8200 + targetPort: 8200 diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/examples/apm-server/jaeger-with-http-configuration.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/examples/apm-server/jaeger-with-http-configuration.yaml new file mode 100644 index 00000000..b694955f --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/examples/apm-server/jaeger-with-http-configuration.yaml @@ -0,0 +1,60 @@ +--- +eck-elasticsearch: + enabled: true + + # Name of the Elasticsearch instance. + # + fullnameOverride: elasticsearch + + nodeSets: + - name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false + +eck-kibana: + enabled: true + + # Name of the Kibana instance. + # + fullnameOverride: kibana + + spec: + config: + xpack.fleet.packages: + - name: apm + version: latest + +eck-apm-server: + enabled: true + + # Count of APM Server replicas to create. + # + count: 1 + + config: + name: elastic-apm + apm-server.jaeger.grpc.enabled: true + apm-server.jaeger.grpc.host: "0.0.0.0:14250" + + # Reference to ECK-managed Elasticsearch resource. + # + elasticsearchRef: + name: elasticsearch + kibanaRef: + name: kibana + http: + service: + spec: + ports: + - name: http + port: 8200 + targetPort: 8200 + - name: grpc + port: 14250 + targetPort: 14250 diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/examples/beats/metricbeat_hosts.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/examples/beats/metricbeat_hosts.yaml new file mode 100644 index 00000000..079de594 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/examples/beats/metricbeat_hosts.yaml @@ -0,0 +1,217 @@ +eck-elasticsearch: + enabled: true + + # Name of the Elasticsearch resource. + # + fullnameOverride: quickstart + + # Version of Elasticsearch. + # + version: 9.0.0 + + nodeSets: + - name: default + count: 3 + config: + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + node.store.allow_mmap: false + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 100Gi + # Adjust to your storage class name + # + # storageClassName: local-storage + +eck-kibana: + enabled: true + + # Name of the Kibana resource. + # + fullnameOverride: quickstart + + # Version of Kibana. + # + version: 9.0.0 + + spec: + # Count of Kibana replicas to create. + # + count: 1 + + # Reference to ECK-managed Elasticsearch resource, ideally from {{ "elasticsearch.fullname" }} + # + elasticsearchRef: + name: quickstart + +eck-beats: + enabled: true + name: metricbeat + type: metricbeat + version: 9.0.0 + elasticsearchRef: + name: quickstart + kibanaRef: + name: quickstart + config: + # Since filebeat is used in the default values, this needs to be removed with an empty list. + filebeat.inputs: [] + metricbeat: + autodiscover: + providers: + - hints: + default_config: {} + enabled: "true" + node: ${NODE_NAME} + type: kubernetes + modules: + - module: system + period: 10s + metricsets: + - cpu + - load + - memory + - network + - process + - process_summary + process: + include_top_n: + by_cpu: 5 + by_memory: 5 + processes: + - .* + - module: system + period: 1m + metricsets: + - filesystem + - fsstat + processors: + - drop_event: + when: + regexp: + system: + filesystem: + mount_point: ^/(sys|cgroup|proc|dev|etc|host|lib)($|/) + - module: kubernetes + period: 10s + node: ${NODE_NAME} + hosts: + - https://${NODE_NAME}:10250 + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + ssl: + verification_mode: none + metricsets: + - node + - system + - pod + - container + - volume + processors: + - add_cloud_metadata: {} + - add_host_metadata: {} + daemonSet: + podTemplate: + spec: + serviceAccountName: metricbeat + automountServiceAccountToken: true # some older Beat versions are depending on this settings presence in k8s context + containers: + - args: + - -e + - -c + - /etc/beat.yml + - --system.hostfs=/hostfs + name: metricbeat + volumeMounts: + - mountPath: /hostfs/sys/fs/cgroup + name: cgroup + - mountPath: /var/run/docker.sock + name: dockersock + - mountPath: /hostfs/proc + name: proc + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + dnsPolicy: ClusterFirstWithHostNet + hostNetwork: true # Allows to provide richer host metadata + securityContext: + runAsUser: 0 + terminationGracePeriodSeconds: 30 + volumes: + - hostPath: + path: /sys/fs/cgroup + name: cgroup + - hostPath: + path: /var/run/docker.sock + name: dockersock + - hostPath: + path: /proc + name: proc + + clusterRole: + # permissions needed for metricbeat + # source: https://www.elastic.co/guide/en/beats/metricbeat/current/metricbeat-module-kubernetes.html + name: metricbeat + rules: + - apiGroups: + - "" + resources: + - nodes + - namespaces + - events + - pods + verbs: + - get + - list + - watch + - apiGroups: + - "extensions" + resources: + - replicasets + verbs: + - get + - list + - watch + - apiGroups: + - apps + resources: + - statefulsets + - deployments + - replicasets + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - nodes/stats + verbs: + - get + - nonResourceURLs: + - /metrics + verbs: + - get + + serviceAccount: + name: metricbeat + + clusterRoleBinding: + name: metricbeat + subjects: + - kind: ServiceAccount + name: metricbeat + roleRef: + kind: ClusterRole + name: metricbeat + apiGroup: rbac.authorization.k8s.io diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/examples/custom-elasticsearch-kibana.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/examples/custom-elasticsearch-kibana.yaml new file mode 100644 index 00000000..ca702acd --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/examples/custom-elasticsearch-kibana.yaml @@ -0,0 +1,78 @@ +--- +eck-elasticsearch: + # Name of the Elasticsearch resource. + # + fullnameOverride: quickstart + + # Version of Elasticsearch. + # + version: 9.0.0 + + nodeSets: + - name: default + count: 1 + config: + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 100Gi + # Adjust to your storage class name + # + # storageClassName: local-storage + +eck-kibana: + # Name of the Kibana resource. + # + fullnameOverride: quickstart + + # Version of Kibana. + # + version: 9.0.0 + + spec: + # Count of Kibana replicas to create. + # + count: 1 + + # Reference to ECK-managed Elasticsearch resource, ideally from {{ "elasticsearch.fullname" }} + # + elasticsearchRef: + name: quickstart + # namespace: default + http: + service: + spec: + # Type of service to deploy for Kibana. + # This deploys a load balancer in a cloud service provider, where supported. + # + type: LoadBalancer + # tls: + # selfSignedCertificate: + # subjectAltNames: + # - ip: 1.2.3.4 + # - dns: kibana.example.com + podTemplate: + spec: + containers: + - name: kibana + env: + - name: NODE_OPTIONS + value: "--max-old-space-size=2048" + resources: + requests: + memory: 1Gi + cpu: 0.5 + limits: + memory: 2.5Gi + cpu: 2 diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/examples/elasticsearch/hot-warm-cold.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/examples/elasticsearch/hot-warm-cold.yaml new file mode 100644 index 00000000..919cb4c7 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/examples/elasticsearch/hot-warm-cold.yaml @@ -0,0 +1,199 @@ +--- +eck-elasticsearch: + nodeSets: + - name: masters + count: 1 + config: + node.roles: ["master"] + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + spec: + containers: + - name: elasticsearch + resources: + limits: + memory: 8Gi + cpu: 2 + # Affinity/Anti-affinity settings for controlling the 'spreading' of Elasticsearch + # pods across existing hosts. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html#k8s-affinity-options + # + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: beta.kubernetes.io/instance-type + # operator: In + # # This should be adjusted to the instance type according to your setup + # # + # values: + # - highio + # Volume Claim settings. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-volume-claim-templates.html + # + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Ti + # Adjust to your storage class name + # + # storageClassName: local-storage + - name: hot + count: 1 + config: + node.roles: ["data_hot", "data_content", "ingest"] + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + spec: + containers: + - name: elasticsearch + resources: + limits: + memory: 16Gi + cpu: 4 + # Affinity/Anti-affinity settings for controlling the 'spreading' of Elasticsearch + # pods across existing hosts. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html#k8s-affinity-options + # + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: beta.kubernetes.io/instance-type + # operator: In + # # This should be adjusted to the instance type according to your setup + # # + # values: + # - highio + # Volume Claim settings. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-volume-claim-templates.html + # + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Ti + # Adjust to your storage class name + # + # storageClassName: local-storage + - name: warm + count: 1 + config: + node.roles: ["data_warm"] + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + spec: + containers: + - name: elasticsearch + resources: + limits: + memory: 16Gi + cpu: 2 + # Affinity/Anti-affinity settings for controlling the 'spreading' of Elasticsearch + # pods across existing hosts. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html#k8s-affinity-options + # + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: beta.kubernetes.io/instance-type + # operator: In + # # This should be adjusted to the instance type according to your setup + # # + # values: + # - highstorage + # Volume Claim settings. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-volume-claim-templates.html + # + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Ti + # Adjust to your storage class name + # + # storageClassName: local-storage + - name: cold + count: 1 + config: + node.roles: ["data_cold"] + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + spec: + containers: + - name: elasticsearch + resources: + limits: + memory: 8Gi + cpu: 2 + # Affinity/Anti-affinity settings for controlling the 'spreading' of Elasticsearch + # pods across existing hosts. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html#k8s-affinity-options + # + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: beta.kubernetes.io/instance-type + # operator: In + # # This should be adjusted to the instance type according to your setup + # # + # values: + # - highstorage + # Volume Claim settings. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-volume-claim-templates.html + # + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 20Ti + # Adjust to your storage class name + # + # storageClassName: local-storage diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/examples/elasticsearch/ingress/elasticsearch-ingress-gke.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/examples/elasticsearch/ingress/elasticsearch-ingress-gke.yaml new file mode 100644 index 00000000..0ca2e8a5 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/examples/elasticsearch/ingress/elasticsearch-ingress-gke.yaml @@ -0,0 +1,40 @@ +# The following is an example of an Elasticsearch resource that is configured to use an Ingress resource in a GKE cluster. +# Additional examples of exposing Elasticsearch with Ingress resources can be found in the following location: +# https://github.com/elastic/cloud-on-k8s/tree/main/deploy/eck-stack/charts/eck-elasticsearch/examples/ingress +# +eck-elasticsearch: + enabled: true + + ingress: + enabled: true + annotations: + my: annotation + labels: + my: label + pathType: Prefix + hosts: + - host: "elasticsearch.company.dev" + path: "/" + http: + service: + metadata: + annotations: + # This is required for `ClusterIP` services (which are the default ECK service type) to be used with Ingress in GKE clusters. + cloud.google.com/neg: '{"ingress": true}' + # This is required to enable the GKE Ingress Controller to use HTTPS as the backend protocol. + cloud.google.com/app-protocols: '{"https":"HTTPS"}' + nodeSets: + - name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false + # Enable anonymous access to allow GCLB health probes to succeed + xpack.security.authc: + anonymous: + username: anon + roles: monitoring_user diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/examples/enterprise-search/basic.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/examples/enterprise-search/basic.yaml new file mode 100644 index 00000000..aeb61b06 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/examples/enterprise-search/basic.yaml @@ -0,0 +1,42 @@ +--- +eck-elasticsearch: + enabled: true + + # Name of the Elasticsearch instance. + # + fullnameOverride: elasticsearch + + nodeSets: + - name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false + +eck-kibana: + enabled: true + + # Name of the Kibana instance. + # + fullnameOverride: kibana + + elasticsearchRef: + name: elasticsearch + + spec: + enterpriseSearchRef: + name: enterprise-search + +eck-enterprise-search: + enabled: true + + # Name of the Enterprise Search instance. + # + fullnameOverride: enterprise-search + + elasticsearchRef: + name: elasticsearch diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/examples/enterprise-search/with-custom-configuration.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/examples/enterprise-search/with-custom-configuration.yaml new file mode 100644 index 00000000..a7c3ad49 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/examples/enterprise-search/with-custom-configuration.yaml @@ -0,0 +1,52 @@ +--- +eck-elasticsearch: + enabled: true + + # Name of the Elasticsearch instance. + # + fullnameOverride: elasticsearch + + nodeSets: + - name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false + +eck-kibana: + enabled: true + + # Name of the Kibana instance. + # + fullnameOverride: kibana + + elasticsearchRef: + name: elasticsearch + + spec: + enterpriseSearchRef: + name: enterprise-search + +eck-enterprise-search: + enabled: true + + # Name of the Enterprise Search instance. + # + fullnameOverride: enterprise-search + + config: + # configure app search document size limit + app_search.engine.document_size.limit: 100kb + + http: + service: + metadata: + labels: + my-custom: label + + elasticsearchRef: + name: elasticsearch diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/examples/kibana/http-configuration.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/examples/kibana/http-configuration.yaml new file mode 100644 index 00000000..d8a4831d --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/examples/kibana/http-configuration.yaml @@ -0,0 +1,23 @@ +--- +eck-kibana: + # Count of Kibana replicas to create. + # + count: 1 + + # Reference to ECK-managed Elasticsearch resource, ideally from {{ "elasticsearch.fullname" }} + # + elasticsearchRef: + name: es-quickstart-eck-elasticsearch + # namespace: default + http: + service: + spec: + # Type of service to deploy for Kibana. + # This deploys a load balancer in a cloud service provider, where supported. + # + type: LoadBalancer + # tls: + # selfSignedCertificate: + # subjectAltNames: + # - ip: 1.2.3.4 + # - dns: kibana.example.com diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/examples/kibana/ingress/kibana-gke.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/examples/kibana/ingress/kibana-gke.yaml new file mode 100644 index 00000000..339a7a57 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/examples/kibana/ingress/kibana-gke.yaml @@ -0,0 +1,82 @@ +# The following is an example of a Kibana resource that is configured to use an Ingress resource in a GKE cluster. +# Additional examples of exposing Kibana with Ingress resources can be found in the following location: +# https://github.com/elastic/cloud-on-k8s/tree/main/deploy/eck-stack/charts/eck-kibana/examples/ingress +# +eck-elasticsearch: + enabled: true + + # Name of the Elasticsearch instance. + # + fullnameOverride: elasticsearch + + ingress: + enabled: true + annotations: + my: annotation + labels: + my: label + pathType: Prefix + hosts: + - host: "kibana.company.dev" + path: "/" + tls: + enabled: true + + http: + service: + metadata: + annotations: + # This is required for `ClusterIP` services (which are the default ECK service type) to be used with Ingress in GKE clusters. + cloud.google.com/neg: '{"ingress": true}' + cloud.google.com/app-protocols: '{"https":"HTTPS"}' + cloud.google.com/backend-config: '{"default": "elasticsearch"}' + + nodeSets: + - name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false + # Enable anonymous access to allow GCLB health probes to succeed + xpack.security.authc: + anonymous: + username: anon + roles: monitoring_user + +eck-kibana: + enabled: true + + # Name of the Kibana instance. + # + fullnameOverride: kibana + + # Reference to ECK-managed Elasticsearch instance, ideally from {{ "elasticsearch.fullname" }} + # + elasticsearchRef: + name: elasticsearch + + config: + server: + publicBaseUrl: "https://kibana.company.dev" + + http: + service: + metadata: + annotations: + # This is required for `ClusterIP` services (which are the default ECK service type) to be used with Ingress in GKE clusters. + cloud.google.com/neg: '{"ingress": true}' + cloud.google.com/app-protocols: '{"https":"HTTPS"}' + cloud.google.com/backend-config: '{"default": "kibana"}' + + ingress: + enabled: true + pathType: Prefix + hosts: + - host: "kibana.company.dev" + path: "/" + tls: + enabled: true diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/examples/logstash/basic-eck.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/examples/logstash/basic-eck.yaml new file mode 100644 index 00000000..00f0b94f --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/examples/logstash/basic-eck.yaml @@ -0,0 +1,114 @@ +--- +eck-elasticsearch: + nodeSets: + - name: default + count: 3 + config: + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + spec: + containers: + - name: elasticsearch + resources: + limits: + memory: 2Gi + requests: + memory: 2Gi +eck-kibana: + enabled: true + spec: + count: 1 + elasticsearchRef: + name: elasticsearch +eck-beats: + enabled: true + spec: + type: filebeat + daemonSet: null + config: + filebeat.inputs: + - type: log + paths: + - /data/logstash-tutorial.log + processors: + - add_host_metadata: {} + - add_cloud_metadata: {} + output.logstash: + # This needs to be {{logstash-name}}-ls-beats:5044 + hosts: ["logstash-ls-beats-ls-beats:5044"] + deployment: + podTemplate: + spec: + automountServiceAccountToken: true + initContainers: + - name: download-tutorial + image: curlimages/curl + command: ["/bin/sh"] + args: ["-c", "curl -L https://download.elastic.co/demos/logstash/gettingstarted/logstash-tutorial.log.gz | gunzip -c > /data/logstash-tutorial.log"] + volumeMounts: + - name: data + mountPath: /data + containers: + - name: filebeat + securityContext: + runAsUser: 1000 + volumeMounts: + - name: data + mountPath: /data + - name: beat-data + mountPath: /usr/share/filebeat/data + volumes: + - name: data + emptydir: {} + - name: beat-data + emptydir: {} +eck-logstash: + enabled: true + # This is required to be able to set the logstash + # output of beats in a consistent manner. + fullnameOverride: "logstash-ls-beats" + elasticsearchRefs: + # This clusterName is required to match the environment variables + # used in the below config.string output section. + - clusterName: eck + name: elasticsearch + pipelines: + - pipeline.id: main + config.string: | + input { + beats { + port => 5044 + } + } + filter { + grok { + match => { "message" => "%{HTTPD_COMMONLOG}"} + } + geoip { + source => "[source][address]" + target => "[source]" + } + } + output { + elasticsearch { + hosts => [ "${ECK_ES_HOSTS}" ] + user => "${ECK_ES_USER}" + password => "${ECK_ES_PASSWORD}" + ssl_certificate_authorities => "${ECK_ES_SSL_CERTIFICATE_AUTHORITY}" + } + } + services: + - name: beats + service: + spec: + type: ClusterIP + ports: + - port: 5044 + name: "filebeat" + protocol: TCP + targetPort: 5044 diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/templates/NOTES.txt b/packs/elastic-stack-0.15.0/charts/eck-stack/templates/NOTES.txt new file mode 100644 index 00000000..65cdae60 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/templates/NOTES.txt @@ -0,0 +1,10 @@ +Elasticsearch ECK-Stack {{ .Chart.Version }} has been deployed successfully! + +To see status of all resources, run + +kubectl get elastic -n {{ .Release.Namespace }} -l "app.kubernetes.io/instance"={{ .Release.Name }} + +More information on the Elastic ECK Operator, and its Helm chart can be found +within our documentation. + +https://www.elastic.co/guide/en/cloud-on-k8s/current/index.html diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/templates/_helpers.tpl b/packs/elastic-stack-0.15.0/charts/eck-stack/templates/_helpers.tpl new file mode 100644 index 00000000..cef61bdb --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/templates/_helpers.tpl @@ -0,0 +1,48 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "eck-stack.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "eck-stack.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "eck-stack.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "eck-stack.labels" -}} +helm.sh/chart: {{ include "eck-stack.chart" . }} +{{ include "eck-stack.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "eck-stack.selectorLabels" -}} +app.kubernetes.io/name: {{ include "eck-stack.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/packs/elastic-stack-0.15.0/charts/eck-stack/values.yaml b/packs/elastic-stack-0.15.0/charts/eck-stack/values.yaml new file mode 100644 index 00000000..5d504211 --- /dev/null +++ b/packs/elastic-stack-0.15.0/charts/eck-stack/values.yaml @@ -0,0 +1,50 @@ +--- +# Default values for eck-stack. +# This is a YAML-formatted file. + +# If enabled, will use the eck-elasticsearch chart and deploy an Elasticsearch resource. +# +eck-elasticsearch: + enabled: true + # This is adjusting the full name of the elasticsearch resource so that both the eck-elasticsearch + # and the eck-kibana chart work together by default in the eck-stack chart. + fullnameOverride: elasticsearch + +# If enabled, will use the eck-kibana chart and deploy a Kibana resource. +# +eck-kibana: + enabled: true + # This is also adjusting the kibana reference to the elasticsearch resource named previously so that + # both the eck-elasticsearch and the eck-kibana chart work together by default in the eck-stack chart. + elasticsearchRef: + name: elasticsearch + +# If enabled, will use the eck-agent chart and deploy an Elastic Agent instance. +# +eck-agent: + enabled: false + +# If enabled, will use the eck-fleet-server chart and deploy a Fleet Server resource. +# +eck-fleet-server: + enabled: false + +# If enabled, will use the eck-beats chart and deploy a Beats resource. +# +eck-beats: + enabled: false + +# If enabled, will use the eck-logstash chart and deploy a Logstash resource. +# +eck-logstash: + enabled: false + +# If enabled, will use the eck-apm-server chart and deploy a standalone APM Server resource. +# +eck-apm-server: + enabled: false + +# If enabled, will use the eck-enterprise-search chart and deploy a Enterprise Search resource. +# +eck-enterprise-search: + enabled: false diff --git a/packs/elastic-stack-0.15.0/logo.png b/packs/elastic-stack-0.15.0/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..fa70b78daa45585ec0f802dfe637e4ce2172d6f8 GIT binary patch literal 5810 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 /data/logstash-tutorial.log"] + volumeMounts: + - name: data + mountPath: /data + containers: + - name: filebeat + securityContext: + runAsUser: 1000 + volumeMounts: + - name: data + mountPath: /data + - name: beat-data + mountPath: /usr/share/filebeat/data + volumes: + - name: data + emptydir: {} + - name: beat-data + emptydir: {} + eck-logstash: + enabled: true + # This is required to be able to set the logstash + # output of beats in a consistent manner. + fullnameOverride: "logstash-ls-beats" + elasticsearchRefs: + # This clusterName is required to match the environment variables + # used in the below config.string output section. + - clusterName: eck + name: elasticsearch + pipelines: + - pipeline.id: main + config.string: | + input { + beats { + port => 5044 + } + } + filter { + grok { + match => { "message" => "%{HTTPD_COMMONLOG}"} + } + geoip { + source => "[source][address]" + target => "[source]" + } + } + output { + elasticsearch { + hosts => [ "${ECK_ES_HOSTS}" ] + user => "${ECK_ES_USER}" + password => "${ECK_ES_PASSWORD}" + ssl_certificate_authorities => "${ECK_ES_SSL_CERTIFICATE_AUTHORITY}" + } + } + services: + - name: beats + service: + spec: + type: ClusterIP + ports: + - port: 5044 + name: "filebeat" + protocol: TCP + targetPort: 5044 \ No newline at end of file diff --git a/packs/elastic-stack-0.15.0/values.yaml b/packs/elastic-stack-0.15.0/values.yaml new file mode 100644 index 00000000..86fafa91 --- /dev/null +++ b/packs/elastic-stack-0.15.0/values.yaml @@ -0,0 +1,71 @@ +# Default values for eck-elastic-operator +# This is a YAML-formatted file +pack: + content: + images: + - image: docker.elastic.co/kibana/kibana:9.0.0 + - image: docker.elastic.co/elasticsearch/elasticsearch:9.0.0 + - image: docker.elastic.co/logstash/logstash:9.0.0 + - image: docker.elastic.co/beats/filebeat:9.0.0 + - image: docker.io/curlimages/curl + + + charts: + - repo: https://helm.elastic.co/ + name: eck-stack + version: 0.15.0 + #The namespace (on the target cluster) to install this chart + #When not found, a new namespace will be created + namespace: "elastic-stack" + +charts: + eck-stack: + # Default values for eck-stack. + # This is a YAML-formatted file. + + # If enabled, will use the eck-elasticsearch chart and deploy an Elasticsearch resource. + # + eck-elasticsearch: + enabled: true + # This is adjusting the full name of the elasticsearch resource so that both the eck-elasticsearch + # and the eck-kibana chart work together by default in the eck-stack chart. + fullnameOverride: elasticsearch + + # If enabled, will use the eck-kibana chart and deploy a Kibana resource. + # + eck-kibana: + enabled: true + # This is also adjusting the kibana reference to the elasticsearch resource named previously so that + # both the eck-elasticsearch and the eck-kibana chart work together by default in the eck-stack chart. + elasticsearchRef: + name: elasticsearch + + # If enabled, will use the eck-agent chart and deploy an Elastic Agent instance. + # + eck-agent: + enabled: false + + # If enabled, will use the eck-fleet-server chart and deploy a Fleet Server resource. + # + eck-fleet-server: + enabled: false + + # If enabled, will use the eck-beats chart and deploy a Beats resource. + # + eck-beats: + enabled: false + + # If enabled, will use the eck-logstash chart and deploy a Logstash resource. + # + eck-logstash: + enabled: false + + # If enabled, will use the eck-apm-server chart and deploy a standalone APM Server resource. + # + eck-apm-server: + enabled: false + + # If enabled, will use the eck-enterprise-search chart and deploy a Enterprise Search resource. + # + eck-enterprise-search: + enabled: false \ No newline at end of file From 2960a99deb8b8f2c762286b4f32e45dc084614bf Mon Sep 17 00:00:00 2001 From: svalenciah19 Date: Mon, 15 Sep 2025 12:57:12 -0500 Subject: [PATCH 3/8] Upgrade pack elastic-operator to version 3.1.0 --- packs/elastic-operator-3.1.0/README.md | 43 + .../charts/eck-operator-3.1.0.tgz | Bin 0 -> 136143 bytes .../charts/eck-operator/.helmignore | 24 + .../charts/eck-operator/Chart.lock | 6 + .../charts/eck-operator/Chart.yaml | 26 + .../charts/eck-operator/LICENSE | 93 + .../charts/eck-operator/README.md | 20 + .../charts/eck-operator-crds/.helmignore | 23 + .../charts/eck-operator-crds/Chart.yaml | 21 + .../charts/eck-operator-crds/README.md | 16 + .../eck-operator-crds/templates/NOTES.txt | 1 + .../eck-operator-crds/templates/_helpers.tpl | 62 + .../eck-operator-crds/templates/all-crds.yaml | 10710 ++++++++++++++++ .../charts/eck-operator-crds/values.yaml | 7 + .../profile-disable-automounting-api.yaml | 29 + .../charts/eck-operator/profile-global.yaml | 6 + .../charts/eck-operator/profile-istio.yaml | 11 + .../eck-operator/profile-restricted.yaml | 12 + .../profile-soft-multi-tenancy.yaml | 18 + .../charts/eck-operator/templates/NOTES.txt | 2 + .../eck-operator/templates/_helpers.tpl | 381 + .../eck-operator/templates/cluster-roles.yaml | 121 + .../eck-operator/templates/configmap.yaml | 81 + .../templates/managed-namespaces.yaml | 13 + .../templates/managed-ns-network-policy.yaml | 228 + .../templates/metrics-service.yaml | 22 + .../templates/operator-namespace.yaml | 9 + .../templates/operator-network-policy.yaml | 59 + .../charts/eck-operator/templates/pdb.yaml | 19 + .../eck-operator/templates/podMonitor.yaml | 42 + .../eck-operator/templates/role-bindings.yaml | 98 + .../templates/service-account.yaml | 15 + .../templates/service-monitor.yaml | 34 + .../eck-operator/templates/statefulset.yaml | 162 + .../templates/validate-chart.yaml | 29 + .../eck-operator/templates/webhook.yaml | 473 + .../charts/eck-operator/values.yaml | 372 + packs/elastic-operator-3.1.0/logo.png | Bin 0 -> 5810 bytes packs/elastic-operator-3.1.0/pack.json | 39 + packs/elastic-operator-3.1.0/values.yaml | 389 + 40 files changed, 13716 insertions(+) create mode 100644 packs/elastic-operator-3.1.0/README.md create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator-3.1.0.tgz create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/.helmignore create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/Chart.lock create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/Chart.yaml create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/LICENSE create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/README.md create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/.helmignore create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/Chart.yaml create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/README.md create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/templates/NOTES.txt create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/templates/_helpers.tpl create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/values.yaml create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/profile-disable-automounting-api.yaml create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/profile-global.yaml create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/profile-istio.yaml create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/profile-restricted.yaml create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/profile-soft-multi-tenancy.yaml create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/templates/NOTES.txt create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/templates/_helpers.tpl create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/templates/cluster-roles.yaml create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/templates/configmap.yaml create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/templates/managed-namespaces.yaml create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/templates/managed-ns-network-policy.yaml create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/templates/metrics-service.yaml create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/templates/operator-namespace.yaml create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/templates/operator-network-policy.yaml create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/templates/pdb.yaml create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/templates/podMonitor.yaml create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/templates/role-bindings.yaml create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/templates/service-account.yaml create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/templates/service-monitor.yaml create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/templates/statefulset.yaml create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/templates/validate-chart.yaml create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/templates/webhook.yaml create mode 100644 packs/elastic-operator-3.1.0/charts/eck-operator/values.yaml create mode 100644 packs/elastic-operator-3.1.0/logo.png create mode 100644 packs/elastic-operator-3.1.0/pack.json create mode 100644 packs/elastic-operator-3.1.0/values.yaml diff --git a/packs/elastic-operator-3.1.0/README.md b/packs/elastic-operator-3.1.0/README.md new file mode 100644 index 00000000..df41d6c2 --- /dev/null +++ b/packs/elastic-operator-3.1.0/README.md @@ -0,0 +1,43 @@ +# Elastic Cloud on Kubernetes (ECK) + +Elastic Cloud on Kubernetes automates the deployment, provisioning, management, and orchestration of Elasticsearch, Kibana, APM Server, Enterprise Search, Beats, Elastic Agent, Elastic Maps Server, and Logstash on Kubernetes based on the operator pattern. + +Current features: + +* Elasticsearch, Kibana, APM Server, Enterprise Search, and Beats deployments +* TLS Certificates management +* Safe Elasticsearch cluster configuration & topology changes +* Persistent volumes usage +* Custom node configuration and attributes +* Secure settings keystore updates + +Supported versions: + +* Kubernetes 1.25-1.29 +* Elasticsearch, Kibana, APM Server: 6.8+, 7.1+, 8+, 9+ +* Enterprise Search: 7.7+, 8+, 9+ +* Beats: 7.0+, 8+, 9+ +* Elastic Agent: 7.10+ (standalone), 7.14+, 8+ (Fleet), 9+ +* Elastic Maps Server: 7.11+, 8+, 9+ +* Logstash 8.7+ + +Check the [Quickstart](https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-quickstart.html) to deploy your first cluster with ECK. + +For general questions, please see the Elastic [forums](https://discuss.elastic.co/c/eck). + +# ECK Operator Helm Chart + +A Helm chart to install the ECK Operator: the official Kubernetes operator from Elastic to orchestrate Elasticsearch, Kibana, APM Server, Enterprise Search, and Beats on Kubernetes. + +For more information about the ECK Operator, see: +- [Documentation](https://www.elastic.co/guide/en/cloud-on-k8s/current/index.html) +- [GitHub repo](https://github.com/elastic/cloud-on-k8s) + + +## Requirements + +- Supported Kubernetes versions are listed in the documentation: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s_supported_versions.html + +## Usage + +Refer to the documentation at https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-install-helm.html \ No newline at end of file diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator-3.1.0.tgz b/packs/elastic-operator-3.1.0/charts/eck-operator-3.1.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..d9ba22e7ccb981a1a7b6cfbe638c599ef8d3d042 GIT binary patch literal 136143 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�L8ow($C{1`=k!Uc$Jx_;2JW>O#%U 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 xC4YbdMJh>WG)3TLS861cLTd$5uX45;y=1.21.0-0' +maintainers: +- email: eck@elastic.co + name: Elastic +name: eck-operator +type: application +version: 3.1.0 diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/LICENSE b/packs/elastic-operator-3.1.0/charts/eck-operator/LICENSE new file mode 100644 index 00000000..92503a72 --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/LICENSE @@ -0,0 +1,93 @@ +Elastic License 2.0 + +URL: https://www.elastic.co/licensing/elastic-license + +## Acceptance + +By using the software, you agree to all of the terms and conditions below. + +## Copyright License + +The licensor grants you a non-exclusive, royalty-free, worldwide, +non-sublicensable, non-transferable license to use, copy, distribute, make +available, and prepare derivative works of the software, in each case subject to +the limitations and conditions below. + +## Limitations + +You may not provide the software to third parties as a hosted or managed +service, where the service provides users with access to any substantial set of +the features or functionality of the software. + +You may not move, change, disable, or circumvent the license key functionality +in the software, and you may not remove or obscure any functionality in the +software that is protected by the license key. + +You may not alter, remove, or obscure any licensing, copyright, or other notices +of the licensor in the software. Any use of the licensor’s trademarks is subject +to applicable law. + +## Patents + +The licensor grants you a license, under any patent claims the licensor can +license, or becomes able to license, to make, have made, use, sell, offer for +sale, import and have imported the software, in each case subject to the +limitations and conditions in this license. This license does not cover any +patent claims that you cause to be infringed by modifications or additions to +the software. If you or your company make any written claim that the software +infringes or contributes to infringement of any patent, your patent license for +the software granted under these terms ends immediately. If your company makes +such a claim, your patent license ends immediately for work on behalf of your +company. + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you +also gets a copy of these terms. + +If you modify the software, you must include in any modified copies of the +software prominent notices stating that you have modified the software. + +## No Other Rights + +These terms do not imply any licenses other than those expressly granted in +these terms. + +## Termination + +If you use the software in violation of these terms, such use is not licensed, +and your licenses will automatically terminate. If the licensor provides you +with a notice of your violation, and you cease all violation of this license no +later than 30 days after you receive that notice, your licenses will be +reinstated retroactively. However, if you violate these terms after such +reinstatement, any additional violation of these terms will cause your licenses +to terminate automatically and permanently. + +## No Liability + +*As far as the law allows, the software comes as is, without any warranty or +condition, and the licensor will not be liable to you for any damages arising +out of these terms or the use or nature of the software, under any kind of +legal claim.* + +## Definitions + +The **licensor** is the entity offering these terms, and the **software** is the +software the licensor makes available under these terms, including any portion +of it. + +**you** refers to the individual or entity agreeing to these terms. + +**your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control over, +are under the control of, or are under common control with that +organization. **control** means ownership of substantially all the assets of an +entity, or the power to direct its management and policies by vote, contract, or +otherwise. Control can be direct or indirect. + +**your licenses** are all the licenses granted to you for the software under +these terms. + +**use** means anything you do with the software requiring one of your licenses. + +**trademark** means trademarks, service marks, and similar rights. \ No newline at end of file diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/README.md b/packs/elastic-operator-3.1.0/charts/eck-operator/README.md new file mode 100644 index 00000000..86452e3d --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/README.md @@ -0,0 +1,20 @@ +# ECK Operator Helm Chart + +[![Artifact HUB](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/elastic)](https://artifacthub.io/packages/helm/elastic/eck-operator) + +A Helm chart to install the ECK Operator: the official Kubernetes operator from Elastic to orchestrate Elasticsearch, Kibana, APM Server, Enterprise Search, and Beats on Kubernetes. + +For more information about the ECK Operator, see: +- [Documentation](https://www.elastic.co/guide/en/cloud-on-k8s/current/index.html) +- [GitHub repo](https://github.com/elastic/cloud-on-k8s) + + +## Requirements + +- Supported Kubernetes versions are listed in the documentation: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s_supported_versions.html +- Helm >= 3.2.0 + + +## Usage + +Refer to the documentation at https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-install-helm.html diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/.helmignore b/packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/Chart.yaml b/packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/Chart.yaml new file mode 100644 index 00000000..22e2bae6 --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/Chart.yaml @@ -0,0 +1,21 @@ +apiVersion: v2 +appVersion: 3.1.0 +description: ECK operator Custom Resource Definitions +home: https://github.com/elastic/cloud-on-k8s +icon: https://helm.elastic.co/icons/eck.png +keywords: +- Logstash +- Elasticsearch +- Kibana +- APM Server +- Beats +- Enterprise Search +- Elastic Stack +- Operator +kubeVersion: '>=1.21.0-0' +maintainers: +- email: eck@elastic.co + name: Elastic +name: eck-operator-crds +type: application +version: 3.1.0 diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/README.md b/packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/README.md new file mode 100644 index 00000000..698d6dd4 --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/README.md @@ -0,0 +1,16 @@ +# ECK Operator CRDs Helm Chart + +[![Artifact HUB](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/elastic)](https://artifacthub.io/packages/helm/elastic/eck-operator-crds) + +A Helm chart to install the Kubernetes Custom Resource Definitions (CRD) required by the ECK Operator: the official Kubernetes operator from Elastic to orchestrate Elasticsearch, Kibana, APM Server, Enterprise Search, and Beats on Kubernetes. This chart is usually automatically installed by the [ECK Operator Helm Chart](https://artifacthub.io/packages/helm/elastic/eck-operator) when installed using the default settings. Refer to the [installation documentation](https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-install-helm.html) for more information. + + +## Requirements + +- Supported Kubernetes versions are listed in the documentation: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s_supported_versions.html +- Helm >= 3.2.0 + + +## Usage + +Refer to the documentation at https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-install-helm.html diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/templates/NOTES.txt b/packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/templates/NOTES.txt new file mode 100644 index 00000000..1478c82b --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/templates/NOTES.txt @@ -0,0 +1 @@ +ECK Custom Resource Definitions installed. diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/templates/_helpers.tpl b/packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/templates/_helpers.tpl new file mode 100644 index 00000000..548f1bc6 --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "eck-operator-crds.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "eck-operator-crds.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "eck-operator-crds.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "eck-operator-crds.labels" -}} +helm.sh/chart: {{ include "eck-operator-crds.chart" . }} +{{ include "eck-operator-crds.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "eck-operator-crds.selectorLabels" -}} +app.kubernetes.io/name: {{ include "eck-operator-crds.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Determine effective Kubernetes version +*/}} +{{- define "eck-operator-crds.effectiveKubeVersion" -}} +{{- if .Values.global.manifestGen -}} +{{- semver .Values.global.kubeVersion -}} +{{- else -}} +{{- .Capabilities.KubeVersion.Version -}} +{{- end -}} +{{- end -}} diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml b/packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml new file mode 100644 index 00000000..f394c613 --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml @@ -0,0 +1,10710 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.18.0 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: agents.agent.k8s.elastic.co +spec: + group: agent.k8s.elastic.co + names: + categories: + - elastic + kind: Agent + listKind: AgentList + plural: agents + shortNames: + - agent + singular: agent + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: available + type: integer + - description: Expected nodes + jsonPath: .status.expectedNodes + name: expected + type: integer + - description: Agent version + jsonPath: .status.version + name: version + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: Agent is the Schema for the Agents API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: AgentSpec defines the desired state of the Agent + properties: + config: + description: Config holds the Agent configuration. At most one of + [`Config`, `ConfigRef`] can be specified. + type: object + x-kubernetes-preserve-unknown-fields: true + configRef: + description: |- + ConfigRef contains a reference to an existing Kubernetes Secret holding the Agent configuration. + Agent settings must be specified as yaml, under a single "agent.yml" entry. At most one of [`Config`, `ConfigRef`] + can be specified. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + daemonSet: + description: |- + DaemonSet specifies the Agent should be deployed as a DaemonSet, and allows providing its spec. + Cannot be used along with `deployment` or `statefulSet`. + properties: + podTemplate: + description: PodTemplateSpec describes the data a pod should have + when created from a template + type: object + x-kubernetes-preserve-unknown-fields: true + updateStrategy: + description: DaemonSetUpdateStrategy is a struct used to control + the update strategy for a DaemonSet. + properties: + rollingUpdate: + description: Rolling update config params. Present only if + type = "RollingUpdate". + properties: + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of nodes with an existing available DaemonSet pod that + can have an updated DaemonSet pod during during an update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up to a minimum of 1. + Default value is 0. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their a new pod created before the old pod is marked as deleted. + The update starts by launching new pods on 30% of nodes. Once an updated + pod is available (Ready for at least minReadySeconds) the old DaemonSet pod + on that node is marked deleted. If the old pod becomes unavailable for any + reason (Ready transitions to false, is evicted, or is drained) an updated + pod is immediatedly created on that node without considering surge limits. + Allowing surge implies the possibility that the resources consumed by the + daemonset on any given node can double if the readiness check fails, and + so resource intensive daemonsets should take into account that they may + cause evictions during disruption. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of DaemonSet pods that can be unavailable during the + update. Value can be an absolute number (ex: 5) or a percentage of total + number of DaemonSet pods at the start of the update (ex: 10%). Absolute + number is calculated from percentage by rounding up. + This cannot be 0 if MaxSurge is 0 + Default value is 1. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their pods stopped for an update at any given time. The update + starts by stopping at most 30% of those DaemonSet pods and then brings + up new DaemonSet pods in their place. Once the new pods are available, + it then proceeds onto other DaemonSet pods, thus ensuring that at least + 70% of original number of DaemonSet pods are available at all times during + the update. + x-kubernetes-int-or-string: true + type: object + type: + description: Type of daemon set update. Can be "RollingUpdate" + or "OnDelete". Default is RollingUpdate. + type: string + type: object + type: object + deployment: + description: |- + Deployment specifies the Agent should be deployed as a Deployment, and allows providing its spec. + Cannot be used along with `daemonSet` or `statefulSet`. + properties: + podTemplate: + description: PodTemplateSpec describes the data a pod should have + when created from a template + type: object + x-kubernetes-preserve-unknown-fields: true + replicas: + format: int32 + type: integer + strategy: + description: DeploymentStrategy describes how to replace existing + pods with new ones. + properties: + rollingUpdate: + description: |- + Rolling update config params. Present only if DeploymentStrategyType = + RollingUpdate. + properties: + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be scheduled above the desired number of + pods. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 25%. + Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when + the rolling update starts, such that the total number of old and new pods do not exceed + 130% of desired pods. Once old pods have been killed, + new ReplicaSet can be scaled up further, ensuring that total number of pods running + at any time during the update is at most 130% of desired pods. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 25%. + Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods + immediately when the rolling update starts. Once new pods are ready, old ReplicaSet + can be scaled down further, followed by scaling up the new ReplicaSet, ensuring + that the total number of pods available at all times during the update is at + least 70% of desired pods. + x-kubernetes-int-or-string: true + type: object + type: + description: Type of deployment. Can be "Recreate" or "RollingUpdate". + Default is RollingUpdate. + type: string + type: object + type: object + elasticsearchRefs: + description: |- + ElasticsearchRefs is a reference to a list of Elasticsearch clusters running in the same Kubernetes cluster. + Due to existing limitations, only a single ES cluster is currently supported. + items: + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + outputName: + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + type: array + fleetServerEnabled: + description: FleetServerEnabled determines whether this Agent will + launch Fleet Server. Don't set unless `mode` is set to `fleet`. + type: boolean + fleetServerRef: + description: |- + FleetServerRef is a reference to Fleet Server that this Agent should connect to to obtain it's configuration. + Don't set unless `mode` is set to `fleet`. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + http: + description: HTTP holds the HTTP layer configuration for the Agent + in Fleet mode with Fleet Server enabled. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic + is distributed to Service endpoints. Implementations can use this field + as a hint, but are not required to guarantee strict adherence. If the + field is not set, the implementation will apply its default routing + strategy. If set to "PreferClose", implementations should prioritize + endpoints that are in the same zone. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the Agent Docker image to deploy. Version has + to match the Agent in the image. + type: string + kibanaRef: + description: |- + KibanaRef is a reference to Kibana where Fleet should be set up and this Agent should be enrolled. Don't set + unless `mode` is set to `fleet`. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + mode: + description: |- + Mode specifies the runtime mode for the Agent. The configuration can be specified locally through + `config` or `configRef` (`standalone` mode), or come from Fleet during runtime (`fleet` mode). Starting with + version 8.13.0 Fleet-managed agents support advanced configuration via a local configuration file. + See https://www.elastic.co/docs/reference/fleet/advanced-kubernetes-managed-by-fleet + Defaults to `standalone` mode. + enum: + - standalone + - fleet + type: string + policyID: + description: |- + PolicyID determines into which Agent Policy this Agent will be enrolled. + This field will become mandatory in a future release, default policies are deprecated since 8.1.0. + type: string + revisionHistoryLimit: + description: RevisionHistoryLimit is the number of revisions to retain + to allow rollback in the underlying DaemonSet or Deployment or StatefulSet. + format: int32 + type: integer + secureSettings: + description: |- + SecureSettings is a list of references to Kubernetes Secrets containing sensitive configuration options for the Agent. + Secrets data can be then referenced in the Agent config using the Secret's keys or as specified in `Entries` field of + each SecureSetting. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + serviceAccountName: + description: |- + ServiceAccountName is used to check access from the current resource to an Elasticsearch resource in a different namespace. + Can only be used if ECK is enforcing RBAC on references. + type: string + statefulSet: + description: |- + StatefulSet specifies the Agent should be deployed as a StatefulSet, and allows providing its spec. + Cannot be used along with `daemonSet` or `deployment`. + properties: + podManagementPolicy: + default: Parallel + description: |- + PodManagementPolicy controls how pods are created during initial scale up, + when replacing pods on nodes, or when scaling down. The default policy is + `Parallel`, where pods are created in parallel to match the desired scale + without waiting, and on scale down will delete all pods at once. + The alternative policy is `OrderedReady`, the default for vanilla kubernetes + StatefulSets, where pods are created in increasing order in increasing order + (pod-0, then pod-1, etc.) and the controller will wait until each pod is ready before + continuing. When scaling down, the pods are removed in the opposite order. + enum: + - OrderedReady + - Parallel + type: string + podTemplate: + description: PodTemplateSpec describes the data a pod should have + when created from a template + type: object + x-kubernetes-preserve-unknown-fields: true + replicas: + format: int32 + type: integer + serviceName: + type: string + volumeClaimTemplates: + description: |- + VolumeClaimTemplates is a list of persistent volume claims to be used by each Pod. + Every claim in this list must have a matching volumeMount in one of the containers defined in the PodTemplate. + Items defined here take precedence over any default claims added by the operator with the same name. + items: + description: PersistentVolumeClaim is a user's request for and + claim to a persistent volume + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + spec defines the desired characteristics of a volume requested by a pod author. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes + to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to + the PersistentVolume backing this claim. + type: string + type: object + type: object + type: array + type: object + version: + description: Version of the Agent. + type: string + required: + - version + type: object + status: + description: AgentStatus defines the observed state of the Agent + properties: + availableNodes: + format: int32 + type: integer + elasticsearchAssociationsStatus: + additionalProperties: + description: AssociationStatus is the status of an association resource. + type: string + description: |- + AssociationStatusMap is the map of association's namespaced name string to its AssociationStatus. For resources that + have a single Association of a given type (for ex. single ES reference), this map contains a single entry. + type: object + expectedNodes: + format: int32 + type: integer + fleetServerAssociationStatus: + description: AssociationStatus is the status of an association resource. + type: string + health: + type: string + kibanaAssociationStatus: + description: AssociationStatus is the status of an association resource. + type: string + observedGeneration: + description: |- + ObservedGeneration is the most recent generation observed for this Elastic Agent. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + If the generation observed in status diverges from the generation in metadata, the Elastic + Agent controller has not yet processed the changes contained in the Elastic Agent specification. + format: int64 + type: integer + version: + description: |- + Version of the stack resource currently running. During version upgrades, multiple versions may run + in parallel: this value specifies the lowest version currently running. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.18.0 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: apmservers.apm.k8s.elastic.co +spec: + group: apm.k8s.elastic.co + names: + categories: + - elastic + kind: ApmServer + listKind: ApmServerList + plural: apmservers + shortNames: + - apm + singular: apmserver + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: nodes + type: integer + - description: APM version + jsonPath: .status.version + name: version + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1 + schema: + openAPIV3Schema: + description: ApmServer represents an APM Server resource in a Kubernetes cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ApmServerSpec holds the specification of an APM Server. + properties: + config: + description: 'Config holds the APM Server configuration. See: https://www.elastic.co/guide/en/apm/server/current/configuring-howto-apm-server.html' + type: object + x-kubernetes-preserve-unknown-fields: true + count: + description: Count of APM Server instances to deploy. + format: int32 + type: integer + elasticsearchRef: + description: ElasticsearchRef is a reference to the output Elasticsearch + cluster running in the same Kubernetes cluster. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + http: + description: HTTP holds the HTTP layer configuration for the APM Server + resource. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic + is distributed to Service endpoints. Implementations can use this field + as a hint, but are not required to guarantee strict adherence. If the + field is not set, the implementation will apply its default routing + strategy. If set to "PreferClose", implementations should prioritize + endpoints that are in the same zone. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the APM Server Docker image to deploy. + type: string + kibanaRef: + description: |- + KibanaRef is a reference to a Kibana instance running in the same Kubernetes cluster. + It allows APM agent central configuration management in Kibana. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + podTemplate: + description: PodTemplate provides customisation options (labels, annotations, + affinity rules, resource requests, and so on) for the APM Server + pods. + type: object + x-kubernetes-preserve-unknown-fields: true + revisionHistoryLimit: + description: RevisionHistoryLimit is the number of revisions to retain + to allow rollback in the underlying Deployment. + format: int32 + type: integer + secureSettings: + description: SecureSettings is a list of references to Kubernetes + secrets containing sensitive configuration options for APM Server. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + serviceAccountName: + description: |- + ServiceAccountName is used to check access from the current resource to a resource (for ex. Elasticsearch) in a different namespace. + Can only be used if ECK is enforcing RBAC on references. + type: string + version: + description: Version of the APM Server. + type: string + required: + - version + type: object + status: + description: ApmServerStatus defines the observed state of ApmServer + properties: + availableNodes: + description: AvailableNodes is the number of available replicas in + the deployment. + format: int32 + type: integer + count: + description: Count corresponds to Scale.Status.Replicas, which is + the actual number of observed instances of the scaled object. + format: int32 + type: integer + elasticsearchAssociationStatus: + description: ElasticsearchAssociationStatus is the status of any auto-linking + to Elasticsearch clusters. + type: string + health: + description: Health of the deployment. + type: string + kibanaAssociationStatus: + description: KibanaAssociationStatus is the status of any auto-linking + to Kibana. + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the status is based upon. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + If the generation observed in status diverges from the generation in metadata, the APM Server + controller has not yet processed the changes contained in the APM Server specification. + format: int64 + type: integer + secretTokenSecret: + description: SecretTokenSecretName is the name of the Secret that + contains the secret token + type: string + selector: + description: Selector is the label selector used to find all pods. + type: string + service: + description: ExternalService is the name of the service the agents + should connect to. + type: string + version: + description: |- + Version of the stack resource currently running. During version upgrades, multiple versions may run + in parallel: this value specifies the lowest version currently running. + type: string + type: object + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.count + statusReplicasPath: .status.count + status: {} + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: nodes + type: integer + - description: APM version + jsonPath: .spec.version + name: version + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: ApmServer represents an APM Server resource in a Kubernetes cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ApmServerSpec holds the specification of an APM Server. + properties: + config: + description: 'Config holds the APM Server configuration. See: https://www.elastic.co/guide/en/apm/server/current/configuring-howto-apm-server.html' + type: object + x-kubernetes-preserve-unknown-fields: true + count: + description: Count of APM Server instances to deploy. + format: int32 + type: integer + elasticsearchRef: + description: ElasticsearchRef is a reference to the output Elasticsearch + cluster running in the same Kubernetes cluster. + properties: + name: + description: Name of the Kubernetes object. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + required: + - name + type: object + http: + description: HTTP holds the HTTP layer configuration for the APM Server + resource. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic + is distributed to Service endpoints. Implementations can use this field + as a hint, but are not required to guarantee strict adherence. If the + field is not set, the implementation will apply its default routing + strategy. If set to "PreferClose", implementations should prioritize + endpoints that are in the same zone. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the APM Server Docker image to deploy. + type: string + podTemplate: + description: PodTemplate provides customisation options (labels, annotations, + affinity rules, resource requests, and so on) for the APM Server + pods. + type: object + x-kubernetes-preserve-unknown-fields: true + secureSettings: + description: SecureSettings is a list of references to Kubernetes + secrets containing sensitive configuration options for APM Server. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + version: + description: Version of the APM Server. + type: string + type: object + status: + description: ApmServerStatus defines the observed state of ApmServer + properties: + associationStatus: + description: Association is the status of any auto-linking to Elasticsearch + clusters. + type: string + availableNodes: + format: int32 + type: integer + health: + description: ApmServerHealth expresses the status of the Apm Server + instances. + type: string + secretTokenSecret: + description: SecretTokenSecretName is the name of the Secret that + contains the secret token + type: string + service: + description: ExternalService is the name of the service the agents + should connect to. + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} + - name: v1alpha1 + schema: + openAPIV3Schema: + description: to not break compatibility when upgrading from previous versions + of the CRD + type: object + served: false + storage: false +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.18.0 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: beats.beat.k8s.elastic.co +spec: + group: beat.k8s.elastic.co + names: + categories: + - elastic + kind: Beat + listKind: BeatList + plural: beats + shortNames: + - beat + singular: beat + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: available + type: integer + - description: Expected nodes + jsonPath: .status.expectedNodes + name: expected + type: integer + - description: Beat type + jsonPath: .spec.type + name: type + type: string + - description: Beat version + jsonPath: .status.version + name: version + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: Beat is the Schema for the Beats API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: BeatSpec defines the desired state of a Beat. + properties: + config: + description: Config holds the Beat configuration. At most one of [`Config`, + `ConfigRef`] can be specified. + type: object + x-kubernetes-preserve-unknown-fields: true + configRef: + description: |- + ConfigRef contains a reference to an existing Kubernetes Secret holding the Beat configuration. + Beat settings must be specified as yaml, under a single "beat.yml" entry. At most one of [`Config`, `ConfigRef`] + can be specified. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + daemonSet: + description: |- + DaemonSet specifies the Beat should be deployed as a DaemonSet, and allows providing its spec. + Cannot be used along with `deployment`. If both are absent a default for the Type is used. + properties: + podTemplate: + description: PodTemplateSpec describes the data a pod should have + when created from a template + type: object + x-kubernetes-preserve-unknown-fields: true + updateStrategy: + description: DaemonSetUpdateStrategy is a struct used to control + the update strategy for a DaemonSet. + properties: + rollingUpdate: + description: Rolling update config params. Present only if + type = "RollingUpdate". + properties: + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of nodes with an existing available DaemonSet pod that + can have an updated DaemonSet pod during during an update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up to a minimum of 1. + Default value is 0. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their a new pod created before the old pod is marked as deleted. + The update starts by launching new pods on 30% of nodes. Once an updated + pod is available (Ready for at least minReadySeconds) the old DaemonSet pod + on that node is marked deleted. If the old pod becomes unavailable for any + reason (Ready transitions to false, is evicted, or is drained) an updated + pod is immediatedly created on that node without considering surge limits. + Allowing surge implies the possibility that the resources consumed by the + daemonset on any given node can double if the readiness check fails, and + so resource intensive daemonsets should take into account that they may + cause evictions during disruption. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of DaemonSet pods that can be unavailable during the + update. Value can be an absolute number (ex: 5) or a percentage of total + number of DaemonSet pods at the start of the update (ex: 10%). Absolute + number is calculated from percentage by rounding up. + This cannot be 0 if MaxSurge is 0 + Default value is 1. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their pods stopped for an update at any given time. The update + starts by stopping at most 30% of those DaemonSet pods and then brings + up new DaemonSet pods in their place. Once the new pods are available, + it then proceeds onto other DaemonSet pods, thus ensuring that at least + 70% of original number of DaemonSet pods are available at all times during + the update. + x-kubernetes-int-or-string: true + type: object + type: + description: Type of daemon set update. Can be "RollingUpdate" + or "OnDelete". Default is RollingUpdate. + type: string + type: object + type: object + deployment: + description: |- + Deployment specifies the Beat should be deployed as a Deployment, and allows providing its spec. + Cannot be used along with `daemonSet`. If both are absent a default for the Type is used. + properties: + podTemplate: + description: PodTemplateSpec describes the data a pod should have + when created from a template + type: object + x-kubernetes-preserve-unknown-fields: true + replicas: + format: int32 + type: integer + strategy: + description: DeploymentStrategy describes how to replace existing + pods with new ones. + properties: + rollingUpdate: + description: |- + Rolling update config params. Present only if DeploymentStrategyType = + RollingUpdate. + properties: + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be scheduled above the desired number of + pods. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 25%. + Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when + the rolling update starts, such that the total number of old and new pods do not exceed + 130% of desired pods. Once old pods have been killed, + new ReplicaSet can be scaled up further, ensuring that total number of pods running + at any time during the update is at most 130% of desired pods. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 25%. + Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods + immediately when the rolling update starts. Once new pods are ready, old ReplicaSet + can be scaled down further, followed by scaling up the new ReplicaSet, ensuring + that the total number of pods available at all times during the update is at + least 70% of desired pods. + x-kubernetes-int-or-string: true + type: object + type: + description: Type of deployment. Can be "Recreate" or "RollingUpdate". + Default is RollingUpdate. + type: string + type: object + type: object + elasticsearchRef: + description: ElasticsearchRef is a reference to an Elasticsearch cluster + running in the same Kubernetes cluster. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + image: + description: Image is the Beat Docker image to deploy. Version and + Type have to match the Beat in the image. + type: string + kibanaRef: + description: |- + KibanaRef is a reference to a Kibana instance running in the same Kubernetes cluster. + It allows automatic setup of dashboards and visualizations. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + monitoring: + description: |- + Monitoring enables you to collect and ship logs and metrics for this Beat. + Metricbeat and/or Filebeat sidecars are configured and send monitoring data to an + Elasticsearch monitoring cluster running in the same Kubernetes cluster. + properties: + logs: + description: Logs holds references to Elasticsearch clusters which + receive log data from an associated resource. + properties: + elasticsearchRefs: + description: |- + ElasticsearchRefs is a reference to a list of monitoring Elasticsearch clusters running in the same Kubernetes cluster. + Due to existing limitations, only a single Elasticsearch cluster is currently supported. + items: + description: |- + ObjectSelector defines a reference to a Kubernetes object which can be an Elastic resource managed by the operator + or a Secret describing an external Elastic resource not managed by the operator. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If + empty, defaults to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + type: array + type: object + metrics: + description: Metrics holds references to Elasticsearch clusters + which receive monitoring data from this resource. + properties: + elasticsearchRefs: + description: |- + ElasticsearchRefs is a reference to a list of monitoring Elasticsearch clusters running in the same Kubernetes cluster. + Due to existing limitations, only a single Elasticsearch cluster is currently supported. + items: + description: |- + ObjectSelector defines a reference to a Kubernetes object which can be an Elastic resource managed by the operator + or a Secret describing an external Elastic resource not managed by the operator. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If + empty, defaults to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + type: array + type: object + type: object + revisionHistoryLimit: + description: RevisionHistoryLimit is the number of revisions to retain + to allow rollback in the underlying DaemonSet or Deployment. + format: int32 + type: integer + secureSettings: + description: |- + SecureSettings is a list of references to Kubernetes Secrets containing sensitive configuration options for the Beat. + Secrets data can be then referenced in the Beat config using the Secret's keys or as specified in `Entries` field of + each SecureSetting. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + serviceAccountName: + description: |- + ServiceAccountName is used to check access from the current resource to Elasticsearch resource in a different namespace. + Can only be used if ECK is enforcing RBAC on references. + type: string + type: + description: |- + Type is the type of the Beat to deploy (filebeat, metricbeat, heartbeat, auditbeat, journalbeat, packetbeat, and so on). + Any string can be used, but well-known types will have the image field defaulted and have the appropriate + Elasticsearch roles created automatically. It also allows for dashboard setup when combined with a `KibanaRef`. + maxLength: 20 + pattern: '[a-zA-Z0-9-]+' + type: string + version: + description: Version of the Beat. + type: string + required: + - type + - version + type: object + status: + description: BeatStatus defines the observed state of a Beat. + properties: + availableNodes: + format: int32 + type: integer + elasticsearchAssociationStatus: + description: AssociationStatus is the status of an association resource. + type: string + expectedNodes: + format: int32 + type: integer + health: + type: string + kibanaAssociationStatus: + description: AssociationStatus is the status of an association resource. + type: string + monitoringAssociationStatus: + additionalProperties: + description: AssociationStatus is the status of an association resource. + type: string + description: |- + AssociationStatusMap is the map of association's namespaced name string to its AssociationStatus. For resources that + have a single Association of a given type (for ex. single ES reference), this map contains a single entry. + type: object + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the status is based upon. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + If the generation observed in status diverges from the generation in metadata, the Beats + controller has not yet processed the changes contained in the Beats specification. + format: int64 + type: integer + version: + description: |- + Version of the stack resource currently running. During version upgrades, multiple versions may run + in parallel: this value specifies the lowest version currently running. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.18.0 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: elasticmapsservers.maps.k8s.elastic.co +spec: + group: maps.k8s.elastic.co + names: + categories: + - elastic + kind: ElasticMapsServer + listKind: ElasticMapsServerList + plural: elasticmapsservers + shortNames: + - ems + singular: elasticmapsserver + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: nodes + type: integer + - description: ElasticMapsServer version + jsonPath: .status.version + name: version + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: ElasticMapsServer represents an Elastic Map Server resource in + a Kubernetes cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MapsSpec holds the specification of an Elastic Maps Server + instance. + properties: + config: + description: 'Config holds the ElasticMapsServer configuration. See: + https://www.elastic.co/guide/en/kibana/current/maps-connect-to-ems.html#elastic-maps-server-configuration' + type: object + x-kubernetes-preserve-unknown-fields: true + configRef: + description: |- + ConfigRef contains a reference to an existing Kubernetes Secret holding the Elastic Maps Server configuration. + Configuration settings are merged and have precedence over settings specified in `config`. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + count: + description: Count of Elastic Maps Server instances to deploy. + format: int32 + type: integer + elasticsearchRef: + description: ElasticsearchRef is a reference to an Elasticsearch cluster + running in the same Kubernetes cluster. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + http: + description: HTTP holds the HTTP layer configuration for Elastic Maps + Server. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic + is distributed to Service endpoints. Implementations can use this field + as a hint, but are not required to guarantee strict adherence. If the + field is not set, the implementation will apply its default routing + strategy. If set to "PreferClose", implementations should prioritize + endpoints that are in the same zone. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the Elastic Maps Server Docker image to deploy. + type: string + podTemplate: + description: PodTemplate provides customisation options (labels, annotations, + affinity rules, resource requests, and so on) for the Elastic Maps + Server pods + type: object + x-kubernetes-preserve-unknown-fields: true + revisionHistoryLimit: + description: RevisionHistoryLimit is the number of revisions to retain + to allow rollback in the underlying Deployment. + format: int32 + type: integer + serviceAccountName: + description: |- + ServiceAccountName is used to check access from the current resource to a resource (for ex. Elasticsearch) in a different namespace. + Can only be used if ECK is enforcing RBAC on references. + type: string + version: + description: Version of Elastic Maps Server. + type: string + required: + - version + type: object + status: + description: MapsStatus defines the observed state of Elastic Maps Server + properties: + associationStatus: + description: AssociationStatus is the status of an association resource. + type: string + availableNodes: + description: AvailableNodes is the number of available replicas in + the deployment. + format: int32 + type: integer + count: + description: Count corresponds to Scale.Status.Replicas, which is + the actual number of observed instances of the scaled object. + format: int32 + type: integer + health: + description: Health of the deployment. + type: string + observedGeneration: + description: |- + ObservedGeneration is the most recent generation observed for this Elastic Maps Server. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + If the generation observed in status diverges from the generation in metadata, the Elastic + Maps controller has not yet processed the changes contained in the Elastic Maps specification. + format: int64 + type: integer + selector: + description: Selector is the label selector used to find all pods. + type: string + version: + description: |- + Version of the stack resource currently running. During version upgrades, multiple versions may run + in parallel: this value specifies the lowest version currently running. + type: string + type: object + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.count + statusReplicasPath: .status.count + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.18.0 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: elasticsearchautoscalers.autoscaling.k8s.elastic.co +spec: + group: autoscaling.k8s.elastic.co + names: + categories: + - elastic + kind: ElasticsearchAutoscaler + listKind: ElasticsearchAutoscalerList + plural: elasticsearchautoscalers + shortNames: + - esa + singular: elasticsearchautoscaler + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.elasticsearchRef.name + name: Target + type: string + - jsonPath: .status.conditions[?(@.type=='Active')].status + name: Active + type: string + - jsonPath: .status.conditions[?(@.type=='Healthy')].status + name: Healthy + type: string + - jsonPath: .status.conditions[?(@.type=='Limited')].status + name: Limited + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: ElasticsearchAutoscaler represents an ElasticsearchAutoscaler + resource in a Kubernetes cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ElasticsearchAutoscalerSpec holds the specification of an + Elasticsearch autoscaler resource. + properties: + elasticsearchRef: + description: ElasticsearchRef is a reference to an Elasticsearch cluster + that exists in the same namespace. + properties: + name: + description: Name is the name of the Elasticsearch resource to + scale automatically. + minLength: 1 + type: string + type: object + policies: + items: + description: AutoscalingPolicySpec holds a named autoscaling policy + and the associated resources limits (cpu, memory, storage). + properties: + deciders: + additionalProperties: + additionalProperties: + type: string + description: |- + DeciderSettings allow the user to tweak autoscaling deciders. + The map data structure complies with the format expected by Elasticsearch. + type: object + description: Deciders allow the user to override default settings + for autoscaling deciders. + type: object + name: + description: Name identifies the autoscaling policy in the autoscaling + specification. + type: string + resources: + description: |- + AutoscalingResources model the limits, submitted by the user, for the supported resources in an autoscaling policy. + Only the node count range is mandatory. For other resources, a limit range is required only + if the Elasticsearch autoscaling capacity API returns a requirement for a given resource. + For example, the memory limit range is only required if the autoscaling API response contains a memory requirement. + If there is no limit range for a resource, and if that resource is not mandatory, then the resources in the NodeSets + managed by the autoscaling policy are left untouched. + properties: + cpu: + description: QuantityRange models a resource limit range + for resources which can be expressed with resource.Quantity. + properties: + max: + anyOf: + - type: integer + - type: string + description: Max represents the upper limit for the + resources managed by the autoscaler. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + min: + anyOf: + - type: integer + - type: string + description: Min represents the lower limit for the + resources managed by the autoscaler. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + requestsToLimitsRatio: + anyOf: + - type: integer + - type: string + description: RequestsToLimitsRatio allows to customize + Kubernetes resource Limit based on the Request. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + required: + - max + - min + type: object + memory: + description: QuantityRange models a resource limit range + for resources which can be expressed with resource.Quantity. + properties: + max: + anyOf: + - type: integer + - type: string + description: Max represents the upper limit for the + resources managed by the autoscaler. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + min: + anyOf: + - type: integer + - type: string + description: Min represents the lower limit for the + resources managed by the autoscaler. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + requestsToLimitsRatio: + anyOf: + - type: integer + - type: string + description: RequestsToLimitsRatio allows to customize + Kubernetes resource Limit based on the Request. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + required: + - max + - min + type: object + nodeCount: + description: NodeCountRange is used to model the minimum + and the maximum number of nodes over all the NodeSets + managed by the same autoscaling policy. + properties: + max: + description: Max represents the maximum number of nodes + in a tier. + format: int32 + type: integer + min: + description: Min represents the minimum number of nodes + in a tier. + format: int32 + type: integer + required: + - max + - min + type: object + storage: + description: QuantityRange models a resource limit range + for resources which can be expressed with resource.Quantity. + properties: + max: + anyOf: + - type: integer + - type: string + description: Max represents the upper limit for the + resources managed by the autoscaler. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + min: + anyOf: + - type: integer + - type: string + description: Min represents the lower limit for the + resources managed by the autoscaler. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + requestsToLimitsRatio: + anyOf: + - type: integer + - type: string + description: RequestsToLimitsRatio allows to customize + Kubernetes resource Limit based on the Request. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + required: + - max + - min + type: object + required: + - nodeCount + type: object + roles: + description: An autoscaling policy must target a unique set + of roles. + items: + type: string + type: array + required: + - resources + type: object + type: array + pollingPeriod: + description: PollingPeriod is the period at which to synchronize with + the Elasticsearch autoscaling API. + type: string + required: + - elasticsearchRef + - policies + type: object + status: + properties: + conditions: + description: Conditions holds the current service state of the autoscaling + controller. + items: + description: |- + Condition represents Elasticsearch resource's condition. + **This API is in technical preview and may be changed or removed in a future release.** + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + status: + type: string + type: + description: ConditionType defines the condition of an Elasticsearch + resource. + type: string + required: + - status + - type + type: object + type: array + observedGeneration: + description: ObservedGeneration is the last observed generation by + the controller. + format: int64 + type: integer + policies: + description: AutoscalingPolicyStatuses is used to expose state messages + to user or external system. + items: + properties: + lastModificationTime: + description: LastModificationTime is the last time the resources + have been updated, used by the cooldown algorithm. + format: date-time + type: string + name: + description: Name is the name of the autoscaling policy + type: string + nodeSets: + description: NodeSetNodeCount holds the number of nodes for + each nodeSet. + items: + description: NodeSetNodeCount models the number of nodes expected + in a given NodeSet. + properties: + name: + description: Name of the Nodeset. + type: string + nodeCount: + description: NodeCount is the number of nodes, as computed + by the autoscaler, expected in this NodeSet. + format: int32 + type: integer + required: + - name + - nodeCount + type: object + type: array + resources: + description: |- + ResourcesSpecification holds the resource values common to all the nodeSets managed by a same autoscaling policy. + Only the resources managed by the autoscaling controller are saved in the Status. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: ResourceList is a set of (resource name, quantity) + pairs. + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: ResourceList is a set of (resource name, quantity) + pairs. + type: object + type: object + state: + description: PolicyStates may contain various messages regarding + the current state of this autoscaling policy. + items: + properties: + messages: + items: + type: string + type: array + type: + type: string + required: + - messages + - type + type: object + type: array + required: + - name + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.18.0 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: elasticsearches.elasticsearch.k8s.elastic.co +spec: + group: elasticsearch.k8s.elastic.co + names: + categories: + - elastic + kind: Elasticsearch + listKind: ElasticsearchList + plural: elasticsearches + shortNames: + - es + singular: elasticsearch + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: nodes + type: integer + - description: Elasticsearch version + jsonPath: .status.version + name: version + type: string + - jsonPath: .status.phase + name: phase + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1 + schema: + openAPIV3Schema: + description: Elasticsearch represents an Elasticsearch resource in a Kubernetes + cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ElasticsearchSpec holds the specification of an Elasticsearch + cluster. + properties: + auth: + description: Auth contains user authentication and authorization security + settings for Elasticsearch. + properties: + disableElasticUser: + description: DisableElasticUser disables the default elastic user + that is created by ECK. + type: boolean + fileRealm: + description: FileRealm to propagate to the Elasticsearch cluster. + items: + description: FileRealmSource references users to create in the + Elasticsearch cluster. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + type: array + roles: + description: Roles to propagate to the Elasticsearch cluster. + items: + description: RoleSource references roles to create in the Elasticsearch + cluster. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + type: array + type: object + http: + description: HTTP holds HTTP layer settings for Elasticsearch. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic + is distributed to Service endpoints. Implementations can use this field + as a hint, but are not required to guarantee strict adherence. If the + field is not set, the implementation will apply its default routing + strategy. If set to "PreferClose", implementations should prioritize + endpoints that are in the same zone. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the Elasticsearch Docker image to deploy. + type: string + monitoring: + description: |- + Monitoring enables you to collect and ship log and monitoring data of this Elasticsearch cluster. + See https://www.elastic.co/guide/en/elasticsearch/reference/current/monitor-elasticsearch-cluster.html. + Metricbeat and Filebeat are deployed in the same Pod as sidecars and each one sends data to one or two different + Elasticsearch monitoring clusters running in the same Kubernetes cluster. + properties: + logs: + description: Logs holds references to Elasticsearch clusters which + receive log data from an associated resource. + properties: + elasticsearchRefs: + description: |- + ElasticsearchRefs is a reference to a list of monitoring Elasticsearch clusters running in the same Kubernetes cluster. + Due to existing limitations, only a single Elasticsearch cluster is currently supported. + items: + description: |- + ObjectSelector defines a reference to a Kubernetes object which can be an Elastic resource managed by the operator + or a Secret describing an external Elastic resource not managed by the operator. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If + empty, defaults to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + type: array + type: object + metrics: + description: Metrics holds references to Elasticsearch clusters + which receive monitoring data from this resource. + properties: + elasticsearchRefs: + description: |- + ElasticsearchRefs is a reference to a list of monitoring Elasticsearch clusters running in the same Kubernetes cluster. + Due to existing limitations, only a single Elasticsearch cluster is currently supported. + items: + description: |- + ObjectSelector defines a reference to a Kubernetes object which can be an Elastic resource managed by the operator + or a Secret describing an external Elastic resource not managed by the operator. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If + empty, defaults to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + type: array + type: object + type: object + nodeSets: + description: NodeSets allow specifying groups of Elasticsearch nodes + sharing the same configuration and Pod templates. + items: + description: NodeSet is the specification for a group of Elasticsearch + nodes sharing the same configuration and a Pod template. + properties: + config: + description: Config holds the Elasticsearch configuration. + type: object + x-kubernetes-preserve-unknown-fields: true + count: + description: |- + Count of Elasticsearch nodes to deploy. + If the node set is managed by an autoscaling policy the initial value is automatically set by the autoscaling controller. + format: int32 + type: integer + name: + description: Name of this set of nodes. Becomes a part of the + Elasticsearch node.name setting. + maxLength: 23 + pattern: '[a-zA-Z0-9-]+' + type: string + podTemplate: + description: PodTemplate provides customisation options (labels, + annotations, affinity rules, resource requests, and so on) + for the Pods belonging to this NodeSet. + type: object + x-kubernetes-preserve-unknown-fields: true + volumeClaimTemplates: + description: |- + VolumeClaimTemplates is a list of persistent volume claims to be used by each Pod in this NodeSet. + Every claim in this list must have a matching volumeMount in one of the containers defined in the PodTemplate. + Items defined here take precedence over any default claims added by the operator with the same name. + items: + description: PersistentVolumeClaim is a user's request for + and claim to a persistent volume + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + spec defines the desired characteristics of a volume requested by a pod author. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes + to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to + the PersistentVolume backing this claim. + type: string + type: object + type: object + type: array + required: + - name + type: object + minItems: 1 + type: array + podDisruptionBudget: + description: |- + PodDisruptionBudget provides access to the default Pod disruption budget for the Elasticsearch cluster. + The default budget doesn't allow any Pod to be removed in case the cluster is not green or if there is only one node of type `data` or `master`. + In all other cases the default PodDisruptionBudget sets `minUnavailable` equal to the total number of nodes minus 1. + To disable, set `PodDisruptionBudget` to the empty value (`{}` in YAML). + properties: + metadata: + description: |- + ObjectMeta is the metadata of the PDB. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the PDB. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + An eviction is allowed if at most "maxUnavailable" pods selected by + "selector" are unavailable after the eviction, i.e. even in absence of + the evicted pod. For example, one can prevent all voluntary evictions + by specifying 0. This is a mutually exclusive setting with "minAvailable". + x-kubernetes-int-or-string: true + minAvailable: + anyOf: + - type: integer + - type: string + description: |- + An eviction is allowed if at least "minAvailable" pods selected by + "selector" will still be available after the eviction, i.e. even in the + absence of the evicted pod. So for example you can prevent all voluntary + evictions by specifying "100%". + x-kubernetes-int-or-string: true + selector: + description: |- + Label query over pods whose evictions are managed by the disruption + budget. + A null selector will match no pods, while an empty ({}) selector will select + all pods within the namespace. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + unhealthyPodEvictionPolicy: + description: |- + UnhealthyPodEvictionPolicy defines the criteria for when unhealthy pods + should be considered for eviction. Current implementation considers healthy pods, + as pods that have status.conditions item with type="Ready",status="True". + + Valid policies are IfHealthyBudget and AlwaysAllow. + If no policy is specified, the default behavior will be used, + which corresponds to the IfHealthyBudget policy. + + IfHealthyBudget policy means that running pods (status.phase="Running"), + but not yet healthy can be evicted only if the guarded application is not + disrupted (status.currentHealthy is at least equal to status.desiredHealthy). + Healthy pods will be subject to the PDB for eviction. + + AlwaysAllow policy means that all running pods (status.phase="Running"), + but not yet healthy are considered disrupted and can be evicted regardless + of whether the criteria in a PDB is met. This means perspective running + pods of a disrupted application might not get a chance to become healthy. + Healthy pods will be subject to the PDB for eviction. + + Additional policies may be added in the future. + Clients making eviction decisions should disallow eviction of unhealthy pods + if they encounter an unrecognized policy in this field. + type: string + type: object + type: object + remoteClusterServer: + description: |- + RemoteClusterServer specifies if the remote cluster server should be enabled. + This must be enabled if this cluster is a remote cluster which is expected to be accessed using API key authentication. + properties: + enabled: + type: boolean + type: object + remoteClusters: + description: RemoteClusters enables you to establish uni-directional + connections to a remote Elasticsearch cluster. + items: + description: RemoteCluster declares a remote Elasticsearch cluster + connection. + properties: + apiKey: + description: 'APIKey can be used to enable remote cluster access + using Cross-Cluster API keys: https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-cross-cluster-api-key.html' + properties: + access: + description: Access is the name of the API Key. It is automatically + generated if not set or empty. + properties: + replication: + properties: + names: + items: + type: string + type: array + required: + - names + type: object + search: + properties: + allow_restricted_indices: + type: boolean + field_security: + properties: + except: + items: + type: string + type: array + grant: + items: + type: string + type: array + required: + - except + - grant + type: object + names: + items: + type: string + type: array + query: + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - names + type: object + type: object + required: + - access + type: object + elasticsearchRef: + description: ElasticsearchRef is a reference to an Elasticsearch + cluster running within the same k8s cluster. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, + defaults to the current namespace. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + name: + description: |- + Name is the name of the remote cluster as it is set in the Elasticsearch settings. + The name is expected to be unique for each remote clusters. + minLength: 1 + type: string + required: + - name + type: object + type: array + revisionHistoryLimit: + description: RevisionHistoryLimit is the number of revisions to retain + to allow rollback in the underlying StatefulSets. + format: int32 + type: integer + secureSettings: + description: SecureSettings is a list of references to Kubernetes + secrets containing sensitive configuration options for Elasticsearch. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + serviceAccountName: + description: |- + ServiceAccountName is used to check access from the current resource to a resource (for ex. a remote Elasticsearch cluster) in a different namespace. + Can only be used if ECK is enforcing RBAC on references. + type: string + transport: + description: Transport holds transport layer settings for Elasticsearch. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic + is distributed to Service endpoints. Implementations can use this field + as a hint, but are not required to guarantee strict adherence. If the + field is not set, the implementation will apply its default routing + strategy. If set to "PreferClose", implementations should prioritize + endpoints that are in the same zone. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS on the transport + layer. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the CA certificate + and private key for generating node certificates. + The referenced secret should contain the following: + + - `ca.crt`: The CA certificate in PEM format. + - `ca.key`: The private key for the CA certificate in PEM format. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + certificateAuthorities: + description: |- + CertificateAuthorities is a reference to a config map that contains one or more x509 certificates for + trusted authorities in PEM format. The certificates need to be in a file called `ca.crt`. + properties: + configMapName: + type: string + type: object + otherNameSuffix: + description: |- + OtherNameSuffix when defined will be prefixed with the Pod name and used as the common name, + and the first DNSName, as well as an OtherName required by Elasticsearch in the Subject Alternative Name + extension of each Elasticsearch node's transport TLS certificate. + Example: if set to "node.cluster.local", the generated certificate will have its otherName set to ".node.cluster.local". + type: string + selfSignedCertificates: + description: SelfSignedCertificates allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that provisioning of the + self-signed certificates should be disabled. + type: boolean + type: object + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs to + include in the generated node transport TLS certificates. + items: + description: SubjectAlternativeName represents a SAN entry + in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + updateStrategy: + description: UpdateStrategy specifies how updates to the cluster should + be performed. + properties: + changeBudget: + description: ChangeBudget defines the constraints to consider + when applying changes to the Elasticsearch cluster. + properties: + maxSurge: + description: |- + MaxSurge is the maximum number of new Pods that can be created exceeding the original number of Pods defined in + the specification. MaxSurge is only taken into consideration when scaling up. Setting a negative value will + disable the restriction. Defaults to unbounded if not specified. + format: int32 + type: integer + maxUnavailable: + description: |- + MaxUnavailable is the maximum number of Pods that can be unavailable (not ready) during the update due to + circumstances under the control of the operator. Setting a negative value will disable this restriction. + Defaults to 1 if not specified. + format: int32 + type: integer + type: object + type: object + version: + description: Version of Elasticsearch. + type: string + volumeClaimDeletePolicy: + description: |- + VolumeClaimDeletePolicy sets the policy for handling deletion of PersistentVolumeClaims for all NodeSets. + Possible values are DeleteOnScaledownOnly and DeleteOnScaledownAndClusterDeletion. Defaults to DeleteOnScaledownAndClusterDeletion. + enum: + - DeleteOnScaledownOnly + - DeleteOnScaledownAndClusterDeletion + type: string + required: + - nodeSets + - version + type: object + status: + description: ElasticsearchStatus represents the observed state of Elasticsearch. + properties: + availableNodes: + description: AvailableNodes is the number of available instances. + format: int32 + type: integer + conditions: + description: |- + Conditions holds the current service state of an Elasticsearch cluster. + **This API is in technical preview and may be changed or removed in a future release.** + items: + description: |- + Condition represents Elasticsearch resource's condition. + **This API is in technical preview and may be changed or removed in a future release.** + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + status: + type: string + type: + description: ConditionType defines the condition of an Elasticsearch + resource. + type: string + required: + - status + - type + type: object + type: array + health: + description: ElasticsearchHealth is the health of the cluster as returned + by the health API. + type: string + inProgressOperations: + description: |- + InProgressOperations represents changes being applied by the operator to the Elasticsearch cluster. + **This API is in technical preview and may be changed or removed in a future release.** + properties: + downscale: + description: |- + DownscaleOperation provides details about in progress downscale operations. + **This API is in technical preview and may be changed or removed in a future release.** + properties: + lastUpdatedTime: + format: date-time + type: string + nodes: + description: Nodes which are scheduled to be removed from + the cluster. + items: + description: |- + DownscaledNode provides an overview of in progress changes applied by the operator to remove Elasticsearch nodes from the cluster. + **This API is in technical preview and may be changed or removed in a future release.** + properties: + explanation: + description: |- + Explanation provides details about an in progress node shutdown. It is only available for clusters managed with the + Elasticsearch shutdown API. + type: string + name: + description: Name of the Elasticsearch node that should + be removed. + type: string + shutdownStatus: + description: |- + Shutdown status as returned by the Elasticsearch shutdown API. + If the Elasticsearch shutdown API is not available, the shutdown status is then inferred from the remaining + shards on the nodes, as observed by the operator. + type: string + required: + - name + - shutdownStatus + type: object + type: array + stalled: + description: |- + Stalled represents a state where no progress can be made. + It is only available for clusters managed with the Elasticsearch shutdown API. + type: boolean + type: object + upgrade: + description: |- + UpgradeOperation provides an overview of the pending or in progress changes applied by the operator to update the Elasticsearch nodes in the cluster. + **This API is in technical preview and may be changed or removed in a future release.** + properties: + lastUpdatedTime: + format: date-time + type: string + nodes: + description: Nodes that must be restarted for upgrade. + items: + description: |- + UpgradedNode provides details about the status of nodes which are expected to be updated. + **This API is in technical preview and may be changed or removed in a future release.** + properties: + message: + description: Optional message to explain why a node + may not be immediately restarted for upgrade. + type: string + name: + description: Name of the Elasticsearch node that should + be upgraded. + type: string + predicate: + description: Predicate is the name of the predicate + currently preventing this node from being deleted + for an upgrade. + type: string + status: + description: |- + Status states if the node is either in the process of being deleted for an upgrade, + or blocked by a predicate or another condition stated in the message field. + type: string + required: + - name + - status + type: object + type: array + type: object + upscale: + description: |- + UpscaleOperation provides an overview of in progress changes applied by the operator to add Elasticsearch nodes to the cluster. + **This API is in technical preview and may be changed or removed in a future release.** + properties: + lastUpdatedTime: + format: date-time + type: string + nodes: + description: Nodes expected to be added by the operator. + items: + properties: + message: + description: Optional message to explain why a node + may not be immediately added. + type: string + name: + description: Name of the Elasticsearch node that should + be added to the cluster. + type: string + status: + description: NewNodeStatus states if a new node is being + created, or if the upscale is delayed. + type: string + required: + - name + - status + type: object + type: array + type: object + required: + - downscale + - upgrade + - upscale + type: object + monitoringAssociationStatus: + additionalProperties: + description: AssociationStatus is the status of an association resource. + type: string + description: |- + AssociationStatusMap is the map of association's namespaced name string to its AssociationStatus. For resources that + have a single Association of a given type (for ex. single ES reference), this map contains a single entry. + type: object + observedGeneration: + description: |- + ObservedGeneration is the most recent generation observed for this Elasticsearch cluster. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + If the generation observed in status diverges from the generation in metadata, the Elasticsearch + controller has not yet processed the changes contained in the Elasticsearch specification. + format: int64 + type: integer + phase: + description: ElasticsearchOrchestrationPhase is the phase Elasticsearch + is in from the controller point of view. + type: string + version: + description: |- + Version of the stack resource currently running. During version upgrades, multiple versions may run + in parallel: this value specifies the lowest version currently running. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: nodes + type: integer + - description: Elasticsearch version + jsonPath: .spec.version + name: version + type: string + - jsonPath: .status.phase + name: phase + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: Elasticsearch represents an Elasticsearch resource in a Kubernetes + cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ElasticsearchSpec holds the specification of an Elasticsearch + cluster. + properties: + http: + description: HTTP holds HTTP layer settings for Elasticsearch. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic + is distributed to Service endpoints. Implementations can use this field + as a hint, but are not required to guarantee strict adherence. If the + field is not set, the implementation will apply its default routing + strategy. If set to "PreferClose", implementations should prioritize + endpoints that are in the same zone. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the Elasticsearch Docker image to deploy. + type: string + nodeSets: + description: NodeSets allow specifying groups of Elasticsearch nodes + sharing the same configuration and Pod templates. + items: + description: NodeSet is the specification for a group of Elasticsearch + nodes sharing the same configuration and a Pod template. + properties: + config: + description: Config holds the Elasticsearch configuration. + type: object + count: + description: Count of Elasticsearch nodes to deploy. + format: int32 + minimum: 1 + type: integer + name: + description: Name of this set of nodes. Becomes a part of the + Elasticsearch node.name setting. + maxLength: 23 + pattern: '[a-zA-Z0-9-]+' + type: string + podTemplate: + description: PodTemplate provides customisation options (labels, + annotations, affinity rules, resource requests, and so on) + for the Pods belonging to this NodeSet. + type: object + volumeClaimTemplates: + description: |- + VolumeClaimTemplates is a list of persistent volume claims to be used by each Pod in this NodeSet. + Every claim in this list must have a matching volumeMount in one of the containers defined in the PodTemplate. + Items defined here take precedence over any default claims added by the operator with the same name. + items: + description: PersistentVolumeClaim is a user's request for + and claim to a persistent volume + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + spec defines the desired characteristics of a volume requested by a pod author. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes + to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to + the PersistentVolume backing this claim. + type: string + type: object + type: object + type: array + required: + - count + - name + type: object + minItems: 1 + type: array + podDisruptionBudget: + description: |- + PodDisruptionBudget provides access to the default pod disruption budget for the Elasticsearch cluster. + The default budget selects all cluster pods and sets `maxUnavailable` to 1. To disable, set `PodDisruptionBudget` + to the empty value (`{}` in YAML). + properties: + metadata: + description: |- + ObjectMeta is the metadata of the PDB. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the PDB. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + An eviction is allowed if at most "maxUnavailable" pods selected by + "selector" are unavailable after the eviction, i.e. even in absence of + the evicted pod. For example, one can prevent all voluntary evictions + by specifying 0. This is a mutually exclusive setting with "minAvailable". + x-kubernetes-int-or-string: true + minAvailable: + anyOf: + - type: integer + - type: string + description: |- + An eviction is allowed if at least "minAvailable" pods selected by + "selector" will still be available after the eviction, i.e. even in the + absence of the evicted pod. So for example you can prevent all voluntary + evictions by specifying "100%". + x-kubernetes-int-or-string: true + selector: + description: |- + Label query over pods whose evictions are managed by the disruption + budget. + A null selector selects no pods. + An empty selector ({}) also selects no pods, which differs from standard behavior of selecting all pods. + In policy/v1, an empty selector will select all pods in the namespace. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + unhealthyPodEvictionPolicy: + description: |- + UnhealthyPodEvictionPolicy defines the criteria for when unhealthy pods + should be considered for eviction. Current implementation considers healthy pods, + as pods that have status.conditions item with type="Ready",status="True". + + Valid policies are IfHealthyBudget and AlwaysAllow. + If no policy is specified, the default behavior will be used, + which corresponds to the IfHealthyBudget policy. + + IfHealthyBudget policy means that running pods (status.phase="Running"), + but not yet healthy can be evicted only if the guarded application is not + disrupted (status.currentHealthy is at least equal to status.desiredHealthy). + Healthy pods will be subject to the PDB for eviction. + + AlwaysAllow policy means that all running pods (status.phase="Running"), + but not yet healthy are considered disrupted and can be evicted regardless + of whether the criteria in a PDB is met. This means perspective running + pods of a disrupted application might not get a chance to become healthy. + Healthy pods will be subject to the PDB for eviction. + + Additional policies may be added in the future. + Clients making eviction decisions should disallow eviction of unhealthy pods + if they encounter an unrecognized policy in this field. + type: string + type: object + type: object + secureSettings: + description: SecureSettings is a list of references to Kubernetes + secrets containing sensitive configuration options for Elasticsearch. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + updateStrategy: + description: UpdateStrategy specifies how updates to the cluster should + be performed. + properties: + changeBudget: + description: ChangeBudget defines the constraints to consider + when applying changes to the Elasticsearch cluster. + properties: + maxSurge: + description: |- + MaxSurge is the maximum number of new pods that can be created exceeding the original number of pods defined in + the specification. MaxSurge is only taken into consideration when scaling up. Setting a negative value will + disable the restriction. Defaults to unbounded if not specified. + format: int32 + type: integer + maxUnavailable: + description: |- + MaxUnavailable is the maximum number of pods that can be unavailable (not ready) during the update due to + circumstances under the control of the operator. Setting a negative value will disable this restriction. + Defaults to 1 if not specified. + format: int32 + type: integer + type: object + type: object + version: + description: Version of Elasticsearch. + type: string + required: + - nodeSets + type: object + status: + description: ElasticsearchStatus defines the observed state of Elasticsearch + properties: + availableNodes: + format: int32 + type: integer + health: + description: ElasticsearchHealth is the health of the cluster as returned + by the health API. + type: string + phase: + description: ElasticsearchOrchestrationPhase is the phase Elasticsearch + is in from the controller point of view. + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} + - name: v1alpha1 + schema: + openAPIV3Schema: + description: to not break compatibility when upgrading from previous versions + of the CRD + type: object + served: false + storage: false +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.18.0 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: enterprisesearches.enterprisesearch.k8s.elastic.co +spec: + group: enterprisesearch.k8s.elastic.co + names: + categories: + - elastic + kind: EnterpriseSearch + listKind: EnterpriseSearchList + plural: enterprisesearches + shortNames: + - ent + singular: enterprisesearch + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: nodes + type: integer + - description: Enterprise Search version + jsonPath: .status.version + name: version + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1 + schema: + openAPIV3Schema: + description: EnterpriseSearch is a Kubernetes CRD to represent Enterprise + Search. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: EnterpriseSearchSpec holds the specification of an Enterprise + Search resource. + properties: + config: + description: Config holds the Enterprise Search configuration. + type: object + x-kubernetes-preserve-unknown-fields: true + configRef: + description: |- + ConfigRef contains a reference to an existing Kubernetes Secret holding the Enterprise Search configuration. + Configuration settings are merged and have precedence over settings specified in `config`. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + count: + description: Count of Enterprise Search instances to deploy. + format: int32 + type: integer + elasticsearchRef: + description: ElasticsearchRef is a reference to the Elasticsearch + cluster running in the same Kubernetes cluster. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + http: + description: HTTP holds the HTTP layer configuration for Enterprise + Search resource. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic + is distributed to Service endpoints. Implementations can use this field + as a hint, but are not required to guarantee strict adherence. If the + field is not set, the implementation will apply its default routing + strategy. If set to "PreferClose", implementations should prioritize + endpoints that are in the same zone. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the Enterprise Search Docker image to deploy. + type: string + podTemplate: + description: |- + PodTemplate provides customisation options (labels, annotations, affinity rules, resource requests, and so on) + for the Enterprise Search pods. + type: object + x-kubernetes-preserve-unknown-fields: true + revisionHistoryLimit: + description: RevisionHistoryLimit is the number of revisions to retain + to allow rollback in the underlying Deployment. + format: int32 + type: integer + serviceAccountName: + description: |- + ServiceAccountName is used to check access from the current resource to a resource (for ex. Elasticsearch) in a different namespace. + Can only be used if ECK is enforcing RBAC on references. + type: string + version: + description: Version of Enterprise Search. + type: string + type: object + status: + description: EnterpriseSearchStatus defines the observed state of EnterpriseSearch + properties: + associationStatus: + description: Association is the status of any auto-linking to Elasticsearch + clusters. + type: string + availableNodes: + description: AvailableNodes is the number of available replicas in + the deployment. + format: int32 + type: integer + count: + description: Count corresponds to Scale.Status.Replicas, which is + the actual number of observed instances of the scaled object. + format: int32 + type: integer + health: + description: Health of the deployment. + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the status is based upon. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + If the generation observed in status diverges from the generation in metadata, the Enterprise Search + controller has not yet processed the changes contained in the Enterprise Search specification. + format: int64 + type: integer + selector: + description: Selector is the label selector used to find all pods. + type: string + service: + description: ExternalService is the name of the service associated + to the Enterprise Search Pods. + type: string + version: + description: |- + Version of the stack resource currently running. During version upgrades, multiple versions may run + in parallel: this value specifies the lowest version currently running. + type: string + type: object + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.count + statusReplicasPath: .status.count + status: {} + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: nodes + type: integer + - description: Enterprise Search version + jsonPath: .status.version + name: version + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: EnterpriseSearch is a Kubernetes CRD to represent Enterprise + Search. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: EnterpriseSearchSpec holds the specification of an Enterprise + Search resource. + properties: + config: + description: Config holds the Enterprise Search configuration. + type: object + x-kubernetes-preserve-unknown-fields: true + configRef: + description: |- + ConfigRef contains a reference to an existing Kubernetes Secret holding the Enterprise Search configuration. + Configuration settings are merged and have precedence over settings specified in `config`. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + count: + description: Count of Enterprise Search instances to deploy. + format: int32 + type: integer + elasticsearchRef: + description: ElasticsearchRef is a reference to the Elasticsearch + cluster running in the same Kubernetes cluster. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + http: + description: HTTP holds the HTTP layer configuration for Enterprise + Search resource. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic + is distributed to Service endpoints. Implementations can use this field + as a hint, but are not required to guarantee strict adherence. If the + field is not set, the implementation will apply its default routing + strategy. If set to "PreferClose", implementations should prioritize + endpoints that are in the same zone. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the Enterprise Search Docker image to deploy. + type: string + podTemplate: + description: |- + PodTemplate provides customisation options (labels, annotations, affinity rules, resource requests, and so on) + for the Enterprise Search pods. + type: object + x-kubernetes-preserve-unknown-fields: true + serviceAccountName: + description: |- + ServiceAccountName is used to check access from the current resource to a resource (for ex. Elasticsearch) in a different namespace. + Can only be used if ECK is enforcing RBAC on references. + type: string + version: + description: Version of Enterprise Search. + type: string + type: object + status: + description: EnterpriseSearchStatus defines the observed state of EnterpriseSearch + properties: + associationStatus: + description: Association is the status of any auto-linking to Elasticsearch + clusters. + type: string + availableNodes: + description: AvailableNodes is the number of available replicas in + the deployment. + format: int32 + type: integer + count: + description: Count corresponds to Scale.Status.Replicas, which is + the actual number of observed instances of the scaled object. + format: int32 + type: integer + health: + description: Health of the deployment. + type: string + selector: + description: Selector is the label selector used to find all pods. + type: string + service: + description: ExternalService is the name of the service associated + to the Enterprise Search Pods. + type: string + version: + description: |- + Version of the stack resource currently running. During version upgrades, multiple versions may run + in parallel: this value specifies the lowest version currently running. + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.18.0 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: kibanas.kibana.k8s.elastic.co +spec: + group: kibana.k8s.elastic.co + names: + categories: + - elastic + kind: Kibana + listKind: KibanaList + plural: kibanas + shortNames: + - kb + singular: kibana + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: nodes + type: integer + - description: Kibana version + jsonPath: .status.version + name: version + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1 + schema: + openAPIV3Schema: + description: Kibana represents a Kibana resource in a Kubernetes cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: KibanaSpec holds the specification of a Kibana instance. + properties: + config: + description: 'Config holds the Kibana configuration. See: https://www.elastic.co/guide/en/kibana/current/settings.html' + type: object + x-kubernetes-preserve-unknown-fields: true + count: + description: Count of Kibana instances to deploy. + format: int32 + type: integer + elasticsearchRef: + description: ElasticsearchRef is a reference to an Elasticsearch cluster + running in the same Kubernetes cluster. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + enterpriseSearchRef: + description: |- + EnterpriseSearchRef is a reference to an EnterpriseSearch running in the same Kubernetes cluster. + Kibana provides the default Enterprise Search UI starting version 7.14. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + http: + description: HTTP holds the HTTP layer configuration for Kibana. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic + is distributed to Service endpoints. Implementations can use this field + as a hint, but are not required to guarantee strict adherence. If the + field is not set, the implementation will apply its default routing + strategy. If set to "PreferClose", implementations should prioritize + endpoints that are in the same zone. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the Kibana Docker image to deploy. + type: string + monitoring: + description: |- + Monitoring enables you to collect and ship log and monitoring data of this Kibana. + See https://www.elastic.co/guide/en/kibana/current/xpack-monitoring.html. + Metricbeat and Filebeat are deployed in the same Pod as sidecars and each one sends data to one or two different + Elasticsearch monitoring clusters running in the same Kubernetes cluster. + properties: + logs: + description: Logs holds references to Elasticsearch clusters which + receive log data from an associated resource. + properties: + elasticsearchRefs: + description: |- + ElasticsearchRefs is a reference to a list of monitoring Elasticsearch clusters running in the same Kubernetes cluster. + Due to existing limitations, only a single Elasticsearch cluster is currently supported. + items: + description: |- + ObjectSelector defines a reference to a Kubernetes object which can be an Elastic resource managed by the operator + or a Secret describing an external Elastic resource not managed by the operator. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If + empty, defaults to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + type: array + type: object + metrics: + description: Metrics holds references to Elasticsearch clusters + which receive monitoring data from this resource. + properties: + elasticsearchRefs: + description: |- + ElasticsearchRefs is a reference to a list of monitoring Elasticsearch clusters running in the same Kubernetes cluster. + Due to existing limitations, only a single Elasticsearch cluster is currently supported. + items: + description: |- + ObjectSelector defines a reference to a Kubernetes object which can be an Elastic resource managed by the operator + or a Secret describing an external Elastic resource not managed by the operator. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If + empty, defaults to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + type: array + type: object + type: object + podTemplate: + description: PodTemplate provides customisation options (labels, annotations, + affinity rules, resource requests, and so on) for the Kibana pods + type: object + x-kubernetes-preserve-unknown-fields: true + revisionHistoryLimit: + description: RevisionHistoryLimit is the number of revisions to retain + to allow rollback in the underlying Deployment. + format: int32 + type: integer + secureSettings: + description: SecureSettings is a list of references to Kubernetes + secrets containing sensitive configuration options for Kibana. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + serviceAccountName: + description: |- + ServiceAccountName is used to check access from the current resource to a resource (for ex. Elasticsearch) in a different namespace. + Can only be used if ECK is enforcing RBAC on references. + type: string + version: + description: Version of Kibana. + type: string + required: + - version + type: object + status: + description: KibanaStatus defines the observed state of Kibana + properties: + associationStatus: + description: |- + AssociationStatus is the status of any auto-linking to Elasticsearch clusters. + This field is deprecated and will be removed in a future release. Use ElasticsearchAssociationStatus instead. + type: string + availableNodes: + description: AvailableNodes is the number of available replicas in + the deployment. + format: int32 + type: integer + count: + description: Count corresponds to Scale.Status.Replicas, which is + the actual number of observed instances of the scaled object. + format: int32 + type: integer + elasticsearchAssociationStatus: + description: ElasticsearchAssociationStatus is the status of any auto-linking + to Elasticsearch clusters. + type: string + enterpriseSearchAssociationStatus: + description: EnterpriseSearchAssociationStatus is the status of any + auto-linking to Enterprise Search. + type: string + health: + description: Health of the deployment. + type: string + monitoringAssociationStatus: + additionalProperties: + description: AssociationStatus is the status of an association resource. + type: string + description: MonitoringAssociationStatus is the status of any auto-linking + to monitoring Elasticsearch clusters. + type: object + observedGeneration: + description: |- + ObservedGeneration is the most recent generation observed for this Kibana instance. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + If the generation observed in status diverges from the generation in metadata, the Kibana + controller has not yet processed the changes contained in the Kibana specification. + format: int64 + type: integer + selector: + description: Selector is the label selector used to find all pods. + type: string + version: + description: |- + Version of the stack resource currently running. During version upgrades, multiple versions may run + in parallel: this value specifies the lowest version currently running. + type: string + type: object + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.count + statusReplicasPath: .status.count + status: {} + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: nodes + type: integer + - description: Kibana version + jsonPath: .spec.version + name: version + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: Kibana represents a Kibana resource in a Kubernetes cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: KibanaSpec holds the specification of a Kibana instance. + properties: + config: + description: 'Config holds the Kibana configuration. See: https://www.elastic.co/guide/en/kibana/current/settings.html' + type: object + x-kubernetes-preserve-unknown-fields: true + count: + description: Count of Kibana instances to deploy. + format: int32 + type: integer + elasticsearchRef: + description: ElasticsearchRef is a reference to an Elasticsearch cluster + running in the same Kubernetes cluster. + properties: + name: + description: Name of the Kubernetes object. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + required: + - name + type: object + http: + description: HTTP holds the HTTP layer configuration for Kibana. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic + is distributed to Service endpoints. Implementations can use this field + as a hint, but are not required to guarantee strict adherence. If the + field is not set, the implementation will apply its default routing + strategy. If set to "PreferClose", implementations should prioritize + endpoints that are in the same zone. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the Kibana Docker image to deploy. + type: string + podTemplate: + description: PodTemplate provides customisation options (labels, annotations, + affinity rules, resource requests, and so on) for the Kibana pods + type: object + x-kubernetes-preserve-unknown-fields: true + secureSettings: + description: SecureSettings is a list of references to Kubernetes + secrets containing sensitive configuration options for Kibana. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + version: + description: Version of Kibana. + type: string + type: object + status: + description: KibanaStatus defines the observed state of Kibana + properties: + associationStatus: + description: AssociationStatus is the status of an association resource. + type: string + availableNodes: + format: int32 + type: integer + health: + description: KibanaHealth expresses the status of the Kibana instances. + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} + - name: v1alpha1 + schema: + openAPIV3Schema: + description: to not break compatibility when upgrading from previous versions + of the CRD + type: object + served: false + storage: false +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.18.0 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: logstashes.logstash.k8s.elastic.co +spec: + group: logstash.k8s.elastic.co + names: + categories: + - elastic + kind: Logstash + listKind: LogstashList + plural: logstashes + shortNames: + - ls + singular: logstash + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Health + jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: available + type: integer + - description: Expected nodes + jsonPath: .status.expectedNodes + name: expected + type: integer + - jsonPath: .metadata.creationTimestamp + name: age + type: date + - description: Logstash version + jsonPath: .status.version + name: version + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: Logstash is the Schema for the logstashes API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: LogstashSpec defines the desired state of Logstash + properties: + config: + description: Config holds the Logstash configuration. At most one + of [`Config`, `ConfigRef`] can be specified. + type: object + x-kubernetes-preserve-unknown-fields: true + configRef: + description: |- + ConfigRef contains a reference to an existing Kubernetes Secret holding the Logstash configuration. + Logstash settings must be specified as yaml, under a single "logstash.yml" entry. At most one of [`Config`, `ConfigRef`] + can be specified. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + count: + format: int32 + type: integer + elasticsearchRefs: + description: ElasticsearchRefs are references to Elasticsearch clusters + running in the same Kubernetes cluster. + items: + description: ElasticsearchCluster is a named reference to an Elasticsearch + cluster which can be used in a Logstash pipeline. + properties: + clusterName: + description: |- + ClusterName is an alias for the cluster to be used to refer to the Elasticsearch cluster in Logstash + configuration files, and will be used to identify "named clusters" in Logstash + minLength: 1 + type: string + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + required: + - clusterName + type: object + type: array + image: + description: Image is the Logstash Docker image to deploy. Version + and Type have to match the Logstash in the image. + type: string + monitoring: + description: |- + Monitoring enables you to collect and ship log and monitoring data of this Logstash. + Metricbeat and Filebeat are deployed in the same Pod as sidecars and each one sends data to one or two different + Elasticsearch monitoring clusters running in the same Kubernetes cluster. + properties: + logs: + description: Logs holds references to Elasticsearch clusters which + receive log data from an associated resource. + properties: + elasticsearchRefs: + description: |- + ElasticsearchRefs is a reference to a list of monitoring Elasticsearch clusters running in the same Kubernetes cluster. + Due to existing limitations, only a single Elasticsearch cluster is currently supported. + items: + description: |- + ObjectSelector defines a reference to a Kubernetes object which can be an Elastic resource managed by the operator + or a Secret describing an external Elastic resource not managed by the operator. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If + empty, defaults to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + type: array + type: object + metrics: + description: Metrics holds references to Elasticsearch clusters + which receive monitoring data from this resource. + properties: + elasticsearchRefs: + description: |- + ElasticsearchRefs is a reference to a list of monitoring Elasticsearch clusters running in the same Kubernetes cluster. + Due to existing limitations, only a single Elasticsearch cluster is currently supported. + items: + description: |- + ObjectSelector defines a reference to a Kubernetes object which can be an Elastic resource managed by the operator + or a Secret describing an external Elastic resource not managed by the operator. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If + empty, defaults to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + type: array + type: object + type: object + pipelines: + description: Pipelines holds the Logstash Pipelines. At most one of + [`Pipelines`, `PipelinesRef`] can be specified. + items: + type: object + type: array + x-kubernetes-preserve-unknown-fields: true + pipelinesRef: + description: |- + PipelinesRef contains a reference to an existing Kubernetes Secret holding the Logstash Pipelines. + Logstash pipelines must be specified as yaml, under a single "pipelines.yml" entry. At most one of [`Pipelines`, `PipelinesRef`] + can be specified. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + podTemplate: + description: PodTemplate provides customisation options for the Logstash + pods. + type: object + x-kubernetes-preserve-unknown-fields: true + revisionHistoryLimit: + description: RevisionHistoryLimit is the number of revisions to retain + to allow rollback in the underlying StatefulSet. + format: int32 + type: integer + secureSettings: + description: |- + SecureSettings is a list of references to Kubernetes Secrets containing sensitive configuration options for the Logstash. + Secrets data can be then referenced in the Logstash config using the Secret's keys or as specified in `Entries` field of + each SecureSetting. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + serviceAccountName: + description: |- + ServiceAccountName is used to check access from the current resource to Elasticsearch resource in a different namespace. + Can only be used if ECK is enforcing RBAC on references. + type: string + services: + description: |- + Services contains details of services that Logstash should expose - similar to the HTTP layer configuration for the + rest of the stack, but also applicable for more use cases than the metrics API, as logstash may need to + be opened up for other services: Beats, TCP, UDP, etc, inputs. + items: + properties: + name: + type: string + service: + description: Service defines the template for the associated + Kubernetes Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by + this service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic + is distributed to Service endpoints. Implementations can use this field + as a hint, but are not required to guarantee strict adherence. If the + field is not set, the implementation will apply its default routing + strategy. If set to "PreferClose", implementations should prioritize + endpoints that are in the same zone. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + type: array + updateStrategy: + description: UpdateStrategy is a StatefulSetUpdateStrategy. The default + type is "RollingUpdate". + properties: + rollingUpdate: + description: RollingUpdate is used to communicate parameters when + Type is RollingUpdateStatefulSetStrategyType. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding up. This can not be 0. + Defaults to 1. This field is alpha-level and is only honored by servers that enable the + MaxUnavailableStatefulSet feature. The field applies to all pods in the range 0 to + Replicas-1. That means if there is any unavailable pod in the range 0 to Replicas-1, it + will be counted towards MaxUnavailable. + x-kubernetes-int-or-string: true + partition: + description: |- + Partition indicates the ordinal at which the StatefulSet should be partitioned + for updates. During a rolling update, all pods from ordinal Replicas-1 to + Partition are updated. All pods from ordinal Partition-1 to 0 remain untouched. + This is helpful in being able to do a canary based deployment. The default value is 0. + format: int32 + type: integer + type: object + type: + description: |- + Type indicates the type of the StatefulSetUpdateStrategy. + Default is RollingUpdate. + type: string + type: object + version: + description: Version of the Logstash. + type: string + volumeClaimTemplates: + description: |- + VolumeClaimTemplates is a list of persistent volume claims to be used by each Pod. + Every claim in this list must have a matching volumeMount in one of the containers defined in the PodTemplate. + Items defined here take precedence over any default claims added by the operator with the same name. + items: + description: PersistentVolumeClaim is a user's request for and claim + to a persistent volume + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + spec defines the desired characteristics of a volume requested by a pod author. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes to consider + for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the + PersistentVolume backing this claim. + type: string + type: object + status: + description: |- + status represents the current information/status of a persistent volume claim. + Read-only. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the actual access modes the volume backing the PVC has. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + allocatedResourceStatuses: + additionalProperties: + description: |- + When a controller receives persistentvolume claim update with ClaimResourceStatus for a resource + that it does not recognizes, then it should ignore that update and let other controllers + handle it. + type: string + description: "allocatedResourceStatuses stores status of + resource being resized for the given PVC.\nKey names follow + standard Kubernetes label syntax. Valid values are either:\n\t* + Un-prefixed keys:\n\t\t- storage - the capacity of the + volume.\n\t* Custom resources must use implementation-defined + prefixed names such as \"example.com/my-custom-resource\"\nApart + from above values - keys that are unprefixed or have kubernetes.io + prefix are considered\nreserved and hence may not be used.\n\nClaimResourceStatus + can be in any of following states:\n\t- ControllerResizeInProgress:\n\t\tState + set when resize controller starts resizing the volume + in control-plane.\n\t- ControllerResizeFailed:\n\t\tState + set when resize has failed in resize controller with a + terminal error.\n\t- NodeResizePending:\n\t\tState set + when resize controller has finished resizing the volume + but further resizing of\n\t\tvolume is needed on the node.\n\t- + NodeResizeInProgress:\n\t\tState set when kubelet starts + resizing the volume.\n\t- NodeResizeFailed:\n\t\tState + set when resizing has failed in kubelet with a terminal + error. Transient errors don't set\n\t\tNodeResizeFailed.\nFor + example: if expanding a PVC for more capacity - this field + can be one of the following states:\n\t- pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeFailed\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizePending\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeFailed\"\nWhen this field is not set, it + means that no resize operation is in progress for the + given PVC.\n\nA controller that receives PVC update with + previously unknown resourceName or ClaimResourceStatus\nshould + ignore the update for the purpose it was designed. For + example - a controller that\nonly is responsible for resizing + capacity of the volume, should ignore PVC updates that + change other valid\nresources associated with PVC.\n\nThis + is an alpha field and requires enabling RecoverVolumeExpansionFailure + feature." + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: "allocatedResources tracks the resources allocated + to a PVC including its capacity.\nKey names follow standard + Kubernetes label syntax. Valid values are either:\n\t* + Un-prefixed keys:\n\t\t- storage - the capacity of the + volume.\n\t* Custom resources must use implementation-defined + prefixed names such as \"example.com/my-custom-resource\"\nApart + from above values - keys that are unprefixed or have kubernetes.io + prefix are considered\nreserved and hence may not be used.\n\nCapacity + reported here may be larger than the actual capacity when + a volume expansion operation\nis requested.\nFor storage + quota, the larger value from allocatedResources and PVC.spec.resources + is used.\nIf allocatedResources is not set, PVC.spec.resources + alone is used for quota calculation.\nIf a volume expansion + capacity request is lowered, allocatedResources is only\nlowered + if there are no expansion operations in progress and if + the actual volume capacity\nis equal or lower than the + requested capacity.\n\nA controller that receives PVC + update with previously unknown resourceName\nshould ignore + the update for the purpose it was designed. For example + - a controller that\nonly is responsible for resizing + capacity of the volume, should ignore PVC updates that + change other valid\nresources associated with PVC.\n\nThis + is an alpha field and requires enabling RecoverVolumeExpansionFailure + feature." + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: capacity represents the actual resources of + the underlying volume. + type: object + conditions: + description: |- + conditions is the current Condition of persistent volume claim. If underlying persistent volume is being + resized then the Condition will be set to 'Resizing'. + items: + description: PersistentVolumeClaimCondition contains details + about state of pvc + properties: + lastProbeTime: + description: lastProbeTime is the time we probed the + condition. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime is the time the condition + transitioned from one status to another. + format: date-time + type: string + message: + description: message is the human-readable message + indicating details about last transition. + type: string + reason: + description: |- + reason is a unique, this should be a short, machine understandable string that gives the reason + for condition's last transition. If it reports "Resizing" that means the underlying + persistent volume is being resized. + type: string + status: + description: |- + Status is the status of the condition. + Can be True, False, Unknown. + More info: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#:~:text=state%20of%20pvc-,conditions.status,-(string)%2C%20required + type: string + type: + description: |- + Type is the type of the condition. + More info: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#:~:text=set%20to%20%27ResizeStarted%27.-,PersistentVolumeClaimCondition,-contains%20details%20about + type: string + required: + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentVolumeAttributesClassName: + description: |- + currentVolumeAttributesClassName is the current name of the VolumeAttributesClass the PVC is using. + When unset, there is no VolumeAttributeClass applied to this PersistentVolumeClaim + This is a beta field and requires enabling VolumeAttributesClass feature (off by default). + type: string + modifyVolumeStatus: + description: |- + ModifyVolumeStatus represents the status object of ControllerModifyVolume operation. + When this is unset, there is no ModifyVolume operation being attempted. + This is a beta field and requires enabling VolumeAttributesClass feature (off by default). + properties: + status: + description: "status is the status of the ControllerModifyVolume + operation. It can be in any of following states:\n + - Pending\n Pending indicates that the PersistentVolumeClaim + cannot be modified due to unmet requirements, such + as\n the specified VolumeAttributesClass not existing.\n + - InProgress\n InProgress indicates that the volume + is being modified.\n - Infeasible\n Infeasible indicates + that the request has been rejected as invalid by the + CSI driver. To\n\t resolve the error, a valid VolumeAttributesClass + needs to be specified.\nNote: New statuses can be + added in the future. Consumers should check for unknown + statuses and fail appropriately." + type: string + targetVolumeAttributesClassName: + description: targetVolumeAttributesClassName is the + name of the VolumeAttributesClass the PVC currently + being reconciled + type: string + required: + - status + type: object + phase: + description: phase represents the current phase of PersistentVolumeClaim. + type: string + type: object + type: object + type: array + required: + - version + type: object + status: + description: LogstashStatus defines the observed state of Logstash + properties: + availableNodes: + format: int32 + type: integer + elasticsearchAssociationsStatus: + additionalProperties: + description: AssociationStatus is the status of an association resource. + type: string + description: ElasticsearchAssociationStatus is the status of any auto-linking + to Elasticsearch clusters. + type: object + expectedNodes: + format: int32 + type: integer + health: + type: string + monitoringAssociationStatus: + additionalProperties: + description: AssociationStatus is the status of an association resource. + type: string + description: MonitoringAssociationStatus is the status of any auto-linking + to monitoring Elasticsearch clusters. + type: object + observedGeneration: + description: |- + ObservedGeneration is the most recent generation observed for this Logstash instance. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + If the generation observed in status diverges from the generation in metadata, the Logstash + controller has not yet processed the changes contained in the Logstash specification. + format: int64 + type: integer + selector: + type: string + version: + description: |- + Version of the stack resource currently running. During version upgrades, multiple versions may run + in parallel: this value specifies the lowest version currently running. + type: string + required: + - selector + type: object + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.count + statusReplicasPath: .status.expectedNodes + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.18.0 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: stackconfigpolicies.stackconfigpolicy.k8s.elastic.co +spec: + group: stackconfigpolicy.k8s.elastic.co + names: + categories: + - elastic + kind: StackConfigPolicy + listKind: StackConfigPolicyList + plural: stackconfigpolicies + shortNames: + - scp + singular: stackconfigpolicy + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Resources configured + jsonPath: .status.readyCount + name: Ready + type: string + - jsonPath: .status.phase + name: Phase + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: StackConfigPolicy represents a StackConfigPolicy resource in + a Kubernetes cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + properties: + elasticsearch: + properties: + clusterSettings: + description: ClusterSettings holds the Elasticsearch cluster settings + (/_cluster/settings) + type: object + x-kubernetes-preserve-unknown-fields: true + config: + description: Config holds the settings that go into elasticsearch.yml. + type: object + x-kubernetes-preserve-unknown-fields: true + indexLifecyclePolicies: + description: IndexLifecyclePolicies holds the Index Lifecycle + policies settings (/_ilm/policy) + type: object + x-kubernetes-preserve-unknown-fields: true + indexTemplates: + description: IndexTemplates holds the Index and Component Templates + settings + properties: + componentTemplates: + description: ComponentTemplates holds the Component Templates + settings (/_component_template) + type: object + x-kubernetes-preserve-unknown-fields: true + composableIndexTemplates: + description: ComposableIndexTemplates holds the Index Templates + settings (/_index_template) + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + x-kubernetes-preserve-unknown-fields: true + ingestPipelines: + description: IngestPipelines holds the Ingest Pipelines settings + (/_ingest/pipeline) + type: object + x-kubernetes-preserve-unknown-fields: true + secretMounts: + description: SecretMounts are additional Secrets that need to + be mounted into the Elasticsearch pods. + items: + description: SecretMount contains information about additional + secrets to be mounted to the elasticsearch pods + properties: + mountPath: + description: MountPath denotes the path to which the secret + should be mounted to inside the elasticsearch pod + type: string + secretName: + description: SecretName denotes the name of the secret that + needs to be mounted to the elasticsearch pod + type: string + type: object + type: array + x-kubernetes-preserve-unknown-fields: true + secureSettings: + description: SecureSettings are additional Secrets that contain + data to be configured to Elasticsearch's keystore. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + x-kubernetes-preserve-unknown-fields: true + securityRoleMappings: + description: SecurityRoleMappings holds the Role Mappings settings + (/_security/role_mapping) + type: object + x-kubernetes-preserve-unknown-fields: true + snapshotLifecyclePolicies: + description: SnapshotLifecyclePolicies holds the Snapshot Lifecycle + Policies settings (/_slm/policy) + type: object + x-kubernetes-preserve-unknown-fields: true + snapshotRepositories: + description: SnapshotRepositories holds the Snapshot Repositories + settings (/_snapshot) + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + kibana: + properties: + config: + description: Config holds the settings that go into kibana.yml. + type: object + x-kubernetes-preserve-unknown-fields: true + secureSettings: + description: SecureSettings are additional Secrets that contain + data to be configured to Kibana's keystore. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + x-kubernetes-preserve-unknown-fields: true + type: object + resourceSelector: + description: |- + A label selector is a label query over a set of resources. The result of matchLabels and + matchExpressions are ANDed. An empty label selector matches all objects. A null + label selector matches no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + secureSettings: + description: 'Deprecated: SecureSettings only applies to Elasticsearch + and is deprecated. It must be set per application instead.' + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + type: object + status: + properties: + details: + additionalProperties: + additionalProperties: + description: ResourcePolicyStatus models the status of the policy + for one resource to be configured. + properties: + currentVersion: + description: |- + CurrentVersion denotes the current version of filesettings applied to the Elasticsearch cluster + This field does not apply to Kibana resources + format: int64 + type: integer + error: + properties: + message: + type: string + version: + format: int64 + type: integer + type: object + expectedVersion: + description: |- + ExpectedVersion denotes the expected version of filesettings that should be applied to the Elasticsearch cluster + This field does not apply to Kibana resources + format: int64 + type: integer + phase: + type: string + type: object + type: object + description: Details holds the status details for each resource to + be configured. + type: object + errors: + description: Errors is the number of resources which have an incorrect + configuration + type: integer + observedGeneration: + description: ObservedGeneration is the most recent generation observed + for this StackConfigPolicy. + format: int64 + type: integer + phase: + description: Phase is the phase of the StackConfigPolicy. + type: string + ready: + description: Ready is the number of resources successfully configured. + type: integer + readyCount: + description: ReadyCount is a human representation of the number of + resources successfully configured. + type: string + resources: + description: Resources is the number of resources to be configured. + type: integer + resourcesStatuses: + additionalProperties: + description: ResourcePolicyStatus models the status of the policy + for one resource to be configured. + properties: + currentVersion: + description: |- + CurrentVersion denotes the current version of filesettings applied to the Elasticsearch cluster + This field does not apply to Kibana resources + format: int64 + type: integer + error: + properties: + message: + type: string + version: + format: int64 + type: integer + type: object + expectedVersion: + description: |- + ExpectedVersion denotes the expected version of filesettings that should be applied to the Elasticsearch cluster + This field does not apply to Kibana resources + format: int64 + type: integer + phase: + type: string + type: object + description: |- + ResourcesStatuses holds the status for each resource to be configured. + Deprecated: Details is used to store the status of resources from ECK 2.11 + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/values.yaml b/packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/values.yaml new file mode 100644 index 00000000..f3fd8bd5 --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/charts/eck-operator-crds/values.yaml @@ -0,0 +1,7 @@ +# Globals meant for internal use only +global: + # manifestGen specifies whether the chart is running under manifest generator. + # This is used for tasks specific to generating the all-in-one.yaml file. + manifestGen: false + # kubeVersion is the effective Kubernetes version we target when generating the all-in-one.yaml. + kubeVersion: 1.21.0 diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/profile-disable-automounting-api.yaml b/packs/elastic-operator-3.1.0/charts/eck-operator/profile-disable-automounting-api.yaml new file mode 100644 index 00000000..50f97157 --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/profile-disable-automounting-api.yaml @@ -0,0 +1,29 @@ +automountServiceAccountToken: false + +serviceAccount: + automountServiceAccountToken: false + +volumeMounts: +- mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: serviceaccount-token + readOnly: true + +volumes: +- name: serviceaccount-token + projected: + defaultMode: 0444 + sources: + - serviceAccountToken: + expirationSeconds: 3607 + path: token + - configMap: + name: kube-root-ca.crt + items: + - key: ca.crt + path: ca.crt + - downwardAPI: + items: + - path: namespace + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/profile-global.yaml b/packs/elastic-operator-3.1.0/charts/eck-operator/profile-global.yaml new file mode 100644 index 00000000..286f8c9e --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/profile-global.yaml @@ -0,0 +1,6 @@ +managedNamespaces: [] + +createClusterScopedResources: true + +webhook: + enabled: true diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/profile-istio.yaml b/packs/elastic-operator-3.1.0/charts/eck-operator/profile-istio.yaml new file mode 100644 index 00000000..c968ba02 --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/profile-istio.yaml @@ -0,0 +1,11 @@ +managedNamespaces: [] + +createClusterScopedResources: true + +webhook: + enabled: true + +podAnnotations: + sidecar.istio.io/inject: "true" + traffic.sidecar.istio.io/includeInboundPorts: "*" + traffic.sidecar.istio.io/excludeInboundPorts: "9443" diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/profile-restricted.yaml b/packs/elastic-operator-3.1.0/charts/eck-operator/profile-restricted.yaml new file mode 100644 index 00000000..640d00f3 --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/profile-restricted.yaml @@ -0,0 +1,12 @@ +managedNamespaces: ["elastic-system"] + +createClusterScopedResources: false + +config: + # no RBAC access to cluster-wide storage classes, hence disable storage class validation + validateStorageClass: false + +installCRDs: false + +webhook: + enabled: false diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/profile-soft-multi-tenancy.yaml b/packs/elastic-operator-3.1.0/charts/eck-operator/profile-soft-multi-tenancy.yaml new file mode 100644 index 00000000..8ac79514 --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/profile-soft-multi-tenancy.yaml @@ -0,0 +1,18 @@ +managedNamespaces: ["team-a", "team-b"] + +createClusterScopedResources: true + +refs: + enforceRBAC: true + +webhook: + enabled: true + namespaceSelector: + matchExpressions: + - key: "eck.k8s.elastic.co/tenant" + operator: In + values: ["team-a", "team-b"] + + +softMultiTenancy: + enabled: true diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/templates/NOTES.txt b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/NOTES.txt new file mode 100644 index 00000000..e25ea9ea --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/NOTES.txt @@ -0,0 +1,2 @@ +1. Inspect the operator logs by running the following command: + kubectl logs -n {{ .Release.Namespace }} sts/{{ .Release.Name }} diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/templates/_helpers.tpl b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/_helpers.tpl new file mode 100644 index 00000000..dc2f7cb3 --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/_helpers.tpl @@ -0,0 +1,381 @@ +{{/* +Expand the name of the chart. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "eck-operator.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "eck-operator.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "eck-operator.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "eck-operator.labels" -}} +{{- include "eck-operator.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +helm.sh/chart: {{ include "eck-operator.chart" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "eck-operator.selectorLabels" -}} +{{- if .Values.global.manifestGen -}} +control-plane: elastic-operator +{{- else -}} +app.kubernetes.io/name: {{ include "eck-operator.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "eck-operator.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "eck-operator.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Determine effective Kubernetes version +*/}} +{{- define "eck-operator.effectiveKubeVersion" -}} +{{- if .Values.global.manifestGen -}} +{{- semver .Values.global.kubeVersion -}} +{{- else -}} +{{- .Capabilities.KubeVersion.Version -}} +{{- end -}} +{{- end -}} + +{{/* +Determine the name for the webhook +*/}} +{{- define "eck-operator.webhookName" -}} +{{- if .Values.global.manifestGen -}} +elastic-webhook.k8s.elastic.co +{{- else -}} +{{- $name := include "eck-operator.name" . -}} +{{ printf "%s.%s.k8s.elastic.co" $name .Release.Namespace }} +{{- end -}} +{{- end -}} + +{{/* +Determine the name for the webhook secret +*/}} +{{- define "eck-operator.webhookSecretName" -}} +{{- if .Values.global.manifestGen -}} +elastic-webhook-server-cert +{{- else if .Values.webhook.certsSecret -}} +{{- .Values.webhook.certsSecret }} +{{- else -}} +{{- $name := include "eck-operator.name" . -}} +{{ printf "%s-webhook-cert" $name | trunc 63 }} +{{- end -}} +{{- end -}} + +{{/* +Determine the name for the webhook service +*/}} +{{- define "eck-operator.webhookServiceName" -}} +{{- if .Values.global.manifestGen -}} +elastic-webhook-server +{{- else -}} +{{- $name := include "eck-operator.name" . -}} +{{ printf "%s-webhook" $name | trunc 63 }} +{{- end -}} +{{- end -}} + +{{/* +Determine the metrics port +*/}} +{{- define "eck-operator.metrics.port" -}} +{{- if .Values.config.metrics.port -}} +{{- .Values.config.metrics.port -}} +{{- else if .Values.config.metricsPort -}} +{{- .Values.config.metricsPort -}} +{{- else -}} +0 +{{- end -}} +{{- end -}} + +{{/* +RBAC permissions +NOTE - any changes made to RBAC permissions below require +updating docs/operating-eck/eck-permissions.asciidoc file. +*/}} +{{- define "eck-operator.rbacRules" -}} +- apiGroups: + - "authorization.k8s.io" + resources: + - subjectaccessreviews + verbs: + - create +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create +- apiGroups: + - coordination.k8s.io + resources: + - leases + resourceNames: + - elastic-operator-leader + verbs: + - get + - watch + - update +- apiGroups: + - "" + resources: + - endpoints + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - pods + - events + - persistentvolumeclaims + - secrets + - services + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - apps + resources: + - deployments + - statefulsets + - daemonsets + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - elasticsearch.k8s.elastic.co + resources: + - elasticsearches + - elasticsearches/status + - elasticsearches/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - autoscaling.k8s.elastic.co + resources: + - elasticsearchautoscalers + - elasticsearchautoscalers/status + - elasticsearchautoscalers/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - kibana.k8s.elastic.co + resources: + - kibanas + - kibanas/status + - kibanas/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - apm.k8s.elastic.co + resources: + - apmservers + - apmservers/status + - apmservers/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - enterprisesearch.k8s.elastic.co + resources: + - enterprisesearches + - enterprisesearches/status + - enterprisesearches/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - beat.k8s.elastic.co + resources: + - beats + - beats/status + - beats/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - agent.k8s.elastic.co + resources: + - agents + - agents/status + - agents/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - maps.k8s.elastic.co + resources: + - elasticmapsservers + - elasticmapsservers/status + - elasticmapsservers/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - stackconfigpolicy.k8s.elastic.co + resources: + - stackconfigpolicies + - stackconfigpolicies/status + - stackconfigpolicies/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - logstash.k8s.elastic.co + resources: + - logstashes + - logstashes/status + - logstashes/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +{{- end -}} + +{{/* +RBAC permissions on non-namespaced resources +*/}} +{{- define "eck-operator.clusterWideRbacRules" -}} +- apiGroups: + - storage.k8s.io + resources: + - storageclasses + verbs: + - get + - list + - watch +- apiGroups: + - admissionregistration.k8s.io + resources: + - validatingwebhookconfigurations + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +{{- end -}} + +{{/* +RBAC permissions to read node labels +*/}} +{{- define "eck-operator.readNodeLabelsRbacRule" -}} +- apiGroups: + - "" + resources: + - nodes + verbs: + - get + - list + - watch +{{- end -}} diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/templates/cluster-roles.yaml b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/cluster-roles.yaml new file mode 100644 index 00000000..dbd0fba3 --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/cluster-roles.yaml @@ -0,0 +1,121 @@ +{{- if and (not .Values.createClusterScopedResources) (.Values.config.metrics.secureMode.enabled) -}} +{{ fail "createClusterScopedResources is required to set config.metrics.secureMode.enabled to true" }} +{{- end }} +{{- if .Values.createClusterScopedResources -}} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "eck-operator.fullname" . }} + labels: + {{- include "eck-operator.labels" . | nindent 4 }} +rules: +{{ template "eck-operator.rbacRules" . | toYaml | indent 2 }} +{{ template "eck-operator.clusterWideRbacRules" . | toYaml | indent 2 }} +{{ if .Values.config.exposedNodeLabels }} +{{ template "eck-operator.readNodeLabelsRbacRule" . | toYaml | indent 2 }} +{{ end -}} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: "{{ include "eck-operator.name" . }}-view" + labels: + rbac.authorization.k8s.io/aggregate-to-view: "true" + rbac.authorization.k8s.io/aggregate-to-edit: "true" + rbac.authorization.k8s.io/aggregate-to-admin: "true" + {{- include "eck-operator.labels" . | nindent 4 }} +rules: + - apiGroups: ["elasticsearch.k8s.elastic.co"] + resources: ["elasticsearches"] + verbs: ["get", "list", "watch"] + - apiGroups: ["autoscaling.k8s.elastic.co"] + resources: ["elasticsearchautoscalers"] + verbs: ["get", "list", "watch"] + - apiGroups: ["apm.k8s.elastic.co"] + resources: ["apmservers"] + verbs: ["get", "list", "watch"] + - apiGroups: ["kibana.k8s.elastic.co"] + resources: ["kibanas"] + verbs: ["get", "list", "watch"] + - apiGroups: ["enterprisesearch.k8s.elastic.co"] + resources: ["enterprisesearches"] + verbs: ["get", "list", "watch"] + - apiGroups: ["beat.k8s.elastic.co"] + resources: ["beats"] + verbs: ["get", "list", "watch"] + - apiGroups: ["agent.k8s.elastic.co"] + resources: ["agents"] + verbs: ["get", "list", "watch"] + - apiGroups: ["maps.k8s.elastic.co"] + resources: ["elasticmapsservers"] + verbs: ["get", "list", "watch"] + - apiGroups: ["stackconfigpolicy.k8s.elastic.co"] + resources: ["stackconfigpolicies"] + verbs: ["get", "list", "watch"] + - apiGroups: ["logstash.k8s.elastic.co"] + resources: ["logstashes"] + verbs: ["get", "list", "watch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: "{{ include "eck-operator.name" . }}-edit" + labels: + rbac.authorization.k8s.io/aggregate-to-edit: "true" + rbac.authorization.k8s.io/aggregate-to-admin: "true" + {{- include "eck-operator.labels" . | nindent 4 }} +rules: + - apiGroups: ["elasticsearch.k8s.elastic.co"] + resources: ["elasticsearches"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["autoscaling.k8s.elastic.co"] + resources: ["elasticsearchautoscalers"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["apm.k8s.elastic.co"] + resources: ["apmservers"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["kibana.k8s.elastic.co"] + resources: ["kibanas"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["enterprisesearch.k8s.elastic.co"] + resources: ["enterprisesearches"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["beat.k8s.elastic.co"] + resources: ["beats"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["agent.k8s.elastic.co"] + resources: ["agents"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["maps.k8s.elastic.co"] + resources: ["elasticmapsservers"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["stackconfigpolicy.k8s.elastic.co"] + resources: ["stackconfigpolicies"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["logstash.k8s.elastic.co"] + resources: ["logstashes"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] +{{- if .Values.config.metrics.secureMode.enabled }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "eck-operator.labels" . | nindent 4 }} + name: "{{ include "eck-operator.fullname" . }}-metrics-auth-role" +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +{{- end }} +{{- end -}} diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/templates/configmap.yaml b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/configmap.yaml new file mode 100644 index 00000000..01708b52 --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/configmap.yaml @@ -0,0 +1,81 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "eck-operator.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "eck-operator.labels" . | nindent 4 }} +data: + eck.yaml: |- + {{- $metricsPort := int (include "eck-operator.metrics.port" .)}} + log-verbosity: {{ int .Values.config.logVerbosity }} + {{- if and .Values.config.metrics.secureMode.enabled (eq $metricsPort 0) }} + {{- fail "config.metrics.port must be greater than 0 when config.metrics.secureMode.enabled is true" }} + {{- end }} + metrics-port: {{ $metricsPort }} + metrics-secure: {{ .Values.config.metrics.secureMode.enabled }} + container-registry: {{ .Values.config.containerRegistry }} + {{- with .Values.config.containerSuffix }} + container-suffix: {{ . }} + {{- end }} + {{- with .Values.config.containerRepository }} + container-repository: {{ . }} + {{- end }} + max-concurrent-reconciles: {{ int .Values.config.maxConcurrentReconciles }} + {{- with .Values.config.passwordHashCacheSize }} + password-hash-cache-size: {{ int . }} + {{- end }} + ca-cert-validity: {{ .Values.config.caValidity }} + ca-cert-rotate-before: {{ .Values.config.caRotateBefore }} + {{- with .Values.config.caDir }} + ca-dir: {{ . }} + {{- end }} + cert-validity: {{ .Values.config.certificatesValidity }} + cert-rotate-before: {{ .Values.config.certificatesRotateBefore }} + disable-config-watch: {{ .Values.config.disableConfigWatch }} + {{- with .Values.config.exposedNodeLabels }} + exposed-node-labels: [{{ join "," . }}] + {{- end }} + {{- with .Values.config.ipFamily }} + ip-family: {{ . }} + {{- end }} + set-default-security-context: {{ .Values.config.setDefaultSecurityContext }} + kube-client-timeout: {{ .Values.config.kubeClientTimeout }} + {{- with .Values.config.kubeClientQPS }} + kube-client-qps: {{ int . }} + {{- end }} + elasticsearch-client-timeout: {{ .Values.config.elasticsearchClientTimeout }} + disable-telemetry: {{ .Values.telemetry.disabled }} + distribution-channel: {{ .Values.telemetry.distributionChannel }} + {{- with .Values.telemetry.interval }} + telemetry-interval: {{ . }} + {{- end }} + validate-storage-class: {{ .Values.config.validateStorageClass }} + {{- if .Values.tracing.enabled }} + enable-tracing: true + {{- end }} + {{- if .Values.refs.enforceRBAC }} + enforce-rbac-on-refs: true + {{- end }} + enable-webhook: {{ .Values.webhook.enabled }} + {{- if .Values.webhook.enabled }} + webhook-name: {{ include "eck-operator.webhookName" . }} + {{- if not .Values.webhook.manageCerts }} + manage-webhook-certs: false + webhook-cert-dir: {{ .Values.webhook.certsDir }} + {{- end }} + webhook-port: {{ .Values.webhook.port }} + {{- end }} + {{- with .Values.managedNamespaces }} + namespaces: [{{ join "," . }}] + {{- end }} + operator-namespace: {{ .Release.Namespace }} + enable-leader-election: {{ .Values.config.enableLeaderElection }} + elasticsearch-observation-interval: {{ .Values.config.elasticsearchObservationInterval }} + {{- if not .Values.config.containerSuffix }} + ubi-only: {{ .Values.config.ubiOnly }} + {{- end }} + {{- with .Values.webhook.certsSecret }} + webhook-secret: {{ . }} + {{- end }} diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/templates/managed-namespaces.yaml b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/managed-namespaces.yaml new file mode 100644 index 00000000..91deaf21 --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/managed-namespaces.yaml @@ -0,0 +1,13 @@ +{{- if .Values.softMultiTenancy.enabled -}} +{{- range .Values.managedNamespaces }} +{{- $namespace := . }} +--- +apiVersion: v1 +kind: Namespace +metadata: + name: {{ $namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} + eck.k8s.elastic.co/tenant: {{ $namespace }} +{{- end -}} +{{- end -}} diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/templates/managed-ns-network-policy.yaml b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/managed-ns-network-policy.yaml new file mode 100644 index 00000000..23fc1e3a --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/managed-ns-network-policy.yaml @@ -0,0 +1,228 @@ +{{- if .Values.softMultiTenancy.enabled -}} +{{- $fullName := include "eck-operator.fullname" . -}} +{{- $name := include "eck-operator.name" . -}} +{{- range .Values.managedNamespaces -}} +{{- $namespace := . }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: "{{ $name }}-elasticsearch" + namespace: {{ $namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +spec: + podSelector: + matchLabels: + common.k8s.elastic.co/type: "elasticsearch" + egress: + # Transport port + - ports: + - port: 9300 + to: + # Elasticsearch within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} + podSelector: + matchLabels: + common.k8s.elastic.co/type: "elasticsearch" + # DNS + - ports: + - port: 53 + protocol: UDP + to: [] + ingress: + # HTTP Port + - ports: + - port: 9200 + from: + # Operator + - namespaceSelector: + matchLabels: + name: "{{ $.Release.Namespace }}" + podSelector: + matchLabels: + {{- include "eck-operator.selectorLabels" $ | nindent 14 }} + # Within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} + # Transport port + - ports: + - port: 9300 + from: + # Within namespace (from other Elasticsearch nodes) + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} + podSelector: + matchLabels: + common.k8s.elastic.co/type: "elasticsearch" +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: "{{ $name }}-kibana" + namespace: {{ $namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +spec: + podSelector: + matchLabels: + common.k8s.elastic.co/type: "kibana" + egress: + # Elasticsearch HTTP port + - ports: + - port: 9200 + to: + # Elasticsearch within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} + podSelector: + matchLabels: + common.k8s.elastic.co/type: "elasticsearch" + # DNS + - ports: + - port: 53 + protocol: UDP + to: [] + ingress: + # HTTP Port + - ports: + - port: 5601 + from: + # Within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: "{{ $name }}-apm-server" + namespace: {{ $namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +spec: + podSelector: + matchLabels: + common.k8s.elastic.co/type: "apm-server" + egress: + # Elasticsearch HTTP port + - ports: + - port: 9200 + to: + # Elasticsearch within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} + podSelector: + matchLabels: + common.k8s.elastic.co/type: "elasticsearch" + # Kibana HTTP port + - ports: + - port: 5601 + to: + # Kibana within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} + podSelector: + matchLabels: + common.k8s.elastic.co/type: "kibana" + # DNS + - ports: + - port: 53 + protocol: UDP + to: [] + ingress: + # HTTP Port + - ports: + - port: 8200 + from: + # Within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: "{{ $name }}-enterprise-search" + namespace: {{ $namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +spec: + podSelector: + matchLabels: + common.k8s.elastic.co/type: "enterprise-search" + egress: + # Elasticsearch HTTP port + - ports: + - port: 9200 + to: + # Elasticsearch within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} + podSelector: + matchLabels: + common.k8s.elastic.co/type: "elasticsearch" + # DNS + - ports: + - port: 53 + protocol: UDP + to: [] + ingress: + # HTTP Port + - ports: + - port: 3002 + from: + # Within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: "{{ $name }}-beats" + namespace: {{ $namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +spec: + podSelector: + matchLabels: + common.k8s.elastic.co/type: "beat" + egress: + # Elasticsearch HTTP port + - ports: + - port: 9200 + to: + # Elasticsearch within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} + podSelector: + matchLabels: + common.k8s.elastic.co/type: "elasticsearch" + # Kibana HTTP port + - ports: + - port: 5601 + to: + # Kibana within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} + podSelector: + matchLabels: + common.k8s.elastic.co/type: "kibana" + # DNS + - ports: + - port: 53 + protocol: UDP + to: [] +{{- end }} +{{- end -}} diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/templates/metrics-service.yaml b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/metrics-service.yaml new file mode 100644 index 00000000..53bdc02b --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/metrics-service.yaml @@ -0,0 +1,22 @@ +{{- if .Values.config.metrics.secureMode.enabled }} +{{- $metricsPort := int (include "eck-operator.metrics.port" .)}} +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: {{ include "eck-operator.name" . }}-metrics-service + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} + helm.sh/chart: {{ include "eck-operator.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + name: "{{ include "eck-operator.fullname" . }}-metrics" + namespace: {{ .Release.Namespace }} +spec: + ports: + - name: https + port: {{ $metricsPort }} + protocol: TCP + targetPort: metrics + selector: + {{- include "eck-operator.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/templates/operator-namespace.yaml b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/operator-namespace.yaml new file mode 100644 index 00000000..07123b70 --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/operator-namespace.yaml @@ -0,0 +1,9 @@ +{{- if (and .Values.global.manifestGen .Values.global.createOperatorNamespace) -}} +--- +apiVersion: v1 +kind: Namespace +metadata: + name: {{ .Release.Namespace }} + labels: + name: {{ .Release.Namespace }} +{{- end -}} diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/templates/operator-network-policy.yaml b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/operator-network-policy.yaml new file mode 100644 index 00000000..ad74156d --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/operator-network-policy.yaml @@ -0,0 +1,59 @@ +{{- if .Values.softMultiTenancy.enabled -}} +{{- $kubeAPIServerIP := (required "kubeAPIServerIP is required" .Values.kubeAPIServerIP) -}} +{{- $metricsPort := int (include "eck-operator.metrics.port" .)}} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "eck-operator.fullname" . }} + namespace: {{ .Release.Namespace}} + labels: + {{- include "eck-operator.labels" . | nindent 4 }} +spec: + podSelector: + matchLabels: + {{- include "eck-operator.selectorLabels" . | nindent 6 }} + egress: + # DNS + - ports: + - port: 53 + protocol: UDP + to: [] + # API server + - ports: + - port: 443 + to: + - ipBlock: + cidr: "{{ $kubeAPIServerIP }}/32" + # Elasticsearch + - ports: + - port: 9200 + to: + - namespaceSelector: + matchExpressions: + - key: "eck.k8s.elastic.co/tenant" + operator: In + values: + {{- range .Values.managedNamespaces }} + - {{ . }} + {{- end }} + podSelector: + matchLabels: + common.k8s.elastic.co/type: "elasticsearch" +{{- if or .Values.webhook.enabled (gt $metricsPort 0) }} + ingress: +{{- if .Values.webhook.enabled }} + - ports: + - port: {{ .Values.webhook.port }} + from: + - ipBlock: + cidr: "{{ $kubeAPIServerIP }}/32" +{{- end }} +{{- if gt $metricsPort 0 }} + # Metrics + - ports: + - port: {{ $metricsPort }} + from: [] +{{- end }} +{{- end }} +{{- end -}} diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/templates/pdb.yaml b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/pdb.yaml new file mode 100644 index 00000000..42b494a3 --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/pdb.yaml @@ -0,0 +1,19 @@ +{{- if .Values.podDisruptionBudget.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "eck-operator.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "eck-operator.labels" . | nindent 4 }} +spec: + {{- with .Values.podDisruptionBudget.minAvailable }} + minAvailable: {{ . }} + {{- end }} + {{- with .Values.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} + selector: + matchLabels: + {{- include "eck-operator.selectorLabels" . | nindent 6 }} +{{- end -}} diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/templates/podMonitor.yaml b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/podMonitor.yaml new file mode 100644 index 00000000..8e073cd3 --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/podMonitor.yaml @@ -0,0 +1,42 @@ +{{- $metricsPort := int (include "eck-operator.metrics.port" .)}} +{{- if and .Values.config.metrics.secureMode.enabled (eq $metricsPort 0) }} +{{- fail "config.metrics.port must be greater than 0 when config.metrics.secureMode.enabled is true" }} +{{- end }} +{{- if and .Values.podMonitor.enabled (gt $metricsPort 0) }} +{{- if and .Values.podMonitor.enabled .Values.config.metrics.secureMode.enabled }} +{{- fail "podMonitor and config.metrics.secureMode are mutually exclusive" }} +{{- end }} +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: {{ include "eck-operator.fullname" . }} + namespace: {{ ternary .Values.podMonitor.namespace .Release.Namespace (not (and (.Values.podMonitor) (empty .Values.podMonitor.namespace))) }} + labels: {{- include "eck-operator.labels" . | nindent 4 }} + {{- with .Values.podMonitor.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.podMonitor.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .Values.podMonitor.podTargetLabels }} + podTargetLabels: {{- toYaml . | nindent 4 }} + {{- end }} + podMetricsEndpoints: + - port: metrics + path: /metrics + {{- with .Values.podMonitor.interval }} + interval: {{ . }} + {{- end }} + {{- with .Values.podMonitor.scrapeTimeout }} + scrapeTimeout: {{ . }} + {{- end }} + {{- with .Values.podMonitor.podMetricsEndpointConfig }} + {{- toYaml . | nindent 6 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: {{- include "eck-operator.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/templates/role-bindings.yaml b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/role-bindings.yaml new file mode 100644 index 00000000..0db9f278 --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/role-bindings.yaml @@ -0,0 +1,98 @@ +{{- $operatorNSIsManaged := has .Release.Namespace .Values.managedNamespaces -}} +{{- $fullName := include "eck-operator.fullname" . -}} +{{- $svcAccount := include "eck-operator.serviceAccountName" . }} +{{- $enableSecureMetrics := .Values.config.metrics.secureMode.enabled -}} + +{{- if not .Values.createClusterScopedResources }} +{{- range .Values.managedNamespaces }} +{{- $namespace := . }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: "{{ $fullName }}" + namespace: {{ $namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +rules: +{{ template "eck-operator.rbacRules" $ | toYaml | indent 2 }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: "{{ $fullName }}" + namespace: {{ $namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: "{{ $fullName }}" +subjects: +- kind: ServiceAccount + name: {{ $svcAccount }} + namespace: {{ $.Release.Namespace }} +{{- end }} {{- /* end of range over managed namespaces */}} +{{- /* If createClusterScopedResources is false and operator namespace is not in the managed namespaces list, create additional role binding */}} +{{- if not $operatorNSIsManaged }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ $fullName }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +rules: +{{ template "eck-operator.rbacRules" $ | toYaml | indent 2 }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: "{{ $fullName }}" + namespace: {{ $.Release.Namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: "{{ $fullName }}" +subjects: +- kind: ServiceAccount + name: {{ $svcAccount }} + namespace: {{ $.Release.Namespace }} +{{- end }} {{- /* end of operator role binding if operator namespace is not managed */}} +{{- else }} {{- /* we can create cluster-scoped resources so just create a cluster role binding */}} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ $fullName }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ $fullName }} +subjects: +- kind: ServiceAccount + name: {{ $svcAccount }} + namespace: {{ $.Release.Namespace }} +{{- if $enableSecureMetrics }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} + name: "{{ include "eck-operator.fullname" . }}-metrics-auth-rolebinding" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: "{{ include "eck-operator.fullname" . }}-metrics-auth-role" +subjects: +- kind: ServiceAccount + name: {{ $svcAccount }} + namespace: {{ $.Release.Namespace }} +{{- end }} +{{- end }} diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/templates/service-account.yaml b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/service-account.yaml new file mode 100644 index 00000000..f91acdcc --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/service-account.yaml @@ -0,0 +1,15 @@ +{{- if .Values.serviceAccount.create }} +--- +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ include "eck-operator.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "eck-operator.labels" . | nindent 4 }} +{{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- end }} diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/templates/service-monitor.yaml b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/service-monitor.yaml new file mode 100644 index 00000000..0d4a3d9c --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/service-monitor.yaml @@ -0,0 +1,34 @@ +{{- if and .Values.config.metrics.secureMode.enabled .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "eck-operator.fullname" . }} + namespace: {{ ternary .Values.serviceMonitor.namespace .Release.Namespace (not (and (.Values.serviceMonitor) (empty .Values.serviceMonitor.namespace))) }} + labels: {{- include "eck-operator.labels" . | nindent 4 }} +spec: + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "eck-operator.name" . }}-metrics-service + app.kubernetes.io/instance: {{ .Release.Name }} + endpoints: + - port: https + path: /metrics + scheme: https + interval: 30s + tlsConfig: + {{- $insecureSkipVerify := (ternary .Values.config.metrics.secureMode.tls.insecureSkipVerify .Values.serviceMonitor.insecureSkipVerify (hasKey .Values.config.metrics.secureMode.tls "insecureSkipVerify")) }} + insecureSkipVerify: {{ $insecureSkipVerify }} + {{- if (not $insecureSkipVerify) }} + {{- $caMountDirectory := or (.Values.config.metrics.secureMode.tls.caMountDirectory) (.Values.serviceMonitor.caMountDirectory) -}} + {{- $leading_path := trimSuffix "/" $caMountDirectory }} + {{- $caSecret := or (.Values.config.metrics.secureMode.tls.caSecret) (.Values.serviceMonitor.caSecret) -}} + {{- with $caSecret }} + caFile: "{{ $leading_path }}/{{ . }}/ca.crt" + {{- end }} + serverName: "{{ include "eck-operator.fullname" . }}-metrics.{{ .Release.Namespace }}.svc" + {{- end }} + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token +{{- end }} diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/templates/statefulset.yaml b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/statefulset.yaml new file mode 100644 index 00000000..c607d8a3 --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/statefulset.yaml @@ -0,0 +1,162 @@ +--- +{{- $metricsPort := int (include "eck-operator.metrics.port" .)}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "eck-operator.fullname" . }} + namespace: {{ .Release.Namespace }} + {{- with .Values.statefulsetAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "eck-operator.labels" . | nindent 4 }} + {{- with .Values.statefulsetLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "eck-operator.selectorLabels" . | nindent 6 }} + serviceName: {{ include "eck-operator.fullname" . }} + replicas: {{ .Values.replicaCount }} + template: + metadata: + annotations: + # Rename the fields "error" to "error.message" and "source" to "event.source" + # This is to avoid a conflict with the ECS "error" and "source" documents. + "co.elastic.logs/raw": "[{\"type\":\"filestream\",\"enabled\":true,\"id\":\"eck-container-logs-${data.kubernetes.container.id}\",\"paths\":[\"/var/log/containers/*${data.kubernetes.container.id}.log\"],\"parsers\":[{\"container\":{}},{\"ndjson\":{\"keys_under_root\":true}}],\"prospector.scanner.symlinks\":true,\"processors\":[{\"convert\":{\"mode\":\"rename\",\"ignore_missing\":true,\"fields\":[{\"from\":\"error\",\"to\":\"_error\"}]}},{\"convert\":{\"mode\":\"rename\",\"ignore_missing\":true,\"fields\":[{\"from\":\"_error\",\"to\":\"error.message\"}]}},{\"convert\":{\"mode\":\"rename\",\"ignore_missing\":true,\"fields\":[{\"from\":\"source\",\"to\":\"_source\"}]}},{\"convert\":{\"mode\":\"rename\",\"ignore_missing\":true,\"fields\":[{\"from\":\"_source\",\"to\":\"event.source\"}]}}]}]" + "checksum/config": {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "eck-operator.selectorLabels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + terminationGracePeriodSeconds: 10 + serviceAccountName: {{ include "eck-operator.serviceAccountName" . }} + automountServiceAccountToken: {{ .Values.automountServiceAccountToken }} + {{- with .Values.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + {{- with .Values.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - image: "{{ .Values.image.repository }}{{- if .Values.config.ubiOnly -}}-ubi{{- end -}}{{- if .Values.image.fips -}}-fips{{- end -}}:{{ default .Chart.AppVersion .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + name: manager + args: + - "manager" + - "--config=/conf/eck.yaml" + {{- with .Values.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + env: + - name: OPERATOR_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + {{- if .Values.webhook.enabled }} + - name: WEBHOOK_SECRET + value: {{ include "eck-operator.webhookSecretName" . }} + {{- end }} + {{- with .Values.env }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.tracing.enabled -}} + {{- range $name, $value := .Values.tracing.config }} + - name: {{ $name }} + value: {{ $value }} + {{- end }} + {{- end }} + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if or .Values.webhook.enabled (gt $metricsPort 0) }} + ports: + {{- if (gt $metricsPort 0) }} + - containerPort: {{ $metricsPort }} + name: metrics + protocol: TCP + {{- end }} + {{- if .Values.webhook.enabled }} + - containerPort: {{ .Values.webhook.port }} + name: https-webhook + protocol: TCP + {{- end }} + {{- end }} + volumeMounts: + - mountPath: "/conf" + name: conf + readOnly: true + {{- if .Values.webhook.enabled }} + - mountPath: {{ .Values.webhook.certsDir }} + name: cert + readOnly: true + {{- end }} + {{- if .Values.config.metrics.secureMode.tls.certificateSecret }} + - mountPath: "/tmp/k8s-metrics-server/serving-certs" + name: tls-certificate + readOnly: true + {{- end }} + {{- with .Values.volumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + volumes: + - name: conf + configMap: + name: {{ include "eck-operator.fullname" . }} + {{- if .Values.webhook.enabled }} + - name: cert + secret: + defaultMode: 420 + secretName: {{ include "eck-operator.webhookSecretName" . }} + {{- end }} + {{- if .Values.config.metrics.secureMode.tls.certificateSecret }} + - name: tls-certificate + secret: + defaultMode: 420 + secretName: {{ .Values.config.metrics.secureMode.tls.certificateSecret }} + {{- end }} + {{- with .Values.volumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.hostNetwork }} + hostNetwork: true + {{- end }} + {{- if .Values.dnsPolicy }} + dnsPolicy: {{ .Values.dnsPolicy }} + {{- else if .Values.hostNetwork }} + dnsPolicy: ClusterFirstWithHostNet + {{- end }} + {{- with .Values.dnsConfig }} + dnsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/templates/validate-chart.yaml b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/validate-chart.yaml new file mode 100644 index 00000000..326b70bc --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/validate-chart.yaml @@ -0,0 +1,29 @@ +{{- if .Values.softMultiTenancy.enabled -}} + {{- if has .Release.Namespace .Values.managedNamespaces -}} + {{- fail "Operator namespace cannot be in managed namespaces when soft multi-tenancy is enabled" -}} + {{- end -}} + + {{- if empty .Values.managedNamespaces -}} + {{- fail "Managed namespaces must be defined when soft multi-tenancy is enabled" -}} + {{- end -}} + + {{- if empty .Values.kubeAPIServerIP -}} + {{- fail "Soft multi-tenancy requires kubeAPIServerIP to be defined" -}} + {{- end -}} +{{- end -}} + +{{- if (not .Values.createClusterScopedResources) -}} + {{- if .Values.webhook.enabled -}} + {{- fail "Webhook cannot be enabled when cluster-scoped resource creation is disabled" -}} + {{- end -}} + + {{- if .Values.config.validateStorageClass -}} + {{- fail "Storage class validation cannot be enabled when cluster-scoped resource creation is disabled" -}} + {{- end -}} +{{- end -}} + +{{- if (not .Values.config.enableLeaderElection) -}} + {{- if gt (int .Values.replicaCount) 1 -}} + {{- fail "Leader election must be enabled with more than one replica" -}} + {{- end -}} +{{- end -}} diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/templates/webhook.yaml b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/webhook.yaml new file mode 100644 index 00000000..8f41e7d0 --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/templates/webhook.yaml @@ -0,0 +1,473 @@ +{{- if .Values.webhook.enabled -}} +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: {{ include "eck-operator.webhookName" . }} + labels: + {{- include "eck-operator.labels" . | nindent 4 }} +{{- with .Values.webhook.certManagerCert }} + annotations: + cert-manager.io/inject-ca-from: "{{ $.Release.Namespace }}/{{ . }}" +{{- end }} +webhooks: +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-agent-k8s-elastic-co-v1alpha1-agent + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-agent-validation-v1alpha1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - agent.k8s.elastic.co + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - agents +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-apm-k8s-elastic-co-v1-apmserver + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-apm-validation-v1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - apm.k8s.elastic.co + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - apmservers +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-apm-k8s-elastic-co-v1beta1-apmserver + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-apm-validation-v1beta1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - apm.k8s.elastic.co + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - apmservers +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-beat-k8s-elastic-co-v1beta1-beat + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-beat-validation-v1beta1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - beat.k8s.elastic.co + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - beats +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-enterprisesearch-k8s-elastic-co-v1-enterprisesearch + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-ent-validation-v1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - enterprisesearch.k8s.elastic.co + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - enterprisesearches +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-enterprisesearch-k8s-elastic-co-v1beta1-enterprisesearch + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-ent-validation-v1beta1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - enterprisesearch.k8s.elastic.co + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - enterprisesearches +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-elasticsearch-k8s-elastic-co-v1-elasticsearch + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-es-validation-v1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - elasticsearch.k8s.elastic.co + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - elasticsearches +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-elasticsearch-k8s-elastic-co-v1beta1-elasticsearch + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-es-validation-v1beta1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - elasticsearch.k8s.elastic.co + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - elasticsearches +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-ems-k8s-elastic-co-v1alpha1-mapsservers + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-ems-validation-v1alpha1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - maps.k8s.elastic.co + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - mapsservers +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-kibana-k8s-elastic-co-v1-kibana + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-kb-validation-v1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - kibana.k8s.elastic.co + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - kibanas +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-kibana-k8s-elastic-co-v1beta1-kibana + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-kb-validation-v1beta1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - kibana.k8s.elastic.co + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - kibanas +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-autoscaling-k8s-elastic-co-v1alpha1-elasticsearchautoscaler + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-esa-validation-v1alpha1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - autoscaling.k8s.elastic.co + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - elasticsearchautoscalers +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-scp-k8s-elastic-co-v1alpha1-stackconfigpolicies + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-scp-validation-v1alpha1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - stackconfigpolicy.k8s.elastic.co + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - stackconfigpolicies +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-logstash-k8s-elastic-co-v1alpha1-logstash + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-logstash-validation-v1alpha1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1,v1beta1] + sideEffects: None + rules: + - apiGroups: + - logstash.k8s.elastic.co + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - logstashes +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "eck-operator.labels" . | nindent 4 }} +spec: + ports: + - name: https + port: 443 + targetPort: {{ .Values.webhook.port }} + selector: + {{- include "eck-operator.selectorLabels" . | nindent 4 }} +{{- if .Values.webhook.manageCerts }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "eck-operator.webhookSecretName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "eck-operator.labels" . | nindent 4 }} +{{- end }} +{{- end -}} diff --git a/packs/elastic-operator-3.1.0/charts/eck-operator/values.yaml b/packs/elastic-operator-3.1.0/charts/eck-operator/values.yaml new file mode 100644 index 00000000..431b8faa --- /dev/null +++ b/packs/elastic-operator-3.1.0/charts/eck-operator/values.yaml @@ -0,0 +1,372 @@ +# nameOverride is the short name for the deployment. Leave empty to let Helm generate a name using chart values. +nameOverride: "elastic-operator" + +# fullnameOverride is the full name for the deployment. Leave empty to let Helm generate a name using chart values. +fullnameOverride: "elastic-operator" + +# managedNamespaces is the set of namespaces that the operator manages. Leave empty to manage all namespaces. +managedNamespaces: [] + +# installCRDs determines whether Custom Resource Definitions (CRD) are installed by the chart. +# Note that CRDs are global resources and require cluster admin privileges to install. +# If you are sharing a cluster with other users who may want to install ECK on their own namespaces, setting this to true can have unintended consequences. +# 1. Upgrades will overwrite the global CRDs and could disrupt the other users of ECK who may be running a different version. +# 2. Uninstalling the chart will delete the CRDs and potentially cause Elastic resources deployed by other users to be removed as well. +installCRDs: true + +# replicaCount is the number of operator pods to run. +replicaCount: 1 + +image: + # repository is the container image prefixed by the registry name. + repository: docker.elastic.co/eck/eck-operator + # pullPolicy is the container image pull policy. + pullPolicy: IfNotPresent + # tag is the container image tag. If not defined, defaults to chart appVersion. + tag: null + # fips specifies whether the operator will use a FIPS compliant container image for its own StatefulSet image. + # This setting does not apply to Elastic Stack applications images. + # Can be combined with config.ubiOnly. + fips: false + +# priorityClassName defines the PriorityClass to be used by the operator pods. +priorityClassName: "" + +# imagePullSecrets defines the secrets to use when pulling the operator container image. +imagePullSecrets: [] + +# resources define the container resource limits for the operator. +resources: + limits: + cpu: 1 + memory: 1Gi + requests: + cpu: 100m + memory: 150Mi + +# statefulsetAnnotations define the annotations that should be added to the operator StatefulSet. +statefulsetAnnotations: {} + +# statefulsetLabels define additional labels that should be added to the operator StatefulSet. +statefulsetLabels: {} + +# podAnnotations define the annotations that should be added to the operator pod. +podAnnotations: {} + +## podLabels define additional labels that should be added to the operator pod. +podLabels: {} + +# podSecurityContext defines the pod security context for the operator pod. +podSecurityContext: + runAsNonRoot: true + +# securityContext defines the security context of the operator container. +securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + +# nodeSelector defines the node selector for the operator pod. +nodeSelector: {} + +# tolerations defines the node tolerations for the operator pod. +tolerations: [] + +# affinity defines the node affinity rules for the operator pod. +affinity: {} + +# podDisruptionBudget configures the minimum or the maxium available pods for voluntary disruptions, +# set to either an integer (e.g. 1) or a percentage value (e.g. 25%). +podDisruptionBudget: + enabled: false + minAvailable: 1 + # maxUnavailable: 3 + +# additional environment variables for the operator container. +env: [] + +# additional volume mounts for the operator container. +volumeMounts: [] + +# additional volumes to add to the operator pod. +volumes: [] + +# createClusterScopedResources determines whether cluster-scoped resources (ClusterRoles, ClusterRoleBindings) should be created. +createClusterScopedResources: true + +# Automount API credentials for the Service Account into the pod. +automountServiceAccountToken: true + +serviceAccount: + # create specifies whether a service account should be created for the operator. + create: true + # Specifies whether a service account should automount API credentials. + automountServiceAccountToken: true + # annotations to add to the service account + annotations: {} + # name of the service account to use. If not set and create is true, a name is generated using the fullname template. + name: "" + +tracing: + # enabled specifies whether APM tracing is enabled for the operator. + enabled: false + # config is a map of APM Server configuration variables that should be set in the environment. + config: + ELASTIC_APM_SERVER_URL: http://localhost:8200 + ELASTIC_APM_SERVER_TIMEOUT: 30s + +refs: + # enforceRBAC specifies whether RBAC should be enforced for cross-namespace associations between resources. + enforceRBAC: false + +webhook: + # enabled determines whether the webhook is installed. + enabled: true + # caBundle is the PEM-encoded CA trust bundle for the webhook certificate. Only required if manageCerts is false and certManagerCert is null. + caBundle: Cg== + # certManagerCert is the name of the cert-manager certificate to use with the webhook. + certManagerCert: null + # certsDir is the directory to mount the certificates. + certsDir: "/tmp/k8s-webhook-server/serving-certs" + # failurePolicy of the webhook. + failurePolicy: Ignore + # manageCerts determines whether the operator manages the webhook certificates automatically. + manageCerts: true + # namespaceSelector corresponds to the namespaceSelector property of the webhook. + # Setting this restricts the webhook to act only on objects submitted to namespaces that match the selector. + namespaceSelector: {} + # objectSelector corresponds to the objectSelector property of the webhook. + # Setting this restricts the webhook to act only on objects that match the selector. + objectSelector: {} + # port is the port that the validating webhook binds to. + port: 9443 + # secret specifies the Kubernetes secret to be mounted into the path designated by the certsDir value to be used for webhook certificates. + certsSecret: "" + +# hostNetwork allows a Pod to use the Node network namespace. +# This is required to allow for communication with the kube API when using some alternate CNIs in conjunction with webhook enabled. +# If hostNetwork is enabled, dnsPolicy defaults to ClusterFirstWithHostNet unless explicitly set. +# CAUTION: Proceed at your own risk. This setting has security concerns such as allowing malicious users to access workloads running on the host. +hostNetwork: false + +# dnsPolicy defines the DNS policy for the operator pod. +# Check https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy for more details. +dnsPolicy: "" + +# dnsConfig defines the DNS configuration for the operator pod. +# Check https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-dns-config for more details. +# dnsConfig: +# nameservers: +# - 169.254.20.10 +# searches: +# - svc.cluster.local +# options: +# - name: ndots +# value: "2" +dnsConfig: {} + +softMultiTenancy: + # enabled determines whether the operator is installed with soft multi-tenancy extensions. + # This requires network policies to be enabled on the Kubernetes cluster. + enabled: false + +# kubeAPIServerIP is required when softMultiTenancy is enabled. +kubeAPIServerIP: null + +telemetry: + # disabled determines whether the operator periodically updates ECK telemetry data for Kibana to consume. + disabled: false + # distributionChannel denotes which distribution channel was used to install the operator. + distributionChannel: "helm" + +# config values for the operator. +config: + # logVerbosity defines the logging level. Valid values are as follows: + # -2: Errors only + # -1: Errors and warnings + # 0: Errors, warnings, and information + # number greater than 0: Errors, warnings, information, and debug details. + logVerbosity: "0" + + # (Deprecated: use metrics.port: will be removed in v2.14.0) metricsPort defines the port to expose operator metrics. Set to 0 to disable metrics reporting. + metricsPort: 0 + + metrics: + # port defines the port to expose operator metrics. Set to 0 to disable metrics reporting. + port: "0" + # secureMode contains the options for enabling and configuring RBAC and TLS/HTTPs for the metrics endpoint. + secureMode: + # secureMode.enabled specifies whether to enable RBAC and TLS/HTTPs for the metrics endpoint. + # * This option makes most sense when using a ServiceMonitor to scrape the metrics and is therefore mutually exclusive with the podMonitor.enabled option. + # * This option also requires using cluster scoped resources (ClusterRole, ClusterRoleBinding) to + # grant access to the /metrics endpoint. (createClusterScopedResources: true is required) + # + enabled: false + tls: + # certificateSecret is the name of the tls secret containing the custom TLS certificate and key for the secure metrics endpoint. + # + # * This is an optional setting and is only required if you are using a custom TLS certificate. A self-signed certificate will be generated by default. + # * TLS secret key must be named tls.crt. + # * TLS key's secret key must be named tls.key. + # * It is assumed to be in the same namespace as the ServiceMonitor. + # + # example: kubectl create secret tls eck-metrics-tls-certificate -n elastic-system \ + # --cert=/path/to/tls.crt --key=/path/to/tls.key + certificateSecret: "" + + # containerRegistry to use for pulling Elasticsearch and other application container images. + containerRegistry: docker.elastic.co + + # containerRepository to use for pulling Elasticsearch and other application container images. + # containerRepository: "" + + # containerSuffix suffix to be appended to container images by default. Cannot be combined with -ubiOnly flag + # containerSuffix: "" + + # maxConcurrentReconciles is the number of concurrent reconciliation operations to perform per controller. + maxConcurrentReconciles: "3" + + # caValidity defines the validity period of the CA certificates generated by the operator. + caValidity: 8760h + + # caRotateBefore defines when to rotate a CA certificate that is due to expire. + caRotateBefore: 24h + + # caDir defines the directory containing a CA certificate (tls.crt) and its associated private key (tls.key) to be used for all managed resources. + # Setting this makes caRotateBefore and caValidity values ineffective. + caDir: "" + + # certificatesValidity defines the validity period of certificates generated by the operator. + certificatesValidity: 8760h + + # certificatesRotateBefore defines when to rotate a certificate that is due to expire. + certificatesRotateBefore: 24h + + # disableConfigWatch specifies whether the operator watches the configuration file for changes. + disableConfigWatch: false + + # exposedNodeLabels is an array of regular expressions of node labels which are allowed to be copied as annotations on Elasticsearch Pods. + exposedNodeLabels: [ "topology.kubernetes.io/.*", "failure-domain.beta.kubernetes.io/.*" ] + + # ipFamily specifies the IP family to use. Possible values: IPv4, IPv6 and "" (auto-detect) + ipFamily: "" + + # setDefaultSecurityContext determines whether a default security context is set on application containers created by the operator. + # *note* that the default option now is "auto-detect" to attempt to set this properly automatically when both running + # in an openshift cluster, and a standard kubernetes cluster. Valid values are as follows: + # "auto-detect" : auto detect + # "true" : set pod security context when creating resources. + # "false" : do not set pod security context when creating resources. + setDefaultSecurityContext: "auto-detect" + + # kubeClientTimeout sets the request timeout for Kubernetes API calls made by the operator. + kubeClientTimeout: 60s + + # elasticsearchClientTimeout sets the request timeout for Elasticsearch API calls made by the operator. + elasticsearchClientTimeout: 180s + + # validateStorageClass specifies whether storage classes volume expansion support should be verified. + # Can be disabled if cluster-wide storage class RBAC access is not available. + validateStorageClass: true + + # enableLeaderElection specifies whether leader election should be enabled + enableLeaderElection: true + + # Interval between observations of Elasticsearch health, non-positive values disable asynchronous observation. + elasticsearchObservationInterval: 10s + + # ubiOnly specifies whether the operator will use only UBI container images to deploy Elastic Stack applications as well as for its own StatefulSet image. UBI images are only available from 7.10.0 onward. + # Cannot be combined with the containerSuffix value. + ubiOnly: false + +# Prometheus PodMonitor configuration +# Reference: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#podmonitor +podMonitor: + + # enabled determines whether a podMonitor should deployed to scrape the eck metrics. + # This requires the prometheus operator and the config.metrics.port not to be 0 + enabled: false + + # labels adds additional labels to the podMonitor + labels: {} + + # annotations adds additional annotations to the podMonitor + annotations: {} + + # namespace determines in which namespace the podMonitor will be deployed. + # If not set the podMonitor will be created in the namespace where the Helm release is installed into + # namespace: monitoring + + # interval specifies the interval at which metrics should be scraped + interval: 5m + + # scrapeTimeout specifies the timeout after which the scrape is ended + scrapeTimeout: 30s + + # podTargetLabels transfers labels on the Kubernetes Pod onto the target. + podTargetLabels: [] + + # podMetricsEndpointConfig allows to add an extended configuration to the podMonitor + podMetricsEndpointConfig: {} + # honorTimestamps: true + +# Prometheus ServiceMonitor configuration +# Only used when config.enableSecureMetrics is true +# Reference: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#servicemonitor +serviceMonitor: + # This option requires the following settings within Prometheus to function: + # 1. RBAC settings for the Prometheus instance to access the metrics endpoint. + # + # - nonResourceURLs: + # - /metrics + # verbs: + # - get + # + # 2. If using the Prometheus Operator and your Prometheus instance is not in the same namespace as the operator you will need + # the Prometheus Operator configured with the following Helm values: + # + # prometheus: + # prometheusSpec: + # serviceMonitorNamespaceSelector: {} + # serviceMonitorSelectorNilUsesHelmValues: false + # + # allows to disable the serviceMonitor, enabled by default for backwards compatibility + enabled: true + # namespace determines in which namespace the serviceMonitor will be deployed. + # If not set the serviceMonitor will be created in the namespace where the Helm release is installed into + # namespace: monitoring + # caSecret is the name of the secret containing the custom CA certificate used to generate the custom TLS certificate for the secure metrics endpoint. + # + # * This *must* be the name of the secret containing the CA certificate used to sign the custom TLS certificate for the metrics endpoint. + # * This secret *must* be in the same namespace as the Prometheus instance that will scrape the metrics. + # * If using the Prometheus operator this secret must be within the `spec.secrets` field of the `Prometheus` custom resource such that it is mounted into the Prometheus pod at `caMountDirectory`, which defaults to /etc/prometheus/secrets/{secret-name}. + # * This is an optional setting and is only required if you are using a custom TLS certificate. + # * Key must be named ca.crt. + # + # example: kubectl create secret generic eck-metrics-tls-ca -n monitoring \ + # --from-file=ca.crt=/path/to/ca.pem + caSecret: "" + # caMountDirectory is the directory at which the CA certificate is mounted within the Prometheus pod. + # + # * You should only need to adjust this if you are *not* using the Prometheus operator. + caMountDirectory: "/etc/prometheus/secrets/" + # insecureSkipVerify specifies whether to skip verification of the TLS certificate for the secure metrics endpoint. + # + # * If this setting is set to false, then the following settings are required: + # - certificateSecret + # - caSecret + insecureSkipVerify: true + +# Globals meant for internal use only +global: + # manifestGen specifies whether the chart is running under manifest generator. + # This is used for tasks specific to generating the all-in-one.yaml file. + manifestGen: false + # createOperatorNamespace defines whether the operator namespace manifest should be generated when in manifestGen mode. + # Usually we do want that to happen (e.g. all-in-one.yaml) but, sometimes we don't (e.g. E2E tests). + createOperatorNamespace: true + # kubeVersion is the effective Kubernetes version we target when generating the all-in-one.yaml. + kubeVersion: 1.21.0 diff --git a/packs/elastic-operator-3.1.0/logo.png b/packs/elastic-operator-3.1.0/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..fa70b78daa45585ec0f802dfe637e4ce2172d6f8 GIT binary patch literal 5810 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 Date: Thu, 18 Sep 2025 02:00:07 -0500 Subject: [PATCH 4/8] Upgrade pack elastic-stack to version 0.16.0 --- packs/elastic-stack-0.16.0/README.md | 63 +++ .../charts/eck-stack-0.16.0.tgz | Bin 0 -> 44116 bytes .../charts/eck-stack/.helmignore | 25 ++ .../charts/eck-stack/Chart.lock | 27 ++ .../charts/eck-stack/Chart.yaml | 39 ++ .../charts/eck-stack/README.md | 93 +++++ .../eck-stack/charts/eck-agent/.helmignore | 24 ++ .../eck-stack/charts/eck-agent/Chart.yaml | 10 + .../charts/eck-stack/charts/eck-agent/LICENSE | 93 +++++ .../eck-agent/examples/fleet-agents.yaml | 24 ++ .../examples/system-integration.yaml | 133 ++++++ .../charts/eck-agent/templates/NOTES.txt | 6 + .../charts/eck-agent/templates/_helpers.tpl | 51 +++ .../templates/cluster-role-binding.yaml | 33 ++ .../eck-agent/templates/cluster-role.yaml | 22 + .../eck-agent/templates/elastic-agent.yaml | 89 ++++ .../eck-agent/templates/service-account.yaml | 22 + .../eck-stack/charts/eck-agent/values.yaml | 245 +++++++++++ .../charts/eck-apm-server/.helmignore | 24 ++ .../charts/eck-apm-server/Chart.yaml | 10 + .../eck-stack/charts/eck-apm-server/LICENSE | 93 +++++ .../jaeger-with-http-configuration.yaml | 29 ++ .../charts/eck-apm-server/templates/NOTES.txt | 6 + .../eck-apm-server/templates/_helpers.tpl | 51 +++ .../eck-apm-server/templates/apmserver.yaml | 53 +++ .../charts/eck-apm-server/values.yaml | 97 +++++ .../eck-stack/charts/eck-beats/.helmignore | 24 ++ .../eck-stack/charts/eck-beats/Chart.yaml | 10 + .../charts/eck-stack/charts/eck-beats/LICENSE | 93 +++++ .../eck-beats/examples/auditbeat_hosts.yaml | 110 +++++ .../examples/filebeat_no_autodiscover.yaml | 52 +++ .../examples/heartbeat_es_kb_health.yaml | 23 + .../eck-beats/examples/metricbeat_hosts.yaml | 158 +++++++ .../examples/packetbeat_dns_http.yaml | 37 ++ .../charts/eck-beats/templates/NOTES.txt | 6 + .../charts/eck-beats/templates/_helpers.tpl | 51 +++ .../charts/eck-beats/templates/beats.yaml | 75 ++++ .../templates/cluster-role-binding.yaml | 35 ++ .../eck-beats/templates/cluster-role.yaml | 22 + .../eck-beats/templates/service-account.yaml | 23 + .../eck-stack/charts/eck-beats/values.yaml | 169 ++++++++ .../charts/eck-elasticsearch/.helmignore | 24 ++ .../charts/eck-elasticsearch/Chart.yaml | 10 + .../charts/eck-elasticsearch/LICENSE | 93 +++++ .../examples/hot-warm-cold.yaml | 198 +++++++++ .../ingress/elasticsearch-ingress-aks.yaml | 26 ++ .../elasticsearch-ingress-eks-alb.yaml | 37 ++ .../elasticsearch-ingress-eks-nlb.yaml | 27 ++ .../ingress/elasticsearch-ingress-gke.yaml | 36 ++ .../eck-elasticsearch/templates/NOTES.txt | 6 + .../eck-elasticsearch/templates/_helpers.tpl | 51 +++ .../templates/elasticsearch.yaml | 78 ++++ .../eck-elasticsearch/templates/ingress.yaml | 48 +++ .../charts/eck-elasticsearch/values.yaml | 393 ++++++++++++++++++ .../charts/eck-enterprise-search/.helmignore | 24 ++ .../charts/eck-enterprise-search/Chart.yaml | 9 + .../examples/with-custom-configuration.yaml | 19 + .../templates/_helpers.tpl | 62 +++ .../templates/enterprisesearch.yaml | 62 +++ .../charts/eck-enterprise-search/values.yaml | 96 +++++ .../charts/eck-fleet-server/.helmignore | 24 ++ .../charts/eck-fleet-server/Chart.yaml | 11 + .../eck-stack/charts/eck-fleet-server/LICENSE | 93 +++++ .../examples/fleet-server.yaml | 17 + .../eck-fleet-server/templates/NOTES.txt | 6 + .../eck-fleet-server/templates/_helpers.tpl | 51 +++ .../templates/cluster-role-binding.yaml | 33 ++ .../templates/cluster-role.yaml | 22 + .../templates/fleet-server.yaml | 64 +++ .../templates/service-account.yaml | 22 + .../charts/eck-fleet-server/values.yaml | 157 +++++++ .../eck-stack/charts/eck-kibana/.helmignore | 24 ++ .../eck-stack/charts/eck-kibana/Chart.yaml | 10 + .../eck-stack/charts/eck-kibana/LICENSE | 93 +++++ .../examples/http-configuration.yaml | 36 ++ .../examples/ingress/kibana-aks.yaml | 28 ++ .../examples/ingress/kibana-eks.yaml | 48 +++ .../examples/ingress/kibana-gke.yaml | 31 ++ .../charts/eck-kibana/templates/NOTES.txt | 6 + .../charts/eck-kibana/templates/_helpers.tpl | 51 +++ .../charts/eck-kibana/templates/ingress.yaml | 48 +++ .../charts/eck-kibana/templates/kibana.yaml | 61 +++ .../eck-stack/charts/eck-kibana/values.yaml | 179 ++++++++ .../eck-stack/charts/eck-logstash/.helmignore | 24 ++ .../eck-stack/charts/eck-logstash/Chart.yaml | 10 + .../eck-stack/charts/eck-logstash/LICENSE | 93 +++++ .../eck-logstash/examples/basic-eck.yaml | 44 ++ .../charts/eck-logstash/examples/es-role.yaml | 25 ++ .../eck-logstash/examples/monitored.yaml | 49 +++ .../charts/eck-logstash/examples/multi.yaml | 78 ++++ .../charts/eck-logstash/examples/volumes.yaml | 107 +++++ .../charts/eck-logstash/templates/NOTES.txt | 6 + .../eck-logstash/templates/_helpers.tpl | 51 +++ .../eck-logstash/templates/logstash.yaml | 58 +++ .../eck-stack/charts/eck-logstash/values.yaml | 115 +++++ .../examples/agent/fleet-agents.yaml | 122 ++++++ .../eck-stack/examples/apm-server/basic.yaml | 52 +++ .../jaeger-with-http-configuration.yaml | 60 +++ .../examples/beats/metricbeat_hosts.yaml | 217 ++++++++++ .../examples/custom-elasticsearch-kibana.yaml | 78 ++++ .../examples/elasticsearch/hot-warm-cold.yaml | 199 +++++++++ .../ingress/elasticsearch-ingress-gke.yaml | 40 ++ .../examples/enterprise-search/basic.yaml | 42 ++ .../with-custom-configuration.yaml | 52 +++ .../examples/kibana/http-configuration.yaml | 23 + .../examples/kibana/ingress/kibana-gke.yaml | 80 ++++ .../examples/logstash/basic-eck.yaml | 112 +++++ .../charts/eck-stack/templates/NOTES.txt | 10 + .../charts/eck-stack/templates/_helpers.tpl | 48 +++ .../charts/eck-stack/values.yaml | 50 +++ packs/elastic-stack-0.16.0/logo.png | Bin 0 -> 5810 bytes packs/elastic-stack-0.16.0/pack.json | 36 ++ packs/elastic-stack-0.16.0/presets.yaml | 260 ++++++++++++ packs/elastic-stack-0.16.0/values.yaml | 71 ++++ 114 files changed, 6876 insertions(+) create mode 100644 packs/elastic-stack-0.16.0/README.md create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack-0.16.0.tgz create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/.helmignore create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/Chart.lock create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/Chart.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/README.md create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/.helmignore create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/Chart.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/LICENSE create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/examples/fleet-agents.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/examples/system-integration.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/templates/NOTES.txt create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/templates/_helpers.tpl create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/templates/cluster-role-binding.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/templates/cluster-role.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/templates/elastic-agent.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/templates/service-account.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/values.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/.helmignore create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/Chart.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/LICENSE create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/examples/jaeger-with-http-configuration.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/templates/NOTES.txt create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/templates/_helpers.tpl create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/templates/apmserver.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/values.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/.helmignore create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/Chart.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/LICENSE create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/examples/auditbeat_hosts.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/examples/filebeat_no_autodiscover.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/examples/heartbeat_es_kb_health.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/examples/metricbeat_hosts.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/examples/packetbeat_dns_http.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/templates/NOTES.txt create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/templates/_helpers.tpl create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/templates/beats.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/templates/cluster-role-binding.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/templates/cluster-role.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/templates/service-account.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/values.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/.helmignore create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/Chart.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/LICENSE create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/examples/hot-warm-cold.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-aks.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-eks-alb.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-eks-nlb.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-gke.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/templates/NOTES.txt create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/templates/_helpers.tpl create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/templates/elasticsearch.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/templates/ingress.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/values.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-enterprise-search/.helmignore create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-enterprise-search/Chart.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-enterprise-search/examples/with-custom-configuration.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-enterprise-search/templates/_helpers.tpl create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-enterprise-search/templates/enterprisesearch.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-enterprise-search/values.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/.helmignore create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/Chart.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/LICENSE create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/examples/fleet-server.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/templates/NOTES.txt create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/templates/_helpers.tpl create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/templates/cluster-role-binding.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/templates/cluster-role.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/templates/fleet-server.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/templates/service-account.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/values.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/.helmignore create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/Chart.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/LICENSE create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/examples/http-configuration.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-aks.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-eks.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-gke.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/templates/NOTES.txt create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/templates/_helpers.tpl create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/templates/ingress.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/templates/kibana.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/values.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/.helmignore create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/Chart.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/LICENSE create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/examples/basic-eck.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/examples/es-role.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/examples/monitored.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/examples/multi.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/examples/volumes.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/templates/NOTES.txt create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/templates/_helpers.tpl create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/templates/logstash.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/values.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/examples/agent/fleet-agents.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/examples/apm-server/basic.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/examples/apm-server/jaeger-with-http-configuration.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/examples/beats/metricbeat_hosts.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/examples/custom-elasticsearch-kibana.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/examples/elasticsearch/hot-warm-cold.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/examples/elasticsearch/ingress/elasticsearch-ingress-gke.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/examples/enterprise-search/basic.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/examples/enterprise-search/with-custom-configuration.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/examples/kibana/http-configuration.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/examples/kibana/ingress/kibana-gke.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/examples/logstash/basic-eck.yaml create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/templates/NOTES.txt create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/templates/_helpers.tpl create mode 100644 packs/elastic-stack-0.16.0/charts/eck-stack/values.yaml create mode 100644 packs/elastic-stack-0.16.0/logo.png create mode 100644 packs/elastic-stack-0.16.0/pack.json create mode 100644 packs/elastic-stack-0.16.0/presets.yaml create mode 100644 packs/elastic-stack-0.16.0/values.yaml diff --git a/packs/elastic-stack-0.16.0/README.md b/packs/elastic-stack-0.16.0/README.md new file mode 100644 index 00000000..e14e757b --- /dev/null +++ b/packs/elastic-stack-0.16.0/README.md @@ -0,0 +1,63 @@ +# Elastic Cloud on Kubernetes (ECK) + +Elastic Cloud on Kubernetes automates the deployment, provisioning, management, and orchestration of Elasticsearch, Kibana, APM Server, Enterprise Search, Beats, Elastic Agent, Elastic Maps Server, and Logstash on Kubernetes based on the operator pattern. + +Current features: + +* Elasticsearch, Kibana, APM Server, Enterprise Search, and Beats deployments +* TLS Certificates management +* Safe Elasticsearch cluster configuration & topology changes +* Persistent volumes usage +* Custom node configuration and attributes +* Secure settings keystore updates + +Supported versions: + +* Kubernetes 1.25-1.29 +* Elasticsearch, Kibana, APM Server: 6.8+, 7.1+, 8+, 9+ +* Enterprise Search: 7.7+, 8+ +* Beats: 7.0+, 8+, 9+ +* Elastic Agent: 7.10+ (standalone), 7.14+, 8+ (Fleet), 9+ +* Elastic Maps Server: 7.11+, 8+ +* Logstash 8.7+, 9+ + +Check the [Quickstart](https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-quickstart.html) to deploy your first cluster with ECK. + +For general questions, please see the Elastic [forums](https://discuss.elastic.co/c/eck). + +# ECK-Stack + +ECK Stack is a Helm chart to assist in the deployment of Elastic Stack components, which are +managed by the [ECK Operator](https://www.elastic.co/guide/en/cloud-on-k8s/current/index.html) + +## Supported Elastic Stack Resources + +The following Elastic Stack resources are currently supported. + +- Elasticsearch +- Kibana +- Elastic Agent +- Fleet Server +- Beats +- Logstash +- APM Server + +Additional resources will be supported in future releases of this Helm Chart. + +## Prerequisites + +- Kubernetes 1.27+ +- Elastic ECK Operator + +## Configuration + +The following table lists the configurable parameters of the eck-stack chart and their default values. + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `eck-elasticsearch.enabled` | If `true`, create an Elasticsearch resource (using the eck-elasticsearch Chart) | `true` | +| `eck-kibana.enabled` | If `true`, create a Kibana resource (using the eck-kibana Chart) | `true` | +| `eck-agent.enabled` | If `true`, create an Elastic Agent resource (using the eck-agent Chart) | `false` | +| `eck-fleet-server.enabled` | If `true`, create a Fleet Server resource (using the eck-fleet-server Chart) | `false` | +| `eck-logstash.enabled` | If `true`, create a Logstash resource (using the eck-logstash Chart) | `false` | +| `eck-apm-server.enabled` | If `true`, create a standalone Elastic APM Server resource (using the eck-apm-server Chart) | `false` | diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack-0.16.0.tgz b/packs/elastic-stack-0.16.0/charts/eck-stack-0.16.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..d04fe9ed237737a9b75542d3c6425115b0349655 GIT binary patch literal 44116 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 literal 0 HcmV?d00001 diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/.helmignore b/packs/elastic-stack-0.16.0/charts/eck-stack/.helmignore new file mode 100644 index 00000000..9e40bf01 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/.helmignore @@ -0,0 +1,25 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests +charts/*/templates/tests \ No newline at end of file diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/Chart.lock b/packs/elastic-stack-0.16.0/charts/eck-stack/Chart.lock new file mode 100644 index 00000000..5a4e3fb6 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/Chart.lock @@ -0,0 +1,27 @@ +dependencies: +- name: eck-elasticsearch + repository: "" + version: 0.16.0 +- name: eck-kibana + repository: "" + version: 0.16.0 +- name: eck-agent + repository: "" + version: 0.16.0 +- name: eck-fleet-server + repository: "" + version: 0.16.0 +- name: eck-beats + repository: "" + version: 0.16.0 +- name: eck-logstash + repository: "" + version: 0.16.0 +- name: eck-apm-server + repository: "" + version: 0.16.0 +- name: eck-enterprise-search + repository: "" + version: 0.16.0 +digest: sha256:e6edc40e5df5c9df93965f52c5cce6ef9a2ae3a6d71750bc522632c7731c4957 +generated: "2025-07-29T14:57:40.491351384Z" diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/Chart.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/Chart.yaml new file mode 100644 index 00000000..e3311be4 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/Chart.yaml @@ -0,0 +1,39 @@ +apiVersion: v2 +dependencies: +- condition: eck-elasticsearch.enabled + name: eck-elasticsearch + repository: "" + version: 0.16.0 +- condition: eck-kibana.enabled + name: eck-kibana + repository: "" + version: 0.16.0 +- condition: eck-agent.enabled + name: eck-agent + repository: "" + version: 0.16.0 +- condition: eck-fleet-server.enabled + name: eck-fleet-server + repository: "" + version: 0.16.0 +- condition: eck-beats.enabled + name: eck-beats + repository: "" + version: 0.16.0 +- condition: eck-logstash.enabled + name: eck-logstash + repository: "" + version: 0.16.0 +- condition: eck-apm-server.enabled + name: eck-apm-server + repository: "" + version: 0.16.0 +- condition: eck-enterprise-search.enabled + name: eck-enterprise-search + repository: "" + version: 0.16.0 +description: Elastic Stack managed by the ECK Operator +kubeVersion: '>= 1.21.0-0' +name: eck-stack +type: application +version: 0.16.0 diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/README.md b/packs/elastic-stack-0.16.0/charts/eck-stack/README.md new file mode 100644 index 00000000..f301bd12 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/README.md @@ -0,0 +1,93 @@ +# ECK-Stack + +ECK Stack is a Helm chart to assist in the deployment of Elastic Stack components, which are +managed by the [ECK Operator](https://www.elastic.co/guide/en/cloud-on-k8s/current/index.html) + +## Supported Elastic Stack Resources + +The following Elastic Stack resources are currently supported. + +- Elasticsearch +- Kibana +- Elastic Agent +- Fleet Server +- Beats +- Logstash +- APM Server + +Additional resources will be supported in future releases of this Helm Chart. + +## Prerequisites + +- Kubernetes 1.21+ +- Elastic ECK Operator + +## Installing the Chart + +### Installing the ECK Operator + +Before using this chart, the Elastic ECK Operator is required to be installed within the Kubernetes cluster. +Full installation instructions can be found within [our documentation](https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-installing-eck.html) + +To install the ECK Operator using Helm. + +```sh +# Add the Elastic Helm Repository +helm repo add elastic https://helm.elastic.co && helm repo update + +# Install the ECK Operator cluster-wide +helm install elastic-operator elastic/eck-operator -n elastic-system --create-namespace +``` + +Additional ECK Operator Helm installation options can be found within [our documentation](https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-install-helm.html) + +### Installing the ECK Stack Chart + +The following will install the ECK-Stack chart using the default values, which will deploy an Elasticsearch [Quickstart Cluster](https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-deploy-elasticsearch.html), and a Kibana [Quickstart Instance](https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-deploy-kibana.html) + +```sh +# Add the Elastic Helm Repository +helm repo add elastic https://helm.elastic.co && helm repo update + +# Install the ECK-Stack helm chart +# This will setup a 'quickstart' Elasticsearch and Kibana resource in the 'elastic-stack' namespace +helm install my-release elastic/eck-stack -n elastic-stack --create-namespace +``` + +More information on the different ways to use the ECK Stack chart to deploy Elastic Stack resources +can be found in [our documentation](https://www.elastic.co/guide/en/cloud-on-k8s/current/index.html). + +## Uninstalling the Chart + +To uninstall/delete the `my-release` deployment from the 'elastic-stack' namespace: + +```console +helm delete my-release -n elastic-stack +``` + +The command removes all the Elastic Stack resources associated with the chart and deletes the release. + +## Configuration + +The following table lists the configurable parameters of the eck-stack chart and their default values. + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `eck-elasticsearch.enabled` | If `true`, create an Elasticsearch resource (using the eck-elasticsearch Chart) | `true` | +| `eck-kibana.enabled` | If `true`, create a Kibana resource (using the eck-kibana Chart) | `true` | +| `eck-agent.enabled` | If `true`, create an Elastic Agent resource (using the eck-agent Chart) | `false` | +| `eck-fleet-server.enabled` | If `true`, create a Fleet Server resource (using the eck-fleet-server Chart) | `false` | +| `eck-logstash.enabled` | If `true`, create a Logstash resource (using the eck-logstash Chart) | `false` | +| `eck-apm-server.enabled` | If `true`, create a standalone Elastic APM Server resource (using the eck-apm-server Chart) | `false` | + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. + +Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example, + +```console +helm install my-release -f values.yaml . +``` + +## Contributing + +This chart is maintained at [github.com/elastic/cloud-on-k8s](https://github.com/elastic/cloud-on-k8s/tree/main/deploy/eck-stack). diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/.helmignore b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/.helmignore new file mode 100644 index 00000000..f1568daf --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/Chart.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/Chart.yaml new file mode 100644 index 00000000..575bc991 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/Chart.yaml @@ -0,0 +1,10 @@ +apiVersion: v2 +description: Elastic Agent managed by the ECK operator +icon: https://images.contentstack.io/v3/assets/bltefdd0b53724fa2ce/blt77c2da6e0198746e/620ac24e6662ca0a6f617114/icon-agent-32-color.svg +kubeVersion: '>= 1.21.0-0' +name: eck-agent +sources: +- https://github.com/elastic/cloud-on-k8s +- https://github.com/elastic/elastic-agent +type: application +version: 0.16.0 diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/LICENSE b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/LICENSE new file mode 100644 index 00000000..92503a72 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/LICENSE @@ -0,0 +1,93 @@ +Elastic License 2.0 + +URL: https://www.elastic.co/licensing/elastic-license + +## Acceptance + +By using the software, you agree to all of the terms and conditions below. + +## Copyright License + +The licensor grants you a non-exclusive, royalty-free, worldwide, +non-sublicensable, non-transferable license to use, copy, distribute, make +available, and prepare derivative works of the software, in each case subject to +the limitations and conditions below. + +## Limitations + +You may not provide the software to third parties as a hosted or managed +service, where the service provides users with access to any substantial set of +the features or functionality of the software. + +You may not move, change, disable, or circumvent the license key functionality +in the software, and you may not remove or obscure any functionality in the +software that is protected by the license key. + +You may not alter, remove, or obscure any licensing, copyright, or other notices +of the licensor in the software. Any use of the licensor’s trademarks is subject +to applicable law. + +## Patents + +The licensor grants you a license, under any patent claims the licensor can +license, or becomes able to license, to make, have made, use, sell, offer for +sale, import and have imported the software, in each case subject to the +limitations and conditions in this license. This license does not cover any +patent claims that you cause to be infringed by modifications or additions to +the software. If you or your company make any written claim that the software +infringes or contributes to infringement of any patent, your patent license for +the software granted under these terms ends immediately. If your company makes +such a claim, your patent license ends immediately for work on behalf of your +company. + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you +also gets a copy of these terms. + +If you modify the software, you must include in any modified copies of the +software prominent notices stating that you have modified the software. + +## No Other Rights + +These terms do not imply any licenses other than those expressly granted in +these terms. + +## Termination + +If you use the software in violation of these terms, such use is not licensed, +and your licenses will automatically terminate. If the licensor provides you +with a notice of your violation, and you cease all violation of this license no +later than 30 days after you receive that notice, your licenses will be +reinstated retroactively. However, if you violate these terms after such +reinstatement, any additional violation of these terms will cause your licenses +to terminate automatically and permanently. + +## No Liability + +*As far as the law allows, the software comes as is, without any warranty or +condition, and the licensor will not be liable to you for any damages arising +out of these terms or the use or nature of the software, under any kind of +legal claim.* + +## Definitions + +The **licensor** is the entity offering these terms, and the **software** is the +software the licensor makes available under these terms, including any portion +of it. + +**you** refers to the individual or entity agreeing to these terms. + +**your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control over, +are under the control of, or are under common control with that +organization. **control** means ownership of substantially all the assets of an +entity, or the power to direct its management and policies by vote, contract, or +otherwise. Control can be direct or indirect. + +**your licenses** are all the licenses granted to you for the software under +these terms. + +**use** means anything you do with the software requiring one of your licenses. + +**trademark** means trademarks, service marks, and similar rights. \ No newline at end of file diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/examples/fleet-agents.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/examples/fleet-agents.yaml new file mode 100644 index 00000000..e6a38293 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/examples/fleet-agents.yaml @@ -0,0 +1,24 @@ +# The following example should only be used in conjunction with the 'eck-fleet-server' Helm Chart, +# and shows how the Agents can be deployed as a daemonset, and controlled by Fleet Server. +# +version: 9.1.0 + +# This must match the name of an Agent policy. +policyID: eck-agent +# This must match the name of the fleet server installed from eck-fleet-server chart. +fleetServerRef: + name: eck-fleet-server +kibanaRef: + name: eck-kibana +mode: fleet +# elasticsearchRefs must be empty when fleet mode is enabled. +elasticsearchRefs: [] +daemonSet: + podTemplate: + spec: + serviceAccountName: elastic-agent + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + automountServiceAccountToken: true + securityContext: + runAsUser: 0 diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/examples/system-integration.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/examples/system-integration.yaml new file mode 100644 index 00000000..b88d59b0 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/examples/system-integration.yaml @@ -0,0 +1,133 @@ +# The following example should only be used in Agent "standalone" mode, +# and should not be used when Agent is used with Fleet Server. +# +version: 9.1.0 +elasticsearchRefs: +- name: eck-elasticsearch +daemonSet: + podTemplate: + spec: + containers: + - name: agent + securityContext: + runAsUser: 0 + volumeMounts: + - name: agent-data + mountPath: /usr/share/elastic-agent/data/elastic-agent-08e204/run +config: + id: 488e0b80-3634-11eb-8208-57893829af4e + revision: 2 + agent: + monitoring: + enabled: true + use_output: default + logs: true + metrics: true + inputs: + - id: 4917ade0-3634-11eb-8208-57893829af4e + name: system-1 + revision: 1 + type: system/metrics + use_output: default + meta: + package: + name: system + version: 9.1.0 + data_stream: + namespace: default + streams: + - id: system/metrics-system.cpu + data_stream: + dataset: system.cpu + type: metrics + metricsets: + - cpu + cpu.metrics: + - percentages + - normalized_percentages + period: 10s + - id: system/metrics-system.diskio + data_stream: + dataset: system.diskio + type: metrics + metricsets: + - diskio + diskio.include_devices: null + period: 10s + - id: system/metrics-system.filesystem + data_stream: + dataset: system.filesystem + type: metrics + metricsets: + - filesystem + period: 1m + processors: + - drop_event.when.regexp: + system.filesystem.mount_point: ^/(sys|cgroup|proc|dev|etc|host|lib|snap)($|/) + - id: system/metrics-system.fsstat + data_stream: + dataset: system.fsstat + type: metrics + metricsets: + - fsstat + period: 1m + processors: + - drop_event.when.regexp: + system.fsstat.mount_point: ^/(sys|cgroup|proc|dev|etc|host|lib|snap)($|/) + - id: system/metrics-system.load + data_stream: + dataset: system.load + type: metrics + metricsets: + - load + period: 10s + - id: system/metrics-system.memory + data_stream: + dataset: system.memory + type: metrics + metricsets: + - memory + period: 10s + - id: system/metrics-system.network + data_stream: + dataset: system.network + type: metrics + metricsets: + - network + period: 10s + network.interfaces: null + - id: system/metrics-system.process + data_stream: + dataset: system.process + type: metrics + metricsets: + - process + period: 10s + process.include_top_n.by_cpu: 5 + process.include_top_n.by_memory: 5 + process.cmdline.cache.enabled: true + process.cgroups.enabled: false + process.include_cpu_ticks: false + processes: + - .* + - id: system/metrics-system.process_summary + data_stream: + dataset: system.process_summary + type: metrics + metricsets: + - process_summary + period: 10s + - id: system/metrics-system.socket_summary + data_stream: + dataset: system.socket_summary + type: metrics + metricsets: + - socket_summary + period: 10s + - id: system/metrics-system.uptime + data_stream: + dataset: system.uptime + type: metrics + metricsets: + - uptime + period: 10s diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/templates/NOTES.txt b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/templates/NOTES.txt new file mode 100644 index 00000000..cfd41883 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/templates/NOTES.txt @@ -0,0 +1,6 @@ + +1. Check Elastic Agent status + $ kubectl get agent {{ include "elasticagent.fullname" . }} -n {{ .Release.Namespace }} + +2. Check Elastic Agent pod status + $ kubectl get pods --namespace={{ .Release.Namespace }} -l agent.k8s.elastic.co/name={{ include "elasticagent.fullname" . }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/templates/_helpers.tpl b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/templates/_helpers.tpl new file mode 100644 index 00000000..748ca7dd --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "elasticagent.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "elasticagent.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "elasticagent.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "elasticagent.labels" -}} +helm.sh/chart: {{ include "elasticagent.chart" . }} +{{ include "elasticagent.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.labels }} +{{ toYaml .Values.labels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "elasticagent.selectorLabels" -}} +app.kubernetes.io/name: {{ include "elasticagent.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/templates/cluster-role-binding.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/templates/cluster-role-binding.yaml new file mode 100644 index 00000000..762a59dc --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/templates/cluster-role-binding.yaml @@ -0,0 +1,33 @@ +{{- with .Values.clusterRoleBinding }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .name }} + labels: + {{- include "elasticagent.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or $.Values.annotations .annotations }} + annotations: + {{- with $.Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +{{- with .subjects }} +subjects: +{{- range . }} + - kind: {{ .kind }} + name: {{ .name }} + namespace: {{ .namespace | default $.Release.Namespace | quote }} +{{- end }} +{{- end }} +roleRef: + kind: {{ .roleRef.kind }} + name: {{ .roleRef.name }} + apiGroup: {{ .roleRef.apiGroup }} +{{- end }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/templates/cluster-role.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/templates/cluster-role.yaml new file mode 100644 index 00000000..5d97ec7a --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/templates/cluster-role.yaml @@ -0,0 +1,22 @@ +{{- with .Values.clusterRole }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ .name }} + labels: + {{- include "elasticagent.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or $.Values.annotations .annotations }} + annotations: + {{- with $.Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +rules: {{- toYaml .rules | nindent 2 }} +{{- end }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/templates/elastic-agent.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/templates/elastic-agent.yaml new file mode 100644 index 00000000..9017e5bb --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/templates/elastic-agent.yaml @@ -0,0 +1,89 @@ +--- +apiVersion: agent.k8s.elastic.co/v1alpha1 +kind: Agent +metadata: + name: {{ include "elasticagent.fullname" . }} + labels: + {{- include "elasticagent.labels" $ | nindent 4 }} + annotations: + eck.k8s.elastic.co/license: basic + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + version: {{ required "An Elastic Agent version is required" (or ((.Values.spec).version) (.Values.version)) }} + {{- $daemonSet := (or (hasKey (.Values.spec) "daemonSet") (hasKey .Values "daemonSet")) }} + {{- $deployment := (or (hasKey (.Values.spec) "deployment") (hasKey .Values "deployment")) }} + {{- $statefulSet := (or (hasKey (.Values.spec) "statefulSet") (hasKey .Values "statefulSet")) }} + {{- if and (not $daemonSet) (not $deployment) (not $statefulSet) }} + {{ fail "At least one of daemonSet, deployment or statefulSet is required" }} + {{- end }} + {{- if $daemonSet }} + {{- $ds := or ((.Values.spec).daemonSet) (.Values.daemonSet) }} + daemonSet: + {{- /* This is required to render the empty daemonset ( {} ) properly */}} + {{- $ds | default dict | toYaml | nindent 4 }} + {{- end }} + {{- if $deployment }} + {{- $deploy := or ((.Values.spec).deployment) (.Values.deployment) }} + deployment: + {{- /* This is required to render the empty deployment ( {} ) properly */}} + {{- $deploy | default dict | toYaml | nindent 4 }} + {{- end }} + {{- if $statefulSet }} + {{- $sts := or ((.Values.spec).statefulSet) (.Values.statefulSet) }} + statefulSet: + {{- /* This is required to render the empty statefulSet ( {} ) properly */}} + {{- $sts | default dict | toYaml | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).image) (.Values.image) }} + image: {{ . }} + {{- end }} + {{- with or ((.Values.spec).elasticsearchRefs) (.Values.elasticsearchRefs) }} + elasticsearchRefs: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).kibanaRef) (.Values.kibanaRef) }} + kibanaRef: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).fleetServerRef) (.Values.fleetServerRef) }} + fleetServerRef: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- $config := or ((.Values.spec).config) (.Values.config) }} + {{- $configRef := or ((.Values.spec).configRef) (.Values.configRef) }} + {{- if and $config $configRef }} + {{ fail "Only one of config and configRef can be specified" }} + {{- end }} + {{- with $config }} + config: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $configRef }} + configRef: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).mode) (.Values.mode) }} + mode: {{ . }} + {{- end }} + {{- with or ((.Values.spec).fleetServerEnabled) (.Values.fleetServerEnabled) }} + fleetServerEnabled: {{ . }} + {{- end }} + {{- with or ((.Values.spec).http) (.Values.http) }} + http: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).policyID) (.Values.policyID) }} + policyID: {{ . }} + {{- end }} + {{- with or ((.Values.spec).secureSettings) (.Values.secureSettings) }} + secureSettings: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).revisionHistoryLimit) (.Values.revisionHistoryLimit) }} + revisionHistoryLimit: {{ . }} + {{- end }} + {{- with or (((.Values.spec).serviceAccount).name) ((.Values.serviceAccount).name) }} + serviceAccountName: {{ . }} + {{- end }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/templates/service-account.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/templates/service-account.yaml new file mode 100644 index 00000000..e8bdf0b5 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/templates/service-account.yaml @@ -0,0 +1,22 @@ +{{- with .Values.serviceAccount }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .name }} + namespace: {{ .namespace | default $.Release.Namespace | quote }} + labels: + {{- include "elasticagent.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or $.Values.annotations .annotations }} + annotations: + {{- with $.Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/values.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/values.yaml new file mode 100644 index 00000000..244aed9b --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-agent/values.yaml @@ -0,0 +1,245 @@ +--- +# Default values for eck-agent. +# This is a YAML-formatted file. + +# Overridable names of the Elastic Agent resource. +# By default, this is the Release name set for the chart, +# followed by 'eck-agent'. +# +# nameOverride will override the name of the Chart with the name set here, +# so nameOverride: quickstart, would convert to '{{ Release.name }}-quickstart' +# +# nameOverride: "quickstart" +# +# fullnameOverride will override both the release name, and the chart name, +# and will name the Fleet Agent resource exactly as specified. +# +# fullnameOverride: "quickstart" + +# Version of Elastic Agent. +# +version: 9.1.0 + +# Labels that will be applied to Elastic Agent. +# +labels: {} + +# Annotations that will be applied to Elastic Agent. +# +annotations: {} + +# Elastic Agent image to deploy. +# +# image: docker.elastic.co/beats/elastic-agent:9.1.0 + +# ** Deprecation Notice ** +# The previous versions of this Helm Chart simply used the `spec` field here +# and allowed the user to specify any fields below `spec` that were templated directly +# into the final Kibana manifest. This is no longer the preferred way to specify these +# fields and each field that is supported underneath `spec` is now directly specified +# in this values file. Currently both patterns are supported for backwards compatibility +# but we plan to remove the `spec` field in the future. +# spec: {} + +# Referenced resources are below and depending on the setup, at least one is required for a functional Agent. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-setting-referenced-resources +# +# Reference to ECK-managed Kibana instance. +# +# kibanaRef: +# name: quickstart + # Optional namespace reference to Kibana instance. + # If not specified, then the namespace of the Agent instance + # will be assumed. + # + # namespace: default + +# Reference to ECK-managed Elasticsearch instance. +# +elasticsearchRefs: +- name: eck-elasticsearch + # Optional namespace reference to Elasticsearch instance. + # If not specified, then the namespace of the Agent instance + # will be assumed. + # + # namespace: default + +# Reference to ECK-managed Fleet Server instance. +# +# fleetServerRef: +# name: eck-fleet-server + # Optional namespace reference to Fleet Server instance. + # If not specified, then the namespace of the Agent instance + # will be assumed. + # + # namespace: default + +# The Elastic Agent configuration, the ECK equivalent to agent.yml +# NOTE: The `config` and `configRef` fields are mutually exclusive. Only one of them should be defined at a time, +# as using both may cause conflicts. +# +# Configuration of Agent, specifically used in Agent standalone mode. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-configuration.html +# +config: null + +# Reference a configuration in a Secret. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-configuration.html +# +# configRef: +# secretName: "" + +# The mode of Agent to use. Only set to "fleet" when Fleet Server is enabled. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-fleet-mode-and-fleet-server +# +# mode: "fleet" + +# fleetServerEnabled determines whether the Agent will be run as the Fleet Server. +# +# NOTE: Both `mode: fleet` and `fleetServerEnabled: true` need to be set for Fleet Server to be enabled. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-fleet-mode-and-fleet-server +# +fleetServerEnabled: false + +# The HTTP layer configuration for the Fleet Server Service. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-customize-fleet-server-service +# +# http: + +# policyID determines into which Agent Policy this Agent will be enrolled. +# policyID: eck-agent + +# DaemonSet, StatefulSet, or Deployment specification for Agent. +# At least one is required of [daemonSet, deployment, statefulSet]. +# No default is currently set, refer to https://github.com/elastic/cloud-on-k8s/issues/7429. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-chose-the-deployment-model +# +# deployment: +# podTemplate: +# spec: +# containers: +# - name: agent +# securityContext: +# runAsUser: 0 +# daemonSet: +# podTemplate: +# spec: +# containers: +# - name: agent +# securityContext: +# runAsUser: 0 +# statefulSet: +# podTemplate: +# spec: +# containers: +# - name: agent +# securityContext: +# runAsUser: 0 + +# SecureSettings is a list of references to Kubernetes Secrets containing sensitive configuration options for Elastic Agent. +secureSettings: [] +# - secretName: my-secret-with-secure-settings + +# Number of revisions to retain to allow rollback in the underlying Deployment. +# If not set Kubernetes sets this to 10 by default. +# +# revisionHistoryLimit: 2 + +# ServiceAccount to be used by Elastic Agent. Some Elastic Agent features, such as the Kubernetes integration, +# require that Agent Pods interact with Kubernetes APIs. This functionality requires specific permissions +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-role-based-access-control +# +serviceAccount: + name: elastic-agent + # { .Release.Namespace } is used here by default, but can be specified. + # namespace: optional-namespace + +# ClusterRoleBinding to be used by Elastic Agent. Similar to ServiceAccount, this is required in some scenarios. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-role-based-access-control +# +clusterRoleBinding: + name: elastic-agent + subjects: + - kind: ServiceAccount + name: elastic-agent + # { .Release.Namespace } is used here by default, but can be specified. + # namespace: default + roleRef: + kind: ClusterRole + name: elastic-agent + apiGroup: rbac.authorization.k8s.io + +# ClusterRole to be used by Elastic Agent. Similar to ServiceAccount, this is required in some scenarios. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-role-based-access-control +# +clusterRole: + name: elastic-agent + rules: + - apiGroups: [""] + resources: + - pods + - nodes + - namespaces + - events + - services + - configmaps + verbs: + - get + - watch + - list + - apiGroups: ["coordination.k8s.io"] + resources: + - leases + verbs: + - get + - create + - update + - nonResourceURLs: + - "/metrics" + verbs: + - get + - apiGroups: ["extensions"] + resources: + - replicasets + verbs: + - "get" + - "list" + - "watch" + - apiGroups: + - "apps" + resources: + - statefulsets + - deployments + - replicasets + - daemonsets + verbs: + - "get" + - "list" + - "watch" + - apiGroups: + - "" + resources: + - nodes/stats + verbs: + - get + - nonResourceURLs: + - "/metrics" + verbs: + - get + - apiGroups: + - "batch" + resources: + - jobs + - cronjobs + verbs: + - "get" + - "list" + - "watch" + - apiGroups: + - "storage.k8s.io" + resources: + - storageclasses + verbs: + - "get" + - "list" + - "watch" diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/.helmignore b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/.helmignore new file mode 100644 index 00000000..f1568daf --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/Chart.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/Chart.yaml new file mode 100644 index 00000000..89294a37 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/Chart.yaml @@ -0,0 +1,10 @@ +apiVersion: v2 +description: Elastic APM Server managed by the ECK operator +icon: https://helm.elastic.co/icons/apm.png +kubeVersion: '>= 1.21.0-0' +name: eck-apm-server +sources: +- https://github.com/elastic/cloud-on-k8s +- https://github.com/elastic/apm-server +type: application +version: 0.16.0 diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/LICENSE b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/LICENSE new file mode 100644 index 00000000..92503a72 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/LICENSE @@ -0,0 +1,93 @@ +Elastic License 2.0 + +URL: https://www.elastic.co/licensing/elastic-license + +## Acceptance + +By using the software, you agree to all of the terms and conditions below. + +## Copyright License + +The licensor grants you a non-exclusive, royalty-free, worldwide, +non-sublicensable, non-transferable license to use, copy, distribute, make +available, and prepare derivative works of the software, in each case subject to +the limitations and conditions below. + +## Limitations + +You may not provide the software to third parties as a hosted or managed +service, where the service provides users with access to any substantial set of +the features or functionality of the software. + +You may not move, change, disable, or circumvent the license key functionality +in the software, and you may not remove or obscure any functionality in the +software that is protected by the license key. + +You may not alter, remove, or obscure any licensing, copyright, or other notices +of the licensor in the software. Any use of the licensor’s trademarks is subject +to applicable law. + +## Patents + +The licensor grants you a license, under any patent claims the licensor can +license, or becomes able to license, to make, have made, use, sell, offer for +sale, import and have imported the software, in each case subject to the +limitations and conditions in this license. This license does not cover any +patent claims that you cause to be infringed by modifications or additions to +the software. If you or your company make any written claim that the software +infringes or contributes to infringement of any patent, your patent license for +the software granted under these terms ends immediately. If your company makes +such a claim, your patent license ends immediately for work on behalf of your +company. + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you +also gets a copy of these terms. + +If you modify the software, you must include in any modified copies of the +software prominent notices stating that you have modified the software. + +## No Other Rights + +These terms do not imply any licenses other than those expressly granted in +these terms. + +## Termination + +If you use the software in violation of these terms, such use is not licensed, +and your licenses will automatically terminate. If the licensor provides you +with a notice of your violation, and you cease all violation of this license no +later than 30 days after you receive that notice, your licenses will be +reinstated retroactively. However, if you violate these terms after such +reinstatement, any additional violation of these terms will cause your licenses +to terminate automatically and permanently. + +## No Liability + +*As far as the law allows, the software comes as is, without any warranty or +condition, and the licensor will not be liable to you for any damages arising +out of these terms or the use or nature of the software, under any kind of +legal claim.* + +## Definitions + +The **licensor** is the entity offering these terms, and the **software** is the +software the licensor makes available under these terms, including any portion +of it. + +**you** refers to the individual or entity agreeing to these terms. + +**your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control over, +are under the control of, or are under common control with that +organization. **control** means ownership of substantially all the assets of an +entity, or the power to direct its management and policies by vote, contract, or +otherwise. Control can be direct or indirect. + +**your licenses** are all the licenses granted to you for the software under +these terms. + +**use** means anything you do with the software requiring one of your licenses. + +**trademark** means trademarks, service marks, and similar rights. \ No newline at end of file diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/examples/jaeger-with-http-configuration.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/examples/jaeger-with-http-configuration.yaml new file mode 100644 index 00000000..ba9251e1 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/examples/jaeger-with-http-configuration.yaml @@ -0,0 +1,29 @@ +--- +# Version of APM Server. +# +version: 9.1.0 + +# Count of APM Server replicas to create. +# +count: 1 + +config: + name: elastic-apm + apm-server.jaeger.grpc.enabled: true + apm-server.jaeger.grpc.host: "0.0.0.0:14250" + +# Reference to ECK-managed Elasticsearch resource. +# +elasticsearchRef: + name: eck-elasticsearch +http: + service: + spec: + ports: + - name: http + port: 8200 + targetPort: 8200 + - name: grpc + port: 14250 + targetPort: 14250 + diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/templates/NOTES.txt b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/templates/NOTES.txt new file mode 100644 index 00000000..42ab52cb --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/templates/NOTES.txt @@ -0,0 +1,6 @@ + +1. Check APM Server status + $ kubectl get apmserver {{ include "apm-server.fullname" . }} -n {{ .Release.Namespace }} + +2. Check APM Server pod status + $ kubectl get pods --namespace={{ .Release.Namespace }} -l apm.k8s.elastic.co/name={{ include "apm-server.fullname" . }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/templates/_helpers.tpl b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/templates/_helpers.tpl new file mode 100644 index 00000000..d06ca3f4 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "apm-server.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "apm-server.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "apm-server.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "apm-server.labels" -}} +helm.sh/chart: {{ include "apm-server.chart" . }} +{{ include "apm-server.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.labels }} +{{ toYaml .Values.labels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "apm-server.selectorLabels" -}} +app.kubernetes.io/name: {{ include "apm-server.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/templates/apmserver.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/templates/apmserver.yaml new file mode 100644 index 00000000..f3dd5ba9 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/templates/apmserver.yaml @@ -0,0 +1,53 @@ +--- +apiVersion: apm.k8s.elastic.co/v1 +kind: ApmServer +metadata: + name: {{ include "apm-server.fullname" . }} + labels: + {{- include "apm-server.labels" . | nindent 4 }} + annotations: + eck.k8s.elastic.co/license: basic + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + version: {{ required "An APM Server version is required" .Values.version }} + count: {{ required "A pod count is required" .Values.count }} + {{- with .Values.image }} + image: {{ . }} + {{- end }} + {{- with .Values.serviceAccountName }} + serviceAccountName: {{ . }} + {{- end }} + {{- with .Values.revisionHistoryLimit }} + revisionHistoryLimit: {{ . }} + {{- end }} + + {{- with .Values.config }} + config: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.http }} + http: + {{- toYaml . | nindent 4 }} + {{- end }} + + {{- with .Values.elasticsearchRef }} + elasticsearchRef: + {{- toYaml . | nindent 4 }} + {{- end }} + + {{- with .Values.kibanaRef }} + kibanaRef: + {{- toYaml . | nindent 4 }} + {{- end }} + + {{- with .Values.podTemplate }} + podTemplate: + {{- toYaml . | nindent 4 }} + {{- end }} + + {{- with .Values.secureSettings }} + secureSettings: + {{- toYaml . | nindent 2 }} + {{- end }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/values.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/values.yaml new file mode 100644 index 00000000..f9cca517 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-apm-server/values.yaml @@ -0,0 +1,97 @@ +--- +# Default values for eck-apm-server. +# This is a YAML-formatted file. + +# Overridable names of the APM Server resource. +# By default, this is the Release name set for the chart, +# followed by 'eck-apm-server'. +# +# nameOverride will override the name of the Chart with the name set here, +# so nameOverride: quickstart, would convert to '{{ Release.name }}-quickstart' +# +# nameOverride: "quickstart" +# +# fullnameOverride will override both the release name, and the chart name, +# and will name the APM Server resource exactly as specified. +# +# fullnameOverride: "quickstart" + +# Version of APM Server. +# +version: 9.1.0 + +# APM Server Docker image to deploy +# +# image: + +# Used to check access from the current resource to a resource (for ex. a remote Elasticsearch cluster) in a different namespace. +# Can only be used if ECK is enforcing RBAC on references. +# +# serviceAccountName: "" + +# Labels that will be applied to APM Server. +# +labels: {} + +# Annotations that will be applied to APM Server. +# +annotations: {} + +# Count of APM Server replicas to create. +# +count: 1 + +# The APM Server configuration, the ECK equivalent to apm-server.yml +# ref: https://www.elastic.co/guide/en/apm/server/current/configuring-howto-apm-server.html +# +config: {} + +# Settings to control how APM Server will be accessed. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-accessing-elastic-services.html +# +http: {} + # service: + # metadata: + # labels: + # my-custom: label + # spec: + # ports: + # - name: http + # port: 8200 + # targetPort: 8200 + +# Reference to ECK-managed Elasticsearch resource. +# +elasticsearchRef: {} + # name: eck-elasticsearch + # Optional namespace reference to Elasticsearch resource. + # If not specified, then the namespace of the APM Server resource + # will be assumed. + # + # namespace: default + +# Optional reference to ECK-managed Kibana resource which allows ECK to +# automatically configure the Kibana endpoint as described in +# https://www.elastic.co/guide/en/apm/server/current/setup-kibana-endpoint.html +# +# kibanaRef: +# name: eck-kibana +# # Optional namespace reference to Kibana resource. +# # If not specified, then the namespace of the APM Server resource +# # will be assumed. +# # +# # namespace: default + +# Set podTemplate to customize the pod used by APM Server +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-customize-pods.html +# +podTemplate: {} + +# Number of revisions to retain to allow rollback in the underlying Deployment. +# If not set Kubernetes sets this to 10 by default. +# +# revisionHistoryLimit: 2 + +# SecureSettings is a list of references to Kubernetes Secrets containing sensitive configuration options for APM Server. +secureSettings: [] +# - secretName: my-secret-with-secure-settings diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/.helmignore b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/.helmignore new file mode 100644 index 00000000..f1568daf --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/Chart.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/Chart.yaml new file mode 100644 index 00000000..cc0ac4f1 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/Chart.yaml @@ -0,0 +1,10 @@ +apiVersion: v2 +description: Elastic Beats managed by the ECK operator +icon: https://helm.elastic.co/icons/beats.png +kubeVersion: '>= 1.20.0-0' +name: eck-beats +sources: +- https://github.com/elastic/cloud-on-k8s +- https://github.com/elastic/beats +type: application +version: 0.16.0 diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/LICENSE b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/LICENSE new file mode 100644 index 00000000..92503a72 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/LICENSE @@ -0,0 +1,93 @@ +Elastic License 2.0 + +URL: https://www.elastic.co/licensing/elastic-license + +## Acceptance + +By using the software, you agree to all of the terms and conditions below. + +## Copyright License + +The licensor grants you a non-exclusive, royalty-free, worldwide, +non-sublicensable, non-transferable license to use, copy, distribute, make +available, and prepare derivative works of the software, in each case subject to +the limitations and conditions below. + +## Limitations + +You may not provide the software to third parties as a hosted or managed +service, where the service provides users with access to any substantial set of +the features or functionality of the software. + +You may not move, change, disable, or circumvent the license key functionality +in the software, and you may not remove or obscure any functionality in the +software that is protected by the license key. + +You may not alter, remove, or obscure any licensing, copyright, or other notices +of the licensor in the software. Any use of the licensor’s trademarks is subject +to applicable law. + +## Patents + +The licensor grants you a license, under any patent claims the licensor can +license, or becomes able to license, to make, have made, use, sell, offer for +sale, import and have imported the software, in each case subject to the +limitations and conditions in this license. This license does not cover any +patent claims that you cause to be infringed by modifications or additions to +the software. If you or your company make any written claim that the software +infringes or contributes to infringement of any patent, your patent license for +the software granted under these terms ends immediately. If your company makes +such a claim, your patent license ends immediately for work on behalf of your +company. + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you +also gets a copy of these terms. + +If you modify the software, you must include in any modified copies of the +software prominent notices stating that you have modified the software. + +## No Other Rights + +These terms do not imply any licenses other than those expressly granted in +these terms. + +## Termination + +If you use the software in violation of these terms, such use is not licensed, +and your licenses will automatically terminate. If the licensor provides you +with a notice of your violation, and you cease all violation of this license no +later than 30 days after you receive that notice, your licenses will be +reinstated retroactively. However, if you violate these terms after such +reinstatement, any additional violation of these terms will cause your licenses +to terminate automatically and permanently. + +## No Liability + +*As far as the law allows, the software comes as is, without any warranty or +condition, and the licensor will not be liable to you for any damages arising +out of these terms or the use or nature of the software, under any kind of +legal claim.* + +## Definitions + +The **licensor** is the entity offering these terms, and the **software** is the +software the licensor makes available under these terms, including any portion +of it. + +**you** refers to the individual or entity agreeing to these terms. + +**your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control over, +are under the control of, or are under common control with that +organization. **control** means ownership of substantially all the assets of an +entity, or the power to direct its management and policies by vote, contract, or +otherwise. Control can be direct or indirect. + +**your licenses** are all the licenses granted to you for the software under +these terms. + +**use** means anything you do with the software requiring one of your licenses. + +**trademark** means trademarks, service marks, and similar rights. \ No newline at end of file diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/examples/auditbeat_hosts.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/examples/auditbeat_hosts.yaml new file mode 100644 index 00000000..2f23fa8c --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/examples/auditbeat_hosts.yaml @@ -0,0 +1,110 @@ +name: auditbeat +version: 9.1.0 +type: auditbeat +elasticsearchRef: + name: eck-elasticsearch +kibanaRef: + name: eck-kibana +config: + auditbeat.modules: + - module: file_integrity + paths: + - /hostfs/bin + - /hostfs/usr/bin + - /hostfs/sbin + - /hostfs/usr/sbin + - /hostfs/etc + exclude_files: + - '(?i)\.sw[nop]$' + - '~$' + - '/\.git($|/)' + scan_at_start: true + scan_rate_per_sec: 50 MiB + max_file_size: 100 MiB + hash_types: [sha1] + recursive: true + - module: auditd + audit_rules: | + # Executions + -a always,exit -F arch=b64 -S execve,execveat -k exec + + # Unauthorized access attempts (amd64 only) + -a always,exit -F arch=b64 -S open,creat,truncate,ftruncate,openat,open_by_handle_at -F exit=-EACCES -k access + -a always,exit -F arch=b64 -S open,creat,truncate,ftruncate,openat,open_by_handle_at -F exit=-EPERM -k access + + processors: + - add_cloud_metadata: {} + - add_host_metadata: {} + - add_process_metadata: + match_pids: ['process.pid'] +daemonSet: + podTemplate: + spec: + hostPID: true # Required by auditd module + dnsPolicy: ClusterFirstWithHostNet + hostNetwork: true # Allows to provide richer host metadata + automountServiceAccountToken: true # some older Beat versions are depending on this settings presence in k8s context + securityContext: + runAsUser: 0 + volumes: + - name: bin + hostPath: + path: /bin + - name: usrbin + hostPath: + path: /usr/bin + - name: sbin + hostPath: + path: /sbin + - name: usrsbin + hostPath: + path: /usr/sbin + - name: etc + hostPath: + path: /etc + - name: run-containerd + hostPath: + path: /run/containerd + type: DirectoryOrCreate + # Uncomment the below when running on GKE. See https://github.com/elastic/beats/issues/8523 for more context. + #- name: run + # hostPath: + # path: /run + #initContainers: + #- name: cos-init + # image: docker.elastic.co/beats/auditbeat:8.3.3 + # volumeMounts: + # - name: run + # mountPath: /run + # command: ['sh', '-c', 'export SYSTEMD_IGNORE_CHROOT=1 && systemctl stop systemd-journald-audit.socket && systemctl mask systemd-journald-audit.socket && systemctl restart systemd-journald'] + containers: + - name: auditbeat + securityContext: + capabilities: + add: + # Capabilities needed for auditd module + - 'AUDIT_READ' + - 'AUDIT_WRITE' + - 'AUDIT_CONTROL' + volumeMounts: + - name: bin + mountPath: /hostfs/bin + readOnly: true + - name: sbin + mountPath: /hostfs/sbin + readOnly: true + - name: usrbin + mountPath: /hostfs/usr/bin + readOnly: true + - name: usrsbin + mountPath: /hostfs/usr/sbin + readOnly: true + - name: etc + mountPath: /hostfs/etc + readOnly: true + # Directory with root filesystems of containers executed with containerd, this can be + # different with other runtimes. This volume is needed to monitor the file integrity + # of files in containers. + - name: run-containerd + mountPath: /run/containerd + readOnly: true diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/examples/filebeat_no_autodiscover.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/examples/filebeat_no_autodiscover.yaml new file mode 100644 index 00000000..fc1b339b --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/examples/filebeat_no_autodiscover.yaml @@ -0,0 +1,52 @@ +name: filebeat +version: 9.1.0 +type: filebeat +elasticsearchRef: + name: eck-elasticsearch +kibanaRef: + name: eck-kibana +config: + filebeat.inputs: + - type: filestream + paths: + - /var/log/containers/*.log + parsers: + - container: ~ + prospector: + scanner: + fingerprint.enabled: true + symlinks: true + file_identity.fingerprint: ~ + processors: + - add_host_metadata: {} + - add_cloud_metadata: {} +daemonSet: + podTemplate: + spec: + automountServiceAccountToken: true + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirstWithHostNet + hostNetwork: true # Allows to provide richer host metadata + containers: + - name: filebeat + securityContext: + runAsUser: 0 + # If using Red Hat OpenShift uncomment this: + #privileged: true + volumeMounts: + - name: varlogcontainers + mountPath: /var/log/containers + - name: varlogpods + mountPath: /var/log/pods + - name: varlibdockercontainers + mountPath: /var/lib/docker/containers + volumes: + - name: varlogcontainers + hostPath: + path: /var/log/containers + - name: varlogpods + hostPath: + path: /var/log/pods + - name: varlibdockercontainers + hostPath: + path: /var/lib/docker/containers diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/examples/heartbeat_es_kb_health.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/examples/heartbeat_es_kb_health.yaml new file mode 100644 index 00000000..09753e98 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/examples/heartbeat_es_kb_health.yaml @@ -0,0 +1,23 @@ +name: heartbeat +version: 9.1.0 +type: heartbeat +elasticsearchRef: + name: eck-elasticsearch +config: + heartbeat.monitors: + - type: tcp + schedule: '@every 5s' + # This should directly match the name of the Elasticsearch instance + # with "-es-http" appended to the name. + hosts: ["elasticsearch-es-http.default.svc:9200"] + - type: tcp + schedule: '@every 5s' + # This should directly match the names of the Kibana instance + # with "-kb-http" appended to the name. + hosts: ["eck-kibana-kb-http.default.svc:5601"] +deployment: + replicas: 1 + podTemplate: + spec: + securityContext: + runAsUser: 0 diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/examples/metricbeat_hosts.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/examples/metricbeat_hosts.yaml new file mode 100644 index 00000000..7b0f6897 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/examples/metricbeat_hosts.yaml @@ -0,0 +1,158 @@ +name: metricbeat +type: metricbeat +version: 9.1.0 +elasticsearchRef: + name: eck-elasticsearch +kibanaRef: + name: eck-kibana +config: + metricbeat: + autodiscover: + providers: + - hints: + default_config: {} + enabled: "true" + node: ${NODE_NAME} + type: kubernetes + modules: + - module: system + period: 10s + metricsets: + - cpu + - load + - memory + - network + - process + - process_summary + process: + include_top_n: + by_cpu: 5 + by_memory: 5 + processes: + - .* + - module: system + period: 1m + metricsets: + - filesystem + - fsstat + processors: + - drop_event: + when: + regexp: + system: + filesystem: + mount_point: ^/(sys|cgroup|proc|dev|etc|host|lib)($|/) + - module: kubernetes + period: 10s + node: ${NODE_NAME} + hosts: + - https://${NODE_NAME}:10250 + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + ssl: + verification_mode: none + metricsets: + - node + - system + - pod + - container + - volume + processors: + - add_cloud_metadata: {} + - add_host_metadata: {} +daemonSet: + podTemplate: + spec: + serviceAccountName: metricbeat + automountServiceAccountToken: true # some older Beat versions are depending on this settings presence in k8s context + containers: + - args: + - -e + - -c + - /etc/beat.yml + - --system.hostfs=/hostfs + name: metricbeat + volumeMounts: + - mountPath: /hostfs/sys/fs/cgroup + name: cgroup + - mountPath: /var/run/docker.sock + name: dockersock + - mountPath: /hostfs/proc + name: proc + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + dnsPolicy: ClusterFirstWithHostNet + hostNetwork: true # Allows to provide richer host metadata + securityContext: + runAsUser: 0 + terminationGracePeriodSeconds: 30 + volumes: + - hostPath: + path: /sys/fs/cgroup + name: cgroup + - hostPath: + path: /var/run/docker.sock + name: dockersock + - hostPath: + path: /proc + name: proc + +clusterRole: + # permissions needed for metricbeat + # source: https://www.elastic.co/guide/en/beats/metricbeat/current/metricbeat-module-kubernetes.html + name: metricbeat + rules: + - apiGroups: + - "" + resources: + - nodes + - namespaces + - events + - pods + verbs: + - get + - list + - watch + - apiGroups: + - "extensions" + resources: + - replicasets + verbs: + - get + - list + - watch + - apiGroups: + - apps + resources: + - statefulsets + - deployments + - replicasets + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - nodes/stats + verbs: + - get + - nonResourceURLs: + - /metrics + verbs: + - get + +serviceAccount: + name: metricbeat + +clusterRoleBinding: + name: metricbeat + subjects: + - kind: ServiceAccount + name: metricbeat + roleRef: + kind: ClusterRole + name: metricbeat + apiGroup: rbac.authorization.k8s.io diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/examples/packetbeat_dns_http.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/examples/packetbeat_dns_http.yaml new file mode 100644 index 00000000..a1af23f9 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/examples/packetbeat_dns_http.yaml @@ -0,0 +1,37 @@ +name: packetbeat +type: packetbeat +version: 9.1.0 +elasticsearchRef: + name: eck-elasticsearch +kibanaRef: + name: eck-kibana +config: + packetbeat.interfaces.device: any + packetbeat.protocols: + - type: dns + ports: [53] + include_authorities: true + include_additionals: true + - type: http + ports: [80, 8000, 8080, 9200] + packetbeat.flows: + timeout: 30s + period: 10s + processors: + - add_cloud_metadata: {} + - add_host_metadata: {} +daemonSet: + podTemplate: + spec: + terminationGracePeriodSeconds: 30 + hostNetwork: true + automountServiceAccountToken: true # some older Beat versions are depending on this settings presence in k8s context + dnsPolicy: ClusterFirstWithHostNet + containers: + - name: packetbeat + securityContext: + runAsUser: 0 + capabilities: + add: + - NET_ADMIN + volumes: [] diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/templates/NOTES.txt b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/templates/NOTES.txt new file mode 100644 index 00000000..10d2dac5 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/templates/NOTES.txt @@ -0,0 +1,6 @@ + +1. Check Beat status + $ kubectl get beat {{ include "beat.fullname" . }} -n {{ .Release.Namespace }} + +2. Check Beat pod status + $ kubectl get pods --namespace={{ .Release.Namespace }} -l beat.k8s.elastic.co/name={{ include "beat.fullname" . }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/templates/_helpers.tpl b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/templates/_helpers.tpl new file mode 100644 index 00000000..5e20af14 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "beat.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "beat.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "beat.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "beat.labels" -}} +helm.sh/chart: {{ include "beat.chart" . }} +{{ include "beat.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.labels }} +{{ toYaml .Values.labels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "beat.selectorLabels" -}} +app.kubernetes.io/name: {{ include "beat.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/templates/beats.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/templates/beats.yaml new file mode 100644 index 00000000..a70ac9a6 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/templates/beats.yaml @@ -0,0 +1,75 @@ +--- +apiVersion: beat.k8s.elastic.co/v1beta1 +kind: Beat +metadata: + name: {{ include "beat.fullname" . }} + labels: + {{- include "beat.labels" . | nindent 4 }} + annotations: + eck.k8s.elastic.co/license: basic + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + version: {{ required "A Beat version is required" (or ((.Values.spec).version) (.Values.version)) }} + {{- $daemonSet := (or (hasKey (.Values.spec) "daemonSet") (hasKey .Values "daemonSet")) }} + {{- $deployment := (or (hasKey (.Values.spec) "deployment") (hasKey .Values "deployment")) }} + {{- if and (not $daemonSet) (not $deployment) }} + {{ fail "At least one of daemonSet or deployment is required for a functional Beat" }} + {{- end }} + {{- if not (or ((.Values.spec).type) (.Values.type)) }}{{ fail "A Beat type is required" }}{{- end }} + type: {{ or ((.Values.spec).type) (.Values.type) }} + {{- if $daemonSet }} + {{- $ds := or ((.Values.spec).daemonSet) (.Values.daemonSet) }} + daemonSet: + {{- /* This is required to render the empty daemonset ( {} ) properly */}} + {{- $ds | default dict | toYaml | nindent 4 }} + {{- end }} + {{- if $deployment }} + {{- $deploy := or ((.Values.spec).deployment) (.Values.deployment) }} + deployment: + {{- /* This is required to render the empty deployment ( {} ) properly */}} + {{- $deploy | default dict | toYaml | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).image) (.Values.image) }} + image: {{ . }} + {{- end }} + {{- with or ((.Values.spec).elasticsearchRef) (.Values.elasticsearchRef) }} + elasticsearchRef: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).kibanaRef) (.Values.kibanaRef) }} + kibanaRef: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- $config := or ((.Values.spec).config) (.Values.config) }} + {{- $configRef := or ((.Values.spec).configRef) (.Values.configRef) }} + {{- if and $config $configRef }} + {{ fail "Only one of config and configRef can be specified" }} + {{- end }} + {{- with $config }} + config: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $configRef }} + configRef: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).http) (.Values.http) }} + http: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).monitoring) (.Values.monitoring) }} + monitoring: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).secureSettings) (.Values.secureSettings) }} + secureSettings: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).revisionHistoryLimit) (.Values.revisionHistoryLimit) }} + revisionHistoryLimit: {{ . }} + {{- end }} + {{- with or (((.Values.spec).serviceAccount).name) ((.Values.serviceAccount).name) }} + serviceAccountName: {{ . }} + {{- end }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/templates/cluster-role-binding.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/templates/cluster-role-binding.yaml new file mode 100644 index 00000000..d8fca15f --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/templates/cluster-role-binding.yaml @@ -0,0 +1,35 @@ +{{- with .Values.clusterRoleBinding }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .name }} + labels: + {{- include "beat.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or $.Values.annotations .annotations }} + annotations: + {{- with $.Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +{{- with .subjects }} +subjects: +{{- range . }} + - kind: {{ .kind }} + name: {{ .name }} + namespace: {{ .namespace | default $.Release.Namespace | quote }} +{{- end }} +{{- end }} +{{- with .roleRef }} +roleRef: + kind: {{ .kind }} + name: {{ .name }} + apiGroup: {{ .apiGroup }} +{{- end }} +{{- end }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/templates/cluster-role.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/templates/cluster-role.yaml new file mode 100644 index 00000000..66406f63 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/templates/cluster-role.yaml @@ -0,0 +1,22 @@ +{{- with .Values.clusterRole }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ .name }} + labels: + {{- include "beat.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or $.Values.annotations .annotations }} + annotations: + {{- with $.Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +rules: {{- toYaml .rules | nindent 2 }} +{{- end }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/templates/service-account.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/templates/service-account.yaml new file mode 100644 index 00000000..08f21f7e --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/templates/service-account.yaml @@ -0,0 +1,23 @@ + +{{- with .Values.serviceAccount }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .name }} + namespace: {{ .namespace | default $.Release.Namespace | quote }} + labels: + {{- include "beat.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or $.Values.annotations .annotations }} + annotations: + {{- with $.Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/values.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/values.yaml new file mode 100644 index 00000000..49b055c6 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-beats/values.yaml @@ -0,0 +1,169 @@ +--- +# Default values for eck-beats. +# This is a YAML-formatted file. + +# Overridable names of the Beats resource. +# By default, this is the Release name set for the chart, +# followed by 'eck-beats'. +# +# nameOverride will override the name of the Chart with the name set here, +# so nameOverride: quickstart, would convert to '{{ Release.name }}-quickstart' +# +# nameOverride: "quickstart" +# +# fullnameOverride will override both the release name, and the chart name, +# and will name the Beats resource exactly as specified. +# +# fullnameOverride: "quickstart" + +# Version of Elastic Beats. +# +version: 9.1.0 + +# Labels that will be applied to Elastic Beats. +# +labels: {} + +# Annotations that will be applied to Elastic Beats. +# +annotations: {} + +# ** Deprecation Notice ** +# The previous versions of this Helm Chart simply used the `spec` field here +# and allowed the user to specify any fields below spec that were templated directly +# into the final Beats manifest. This is no longer the preferred way to specify these +# fields and each field that is supported underneath `spec` is now directly specified +# in this values file. Currently both patterns are supported for backwards compatibility +# but we plan to remove the `spec` field in the future. +# spec: {} + +# Type of Elastic Beats. Standard types of Beat are [filebeat,metricbeat,heartbeat,auditbeat,packetbeat,journalbeat]. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-beat-configuration.html#k8s-beat-deploy-elastic-beat +# +# Note: This is required to be set, or the release install will fail. +# +type: "" + +# Beats image to deploy. +# +# image: docker.elastic.co/beats/metricbeat:9.1.0 + +# Referenced resources are below and depending on the setup, at least elasticsearchRef is required for a functional Beat. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-beat-configuration.html#k8s-beat-connect-es +# +# Reference to ECK-managed Kibana instance. +# +# kibanaRef: +# name: quickstart + # Optional namespace reference to Kibana instance. + # If not specified, then the namespace of the Beats instance + # will be assumed. + # + # namespace: default + +# Reference to ECK-managed Elasticsearch instance. +# *Note* If Beat's output is intended to go to Elasticsearch and not something like Logstash, +# this elasticsearchRef must be updated to the name of the Elasticsearch instance. +# +elasticsearchRef: {} + # name: elasticsearch + # Optional namespace reference to Elasticsearch instance. + # If not specified, then the namespace of the Beats instance + # will be assumed. + # + # namespace: default + +# Daemonset, or Deployment specification for the type of Beat specified. +# At least one is required of [daemonSet, deployment]. +# No default is currently set, refer to https://github.com/elastic/cloud-on-k8s/issues/7429. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-beat-configuration.html#k8s-beat-chose-the-deployment-model +# +# deployment: +# podTemplate: +# spec: +# securityContext: +# runAsUser: 0 +# daemonSet: +# podTemplate: +# spec: +# securityContext: +# runAsUser: 0 + +# Configuration of Beat, which is dependent on the `type` of Beat specified. +# NOTE: The `config` and `configRef` fields are mutually exclusive. Only one of them should be defined at a time, +# as using both may cause conflicts. +# +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-beat-configuration.html#k8s-beat-custom-configuration +# +config: {} + +# Reference a configuration in a Secret. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-beat-configuration.html#k8s-beat-custom-configuration +# +# configRef: +# secretName: "" + +# The HTTP layer configuration for the Beats Service. +# +# http: + +# Settings for configuring stack monitoring. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-stack-monitoring.html +# +# monitoring: {} + # metrics: + # elasticsearchRefs: + # - name: monitoring + # namespace: observability + # logs: + # elasticsearchRefs: + # - name: monitoring + # namespace: observability + +# SecureSettings is a list of references to Kubernetes Secrets containing sensitive configuration options for Elastic Beats. +secureSettings: [] +# - secretName: my-secret-with-secure-settings + +# Number of revisions to retain to allow rollback in the underlying Deployment. +# If not set Kubernetes sets this to 10 by default. +# +# revisionHistoryLimit: 2 + +# ServiceAccount to be used by Elastic Beats. Some Beats features (such as autodiscover or Kubernetes module metricsets) +# require that Beat Pods interact with Kubernetes APIs. This functionality requires specific permissions +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-beat-configuration.html#k8s-beat-role-based-access-control-for-beats +# +serviceAccount: {} +# name: elastic-beat-filebeat-quickstart +# namespace: optional-namespace + +# ClusterRoleBinding to be used by Elastic Beats. Similar to ServiceAccount, this is required in some scenarios. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-beat-configuration.html#k8s-beat-role-based-access-control-for-beats +# +clusterRoleBinding: {} +# name: elastic-beat-autodiscover-binding +# subjects: +# - kind: ServiceAccount +# name: elastic-beat-filebeat-quickstart +# namespace: default +# roleRef: +# kind: ClusterRole +# name: elastic-beat-autodiscover +# apiGroup: rbac.authorization.k8s.io + +# ClusterRole to be used by Elastic Beats. Similar to ServiceAccount, this is required in some scenarios. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-beat-configuration.html#k8s-beat-role-based-access-control-for-beats +# +clusterRole: {} +# name: elastic-beat-autodiscover +# rules: +# - apiGroups: [""] +# resources: +# - events +# - pods +# - namespaces +# - nodes +# verbs: +# - get +# - watch +# - list diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/.helmignore b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/.helmignore new file mode 100644 index 00000000..f1568daf --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/Chart.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/Chart.yaml new file mode 100644 index 00000000..594d487e --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/Chart.yaml @@ -0,0 +1,10 @@ +apiVersion: v2 +description: Elasticsearch managed by the ECK operator +icon: https://helm.elastic.co/icons/elasticsearch.png +kubeVersion: '>= 1.21.0-0' +name: eck-elasticsearch +sources: +- https://github.com/elastic/cloud-on-k8s +- https://github.com/elastic/elasticsearch/ +type: application +version: 0.16.0 diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/LICENSE b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/LICENSE new file mode 100644 index 00000000..92503a72 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/LICENSE @@ -0,0 +1,93 @@ +Elastic License 2.0 + +URL: https://www.elastic.co/licensing/elastic-license + +## Acceptance + +By using the software, you agree to all of the terms and conditions below. + +## Copyright License + +The licensor grants you a non-exclusive, royalty-free, worldwide, +non-sublicensable, non-transferable license to use, copy, distribute, make +available, and prepare derivative works of the software, in each case subject to +the limitations and conditions below. + +## Limitations + +You may not provide the software to third parties as a hosted or managed +service, where the service provides users with access to any substantial set of +the features or functionality of the software. + +You may not move, change, disable, or circumvent the license key functionality +in the software, and you may not remove or obscure any functionality in the +software that is protected by the license key. + +You may not alter, remove, or obscure any licensing, copyright, or other notices +of the licensor in the software. Any use of the licensor’s trademarks is subject +to applicable law. + +## Patents + +The licensor grants you a license, under any patent claims the licensor can +license, or becomes able to license, to make, have made, use, sell, offer for +sale, import and have imported the software, in each case subject to the +limitations and conditions in this license. This license does not cover any +patent claims that you cause to be infringed by modifications or additions to +the software. If you or your company make any written claim that the software +infringes or contributes to infringement of any patent, your patent license for +the software granted under these terms ends immediately. If your company makes +such a claim, your patent license ends immediately for work on behalf of your +company. + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you +also gets a copy of these terms. + +If you modify the software, you must include in any modified copies of the +software prominent notices stating that you have modified the software. + +## No Other Rights + +These terms do not imply any licenses other than those expressly granted in +these terms. + +## Termination + +If you use the software in violation of these terms, such use is not licensed, +and your licenses will automatically terminate. If the licensor provides you +with a notice of your violation, and you cease all violation of this license no +later than 30 days after you receive that notice, your licenses will be +reinstated retroactively. However, if you violate these terms after such +reinstatement, any additional violation of these terms will cause your licenses +to terminate automatically and permanently. + +## No Liability + +*As far as the law allows, the software comes as is, without any warranty or +condition, and the licensor will not be liable to you for any damages arising +out of these terms or the use or nature of the software, under any kind of +legal claim.* + +## Definitions + +The **licensor** is the entity offering these terms, and the **software** is the +software the licensor makes available under these terms, including any portion +of it. + +**you** refers to the individual or entity agreeing to these terms. + +**your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control over, +are under the control of, or are under common control with that +organization. **control** means ownership of substantially all the assets of an +entity, or the power to direct its management and policies by vote, contract, or +otherwise. Control can be direct or indirect. + +**your licenses** are all the licenses granted to you for the software under +these terms. + +**use** means anything you do with the software requiring one of your licenses. + +**trademark** means trademarks, service marks, and similar rights. \ No newline at end of file diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/examples/hot-warm-cold.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/examples/hot-warm-cold.yaml new file mode 100644 index 00000000..4eb99e60 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/examples/hot-warm-cold.yaml @@ -0,0 +1,198 @@ +--- +nodeSets: +- name: masters + count: 1 + config: + node.roles: ["master"] + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + spec: + containers: + - name: elasticsearch + resources: + limits: + memory: 8Gi + cpu: 2 + # Affinity/Anti-affinity settings for controlling the 'spreading' of Elasticsearch + # pods across existing hosts. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html#k8s-affinity-options + # + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: beta.kubernetes.io/instance-type + # operator: In + # # This should be adjusted to the instance type according to your setup + # # + # values: + # - highio + # Volume Claim settings. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-volume-claim-templates.html + # + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Ti + # Adjust to your storage class name + # + # storageClassName: local-storage +- name: hot + count: 1 + config: + node.roles: ["data_hot", "data_content", "ingest"] + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + spec: + containers: + - name: elasticsearch + resources: + limits: + memory: 16Gi + cpu: 4 + # Affinity/Anti-affinity settings for controlling the 'spreading' of Elasticsearch + # pods across existing hosts. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html#k8s-affinity-options + # + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: beta.kubernetes.io/instance-type + # operator: In + # # This should be adjusted to the instance type according to your setup + # # + # values: + # - highio + # Volume Claim settings. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-volume-claim-templates.html + # + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Ti + # Adjust to your storage class name + # + # storageClassName: local-storage +- name: warm + count: 1 + config: + node.roles: ["data_warm"] + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + spec: + containers: + - name: elasticsearch + resources: + limits: + memory: 16Gi + cpu: 2 + # Affinity/Anti-affinity settings for controlling the 'spreading' of Elasticsearch + # pods across existing hosts. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html#k8s-affinity-options + # + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: beta.kubernetes.io/instance-type + # operator: In + # # This should be adjusted to the instance type according to your setup + # # + # values: + # - highstorage + # Volume Claim settings. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-volume-claim-templates.html + # + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Ti + # Adjust to your storage class name + # + # storageClassName: local-storage +- name: cold + count: 1 + config: + node.roles: ["data_cold"] + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + spec: + containers: + - name: elasticsearch + resources: + limits: + memory: 8Gi + cpu: 2 + # Affinity/Anti-affinity settings for controlling the 'spreading' of Elasticsearch + # pods across existing hosts. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html#k8s-affinity-options + # + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: beta.kubernetes.io/instance-type + # operator: In + # # This should be adjusted to the instance type according to your setup + # # + # values: + # - highstorage + # Volume Claim settings. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-volume-claim-templates.html + # + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 20Ti + # Adjust to your storage class name + # + # storageClassName: local-storage diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-aks.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-aks.yaml new file mode 100644 index 00000000..0ca310c3 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-aks.yaml @@ -0,0 +1,26 @@ +--- +# The following is an example of an Elasticsearch resource that is configured to use an Ingress resource in an AKS cluster. +# +ingress: + enabled: true + className: webapprouting.kubernetes.azure.com + annotations: + # This is required for AKS Loadbalancing to understand that it's communicating with + # an HTTPS backend. + nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" + labels: + my: label + pathType: Prefix + hosts: + - host: "elasticsearch.company.dev" + path: "/" +nodeSets: +- name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-eks-alb.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-eks-alb.yaml new file mode 100644 index 00000000..d3cc4041 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-eks-alb.yaml @@ -0,0 +1,37 @@ +--- +# The following is an example of an Elasticsearch resource that is configured to use an Ingress resource in an EKS cluster +# which provisions an application load balancer. +# +ingress: + enabled: true + className: alb + annotations: + alb.ingress.kubernetes.io/scheme: "internet-facing" + alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]' + alb.ingress.kubernetes.io/backend-protocol: "HTTPS" + alb.ingress.kubernetes.io/target-type: "ip" + # To use an ALB with ECK, you must provide a valid ACM certificate ARN or use certificate discovery. + # There are 2 options for EKS: + # 1. Create a valid ACM certificate, and uncomment the following annotation and update it to the correct ARN. + # 2. Create a valid ACM certificate and ensure that the hosts[0].host matches the certificate's Common Name (CN) and + # certificate discovery *should* find the certificate automatically and use it. + # + # ref: https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.8/guide/ingress/cert_discovery/ + # + # alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:us-east-1:00000000000:certificate/b65be571-8220-4f2e-8cb1-94194535d877" + labels: + my: label + pathType: Prefix + hosts: + - host: "elasticsearch.company.dev" + path: "/" +nodeSets: +- name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-eks-nlb.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-eks-nlb.yaml new file mode 100644 index 00000000..3809e871 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-eks-nlb.yaml @@ -0,0 +1,27 @@ +--- +# The following is an example of an Elasticsearch resource that is configured to deploy a +# network load balancer (NLB) in an EKS cluster. To provision an NLB "ingress" for the +# Elasticsearch cluster, you are required to set annotations on the service, +# and not an Ingress resource. +ingress: + enabled: false +http: + service: + metadata: + annotations: + service.beta.kubernetes.io/aws-load-balancer-type: external + service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip + service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing + service.beta.kubernetes.io/aws-load-balancer-backend-protocol: ssl + spec: + type: LoadBalancer +nodeSets: +- name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-gke.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-gke.yaml new file mode 100644 index 00000000..3adbd29c --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-gke.yaml @@ -0,0 +1,36 @@ +--- +# The following is an example of an Elasticsearch resource that is configured to use an Ingress resource in a GKE cluster. +# +ingress: + enabled: true + annotations: + my: annotation + labels: + my: label + pathType: Prefix + hosts: + - host: "elasticsearch.company.dev" + path: "/" +http: + service: + metadata: + annotations: + # This is required for `ClusterIP` services (which are the default ECK service type) to be used with Ingress in GKE clusters. + cloud.google.com/neg: '{"ingress": true}' + # This is required to enable the GKE Ingress Controller to use HTTPS as the backend protocol. + cloud.google.com/app-protocols: '{"https":"HTTPS"}' +nodeSets: +- name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false + # Enable anonymous access to allow GCLB health probes to succeed + xpack.security.authc: + anonymous: + username: anon + roles: monitoring_user diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/templates/NOTES.txt b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/templates/NOTES.txt new file mode 100644 index 00000000..f6ab0020 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/templates/NOTES.txt @@ -0,0 +1,6 @@ + +1. Check Elasticsearch resource status + $ kubectl get es {{ include "elasticsearch.fullname" . }} -n {{ .Release.Namespace }} + +2. Check Elasticsearch pod status + $ kubectl get pods --namespace={{ .Release.Namespace }} -l elasticsearch.k8s.elastic.co/cluster-name={{ include "elasticsearch.fullname" . }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/templates/_helpers.tpl b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/templates/_helpers.tpl new file mode 100644 index 00000000..8fbf57b3 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "elasticsearch.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "elasticsearch.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "elasticsearch.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "elasticsearch.labels" -}} +helm.sh/chart: {{ include "elasticsearch.chart" . }} +{{ include "elasticsearch.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.labels }} +{{ toYaml .Values.labels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "elasticsearch.selectorLabels" -}} +app.kubernetes.io/name: {{ include "elasticsearch.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/templates/elasticsearch.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/templates/elasticsearch.yaml new file mode 100644 index 00000000..4a4d7465 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/templates/elasticsearch.yaml @@ -0,0 +1,78 @@ +--- +apiVersion: elasticsearch.k8s.elastic.co/v1 +kind: Elasticsearch +metadata: + name: {{ include "elasticsearch.fullname" . }} + labels: + {{- include "elasticsearch.labels" . | nindent 4 }} + annotations: + eck.k8s.elastic.co/license: basic + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .Values.auth }} + auth: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.updateStrategy }} + updateStrategy: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.secureSettings }} + secureSettings: + {{- toYaml . | nindent 2 }} + {{- end }} + {{- with .Values.transport }} + transport: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.http }} + http: + {{- toYaml . | nindent 4 }} + {{- end }} + version: {{ required "An Elasticsearch version is required" .Values.version }} + {{- with .Values.monitoring }} + monitoring: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.remoteClusters }} + remoteClusters: + {{- toYaml . | nindent 2 }} + {{- end }} + {{- with .Values.remoteClusterServer }} + remoteClusterServer: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.volumeClaimDeletePolicy }} + volumeClaimDeletePolicy: + {{- if and (not (eq . "DeleteOnScaledownOnly")) (not (eq . "DeleteOnScaledownAndClusterDeletion")) }} + {{ fail "volumeClaimDeletePolicy can only be one of 'DeleteOnScaledownOnly' or 'DeleteOnScaledownAndClusterDeletion'" }} + {{- end }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if eq (len .Values.nodeSets) 0 }} + {{ fail "At least one nodeSet is required" }} + {{- end }} + nodeSets: + {{ toYaml .Values.nodeSets | nindent 4 }} + {{- with .Values.image }} + image: {{ . }} + {{- end }} + {{- with .Values.podDisruptionBudget }} + {{- if .disabled }} + podDisruptionBudget: {} + {{- else }} + {{- with .spec }} + podDisruptionBudget: + spec: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- end }} + {{- end }} + {{- with .Values.serviceAccountName }} + serviceAccountName: {{ . }} + {{- end }} + {{- with .Values.revisionHistoryLimit }} + revisionHistoryLimit: {{ . }} + {{- end }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/templates/ingress.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/templates/ingress.yaml new file mode 100644 index 00000000..99aa1813 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/templates/ingress.yaml @@ -0,0 +1,48 @@ +{{- if .Values.ingress.enabled -}} +{{- $pathType := .Values.ingress.pathType | default "Prefix" -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "elasticsearch.fullname" . }} + labels: + {{- include "elasticsearch.labels" . | nindent 4 }} + {{- with .Values.ingress.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.ingress.annotations }} + annotations: + {{- with .Values.ingress.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +spec: + {{- if .Values.ingress.className }} + ingressClassName: {{ .Values.ingress.className | quote }} + {{- end }} + {{- if .Values.ingress.tls.enabled }} + tls: + - hosts: + {{- range .Values.ingress.hosts }} + - {{ .host | quote }} + {{- end }} + {{- if .Values.ingress.tls.secretName }} + secretName: {{ .Values.ingress.tls.secretName }} + {{- else }} + secretName: {{ include "elasticsearch.fullname" . }}-es-http-certs-internal + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + {{- $hostPath := .path | default "/" }} + - host: {{ .host | quote }} + http: + paths: + - path: {{ $hostPath }} + pathType: {{ $pathType }} + backend: + service: + name: {{ include "elasticsearch.fullname" $ }}-es-http + port: + number: 9200 + {{- end }} +{{ end }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/values.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/values.yaml new file mode 100644 index 00000000..8d8e21c8 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-elasticsearch/values.yaml @@ -0,0 +1,393 @@ +--- +# Default values for eck-elasticsearch. +# This is a YAML-formatted file. + +# Overridable names of the Elasticsearch resource. +# By default, this is the Release name set for the chart, +# followed by 'eck-elasticsearch'. +# +# nameOverride will override the name of the Chart with the name set here, +# so nameOverride: quickstart, would convert to '{{ Release.name }}-quickstart' +# +# nameOverride: "quickstart" +# +# fullnameOverride will override both the release name, and the chart name, +# and will name the Elasticsearch resource exactly as specified. +# +# fullnameOverride: "quickstart" + +# Version of Elasticsearch. +# +version: 9.1.0 + +# Elasticsearch Docker image to deploy +# +# image: + +# Labels that will be applied to Elasticsearch. +# +labels: {} + +# Annotations that will be applied to Elasticsearch. +# +annotations: {} + +# Settings for configuring Elasticsearch users and roles. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-users-and-roles.html +# +auth: {} + +# Settings for configuring stack monitoring. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-stack-monitoring.html +# +monitoring: {} + # metrics: + # elasticsearchRefs: + # - name: monitoring + # namespace: observability + # logs: + # elasticsearchRefs: + # - name: monitoring + # namespace: observability + +# Control the Elasticsearch transport module used for internal communication between nodes. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-transport-settings.html +# +transport: {} + # service: + # metadata: + # labels: + # my-custom: label + # spec: + # type: LoadBalancer + # tls: + # subjectAltNames: + # - ip: 1.2.3.4 + # - dns: hulk.example.com + # certificate: + # secretName: custom-ca + +# Settings to control how Elasticsearch will be accessed. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-accessing-elastic-services.html +# +http: {} + # service: + # metadata: + # labels: + # my-custom: label + # spec: + # type: LoadBalancer + # tls: + # selfSignedCertificate: + # # To fully disable TLS for the HTTP layer of Elasticsearch, simply + # # set the below field to 'true', removing all other fields. + # disabled: false + # subjectAltNames: + # - ip: 1.2.3.4 + # - dns: hulk.example.com + # certificate: + # secretName: custom-ca + +# Control Elasticsearch Secure Settings. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-es-secure-settings.html#k8s-es-secure-settings +# +secureSettings: [] + # - secretName: one-secure-settings-secret + # Projection of secret keys to specific paths + # - secretName: gcs-secure-settings + # entries: + # - key: gcs.client.default.credentials_file + # - key: gcs_client_1 + # path: gcs.client.client_1.credentials_file + # - key: gcs_client_2 + # path: gcs.client.client_2.credentials_file + +# Settings for limiting the number of simultaneous changes to an Elasticsearch resource. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-update-strategy.html +# +updateStrategy: {} + # changeBudget: + # maxSurge: 3 + # maxUnavailable: 1 + +# Controlling of connectivity between remote clusters within the same kubernetes cluster. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-remote-clusters.html +# +remoteClusters: {} + # - name: cluster-two + # elasticsearchRef: + # name: cluster-two + # namespace: ns-two + +# RemoteClusterServer specifies if the remote cluster server should be enabled. +# This must be enabled if this cluster is a remote cluster which is expected to be accessed using API key authentication. +# +remoteClusterServer: {} +# enabled: true + +# VolumeClaimDeletePolicy sets the policy for handling deletion of PersistentVolumeClaims for all NodeSets. +# Possible values are DeleteOnScaledownOnly and DeleteOnScaledownAndClusterDeletion. +# By default, if not set or empty, the operator sets DeleteOnScaledownAndClusterDeletion. +# +volumeClaimDeletePolicy: "" + +# Settings to limit the disruption when pods need to be rescheduled for some reason such as upgrades or routine maintenance. +# By default, if not set, the operator sets a budget that doesn't allow any pod to be removed in case the cluster is not green or if there is only one node of type `data` or `master`. +# In all other cases the default PodDisruptionBudget sets `minUnavailable` equal to the total number of nodes minus 1. +# To completely disable the pod disruption budget set `disabled` to true. +# +# podDisruptionBudget: +# spec: +# minAvailable: 2 +# selector: +# matchLabels: +# elasticsearch.k8s.elastic.co/cluster-name: quickstart +# disabled: true + +# Used to check access from the current resource to a resource (for ex. a remote Elasticsearch cluster) in a different namespace. +# Can only be used if ECK is enforcing RBAC on references. +# +# serviceAccountName: "" + +# Number of revisions to retain to allow rollback in the underlying StatefulSets. +# By default, if not set, Kubernetes sets 10. +# +# revisionHistoryLimit: 2 + +# Node configuration settings. +# The node roles which can be configured here are: +# - "master" +# - "data_hot" +# - "data_cold" +# - "data_frozen" +# - "data_content" +# - "ml" +# - "ingest" +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-node-configuration.html +# +nodeSets: +- name: default + count: 1 + config: + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + # The following spec is exactly the Kubernetes Core V1 PodTemplateSpec. Any fields within the PodTemplateSpec + # are supported within the 'spec' field below. Please see below documentation for the exhaustive list of fields. + # + # https://v1-24.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#podtemplatespec-v1-core + # + # Only the commonly overridden/used fields will be noted below. + # + spec: + + # If specified, the pod's scheduling constraints + # https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html + # https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: topology.kubernetes.io/zone + # operator: In + # values: + # - antarctica-east1 + # - antarctica-west1 + + # Containers array. Should only be used to customize the 'elasticsearch' container using the following fields. + containers: + - name: elasticsearch + + # List of environment variables to set in the 'elasticsearch' container. + # https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/ + # env: + # - name: "my-env-var" + # value: "my-value" + + # Compute Resources required by this container. + resources: + # Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, + # it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. + # + # Defaults used by the ECK Operator, if not specified, are below + limits: + # cpu: 1 + memory: 2Gi + requests: + # cpu: 1 + memory: 2Gi + + # Example increasing both the requests and limits values: + # limits: + # cpu: 4 + # memory: 8Gi + # requests: + # cpu: 1 + # memory: 8Gi + + # SecurityContext defines the security options the container should be run with. + # If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + # + # These typically are set automatically by the ECK Operator, and should only be adjusted + # with the full knowledge of the effects of each field. + # + # securityContext: + + # Whether this container has a read-only root filesystem. Default is false. + # readOnlyRootFilesystem: false + + # The GID to run the entrypoint of the container process. Uses runtime default if unset. + # runAsGroup: 1000 + + # Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure + # that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. + # runAsNonRoot: true + + # The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. + # runAsUser: 1000 + + # ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. + # https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod + # imagePullSecrets: + # - name: "image-pull-secret" + + # List of initialization containers belonging to the pod. + # + # Common initContainers include setting sysctl, or in 7.x versions of Elasticsearch, + # installing Elasticsearch plugins. + # + # https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + # initContainers: + # - command: + # - sh + # - "-c" + # - sysctl -w vm.max_map_count=262144 + # name: sysctl + # securityContext: + # privileged: true + # - command: + # - sh + # - "-c" + # - bin/elasticsearch-plugin remove --purge analysis-icu ; bin/elasticsearch-plugin install --batch analysis-icu + # name: install-plugins + # securityContext: + # privileged: true + + + # NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. + # https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + # https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html + # nodeSelector: + # diskType: ssd + # environment: production + + # If specified, indicates the pod's priority. "system-node-critical" and "system-cluster-critical" are two special keywords which indicate the highest priorities with the former being the highest priority. + # Any other name must be defined by creating a PriorityClass object with that name. If not specified, the pod priority will be default or zero if there is no default. + # https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/ + # priorityClassName: "" + + # SecurityContext holds pod-level security attributes and common container settings. Optional: Defaults to empty. See type description for default values of each field. + # See previously defined 'securityContext' within 'podTemplate' for all available fields. + # securityContext: {} + + # ServiceAccountName is the name of the ServiceAccount to use to run this pod. + # https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + # serviceAccountName: "" + + # Optional duration in seconds to wait for the Elasticsearch pod to terminate gracefully. + # terminationGracePeriodSeconds: 30s + + # If specified, the pod's tolerations that will apply to all containers within the pod. + # https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/ + # tolerations: + # - key: "node-role.kubernetes.io/elasticsearch" + # effect: "NoSchedule" + # operator: "Exists" + + # TopologySpreadConstraints describes how a group of pods ought to spread across topology domains. + # Scheduler will schedule pods in a way which abides by the constraints. All topologySpreadConstraints are ANDed. + # + # These settings are generally applied within each `nodeSets[].podTemplate` field to apply to a specific Elasticsearch nodeset. + # + # https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html + # topologySpreadConstraints: {} + + # List of volumes that can be mounted by containers belonging to the pod. + # https://kubernetes.io/docs/concepts/storage/volumes + # volumes: [] + +# Settings for controlling Elasticsearch ingress. Enabling ingress will expose your Elasticsearch instance +# to the public internet, and as such is disabled by default. +# +# Each Cloud Service Provider has different requirements for setting up Ingress. Some links to common documentation are: +# - AWS: https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html +# - GCP: https://cloud.google.com/kubernetes-engine/docs/concepts/ingress +# - Azure: https://learn.microsoft.com/en-us/azure/aks/app-routing +# - Nginx: https://kubernetes.github.io/ingress-nginx/ +# +ingress: + enabled: false + + # Annotations that will be applied to the Ingress resource. Note that some ingress controllers are controlled via annotations. + # + # Nginx Annotations: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/ + # + # Common annotations: + # kubernetes.io/ingress.class: gce # Configures the Ingress resource to use the GCE ingress controller and create an external Application Load Balancer. + # kubernetes.io/ingress.class: gce-internal # Configures the Ingress resource to use the GCE ingress controller and create an internal Application Load Balancer. + # kubernetes.io/ingress.class: nginx # Configures the Ingress resource to use the NGINX ingress controller. + # + annotations: {} + + # Labels that will be applied to the Ingress resource. + # + labels: {} + + # Some ingress controllers require the use of a specific class name to route traffic to the correct controller, notably AKS and EKS, which + # replaces the use of the 'kubernetes.io/ingress.class' annotation. + # + # className: webapprouting.kubernetes.azure.com | alb + + # Ingress paths are required to have a corresponding path type. Defaults to 'Prefix'. + # + # There are 3 supported path types: + # - ImplementationSpecific + # - Prefix + # - Exact + # + # ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#path-types + # + pathType: Prefix + + # Hosts are a list of hosts included in the Ingress definition, with a corresponding path at which the default Elasticsearch service + # will be exposed. Each host in the list should be a fully qualified DNS name that will resolve to the exposed Ingress object. + # + # ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#name-based-virtual-hosting + # + hosts: + - host: chart-example.local + path: / + + # TLS defines whether TLS will be enabled on the Ingress resource. + # + # *NOTE* Many Cloud Service Providers handle TLS in a custom manner, and as such, it is recommended to consult their documentation. + # Notably GKE and Nginx Ingress Controllers seems to respect the Ingress TLS settings, AKS and EKS ignore it. + # + # - AKS: https://learn.microsoft.com/en-us/azure/aks/app-routing-dns-ssl + # - GKE: https://cloud.google.com/kubernetes-engine/docs/concepts/ingress#options_for_providing_ssl_certificates + # - EKS: https://aws.amazon.com/blogs/containers/serve-distinct-domains-with-tls-powered-by-acm-on-amazon-eks/ + # - Nginx: https://kubernetes.github.io/ingress-nginx/user-guide/tls/ + # + # Kubernetes ingress TLS documentation: + # ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#tls + # + tls: + enabled: false + # Optional Kubernetes secret name that contains a base64 encoded PEM certificate and private key that corresponds to the above 'hosts' definitions. + # If tls is enabled, but this field is not set, the self-signed certificate and key created by the ECK operator will be used. + # secretName: chart-example-tls diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-enterprise-search/.helmignore b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-enterprise-search/.helmignore new file mode 100644 index 00000000..f1568daf --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-enterprise-search/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-enterprise-search/Chart.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-enterprise-search/Chart.yaml new file mode 100644 index 00000000..666c2703 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-enterprise-search/Chart.yaml @@ -0,0 +1,9 @@ +apiVersion: v2 +description: Elastic Enterprise Search managed by the ECK operator +icon: https://github.com/elastic/ent-search/blob/main/public/app-search-favicon-196x196.png +kubeVersion: '>= 1.21.0-0' +name: eck-enterprise-search +sources: +- https://github.com/elastic/cloud-on-k8s +type: application +version: 0.16.0 diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-enterprise-search/examples/with-custom-configuration.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-enterprise-search/examples/with-custom-configuration.yaml new file mode 100644 index 00000000..4216a112 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-enterprise-search/examples/with-custom-configuration.yaml @@ -0,0 +1,19 @@ +config: + # define the exposed URL at which users will reach Enterprise Search + ent_search.external_url: https://my-custom-domain:3002 + # define the exposed URL at which users will reach Kibana + kibana.host: https://kibana.my-custom-domain:5601 + # configure app search document size limit + app_search.engine.document_size.limit: 100kb + +http: + service: + metadata: + labels: + my-custom: label + tls: + certificate: + secretName: my-cert + +elasticsearchRef: + name: eck-elasticsearch diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-enterprise-search/templates/_helpers.tpl b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-enterprise-search/templates/_helpers.tpl new file mode 100644 index 00000000..21025dc7 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-enterprise-search/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "eck-enterprise-search.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "eck-enterprise-search.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "eck-enterprise-search.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "eck-enterprise-search.labels" -}} +helm.sh/chart: {{ include "eck-enterprise-search.chart" . }} +{{ include "eck-enterprise-search.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "eck-enterprise-search.selectorLabels" -}} +app.kubernetes.io/name: {{ include "eck-enterprise-search.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "eck-enterprise-search.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "eck-enterprise-search.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-enterprise-search/templates/enterprisesearch.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-enterprise-search/templates/enterprisesearch.yaml new file mode 100644 index 00000000..af224e35 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-enterprise-search/templates/enterprisesearch.yaml @@ -0,0 +1,62 @@ +--- +apiVersion: enterprisesearch.k8s.elastic.co/v1 +kind: EnterpriseSearch +metadata: + name: {{ include "eck-enterprise-search.fullname" . }} + labels: + {{- include "eck-enterprise-search.labels" . | nindent 4 }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + eck.k8s.elastic.co/license: basic + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + version: {{ required "An Enterprise Search version is required" .Values.version }} + count: {{ required "A pod count is required" .Values.count }} + + {{- /* + This is complicated, but seems required to catch both the situations where the key does not exist (commented out), and the key exists but is an empty map. + */ -}} + {{- if and (or (and (hasKey .Values "configRef") (eq 0 (len .Values.configRef))) (not (hasKey .Values "configRef"))) (or (and (hasKey .Values "elasticsearchRef") (eq 0 (len .Values.elasticsearchRef))) (not (hasKey .Values "elasticsearchRef"))) }} + {{ fail "At least one of configRef or elasticsearchRef is required" }} + {{- end }} + + {{- with .Values.image }} + image: {{ . }} + {{- end }} + + {{- with .Values.serviceAccountName }} + serviceAccountName: {{ . }} + {{- end }} + + {{- with .Values.revisionHistoryLimit }} + revisionHistoryLimit: {{ . }} + {{- end }} + + {{- with .Values.config }} + config: + {{- toYaml . | nindent 4 }} + {{- end }} + + {{- with .Values.http }} + http: + {{- toYaml . | nindent 4 }} + {{- end }} + + {{- with .Values.elasticsearchRef }} + elasticsearchRef: + {{- toYaml . | nindent 4 }} + {{- end }} + + {{- with .Values.podTemplate }} + podTemplate: + {{- toYaml . | nindent 4 }} + {{- end }} + + {{- with .Values.configRef }} + configRef: + {{- toYaml . | nindent 2 }} + {{- end }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-enterprise-search/values.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-enterprise-search/values.yaml new file mode 100644 index 00000000..04d95667 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-enterprise-search/values.yaml @@ -0,0 +1,96 @@ +--- +# Default values for eck-enterprise-search. +# This is a YAML-formatted file. + +# Overridable names of the Enterprise Search resource. +# By default, this is the Release name set for the chart, +# followed by 'eck-enterprise-search'. +# +# nameOverride will override the name of the Chart with the name set here, +# so nameOverride: quickstart, would convert to '{{ Release.name }}-quickstart' +# +# nameOverride: "quickstart" +# +# fullnameOverride will override both the release name, and the chart name, +# and will name the Enterprise Search resource exactly as specified. +# +# fullnameOverride: "quickstart" + +# Version of Enterprise Search. +# +version: 8.19.0 + +# Enterprise Search Docker image to deploy +# +# image: + +# Used to check access from the current resource to a resource (for ex. a remote Elasticsearch cluster) in a different namespace. +# Can only be used if ECK is enforcing RBAC on references. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-restrict-cross-namespace-associations.html +# +# serviceAccountName: "" + +# Labels that will be applied to Enterprise Search. +# +labels: {} + +# Annotations that will be applied to Enterprise Search. +# +annotations: {} + +# Count of Enterprise Search replicas to create. +# +count: 1 + +# The Enterprise Search configuration, the ECK equivalent to enterprise-search.yml +# ref: https://www.elastic.co/guide/en/enterprise-search/current/configuration.html#configuration-configure +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-enterprise-search-configuration.html +# +# At a minimum, you must specify the external URL and Kibana host. +# +config: {} + # define the exposed URL at which users will reach Enterprise Search + # ent_search.external_url: https://my-custom-domain:3002 + # define the exposed URL at which users will reach Kibana + # kibana.host: https://kibana.my-custom-domain:5601 + +# Settings to control how Enterprise Search will be accessed. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-accessing-elastic-services.html +# +http: {} + # tls: + # certificate: + # secretName: my-cert + # service: + # metadata: + # labels: + # my-custom: label + +# Reference to ECK-managed Elasticsearch resource. +# +elasticsearchRef: {} + # name: eck-elasticsearch + # Optional namespace reference to Elasticsearch resource. + # If not specified, then the namespace of the Enterprise Search resource + # will be assumed. + # + # namespace: default + +# Set podTemplate to customize the pod used by Enterprise Search +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-customize-pods.html +# +podTemplate: {} + +# Number of revisions to retain to allow rollback in the underlying Deployment. +# If not set Kubernetes sets this to 10 by default. +# +# revisionHistoryLimit: 2 + +# If you would prefer your sensitive data to be stored in a Secret, you can specify the name of the Secret reference. +# In addition, if you do not want to use the `elasticsearchRef` mechanism or if you want to connect to an Elasticsearch +# cluster not managed by ECK, you can manually configure Enterprise Search to access any available Elasticsearch cluster: +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-enterprise-search-configuration.html#k8s-enterprise-search-secret-configuration +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-enterprise-search-configuration.html#k8s-enterprise-search-connect-non-eck-es +# +configRef: {} + # secretName: enterprise-search-config diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/.helmignore b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/.helmignore new file mode 100644 index 00000000..f1568daf --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/Chart.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/Chart.yaml new file mode 100644 index 00000000..a96711c8 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +description: Elastic Fleet Server as an Agent managed by the ECK operator +kubeVersion: '>= 1.21.0-0' +name: eck-fleet-server +sources: +- https://github.com/elastic/cloud-on-k8s +- https://github.com/elastic/elastic-agent +- https://github.com/elastic/fleet-server +- https://www.elastic.co/guide/en/fleet/current/fleet-overview.html +type: application +version: 0.16.0 diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/LICENSE b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/LICENSE new file mode 100644 index 00000000..92503a72 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/LICENSE @@ -0,0 +1,93 @@ +Elastic License 2.0 + +URL: https://www.elastic.co/licensing/elastic-license + +## Acceptance + +By using the software, you agree to all of the terms and conditions below. + +## Copyright License + +The licensor grants you a non-exclusive, royalty-free, worldwide, +non-sublicensable, non-transferable license to use, copy, distribute, make +available, and prepare derivative works of the software, in each case subject to +the limitations and conditions below. + +## Limitations + +You may not provide the software to third parties as a hosted or managed +service, where the service provides users with access to any substantial set of +the features or functionality of the software. + +You may not move, change, disable, or circumvent the license key functionality +in the software, and you may not remove or obscure any functionality in the +software that is protected by the license key. + +You may not alter, remove, or obscure any licensing, copyright, or other notices +of the licensor in the software. Any use of the licensor’s trademarks is subject +to applicable law. + +## Patents + +The licensor grants you a license, under any patent claims the licensor can +license, or becomes able to license, to make, have made, use, sell, offer for +sale, import and have imported the software, in each case subject to the +limitations and conditions in this license. This license does not cover any +patent claims that you cause to be infringed by modifications or additions to +the software. If you or your company make any written claim that the software +infringes or contributes to infringement of any patent, your patent license for +the software granted under these terms ends immediately. If your company makes +such a claim, your patent license ends immediately for work on behalf of your +company. + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you +also gets a copy of these terms. + +If you modify the software, you must include in any modified copies of the +software prominent notices stating that you have modified the software. + +## No Other Rights + +These terms do not imply any licenses other than those expressly granted in +these terms. + +## Termination + +If you use the software in violation of these terms, such use is not licensed, +and your licenses will automatically terminate. If the licensor provides you +with a notice of your violation, and you cease all violation of this license no +later than 30 days after you receive that notice, your licenses will be +reinstated retroactively. However, if you violate these terms after such +reinstatement, any additional violation of these terms will cause your licenses +to terminate automatically and permanently. + +## No Liability + +*As far as the law allows, the software comes as is, without any warranty or +condition, and the licensor will not be liable to you for any damages arising +out of these terms or the use or nature of the software, under any kind of +legal claim.* + +## Definitions + +The **licensor** is the entity offering these terms, and the **software** is the +software the licensor makes available under these terms, including any portion +of it. + +**you** refers to the individual or entity agreeing to these terms. + +**your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control over, +are under the control of, or are under common control with that +organization. **control** means ownership of substantially all the assets of an +entity, or the power to direct its management and policies by vote, contract, or +otherwise. Control can be direct or indirect. + +**your licenses** are all the licenses granted to you for the software under +these terms. + +**use** means anything you do with the software requiring one of your licenses. + +**trademark** means trademarks, service marks, and similar rights. \ No newline at end of file diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/examples/fleet-server.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/examples/fleet-server.yaml new file mode 100644 index 00000000..8b8bbe17 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/examples/fleet-server.yaml @@ -0,0 +1,17 @@ +version: 9.1.0 +deployment: + replicas: 1 + podTemplate: + spec: + serviceAccountName: fleet-server + automountServiceAccountToken: true +elasticsearchRefs: +- name: eck-elasticsearch +kibanaRef: + name: eck-kibana +http: + service: + spec: + type: ClusterIP +serviceAccount: + name: fleet-server diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/templates/NOTES.txt b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/templates/NOTES.txt new file mode 100644 index 00000000..eb3c879d --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/templates/NOTES.txt @@ -0,0 +1,6 @@ + +1. Check Fleet Server status + $ kubectl get agent {{ include "fleet-server.fullname" . }} -n {{ .Release.Namespace }} + +2. Check Fleet Server pod status + $ kubectl get pods --namespace={{ .Release.Namespace }} -l fleet-server.k8s.elastic.co/name={{ include "fleet-server.fullname" . }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/templates/_helpers.tpl b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/templates/_helpers.tpl new file mode 100644 index 00000000..173f5089 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "fleet-server.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "fleet-server.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "fleet-server.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "fleet-server.labels" -}} +helm.sh/chart: {{ include "fleet-server.chart" . }} +{{ include "fleet-server.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.labels }} +{{ toYaml .Values.labels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "fleet-server.selectorLabels" -}} +app.kubernetes.io/name: {{ include "fleet-server.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/templates/cluster-role-binding.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/templates/cluster-role-binding.yaml new file mode 100644 index 00000000..e5fee457 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/templates/cluster-role-binding.yaml @@ -0,0 +1,33 @@ +{{- with .Values.clusterRoleBinding }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .name }} + labels: + {{- include "fleet-server.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or $.Values.annotations .annotations }} + annotations: + {{- with $.Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +{{- with .subjects }} +subjects: +{{- range . }} + - kind: {{ .kind }} + name: {{ .name }} + namespace: {{ .namespace | default $.Release.Namespace | quote }} +{{- end }} +{{- end }} +roleRef: + kind: {{ .roleRef.kind }} + name: {{ .roleRef.name }} + apiGroup: {{ .roleRef.apiGroup }} +{{- end }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/templates/cluster-role.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/templates/cluster-role.yaml new file mode 100644 index 00000000..f067b628 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/templates/cluster-role.yaml @@ -0,0 +1,22 @@ +{{- with .Values.clusterRole }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ .name }} + labels: + {{- include "fleet-server.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or $.Values.annotations .annotations }} + annotations: + {{- with $.Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +rules: {{- toYaml .rules | nindent 2 }} +{{- end }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/templates/fleet-server.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/templates/fleet-server.yaml new file mode 100644 index 00000000..2eb3b0d3 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/templates/fleet-server.yaml @@ -0,0 +1,64 @@ +--- +apiVersion: agent.k8s.elastic.co/v1alpha1 +kind: Agent +metadata: + name: {{ include "fleet-server.fullname" . }} + labels: + {{- include "fleet-server.labels" . | nindent 4 }} + annotations: + eck.k8s.elastic.co/license: basic + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + version: {{ required "A Fleet Server version is required" (or ((.Values.spec).version) (.Values.version)) }} + mode: fleet + fleetServerEnabled: true + {{- if (or (hasKey (.Values.spec) "mode") (hasKey .Values "mode")) }} + {{- fail "mode cannot be changed" }} + {{- end }} + {{- if (or (hasKey (.Values.spec) "fleetServerEnabled") (hasKey .Values "fleetServerEnabled"))}} + {{- fail "fleetServerEnabled cannot be changed" }} + {{- end }} + + {{- $statefulSet := (or (hasKey (.Values.spec) "statefulSet") (hasKey .Values "statefulSet")) }} + {{- $deployment := (or (hasKey (.Values.spec) "deployment") (hasKey .Values "deployment")) }} + {{- if and (not $statefulSet) (not $deployment) }} + {{ fail "At least one of statefulSet or deployment is required" }} + {{- end }} + {{- if $statefulSet }} + {{- $ss := or ((.Values.spec).statefulSet) (.Values.statefulSet) }} + statefulSet: + {{- /* This is required to render the empty statefulSet ( {} ) properly */}} + {{- $ss | default dict | toYaml | nindent 4 }} + {{- end }} + {{- if $deployment }} + {{- $deploy := or ((.Values.spec).deployment) (.Values.deployment) }} + deployment: + {{- /* This is required to render the empty deployment ( {} ) properly */}} + {{- $deploy | default dict | toYaml | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).image) (.Values.image) }} + image: {{ . }} + {{- end }} + {{- with or ((.Values.spec).elasticsearchRefs) (.Values.elasticsearchRefs) }} + elasticsearchRefs: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).kibanaRef) (.Values.kibanaRef) }} + kibanaRef: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).policyID) (.Values.policyID) }} + policyID: {{ . }} + {{- end }} + {{- with or ((.Values.spec).http) (.Values.http) }} + http: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).revisionHistoryLimit) (.Values.revisionHistoryLimit) }} + revisionHistoryLimit: {{ . }} + {{- end }} + {{- with or (((.Values.spec).serviceAccount).name) ((.Values.serviceAccount).name) }} + serviceAccountName: {{ . }} + {{- end }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/templates/service-account.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/templates/service-account.yaml new file mode 100644 index 00000000..0f8901d9 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/templates/service-account.yaml @@ -0,0 +1,22 @@ +{{- with .Values.serviceAccount }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .name }} + namespace: {{ .namespace | default $.Release.Namespace | quote }} + labels: + {{- include "fleet-server.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or $.Values.annotations .annotations }} + annotations: + {{- with $.Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/values.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/values.yaml new file mode 100644 index 00000000..e0e14154 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-fleet-server/values.yaml @@ -0,0 +1,157 @@ +--- +# Default values for eck-fleet-server. +# This is a YAML-formatted file. + +# Overridable names of the Fleet Server resource. +# By default, this is the Release name set for the chart, +# followed by 'eck-fleet-server'. +# +# nameOverride will override the name of the Chart with the name set here, +# so nameOverride: quickstart, would convert to '{{ Release.name }}-quickstart' +# +# nameOverride: "quickstart" +# +# fullnameOverride will override both the release name, and the chart name, +# and will name the Fleet Server resource exactly as specified. +# +# fullnameOverride: "quickstart" + +# Version of Elastic Fleet Server. +# +version: 9.1.0 + +# Labels that will be applied to Elastic Fleet Server. +# +labels: {} + +# Annotations that will be applied to Elastic Fleet Server. +# +annotations: {} + +# Elastic Fleet Server Agent image to deploy. +# +# image: docker.elastic.co/beats/elastic-agent:9.1.0 + +# ** Deprecation Notice ** +# The previous versions of this Helm Chart simply used the `spec` field here +# and allowed the user to specify any fields below `spec` that were templated directly +# into the final Agent/Fleet Server manifest. This is no longer the preferred way to specify these +# fields and each field that is supported underneath `spec` is now directly specified +# in this values file. Currently both patterns are supported for backwards compatibility +# but we plan to remove the `spec` field in the future. +# spec: {} + +# Referenced resources are below and both elasticsearchRefs and kibanaRef are required for a functional Fleet Server. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-setting-referenced-resources +# +# Reference to ECK-managed Kibana instance. +# This is required for Fleet Server. +# +# kibanaRef: +# name: quickstart + # Optional namespace reference to Kibana instance. + # If not specified, then the namespace of the Fleet Server resource + # will be assumed. + # + # namespace: default + +# Reference to ECK-managed Elasticsearch instance. +# This is required for Fleet Server. +# +elasticsearchRefs: [] +# - name: eck-elasticsearch + # Optional namespace reference to Elasticsearch instance. + # If not specified, then the namespace of the Fleet Server resource + # will be assumed. + # + # namespace: default + +# policyID determines into which Agent Policy this Fleet Server will be enrolled. +policyID: eck-fleet-server + +# The HTTP layer configuration for the Fleet Server Service. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-customize-fleet-server-service +# +# http: + +# Deployment or StatefulSet specification for Fleet Server. +# At least one is required of [deployment, statefulSet]. +# No default is currently set, refer to https://github.com/elastic/cloud-on-k8s/issues/7429. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-chose-the-deployment-model +# +# deployment: +# replicas: 1 +# podTemplate: +# spec: +# serviceAccountName: fleet-server +# automountServiceAccountToken: true +# +# statefulSet: +# podTemplate: +# spec: +# serviceAccountName: fleet-server +# automountServiceAccountToken: true + +# Number of revisions to retain to allow rollback in the underlying Deployment. +# If not set Kubernetes sets this to 10 by default. +# +# revisionHistoryLimit: 2 + +# ServiceAccount to be used by Elastic Fleet Server. Some Fleet Server features (such as autodiscover or Kubernetes module metricsets) +# require that Fleet Server Pods interact with Kubernetes APIs. This functionality requires specific permissions +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-role-based-access-control +# +serviceAccount: + name: fleet-server + # namespace: optional-namespace + +# ClusterRoleBinding to be used by Elastic Fleet Server. Similar to ServiceAccount, this is required in some scenarios. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-role-based-access-control +# +clusterRoleBinding: + name: fleet-server + subjects: + - kind: ServiceAccount + name: fleet-server + # namespace: default + roleRef: + kind: ClusterRole + name: fleet-server + apiGroup: rbac.authorization.k8s.io + +# ClusterRole to be used by Elastic Fleet Server. Similar to ServiceAccount, this is required in some scenarios. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-role-based-access-control +# +clusterRole: + name: fleet-server + rules: + - apiGroups: [""] + resources: + - pods + - namespaces + - nodes + verbs: + - get + - watch + - list + - apiGroups: ["apps"] + resources: + - replicasets + verbs: + - get + - watch + - list + - apiGroups: ["batch"] + resources: + - jobs + verbs: + - get + - watch + - list + - apiGroups: ["coordination.k8s.io"] + resources: + - leases + verbs: + - get + - create + - update diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/.helmignore b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/.helmignore new file mode 100644 index 00000000..f1568daf --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/Chart.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/Chart.yaml new file mode 100644 index 00000000..cbb3a72f --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/Chart.yaml @@ -0,0 +1,10 @@ +apiVersion: v2 +description: Kibana managed by the ECK operator +icon: https://helm.elastic.co/icons/kibana.png +kubeVersion: '>= 1.21.0-0' +name: eck-kibana +sources: +- https://github.com/elastic/cloud-on-k8s +- https://github.com/elastic/kibana +type: application +version: 0.16.0 diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/LICENSE b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/LICENSE new file mode 100644 index 00000000..92503a72 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/LICENSE @@ -0,0 +1,93 @@ +Elastic License 2.0 + +URL: https://www.elastic.co/licensing/elastic-license + +## Acceptance + +By using the software, you agree to all of the terms and conditions below. + +## Copyright License + +The licensor grants you a non-exclusive, royalty-free, worldwide, +non-sublicensable, non-transferable license to use, copy, distribute, make +available, and prepare derivative works of the software, in each case subject to +the limitations and conditions below. + +## Limitations + +You may not provide the software to third parties as a hosted or managed +service, where the service provides users with access to any substantial set of +the features or functionality of the software. + +You may not move, change, disable, or circumvent the license key functionality +in the software, and you may not remove or obscure any functionality in the +software that is protected by the license key. + +You may not alter, remove, or obscure any licensing, copyright, or other notices +of the licensor in the software. Any use of the licensor’s trademarks is subject +to applicable law. + +## Patents + +The licensor grants you a license, under any patent claims the licensor can +license, or becomes able to license, to make, have made, use, sell, offer for +sale, import and have imported the software, in each case subject to the +limitations and conditions in this license. This license does not cover any +patent claims that you cause to be infringed by modifications or additions to +the software. If you or your company make any written claim that the software +infringes or contributes to infringement of any patent, your patent license for +the software granted under these terms ends immediately. If your company makes +such a claim, your patent license ends immediately for work on behalf of your +company. + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you +also gets a copy of these terms. + +If you modify the software, you must include in any modified copies of the +software prominent notices stating that you have modified the software. + +## No Other Rights + +These terms do not imply any licenses other than those expressly granted in +these terms. + +## Termination + +If you use the software in violation of these terms, such use is not licensed, +and your licenses will automatically terminate. If the licensor provides you +with a notice of your violation, and you cease all violation of this license no +later than 30 days after you receive that notice, your licenses will be +reinstated retroactively. However, if you violate these terms after such +reinstatement, any additional violation of these terms will cause your licenses +to terminate automatically and permanently. + +## No Liability + +*As far as the law allows, the software comes as is, without any warranty or +condition, and the licensor will not be liable to you for any damages arising +out of these terms or the use or nature of the software, under any kind of +legal claim.* + +## Definitions + +The **licensor** is the entity offering these terms, and the **software** is the +software the licensor makes available under these terms, including any portion +of it. + +**you** refers to the individual or entity agreeing to these terms. + +**your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control over, +are under the control of, or are under common control with that +organization. **control** means ownership of substantially all the assets of an +entity, or the power to direct its management and policies by vote, contract, or +otherwise. Control can be direct or indirect. + +**your licenses** are all the licenses granted to you for the software under +these terms. + +**use** means anything you do with the software requiring one of your licenses. + +**trademark** means trademarks, service marks, and similar rights. \ No newline at end of file diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/examples/http-configuration.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/examples/http-configuration.yaml new file mode 100644 index 00000000..7bb0001b --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/examples/http-configuration.yaml @@ -0,0 +1,36 @@ +--- +# Version of Kibana. +# +version: 9.1.0 + +# Labels that will be applied to Kibana. +# +labels: {} + # key: value + +# Annotations that will be applied to Kibana. +# +annotations: {} + # key: value + +# Count of Kibana replicas to create. +# +count: 1 + +# Reference to ECK-managed Elasticsearch resource, ideally from {{ "elasticsearch.fullname" }} +# +elasticsearchRef: + name: eck-elasticsearch + # namespace: default +http: + service: + spec: + # Type of service to deploy for Kibana. + # This deploys a load balancer in a cloud service provider, where supported. + # + type: LoadBalancer + # tls: + # selfSignedCertificate: + # subjectAltNames: + # - ip: 1.2.3.4 + # - dns: kibana.example.com diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-aks.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-aks.yaml new file mode 100644 index 00000000..b7363dd0 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-aks.yaml @@ -0,0 +1,28 @@ +# The following is an example of a Kibana resource that is configured to use an Ingress resource in an AKS cluster. +# + +# Name of the Kibana instance. +# +fullnameOverride: kibana + +# Reference to ECK-managed Elasticsearch instance, ideally from {{ "elasticsearch.fullname" }} +# +elasticsearchRef: + name: elasticsearch +config: + server: + publicBaseUrl: "https://kibana.company.dev" + +ingress: + enabled: true + className: webapprouting.kubernetes.azure.com + annotations: + # This is required for AKS Loadbalancing to understand that it's communicating with + # an HTTPS backend. + nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" + labels: + my: label + pathType: Prefix + hosts: + - host: "kibana.company.dev" + path: "/" diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-eks.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-eks.yaml new file mode 100644 index 00000000..c5f2f43b --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-eks.yaml @@ -0,0 +1,48 @@ +# The following is an example of a Kibana resource that is configured to use an Ingress resource in an EKS cluster. +# + +# Name of the Kibana instance. +# +fullnameOverride: kibana + +# Reference to ECK-managed Elasticsearch instance, ideally from {{ "elasticsearch.fullname" }} +# +elasticsearchRef: + name: elasticsearch +config: + server: + publicBaseUrl: "https://kibana.company.dev" + +ingress: + enabled: true + className: alb + annotations: + alb.ingress.kubernetes.io/scheme: "internet-facing" + alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]' + alb.ingress.kubernetes.io/backend-protocol: "HTTPS" + alb.ingress.kubernetes.io/target-type: "ip" + # To use an ALB with ECK, you must provide a valid ACM certificate ARN or use certificate discovery. + # There are 2 options for EKS: + # 1. Create a valid ACM certificate, and uncomment the following annotation and update it to the correct ARN. + # 2. Create a valid ACM certificate and ensure that the hosts[0].host matches the certificate's Common Name (CN) and + # certificate discovery *should* find the certificate automatically and use it. + # + # ref: https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.8/guide/ingress/cert_discovery/ + # + # alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:us-east-1:00000000000:certificate/b65be571-8220-4f2e-8cb1-94194535d877" + labels: + my: label + pathType: Prefix + hosts: + - host: "kibana.company.dev" + path: "/" +nodeSets: +- name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-gke.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-gke.yaml new file mode 100644 index 00000000..61427581 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-gke.yaml @@ -0,0 +1,31 @@ +# The following is an example of a Kibana resource that is configured to use an Ingress resource in a GKE cluster. +# + +# Name of the Kibana instance. +# +fullnameOverride: kibana + +# Reference to ECK-managed Elasticsearch instance, ideally from {{ "elasticsearch.fullname" }} +# +elasticsearchRef: + name: elasticsearch +config: + server: + publicBaseUrl: "https://kibana.company.dev" +http: + service: + metadata: + annotations: + # This is required for `ClusterIP` services (which are the default ECK service type) to be used with Ingress in GKE clusters. + cloud.google.com/neg: '{"ingress": true}' + # This is required to enable the GKE Ingress Controller to use HTTPS as the backend protocol. + cloud.google.com/app-protocols: '{"https":"HTTPS"}' + +ingress: + enabled: true + pathType: Prefix + hosts: + - host: "kibana.company.dev" + path: "/" + tls: + enabled: true diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/templates/NOTES.txt b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/templates/NOTES.txt new file mode 100644 index 00000000..9652161c --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/templates/NOTES.txt @@ -0,0 +1,6 @@ + +1. Check Kibana status + $ kubectl get kibana {{ include "kibana.fullname" . }} -n {{ .Release.Namespace }} + +2. Check Kibana pod status + $ kubectl get pods --namespace={{ .Release.Namespace }} -l kibana.k8s.elastic.co/name={{ include "kibana.fullname" . }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/templates/_helpers.tpl b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/templates/_helpers.tpl new file mode 100644 index 00000000..eba5497d --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "kibana.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "kibana.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "kibana.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "kibana.labels" -}} +helm.sh/chart: {{ include "kibana.chart" . }} +{{ include "kibana.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.labels }} +{{ toYaml .Values.labels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "kibana.selectorLabels" -}} +app.kubernetes.io/name: {{ include "kibana.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/templates/ingress.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/templates/ingress.yaml new file mode 100644 index 00000000..171463c0 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/templates/ingress.yaml @@ -0,0 +1,48 @@ +{{- if .Values.ingress.enabled -}} +{{- $pathType := .Values.ingress.pathType | default "Prefix" -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "kibana.fullname" . }} + labels: + {{- include "kibana.labels" . | nindent 4 }} + {{- with .Values.ingress.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.ingress.annotations }} + annotations: + {{- with .Values.ingress.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +spec: + {{- if .Values.ingress.className }} + ingressClassName: {{ .Values.ingress.className | quote }} + {{- end }} + {{- if .Values.ingress.tls.enabled }} + tls: + - hosts: + {{- range .Values.ingress.hosts }} + - {{ .host | quote }} + {{- end }} + {{- if .Values.ingress.tls.secretName }} + secretName: {{ .Values.ingress.tls.secretName }} + {{- else }} + secretName: {{ include "kibana.fullname" . }}-kb-http-certs-internal + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + {{- $hostPath := .path | default "/" }} + - host: {{ .host | quote }} + http: + paths: + - path: {{ $hostPath }} + pathType: {{ $pathType }} + backend: + service: + name: {{ include "kibana.fullname" $ }}-kb-http + port: + number: 5601 + {{- end }} +{{ end }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/templates/kibana.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/templates/kibana.yaml new file mode 100644 index 00000000..2d07efaa --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/templates/kibana.yaml @@ -0,0 +1,61 @@ +--- +apiVersion: kibana.k8s.elastic.co/v1 +kind: Kibana +metadata: + name: {{ include "kibana.fullname" . }} + labels: + {{- include "kibana.labels" . | nindent 4 }} + annotations: + eck.k8s.elastic.co/license: basic + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + version: {{ required "A Kibana version is required" .Values.version }} + {{- /* + The following templates with 'or' are to allow both .spec.field and .field to be set for backwards + compatibility purposes. See https://github.com/elastic/cloud-on-k8s/pull/8192 for details. + */ -}} + {{- with or ((.Values.spec).image) (.Values.image) }} + image: {{ . }} + {{- end }} + {{- with or ((.Values.spec).count) (.Values.count) }} + count: {{ . }} + {{- end }} + {{- $esRef := or ((.Values.spec).elasticsearchRef) (.Values.elasticsearchRef) }} + {{- if not ($esRef).name }} + {{ fail "An elasticsearchRef is required" }} + {{- end }} + elasticsearchRef: + {{- toYaml $esRef | nindent 4 }} + {{- $entsearchRef := or ((.Values.spec).enterpriseSearchRef) (.Values.enterpriseSearchRef) }} + {{- if $entsearchRef }} + enterpriseSearchRef: + {{- toYaml $entsearchRef | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).config) (.Values.config) }} + config: + {{ toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).http) (.Values.http) }} + http: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).podTemplate) (.Values.podTemplate) }} + podTemplate: + {{ toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).revisionHistoryLimit) (.Values.revisionHistoryLimit) }} + revisionHistoryLimit: {{ . }} + {{- end }} + {{- with or ((.Values.spec).secureSettings) (.Values.secureSettings) }} + secureSettings: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).serviceAccountName) (.Values.serviceAccountName) }} + serviceAccountName: {{ . }} + {{- end }} + {{- with or ((.Values.spec).monitoring) (.Values.monitoring) }} + monitoring: + {{- toYaml . | nindent 4 }} + {{- end }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/values.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/values.yaml new file mode 100644 index 00000000..fe1c3f3f --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-kibana/values.yaml @@ -0,0 +1,179 @@ +--- +# Default values for eck-kibana. +# This is a YAML-formatted file. + +# Overridable names of the Kibana resource. +# By default, this is the Release name set for the chart, +# followed by 'eck-kibana'. +# +# nameOverride will override the name of the Chart with the name set here, +# so nameOverride: quickstart, would convert to '{{ Release.name }}-quickstart' +# +# nameOverride: "quickstart" +# +# fullnameOverride will override both the release name, and the chart name, +# and will name the Kibana resource exactly as specified. +# +# fullnameOverride: "quickstart" + +# Version of Kibana. +# +version: 9.1.0 + +# Kibana Docker image to deploy +# +# image: docker.elastic.co/kibana/kibana:9.1.0 + +# Labels that will be applied to Kibana. +# +labels: {} + +# Annotations that will be applied to Kibana. +# +annotations: {} + +# ** Deprecation Notice ** +# The previous versions of this Helm Chart simply used the `spec` field here +# and allowed the user to specify any fields below spec that were templated directly +# into the final Kibana manifest. This is no long the preferred way to specify these +# fields and each field that is supported underneath `spec` is now directly specified +# in this values file. Currently both patterns are supported for backwards compatibility +# but we plan to remove the `spec` field in the future. +# spec: {} + +# Count of Kibana replicas to create. +# +count: 1 + +# Reference to ECK-managed Elasticsearch resource. +# +elasticsearchRef: {} + # name: eck-elasticsearch + # Optional namespace reference to Elasticsearch resource. + # If not specified, then the namespace of the Kibana resource + # will be assumed. + # + # namespace: default + +# Reference to an EnterpriseSearch running in the same Kubernetes cluster +# +# enterpriseSearchRef: + +# The Kibana configuration (kibana.yml) +# ref: https://www.elastic.co/guide/en/kibana/current/settings.html +# +config: null + +# The HTTP layer configuration for Kibana. +# +# http: + +# PodTemplate provides customisation options (labels, annotations, affinity rules, +# resource requests, and so on) for the Kibana pods +# +# podTemplate: + +# Number of revisions to retain to allow rollback in the underlying deployment. +# By default, if not set, Kubernetes sets 10. +# +# revisionHistoryLimit: 2 + +# Control Kibana Secure Settings. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-kibana-secure-settings.html +# +secureSettings: [] + +# Used to check access from the current resource to a resource (for ex. Elasticsearch) in a different namespace. +# Can only be used if ECK is enforcing RBAC on references. +# +# serviceAccountName: "" + +# Settings for configuring stack monitoring. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-stack-monitoring.html +# +monitoring: {} + # metrics: + # elasticsearchRefs: + # - name: monitoring + # namespace: observability + # logs: + # elasticsearchRefs: + # - name: monitoring + # namespace: observability + +# Settings for controlling Kibana ingress. Enabling ingress will expose your Kibana instance +# to the public internet, and as such is disabled by default. +# +# *NOTE* when configuring Kibana Ingress, ensure that `config.server.publicBaseUrl` setting for +# Kibana is also set, as it is required when exposing Kibana behind a load balancer/ingress. +# Also of note are `server.basePath`, and `server.rewriteBasePath` settings in the Kibana configuration. +# +# ref: https://www.elastic.co/guide/en/kibana/current/settings.html +# +# Each Cloud Service Provider has different requirements for setting up Ingress. Some links to common documentation are: +# - AWS: https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html +# - GCP: https://cloud.google.com/kubernetes-engine/docs/concepts/ingress +# - Azure: https://learn.microsoft.com/en-us/azure/aks/app-routing +# - Nginx: https://kubernetes.github.io/ingress-nginx/ +# +ingress: + enabled: false + + # Annotations that will be applied to the Ingress resource. Note that some ingress controllers are controlled via annotations. + # + # Nginx Annotations: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/ + # + # Common annotations: + # kubernetes.io/ingress.class: gce # Configures the Ingress resource to use the GCE ingress controller and create an external Application Load Balancer. + # kubernetes.io/ingress.class: gce-internal # Configures the Ingress resource to use the GCE ingress controller and create an internal Application Load Balancer. + # kubernetes.io/ingress.class: nginx # Configures the Ingress resource to use the NGINX ingress controller. + # + annotations: {} + + # Labels that will be applied to the Ingress resource. + # + labels: {} + + # Some ingress controllers require the use of a specific class name to route traffic to the correct controller, notably AKS and EKS, which + # replaces the use of the 'kubernetes.io/ingress.class' annotation. + # + # className: webapprouting.kubernetes.azure.com | alb + + # Ingress paths are required to have a corresponding path type. Defaults to 'Prefix'. + # + # There are 3 supported path types: + # - ImplementationSpecific + # - Prefix + # - Exact + # + # ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#path-types + # + pathType: Prefix + + # Hosts are a list of hosts included in the Ingress definition, with a corresponding path at which the Kibana service + # will be exposed. Each host in the list should be a fully qualified DNS name that will resolve to the exposed Ingress object. + # + # ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#name-based-virtual-hosting + # + hosts: + - host: chart-example.local + path: / + + # TLS defines whether TLS will be enabled on the Ingress resource. + # + # *NOTE* Many Cloud Service Providers handle TLS in a custom manner, and as such, it is recommended to consult their documentation. + # Notably GKE and Nginx Ingress Controllers seems to respect the Ingress TLS settings, AKS and EKS ignore it. + # + # - AKS: https://learn.microsoft.com/en-us/azure/aks/app-routing-dns-ssl + # - GKE: https://cloud.google.com/kubernetes-engine/docs/concepts/ingress#options_for_providing_ssl_certificates + # - EKS: https://aws.amazon.com/blogs/containers/serve-distinct-domains-with-tls-powered-by-acm-on-amazon-eks/ + # - Nginx: https://kubernetes.github.io/ingress-nginx/user-guide/tls/ + # + # Kubernetes ingress TLS documentation: + # ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#tls + # + tls: + enabled: false + # Optional Kubernetes secret name that contains a base64 encoded PEM certificate and private key that corresponds to the above 'hosts' definitions. + # If tls is enabled, but this field is not set, the self-signed certificate and key created by the ECK operator will be used. + # secretName: chart-example-tls diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/.helmignore b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/.helmignore new file mode 100644 index 00000000..f1568daf --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/Chart.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/Chart.yaml new file mode 100644 index 00000000..4a6f75eb --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/Chart.yaml @@ -0,0 +1,10 @@ +apiVersion: v2 +description: Logstash managed by the ECK operator +icon: https://helm.elastic.co/icons/logstash.png +kubeVersion: '>= 1.21.0-0' +name: eck-logstash +sources: +- https://github.com/elastic/cloud-on-k8s +- https://github.com/elastic/logstash +type: application +version: 0.16.0 diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/LICENSE b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/LICENSE new file mode 100644 index 00000000..92503a72 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/LICENSE @@ -0,0 +1,93 @@ +Elastic License 2.0 + +URL: https://www.elastic.co/licensing/elastic-license + +## Acceptance + +By using the software, you agree to all of the terms and conditions below. + +## Copyright License + +The licensor grants you a non-exclusive, royalty-free, worldwide, +non-sublicensable, non-transferable license to use, copy, distribute, make +available, and prepare derivative works of the software, in each case subject to +the limitations and conditions below. + +## Limitations + +You may not provide the software to third parties as a hosted or managed +service, where the service provides users with access to any substantial set of +the features or functionality of the software. + +You may not move, change, disable, or circumvent the license key functionality +in the software, and you may not remove or obscure any functionality in the +software that is protected by the license key. + +You may not alter, remove, or obscure any licensing, copyright, or other notices +of the licensor in the software. Any use of the licensor’s trademarks is subject +to applicable law. + +## Patents + +The licensor grants you a license, under any patent claims the licensor can +license, or becomes able to license, to make, have made, use, sell, offer for +sale, import and have imported the software, in each case subject to the +limitations and conditions in this license. This license does not cover any +patent claims that you cause to be infringed by modifications or additions to +the software. If you or your company make any written claim that the software +infringes or contributes to infringement of any patent, your patent license for +the software granted under these terms ends immediately. If your company makes +such a claim, your patent license ends immediately for work on behalf of your +company. + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you +also gets a copy of these terms. + +If you modify the software, you must include in any modified copies of the +software prominent notices stating that you have modified the software. + +## No Other Rights + +These terms do not imply any licenses other than those expressly granted in +these terms. + +## Termination + +If you use the software in violation of these terms, such use is not licensed, +and your licenses will automatically terminate. If the licensor provides you +with a notice of your violation, and you cease all violation of this license no +later than 30 days after you receive that notice, your licenses will be +reinstated retroactively. However, if you violate these terms after such +reinstatement, any additional violation of these terms will cause your licenses +to terminate automatically and permanently. + +## No Liability + +*As far as the law allows, the software comes as is, without any warranty or +condition, and the licensor will not be liable to you for any damages arising +out of these terms or the use or nature of the software, under any kind of +legal claim.* + +## Definitions + +The **licensor** is the entity offering these terms, and the **software** is the +software the licensor makes available under these terms, including any portion +of it. + +**you** refers to the individual or entity agreeing to these terms. + +**your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control over, +are under the control of, or are under common control with that +organization. **control** means ownership of substantially all the assets of an +entity, or the power to direct its management and policies by vote, contract, or +otherwise. Control can be direct or indirect. + +**your licenses** are all the licenses granted to you for the software under +these terms. + +**use** means anything you do with the software requiring one of your licenses. + +**trademark** means trademarks, service marks, and similar rights. \ No newline at end of file diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/examples/basic-eck.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/examples/basic-eck.yaml new file mode 100644 index 00000000..170b9a8c --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/examples/basic-eck.yaml @@ -0,0 +1,44 @@ +--- +# values corresponding to config/recipes/logstash/logstash-eck.yaml +version: 9.1.0 + +elasticsearchRefs: + - clusterName: eck + name: elasticsearch + +pipelines: + - pipeline.id: main + config.string: | + input { + beats { + port => 5044 + } + } + filter { + grok { + match => { "message" => "%{HTTPD_COMMONLOG}"} + } + geoip { + source => "[source][address]" + target => "[source]" + } + } + output { + elasticsearch { + hosts => [ "${ECK_ES_HOSTS}" ] + user => "${ECK_ES_USER}" + password => "${ECK_ES_PASSWORD}" + ssl_certificate_authorities => "${ECK_ES_SSL_CERTIFICATE_AUTHORITY}" + } + } + +services: + - name: beats + service: + spec: + type: ClusterIP + ports: + - port: 5044 + name: "filebeat" + protocol: TCP + targetPort: 5044 diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/examples/es-role.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/examples/es-role.yaml new file mode 100644 index 00000000..f8ed1f86 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/examples/es-role.yaml @@ -0,0 +1,25 @@ +--- +# values corresponding to config/recipes/logstash/logstash-es-role.yaml +version: 9.1.0 + +elasticsearchRefs: + - clusterName: eck + name: elasticsearch + +pipelines: + - pipeline.id: main + config.string: | + input { exec { command => "uptime" interval => 10 } } + output { + elasticsearch { + hosts => [ "${ECK_ES_HOSTS}" ] + ssl_enabled => true + ssl_certificate_authorities => "${ECK_ES_SSL_CERTIFICATE_AUTHORITY}" + user => "${ECK_ES_USER}" + password => "${ECK_ES_PASSWORD}" + index => "my-index" + data_stream => false + ilm_enabled => false + manage_template => false + } + } diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/examples/monitored.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/examples/monitored.yaml new file mode 100644 index 00000000..2cc98e12 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/examples/monitored.yaml @@ -0,0 +1,49 @@ +--- +# values corresponding to config/recipes/logstash/logstash-monitored.yaml +version: 9.1.0 + +monitoring: + metrics: + elasticsearchRefs: + - name: elasticsearch-monitoring + +pipelines: + - pipeline.id: main + config.string: | + input { + beats { + port => 5044 + } + } + filter { + grok { + match => { "message" => "%{HTTPD_COMMONLOG}"} + } + geoip { + source => "[source][address]" + target => "[source]" + } + } + output { + elasticsearch { + hosts => [ "${ECK_ES_HOSTS}" ] + user => "${ECK_ES_USER}" + password => "${ECK_ES_PASSWORD}" + ssl_certificate_authorities => "${ECK_ES_SSL_CERTIFICATE_AUTHORITY}" + } + } + +elasticsearchRefs: + - clusterName: eck + name: elasticsearch + +services: + - name: beats + service: + spec: + type: ClusterIP + ports: + - port: 5044 + name: "filebeat" + protocol: TCP + targetPort: 5044 diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/examples/multi.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/examples/multi.yaml new file mode 100644 index 00000000..7fe2a7bc --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/examples/multi.yaml @@ -0,0 +1,78 @@ +--- +# values corresponding to config/recipes/logstash/logstash-multi.yaml +version: 9.1.0 + +pipelines: + - pipeline.id: main + config.string: | + input { + beats { + port => 5044 + } + } + filter { + grok { + match => { "message" => "%{HTTPD_COMMONLOG}"} + } + geoip { + source => "[source][address]" + target => "[source]" + } + } + output { + pipeline { + send_to => 'prod' + } + pipeline { + send_to => 'qa' + } + } + - pipeline.id: production + config.string: | + input { + pipeline { + address => 'prod' + } + } + output { + elasticsearch { + hosts => [ "${PROD_ES_ES_HOSTS}" ] + user => "${PROD_ES_ES_USER}" + password => "${PROD_ES_ES_PASSWORD}" + ssl_certificate_authorities => "${PROD_ES_ES_SSL_CERTIFICATE_AUTHORITY}" + } + } + - pipeline.id: qa + config.string: | + input { + pipeline { + address => 'qa' + } + } + output { + elasticsearch { + hosts => [ "${QA_ES_ES_HOSTS}" ] + user => "${QA_ES_ES_USER}" + password => "${QA_ES_ES_PASSWORD}" + ssl_certificate_authorities => "${QA_ES_ES_SSL_CERTIFICATE_AUTHORITY}" + } + } + +elasticsearchRefs: + - clusterName: prod-es + name: production + - clusterName: qa-es + name: qa + namespace: qa + +services: + - name: beats + service: + spec: + type: ClusterIP + ports: + - port: 5044 + name: "filebeat" + protocol: TCP + targetPort: 5044 + diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/examples/volumes.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/examples/volumes.yaml new file mode 100644 index 00000000..83e3dece --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/examples/volumes.yaml @@ -0,0 +1,107 @@ +--- +# values corresponding to config/recipes/logstash/logstash-volumes.yaml +version: 9.1.0 + +config: + log.level: info + queue.type: persisted + path.queue: /usr/share/logstash/pq + +podTemplate: + spec: + containers: + - name: logstash + volumeMounts: + - mountPath: /usr/share/logstash/pq + name: pq + readOnly: false + - mountPath: /usr/share/logstash/dlq + name: dlq + readOnly: false + +pipelines: + - pipeline.id: dlq_read + dead_letter_queue.enable: false + config.string: | + input { + dead_letter_queue { + path => "/usr/share/logstash/dlq" + commit_offsets => true + pipeline_id => "beats" + clean_consumed => true + } + } + filter { + mutate { + remove_field => "[geoip][location]" + } + } + output { + elasticsearch { + hosts => [ "${ECK_ES_HOSTS}" ] + user => "${ECK_ES_USER}" + password => "${ECK_ES_PASSWORD}" + ssl_certificate_authorities => "${ECK_ES_SSL_CERTIFICATE_AUTHORITY}" + } + } + - pipeline.id: beats + dead_letter_queue.enable: true + path.dead_letter_queue: /usr/share/logstash/dlq + config.string: | + input { + beats { + port => 5044 + } + } + filter { + grok { + match => { "message" => "%{HTTPD_COMMONLOG}"} + } + geoip { + source => "[source][address]" + target => "[source]" + } + } + output { + elasticsearch { + hosts => [ "${ECK_ES_HOSTS}" ] + user => "${ECK_ES_USER}" + password => "${ECK_ES_PASSWORD}" + ssl_certificate_authorities => "${ECK_ES_SSL_CERTIFICATE_AUTHORITY}" + } + } + +volumeClaimTemplates: + - metadata: + name: pq + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + - metadata: + name: dlq + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi + + +elasticsearchRefs: + - clusterName: eck + name: elasticsearch + +services: + - name: beats + service: + spec: + type: ClusterIP + ports: + - port: 5044 + name: "filebeat" + protocol: TCP + targetPort: 5044 + diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/templates/NOTES.txt b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/templates/NOTES.txt new file mode 100644 index 00000000..c2f255af --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/templates/NOTES.txt @@ -0,0 +1,6 @@ + +1. Check Logstash status + $ kubectl get logstash {{ include "logstash.fullname" . }} -n {{ .Release.Namespace }} + +2. Check Logstash pod status + $ kubectl get pods --namespace={{ .Release.Namespace }} -l logstash.k8s.elastic.co/name={{ include "logstash.fullname" . }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/templates/_helpers.tpl b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/templates/_helpers.tpl new file mode 100644 index 00000000..7efd669f --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "logstash.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "logstash.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "logstash.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "logstash.labels" -}} +helm.sh/chart: {{ include "logstash.chart" . }} +{{ include "logstash.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.labels }} +{{ toYaml .Values.labels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "logstash.selectorLabels" -}} +app.kubernetes.io/name: {{ include "logstash.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/templates/logstash.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/templates/logstash.yaml new file mode 100644 index 00000000..8ba52ef6 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/templates/logstash.yaml @@ -0,0 +1,58 @@ +--- +apiVersion: logstash.k8s.elastic.co/v1alpha1 +kind: Logstash +metadata: + name: {{ include "logstash.fullname" . }} + labels: + {{- include "logstash.labels" . | nindent 4 }} + annotations: + eck.k8s.elastic.co/license: basic + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + version: {{ required "A Logstash version is required" .Values.version }} + count: {{ required "A pod count is required" .Values.count }} + {{- with .Values.image }} + image: {{ . }} + {{- end }} + {{- with .Values.serviceAccountName }} + serviceAccountName: {{ . }} + {{- end }} + {{- with .Values.revisionHistoryLimit }} + revisionHistoryLimit: {{ . }} + {{- end }} + + {{- if and .Values.config .Values.configRef }} + {{- fail "config and configRef are mutually exclusive!" }} + {{- end }} + {{- with .Values.config }} + config: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.configRef }} + configRef: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.podTemplate }} + podTemplate: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.monitoring }} + monitoring: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if and .Values.pipelines .Values.pipelinesRef }} + {{- fail "pipelines and pipelinesRef are mutually exclusive!" }} + {{- end }} + {{- with .Values.pipelinesRef }} + pipelinesRef: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.pipelines }} + pipelines: {{ toYaml .Values.pipelines | nindent 4 }} + {{- end }} + volumeClaimTemplates: {{ toYaml .Values.volumeClaimTemplates | nindent 4 }} + elasticsearchRefs: {{ toYaml .Values.elasticsearchRefs | nindent 4 }} + services: {{ toYaml .Values.services | nindent 4 }} + secureSettings: {{ toYaml .Values.secureSettings | nindent 4 }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/values.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/values.yaml new file mode 100644 index 00000000..8be00932 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/charts/eck-logstash/values.yaml @@ -0,0 +1,115 @@ +--- +# Default values for eck-logstash. +# This is a YAML-formatted file. + +# Overridable names of the Logstash resource. +# By default, this is the Release name set for the chart, +# followed by 'eck-logstash'. +# +# nameOverride will override the name of the Chart with the name set here, +# so nameOverride: quickstart, would convert to '{{ Release.name }}-quickstart' +# +# nameOverride: "quickstart" +# +# fullnameOverride will override both the release name, and the chart name, +# and will name the Logstash resource exactly as specified. +# +# fullnameOverride: "quickstart" + +# Version of Logstash. +# +version: 9.1.0 + +# Logstash Docker image to deploy +# +# image: + +# Used to check access from the current resource to a resource (for ex. a remote Elasticsearch cluster) in a different namespace. +# Can only be used if ECK is enforcing RBAC on references. +# +# serviceAccountName: "" + +# Labels that will be applied to Logstash. +# +labels: {} + +# Annotations that will be applied to Logstash. +# +annotations: {} + +# Number of revisions to retain to allow rollback in the underlying StatefulSets. +# By default, if not set, Kubernetes sets 10. +# +# revisionHistoryLimit: 2 + +# Controlling the number of pods. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-logstash-scaling-logstash.html +# +count: 1 + +# The logstash configuration, the ECK equivalent to logstash.yml +# +# NOTE: The `config` and `configRef` fields are mutually exclusive. Only one of them should be defined at a time, +# as using both may cause conflicts. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-logstash-configuration.html#k8s-logstash-configuring-logstash +# +config: {} + +# Reference a configuration in a Secret. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-logstash-configuration.html#k8s-logstash-configuring-logstash +# +# configRef: +# secretName: '' + +# Set podTemplate to customize the pod used by Logstash +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-customize-pods.html +# +podTemplate: {} + +# Settings for configuring stack monitoring. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-stack-monitoring.html +# +monitoring: {} + # metrics: + # elasticsearchRefs: + # - name: monitoring + # namespace: observability + # logs: + # elasticsearchRefs: + # - name: monitoring + # namespace: observability + +# The Logstash pipelines, the ECK equivalent to pipelines.yml +# +# NOTE: The `pipelines` and `pipelinesRef` fields are mutually exclusive. Only one of them should be defined at a time, +# as using both may cause conflicts. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-logstash-configuration.html#k8s-logstash-pipelines +# +pipelines: [] + +# Reference a pipelines configuration in a Secret. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-logstash-configuration.html#k8s-logstash-pipelines +# +# pipelinesRef: +# secretName: '' + +# volumeClaimTemplates +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-logstash-configuration.html#k8s-volume-claim-settings +# +volumeClaimTemplates: [] + +# ElasticsearchRefs are references to Elasticsearch clusters running in the same Kubernetes cluster. +# Ensure that the 'clusterName' field matches what is referenced in the pipeline. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-logstash-configuration.html#k8s-logstash-pipelines-es +# +elasticsearchRefs: [] +# - namespace: '' +# name: '' +# clusterName: '' +# serviceName: '' +# secretName: '' + +services: [] + +# SecureSettings is a list of references to Kubernetes Secrets containing sensitive configuration options for the Logstash +secureSettings: [] diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/examples/agent/fleet-agents.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/examples/agent/fleet-agents.yaml new file mode 100644 index 00000000..4358b6f6 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/examples/agent/fleet-agents.yaml @@ -0,0 +1,122 @@ +--- +eck-elasticsearch: + enabled: true + + # Name of the Elasticsearch instance. + # + fullnameOverride: elasticsearch + + nodeSets: + - name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false + +eck-kibana: + enabled: true + + # Name of the Kibana instance. + # + fullnameOverride: kibana + + # Reference to ECK-managed Elasticsearch instance, ideally from {{ "elasticsearch.fullname" }} + # + elasticsearchRef: + name: elasticsearch + + config: + # Note that these are specific to the namespace into which this example is installed, and are + # using `elastic-stack` as configured here and detailed in the README when installing: + # + # `helm install es-kb-quickstart elastic/eck-stack -n elastic-stack` + # + # If installed outside of the `elastic-stack` namespace, the following 2 lines need modification. + xpack.fleet.agents.elasticsearch.hosts: ["https://elasticsearch-es-http.elastic-stack.svc:9200"] + xpack.fleet.agents.fleet_server.hosts: ["https://fleet-server-agent-http.elastic-stack.svc:8220"] + xpack.fleet.packages: + - name: system + version: latest + - name: elastic_agent + version: latest + - name: fleet_server + version: latest + - name: kubernetes + version: latest + xpack.fleet.agentPolicies: + - name: Fleet Server on ECK policy + id: eck-fleet-server + namespace: default + is_managed: true + monitoring_enabled: + - logs + - metrics + package_policies: + - name: fleet_server-1 + id: fleet_server-1 + package: + name: fleet_server + - name: Elastic Agent on ECK policy + id: eck-agent + namespace: default + is_managed: true + monitoring_enabled: + - logs + - metrics + unenroll_timeout: 900 + package_policies: + - package: + name: system + name: system-1 + - package: + name: kubernetes + name: kubernetes-1 + +eck-agent: + enabled: true + + # Agent policy to be used. + policyID: eck-agent + # Reference to ECK-managed Kibana instance. + # + kibanaRef: + name: kibana + elasticsearchRefs: [] + # Reference to ECK-managed Fleet instance. + # + fleetServerRef: + name: fleet-server + + mode: fleet + daemonSet: + podTemplate: + spec: + serviceAccountName: elastic-agent + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + automountServiceAccountToken: true + securityContext: + runAsUser: 0 + +eck-fleet-server: + enabled: true + + fullnameOverride: "fleet-server" + + deployment: + replicas: 1 + podTemplate: + spec: + serviceAccountName: fleet-server + automountServiceAccountToken: true + + # Agent policy to be used. + policyID: eck-fleet-server + kibanaRef: + name: kibana + elasticsearchRefs: + - name: elasticsearch diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/examples/apm-server/basic.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/examples/apm-server/basic.yaml new file mode 100644 index 00000000..227b5825 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/examples/apm-server/basic.yaml @@ -0,0 +1,52 @@ +--- +eck-elasticsearch: + enabled: true + + # Name of the Elasticsearch instance. + # + fullnameOverride: elasticsearch + + nodeSets: + - name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false + +eck-kibana: + enabled: true + + # Name of the Kibana instance. + # + fullnameOverride: kibana + + spec: + config: + xpack.fleet.packages: + - name: apm + version: latest + +eck-apm-server: + enabled: true + + # Count of APM Server replicas to create. + # + count: 1 + + # Reference to ECK-managed Elasticsearch resource. + # + elasticsearchRef: + name: elasticsearch + kibanaRef: + name: kibana + http: + service: + spec: + ports: + - name: http + port: 8200 + targetPort: 8200 diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/examples/apm-server/jaeger-with-http-configuration.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/examples/apm-server/jaeger-with-http-configuration.yaml new file mode 100644 index 00000000..b694955f --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/examples/apm-server/jaeger-with-http-configuration.yaml @@ -0,0 +1,60 @@ +--- +eck-elasticsearch: + enabled: true + + # Name of the Elasticsearch instance. + # + fullnameOverride: elasticsearch + + nodeSets: + - name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false + +eck-kibana: + enabled: true + + # Name of the Kibana instance. + # + fullnameOverride: kibana + + spec: + config: + xpack.fleet.packages: + - name: apm + version: latest + +eck-apm-server: + enabled: true + + # Count of APM Server replicas to create. + # + count: 1 + + config: + name: elastic-apm + apm-server.jaeger.grpc.enabled: true + apm-server.jaeger.grpc.host: "0.0.0.0:14250" + + # Reference to ECK-managed Elasticsearch resource. + # + elasticsearchRef: + name: elasticsearch + kibanaRef: + name: kibana + http: + service: + spec: + ports: + - name: http + port: 8200 + targetPort: 8200 + - name: grpc + port: 14250 + targetPort: 14250 diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/examples/beats/metricbeat_hosts.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/examples/beats/metricbeat_hosts.yaml new file mode 100644 index 00000000..6ef637ea --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/examples/beats/metricbeat_hosts.yaml @@ -0,0 +1,217 @@ +eck-elasticsearch: + enabled: true + + # Name of the Elasticsearch resource. + # + fullnameOverride: quickstart + + # Version of Elasticsearch. + # + version: 9.1.0 + + nodeSets: + - name: default + count: 3 + config: + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + node.store.allow_mmap: false + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 100Gi + # Adjust to your storage class name + # + # storageClassName: local-storage + +eck-kibana: + enabled: true + + # Name of the Kibana resource. + # + fullnameOverride: quickstart + + # Version of Kibana. + # + version: 9.1.0 + + spec: + # Count of Kibana replicas to create. + # + count: 1 + + # Reference to ECK-managed Elasticsearch resource, ideally from {{ "elasticsearch.fullname" }} + # + elasticsearchRef: + name: quickstart + +eck-beats: + enabled: true + name: metricbeat + type: metricbeat + version: 9.1.0 + elasticsearchRef: + name: quickstart + kibanaRef: + name: quickstart + config: + # Since filebeat is used in the default values, this needs to be removed with an empty list. + filebeat.inputs: [] + metricbeat: + autodiscover: + providers: + - hints: + default_config: {} + enabled: "true" + node: ${NODE_NAME} + type: kubernetes + modules: + - module: system + period: 10s + metricsets: + - cpu + - load + - memory + - network + - process + - process_summary + process: + include_top_n: + by_cpu: 5 + by_memory: 5 + processes: + - .* + - module: system + period: 1m + metricsets: + - filesystem + - fsstat + processors: + - drop_event: + when: + regexp: + system: + filesystem: + mount_point: ^/(sys|cgroup|proc|dev|etc|host|lib)($|/) + - module: kubernetes + period: 10s + node: ${NODE_NAME} + hosts: + - https://${NODE_NAME}:10250 + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + ssl: + verification_mode: none + metricsets: + - node + - system + - pod + - container + - volume + processors: + - add_cloud_metadata: {} + - add_host_metadata: {} + daemonSet: + podTemplate: + spec: + serviceAccountName: metricbeat + automountServiceAccountToken: true # some older Beat versions are depending on this settings presence in k8s context + containers: + - args: + - -e + - -c + - /etc/beat.yml + - --system.hostfs=/hostfs + name: metricbeat + volumeMounts: + - mountPath: /hostfs/sys/fs/cgroup + name: cgroup + - mountPath: /var/run/docker.sock + name: dockersock + - mountPath: /hostfs/proc + name: proc + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + dnsPolicy: ClusterFirstWithHostNet + hostNetwork: true # Allows to provide richer host metadata + securityContext: + runAsUser: 0 + terminationGracePeriodSeconds: 30 + volumes: + - hostPath: + path: /sys/fs/cgroup + name: cgroup + - hostPath: + path: /var/run/docker.sock + name: dockersock + - hostPath: + path: /proc + name: proc + + clusterRole: + # permissions needed for metricbeat + # source: https://www.elastic.co/guide/en/beats/metricbeat/current/metricbeat-module-kubernetes.html + name: metricbeat + rules: + - apiGroups: + - "" + resources: + - nodes + - namespaces + - events + - pods + verbs: + - get + - list + - watch + - apiGroups: + - "extensions" + resources: + - replicasets + verbs: + - get + - list + - watch + - apiGroups: + - apps + resources: + - statefulsets + - deployments + - replicasets + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - nodes/stats + verbs: + - get + - nonResourceURLs: + - /metrics + verbs: + - get + + serviceAccount: + name: metricbeat + + clusterRoleBinding: + name: metricbeat + subjects: + - kind: ServiceAccount + name: metricbeat + roleRef: + kind: ClusterRole + name: metricbeat + apiGroup: rbac.authorization.k8s.io diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/examples/custom-elasticsearch-kibana.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/examples/custom-elasticsearch-kibana.yaml new file mode 100644 index 00000000..74f625de --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/examples/custom-elasticsearch-kibana.yaml @@ -0,0 +1,78 @@ +--- +eck-elasticsearch: + # Name of the Elasticsearch resource. + # + fullnameOverride: quickstart + + # Version of Elasticsearch. + # + version: 9.1.0 + + nodeSets: + - name: default + count: 1 + config: + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 100Gi + # Adjust to your storage class name + # + # storageClassName: local-storage + +eck-kibana: + # Name of the Kibana resource. + # + fullnameOverride: quickstart + + # Version of Kibana. + # + version: 9.1.0 + + spec: + # Count of Kibana replicas to create. + # + count: 1 + + # Reference to ECK-managed Elasticsearch resource, ideally from {{ "elasticsearch.fullname" }} + # + elasticsearchRef: + name: quickstart + # namespace: default + http: + service: + spec: + # Type of service to deploy for Kibana. + # This deploys a load balancer in a cloud service provider, where supported. + # + type: LoadBalancer + # tls: + # selfSignedCertificate: + # subjectAltNames: + # - ip: 1.2.3.4 + # - dns: kibana.example.com + podTemplate: + spec: + containers: + - name: kibana + env: + - name: NODE_OPTIONS + value: "--max-old-space-size=2048" + resources: + requests: + memory: 1Gi + cpu: 0.5 + limits: + memory: 2.5Gi + cpu: 2 diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/examples/elasticsearch/hot-warm-cold.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/examples/elasticsearch/hot-warm-cold.yaml new file mode 100644 index 00000000..919cb4c7 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/examples/elasticsearch/hot-warm-cold.yaml @@ -0,0 +1,199 @@ +--- +eck-elasticsearch: + nodeSets: + - name: masters + count: 1 + config: + node.roles: ["master"] + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + spec: + containers: + - name: elasticsearch + resources: + limits: + memory: 8Gi + cpu: 2 + # Affinity/Anti-affinity settings for controlling the 'spreading' of Elasticsearch + # pods across existing hosts. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html#k8s-affinity-options + # + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: beta.kubernetes.io/instance-type + # operator: In + # # This should be adjusted to the instance type according to your setup + # # + # values: + # - highio + # Volume Claim settings. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-volume-claim-templates.html + # + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Ti + # Adjust to your storage class name + # + # storageClassName: local-storage + - name: hot + count: 1 + config: + node.roles: ["data_hot", "data_content", "ingest"] + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + spec: + containers: + - name: elasticsearch + resources: + limits: + memory: 16Gi + cpu: 4 + # Affinity/Anti-affinity settings for controlling the 'spreading' of Elasticsearch + # pods across existing hosts. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html#k8s-affinity-options + # + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: beta.kubernetes.io/instance-type + # operator: In + # # This should be adjusted to the instance type according to your setup + # # + # values: + # - highio + # Volume Claim settings. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-volume-claim-templates.html + # + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Ti + # Adjust to your storage class name + # + # storageClassName: local-storage + - name: warm + count: 1 + config: + node.roles: ["data_warm"] + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + spec: + containers: + - name: elasticsearch + resources: + limits: + memory: 16Gi + cpu: 2 + # Affinity/Anti-affinity settings for controlling the 'spreading' of Elasticsearch + # pods across existing hosts. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html#k8s-affinity-options + # + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: beta.kubernetes.io/instance-type + # operator: In + # # This should be adjusted to the instance type according to your setup + # # + # values: + # - highstorage + # Volume Claim settings. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-volume-claim-templates.html + # + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Ti + # Adjust to your storage class name + # + # storageClassName: local-storage + - name: cold + count: 1 + config: + node.roles: ["data_cold"] + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + spec: + containers: + - name: elasticsearch + resources: + limits: + memory: 8Gi + cpu: 2 + # Affinity/Anti-affinity settings for controlling the 'spreading' of Elasticsearch + # pods across existing hosts. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html#k8s-affinity-options + # + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: beta.kubernetes.io/instance-type + # operator: In + # # This should be adjusted to the instance type according to your setup + # # + # values: + # - highstorage + # Volume Claim settings. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-volume-claim-templates.html + # + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 20Ti + # Adjust to your storage class name + # + # storageClassName: local-storage diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/examples/elasticsearch/ingress/elasticsearch-ingress-gke.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/examples/elasticsearch/ingress/elasticsearch-ingress-gke.yaml new file mode 100644 index 00000000..0ca2e8a5 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/examples/elasticsearch/ingress/elasticsearch-ingress-gke.yaml @@ -0,0 +1,40 @@ +# The following is an example of an Elasticsearch resource that is configured to use an Ingress resource in a GKE cluster. +# Additional examples of exposing Elasticsearch with Ingress resources can be found in the following location: +# https://github.com/elastic/cloud-on-k8s/tree/main/deploy/eck-stack/charts/eck-elasticsearch/examples/ingress +# +eck-elasticsearch: + enabled: true + + ingress: + enabled: true + annotations: + my: annotation + labels: + my: label + pathType: Prefix + hosts: + - host: "elasticsearch.company.dev" + path: "/" + http: + service: + metadata: + annotations: + # This is required for `ClusterIP` services (which are the default ECK service type) to be used with Ingress in GKE clusters. + cloud.google.com/neg: '{"ingress": true}' + # This is required to enable the GKE Ingress Controller to use HTTPS as the backend protocol. + cloud.google.com/app-protocols: '{"https":"HTTPS"}' + nodeSets: + - name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false + # Enable anonymous access to allow GCLB health probes to succeed + xpack.security.authc: + anonymous: + username: anon + roles: monitoring_user diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/examples/enterprise-search/basic.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/examples/enterprise-search/basic.yaml new file mode 100644 index 00000000..aeb61b06 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/examples/enterprise-search/basic.yaml @@ -0,0 +1,42 @@ +--- +eck-elasticsearch: + enabled: true + + # Name of the Elasticsearch instance. + # + fullnameOverride: elasticsearch + + nodeSets: + - name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false + +eck-kibana: + enabled: true + + # Name of the Kibana instance. + # + fullnameOverride: kibana + + elasticsearchRef: + name: elasticsearch + + spec: + enterpriseSearchRef: + name: enterprise-search + +eck-enterprise-search: + enabled: true + + # Name of the Enterprise Search instance. + # + fullnameOverride: enterprise-search + + elasticsearchRef: + name: elasticsearch diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/examples/enterprise-search/with-custom-configuration.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/examples/enterprise-search/with-custom-configuration.yaml new file mode 100644 index 00000000..a7c3ad49 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/examples/enterprise-search/with-custom-configuration.yaml @@ -0,0 +1,52 @@ +--- +eck-elasticsearch: + enabled: true + + # Name of the Elasticsearch instance. + # + fullnameOverride: elasticsearch + + nodeSets: + - name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false + +eck-kibana: + enabled: true + + # Name of the Kibana instance. + # + fullnameOverride: kibana + + elasticsearchRef: + name: elasticsearch + + spec: + enterpriseSearchRef: + name: enterprise-search + +eck-enterprise-search: + enabled: true + + # Name of the Enterprise Search instance. + # + fullnameOverride: enterprise-search + + config: + # configure app search document size limit + app_search.engine.document_size.limit: 100kb + + http: + service: + metadata: + labels: + my-custom: label + + elasticsearchRef: + name: elasticsearch diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/examples/kibana/http-configuration.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/examples/kibana/http-configuration.yaml new file mode 100644 index 00000000..d8a4831d --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/examples/kibana/http-configuration.yaml @@ -0,0 +1,23 @@ +--- +eck-kibana: + # Count of Kibana replicas to create. + # + count: 1 + + # Reference to ECK-managed Elasticsearch resource, ideally from {{ "elasticsearch.fullname" }} + # + elasticsearchRef: + name: es-quickstart-eck-elasticsearch + # namespace: default + http: + service: + spec: + # Type of service to deploy for Kibana. + # This deploys a load balancer in a cloud service provider, where supported. + # + type: LoadBalancer + # tls: + # selfSignedCertificate: + # subjectAltNames: + # - ip: 1.2.3.4 + # - dns: kibana.example.com diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/examples/kibana/ingress/kibana-gke.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/examples/kibana/ingress/kibana-gke.yaml new file mode 100644 index 00000000..4aa1dc06 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/examples/kibana/ingress/kibana-gke.yaml @@ -0,0 +1,80 @@ +# The following is an example of a Kibana resource that is configured to use an Ingress resource in a GKE cluster. +# Additional examples of exposing Kibana with Ingress resources can be found in the following location: +# https://github.com/elastic/cloud-on-k8s/tree/main/deploy/eck-stack/charts/eck-kibana/examples/ingress +# +eck-elasticsearch: + enabled: true + + # Name of the Elasticsearch instance. + # + fullnameOverride: elasticsearch + + ingress: + enabled: true + annotations: + my: annotation + labels: + my: label + pathType: Prefix + hosts: + - host: "elasticsearch.company.dev" + path: "/" + tls: + enabled: true + + http: + service: + metadata: + annotations: + # This is required for `ClusterIP` services (which are the default ECK service type) to be used with Ingress in GKE clusters. + cloud.google.com/neg: '{"ingress": true}' + cloud.google.com/app-protocols: '{"https":"HTTPS"}' + + nodeSets: + - name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false + # Enable anonymous access to allow GCLB health probes to succeed + xpack.security.authc: + anonymous: + username: anon + roles: monitoring_user + +eck-kibana: + enabled: true + + # Name of the Kibana instance. + # + fullnameOverride: kibana + + # Reference to ECK-managed Elasticsearch instance, ideally from {{ "elasticsearch.fullname" }} + # + elasticsearchRef: + name: elasticsearch + + config: + server: + publicBaseUrl: "https://kibana.company.dev" + + http: + service: + metadata: + annotations: + # This is required for `ClusterIP` services (which are the default ECK service type) to be used with Ingress in GKE clusters. + cloud.google.com/neg: '{"ingress": true}' + cloud.google.com/app-protocols: '{"https":"HTTPS"}' + + ingress: + enabled: true + pathType: Prefix + hosts: + - host: "kibana.company.dev" + path: "/" + tls: + enabled: true diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/examples/logstash/basic-eck.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/examples/logstash/basic-eck.yaml new file mode 100644 index 00000000..38255b0a --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/examples/logstash/basic-eck.yaml @@ -0,0 +1,112 @@ +--- +eck-elasticsearch: + nodeSets: + - name: default + count: 3 + config: + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + spec: + containers: + - name: elasticsearch + resources: + limits: + memory: 2Gi + requests: + memory: 2Gi +eck-kibana: + enabled: true + spec: + count: 1 + elasticsearchRef: + name: elasticsearch +eck-beats: + enabled: true + deployment: + podTemplate: + spec: + automountServiceAccountToken: true + initContainers: + - name: download-tutorial + image: curlimages/curl + command: ["/bin/sh"] + args: ["-c", "curl -L https://download.elastic.co/demos/logstash/gettingstarted/logstash-tutorial.log.gz | gunzip -c > /data/logstash-tutorial.log"] + volumeMounts: + - name: data + mountPath: /data + containers: + - name: filebeat + securityContext: + runAsUser: 1000 + volumeMounts: + - name: data + mountPath: /data + - name: beat-data + mountPath: /usr/share/filebeat/data + volumes: + - name: data + emptydir: {} + - name: beat-data + emptydir: {} + type: filebeat + config: + filebeat.inputs: + - type: log + paths: + - /data/logstash-tutorial.log + processors: + - add_host_metadata: {} + - add_cloud_metadata: {} + output.logstash: + # This needs to be {{logstash-name}}-ls-beats:5044 + hosts: ["logstash-ls-beats-ls-beats:5044"] +eck-logstash: + enabled: true + # This is required to be able to set the logstash + # output of beats in a consistent manner. + fullnameOverride: "logstash-ls-beats" + elasticsearchRefs: + # This clusterName is required to match the environment variables + # used in the below config.string output section. + - clusterName: eck + name: elasticsearch + pipelines: + - pipeline.id: main + config.string: | + input { + beats { + port => 5044 + } + } + filter { + grok { + match => { "message" => "%{HTTPD_COMMONLOG}"} + } + geoip { + source => "[source][address]" + target => "[source]" + } + } + output { + elasticsearch { + hosts => [ "${ECK_ES_HOSTS}" ] + user => "${ECK_ES_USER}" + password => "${ECK_ES_PASSWORD}" + ssl_certificate_authorities => "${ECK_ES_SSL_CERTIFICATE_AUTHORITY}" + } + } + services: + - name: beats + service: + spec: + type: ClusterIP + ports: + - port: 5044 + name: "filebeat" + protocol: TCP + targetPort: 5044 diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/templates/NOTES.txt b/packs/elastic-stack-0.16.0/charts/eck-stack/templates/NOTES.txt new file mode 100644 index 00000000..65cdae60 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/templates/NOTES.txt @@ -0,0 +1,10 @@ +Elasticsearch ECK-Stack {{ .Chart.Version }} has been deployed successfully! + +To see status of all resources, run + +kubectl get elastic -n {{ .Release.Namespace }} -l "app.kubernetes.io/instance"={{ .Release.Name }} + +More information on the Elastic ECK Operator, and its Helm chart can be found +within our documentation. + +https://www.elastic.co/guide/en/cloud-on-k8s/current/index.html diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/templates/_helpers.tpl b/packs/elastic-stack-0.16.0/charts/eck-stack/templates/_helpers.tpl new file mode 100644 index 00000000..cef61bdb --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/templates/_helpers.tpl @@ -0,0 +1,48 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "eck-stack.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "eck-stack.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "eck-stack.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "eck-stack.labels" -}} +helm.sh/chart: {{ include "eck-stack.chart" . }} +{{ include "eck-stack.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "eck-stack.selectorLabels" -}} +app.kubernetes.io/name: {{ include "eck-stack.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/packs/elastic-stack-0.16.0/charts/eck-stack/values.yaml b/packs/elastic-stack-0.16.0/charts/eck-stack/values.yaml new file mode 100644 index 00000000..5d504211 --- /dev/null +++ b/packs/elastic-stack-0.16.0/charts/eck-stack/values.yaml @@ -0,0 +1,50 @@ +--- +# Default values for eck-stack. +# This is a YAML-formatted file. + +# If enabled, will use the eck-elasticsearch chart and deploy an Elasticsearch resource. +# +eck-elasticsearch: + enabled: true + # This is adjusting the full name of the elasticsearch resource so that both the eck-elasticsearch + # and the eck-kibana chart work together by default in the eck-stack chart. + fullnameOverride: elasticsearch + +# If enabled, will use the eck-kibana chart and deploy a Kibana resource. +# +eck-kibana: + enabled: true + # This is also adjusting the kibana reference to the elasticsearch resource named previously so that + # both the eck-elasticsearch and the eck-kibana chart work together by default in the eck-stack chart. + elasticsearchRef: + name: elasticsearch + +# If enabled, will use the eck-agent chart and deploy an Elastic Agent instance. +# +eck-agent: + enabled: false + +# If enabled, will use the eck-fleet-server chart and deploy a Fleet Server resource. +# +eck-fleet-server: + enabled: false + +# If enabled, will use the eck-beats chart and deploy a Beats resource. +# +eck-beats: + enabled: false + +# If enabled, will use the eck-logstash chart and deploy a Logstash resource. +# +eck-logstash: + enabled: false + +# If enabled, will use the eck-apm-server chart and deploy a standalone APM Server resource. +# +eck-apm-server: + enabled: false + +# If enabled, will use the eck-enterprise-search chart and deploy a Enterprise Search resource. +# +eck-enterprise-search: + enabled: false diff --git a/packs/elastic-stack-0.16.0/logo.png b/packs/elastic-stack-0.16.0/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..fa70b78daa45585ec0f802dfe637e4ce2172d6f8 GIT binary patch literal 5810 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 /data/logstash-tutorial.log"] + volumeMounts: + - name: data + mountPath: /data + containers: + - name: filebeat + securityContext: + runAsUser: 1000 + volumeMounts: + - name: data + mountPath: /data + - name: beat-data + mountPath: /usr/share/filebeat/data + volumes: + - name: data + emptydir: {} + - name: beat-data + emptydir: {} + eck-logstash: + enabled: true + # This is required to be able to set the logstash + # output of beats in a consistent manner. + fullnameOverride: "logstash-ls-beats" + elasticsearchRefs: + # This clusterName is required to match the environment variables + # used in the below config.string output section. + - clusterName: eck + name: elasticsearch + pipelines: + - pipeline.id: main + config.string: | + input { + beats { + port => 5044 + } + } + filter { + grok { + match => { "message" => "%{HTTPD_COMMONLOG}"} + } + geoip { + source => "[source][address]" + target => "[source]" + } + } + output { + elasticsearch { + hosts => [ "${ECK_ES_HOSTS}" ] + user => "${ECK_ES_USER}" + password => "${ECK_ES_PASSWORD}" + ssl_certificate_authorities => "${ECK_ES_SSL_CERTIFICATE_AUTHORITY}" + } + } + services: + - name: beats + service: + spec: + type: ClusterIP + ports: + - port: 5044 + name: "filebeat" + protocol: TCP + targetPort: 5044 \ No newline at end of file diff --git a/packs/elastic-stack-0.16.0/values.yaml b/packs/elastic-stack-0.16.0/values.yaml new file mode 100644 index 00000000..e9f44a2d --- /dev/null +++ b/packs/elastic-stack-0.16.0/values.yaml @@ -0,0 +1,71 @@ +# Default values for eck-elastic-operator +# This is a YAML-formatted file +pack: + content: + images: + - image: docker.elastic.co/kibana/kibana:9.1.0 + - image: docker.elastic.co/elasticsearch/elasticsearch:9.1.0 + - image: docker.elastic.co/logstash/logstash:9.1.0 + - image: docker.elastic.co/beats/filebeat:9.1.0 + - image: docker.io/curlimages/curl + + + charts: + - repo: https://helm.elastic.co/ + name: eck-stack + version: 0.16.0 + #The namespace (on the target cluster) to install this chart + #When not found, a new namespace will be created + namespace: "elastic-stack" + +charts: + eck-stack: + # Default values for eck-stack. + # This is a YAML-formatted file. + + # If enabled, will use the eck-elasticsearch chart and deploy an Elasticsearch resource. + # + eck-elasticsearch: + enabled: true + # This is adjusting the full name of the elasticsearch resource so that both the eck-elasticsearch + # and the eck-kibana chart work together by default in the eck-stack chart. + fullnameOverride: elasticsearch + + # If enabled, will use the eck-kibana chart and deploy a Kibana resource. + # + eck-kibana: + enabled: true + # This is also adjusting the kibana reference to the elasticsearch resource named previously so that + # both the eck-elasticsearch and the eck-kibana chart work together by default in the eck-stack chart. + elasticsearchRef: + name: elasticsearch + + # If enabled, will use the eck-agent chart and deploy an Elastic Agent instance. + # + eck-agent: + enabled: false + + # If enabled, will use the eck-fleet-server chart and deploy a Fleet Server resource. + # + eck-fleet-server: + enabled: false + + # If enabled, will use the eck-beats chart and deploy a Beats resource. + # + eck-beats: + enabled: false + + # If enabled, will use the eck-logstash chart and deploy a Logstash resource. + # + eck-logstash: + enabled: false + + # If enabled, will use the eck-apm-server chart and deploy a standalone APM Server resource. + # + eck-apm-server: + enabled: false + + # If enabled, will use the eck-enterprise-search chart and deploy a Enterprise Search resource. + # + eck-enterprise-search: + enabled: false \ No newline at end of file From 5482192778dc7daef48ab42d91c91fcd95509bd3 Mon Sep 17 00:00:00 2001 From: svalenciah19 Date: Tue, 4 Nov 2025 15:26:45 -0500 Subject: [PATCH 5/8] Upgrade elastick-operator pack to version 3.2.0 --- packs/elastic-operator-3.2.0/README.md | 43 + .../charts/eck-operator-3.2.0.tgz | Bin 0 -> 136454 bytes .../charts/eck-operator/.helmignore | 24 + .../charts/eck-operator/Chart.lock | 6 + .../charts/eck-operator/Chart.yaml | 26 + .../charts/eck-operator/LICENSE | 93 + .../charts/eck-operator/README.md | 20 + .../charts/eck-operator-crds/.helmignore | 23 + .../charts/eck-operator-crds/Chart.yaml | 21 + .../charts/eck-operator-crds/README.md | 16 + .../eck-operator-crds/templates/NOTES.txt | 1 + .../eck-operator-crds/templates/_helpers.tpl | 62 + .../eck-operator-crds/templates/all-crds.yaml | 10730 ++++++++++++++++ .../charts/eck-operator-crds/values.yaml | 7 + .../profile-disable-automounting-api.yaml | 29 + .../charts/eck-operator/profile-global.yaml | 6 + .../charts/eck-operator/profile-istio.yaml | 11 + .../eck-operator/profile-restricted.yaml | 12 + .../profile-soft-multi-tenancy.yaml | 18 + .../charts/eck-operator/templates/NOTES.txt | 2 + .../eck-operator/templates/_helpers.tpl | 383 + .../eck-operator/templates/cluster-roles.yaml | 121 + .../eck-operator/templates/configmap.yaml | 88 + .../templates/managed-namespaces.yaml | 13 + .../templates/managed-ns-network-policy.yaml | 228 + .../templates/metrics-service.yaml | 22 + .../templates/operator-namespace.yaml | 9 + .../templates/operator-network-policy.yaml | 59 + .../charts/eck-operator/templates/pdb.yaml | 19 + .../eck-operator/templates/podMonitor.yaml | 42 + .../eck-operator/templates/role-bindings.yaml | 98 + .../templates/service-account.yaml | 15 + .../templates/service-monitor.yaml | 34 + .../eck-operator/templates/statefulset.yaml | 162 + .../templates/validate-chart.yaml | 29 + .../eck-operator/templates/webhook.yaml | 473 + .../charts/eck-operator/values.yaml | 377 + packs/elastic-operator-3.2.0/logo.png | Bin 0 -> 5810 bytes packs/elastic-operator-3.2.0/pack.json | 39 + packs/elastic-operator-3.2.0/values.yaml | 395 + 40 files changed, 13756 insertions(+) create mode 100644 packs/elastic-operator-3.2.0/README.md create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator-3.2.0.tgz create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/.helmignore create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/Chart.lock create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/Chart.yaml create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/LICENSE create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/README.md create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/.helmignore create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/Chart.yaml create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/README.md create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/templates/NOTES.txt create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/templates/_helpers.tpl create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/values.yaml create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/profile-disable-automounting-api.yaml create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/profile-global.yaml create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/profile-istio.yaml create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/profile-restricted.yaml create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/profile-soft-multi-tenancy.yaml create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/templates/NOTES.txt create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/templates/_helpers.tpl create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/templates/cluster-roles.yaml create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/templates/configmap.yaml create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/templates/managed-namespaces.yaml create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/templates/managed-ns-network-policy.yaml create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/templates/metrics-service.yaml create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/templates/operator-namespace.yaml create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/templates/operator-network-policy.yaml create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/templates/pdb.yaml create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/templates/podMonitor.yaml create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/templates/role-bindings.yaml create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/templates/service-account.yaml create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/templates/service-monitor.yaml create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/templates/statefulset.yaml create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/templates/validate-chart.yaml create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/templates/webhook.yaml create mode 100644 packs/elastic-operator-3.2.0/charts/eck-operator/values.yaml create mode 100644 packs/elastic-operator-3.2.0/logo.png create mode 100644 packs/elastic-operator-3.2.0/pack.json create mode 100644 packs/elastic-operator-3.2.0/values.yaml diff --git a/packs/elastic-operator-3.2.0/README.md b/packs/elastic-operator-3.2.0/README.md new file mode 100644 index 00000000..df41d6c2 --- /dev/null +++ b/packs/elastic-operator-3.2.0/README.md @@ -0,0 +1,43 @@ +# Elastic Cloud on Kubernetes (ECK) + +Elastic Cloud on Kubernetes automates the deployment, provisioning, management, and orchestration of Elasticsearch, Kibana, APM Server, Enterprise Search, Beats, Elastic Agent, Elastic Maps Server, and Logstash on Kubernetes based on the operator pattern. + +Current features: + +* Elasticsearch, Kibana, APM Server, Enterprise Search, and Beats deployments +* TLS Certificates management +* Safe Elasticsearch cluster configuration & topology changes +* Persistent volumes usage +* Custom node configuration and attributes +* Secure settings keystore updates + +Supported versions: + +* Kubernetes 1.25-1.29 +* Elasticsearch, Kibana, APM Server: 6.8+, 7.1+, 8+, 9+ +* Enterprise Search: 7.7+, 8+, 9+ +* Beats: 7.0+, 8+, 9+ +* Elastic Agent: 7.10+ (standalone), 7.14+, 8+ (Fleet), 9+ +* Elastic Maps Server: 7.11+, 8+, 9+ +* Logstash 8.7+ + +Check the [Quickstart](https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-quickstart.html) to deploy your first cluster with ECK. + +For general questions, please see the Elastic [forums](https://discuss.elastic.co/c/eck). + +# ECK Operator Helm Chart + +A Helm chart to install the ECK Operator: the official Kubernetes operator from Elastic to orchestrate Elasticsearch, Kibana, APM Server, Enterprise Search, and Beats on Kubernetes. + +For more information about the ECK Operator, see: +- [Documentation](https://www.elastic.co/guide/en/cloud-on-k8s/current/index.html) +- [GitHub repo](https://github.com/elastic/cloud-on-k8s) + + +## Requirements + +- Supported Kubernetes versions are listed in the documentation: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s_supported_versions.html + +## Usage + +Refer to the documentation at https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-install-helm.html \ No newline at end of file diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator-3.2.0.tgz b/packs/elastic-operator-3.2.0/charts/eck-operator-3.2.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..64ef4e19cf4c15ae1a1777284cbcd9e4710c2713 GIT binary patch literal 136454 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 literal 0 HcmV?d00001 diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/.helmignore b/packs/elastic-operator-3.2.0/charts/eck-operator/.helmignore new file mode 100644 index 00000000..f5e0fb21 --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests \ No newline at end of file diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/Chart.lock b/packs/elastic-operator-3.2.0/charts/eck-operator/Chart.lock new file mode 100644 index 00000000..6ceb0ec7 --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: eck-operator-crds + repository: "" + version: 3.2.0 +digest: sha256:29bf07f8c48d5775183fea3aadd1cd3611add8af3576dd0528d45375a8a6e7aa +generated: "2025-10-30T08:49:46.07268429Z" diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/Chart.yaml b/packs/elastic-operator-3.2.0/charts/eck-operator/Chart.yaml new file mode 100644 index 00000000..5120c591 --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/Chart.yaml @@ -0,0 +1,26 @@ +apiVersion: v2 +appVersion: 3.2.0 +dependencies: +- condition: installCRDs + name: eck-operator-crds + repository: "" + version: 3.2.0 +description: Elastic Cloud on Kubernetes (ECK) operator +home: https://github.com/elastic/cloud-on-k8s +icon: https://helm.elastic.co/icons/eck.png +keywords: +- Logstash +- Elasticsearch +- Kibana +- APM Server +- Beats +- Enterprise Search +- Elastic Stack +- Operator +kubeVersion: '>=1.21.0-0' +maintainers: +- email: eck@elastic.co + name: Elastic +name: eck-operator +type: application +version: 3.2.0 diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/LICENSE b/packs/elastic-operator-3.2.0/charts/eck-operator/LICENSE new file mode 100644 index 00000000..92503a72 --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/LICENSE @@ -0,0 +1,93 @@ +Elastic License 2.0 + +URL: https://www.elastic.co/licensing/elastic-license + +## Acceptance + +By using the software, you agree to all of the terms and conditions below. + +## Copyright License + +The licensor grants you a non-exclusive, royalty-free, worldwide, +non-sublicensable, non-transferable license to use, copy, distribute, make +available, and prepare derivative works of the software, in each case subject to +the limitations and conditions below. + +## Limitations + +You may not provide the software to third parties as a hosted or managed +service, where the service provides users with access to any substantial set of +the features or functionality of the software. + +You may not move, change, disable, or circumvent the license key functionality +in the software, and you may not remove or obscure any functionality in the +software that is protected by the license key. + +You may not alter, remove, or obscure any licensing, copyright, or other notices +of the licensor in the software. Any use of the licensor’s trademarks is subject +to applicable law. + +## Patents + +The licensor grants you a license, under any patent claims the licensor can +license, or becomes able to license, to make, have made, use, sell, offer for +sale, import and have imported the software, in each case subject to the +limitations and conditions in this license. This license does not cover any +patent claims that you cause to be infringed by modifications or additions to +the software. If you or your company make any written claim that the software +infringes or contributes to infringement of any patent, your patent license for +the software granted under these terms ends immediately. If your company makes +such a claim, your patent license ends immediately for work on behalf of your +company. + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you +also gets a copy of these terms. + +If you modify the software, you must include in any modified copies of the +software prominent notices stating that you have modified the software. + +## No Other Rights + +These terms do not imply any licenses other than those expressly granted in +these terms. + +## Termination + +If you use the software in violation of these terms, such use is not licensed, +and your licenses will automatically terminate. If the licensor provides you +with a notice of your violation, and you cease all violation of this license no +later than 30 days after you receive that notice, your licenses will be +reinstated retroactively. However, if you violate these terms after such +reinstatement, any additional violation of these terms will cause your licenses +to terminate automatically and permanently. + +## No Liability + +*As far as the law allows, the software comes as is, without any warranty or +condition, and the licensor will not be liable to you for any damages arising +out of these terms or the use or nature of the software, under any kind of +legal claim.* + +## Definitions + +The **licensor** is the entity offering these terms, and the **software** is the +software the licensor makes available under these terms, including any portion +of it. + +**you** refers to the individual or entity agreeing to these terms. + +**your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control over, +are under the control of, or are under common control with that +organization. **control** means ownership of substantially all the assets of an +entity, or the power to direct its management and policies by vote, contract, or +otherwise. Control can be direct or indirect. + +**your licenses** are all the licenses granted to you for the software under +these terms. + +**use** means anything you do with the software requiring one of your licenses. + +**trademark** means trademarks, service marks, and similar rights. \ No newline at end of file diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/README.md b/packs/elastic-operator-3.2.0/charts/eck-operator/README.md new file mode 100644 index 00000000..86452e3d --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/README.md @@ -0,0 +1,20 @@ +# ECK Operator Helm Chart + +[![Artifact HUB](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/elastic)](https://artifacthub.io/packages/helm/elastic/eck-operator) + +A Helm chart to install the ECK Operator: the official Kubernetes operator from Elastic to orchestrate Elasticsearch, Kibana, APM Server, Enterprise Search, and Beats on Kubernetes. + +For more information about the ECK Operator, see: +- [Documentation](https://www.elastic.co/guide/en/cloud-on-k8s/current/index.html) +- [GitHub repo](https://github.com/elastic/cloud-on-k8s) + + +## Requirements + +- Supported Kubernetes versions are listed in the documentation: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s_supported_versions.html +- Helm >= 3.2.0 + + +## Usage + +Refer to the documentation at https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-install-helm.html diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/.helmignore b/packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/Chart.yaml b/packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/Chart.yaml new file mode 100644 index 00000000..26d3a26d --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/Chart.yaml @@ -0,0 +1,21 @@ +apiVersion: v2 +appVersion: 3.2.0 +description: ECK operator Custom Resource Definitions +home: https://github.com/elastic/cloud-on-k8s +icon: https://helm.elastic.co/icons/eck.png +keywords: +- Logstash +- Elasticsearch +- Kibana +- APM Server +- Beats +- Enterprise Search +- Elastic Stack +- Operator +kubeVersion: '>=1.21.0-0' +maintainers: +- email: eck@elastic.co + name: Elastic +name: eck-operator-crds +type: application +version: 3.2.0 diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/README.md b/packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/README.md new file mode 100644 index 00000000..698d6dd4 --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/README.md @@ -0,0 +1,16 @@ +# ECK Operator CRDs Helm Chart + +[![Artifact HUB](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/elastic)](https://artifacthub.io/packages/helm/elastic/eck-operator-crds) + +A Helm chart to install the Kubernetes Custom Resource Definitions (CRD) required by the ECK Operator: the official Kubernetes operator from Elastic to orchestrate Elasticsearch, Kibana, APM Server, Enterprise Search, and Beats on Kubernetes. This chart is usually automatically installed by the [ECK Operator Helm Chart](https://artifacthub.io/packages/helm/elastic/eck-operator) when installed using the default settings. Refer to the [installation documentation](https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-install-helm.html) for more information. + + +## Requirements + +- Supported Kubernetes versions are listed in the documentation: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s_supported_versions.html +- Helm >= 3.2.0 + + +## Usage + +Refer to the documentation at https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-install-helm.html diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/templates/NOTES.txt b/packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/templates/NOTES.txt new file mode 100644 index 00000000..1478c82b --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/templates/NOTES.txt @@ -0,0 +1 @@ +ECK Custom Resource Definitions installed. diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/templates/_helpers.tpl b/packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/templates/_helpers.tpl new file mode 100644 index 00000000..548f1bc6 --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "eck-operator-crds.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "eck-operator-crds.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "eck-operator-crds.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "eck-operator-crds.labels" -}} +helm.sh/chart: {{ include "eck-operator-crds.chart" . }} +{{ include "eck-operator-crds.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "eck-operator-crds.selectorLabels" -}} +app.kubernetes.io/name: {{ include "eck-operator-crds.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Determine effective Kubernetes version +*/}} +{{- define "eck-operator-crds.effectiveKubeVersion" -}} +{{- if .Values.global.manifestGen -}} +{{- semver .Values.global.kubeVersion -}} +{{- else -}} +{{- .Capabilities.KubeVersion.Version -}} +{{- end -}} +{{- end -}} diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml b/packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml new file mode 100644 index 00000000..97707a8b --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml @@ -0,0 +1,10730 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: agents.agent.k8s.elastic.co +spec: + group: agent.k8s.elastic.co + names: + categories: + - elastic + kind: Agent + listKind: AgentList + plural: agents + shortNames: + - agent + singular: agent + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: available + type: integer + - description: Expected nodes + jsonPath: .status.expectedNodes + name: expected + type: integer + - description: Agent version + jsonPath: .status.version + name: version + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: Agent is the Schema for the Agents API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: AgentSpec defines the desired state of the Agent + properties: + config: + description: Config holds the Agent configuration. At most one of + [`Config`, `ConfigRef`] can be specified. + type: object + x-kubernetes-preserve-unknown-fields: true + configRef: + description: |- + ConfigRef contains a reference to an existing Kubernetes Secret holding the Agent configuration. + Agent settings must be specified as yaml, under a single "agent.yml" entry. At most one of [`Config`, `ConfigRef`] + can be specified. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + daemonSet: + description: |- + DaemonSet specifies the Agent should be deployed as a DaemonSet, and allows providing its spec. + Cannot be used along with `deployment` or `statefulSet`. + properties: + podTemplate: + description: PodTemplateSpec describes the data a pod should have + when created from a template + type: object + x-kubernetes-preserve-unknown-fields: true + updateStrategy: + description: DaemonSetUpdateStrategy is a struct used to control + the update strategy for a DaemonSet. + properties: + rollingUpdate: + description: Rolling update config params. Present only if + type = "RollingUpdate". + properties: + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of nodes with an existing available DaemonSet pod that + can have an updated DaemonSet pod during during an update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up to a minimum of 1. + Default value is 0. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their a new pod created before the old pod is marked as deleted. + The update starts by launching new pods on 30% of nodes. Once an updated + pod is available (Ready for at least minReadySeconds) the old DaemonSet pod + on that node is marked deleted. If the old pod becomes unavailable for any + reason (Ready transitions to false, is evicted, or is drained) an updated + pod is immediately created on that node without considering surge limits. + Allowing surge implies the possibility that the resources consumed by the + daemonset on any given node can double if the readiness check fails, and + so resource intensive daemonsets should take into account that they may + cause evictions during disruption. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of DaemonSet pods that can be unavailable during the + update. Value can be an absolute number (ex: 5) or a percentage of total + number of DaemonSet pods at the start of the update (ex: 10%). Absolute + number is calculated from percentage by rounding up. + This cannot be 0 if MaxSurge is 0 + Default value is 1. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their pods stopped for an update at any given time. The update + starts by stopping at most 30% of those DaemonSet pods and then brings + up new DaemonSet pods in their place. Once the new pods are available, + it then proceeds onto other DaemonSet pods, thus ensuring that at least + 70% of original number of DaemonSet pods are available at all times during + the update. + x-kubernetes-int-or-string: true + type: object + type: + description: Type of daemon set update. Can be "RollingUpdate" + or "OnDelete". Default is RollingUpdate. + type: string + type: object + type: object + deployment: + description: |- + Deployment specifies the Agent should be deployed as a Deployment, and allows providing its spec. + Cannot be used along with `daemonSet` or `statefulSet`. + properties: + podTemplate: + description: PodTemplateSpec describes the data a pod should have + when created from a template + type: object + x-kubernetes-preserve-unknown-fields: true + replicas: + format: int32 + type: integer + strategy: + description: DeploymentStrategy describes how to replace existing + pods with new ones. + properties: + rollingUpdate: + description: |- + Rolling update config params. Present only if DeploymentStrategyType = + RollingUpdate. + properties: + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be scheduled above the desired number of + pods. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 25%. + Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when + the rolling update starts, such that the total number of old and new pods do not exceed + 130% of desired pods. Once old pods have been killed, + new ReplicaSet can be scaled up further, ensuring that total number of pods running + at any time during the update is at most 130% of desired pods. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 25%. + Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods + immediately when the rolling update starts. Once new pods are ready, old ReplicaSet + can be scaled down further, followed by scaling up the new ReplicaSet, ensuring + that the total number of pods available at all times during the update is at + least 70% of desired pods. + x-kubernetes-int-or-string: true + type: object + type: + description: Type of deployment. Can be "Recreate" or "RollingUpdate". + Default is RollingUpdate. + type: string + type: object + type: object + elasticsearchRefs: + description: |- + ElasticsearchRefs is a reference to a list of Elasticsearch clusters running in the same Kubernetes cluster. + Due to existing limitations, only a single ES cluster is currently supported. + items: + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + outputName: + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. + The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + type: array + fleetServerEnabled: + description: FleetServerEnabled determines whether this Agent will + launch Fleet Server. Don't set unless `mode` is set to `fleet`. + type: boolean + fleetServerRef: + description: |- + FleetServerRef is a reference to Fleet Server that this Agent should connect to to obtain it's configuration. + Don't set unless `mode` is set to `fleet`. + References to Fleet servers running outside the Kubernetes cluster via the `secretName` attribute are not supported. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. + The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + http: + description: HTTP holds the HTTP layer configuration for the Agent + in Fleet mode with Fleet Server enabled. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic + is distributed to Service endpoints. Implementations can use this field + as a hint, but are not required to guarantee strict adherence. If the + field is not set, the implementation will apply its default routing + strategy. If set to "PreferClose", implementations should prioritize + endpoints that are in the same zone. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the Agent Docker image to deploy. Version has + to match the Agent in the image. + type: string + kibanaRef: + description: |- + KibanaRef is a reference to Kibana where Fleet should be set up and this Agent should be enrolled. Don't set + unless `mode` is set to `fleet`. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. + The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + mode: + description: |- + Mode specifies the runtime mode for the Agent. The configuration can be specified locally through + `config` or `configRef` (`standalone` mode), or come from Fleet during runtime (`fleet` mode). Starting with + version 8.13.0 Fleet-managed agents support advanced configuration via a local configuration file. + See https://www.elastic.co/docs/reference/fleet/advanced-kubernetes-managed-by-fleet + Defaults to `standalone` mode. + enum: + - standalone + - fleet + type: string + policyID: + description: |- + PolicyID determines into which Agent Policy this Agent will be enrolled. + This field will become mandatory in a future release, default policies are deprecated since 8.1.0. + type: string + revisionHistoryLimit: + description: RevisionHistoryLimit is the number of revisions to retain + to allow rollback in the underlying DaemonSet or Deployment or StatefulSet. + format: int32 + type: integer + secureSettings: + description: |- + SecureSettings is a list of references to Kubernetes Secrets containing sensitive configuration options for the Agent. + Secrets data can be then referenced in the Agent config using the Secret's keys or as specified in `Entries` field of + each SecureSetting. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + serviceAccountName: + description: |- + ServiceAccountName is used to check access from the current resource to an Elasticsearch resource in a different namespace. + Can only be used if ECK is enforcing RBAC on references. + type: string + statefulSet: + description: |- + StatefulSet specifies the Agent should be deployed as a StatefulSet, and allows providing its spec. + Cannot be used along with `daemonSet` or `deployment`. + properties: + podManagementPolicy: + default: Parallel + description: |- + PodManagementPolicy controls how pods are created during initial scale up, + when replacing pods on nodes, or when scaling down. The default policy is + `Parallel`, where pods are created in parallel to match the desired scale + without waiting, and on scale down will delete all pods at once. + The alternative policy is `OrderedReady`, the default for vanilla kubernetes + StatefulSets, where pods are created in increasing order in increasing order + (pod-0, then pod-1, etc.) and the controller will wait until each pod is ready before + continuing. When scaling down, the pods are removed in the opposite order. + enum: + - OrderedReady + - Parallel + type: string + podTemplate: + description: PodTemplateSpec describes the data a pod should have + when created from a template + type: object + x-kubernetes-preserve-unknown-fields: true + replicas: + format: int32 + type: integer + serviceName: + type: string + volumeClaimTemplates: + description: |- + VolumeClaimTemplates is a list of persistent volume claims to be used by each Pod. + Every claim in this list must have a matching volumeMount in one of the containers defined in the PodTemplate. + Items defined here take precedence over any default claims added by the operator with the same name. + items: + description: PersistentVolumeClaim is a user's request for and + claim to a persistent volume + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + spec defines the desired characteristics of a volume requested by a pod author. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes + to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string or nil value indicates that no + VolumeAttributesClass will be applied to the claim. If the claim enters an Infeasible error state, + this field can be reset to its previous value (including nil) to cancel the modification. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to + the PersistentVolume backing this claim. + type: string + type: object + type: object + type: array + type: object + version: + description: Version of the Agent. + type: string + required: + - version + type: object + status: + description: AgentStatus defines the observed state of the Agent + properties: + availableNodes: + format: int32 + type: integer + elasticsearchAssociationsStatus: + additionalProperties: + description: AssociationStatus is the status of an association resource. + type: string + description: |- + AssociationStatusMap is the map of association's namespaced name string to its AssociationStatus. For resources that + have a single Association of a given type (for ex. single ES reference), this map contains a single entry. + type: object + expectedNodes: + format: int32 + type: integer + fleetServerAssociationStatus: + description: AssociationStatus is the status of an association resource. + type: string + health: + type: string + kibanaAssociationStatus: + description: AssociationStatus is the status of an association resource. + type: string + observedGeneration: + description: |- + ObservedGeneration is the most recent generation observed for this Elastic Agent. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + If the generation observed in status diverges from the generation in metadata, the Elastic + Agent controller has not yet processed the changes contained in the Elastic Agent specification. + format: int64 + type: integer + version: + description: |- + Version of the stack resource currently running. During version upgrades, multiple versions may run + in parallel: this value specifies the lowest version currently running. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: apmservers.apm.k8s.elastic.co +spec: + group: apm.k8s.elastic.co + names: + categories: + - elastic + kind: ApmServer + listKind: ApmServerList + plural: apmservers + shortNames: + - apm + singular: apmserver + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: nodes + type: integer + - description: APM version + jsonPath: .status.version + name: version + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1 + schema: + openAPIV3Schema: + description: ApmServer represents an APM Server resource in a Kubernetes cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ApmServerSpec holds the specification of an APM Server. + properties: + config: + description: 'Config holds the APM Server configuration. See: https://www.elastic.co/guide/en/apm/server/current/configuring-howto-apm-server.html' + type: object + x-kubernetes-preserve-unknown-fields: true + count: + description: Count of APM Server instances to deploy. + format: int32 + type: integer + elasticsearchRef: + description: ElasticsearchRef is a reference to the output Elasticsearch + cluster running in the same Kubernetes cluster. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. + The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + http: + description: HTTP holds the HTTP layer configuration for the APM Server + resource. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic + is distributed to Service endpoints. Implementations can use this field + as a hint, but are not required to guarantee strict adherence. If the + field is not set, the implementation will apply its default routing + strategy. If set to "PreferClose", implementations should prioritize + endpoints that are in the same zone. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the APM Server Docker image to deploy. + type: string + kibanaRef: + description: |- + KibanaRef is a reference to a Kibana instance running in the same Kubernetes cluster. + It allows APM agent central configuration management in Kibana. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. + The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + podTemplate: + description: PodTemplate provides customisation options (labels, annotations, + affinity rules, resource requests, and so on) for the APM Server + pods. + type: object + x-kubernetes-preserve-unknown-fields: true + revisionHistoryLimit: + description: RevisionHistoryLimit is the number of revisions to retain + to allow rollback in the underlying Deployment. + format: int32 + type: integer + secureSettings: + description: SecureSettings is a list of references to Kubernetes + secrets containing sensitive configuration options for APM Server. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + serviceAccountName: + description: |- + ServiceAccountName is used to check access from the current resource to a resource (for ex. Elasticsearch) in a different namespace. + Can only be used if ECK is enforcing RBAC on references. + type: string + version: + description: Version of the APM Server. + type: string + required: + - version + type: object + status: + description: ApmServerStatus defines the observed state of ApmServer + properties: + availableNodes: + description: AvailableNodes is the number of available replicas in + the deployment. + format: int32 + type: integer + count: + description: Count corresponds to Scale.Status.Replicas, which is + the actual number of observed instances of the scaled object. + format: int32 + type: integer + elasticsearchAssociationStatus: + description: ElasticsearchAssociationStatus is the status of any auto-linking + to Elasticsearch clusters. + type: string + health: + description: Health of the deployment. + type: string + kibanaAssociationStatus: + description: KibanaAssociationStatus is the status of any auto-linking + to Kibana. + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the status is based upon. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + If the generation observed in status diverges from the generation in metadata, the APM Server + controller has not yet processed the changes contained in the APM Server specification. + format: int64 + type: integer + secretTokenSecret: + description: SecretTokenSecretName is the name of the Secret that + contains the secret token + type: string + selector: + description: Selector is the label selector used to find all pods. + type: string + service: + description: ExternalService is the name of the service the agents + should connect to. + type: string + version: + description: |- + Version of the stack resource currently running. During version upgrades, multiple versions may run + in parallel: this value specifies the lowest version currently running. + type: string + type: object + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.count + statusReplicasPath: .status.count + status: {} + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: nodes + type: integer + - description: APM version + jsonPath: .spec.version + name: version + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: ApmServer represents an APM Server resource in a Kubernetes cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ApmServerSpec holds the specification of an APM Server. + properties: + config: + description: 'Config holds the APM Server configuration. See: https://www.elastic.co/guide/en/apm/server/current/configuring-howto-apm-server.html' + type: object + x-kubernetes-preserve-unknown-fields: true + count: + description: Count of APM Server instances to deploy. + format: int32 + type: integer + elasticsearchRef: + description: ElasticsearchRef is a reference to the output Elasticsearch + cluster running in the same Kubernetes cluster. + properties: + name: + description: Name of the Kubernetes object. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + required: + - name + type: object + http: + description: HTTP holds the HTTP layer configuration for the APM Server + resource. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic + is distributed to Service endpoints. Implementations can use this field + as a hint, but are not required to guarantee strict adherence. If the + field is not set, the implementation will apply its default routing + strategy. If set to "PreferClose", implementations should prioritize + endpoints that are in the same zone. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the APM Server Docker image to deploy. + type: string + podTemplate: + description: PodTemplate provides customisation options (labels, annotations, + affinity rules, resource requests, and so on) for the APM Server + pods. + type: object + x-kubernetes-preserve-unknown-fields: true + secureSettings: + description: SecureSettings is a list of references to Kubernetes + secrets containing sensitive configuration options for APM Server. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + version: + description: Version of the APM Server. + type: string + type: object + status: + description: ApmServerStatus defines the observed state of ApmServer + properties: + associationStatus: + description: Association is the status of any auto-linking to Elasticsearch + clusters. + type: string + availableNodes: + format: int32 + type: integer + health: + description: ApmServerHealth expresses the status of the Apm Server + instances. + type: string + secretTokenSecret: + description: SecretTokenSecretName is the name of the Secret that + contains the secret token + type: string + service: + description: ExternalService is the name of the service the agents + should connect to. + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} + - name: v1alpha1 + schema: + openAPIV3Schema: + description: to not break compatibility when upgrading from previous versions + of the CRD + type: object + served: false + storage: false +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: beats.beat.k8s.elastic.co +spec: + group: beat.k8s.elastic.co + names: + categories: + - elastic + kind: Beat + listKind: BeatList + plural: beats + shortNames: + - beat + singular: beat + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: available + type: integer + - description: Expected nodes + jsonPath: .status.expectedNodes + name: expected + type: integer + - description: Beat type + jsonPath: .spec.type + name: type + type: string + - description: Beat version + jsonPath: .status.version + name: version + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: Beat is the Schema for the Beats API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: BeatSpec defines the desired state of a Beat. + properties: + config: + description: Config holds the Beat configuration. At most one of [`Config`, + `ConfigRef`] can be specified. + type: object + x-kubernetes-preserve-unknown-fields: true + configRef: + description: |- + ConfigRef contains a reference to an existing Kubernetes Secret holding the Beat configuration. + Beat settings must be specified as yaml, under a single "beat.yml" entry. At most one of [`Config`, `ConfigRef`] + can be specified. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + daemonSet: + description: |- + DaemonSet specifies the Beat should be deployed as a DaemonSet, and allows providing its spec. + Cannot be used along with `deployment`. If both are absent a default for the Type is used. + properties: + podTemplate: + description: PodTemplateSpec describes the data a pod should have + when created from a template + type: object + x-kubernetes-preserve-unknown-fields: true + updateStrategy: + description: DaemonSetUpdateStrategy is a struct used to control + the update strategy for a DaemonSet. + properties: + rollingUpdate: + description: Rolling update config params. Present only if + type = "RollingUpdate". + properties: + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of nodes with an existing available DaemonSet pod that + can have an updated DaemonSet pod during during an update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up to a minimum of 1. + Default value is 0. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their a new pod created before the old pod is marked as deleted. + The update starts by launching new pods on 30% of nodes. Once an updated + pod is available (Ready for at least minReadySeconds) the old DaemonSet pod + on that node is marked deleted. If the old pod becomes unavailable for any + reason (Ready transitions to false, is evicted, or is drained) an updated + pod is immediately created on that node without considering surge limits. + Allowing surge implies the possibility that the resources consumed by the + daemonset on any given node can double if the readiness check fails, and + so resource intensive daemonsets should take into account that they may + cause evictions during disruption. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of DaemonSet pods that can be unavailable during the + update. Value can be an absolute number (ex: 5) or a percentage of total + number of DaemonSet pods at the start of the update (ex: 10%). Absolute + number is calculated from percentage by rounding up. + This cannot be 0 if MaxSurge is 0 + Default value is 1. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their pods stopped for an update at any given time. The update + starts by stopping at most 30% of those DaemonSet pods and then brings + up new DaemonSet pods in their place. Once the new pods are available, + it then proceeds onto other DaemonSet pods, thus ensuring that at least + 70% of original number of DaemonSet pods are available at all times during + the update. + x-kubernetes-int-or-string: true + type: object + type: + description: Type of daemon set update. Can be "RollingUpdate" + or "OnDelete". Default is RollingUpdate. + type: string + type: object + type: object + deployment: + description: |- + Deployment specifies the Beat should be deployed as a Deployment, and allows providing its spec. + Cannot be used along with `daemonSet`. If both are absent a default for the Type is used. + properties: + podTemplate: + description: PodTemplateSpec describes the data a pod should have + when created from a template + type: object + x-kubernetes-preserve-unknown-fields: true + replicas: + format: int32 + type: integer + strategy: + description: DeploymentStrategy describes how to replace existing + pods with new ones. + properties: + rollingUpdate: + description: |- + Rolling update config params. Present only if DeploymentStrategyType = + RollingUpdate. + properties: + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be scheduled above the desired number of + pods. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 25%. + Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when + the rolling update starts, such that the total number of old and new pods do not exceed + 130% of desired pods. Once old pods have been killed, + new ReplicaSet can be scaled up further, ensuring that total number of pods running + at any time during the update is at most 130% of desired pods. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 25%. + Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods + immediately when the rolling update starts. Once new pods are ready, old ReplicaSet + can be scaled down further, followed by scaling up the new ReplicaSet, ensuring + that the total number of pods available at all times during the update is at + least 70% of desired pods. + x-kubernetes-int-or-string: true + type: object + type: + description: Type of deployment. Can be "Recreate" or "RollingUpdate". + Default is RollingUpdate. + type: string + type: object + type: object + elasticsearchRef: + description: ElasticsearchRef is a reference to an Elasticsearch cluster + running in the same Kubernetes cluster. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. + The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + image: + description: Image is the Beat Docker image to deploy. Version and + Type have to match the Beat in the image. + type: string + kibanaRef: + description: |- + KibanaRef is a reference to a Kibana instance running in the same Kubernetes cluster. + It allows automatic setup of dashboards and visualizations. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. + The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + monitoring: + description: |- + Monitoring enables you to collect and ship logs and metrics for this Beat. + Metricbeat and/or Filebeat sidecars are configured and send monitoring data to an + Elasticsearch monitoring cluster running in the same Kubernetes cluster. + properties: + logs: + description: Logs holds references to Elasticsearch clusters which + receive log data from an associated resource. + properties: + elasticsearchRefs: + description: |- + ElasticsearchRefs is a reference to a list of monitoring Elasticsearch clusters running in the same Kubernetes cluster. + Due to existing limitations, only a single Elasticsearch cluster is currently supported. + items: + description: |- + ObjectSelector defines a reference to a Kubernetes object which can be an Elastic resource managed by the operator + or a Secret describing an external Elastic resource not managed by the operator. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If + empty, defaults to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. + The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + type: array + type: object + metrics: + description: Metrics holds references to Elasticsearch clusters + which receive monitoring data from this resource. + properties: + elasticsearchRefs: + description: |- + ElasticsearchRefs is a reference to a list of monitoring Elasticsearch clusters running in the same Kubernetes cluster. + Due to existing limitations, only a single Elasticsearch cluster is currently supported. + items: + description: |- + ObjectSelector defines a reference to a Kubernetes object which can be an Elastic resource managed by the operator + or a Secret describing an external Elastic resource not managed by the operator. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If + empty, defaults to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. + The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + type: array + type: object + type: object + revisionHistoryLimit: + description: RevisionHistoryLimit is the number of revisions to retain + to allow rollback in the underlying DaemonSet or Deployment. + format: int32 + type: integer + secureSettings: + description: |- + SecureSettings is a list of references to Kubernetes Secrets containing sensitive configuration options for the Beat. + Secrets data can be then referenced in the Beat config using the Secret's keys or as specified in `Entries` field of + each SecureSetting. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + serviceAccountName: + description: |- + ServiceAccountName is used to check access from the current resource to Elasticsearch resource in a different namespace. + Can only be used if ECK is enforcing RBAC on references. + type: string + type: + description: |- + Type is the type of the Beat to deploy (filebeat, metricbeat, heartbeat, auditbeat, journalbeat, packetbeat, and so on). + Any string can be used, but well-known types will have the image field defaulted and have the appropriate + Elasticsearch roles created automatically. It also allows for dashboard setup when combined with a `KibanaRef`. + maxLength: 20 + pattern: '[a-zA-Z0-9-]+' + type: string + version: + description: Version of the Beat. + type: string + required: + - type + - version + type: object + status: + description: BeatStatus defines the observed state of a Beat. + properties: + availableNodes: + format: int32 + type: integer + elasticsearchAssociationStatus: + description: AssociationStatus is the status of an association resource. + type: string + expectedNodes: + format: int32 + type: integer + health: + type: string + kibanaAssociationStatus: + description: AssociationStatus is the status of an association resource. + type: string + monitoringAssociationStatus: + additionalProperties: + description: AssociationStatus is the status of an association resource. + type: string + description: |- + AssociationStatusMap is the map of association's namespaced name string to its AssociationStatus. For resources that + have a single Association of a given type (for ex. single ES reference), this map contains a single entry. + type: object + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the status is based upon. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + If the generation observed in status diverges from the generation in metadata, the Beats + controller has not yet processed the changes contained in the Beats specification. + format: int64 + type: integer + version: + description: |- + Version of the stack resource currently running. During version upgrades, multiple versions may run + in parallel: this value specifies the lowest version currently running. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: elasticmapsservers.maps.k8s.elastic.co +spec: + group: maps.k8s.elastic.co + names: + categories: + - elastic + kind: ElasticMapsServer + listKind: ElasticMapsServerList + plural: elasticmapsservers + shortNames: + - ems + singular: elasticmapsserver + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: nodes + type: integer + - description: ElasticMapsServer version + jsonPath: .status.version + name: version + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: ElasticMapsServer represents an Elastic Map Server resource in + a Kubernetes cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MapsSpec holds the specification of an Elastic Maps Server + instance. + properties: + config: + description: 'Config holds the ElasticMapsServer configuration. See: + https://www.elastic.co/guide/en/kibana/current/maps-connect-to-ems.html#elastic-maps-server-configuration' + type: object + x-kubernetes-preserve-unknown-fields: true + configRef: + description: |- + ConfigRef contains a reference to an existing Kubernetes Secret holding the Elastic Maps Server configuration. + Configuration settings are merged and have precedence over settings specified in `config`. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + count: + description: Count of Elastic Maps Server instances to deploy. + format: int32 + type: integer + elasticsearchRef: + description: ElasticsearchRef is a reference to an Elasticsearch cluster + running in the same Kubernetes cluster. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. + The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + http: + description: HTTP holds the HTTP layer configuration for Elastic Maps + Server. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic + is distributed to Service endpoints. Implementations can use this field + as a hint, but are not required to guarantee strict adherence. If the + field is not set, the implementation will apply its default routing + strategy. If set to "PreferClose", implementations should prioritize + endpoints that are in the same zone. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the Elastic Maps Server Docker image to deploy. + type: string + podTemplate: + description: PodTemplate provides customisation options (labels, annotations, + affinity rules, resource requests, and so on) for the Elastic Maps + Server pods + type: object + x-kubernetes-preserve-unknown-fields: true + revisionHistoryLimit: + description: RevisionHistoryLimit is the number of revisions to retain + to allow rollback in the underlying Deployment. + format: int32 + type: integer + serviceAccountName: + description: |- + ServiceAccountName is used to check access from the current resource to a resource (for ex. Elasticsearch) in a different namespace. + Can only be used if ECK is enforcing RBAC on references. + type: string + version: + description: Version of Elastic Maps Server. + type: string + required: + - version + type: object + status: + description: MapsStatus defines the observed state of Elastic Maps Server + properties: + associationStatus: + description: AssociationStatus is the status of an association resource. + type: string + availableNodes: + description: AvailableNodes is the number of available replicas in + the deployment. + format: int32 + type: integer + count: + description: Count corresponds to Scale.Status.Replicas, which is + the actual number of observed instances of the scaled object. + format: int32 + type: integer + health: + description: Health of the deployment. + type: string + observedGeneration: + description: |- + ObservedGeneration is the most recent generation observed for this Elastic Maps Server. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + If the generation observed in status diverges from the generation in metadata, the Elastic + Maps controller has not yet processed the changes contained in the Elastic Maps specification. + format: int64 + type: integer + selector: + description: Selector is the label selector used to find all pods. + type: string + version: + description: |- + Version of the stack resource currently running. During version upgrades, multiple versions may run + in parallel: this value specifies the lowest version currently running. + type: string + type: object + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.count + statusReplicasPath: .status.count + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: elasticsearchautoscalers.autoscaling.k8s.elastic.co +spec: + group: autoscaling.k8s.elastic.co + names: + categories: + - elastic + kind: ElasticsearchAutoscaler + listKind: ElasticsearchAutoscalerList + plural: elasticsearchautoscalers + shortNames: + - esa + singular: elasticsearchautoscaler + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.elasticsearchRef.name + name: Target + type: string + - jsonPath: .status.conditions[?(@.type=='Active')].status + name: Active + type: string + - jsonPath: .status.conditions[?(@.type=='Healthy')].status + name: Healthy + type: string + - jsonPath: .status.conditions[?(@.type=='Limited')].status + name: Limited + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: ElasticsearchAutoscaler represents an ElasticsearchAutoscaler + resource in a Kubernetes cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ElasticsearchAutoscalerSpec holds the specification of an + Elasticsearch autoscaler resource. + properties: + elasticsearchRef: + description: ElasticsearchRef is a reference to an Elasticsearch cluster + that exists in the same namespace. + properties: + name: + description: Name is the name of the Elasticsearch resource to + scale automatically. + minLength: 1 + type: string + type: object + policies: + items: + description: AutoscalingPolicySpec holds a named autoscaling policy + and the associated resources limits (cpu, memory, storage). + properties: + deciders: + additionalProperties: + additionalProperties: + type: string + description: |- + DeciderSettings allow the user to tweak autoscaling deciders. + The map data structure complies with the format expected by Elasticsearch. + type: object + description: Deciders allow the user to override default settings + for autoscaling deciders. + type: object + name: + description: Name identifies the autoscaling policy in the autoscaling + specification. + type: string + resources: + description: |- + AutoscalingResources model the limits, submitted by the user, for the supported resources in an autoscaling policy. + Only the node count range is mandatory. For other resources, a limit range is required only + if the Elasticsearch autoscaling capacity API returns a requirement for a given resource. + For example, the memory limit range is only required if the autoscaling API response contains a memory requirement. + If there is no limit range for a resource, and if that resource is not mandatory, then the resources in the NodeSets + managed by the autoscaling policy are left untouched. + properties: + cpu: + description: QuantityRange models a resource limit range + for resources which can be expressed with resource.Quantity. + properties: + max: + anyOf: + - type: integer + - type: string + description: Max represents the upper limit for the + resources managed by the autoscaler. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + min: + anyOf: + - type: integer + - type: string + description: Min represents the lower limit for the + resources managed by the autoscaler. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + requestsToLimitsRatio: + anyOf: + - type: integer + - type: string + description: RequestsToLimitsRatio allows to customize + Kubernetes resource Limit based on the Request. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + required: + - max + - min + type: object + memory: + description: QuantityRange models a resource limit range + for resources which can be expressed with resource.Quantity. + properties: + max: + anyOf: + - type: integer + - type: string + description: Max represents the upper limit for the + resources managed by the autoscaler. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + min: + anyOf: + - type: integer + - type: string + description: Min represents the lower limit for the + resources managed by the autoscaler. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + requestsToLimitsRatio: + anyOf: + - type: integer + - type: string + description: RequestsToLimitsRatio allows to customize + Kubernetes resource Limit based on the Request. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + required: + - max + - min + type: object + nodeCount: + description: NodeCountRange is used to model the minimum + and the maximum number of nodes over all the NodeSets + managed by the same autoscaling policy. + properties: + max: + description: Max represents the maximum number of nodes + in a tier. + format: int32 + type: integer + min: + description: Min represents the minimum number of nodes + in a tier. + format: int32 + type: integer + required: + - max + - min + type: object + storage: + description: QuantityRange models a resource limit range + for resources which can be expressed with resource.Quantity. + properties: + max: + anyOf: + - type: integer + - type: string + description: Max represents the upper limit for the + resources managed by the autoscaler. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + min: + anyOf: + - type: integer + - type: string + description: Min represents the lower limit for the + resources managed by the autoscaler. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + requestsToLimitsRatio: + anyOf: + - type: integer + - type: string + description: RequestsToLimitsRatio allows to customize + Kubernetes resource Limit based on the Request. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + required: + - max + - min + type: object + required: + - nodeCount + type: object + roles: + description: An autoscaling policy must target a unique set + of roles. + items: + type: string + type: array + required: + - resources + type: object + type: array + pollingPeriod: + description: PollingPeriod is the period at which to synchronize with + the Elasticsearch autoscaling API. + type: string + required: + - elasticsearchRef + - policies + type: object + status: + properties: + conditions: + description: Conditions holds the current service state of the autoscaling + controller. + items: + description: |- + Condition represents Elasticsearch resource's condition. + **This API is in technical preview and may be changed or removed in a future release.** + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + status: + type: string + type: + description: ConditionType defines the condition of an Elasticsearch + resource. + type: string + required: + - status + - type + type: object + type: array + observedGeneration: + description: ObservedGeneration is the last observed generation by + the controller. + format: int64 + type: integer + policies: + description: AutoscalingPolicyStatuses is used to expose state messages + to user or external system. + items: + properties: + lastModificationTime: + description: LastModificationTime is the last time the resources + have been updated, used by the cooldown algorithm. + format: date-time + type: string + name: + description: Name is the name of the autoscaling policy + type: string + nodeSets: + description: NodeSetNodeCount holds the number of nodes for + each nodeSet. + items: + description: NodeSetNodeCount models the number of nodes expected + in a given NodeSet. + properties: + name: + description: Name of the Nodeset. + type: string + nodeCount: + description: NodeCount is the number of nodes, as computed + by the autoscaler, expected in this NodeSet. + format: int32 + type: integer + required: + - name + - nodeCount + type: object + type: array + resources: + description: |- + ResourcesSpecification holds the resource values common to all the nodeSets managed by a same autoscaling policy. + Only the resources managed by the autoscaling controller are saved in the Status. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: ResourceList is a set of (resource name, quantity) + pairs. + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: ResourceList is a set of (resource name, quantity) + pairs. + type: object + type: object + state: + description: PolicyStates may contain various messages regarding + the current state of this autoscaling policy. + items: + properties: + messages: + items: + type: string + type: array + type: + type: string + required: + - messages + - type + type: object + type: array + required: + - name + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: elasticsearches.elasticsearch.k8s.elastic.co +spec: + group: elasticsearch.k8s.elastic.co + names: + categories: + - elastic + kind: Elasticsearch + listKind: ElasticsearchList + plural: elasticsearches + shortNames: + - es + singular: elasticsearch + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: nodes + type: integer + - description: Elasticsearch version + jsonPath: .status.version + name: version + type: string + - jsonPath: .status.phase + name: phase + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1 + schema: + openAPIV3Schema: + description: Elasticsearch represents an Elasticsearch resource in a Kubernetes + cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ElasticsearchSpec holds the specification of an Elasticsearch + cluster. + properties: + auth: + description: Auth contains user authentication and authorization security + settings for Elasticsearch. + properties: + disableElasticUser: + description: DisableElasticUser disables the default elastic user + that is created by ECK. + type: boolean + fileRealm: + description: FileRealm to propagate to the Elasticsearch cluster. + items: + description: FileRealmSource references users to create in the + Elasticsearch cluster. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + type: array + roles: + description: Roles to propagate to the Elasticsearch cluster. + items: + description: RoleSource references roles to create in the Elasticsearch + cluster. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + type: array + type: object + http: + description: HTTP holds HTTP layer settings for Elasticsearch. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic + is distributed to Service endpoints. Implementations can use this field + as a hint, but are not required to guarantee strict adherence. If the + field is not set, the implementation will apply its default routing + strategy. If set to "PreferClose", implementations should prioritize + endpoints that are in the same zone. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the Elasticsearch Docker image to deploy. + type: string + monitoring: + description: |- + Monitoring enables you to collect and ship log and monitoring data of this Elasticsearch cluster. + See https://www.elastic.co/guide/en/elasticsearch/reference/current/monitor-elasticsearch-cluster.html. + Metricbeat and Filebeat are deployed in the same Pod as sidecars and each one sends data to one or two different + Elasticsearch monitoring clusters running in the same Kubernetes cluster. + properties: + logs: + description: Logs holds references to Elasticsearch clusters which + receive log data from an associated resource. + properties: + elasticsearchRefs: + description: |- + ElasticsearchRefs is a reference to a list of monitoring Elasticsearch clusters running in the same Kubernetes cluster. + Due to existing limitations, only a single Elasticsearch cluster is currently supported. + items: + description: |- + ObjectSelector defines a reference to a Kubernetes object which can be an Elastic resource managed by the operator + or a Secret describing an external Elastic resource not managed by the operator. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If + empty, defaults to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. + The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + type: array + type: object + metrics: + description: Metrics holds references to Elasticsearch clusters + which receive monitoring data from this resource. + properties: + elasticsearchRefs: + description: |- + ElasticsearchRefs is a reference to a list of monitoring Elasticsearch clusters running in the same Kubernetes cluster. + Due to existing limitations, only a single Elasticsearch cluster is currently supported. + items: + description: |- + ObjectSelector defines a reference to a Kubernetes object which can be an Elastic resource managed by the operator + or a Secret describing an external Elastic resource not managed by the operator. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If + empty, defaults to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. + The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + type: array + type: object + type: object + nodeSets: + description: NodeSets allow specifying groups of Elasticsearch nodes + sharing the same configuration and Pod templates. + items: + description: NodeSet is the specification for a group of Elasticsearch + nodes sharing the same configuration and a Pod template. + properties: + config: + description: Config holds the Elasticsearch configuration. + type: object + x-kubernetes-preserve-unknown-fields: true + count: + description: |- + Count of Elasticsearch nodes to deploy. + If the node set is managed by an autoscaling policy the initial value is automatically set by the autoscaling controller. + format: int32 + type: integer + name: + description: Name of this set of nodes. Becomes a part of the + Elasticsearch node.name setting. + maxLength: 23 + pattern: '[a-zA-Z0-9-]+' + type: string + podTemplate: + description: PodTemplate provides customisation options (labels, + annotations, affinity rules, resource requests, and so on) + for the Pods belonging to this NodeSet. + type: object + x-kubernetes-preserve-unknown-fields: true + volumeClaimTemplates: + description: |- + VolumeClaimTemplates is a list of persistent volume claims to be used by each Pod in this NodeSet. + Every claim in this list must have a matching volumeMount in one of the containers defined in the PodTemplate. + Items defined here take precedence over any default claims added by the operator with the same name. + items: + description: PersistentVolumeClaim is a user's request for + and claim to a persistent volume + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + spec defines the desired characteristics of a volume requested by a pod author. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes + to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string or nil value indicates that no + VolumeAttributesClass will be applied to the claim. If the claim enters an Infeasible error state, + this field can be reset to its previous value (including nil) to cancel the modification. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to + the PersistentVolume backing this claim. + type: string + type: object + type: object + type: array + required: + - name + type: object + minItems: 1 + type: array + podDisruptionBudget: + description: |- + PodDisruptionBudget provides access to the default Pod disruption budget(s) for the Elasticsearch cluster. + The behavior depends on the license level. + With a Basic license or if podDisruptionBudget.spec is not empty: + The default budget doesn't allow any Pod to be removed in case the cluster is not green or if there is only one node of type `data` or `master`. + In all other cases the default podDisruptionBudget sets `minUnavailable` equal to the total number of nodes minus 1. + With an Enterprise license and if podDisruptionBudget.spec is empty: + The default budget is split into multiple budgets, each targeting a specific node role type allowing additional disruptions + for certain roles according to the health status of the cluster. + Example: + All data roles (excluding frozen): allows disruptions only when the cluster is green. + All other roles: allows disruptions only when the cluster is yellow or green. + To disable, set `podDisruptionBudget` to the empty value (`{}` in YAML). + properties: + metadata: + description: |- + ObjectMeta is the metadata of the PDB. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the PDB. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + An eviction is allowed if at most "maxUnavailable" pods selected by + "selector" are unavailable after the eviction, i.e. even in absence of + the evicted pod. For example, one can prevent all voluntary evictions + by specifying 0. This is a mutually exclusive setting with "minAvailable". + x-kubernetes-int-or-string: true + minAvailable: + anyOf: + - type: integer + - type: string + description: |- + An eviction is allowed if at least "minAvailable" pods selected by + "selector" will still be available after the eviction, i.e. even in the + absence of the evicted pod. So for example you can prevent all voluntary + evictions by specifying "100%". + x-kubernetes-int-or-string: true + selector: + description: |- + Label query over pods whose evictions are managed by the disruption + budget. + A null selector will match no pods, while an empty ({}) selector will select + all pods within the namespace. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + unhealthyPodEvictionPolicy: + description: |- + UnhealthyPodEvictionPolicy defines the criteria for when unhealthy pods + should be considered for eviction. Current implementation considers healthy pods, + as pods that have status.conditions item with type="Ready",status="True". + + Valid policies are IfHealthyBudget and AlwaysAllow. + If no policy is specified, the default behavior will be used, + which corresponds to the IfHealthyBudget policy. + + IfHealthyBudget policy means that running pods (status.phase="Running"), + but not yet healthy can be evicted only if the guarded application is not + disrupted (status.currentHealthy is at least equal to status.desiredHealthy). + Healthy pods will be subject to the PDB for eviction. + + AlwaysAllow policy means that all running pods (status.phase="Running"), + but not yet healthy are considered disrupted and can be evicted regardless + of whether the criteria in a PDB is met. This means perspective running + pods of a disrupted application might not get a chance to become healthy. + Healthy pods will be subject to the PDB for eviction. + + Additional policies may be added in the future. + Clients making eviction decisions should disallow eviction of unhealthy pods + if they encounter an unrecognized policy in this field. + type: string + type: object + type: object + remoteClusterServer: + description: |- + RemoteClusterServer specifies if the remote cluster server should be enabled. + This must be enabled if this cluster is a remote cluster which is expected to be accessed using API key authentication. + properties: + enabled: + type: boolean + type: object + remoteClusters: + description: RemoteClusters enables you to establish uni-directional + connections to a remote Elasticsearch cluster. + items: + description: RemoteCluster declares a remote Elasticsearch cluster + connection. + properties: + apiKey: + description: 'APIKey can be used to enable remote cluster access + using Cross-Cluster API keys: https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-cross-cluster-api-key.html' + properties: + access: + description: Access is the name of the API Key. It is automatically + generated if not set or empty. + properties: + replication: + properties: + names: + items: + type: string + type: array + required: + - names + type: object + search: + properties: + allow_restricted_indices: + type: boolean + field_security: + properties: + except: + items: + type: string + type: array + grant: + items: + type: string + type: array + required: + - except + - grant + type: object + names: + items: + type: string + type: array + query: + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - names + type: object + type: object + required: + - access + type: object + elasticsearchRef: + description: ElasticsearchRef is a reference to an Elasticsearch + cluster running within the same k8s cluster. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, + defaults to the current namespace. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + name: + description: |- + Name is the name of the remote cluster as it is set in the Elasticsearch settings. + The name is expected to be unique for each remote clusters. + minLength: 1 + type: string + required: + - name + type: object + type: array + revisionHistoryLimit: + description: RevisionHistoryLimit is the number of revisions to retain + to allow rollback in the underlying StatefulSets. + format: int32 + type: integer + secureSettings: + description: SecureSettings is a list of references to Kubernetes + secrets containing sensitive configuration options for Elasticsearch. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + serviceAccountName: + description: |- + ServiceAccountName is used to check access from the current resource to a resource (for ex. a remote Elasticsearch cluster) in a different namespace. + Can only be used if ECK is enforcing RBAC on references. + type: string + transport: + description: Transport holds transport layer settings for Elasticsearch. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic + is distributed to Service endpoints. Implementations can use this field + as a hint, but are not required to guarantee strict adherence. If the + field is not set, the implementation will apply its default routing + strategy. If set to "PreferClose", implementations should prioritize + endpoints that are in the same zone. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS on the transport + layer. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the CA certificate + and private key for generating node certificates. + The referenced secret should contain the following: + + - `ca.crt`: The CA certificate in PEM format. + - `ca.key`: The private key for the CA certificate in PEM format. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + certificateAuthorities: + description: |- + CertificateAuthorities is a reference to a config map that contains one or more x509 certificates for + trusted authorities in PEM format. The certificates need to be in a file called `ca.crt`. + properties: + configMapName: + type: string + type: object + otherNameSuffix: + description: |- + OtherNameSuffix when defined will be prefixed with the Pod name and used as the common name, + and the first DNSName, as well as an OtherName required by Elasticsearch in the Subject Alternative Name + extension of each Elasticsearch node's transport TLS certificate. + Example: if set to "node.cluster.local", the generated certificate will have its otherName set to ".node.cluster.local". + type: string + selfSignedCertificates: + description: SelfSignedCertificates allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that provisioning of the + self-signed certificates should be disabled. + type: boolean + type: object + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs to + include in the generated node transport TLS certificates. + items: + description: SubjectAlternativeName represents a SAN entry + in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + updateStrategy: + description: UpdateStrategy specifies how updates to the cluster should + be performed. + properties: + changeBudget: + description: ChangeBudget defines the constraints to consider + when applying changes to the Elasticsearch cluster. + properties: + maxSurge: + description: |- + MaxSurge is the maximum number of new Pods that can be created exceeding the original number of Pods defined in + the specification. MaxSurge is only taken into consideration when scaling up. Setting a negative value will + disable the restriction. Defaults to unbounded if not specified. + format: int32 + type: integer + maxUnavailable: + description: |- + MaxUnavailable is the maximum number of Pods that can be unavailable (not ready) during the update due to + circumstances under the control of the operator. Setting a negative value will disable this restriction. + Defaults to 1 if not specified. + format: int32 + type: integer + type: object + type: object + version: + description: Version of Elasticsearch. + type: string + volumeClaimDeletePolicy: + description: |- + VolumeClaimDeletePolicy sets the policy for handling deletion of PersistentVolumeClaims for all NodeSets. + Possible values are DeleteOnScaledownOnly and DeleteOnScaledownAndClusterDeletion. Defaults to DeleteOnScaledownAndClusterDeletion. + enum: + - DeleteOnScaledownOnly + - DeleteOnScaledownAndClusterDeletion + type: string + required: + - nodeSets + - version + type: object + status: + description: ElasticsearchStatus represents the observed state of Elasticsearch. + properties: + availableNodes: + description: AvailableNodes is the number of available instances. + format: int32 + type: integer + conditions: + description: |- + Conditions holds the current service state of an Elasticsearch cluster. + **This API is in technical preview and may be changed or removed in a future release.** + items: + description: |- + Condition represents Elasticsearch resource's condition. + **This API is in technical preview and may be changed or removed in a future release.** + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + status: + type: string + type: + description: ConditionType defines the condition of an Elasticsearch + resource. + type: string + required: + - status + - type + type: object + type: array + health: + description: ElasticsearchHealth is the health of the cluster as returned + by the health API. + type: string + inProgressOperations: + description: |- + InProgressOperations represents changes being applied by the operator to the Elasticsearch cluster. + **This API is in technical preview and may be changed or removed in a future release.** + properties: + downscale: + description: |- + DownscaleOperation provides details about in progress downscale operations. + **This API is in technical preview and may be changed or removed in a future release.** + properties: + lastUpdatedTime: + format: date-time + type: string + nodes: + description: Nodes which are scheduled to be removed from + the cluster. + items: + description: |- + DownscaledNode provides an overview of in progress changes applied by the operator to remove Elasticsearch nodes from the cluster. + **This API is in technical preview and may be changed or removed in a future release.** + properties: + explanation: + description: |- + Explanation provides details about an in progress node shutdown. It is only available for clusters managed with the + Elasticsearch shutdown API. + type: string + name: + description: Name of the Elasticsearch node that should + be removed. + type: string + shutdownStatus: + description: |- + Shutdown status as returned by the Elasticsearch shutdown API. + If the Elasticsearch shutdown API is not available, the shutdown status is then inferred from the remaining + shards on the nodes, as observed by the operator. + type: string + required: + - name + - shutdownStatus + type: object + type: array + stalled: + description: |- + Stalled represents a state where no progress can be made. + It is only available for clusters managed with the Elasticsearch shutdown API. + type: boolean + type: object + upgrade: + description: |- + UpgradeOperation provides an overview of the pending or in progress changes applied by the operator to update the Elasticsearch nodes in the cluster. + **This API is in technical preview and may be changed or removed in a future release.** + properties: + lastUpdatedTime: + format: date-time + type: string + nodes: + description: Nodes that must be restarted for upgrade. + items: + description: |- + UpgradedNode provides details about the status of nodes which are expected to be updated. + **This API is in technical preview and may be changed or removed in a future release.** + properties: + message: + description: Optional message to explain why a node + may not be immediately restarted for upgrade. + type: string + name: + description: Name of the Elasticsearch node that should + be upgraded. + type: string + predicate: + description: Predicate is the name of the predicate + currently preventing this node from being deleted + for an upgrade. + type: string + status: + description: |- + Status states if the node is either in the process of being deleted for an upgrade, + or blocked by a predicate or another condition stated in the message field. + type: string + required: + - name + - status + type: object + type: array + type: object + upscale: + description: |- + UpscaleOperation provides an overview of in progress changes applied by the operator to add Elasticsearch nodes to the cluster. + **This API is in technical preview and may be changed or removed in a future release.** + properties: + lastUpdatedTime: + format: date-time + type: string + nodes: + description: Nodes expected to be added by the operator. + items: + properties: + message: + description: Optional message to explain why a node + may not be immediately added. + type: string + name: + description: Name of the Elasticsearch node that should + be added to the cluster. + type: string + status: + description: NewNodeStatus states if a new node is being + created, or if the upscale is delayed. + type: string + required: + - name + - status + type: object + type: array + type: object + required: + - downscale + - upgrade + - upscale + type: object + monitoringAssociationStatus: + additionalProperties: + description: AssociationStatus is the status of an association resource. + type: string + description: |- + AssociationStatusMap is the map of association's namespaced name string to its AssociationStatus. For resources that + have a single Association of a given type (for ex. single ES reference), this map contains a single entry. + type: object + observedGeneration: + description: |- + ObservedGeneration is the most recent generation observed for this Elasticsearch cluster. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + If the generation observed in status diverges from the generation in metadata, the Elasticsearch + controller has not yet processed the changes contained in the Elasticsearch specification. + format: int64 + type: integer + phase: + description: ElasticsearchOrchestrationPhase is the phase Elasticsearch + is in from the controller point of view. + type: string + version: + description: |- + Version of the stack resource currently running. During version upgrades, multiple versions may run + in parallel: this value specifies the lowest version currently running. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: nodes + type: integer + - description: Elasticsearch version + jsonPath: .spec.version + name: version + type: string + - jsonPath: .status.phase + name: phase + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: Elasticsearch represents an Elasticsearch resource in a Kubernetes + cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ElasticsearchSpec holds the specification of an Elasticsearch + cluster. + properties: + http: + description: HTTP holds HTTP layer settings for Elasticsearch. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic + is distributed to Service endpoints. Implementations can use this field + as a hint, but are not required to guarantee strict adherence. If the + field is not set, the implementation will apply its default routing + strategy. If set to "PreferClose", implementations should prioritize + endpoints that are in the same zone. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the Elasticsearch Docker image to deploy. + type: string + nodeSets: + description: NodeSets allow specifying groups of Elasticsearch nodes + sharing the same configuration and Pod templates. + items: + description: NodeSet is the specification for a group of Elasticsearch + nodes sharing the same configuration and a Pod template. + properties: + config: + description: Config holds the Elasticsearch configuration. + type: object + count: + description: Count of Elasticsearch nodes to deploy. + format: int32 + minimum: 1 + type: integer + name: + description: Name of this set of nodes. Becomes a part of the + Elasticsearch node.name setting. + maxLength: 23 + pattern: '[a-zA-Z0-9-]+' + type: string + podTemplate: + description: PodTemplate provides customisation options (labels, + annotations, affinity rules, resource requests, and so on) + for the Pods belonging to this NodeSet. + type: object + volumeClaimTemplates: + description: |- + VolumeClaimTemplates is a list of persistent volume claims to be used by each Pod in this NodeSet. + Every claim in this list must have a matching volumeMount in one of the containers defined in the PodTemplate. + Items defined here take precedence over any default claims added by the operator with the same name. + items: + description: PersistentVolumeClaim is a user's request for + and claim to a persistent volume + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + spec defines the desired characteristics of a volume requested by a pod author. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes + to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string or nil value indicates that no + VolumeAttributesClass will be applied to the claim. If the claim enters an Infeasible error state, + this field can be reset to its previous value (including nil) to cancel the modification. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to + the PersistentVolume backing this claim. + type: string + type: object + type: object + type: array + required: + - count + - name + type: object + minItems: 1 + type: array + podDisruptionBudget: + description: |- + PodDisruptionBudget provides access to the default pod disruption budget for the Elasticsearch cluster. + The default budget selects all cluster pods and sets `maxUnavailable` to 1. To disable, set `PodDisruptionBudget` + to the empty value (`{}` in YAML). + properties: + metadata: + description: |- + ObjectMeta is the metadata of the PDB. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the PDB. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + An eviction is allowed if at most "maxUnavailable" pods selected by + "selector" are unavailable after the eviction, i.e. even in absence of + the evicted pod. For example, one can prevent all voluntary evictions + by specifying 0. This is a mutually exclusive setting with "minAvailable". + x-kubernetes-int-or-string: true + minAvailable: + anyOf: + - type: integer + - type: string + description: |- + An eviction is allowed if at least "minAvailable" pods selected by + "selector" will still be available after the eviction, i.e. even in the + absence of the evicted pod. So for example you can prevent all voluntary + evictions by specifying "100%". + x-kubernetes-int-or-string: true + selector: + description: |- + Label query over pods whose evictions are managed by the disruption + budget. + A null selector selects no pods. + An empty selector ({}) also selects no pods, which differs from standard behavior of selecting all pods. + In policy/v1, an empty selector will select all pods in the namespace. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + unhealthyPodEvictionPolicy: + description: |- + UnhealthyPodEvictionPolicy defines the criteria for when unhealthy pods + should be considered for eviction. Current implementation considers healthy pods, + as pods that have status.conditions item with type="Ready",status="True". + + Valid policies are IfHealthyBudget and AlwaysAllow. + If no policy is specified, the default behavior will be used, + which corresponds to the IfHealthyBudget policy. + + IfHealthyBudget policy means that running pods (status.phase="Running"), + but not yet healthy can be evicted only if the guarded application is not + disrupted (status.currentHealthy is at least equal to status.desiredHealthy). + Healthy pods will be subject to the PDB for eviction. + + AlwaysAllow policy means that all running pods (status.phase="Running"), + but not yet healthy are considered disrupted and can be evicted regardless + of whether the criteria in a PDB is met. This means perspective running + pods of a disrupted application might not get a chance to become healthy. + Healthy pods will be subject to the PDB for eviction. + + Additional policies may be added in the future. + Clients making eviction decisions should disallow eviction of unhealthy pods + if they encounter an unrecognized policy in this field. + type: string + type: object + type: object + secureSettings: + description: SecureSettings is a list of references to Kubernetes + secrets containing sensitive configuration options for Elasticsearch. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + updateStrategy: + description: UpdateStrategy specifies how updates to the cluster should + be performed. + properties: + changeBudget: + description: ChangeBudget defines the constraints to consider + when applying changes to the Elasticsearch cluster. + properties: + maxSurge: + description: |- + MaxSurge is the maximum number of new pods that can be created exceeding the original number of pods defined in + the specification. MaxSurge is only taken into consideration when scaling up. Setting a negative value will + disable the restriction. Defaults to unbounded if not specified. + format: int32 + type: integer + maxUnavailable: + description: |- + MaxUnavailable is the maximum number of pods that can be unavailable (not ready) during the update due to + circumstances under the control of the operator. Setting a negative value will disable this restriction. + Defaults to 1 if not specified. + format: int32 + type: integer + type: object + type: object + version: + description: Version of Elasticsearch. + type: string + required: + - nodeSets + type: object + status: + description: ElasticsearchStatus defines the observed state of Elasticsearch + properties: + availableNodes: + format: int32 + type: integer + health: + description: ElasticsearchHealth is the health of the cluster as returned + by the health API. + type: string + phase: + description: ElasticsearchOrchestrationPhase is the phase Elasticsearch + is in from the controller point of view. + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} + - name: v1alpha1 + schema: + openAPIV3Schema: + description: to not break compatibility when upgrading from previous versions + of the CRD + type: object + served: false + storage: false +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: enterprisesearches.enterprisesearch.k8s.elastic.co +spec: + group: enterprisesearch.k8s.elastic.co + names: + categories: + - elastic + kind: EnterpriseSearch + listKind: EnterpriseSearchList + plural: enterprisesearches + shortNames: + - ent + singular: enterprisesearch + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: nodes + type: integer + - description: Enterprise Search version + jsonPath: .status.version + name: version + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1 + schema: + openAPIV3Schema: + description: EnterpriseSearch is a Kubernetes CRD to represent Enterprise + Search. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: EnterpriseSearchSpec holds the specification of an Enterprise + Search resource. + properties: + config: + description: Config holds the Enterprise Search configuration. + type: object + x-kubernetes-preserve-unknown-fields: true + configRef: + description: |- + ConfigRef contains a reference to an existing Kubernetes Secret holding the Enterprise Search configuration. + Configuration settings are merged and have precedence over settings specified in `config`. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + count: + description: Count of Enterprise Search instances to deploy. + format: int32 + type: integer + elasticsearchRef: + description: ElasticsearchRef is a reference to the Elasticsearch + cluster running in the same Kubernetes cluster. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. + The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + http: + description: HTTP holds the HTTP layer configuration for Enterprise + Search resource. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic + is distributed to Service endpoints. Implementations can use this field + as a hint, but are not required to guarantee strict adherence. If the + field is not set, the implementation will apply its default routing + strategy. If set to "PreferClose", implementations should prioritize + endpoints that are in the same zone. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the Enterprise Search Docker image to deploy. + type: string + podTemplate: + description: |- + PodTemplate provides customisation options (labels, annotations, affinity rules, resource requests, and so on) + for the Enterprise Search pods. + type: object + x-kubernetes-preserve-unknown-fields: true + revisionHistoryLimit: + description: RevisionHistoryLimit is the number of revisions to retain + to allow rollback in the underlying Deployment. + format: int32 + type: integer + serviceAccountName: + description: |- + ServiceAccountName is used to check access from the current resource to a resource (for ex. Elasticsearch) in a different namespace. + Can only be used if ECK is enforcing RBAC on references. + type: string + version: + description: Version of Enterprise Search. + type: string + type: object + status: + description: EnterpriseSearchStatus defines the observed state of EnterpriseSearch + properties: + associationStatus: + description: Association is the status of any auto-linking to Elasticsearch + clusters. + type: string + availableNodes: + description: AvailableNodes is the number of available replicas in + the deployment. + format: int32 + type: integer + count: + description: Count corresponds to Scale.Status.Replicas, which is + the actual number of observed instances of the scaled object. + format: int32 + type: integer + health: + description: Health of the deployment. + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the status is based upon. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + If the generation observed in status diverges from the generation in metadata, the Enterprise Search + controller has not yet processed the changes contained in the Enterprise Search specification. + format: int64 + type: integer + selector: + description: Selector is the label selector used to find all pods. + type: string + service: + description: ExternalService is the name of the service associated + to the Enterprise Search Pods. + type: string + version: + description: |- + Version of the stack resource currently running. During version upgrades, multiple versions may run + in parallel: this value specifies the lowest version currently running. + type: string + type: object + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.count + statusReplicasPath: .status.count + status: {} + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: nodes + type: integer + - description: Enterprise Search version + jsonPath: .status.version + name: version + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: EnterpriseSearch is a Kubernetes CRD to represent Enterprise + Search. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: EnterpriseSearchSpec holds the specification of an Enterprise + Search resource. + properties: + config: + description: Config holds the Enterprise Search configuration. + type: object + x-kubernetes-preserve-unknown-fields: true + configRef: + description: |- + ConfigRef contains a reference to an existing Kubernetes Secret holding the Enterprise Search configuration. + Configuration settings are merged and have precedence over settings specified in `config`. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + count: + description: Count of Enterprise Search instances to deploy. + format: int32 + type: integer + elasticsearchRef: + description: ElasticsearchRef is a reference to the Elasticsearch + cluster running in the same Kubernetes cluster. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. + The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + http: + description: HTTP holds the HTTP layer configuration for Enterprise + Search resource. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic + is distributed to Service endpoints. Implementations can use this field + as a hint, but are not required to guarantee strict adherence. If the + field is not set, the implementation will apply its default routing + strategy. If set to "PreferClose", implementations should prioritize + endpoints that are in the same zone. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the Enterprise Search Docker image to deploy. + type: string + podTemplate: + description: |- + PodTemplate provides customisation options (labels, annotations, affinity rules, resource requests, and so on) + for the Enterprise Search pods. + type: object + x-kubernetes-preserve-unknown-fields: true + serviceAccountName: + description: |- + ServiceAccountName is used to check access from the current resource to a resource (for ex. Elasticsearch) in a different namespace. + Can only be used if ECK is enforcing RBAC on references. + type: string + version: + description: Version of Enterprise Search. + type: string + type: object + status: + description: EnterpriseSearchStatus defines the observed state of EnterpriseSearch + properties: + associationStatus: + description: Association is the status of any auto-linking to Elasticsearch + clusters. + type: string + availableNodes: + description: AvailableNodes is the number of available replicas in + the deployment. + format: int32 + type: integer + count: + description: Count corresponds to Scale.Status.Replicas, which is + the actual number of observed instances of the scaled object. + format: int32 + type: integer + health: + description: Health of the deployment. + type: string + selector: + description: Selector is the label selector used to find all pods. + type: string + service: + description: ExternalService is the name of the service associated + to the Enterprise Search Pods. + type: string + version: + description: |- + Version of the stack resource currently running. During version upgrades, multiple versions may run + in parallel: this value specifies the lowest version currently running. + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: kibanas.kibana.k8s.elastic.co +spec: + group: kibana.k8s.elastic.co + names: + categories: + - elastic + kind: Kibana + listKind: KibanaList + plural: kibanas + shortNames: + - kb + singular: kibana + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: nodes + type: integer + - description: Kibana version + jsonPath: .status.version + name: version + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1 + schema: + openAPIV3Schema: + description: Kibana represents a Kibana resource in a Kubernetes cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: KibanaSpec holds the specification of a Kibana instance. + properties: + config: + description: 'Config holds the Kibana configuration. See: https://www.elastic.co/guide/en/kibana/current/settings.html' + type: object + x-kubernetes-preserve-unknown-fields: true + count: + description: Count of Kibana instances to deploy. + format: int32 + type: integer + elasticsearchRef: + description: ElasticsearchRef is a reference to an Elasticsearch cluster + running in the same Kubernetes cluster. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. + The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + enterpriseSearchRef: + description: |- + EnterpriseSearchRef is a reference to an EnterpriseSearch running in the same Kubernetes cluster. + Kibana provides the default Enterprise Search UI starting version 7.14. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. + The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + http: + description: HTTP holds the HTTP layer configuration for Kibana. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic + is distributed to Service endpoints. Implementations can use this field + as a hint, but are not required to guarantee strict adherence. If the + field is not set, the implementation will apply its default routing + strategy. If set to "PreferClose", implementations should prioritize + endpoints that are in the same zone. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the Kibana Docker image to deploy. + type: string + monitoring: + description: |- + Monitoring enables you to collect and ship log and monitoring data of this Kibana. + See https://www.elastic.co/guide/en/kibana/current/xpack-monitoring.html. + Metricbeat and Filebeat are deployed in the same Pod as sidecars and each one sends data to one or two different + Elasticsearch monitoring clusters running in the same Kubernetes cluster. + properties: + logs: + description: Logs holds references to Elasticsearch clusters which + receive log data from an associated resource. + properties: + elasticsearchRefs: + description: |- + ElasticsearchRefs is a reference to a list of monitoring Elasticsearch clusters running in the same Kubernetes cluster. + Due to existing limitations, only a single Elasticsearch cluster is currently supported. + items: + description: |- + ObjectSelector defines a reference to a Kubernetes object which can be an Elastic resource managed by the operator + or a Secret describing an external Elastic resource not managed by the operator. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If + empty, defaults to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. + The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + type: array + type: object + metrics: + description: Metrics holds references to Elasticsearch clusters + which receive monitoring data from this resource. + properties: + elasticsearchRefs: + description: |- + ElasticsearchRefs is a reference to a list of monitoring Elasticsearch clusters running in the same Kubernetes cluster. + Due to existing limitations, only a single Elasticsearch cluster is currently supported. + items: + description: |- + ObjectSelector defines a reference to a Kubernetes object which can be an Elastic resource managed by the operator + or a Secret describing an external Elastic resource not managed by the operator. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If + empty, defaults to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. + The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + type: array + type: object + type: object + podTemplate: + description: PodTemplate provides customisation options (labels, annotations, + affinity rules, resource requests, and so on) for the Kibana pods + type: object + x-kubernetes-preserve-unknown-fields: true + revisionHistoryLimit: + description: RevisionHistoryLimit is the number of revisions to retain + to allow rollback in the underlying Deployment. + format: int32 + type: integer + secureSettings: + description: SecureSettings is a list of references to Kubernetes + secrets containing sensitive configuration options for Kibana. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + serviceAccountName: + description: |- + ServiceAccountName is used to check access from the current resource to a resource (for ex. Elasticsearch) in a different namespace. + Can only be used if ECK is enforcing RBAC on references. + type: string + version: + description: Version of Kibana. + type: string + required: + - version + type: object + status: + description: KibanaStatus defines the observed state of Kibana + properties: + associationStatus: + description: |- + AssociationStatus is the status of any auto-linking to Elasticsearch clusters. + This field is deprecated and will be removed in a future release. Use ElasticsearchAssociationStatus instead. + type: string + availableNodes: + description: AvailableNodes is the number of available replicas in + the deployment. + format: int32 + type: integer + count: + description: Count corresponds to Scale.Status.Replicas, which is + the actual number of observed instances of the scaled object. + format: int32 + type: integer + elasticsearchAssociationStatus: + description: ElasticsearchAssociationStatus is the status of any auto-linking + to Elasticsearch clusters. + type: string + enterpriseSearchAssociationStatus: + description: EnterpriseSearchAssociationStatus is the status of any + auto-linking to Enterprise Search. + type: string + health: + description: Health of the deployment. + type: string + monitoringAssociationStatus: + additionalProperties: + description: AssociationStatus is the status of an association resource. + type: string + description: MonitoringAssociationStatus is the status of any auto-linking + to monitoring Elasticsearch clusters. + type: object + observedGeneration: + description: |- + ObservedGeneration is the most recent generation observed for this Kibana instance. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + If the generation observed in status diverges from the generation in metadata, the Kibana + controller has not yet processed the changes contained in the Kibana specification. + format: int64 + type: integer + selector: + description: Selector is the label selector used to find all pods. + type: string + version: + description: |- + Version of the stack resource currently running. During version upgrades, multiple versions may run + in parallel: this value specifies the lowest version currently running. + type: string + type: object + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.count + statusReplicasPath: .status.count + status: {} + - additionalPrinterColumns: + - jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: nodes + type: integer + - description: Kibana version + jsonPath: .spec.version + name: version + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: Kibana represents a Kibana resource in a Kubernetes cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: KibanaSpec holds the specification of a Kibana instance. + properties: + config: + description: 'Config holds the Kibana configuration. See: https://www.elastic.co/guide/en/kibana/current/settings.html' + type: object + x-kubernetes-preserve-unknown-fields: true + count: + description: Count of Kibana instances to deploy. + format: int32 + type: integer + elasticsearchRef: + description: ElasticsearchRef is a reference to an Elasticsearch cluster + running in the same Kubernetes cluster. + properties: + name: + description: Name of the Kubernetes object. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + required: + - name + type: object + http: + description: HTTP holds the HTTP layer configuration for Kibana. + properties: + service: + description: Service defines the template for the associated Kubernetes + Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic + is distributed to Service endpoints. Implementations can use this field + as a hint, but are not required to guarantee strict adherence. If the + field is not set, the implementation will apply its default routing + strategy. If set to "PreferClose", implementations should prioritize + endpoints that are in the same zone. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + image: + description: Image is the Kibana Docker image to deploy. + type: string + podTemplate: + description: PodTemplate provides customisation options (labels, annotations, + affinity rules, resource requests, and so on) for the Kibana pods + type: object + x-kubernetes-preserve-unknown-fields: true + secureSettings: + description: SecureSettings is a list of references to Kubernetes + secrets containing sensitive configuration options for Kibana. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + version: + description: Version of Kibana. + type: string + type: object + status: + description: KibanaStatus defines the observed state of Kibana + properties: + associationStatus: + description: AssociationStatus is the status of an association resource. + type: string + availableNodes: + format: int32 + type: integer + health: + description: KibanaHealth expresses the status of the Kibana instances. + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} + - name: v1alpha1 + schema: + openAPIV3Schema: + description: to not break compatibility when upgrading from previous versions + of the CRD + type: object + served: false + storage: false +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: logstashes.logstash.k8s.elastic.co +spec: + group: logstash.k8s.elastic.co + names: + categories: + - elastic + kind: Logstash + listKind: LogstashList + plural: logstashes + shortNames: + - ls + singular: logstash + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Health + jsonPath: .status.health + name: health + type: string + - description: Available nodes + jsonPath: .status.availableNodes + name: available + type: integer + - description: Expected nodes + jsonPath: .status.expectedNodes + name: expected + type: integer + - jsonPath: .metadata.creationTimestamp + name: age + type: date + - description: Logstash version + jsonPath: .status.version + name: version + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: Logstash is the Schema for the logstashes API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: LogstashSpec defines the desired state of Logstash + properties: + config: + description: Config holds the Logstash configuration. At most one + of [`Config`, `ConfigRef`] can be specified. + type: object + x-kubernetes-preserve-unknown-fields: true + configRef: + description: |- + ConfigRef contains a reference to an existing Kubernetes Secret holding the Logstash configuration. + Logstash settings must be specified as yaml, under a single "logstash.yml" entry. At most one of [`Config`, `ConfigRef`] + can be specified. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + count: + format: int32 + type: integer + elasticsearchRefs: + description: ElasticsearchRefs are references to Elasticsearch clusters + running in the same Kubernetes cluster. + items: + description: ElasticsearchCluster is a named reference to an Elasticsearch + cluster which can be used in a Logstash pipeline. + properties: + clusterName: + description: |- + ClusterName is an alias for the cluster to be used to refer to the Elasticsearch cluster in Logstash + configuration files, and will be used to identify "named clusters" in Logstash + minLength: 1 + type: string + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If empty, defaults + to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. + The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + required: + - clusterName + type: object + type: array + image: + description: Image is the Logstash Docker image to deploy. Version + and Type have to match the Logstash in the image. + type: string + monitoring: + description: |- + Monitoring enables you to collect and ship log and monitoring data of this Logstash. + Metricbeat and Filebeat are deployed in the same Pod as sidecars and each one sends data to one or two different + Elasticsearch monitoring clusters running in the same Kubernetes cluster. + properties: + logs: + description: Logs holds references to Elasticsearch clusters which + receive log data from an associated resource. + properties: + elasticsearchRefs: + description: |- + ElasticsearchRefs is a reference to a list of monitoring Elasticsearch clusters running in the same Kubernetes cluster. + Due to existing limitations, only a single Elasticsearch cluster is currently supported. + items: + description: |- + ObjectSelector defines a reference to a Kubernetes object which can be an Elastic resource managed by the operator + or a Secret describing an external Elastic resource not managed by the operator. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If + empty, defaults to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. + The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + type: array + type: object + metrics: + description: Metrics holds references to Elasticsearch clusters + which receive monitoring data from this resource. + properties: + elasticsearchRefs: + description: |- + ElasticsearchRefs is a reference to a list of monitoring Elasticsearch clusters running in the same Kubernetes cluster. + Due to existing limitations, only a single Elasticsearch cluster is currently supported. + items: + description: |- + ObjectSelector defines a reference to a Kubernetes object which can be an Elastic resource managed by the operator + or a Secret describing an external Elastic resource not managed by the operator. + properties: + name: + description: Name of an existing Kubernetes object corresponding + to an Elastic resource managed by ECK. + type: string + namespace: + description: Namespace of the Kubernetes object. If + empty, defaults to the current namespace. + type: string + secretName: + description: |- + SecretName is the name of an existing Kubernetes secret that contains connection information for associating an + Elastic resource not managed by the operator. + The referenced secret must contain the following: + - `url`: the URL to reach the Elastic resource + - `username`: the username of the user to be authenticated to the Elastic resource + - `password`: the password of the user to be authenticated to the Elastic resource + - `ca.crt`: the CA certificate in PEM format (optional) + - `api-key`: the key to authenticate against the Elastic resource instead of a username and password (supported only for `elasticsearchRefs` in AgentSpec and in BeatSpec) + This field cannot be used in combination with the other fields name, namespace or serviceName. + type: string + serviceName: + description: |- + ServiceName is the name of an existing Kubernetes service which is used to make requests to the referenced + object. It has to be in the same namespace as the referenced resource. If left empty, the default HTTP service of + the referenced resource is used. + type: string + type: object + type: array + type: object + type: object + pipelines: + description: Pipelines holds the Logstash Pipelines. At most one of + [`Pipelines`, `PipelinesRef`] can be specified. + items: + type: object + type: array + x-kubernetes-preserve-unknown-fields: true + pipelinesRef: + description: |- + PipelinesRef contains a reference to an existing Kubernetes Secret holding the Logstash Pipelines. + Logstash pipelines must be specified as yaml, under a single "pipelines.yml" entry. At most one of [`Pipelines`, `PipelinesRef`] + can be specified. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + podTemplate: + description: PodTemplate provides customisation options for the Logstash + pods. + type: object + x-kubernetes-preserve-unknown-fields: true + revisionHistoryLimit: + description: RevisionHistoryLimit is the number of revisions to retain + to allow rollback in the underlying StatefulSet. + format: int32 + type: integer + secureSettings: + description: |- + SecureSettings is a list of references to Kubernetes Secrets containing sensitive configuration options for the Logstash. + Secrets data can be then referenced in the Logstash config using the Secret's keys or as specified in `Entries` field of + each SecureSetting. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + serviceAccountName: + description: |- + ServiceAccountName is used to check access from the current resource to Elasticsearch resource in a different namespace. + Can only be used if ECK is enforcing RBAC on references. + type: string + services: + description: |- + Services contains details of services that Logstash should expose - similar to the HTTP layer configuration for the + rest of the stack, but also applicable for more use cases than the metrics API, as logstash may need to + be opened up for other services: Beats, TCP, UDP, etc, inputs. + items: + properties: + name: + type: string + service: + description: Service defines the template for the associated + Kubernetes Service object. + properties: + metadata: + description: |- + ObjectMeta is the metadata of the service. + The name and namespace provided here are managed by ECK and will be ignored. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: Spec is the specification of the service. + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by + this service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic + is distributed to Service endpoints. Implementations can use this field + as a hint, but are not required to guarantee strict adherence. If the + field is not set, the implementation will apply its default routing + strategy. If set to "PreferClose", implementations should prioritize + endpoints that are in the same zone. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + tls: + description: TLS defines options for configuring TLS for HTTP. + properties: + certificate: + description: |- + Certificate is a reference to a Kubernetes secret that contains the certificate and private key for enabling TLS. + The referenced secret should contain the following: + + - `ca.crt`: The certificate authority (optional). + - `tls.crt`: The certificate (or a chain). + - `tls.key`: The private key to the first certificate in the certificate chain. + properties: + secretName: + description: SecretName is the name of the secret. + type: string + type: object + selfSignedCertificate: + description: SelfSignedCertificate allows configuring the + self-signed certificate generated by the operator. + properties: + disabled: + description: Disabled indicates that the provisioning + of the self-signed certifcate should be disabled. + type: boolean + subjectAltNames: + description: SubjectAlternativeNames is a list of SANs + to include in the generated HTTP TLS certificate. + items: + description: SubjectAlternativeName represents a SAN + entry in a x509 certificate. + properties: + dns: + description: DNS is the DNS name of the subject. + type: string + ip: + description: IP is the IP address of the subject. + type: string + type: object + type: array + type: object + type: object + type: object + type: array + updateStrategy: + description: UpdateStrategy is a StatefulSetUpdateStrategy. The default + type is "RollingUpdate". + properties: + rollingUpdate: + description: RollingUpdate is used to communicate parameters when + Type is RollingUpdateStatefulSetStrategyType. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding up. This can not be 0. + Defaults to 1. This field is alpha-level and is only honored by servers that enable the + MaxUnavailableStatefulSet feature. The field applies to all pods in the range 0 to + Replicas-1. That means if there is any unavailable pod in the range 0 to Replicas-1, it + will be counted towards MaxUnavailable. + x-kubernetes-int-or-string: true + partition: + description: |- + Partition indicates the ordinal at which the StatefulSet should be partitioned + for updates. During a rolling update, all pods from ordinal Replicas-1 to + Partition are updated. All pods from ordinal Partition-1 to 0 remain untouched. + This is helpful in being able to do a canary based deployment. The default value is 0. + format: int32 + type: integer + type: object + type: + description: |- + Type indicates the type of the StatefulSetUpdateStrategy. + Default is RollingUpdate. + type: string + type: object + version: + description: Version of the Logstash. + type: string + volumeClaimTemplates: + description: |- + VolumeClaimTemplates is a list of persistent volume claims to be used by each Pod. + Every claim in this list must have a matching volumeMount in one of the containers defined in the PodTemplate. + Items defined here take precedence over any default claims added by the operator with the same name. + items: + description: PersistentVolumeClaim is a user's request for and claim + to a persistent volume + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + spec defines the desired characteristics of a volume requested by a pod author. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes to consider + for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string or nil value indicates that no + VolumeAttributesClass will be applied to the claim. If the claim enters an Infeasible error state, + this field can be reset to its previous value (including nil) to cancel the modification. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the + PersistentVolume backing this claim. + type: string + type: object + status: + description: |- + status represents the current information/status of a persistent volume claim. + Read-only. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the actual access modes the volume backing the PVC has. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + allocatedResourceStatuses: + additionalProperties: + description: |- + When a controller receives persistentvolume claim update with ClaimResourceStatus for a resource + that it does not recognizes, then it should ignore that update and let other controllers + handle it. + type: string + description: "allocatedResourceStatuses stores status of + resource being resized for the given PVC.\nKey names follow + standard Kubernetes label syntax. Valid values are either:\n\t* + Un-prefixed keys:\n\t\t- storage - the capacity of the + volume.\n\t* Custom resources must use implementation-defined + prefixed names such as \"example.com/my-custom-resource\"\nApart + from above values - keys that are unprefixed or have kubernetes.io + prefix are considered\nreserved and hence may not be used.\n\nClaimResourceStatus + can be in any of following states:\n\t- ControllerResizeInProgress:\n\t\tState + set when resize controller starts resizing the volume + in control-plane.\n\t- ControllerResizeFailed:\n\t\tState + set when resize has failed in resize controller with a + terminal error.\n\t- NodeResizePending:\n\t\tState set + when resize controller has finished resizing the volume + but further resizing of\n\t\tvolume is needed on the node.\n\t- + NodeResizeInProgress:\n\t\tState set when kubelet starts + resizing the volume.\n\t- NodeResizeFailed:\n\t\tState + set when resizing has failed in kubelet with a terminal + error. Transient errors don't set\n\t\tNodeResizeFailed.\nFor + example: if expanding a PVC for more capacity - this field + can be one of the following states:\n\t- pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeFailed\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizePending\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeFailed\"\nWhen this field is not set, it + means that no resize operation is in progress for the + given PVC.\n\nA controller that receives PVC update with + previously unknown resourceName or ClaimResourceStatus\nshould + ignore the update for the purpose it was designed. For + example - a controller that\nonly is responsible for resizing + capacity of the volume, should ignore PVC updates that + change other valid\nresources associated with PVC.\n\nThis + is an alpha field and requires enabling RecoverVolumeExpansionFailure + feature." + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: "allocatedResources tracks the resources allocated + to a PVC including its capacity.\nKey names follow standard + Kubernetes label syntax. Valid values are either:\n\t* + Un-prefixed keys:\n\t\t- storage - the capacity of the + volume.\n\t* Custom resources must use implementation-defined + prefixed names such as \"example.com/my-custom-resource\"\nApart + from above values - keys that are unprefixed or have kubernetes.io + prefix are considered\nreserved and hence may not be used.\n\nCapacity + reported here may be larger than the actual capacity when + a volume expansion operation\nis requested.\nFor storage + quota, the larger value from allocatedResources and PVC.spec.resources + is used.\nIf allocatedResources is not set, PVC.spec.resources + alone is used for quota calculation.\nIf a volume expansion + capacity request is lowered, allocatedResources is only\nlowered + if there are no expansion operations in progress and if + the actual volume capacity\nis equal or lower than the + requested capacity.\n\nA controller that receives PVC + update with previously unknown resourceName\nshould ignore + the update for the purpose it was designed. For example + - a controller that\nonly is responsible for resizing + capacity of the volume, should ignore PVC updates that + change other valid\nresources associated with PVC.\n\nThis + is an alpha field and requires enabling RecoverVolumeExpansionFailure + feature." + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: capacity represents the actual resources of + the underlying volume. + type: object + conditions: + description: |- + conditions is the current Condition of persistent volume claim. If underlying persistent volume is being + resized then the Condition will be set to 'Resizing'. + items: + description: PersistentVolumeClaimCondition contains details + about state of pvc + properties: + lastProbeTime: + description: lastProbeTime is the time we probed the + condition. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime is the time the condition + transitioned from one status to another. + format: date-time + type: string + message: + description: message is the human-readable message + indicating details about last transition. + type: string + reason: + description: |- + reason is a unique, this should be a short, machine understandable string that gives the reason + for condition's last transition. If it reports "Resizing" that means the underlying + persistent volume is being resized. + type: string + status: + description: |- + Status is the status of the condition. + Can be True, False, Unknown. + More info: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#:~:text=state%20of%20pvc-,conditions.status,-(string)%2C%20required + type: string + type: + description: |- + Type is the type of the condition. + More info: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#:~:text=set%20to%20%27ResizeStarted%27.-,PersistentVolumeClaimCondition,-contains%20details%20about + type: string + required: + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentVolumeAttributesClassName: + description: |- + currentVolumeAttributesClassName is the current name of the VolumeAttributesClass the PVC is using. + When unset, there is no VolumeAttributeClass applied to this PersistentVolumeClaim + type: string + modifyVolumeStatus: + description: |- + ModifyVolumeStatus represents the status object of ControllerModifyVolume operation. + When this is unset, there is no ModifyVolume operation being attempted. + properties: + status: + description: "status is the status of the ControllerModifyVolume + operation. It can be in any of following states:\n + - Pending\n Pending indicates that the PersistentVolumeClaim + cannot be modified due to unmet requirements, such + as\n the specified VolumeAttributesClass not existing.\n + - InProgress\n InProgress indicates that the volume + is being modified.\n - Infeasible\n Infeasible indicates + that the request has been rejected as invalid by the + CSI driver. To\n\t resolve the error, a valid VolumeAttributesClass + needs to be specified.\nNote: New statuses can be + added in the future. Consumers should check for unknown + statuses and fail appropriately." + type: string + targetVolumeAttributesClassName: + description: targetVolumeAttributesClassName is the + name of the VolumeAttributesClass the PVC currently + being reconciled + type: string + required: + - status + type: object + phase: + description: phase represents the current phase of PersistentVolumeClaim. + type: string + type: object + type: object + type: array + required: + - version + type: object + status: + description: LogstashStatus defines the observed state of Logstash + properties: + availableNodes: + format: int32 + type: integer + elasticsearchAssociationsStatus: + additionalProperties: + description: AssociationStatus is the status of an association resource. + type: string + description: ElasticsearchAssociationStatus is the status of any auto-linking + to Elasticsearch clusters. + type: object + expectedNodes: + format: int32 + type: integer + health: + type: string + monitoringAssociationStatus: + additionalProperties: + description: AssociationStatus is the status of an association resource. + type: string + description: MonitoringAssociationStatus is the status of any auto-linking + to monitoring Elasticsearch clusters. + type: object + observedGeneration: + description: |- + ObservedGeneration is the most recent generation observed for this Logstash instance. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + If the generation observed in status diverges from the generation in metadata, the Logstash + controller has not yet processed the changes contained in the Logstash specification. + format: int64 + type: integer + selector: + type: string + version: + description: |- + Version of the stack resource currently running. During version upgrades, multiple versions may run + in parallel: this value specifies the lowest version currently running. + type: string + required: + - selector + type: object + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.count + statusReplicasPath: .status.expectedNodes + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: stackconfigpolicies.stackconfigpolicy.k8s.elastic.co +spec: + group: stackconfigpolicy.k8s.elastic.co + names: + categories: + - elastic + kind: StackConfigPolicy + listKind: StackConfigPolicyList + plural: stackconfigpolicies + shortNames: + - scp + singular: stackconfigpolicy + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Resources configured + jsonPath: .status.readyCount + name: Ready + type: string + - jsonPath: .status.phase + name: Phase + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: StackConfigPolicy represents a StackConfigPolicy resource in + a Kubernetes cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + properties: + elasticsearch: + properties: + clusterSettings: + description: ClusterSettings holds the Elasticsearch cluster settings + (/_cluster/settings) + type: object + x-kubernetes-preserve-unknown-fields: true + config: + description: Config holds the settings that go into elasticsearch.yml. + type: object + x-kubernetes-preserve-unknown-fields: true + indexLifecyclePolicies: + description: IndexLifecyclePolicies holds the Index Lifecycle + policies settings (/_ilm/policy) + type: object + x-kubernetes-preserve-unknown-fields: true + indexTemplates: + description: IndexTemplates holds the Index and Component Templates + settings + properties: + componentTemplates: + description: ComponentTemplates holds the Component Templates + settings (/_component_template) + type: object + x-kubernetes-preserve-unknown-fields: true + composableIndexTemplates: + description: ComposableIndexTemplates holds the Index Templates + settings (/_index_template) + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + x-kubernetes-preserve-unknown-fields: true + ingestPipelines: + description: IngestPipelines holds the Ingest Pipelines settings + (/_ingest/pipeline) + type: object + x-kubernetes-preserve-unknown-fields: true + secretMounts: + description: SecretMounts are additional Secrets that need to + be mounted into the Elasticsearch pods. + items: + description: SecretMount contains information about additional + secrets to be mounted to the elasticsearch pods + properties: + mountPath: + description: MountPath denotes the path to which the secret + should be mounted to inside the elasticsearch pod + type: string + secretName: + description: SecretName denotes the name of the secret that + needs to be mounted to the elasticsearch pod + type: string + type: object + type: array + x-kubernetes-preserve-unknown-fields: true + secureSettings: + description: SecureSettings are additional Secrets that contain + data to be configured to Elasticsearch's keystore. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + x-kubernetes-preserve-unknown-fields: true + securityRoleMappings: + description: SecurityRoleMappings holds the Role Mappings settings + (/_security/role_mapping) + type: object + x-kubernetes-preserve-unknown-fields: true + snapshotLifecyclePolicies: + description: SnapshotLifecyclePolicies holds the Snapshot Lifecycle + Policies settings (/_slm/policy) + type: object + x-kubernetes-preserve-unknown-fields: true + snapshotRepositories: + description: SnapshotRepositories holds the Snapshot Repositories + settings (/_snapshot) + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + kibana: + properties: + config: + description: Config holds the settings that go into kibana.yml. + type: object + x-kubernetes-preserve-unknown-fields: true + secureSettings: + description: SecureSettings are additional Secrets that contain + data to be configured to Kibana's keystore. + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + x-kubernetes-preserve-unknown-fields: true + type: object + resourceSelector: + description: |- + A label selector is a label query over a set of resources. The result of matchLabels and + matchExpressions are ANDed. An empty label selector matches all objects. A null + label selector matches no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + secureSettings: + description: 'Deprecated: SecureSettings only applies to Elasticsearch + and is deprecated. It must be set per application instead.' + items: + description: SecretSource defines a data source based on a Kubernetes + Secret. + properties: + entries: + description: |- + Entries define how to project each key-value pair in the secret to filesystem paths. + If not defined, all keys will be projected to similarly named paths in the filesystem. + If defined, only the specified keys will be projected to the corresponding paths. + items: + description: KeyToPath defines how to map a key in a Secret + object to a filesystem path. + properties: + key: + description: Key is the key contained in the secret. + type: string + path: + description: |- + Path is the relative file path to map the key to. + Path must not be an absolute file path and must not contain any ".." components. + type: string + required: + - key + type: object + type: array + secretName: + description: SecretName is the name of the secret. + type: string + required: + - secretName + type: object + type: array + type: object + status: + properties: + details: + additionalProperties: + additionalProperties: + description: ResourcePolicyStatus models the status of the policy + for one resource to be configured. + properties: + currentVersion: + description: |- + CurrentVersion denotes the current version of filesettings applied to the Elasticsearch cluster + This field does not apply to Kibana resources + format: int64 + type: integer + error: + properties: + message: + type: string + version: + format: int64 + type: integer + type: object + expectedVersion: + description: |- + ExpectedVersion denotes the expected version of filesettings that should be applied to the Elasticsearch cluster + This field does not apply to Kibana resources + format: int64 + type: integer + phase: + type: string + type: object + type: object + description: Details holds the status details for each resource to + be configured. + type: object + errors: + description: Errors is the number of resources which have an incorrect + configuration + type: integer + observedGeneration: + description: ObservedGeneration is the most recent generation observed + for this StackConfigPolicy. + format: int64 + type: integer + phase: + description: Phase is the phase of the StackConfigPolicy. + type: string + ready: + description: Ready is the number of resources successfully configured. + type: integer + readyCount: + description: ReadyCount is a human representation of the number of + resources successfully configured. + type: string + resources: + description: Resources is the number of resources to be configured. + type: integer + resourcesStatuses: + additionalProperties: + description: ResourcePolicyStatus models the status of the policy + for one resource to be configured. + properties: + currentVersion: + description: |- + CurrentVersion denotes the current version of filesettings applied to the Elasticsearch cluster + This field does not apply to Kibana resources + format: int64 + type: integer + error: + properties: + message: + type: string + version: + format: int64 + type: integer + type: object + expectedVersion: + description: |- + ExpectedVersion denotes the expected version of filesettings that should be applied to the Elasticsearch cluster + This field does not apply to Kibana resources + format: int64 + type: integer + phase: + type: string + type: object + description: |- + ResourcesStatuses holds the status for each resource to be configured. + Deprecated: Details is used to store the status of resources from ECK 2.11 + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/values.yaml b/packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/values.yaml new file mode 100644 index 00000000..f3fd8bd5 --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/charts/eck-operator-crds/values.yaml @@ -0,0 +1,7 @@ +# Globals meant for internal use only +global: + # manifestGen specifies whether the chart is running under manifest generator. + # This is used for tasks specific to generating the all-in-one.yaml file. + manifestGen: false + # kubeVersion is the effective Kubernetes version we target when generating the all-in-one.yaml. + kubeVersion: 1.21.0 diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/profile-disable-automounting-api.yaml b/packs/elastic-operator-3.2.0/charts/eck-operator/profile-disable-automounting-api.yaml new file mode 100644 index 00000000..50f97157 --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/profile-disable-automounting-api.yaml @@ -0,0 +1,29 @@ +automountServiceAccountToken: false + +serviceAccount: + automountServiceAccountToken: false + +volumeMounts: +- mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: serviceaccount-token + readOnly: true + +volumes: +- name: serviceaccount-token + projected: + defaultMode: 0444 + sources: + - serviceAccountToken: + expirationSeconds: 3607 + path: token + - configMap: + name: kube-root-ca.crt + items: + - key: ca.crt + path: ca.crt + - downwardAPI: + items: + - path: namespace + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/profile-global.yaml b/packs/elastic-operator-3.2.0/charts/eck-operator/profile-global.yaml new file mode 100644 index 00000000..286f8c9e --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/profile-global.yaml @@ -0,0 +1,6 @@ +managedNamespaces: [] + +createClusterScopedResources: true + +webhook: + enabled: true diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/profile-istio.yaml b/packs/elastic-operator-3.2.0/charts/eck-operator/profile-istio.yaml new file mode 100644 index 00000000..c968ba02 --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/profile-istio.yaml @@ -0,0 +1,11 @@ +managedNamespaces: [] + +createClusterScopedResources: true + +webhook: + enabled: true + +podAnnotations: + sidecar.istio.io/inject: "true" + traffic.sidecar.istio.io/includeInboundPorts: "*" + traffic.sidecar.istio.io/excludeInboundPorts: "9443" diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/profile-restricted.yaml b/packs/elastic-operator-3.2.0/charts/eck-operator/profile-restricted.yaml new file mode 100644 index 00000000..640d00f3 --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/profile-restricted.yaml @@ -0,0 +1,12 @@ +managedNamespaces: ["elastic-system"] + +createClusterScopedResources: false + +config: + # no RBAC access to cluster-wide storage classes, hence disable storage class validation + validateStorageClass: false + +installCRDs: false + +webhook: + enabled: false diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/profile-soft-multi-tenancy.yaml b/packs/elastic-operator-3.2.0/charts/eck-operator/profile-soft-multi-tenancy.yaml new file mode 100644 index 00000000..8ac79514 --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/profile-soft-multi-tenancy.yaml @@ -0,0 +1,18 @@ +managedNamespaces: ["team-a", "team-b"] + +createClusterScopedResources: true + +refs: + enforceRBAC: true + +webhook: + enabled: true + namespaceSelector: + matchExpressions: + - key: "eck.k8s.elastic.co/tenant" + operator: In + values: ["team-a", "team-b"] + + +softMultiTenancy: + enabled: true diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/templates/NOTES.txt b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/NOTES.txt new file mode 100644 index 00000000..e25ea9ea --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/NOTES.txt @@ -0,0 +1,2 @@ +1. Inspect the operator logs by running the following command: + kubectl logs -n {{ .Release.Namespace }} sts/{{ .Release.Name }} diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/templates/_helpers.tpl b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/_helpers.tpl new file mode 100644 index 00000000..ddfd8b75 --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/_helpers.tpl @@ -0,0 +1,383 @@ +{{/* +Expand the name of the chart. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "eck-operator.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "eck-operator.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "eck-operator.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "eck-operator.labels" -}} +{{- include "eck-operator.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +helm.sh/chart: {{ include "eck-operator.chart" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "eck-operator.selectorLabels" -}} +{{- if .Values.global.manifestGen -}} +control-plane: elastic-operator +{{- else -}} +app.kubernetes.io/name: {{ include "eck-operator.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "eck-operator.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "eck-operator.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Determine effective Kubernetes version +*/}} +{{- define "eck-operator.effectiveKubeVersion" -}} +{{- if .Values.global.manifestGen -}} +{{- semver .Values.global.kubeVersion -}} +{{- else -}} +{{- .Capabilities.KubeVersion.Version -}} +{{- end -}} +{{- end -}} + +{{/* +Determine the name for the webhook +*/}} +{{- define "eck-operator.webhookName" -}} +{{- if .Values.global.manifestGen -}} +elastic-webhook.k8s.elastic.co +{{- else -}} +{{- $name := include "eck-operator.name" . -}} +{{ printf "%s.%s.k8s.elastic.co" $name .Release.Namespace }} +{{- end -}} +{{- end -}} + +{{/* +Determine the name for the webhook secret +*/}} +{{- define "eck-operator.webhookSecretName" -}} +{{- if .Values.global.manifestGen -}} +elastic-webhook-server-cert +{{- else if .Values.webhook.certsSecret -}} +{{- .Values.webhook.certsSecret }} +{{- else -}} +{{- $name := include "eck-operator.name" . -}} +{{ printf "%s-webhook-cert" $name | trunc 63 }} +{{- end -}} +{{- end -}} + +{{/* +Determine the name for the webhook service +*/}} +{{- define "eck-operator.webhookServiceName" -}} +{{- if .Values.global.manifestGen -}} +elastic-webhook-server +{{- else -}} +{{- $name := include "eck-operator.name" . -}} +{{ printf "%s-webhook" $name | trunc 63 }} +{{- end -}} +{{- end -}} + +{{/* +Determine the metrics port +*/}} +{{- define "eck-operator.metrics.port" -}} +{{- if .Values.config.metrics.port -}} +{{- .Values.config.metrics.port -}} +{{- else if .Values.config.metricsPort -}} +{{- .Values.config.metricsPort -}} +{{- else -}} +0 +{{- end -}} +{{- end -}} + + + +{{/* +RBAC permissions +NOTE - any changes made to RBAC permissions below require +updating docs/operating-eck/eck-permissions.asciidoc file. +*/}} +{{- define "eck-operator.rbacRules" -}} +- apiGroups: + - "authorization.k8s.io" + resources: + - subjectaccessreviews + verbs: + - create +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create +- apiGroups: + - coordination.k8s.io + resources: + - leases + resourceNames: + - elastic-operator-leader + verbs: + - get + - watch + - update +- apiGroups: + - "" + resources: + - endpoints + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - pods + - events + - persistentvolumeclaims + - secrets + - services + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - apps + resources: + - deployments + - statefulsets + - daemonsets + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - elasticsearch.k8s.elastic.co + resources: + - elasticsearches + - elasticsearches/status + - elasticsearches/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - autoscaling.k8s.elastic.co + resources: + - elasticsearchautoscalers + - elasticsearchautoscalers/status + - elasticsearchautoscalers/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - kibana.k8s.elastic.co + resources: + - kibanas + - kibanas/status + - kibanas/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - apm.k8s.elastic.co + resources: + - apmservers + - apmservers/status + - apmservers/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - enterprisesearch.k8s.elastic.co + resources: + - enterprisesearches + - enterprisesearches/status + - enterprisesearches/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - beat.k8s.elastic.co + resources: + - beats + - beats/status + - beats/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - agent.k8s.elastic.co + resources: + - agents + - agents/status + - agents/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - maps.k8s.elastic.co + resources: + - elasticmapsservers + - elasticmapsservers/status + - elasticmapsservers/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - stackconfigpolicy.k8s.elastic.co + resources: + - stackconfigpolicies + - stackconfigpolicies/status + - stackconfigpolicies/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - logstash.k8s.elastic.co + resources: + - logstashes + - logstashes/status + - logstashes/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch +{{- end -}} + +{{/* +RBAC permissions on non-namespaced resources +*/}} +{{- define "eck-operator.clusterWideRbacRules" -}} +- apiGroups: + - storage.k8s.io + resources: + - storageclasses + verbs: + - get + - list + - watch +- apiGroups: + - admissionregistration.k8s.io + resources: + - validatingwebhookconfigurations + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +{{- end -}} + +{{/* +RBAC permissions to read node labels +*/}} +{{- define "eck-operator.readNodeLabelsRbacRule" -}} +- apiGroups: + - "" + resources: + - nodes + verbs: + - get + - list + - watch +{{- end -}} diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/templates/cluster-roles.yaml b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/cluster-roles.yaml new file mode 100644 index 00000000..dbd0fba3 --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/cluster-roles.yaml @@ -0,0 +1,121 @@ +{{- if and (not .Values.createClusterScopedResources) (.Values.config.metrics.secureMode.enabled) -}} +{{ fail "createClusterScopedResources is required to set config.metrics.secureMode.enabled to true" }} +{{- end }} +{{- if .Values.createClusterScopedResources -}} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "eck-operator.fullname" . }} + labels: + {{- include "eck-operator.labels" . | nindent 4 }} +rules: +{{ template "eck-operator.rbacRules" . | toYaml | indent 2 }} +{{ template "eck-operator.clusterWideRbacRules" . | toYaml | indent 2 }} +{{ if .Values.config.exposedNodeLabels }} +{{ template "eck-operator.readNodeLabelsRbacRule" . | toYaml | indent 2 }} +{{ end -}} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: "{{ include "eck-operator.name" . }}-view" + labels: + rbac.authorization.k8s.io/aggregate-to-view: "true" + rbac.authorization.k8s.io/aggregate-to-edit: "true" + rbac.authorization.k8s.io/aggregate-to-admin: "true" + {{- include "eck-operator.labels" . | nindent 4 }} +rules: + - apiGroups: ["elasticsearch.k8s.elastic.co"] + resources: ["elasticsearches"] + verbs: ["get", "list", "watch"] + - apiGroups: ["autoscaling.k8s.elastic.co"] + resources: ["elasticsearchautoscalers"] + verbs: ["get", "list", "watch"] + - apiGroups: ["apm.k8s.elastic.co"] + resources: ["apmservers"] + verbs: ["get", "list", "watch"] + - apiGroups: ["kibana.k8s.elastic.co"] + resources: ["kibanas"] + verbs: ["get", "list", "watch"] + - apiGroups: ["enterprisesearch.k8s.elastic.co"] + resources: ["enterprisesearches"] + verbs: ["get", "list", "watch"] + - apiGroups: ["beat.k8s.elastic.co"] + resources: ["beats"] + verbs: ["get", "list", "watch"] + - apiGroups: ["agent.k8s.elastic.co"] + resources: ["agents"] + verbs: ["get", "list", "watch"] + - apiGroups: ["maps.k8s.elastic.co"] + resources: ["elasticmapsservers"] + verbs: ["get", "list", "watch"] + - apiGroups: ["stackconfigpolicy.k8s.elastic.co"] + resources: ["stackconfigpolicies"] + verbs: ["get", "list", "watch"] + - apiGroups: ["logstash.k8s.elastic.co"] + resources: ["logstashes"] + verbs: ["get", "list", "watch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: "{{ include "eck-operator.name" . }}-edit" + labels: + rbac.authorization.k8s.io/aggregate-to-edit: "true" + rbac.authorization.k8s.io/aggregate-to-admin: "true" + {{- include "eck-operator.labels" . | nindent 4 }} +rules: + - apiGroups: ["elasticsearch.k8s.elastic.co"] + resources: ["elasticsearches"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["autoscaling.k8s.elastic.co"] + resources: ["elasticsearchautoscalers"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["apm.k8s.elastic.co"] + resources: ["apmservers"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["kibana.k8s.elastic.co"] + resources: ["kibanas"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["enterprisesearch.k8s.elastic.co"] + resources: ["enterprisesearches"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["beat.k8s.elastic.co"] + resources: ["beats"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["agent.k8s.elastic.co"] + resources: ["agents"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["maps.k8s.elastic.co"] + resources: ["elasticmapsservers"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["stackconfigpolicy.k8s.elastic.co"] + resources: ["stackconfigpolicies"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["logstash.k8s.elastic.co"] + resources: ["logstashes"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] +{{- if .Values.config.metrics.secureMode.enabled }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "eck-operator.labels" . | nindent 4 }} + name: "{{ include "eck-operator.fullname" . }}-metrics-auth-role" +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +{{- end }} +{{- end -}} diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/templates/configmap.yaml b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/configmap.yaml new file mode 100644 index 00000000..7582f8e6 --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/configmap.yaml @@ -0,0 +1,88 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "eck-operator.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "eck-operator.labels" . | nindent 4 }} +data: + eck.yaml: |- + {{- $metricsPort := int (include "eck-operator.metrics.port" .)}} + log-verbosity: {{ int .Values.config.logVerbosity }} + {{- if and .Values.config.metrics.secureMode.enabled (eq $metricsPort 0) }} + {{- fail "config.metrics.port must be greater than 0 when config.metrics.secureMode.enabled is true" }} + {{- end }} + metrics-port: {{ $metricsPort }} + metrics-secure: {{ .Values.config.metrics.secureMode.enabled }} + container-registry: {{ .Values.config.containerRegistry }} + {{- with .Values.config.containerSuffix }} + container-suffix: {{ . }} + {{- end }} + {{- with .Values.config.containerRepository }} + container-repository: {{ . }} + {{- end }} + max-concurrent-reconciles: {{ int .Values.config.maxConcurrentReconciles }} + {{- with .Values.config.passwordHashCacheSize }} + password-hash-cache-size: {{ int . }} + {{- end }} + ca-cert-validity: {{ .Values.config.caValidity }} + ca-cert-rotate-before: {{ .Values.config.caRotateBefore }} + {{- with .Values.config.caDir }} + ca-dir: {{ . }} + {{- end }} + cert-validity: {{ .Values.config.certificatesValidity }} + cert-rotate-before: {{ .Values.config.certificatesRotateBefore }} + disable-config-watch: {{ .Values.config.disableConfigWatch }} + {{- with .Values.config.exposedNodeLabels }} + exposed-node-labels: [{{ join "," . }}] + {{- end }} + {{- with .Values.config.ipFamily }} + ip-family: {{ . }} + {{- end }} + set-default-security-context: {{ .Values.config.setDefaultSecurityContext }} + kube-client-timeout: {{ .Values.config.kubeClientTimeout }} + {{- with .Values.config.kubeClientQPS }} + kube-client-qps: {{ int . }} + {{- end }} + elasticsearch-client-timeout: {{ .Values.config.elasticsearchClientTimeout }} + disable-telemetry: {{ .Values.telemetry.disabled }} + distribution-channel: {{ .Values.telemetry.distributionChannel }} + {{- with .Values.telemetry.interval }} + telemetry-interval: {{ . }} + {{- end }} + validate-storage-class: {{ .Values.config.validateStorageClass }} + {{- if .Values.tracing.enabled }} + enable-tracing: true + {{- end }} + {{- if .Values.refs.enforceRBAC }} + enforce-rbac-on-refs: true + {{- end }} + enable-webhook: {{ .Values.webhook.enabled }} + {{- if .Values.webhook.enabled }} + webhook-name: {{ include "eck-operator.webhookName" . }} + {{- if not .Values.webhook.manageCerts }} + manage-webhook-certs: false + webhook-cert-dir: {{ .Values.webhook.certsDir }} + {{- end }} + webhook-port: {{ .Values.webhook.port }} + {{- end }} + {{- with .Values.managedNamespaces }} + namespaces: [{{ join "," . }}] + {{- end }} + operator-namespace: {{ .Release.Namespace }} + enable-leader-election: {{ .Values.config.enableLeaderElection }} + elasticsearch-observation-interval: {{ .Values.config.elasticsearchObservationInterval }} + {{- if not .Values.config.containerSuffix }} + ubi-only: {{ .Values.config.ubiOnly }} + {{- end }} + {{- with .Values.webhook.certsSecret }} + webhook-secret: {{ . }} + {{- end }} + {{- $passwordLength := int (dig "policies" "passwords" "length" 0 .Values.config) }} + {{- with $passwordLength }} + {{- if or (lt $passwordLength 6) (gt $passwordLength 72) }} + {{- fail "config.policies.passwords.length must be >= 6 and <= 72" }} + {{- end }} + password-length: {{ $passwordLength }} + {{- end }} diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/templates/managed-namespaces.yaml b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/managed-namespaces.yaml new file mode 100644 index 00000000..91deaf21 --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/managed-namespaces.yaml @@ -0,0 +1,13 @@ +{{- if .Values.softMultiTenancy.enabled -}} +{{- range .Values.managedNamespaces }} +{{- $namespace := . }} +--- +apiVersion: v1 +kind: Namespace +metadata: + name: {{ $namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} + eck.k8s.elastic.co/tenant: {{ $namespace }} +{{- end -}} +{{- end -}} diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/templates/managed-ns-network-policy.yaml b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/managed-ns-network-policy.yaml new file mode 100644 index 00000000..23fc1e3a --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/managed-ns-network-policy.yaml @@ -0,0 +1,228 @@ +{{- if .Values.softMultiTenancy.enabled -}} +{{- $fullName := include "eck-operator.fullname" . -}} +{{- $name := include "eck-operator.name" . -}} +{{- range .Values.managedNamespaces -}} +{{- $namespace := . }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: "{{ $name }}-elasticsearch" + namespace: {{ $namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +spec: + podSelector: + matchLabels: + common.k8s.elastic.co/type: "elasticsearch" + egress: + # Transport port + - ports: + - port: 9300 + to: + # Elasticsearch within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} + podSelector: + matchLabels: + common.k8s.elastic.co/type: "elasticsearch" + # DNS + - ports: + - port: 53 + protocol: UDP + to: [] + ingress: + # HTTP Port + - ports: + - port: 9200 + from: + # Operator + - namespaceSelector: + matchLabels: + name: "{{ $.Release.Namespace }}" + podSelector: + matchLabels: + {{- include "eck-operator.selectorLabels" $ | nindent 14 }} + # Within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} + # Transport port + - ports: + - port: 9300 + from: + # Within namespace (from other Elasticsearch nodes) + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} + podSelector: + matchLabels: + common.k8s.elastic.co/type: "elasticsearch" +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: "{{ $name }}-kibana" + namespace: {{ $namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +spec: + podSelector: + matchLabels: + common.k8s.elastic.co/type: "kibana" + egress: + # Elasticsearch HTTP port + - ports: + - port: 9200 + to: + # Elasticsearch within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} + podSelector: + matchLabels: + common.k8s.elastic.co/type: "elasticsearch" + # DNS + - ports: + - port: 53 + protocol: UDP + to: [] + ingress: + # HTTP Port + - ports: + - port: 5601 + from: + # Within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: "{{ $name }}-apm-server" + namespace: {{ $namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +spec: + podSelector: + matchLabels: + common.k8s.elastic.co/type: "apm-server" + egress: + # Elasticsearch HTTP port + - ports: + - port: 9200 + to: + # Elasticsearch within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} + podSelector: + matchLabels: + common.k8s.elastic.co/type: "elasticsearch" + # Kibana HTTP port + - ports: + - port: 5601 + to: + # Kibana within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} + podSelector: + matchLabels: + common.k8s.elastic.co/type: "kibana" + # DNS + - ports: + - port: 53 + protocol: UDP + to: [] + ingress: + # HTTP Port + - ports: + - port: 8200 + from: + # Within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: "{{ $name }}-enterprise-search" + namespace: {{ $namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +spec: + podSelector: + matchLabels: + common.k8s.elastic.co/type: "enterprise-search" + egress: + # Elasticsearch HTTP port + - ports: + - port: 9200 + to: + # Elasticsearch within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} + podSelector: + matchLabels: + common.k8s.elastic.co/type: "elasticsearch" + # DNS + - ports: + - port: 53 + protocol: UDP + to: [] + ingress: + # HTTP Port + - ports: + - port: 3002 + from: + # Within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: "{{ $name }}-beats" + namespace: {{ $namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +spec: + podSelector: + matchLabels: + common.k8s.elastic.co/type: "beat" + egress: + # Elasticsearch HTTP port + - ports: + - port: 9200 + to: + # Elasticsearch within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} + podSelector: + matchLabels: + common.k8s.elastic.co/type: "elasticsearch" + # Kibana HTTP port + - ports: + - port: 5601 + to: + # Kibana within namespace + - namespaceSelector: + matchLabels: + eck.k8s.elastic.co/tenant: {{ $namespace }} + podSelector: + matchLabels: + common.k8s.elastic.co/type: "kibana" + # DNS + - ports: + - port: 53 + protocol: UDP + to: [] +{{- end }} +{{- end -}} diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/templates/metrics-service.yaml b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/metrics-service.yaml new file mode 100644 index 00000000..53bdc02b --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/metrics-service.yaml @@ -0,0 +1,22 @@ +{{- if .Values.config.metrics.secureMode.enabled }} +{{- $metricsPort := int (include "eck-operator.metrics.port" .)}} +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: {{ include "eck-operator.name" . }}-metrics-service + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} + helm.sh/chart: {{ include "eck-operator.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + name: "{{ include "eck-operator.fullname" . }}-metrics" + namespace: {{ .Release.Namespace }} +spec: + ports: + - name: https + port: {{ $metricsPort }} + protocol: TCP + targetPort: metrics + selector: + {{- include "eck-operator.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/templates/operator-namespace.yaml b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/operator-namespace.yaml new file mode 100644 index 00000000..07123b70 --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/operator-namespace.yaml @@ -0,0 +1,9 @@ +{{- if (and .Values.global.manifestGen .Values.global.createOperatorNamespace) -}} +--- +apiVersion: v1 +kind: Namespace +metadata: + name: {{ .Release.Namespace }} + labels: + name: {{ .Release.Namespace }} +{{- end -}} diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/templates/operator-network-policy.yaml b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/operator-network-policy.yaml new file mode 100644 index 00000000..ad74156d --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/operator-network-policy.yaml @@ -0,0 +1,59 @@ +{{- if .Values.softMultiTenancy.enabled -}} +{{- $kubeAPIServerIP := (required "kubeAPIServerIP is required" .Values.kubeAPIServerIP) -}} +{{- $metricsPort := int (include "eck-operator.metrics.port" .)}} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "eck-operator.fullname" . }} + namespace: {{ .Release.Namespace}} + labels: + {{- include "eck-operator.labels" . | nindent 4 }} +spec: + podSelector: + matchLabels: + {{- include "eck-operator.selectorLabels" . | nindent 6 }} + egress: + # DNS + - ports: + - port: 53 + protocol: UDP + to: [] + # API server + - ports: + - port: 443 + to: + - ipBlock: + cidr: "{{ $kubeAPIServerIP }}/32" + # Elasticsearch + - ports: + - port: 9200 + to: + - namespaceSelector: + matchExpressions: + - key: "eck.k8s.elastic.co/tenant" + operator: In + values: + {{- range .Values.managedNamespaces }} + - {{ . }} + {{- end }} + podSelector: + matchLabels: + common.k8s.elastic.co/type: "elasticsearch" +{{- if or .Values.webhook.enabled (gt $metricsPort 0) }} + ingress: +{{- if .Values.webhook.enabled }} + - ports: + - port: {{ .Values.webhook.port }} + from: + - ipBlock: + cidr: "{{ $kubeAPIServerIP }}/32" +{{- end }} +{{- if gt $metricsPort 0 }} + # Metrics + - ports: + - port: {{ $metricsPort }} + from: [] +{{- end }} +{{- end }} +{{- end -}} diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/templates/pdb.yaml b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/pdb.yaml new file mode 100644 index 00000000..42b494a3 --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/pdb.yaml @@ -0,0 +1,19 @@ +{{- if .Values.podDisruptionBudget.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "eck-operator.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "eck-operator.labels" . | nindent 4 }} +spec: + {{- with .Values.podDisruptionBudget.minAvailable }} + minAvailable: {{ . }} + {{- end }} + {{- with .Values.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} + selector: + matchLabels: + {{- include "eck-operator.selectorLabels" . | nindent 6 }} +{{- end -}} diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/templates/podMonitor.yaml b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/podMonitor.yaml new file mode 100644 index 00000000..8e073cd3 --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/podMonitor.yaml @@ -0,0 +1,42 @@ +{{- $metricsPort := int (include "eck-operator.metrics.port" .)}} +{{- if and .Values.config.metrics.secureMode.enabled (eq $metricsPort 0) }} +{{- fail "config.metrics.port must be greater than 0 when config.metrics.secureMode.enabled is true" }} +{{- end }} +{{- if and .Values.podMonitor.enabled (gt $metricsPort 0) }} +{{- if and .Values.podMonitor.enabled .Values.config.metrics.secureMode.enabled }} +{{- fail "podMonitor and config.metrics.secureMode are mutually exclusive" }} +{{- end }} +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: {{ include "eck-operator.fullname" . }} + namespace: {{ ternary .Values.podMonitor.namespace .Release.Namespace (not (and (.Values.podMonitor) (empty .Values.podMonitor.namespace))) }} + labels: {{- include "eck-operator.labels" . | nindent 4 }} + {{- with .Values.podMonitor.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.podMonitor.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .Values.podMonitor.podTargetLabels }} + podTargetLabels: {{- toYaml . | nindent 4 }} + {{- end }} + podMetricsEndpoints: + - port: metrics + path: /metrics + {{- with .Values.podMonitor.interval }} + interval: {{ . }} + {{- end }} + {{- with .Values.podMonitor.scrapeTimeout }} + scrapeTimeout: {{ . }} + {{- end }} + {{- with .Values.podMonitor.podMetricsEndpointConfig }} + {{- toYaml . | nindent 6 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: {{- include "eck-operator.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/templates/role-bindings.yaml b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/role-bindings.yaml new file mode 100644 index 00000000..0db9f278 --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/role-bindings.yaml @@ -0,0 +1,98 @@ +{{- $operatorNSIsManaged := has .Release.Namespace .Values.managedNamespaces -}} +{{- $fullName := include "eck-operator.fullname" . -}} +{{- $svcAccount := include "eck-operator.serviceAccountName" . }} +{{- $enableSecureMetrics := .Values.config.metrics.secureMode.enabled -}} + +{{- if not .Values.createClusterScopedResources }} +{{- range .Values.managedNamespaces }} +{{- $namespace := . }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: "{{ $fullName }}" + namespace: {{ $namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +rules: +{{ template "eck-operator.rbacRules" $ | toYaml | indent 2 }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: "{{ $fullName }}" + namespace: {{ $namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: "{{ $fullName }}" +subjects: +- kind: ServiceAccount + name: {{ $svcAccount }} + namespace: {{ $.Release.Namespace }} +{{- end }} {{- /* end of range over managed namespaces */}} +{{- /* If createClusterScopedResources is false and operator namespace is not in the managed namespaces list, create additional role binding */}} +{{- if not $operatorNSIsManaged }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ $fullName }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +rules: +{{ template "eck-operator.rbacRules" $ | toYaml | indent 2 }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: "{{ $fullName }}" + namespace: {{ $.Release.Namespace }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: "{{ $fullName }}" +subjects: +- kind: ServiceAccount + name: {{ $svcAccount }} + namespace: {{ $.Release.Namespace }} +{{- end }} {{- /* end of operator role binding if operator namespace is not managed */}} +{{- else }} {{- /* we can create cluster-scoped resources so just create a cluster role binding */}} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ $fullName }} + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ $fullName }} +subjects: +- kind: ServiceAccount + name: {{ $svcAccount }} + namespace: {{ $.Release.Namespace }} +{{- if $enableSecureMetrics }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "eck-operator.labels" $ | nindent 4 }} + name: "{{ include "eck-operator.fullname" . }}-metrics-auth-rolebinding" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: "{{ include "eck-operator.fullname" . }}-metrics-auth-role" +subjects: +- kind: ServiceAccount + name: {{ $svcAccount }} + namespace: {{ $.Release.Namespace }} +{{- end }} +{{- end }} diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/templates/service-account.yaml b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/service-account.yaml new file mode 100644 index 00000000..f91acdcc --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/service-account.yaml @@ -0,0 +1,15 @@ +{{- if .Values.serviceAccount.create }} +--- +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ include "eck-operator.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "eck-operator.labels" . | nindent 4 }} +{{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- end }} diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/templates/service-monitor.yaml b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/service-monitor.yaml new file mode 100644 index 00000000..0d4a3d9c --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/service-monitor.yaml @@ -0,0 +1,34 @@ +{{- if and .Values.config.metrics.secureMode.enabled .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "eck-operator.fullname" . }} + namespace: {{ ternary .Values.serviceMonitor.namespace .Release.Namespace (not (and (.Values.serviceMonitor) (empty .Values.serviceMonitor.namespace))) }} + labels: {{- include "eck-operator.labels" . | nindent 4 }} +spec: + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "eck-operator.name" . }}-metrics-service + app.kubernetes.io/instance: {{ .Release.Name }} + endpoints: + - port: https + path: /metrics + scheme: https + interval: 30s + tlsConfig: + {{- $insecureSkipVerify := (ternary .Values.config.metrics.secureMode.tls.insecureSkipVerify .Values.serviceMonitor.insecureSkipVerify (hasKey .Values.config.metrics.secureMode.tls "insecureSkipVerify")) }} + insecureSkipVerify: {{ $insecureSkipVerify }} + {{- if (not $insecureSkipVerify) }} + {{- $caMountDirectory := or (.Values.config.metrics.secureMode.tls.caMountDirectory) (.Values.serviceMonitor.caMountDirectory) -}} + {{- $leading_path := trimSuffix "/" $caMountDirectory }} + {{- $caSecret := or (.Values.config.metrics.secureMode.tls.caSecret) (.Values.serviceMonitor.caSecret) -}} + {{- with $caSecret }} + caFile: "{{ $leading_path }}/{{ . }}/ca.crt" + {{- end }} + serverName: "{{ include "eck-operator.fullname" . }}-metrics.{{ .Release.Namespace }}.svc" + {{- end }} + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token +{{- end }} diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/templates/statefulset.yaml b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/statefulset.yaml new file mode 100644 index 00000000..c607d8a3 --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/statefulset.yaml @@ -0,0 +1,162 @@ +--- +{{- $metricsPort := int (include "eck-operator.metrics.port" .)}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "eck-operator.fullname" . }} + namespace: {{ .Release.Namespace }} + {{- with .Values.statefulsetAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "eck-operator.labels" . | nindent 4 }} + {{- with .Values.statefulsetLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "eck-operator.selectorLabels" . | nindent 6 }} + serviceName: {{ include "eck-operator.fullname" . }} + replicas: {{ .Values.replicaCount }} + template: + metadata: + annotations: + # Rename the fields "error" to "error.message" and "source" to "event.source" + # This is to avoid a conflict with the ECS "error" and "source" documents. + "co.elastic.logs/raw": "[{\"type\":\"filestream\",\"enabled\":true,\"id\":\"eck-container-logs-${data.kubernetes.container.id}\",\"paths\":[\"/var/log/containers/*${data.kubernetes.container.id}.log\"],\"parsers\":[{\"container\":{}},{\"ndjson\":{\"keys_under_root\":true}}],\"prospector.scanner.symlinks\":true,\"processors\":[{\"convert\":{\"mode\":\"rename\",\"ignore_missing\":true,\"fields\":[{\"from\":\"error\",\"to\":\"_error\"}]}},{\"convert\":{\"mode\":\"rename\",\"ignore_missing\":true,\"fields\":[{\"from\":\"_error\",\"to\":\"error.message\"}]}},{\"convert\":{\"mode\":\"rename\",\"ignore_missing\":true,\"fields\":[{\"from\":\"source\",\"to\":\"_source\"}]}},{\"convert\":{\"mode\":\"rename\",\"ignore_missing\":true,\"fields\":[{\"from\":\"_source\",\"to\":\"event.source\"}]}}]}]" + "checksum/config": {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "eck-operator.selectorLabels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + terminationGracePeriodSeconds: 10 + serviceAccountName: {{ include "eck-operator.serviceAccountName" . }} + automountServiceAccountToken: {{ .Values.automountServiceAccountToken }} + {{- with .Values.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + {{- with .Values.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - image: "{{ .Values.image.repository }}{{- if .Values.config.ubiOnly -}}-ubi{{- end -}}{{- if .Values.image.fips -}}-fips{{- end -}}:{{ default .Chart.AppVersion .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + name: manager + args: + - "manager" + - "--config=/conf/eck.yaml" + {{- with .Values.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + env: + - name: OPERATOR_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + {{- if .Values.webhook.enabled }} + - name: WEBHOOK_SECRET + value: {{ include "eck-operator.webhookSecretName" . }} + {{- end }} + {{- with .Values.env }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.tracing.enabled -}} + {{- range $name, $value := .Values.tracing.config }} + - name: {{ $name }} + value: {{ $value }} + {{- end }} + {{- end }} + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if or .Values.webhook.enabled (gt $metricsPort 0) }} + ports: + {{- if (gt $metricsPort 0) }} + - containerPort: {{ $metricsPort }} + name: metrics + protocol: TCP + {{- end }} + {{- if .Values.webhook.enabled }} + - containerPort: {{ .Values.webhook.port }} + name: https-webhook + protocol: TCP + {{- end }} + {{- end }} + volumeMounts: + - mountPath: "/conf" + name: conf + readOnly: true + {{- if .Values.webhook.enabled }} + - mountPath: {{ .Values.webhook.certsDir }} + name: cert + readOnly: true + {{- end }} + {{- if .Values.config.metrics.secureMode.tls.certificateSecret }} + - mountPath: "/tmp/k8s-metrics-server/serving-certs" + name: tls-certificate + readOnly: true + {{- end }} + {{- with .Values.volumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + volumes: + - name: conf + configMap: + name: {{ include "eck-operator.fullname" . }} + {{- if .Values.webhook.enabled }} + - name: cert + secret: + defaultMode: 420 + secretName: {{ include "eck-operator.webhookSecretName" . }} + {{- end }} + {{- if .Values.config.metrics.secureMode.tls.certificateSecret }} + - name: tls-certificate + secret: + defaultMode: 420 + secretName: {{ .Values.config.metrics.secureMode.tls.certificateSecret }} + {{- end }} + {{- with .Values.volumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.hostNetwork }} + hostNetwork: true + {{- end }} + {{- if .Values.dnsPolicy }} + dnsPolicy: {{ .Values.dnsPolicy }} + {{- else if .Values.hostNetwork }} + dnsPolicy: ClusterFirstWithHostNet + {{- end }} + {{- with .Values.dnsConfig }} + dnsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/templates/validate-chart.yaml b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/validate-chart.yaml new file mode 100644 index 00000000..326b70bc --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/validate-chart.yaml @@ -0,0 +1,29 @@ +{{- if .Values.softMultiTenancy.enabled -}} + {{- if has .Release.Namespace .Values.managedNamespaces -}} + {{- fail "Operator namespace cannot be in managed namespaces when soft multi-tenancy is enabled" -}} + {{- end -}} + + {{- if empty .Values.managedNamespaces -}} + {{- fail "Managed namespaces must be defined when soft multi-tenancy is enabled" -}} + {{- end -}} + + {{- if empty .Values.kubeAPIServerIP -}} + {{- fail "Soft multi-tenancy requires kubeAPIServerIP to be defined" -}} + {{- end -}} +{{- end -}} + +{{- if (not .Values.createClusterScopedResources) -}} + {{- if .Values.webhook.enabled -}} + {{- fail "Webhook cannot be enabled when cluster-scoped resource creation is disabled" -}} + {{- end -}} + + {{- if .Values.config.validateStorageClass -}} + {{- fail "Storage class validation cannot be enabled when cluster-scoped resource creation is disabled" -}} + {{- end -}} +{{- end -}} + +{{- if (not .Values.config.enableLeaderElection) -}} + {{- if gt (int .Values.replicaCount) 1 -}} + {{- fail "Leader election must be enabled with more than one replica" -}} + {{- end -}} +{{- end -}} diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/templates/webhook.yaml b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/webhook.yaml new file mode 100644 index 00000000..e31df165 --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/templates/webhook.yaml @@ -0,0 +1,473 @@ +{{- if .Values.webhook.enabled -}} +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: {{ include "eck-operator.webhookName" . }} + labels: + {{- include "eck-operator.labels" . | nindent 4 }} +{{- with .Values.webhook.certManagerCert }} + annotations: + cert-manager.io/inject-ca-from: "{{ $.Release.Namespace }}/{{ . }}" +{{- end }} +webhooks: +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-agent-k8s-elastic-co-v1alpha1-agent + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-agent-validation-v1alpha1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1] + sideEffects: None + rules: + - apiGroups: + - agent.k8s.elastic.co + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - agents +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-apm-k8s-elastic-co-v1-apmserver + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-apm-validation-v1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1] + sideEffects: None + rules: + - apiGroups: + - apm.k8s.elastic.co + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - apmservers +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-apm-k8s-elastic-co-v1beta1-apmserver + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-apm-validation-v1beta1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1] + sideEffects: None + rules: + - apiGroups: + - apm.k8s.elastic.co + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - apmservers +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-beat-k8s-elastic-co-v1beta1-beat + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-beat-validation-v1beta1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1] + sideEffects: None + rules: + - apiGroups: + - beat.k8s.elastic.co + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - beats +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-enterprisesearch-k8s-elastic-co-v1-enterprisesearch + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-ent-validation-v1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1] + sideEffects: None + rules: + - apiGroups: + - enterprisesearch.k8s.elastic.co + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - enterprisesearches +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-enterprisesearch-k8s-elastic-co-v1beta1-enterprisesearch + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-ent-validation-v1beta1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1] + sideEffects: None + rules: + - apiGroups: + - enterprisesearch.k8s.elastic.co + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - enterprisesearches +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-elasticsearch-k8s-elastic-co-v1-elasticsearch + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-es-validation-v1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1] + sideEffects: None + rules: + - apiGroups: + - elasticsearch.k8s.elastic.co + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - elasticsearches +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-elasticsearch-k8s-elastic-co-v1beta1-elasticsearch + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-es-validation-v1beta1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1] + sideEffects: None + rules: + - apiGroups: + - elasticsearch.k8s.elastic.co + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - elasticsearches +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-ems-k8s-elastic-co-v1alpha1-mapsservers + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-ems-validation-v1alpha1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1] + sideEffects: None + rules: + - apiGroups: + - maps.k8s.elastic.co + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - mapsservers +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-kibana-k8s-elastic-co-v1-kibana + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-kb-validation-v1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1] + sideEffects: None + rules: + - apiGroups: + - kibana.k8s.elastic.co + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - kibanas +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-kibana-k8s-elastic-co-v1beta1-kibana + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-kb-validation-v1beta1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1] + sideEffects: None + rules: + - apiGroups: + - kibana.k8s.elastic.co + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - kibanas +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-autoscaling-k8s-elastic-co-v1alpha1-elasticsearchautoscaler + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-esa-validation-v1alpha1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1] + sideEffects: None + rules: + - apiGroups: + - autoscaling.k8s.elastic.co + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - elasticsearchautoscalers +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-scp-k8s-elastic-co-v1alpha1-stackconfigpolicies + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-scp-validation-v1alpha1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1] + sideEffects: None + rules: + - apiGroups: + - stackconfigpolicy.k8s.elastic.co + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - stackconfigpolicies +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-logstash-k8s-elastic-co-v1alpha1-logstash + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-logstash-validation-v1alpha1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1] + sideEffects: None + rules: + - apiGroups: + - logstash.k8s.elastic.co + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - logstashes +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "eck-operator.labels" . | nindent 4 }} +spec: + ports: + - name: https + port: 443 + targetPort: {{ .Values.webhook.port }} + selector: + {{- include "eck-operator.selectorLabels" . | nindent 4 }} +{{- if .Values.webhook.manageCerts }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "eck-operator.webhookSecretName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "eck-operator.labels" . | nindent 4 }} +{{- end }} +{{- end -}} diff --git a/packs/elastic-operator-3.2.0/charts/eck-operator/values.yaml b/packs/elastic-operator-3.2.0/charts/eck-operator/values.yaml new file mode 100644 index 00000000..adc48be3 --- /dev/null +++ b/packs/elastic-operator-3.2.0/charts/eck-operator/values.yaml @@ -0,0 +1,377 @@ +# nameOverride is the short name for the deployment. Leave empty to let Helm generate a name using chart values. +nameOverride: "elastic-operator" + +# fullnameOverride is the full name for the deployment. Leave empty to let Helm generate a name using chart values. +fullnameOverride: "elastic-operator" + +# managedNamespaces is the set of namespaces that the operator manages. Leave empty to manage all namespaces. +managedNamespaces: [] + +# installCRDs determines whether Custom Resource Definitions (CRD) are installed by the chart. +# Note that CRDs are global resources and require cluster admin privileges to install. +# If you are sharing a cluster with other users who may want to install ECK on their own namespaces, setting this to true can have unintended consequences. +# 1. Upgrades will overwrite the global CRDs and could disrupt the other users of ECK who may be running a different version. +# 2. Uninstalling the chart will delete the CRDs and potentially cause Elastic resources deployed by other users to be removed as well. +installCRDs: true + +# replicaCount is the number of operator pods to run. +replicaCount: 1 + +image: + # repository is the container image prefixed by the registry name. + repository: docker.elastic.co/eck/eck-operator + # pullPolicy is the container image pull policy. + pullPolicy: IfNotPresent + # tag is the container image tag. If not defined, defaults to chart appVersion. + tag: null + # fips specifies whether the operator will use a FIPS compliant container image for its own StatefulSet image. + # This setting does not apply to Elastic Stack applications images. + # Can be combined with config.ubiOnly. + fips: false + +# priorityClassName defines the PriorityClass to be used by the operator pods. +priorityClassName: "" + +# imagePullSecrets defines the secrets to use when pulling the operator container image. +imagePullSecrets: [] + +# resources define the container resource limits for the operator. +resources: + limits: + cpu: 1 + memory: 1Gi + requests: + cpu: 100m + memory: 150Mi + +# statefulsetAnnotations define the annotations that should be added to the operator StatefulSet. +statefulsetAnnotations: {} + +# statefulsetLabels define additional labels that should be added to the operator StatefulSet. +statefulsetLabels: {} + +# podAnnotations define the annotations that should be added to the operator pod. +podAnnotations: {} + +## podLabels define additional labels that should be added to the operator pod. +podLabels: {} + +# podSecurityContext defines the pod security context for the operator pod. +podSecurityContext: + runAsNonRoot: true + +# securityContext defines the security context of the operator container. +securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + +# nodeSelector defines the node selector for the operator pod. +nodeSelector: {} + +# tolerations defines the node tolerations for the operator pod. +tolerations: [] + +# affinity defines the node affinity rules for the operator pod. +affinity: {} + +# podDisruptionBudget configures the minimum or the maxium available pods for voluntary disruptions, +# set to either an integer (e.g. 1) or a percentage value (e.g. 25%). +podDisruptionBudget: + enabled: false + minAvailable: 1 + # maxUnavailable: 3 + +# additional environment variables for the operator container. +env: [] + +# additional volume mounts for the operator container. +volumeMounts: [] + +# additional volumes to add to the operator pod. +volumes: [] + +# createClusterScopedResources determines whether cluster-scoped resources (ClusterRoles, ClusterRoleBindings) should be created. +createClusterScopedResources: true + +# Automount API credentials for the Service Account into the pod. +automountServiceAccountToken: true + +serviceAccount: + # create specifies whether a service account should be created for the operator. + create: true + # Specifies whether a service account should automount API credentials. + automountServiceAccountToken: true + # annotations to add to the service account + annotations: {} + # name of the service account to use. If not set and create is true, a name is generated using the fullname template. + name: "" + +tracing: + # enabled specifies whether APM tracing is enabled for the operator. + enabled: false + # config is a map of APM Server configuration variables that should be set in the environment. + config: + ELASTIC_APM_SERVER_URL: http://localhost:8200 + ELASTIC_APM_SERVER_TIMEOUT: 30s + +refs: + # enforceRBAC specifies whether RBAC should be enforced for cross-namespace associations between resources. + enforceRBAC: false + +webhook: + # enabled determines whether the webhook is installed. + enabled: true + # caBundle is the PEM-encoded CA trust bundle for the webhook certificate. Only required if manageCerts is false and certManagerCert is null. + caBundle: Cg== + # certManagerCert is the name of the cert-manager certificate to use with the webhook. + certManagerCert: null + # certsDir is the directory to mount the certificates. + certsDir: "/tmp/k8s-webhook-server/serving-certs" + # failurePolicy of the webhook. + failurePolicy: Ignore + # manageCerts determines whether the operator manages the webhook certificates automatically. + manageCerts: true + # namespaceSelector corresponds to the namespaceSelector property of the webhook. + # Setting this restricts the webhook to act only on objects submitted to namespaces that match the selector. + namespaceSelector: {} + # objectSelector corresponds to the objectSelector property of the webhook. + # Setting this restricts the webhook to act only on objects that match the selector. + objectSelector: {} + # port is the port that the validating webhook binds to. + port: 9443 + # secret specifies the Kubernetes secret to be mounted into the path designated by the certsDir value to be used for webhook certificates. + certsSecret: "" + +# hostNetwork allows a Pod to use the Node network namespace. +# This is required to allow for communication with the kube API when using some alternate CNIs in conjunction with webhook enabled. +# If hostNetwork is enabled, dnsPolicy defaults to ClusterFirstWithHostNet unless explicitly set. +# CAUTION: Proceed at your own risk. This setting has security concerns such as allowing malicious users to access workloads running on the host. +hostNetwork: false + +# dnsPolicy defines the DNS policy for the operator pod. +# Check https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy for more details. +dnsPolicy: "" + +# dnsConfig defines the DNS configuration for the operator pod. +# Check https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-dns-config for more details. +# dnsConfig: +# nameservers: +# - 169.254.20.10 +# searches: +# - svc.cluster.local +# options: +# - name: ndots +# value: "2" +dnsConfig: {} + +softMultiTenancy: + # enabled determines whether the operator is installed with soft multi-tenancy extensions. + # This requires network policies to be enabled on the Kubernetes cluster. + enabled: false + +# kubeAPIServerIP is required when softMultiTenancy is enabled. +kubeAPIServerIP: null + +telemetry: + # disabled determines whether the operator periodically updates ECK telemetry data for Kibana to consume. + disabled: false + # distributionChannel denotes which distribution channel was used to install the operator. + distributionChannel: "helm" + +# config values for the operator. +config: + # logVerbosity defines the logging level. Valid values are as follows: + # -2: Errors only + # -1: Errors and warnings + # 0: Errors, warnings, and information + # number greater than 0: Errors, warnings, information, and debug details. + logVerbosity: "0" + + # (Deprecated: use metrics.port: will be removed in v2.14.0) metricsPort defines the port to expose operator metrics. Set to 0 to disable metrics reporting. + metricsPort: 0 + + metrics: + # port defines the port to expose operator metrics. Set to 0 to disable metrics reporting. + port: "0" + # secureMode contains the options for enabling and configuring RBAC and TLS/HTTPs for the metrics endpoint. + secureMode: + # secureMode.enabled specifies whether to enable RBAC and TLS/HTTPs for the metrics endpoint. + # * This option makes most sense when using a ServiceMonitor to scrape the metrics and is therefore mutually exclusive with the podMonitor.enabled option. + # * This option also requires using cluster scoped resources (ClusterRole, ClusterRoleBinding) to + # grant access to the /metrics endpoint. (createClusterScopedResources: true is required) + # + enabled: false + tls: + # certificateSecret is the name of the tls secret containing the custom TLS certificate and key for the secure metrics endpoint. + # + # * This is an optional setting and is only required if you are using a custom TLS certificate. A self-signed certificate will be generated by default. + # * TLS secret key must be named tls.crt. + # * TLS key's secret key must be named tls.key. + # * It is assumed to be in the same namespace as the ServiceMonitor. + # + # example: kubectl create secret tls eck-metrics-tls-certificate -n elastic-system \ + # --cert=/path/to/tls.crt --key=/path/to/tls.key + certificateSecret: "" + + # containerRegistry to use for pulling Elasticsearch and other application container images. + containerRegistry: docker.elastic.co + + # containerRepository to use for pulling Elasticsearch and other application container images. + # containerRepository: "" + + # containerSuffix suffix to be appended to container images by default. Cannot be combined with -ubiOnly flag + # containerSuffix: "" + + # maxConcurrentReconciles is the number of concurrent reconciliation operations to perform per controller. + maxConcurrentReconciles: "3" + + # caValidity defines the validity period of the CA certificates generated by the operator. + caValidity: 8760h + + # caRotateBefore defines when to rotate a CA certificate that is due to expire. + caRotateBefore: 24h + + # caDir defines the directory containing a CA certificate (tls.crt) and its associated private key (tls.key) to be used for all managed resources. + # Setting this makes caRotateBefore and caValidity values ineffective. + caDir: "" + + # certificatesValidity defines the validity period of certificates generated by the operator. + certificatesValidity: 8760h + + # certificatesRotateBefore defines when to rotate a certificate that is due to expire. + certificatesRotateBefore: 24h + + # disableConfigWatch specifies whether the operator watches the configuration file for changes. + disableConfigWatch: false + + # exposedNodeLabels is an array of regular expressions of node labels which are allowed to be copied as annotations on Elasticsearch Pods. + exposedNodeLabels: + ["topology.kubernetes.io/.*", "failure-domain.beta.kubernetes.io/.*"] + + # ipFamily specifies the IP family to use. Possible values: IPv4, IPv6 and "" (auto-detect) + ipFamily: "" + + # setDefaultSecurityContext determines whether a default security context is set on application containers created by the operator. + # *note* that the default option now is "auto-detect" to attempt to set this properly automatically when both running + # in an openshift cluster, and a standard kubernetes cluster. Valid values are as follows: + # "auto-detect" : auto detect + # "true" : set pod security context when creating resources. + # "false" : do not set pod security context when creating resources. + setDefaultSecurityContext: "auto-detect" + + # kubeClientTimeout sets the request timeout for Kubernetes API calls made by the operator. + kubeClientTimeout: 60s + + # elasticsearchClientTimeout sets the request timeout for Elasticsearch API calls made by the operator. + elasticsearchClientTimeout: 180s + + # policies contains policies for the operator, currently only password generation policies are supported. + policies: {} + # passwords: + # length: 24 + + # validateStorageClass specifies whether storage classes volume expansion support should be verified. + # Can be disabled if cluster-wide storage class RBAC access is not available. + validateStorageClass: true + + # enableLeaderElection specifies whether leader election should be enabled + enableLeaderElection: true + + # Interval between observations of Elasticsearch health, non-positive values disable asynchronous observation. + elasticsearchObservationInterval: 10s + + # ubiOnly specifies whether the operator will use only UBI container images to deploy Elastic Stack applications as well as for its own StatefulSet image. UBI images are only available from 7.10.0 onward. + # Cannot be combined with the containerSuffix value. + ubiOnly: false + +# Prometheus PodMonitor configuration +# Reference: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#podmonitor +podMonitor: + # enabled determines whether a podMonitor should deployed to scrape the eck metrics. + # This requires the prometheus operator and the config.metrics.port not to be 0 + enabled: false + + # labels adds additional labels to the podMonitor + labels: {} + + # annotations adds additional annotations to the podMonitor + annotations: {} + + # namespace determines in which namespace the podMonitor will be deployed. + # If not set the podMonitor will be created in the namespace where the Helm release is installed into + # namespace: monitoring + + # interval specifies the interval at which metrics should be scraped + interval: 5m + + # scrapeTimeout specifies the timeout after which the scrape is ended + scrapeTimeout: 30s + + # podTargetLabels transfers labels on the Kubernetes Pod onto the target. + podTargetLabels: [] + + # podMetricsEndpointConfig allows to add an extended configuration to the podMonitor + podMetricsEndpointConfig: {} + # honorTimestamps: true + +# Prometheus ServiceMonitor configuration +# Only used when config.enableSecureMetrics is true +# Reference: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#servicemonitor +serviceMonitor: + # This option requires the following settings within Prometheus to function: + # 1. RBAC settings for the Prometheus instance to access the metrics endpoint. + # + # - nonResourceURLs: + # - /metrics + # verbs: + # - get + # + # 2. If using the Prometheus Operator and your Prometheus instance is not in the same namespace as the operator you will need + # the Prometheus Operator configured with the following Helm values: + # + # prometheus: + # prometheusSpec: + # serviceMonitorNamespaceSelector: {} + # serviceMonitorSelectorNilUsesHelmValues: false + # + # allows to disable the serviceMonitor, enabled by default for backwards compatibility + enabled: true + # namespace determines in which namespace the serviceMonitor will be deployed. + # If not set the serviceMonitor will be created in the namespace where the Helm release is installed into + # namespace: monitoring + # caSecret is the name of the secret containing the custom CA certificate used to generate the custom TLS certificate for the secure metrics endpoint. + # + # * This *must* be the name of the secret containing the CA certificate used to sign the custom TLS certificate for the metrics endpoint. + # * This secret *must* be in the same namespace as the Prometheus instance that will scrape the metrics. + # * If using the Prometheus operator this secret must be within the `spec.secrets` field of the `Prometheus` custom resource such that it is mounted into the Prometheus pod at `caMountDirectory`, which defaults to /etc/prometheus/secrets/{secret-name}. + # * This is an optional setting and is only required if you are using a custom TLS certificate. + # * Key must be named ca.crt. + # + # example: kubectl create secret generic eck-metrics-tls-ca -n monitoring \ + # --from-file=ca.crt=/path/to/ca.pem + caSecret: "" + # caMountDirectory is the directory at which the CA certificate is mounted within the Prometheus pod. + # + # * You should only need to adjust this if you are *not* using the Prometheus operator. + caMountDirectory: "/etc/prometheus/secrets/" + # insecureSkipVerify specifies whether to skip verification of the TLS certificate for the secure metrics endpoint. + # + # * If this setting is set to false, then the following settings are required: + # - certificateSecret + # - caSecret + insecureSkipVerify: true + +# Globals meant for internal use only +global: + # manifestGen specifies whether the chart is running under manifest generator. + # This is used for tasks specific to generating the all-in-one.yaml file. + manifestGen: false + # createOperatorNamespace defines whether the operator namespace manifest should be generated when in manifestGen mode. + # Usually we do want that to happen (e.g. all-in-one.yaml) but, sometimes we don't (e.g. E2E tests). + createOperatorNamespace: true + # kubeVersion is the effective Kubernetes version we target when generating the all-in-one.yaml. + kubeVersion: 1.21.0 diff --git a/packs/elastic-operator-3.2.0/logo.png b/packs/elastic-operator-3.2.0/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..fa70b78daa45585ec0f802dfe637e4ce2172d6f8 GIT binary patch literal 5810 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 Date: Thu, 6 Nov 2025 15:00:25 -0500 Subject: [PATCH 6/8] Upgrade elastic-stack pack to version 0.17.0 --- packs/elastic-stack-0.17.0/README.md | 63 +++ .../charts/eck-stack-0.17.0.tgz | Bin 0 -> 44763 bytes .../charts/eck-stack/.helmignore | 25 ++ .../charts/eck-stack/Chart.lock | 27 ++ .../charts/eck-stack/Chart.yaml | 39 ++ .../charts/eck-stack/README.md | 93 +++++ .../eck-stack/charts/eck-agent/.helmignore | 24 ++ .../eck-stack/charts/eck-agent/Chart.yaml | 10 + .../charts/eck-stack/charts/eck-agent/LICENSE | 93 +++++ .../eck-agent/examples/fleet-agents.yaml | 24 ++ .../examples/system-integration.yaml | 133 ++++++ .../charts/eck-agent/templates/NOTES.txt | 6 + .../charts/eck-agent/templates/_helpers.tpl | 51 +++ .../templates/cluster-role-binding.yaml | 33 ++ .../eck-agent/templates/cluster-role.yaml | 22 + .../eck-agent/templates/elastic-agent.yaml | 89 ++++ .../eck-agent/templates/service-account.yaml | 22 + .../eck-stack/charts/eck-agent/values.yaml | 257 ++++++++++++ .../charts/eck-apm-server/.helmignore | 24 ++ .../charts/eck-apm-server/Chart.yaml | 10 + .../eck-stack/charts/eck-apm-server/LICENSE | 93 +++++ .../jaeger-with-http-configuration.yaml | 29 ++ .../charts/eck-apm-server/templates/NOTES.txt | 6 + .../eck-apm-server/templates/_helpers.tpl | 51 +++ .../eck-apm-server/templates/apmserver.yaml | 53 +++ .../charts/eck-apm-server/values.yaml | 108 +++++ .../eck-stack/charts/eck-beats/.helmignore | 24 ++ .../eck-stack/charts/eck-beats/Chart.yaml | 10 + .../charts/eck-stack/charts/eck-beats/LICENSE | 93 +++++ .../eck-beats/examples/auditbeat_hosts.yaml | 110 +++++ .../examples/filebeat_no_autodiscover.yaml | 52 +++ .../examples/heartbeat_es_kb_health.yaml | 23 + .../eck-beats/examples/metricbeat_hosts.yaml | 158 +++++++ .../examples/packetbeat_dns_http.yaml | 37 ++ .../charts/eck-beats/templates/NOTES.txt | 6 + .../charts/eck-beats/templates/_helpers.tpl | 51 +++ .../charts/eck-beats/templates/beats.yaml | 75 ++++ .../templates/cluster-role-binding.yaml | 35 ++ .../eck-beats/templates/cluster-role.yaml | 22 + .../eck-beats/templates/service-account.yaml | 23 + .../eck-stack/charts/eck-beats/values.yaml | 181 ++++++++ .../charts/eck-elasticsearch/.helmignore | 24 ++ .../charts/eck-elasticsearch/Chart.yaml | 10 + .../charts/eck-elasticsearch/LICENSE | 93 +++++ .../examples/hot-warm-cold.yaml | 198 +++++++++ .../ingress/elasticsearch-ingress-aks.yaml | 26 ++ .../elasticsearch-ingress-eks-alb.yaml | 37 ++ .../elasticsearch-ingress-eks-nlb.yaml | 27 ++ .../ingress/elasticsearch-ingress-gke.yaml | 36 ++ .../eck-elasticsearch/templates/NOTES.txt | 6 + .../eck-elasticsearch/templates/_helpers.tpl | 51 +++ .../templates/elasticsearch.yaml | 78 ++++ .../eck-elasticsearch/templates/ingress.yaml | 48 +++ .../charts/eck-elasticsearch/values.yaml | 393 ++++++++++++++++++ .../charts/eck-enterprise-search/.helmignore | 24 ++ .../charts/eck-enterprise-search/Chart.yaml | 9 + .../examples/with-custom-configuration.yaml | 19 + .../templates/_helpers.tpl | 62 +++ .../templates/enterprisesearch.yaml | 62 +++ .../charts/eck-enterprise-search/values.yaml | 108 +++++ .../charts/eck-fleet-server/.helmignore | 24 ++ .../charts/eck-fleet-server/Chart.yaml | 11 + .../eck-stack/charts/eck-fleet-server/LICENSE | 93 +++++ .../examples/fleet-server.yaml | 17 + .../eck-fleet-server/templates/NOTES.txt | 6 + .../eck-fleet-server/templates/_helpers.tpl | 51 +++ .../templates/cluster-role-binding.yaml | 33 ++ .../templates/cluster-role.yaml | 22 + .../templates/fleet-server.yaml | 64 +++ .../templates/service-account.yaml | 22 + .../charts/eck-fleet-server/values.yaml | 169 ++++++++ .../eck-stack/charts/eck-kibana/.helmignore | 24 ++ .../eck-stack/charts/eck-kibana/Chart.yaml | 10 + .../eck-stack/charts/eck-kibana/LICENSE | 93 +++++ .../examples/http-configuration.yaml | 36 ++ .../examples/ingress/kibana-aks.yaml | 28 ++ .../examples/ingress/kibana-eks.yaml | 48 +++ .../examples/ingress/kibana-gke.yaml | 31 ++ .../charts/eck-kibana/templates/NOTES.txt | 6 + .../charts/eck-kibana/templates/_helpers.tpl | 51 +++ .../charts/eck-kibana/templates/ingress.yaml | 48 +++ .../charts/eck-kibana/templates/kibana.yaml | 61 +++ .../eck-stack/charts/eck-kibana/values.yaml | 190 +++++++++ .../eck-stack/charts/eck-logstash/.helmignore | 24 ++ .../eck-stack/charts/eck-logstash/Chart.yaml | 10 + .../eck-stack/charts/eck-logstash/LICENSE | 93 +++++ .../eck-logstash/examples/basic-eck.yaml | 44 ++ .../charts/eck-logstash/examples/es-role.yaml | 25 ++ .../eck-logstash/examples/monitored.yaml | 49 +++ .../charts/eck-logstash/examples/multi.yaml | 78 ++++ .../charts/eck-logstash/examples/volumes.yaml | 107 +++++ .../charts/eck-logstash/templates/NOTES.txt | 6 + .../eck-logstash/templates/_helpers.tpl | 51 +++ .../eck-logstash/templates/logstash.yaml | 58 +++ .../eck-stack/charts/eck-logstash/values.yaml | 115 +++++ .../examples/agent/fleet-agents.yaml | 122 ++++++ .../eck-stack/examples/apm-server/basic.yaml | 52 +++ .../jaeger-with-http-configuration.yaml | 60 +++ .../examples/beats/metricbeat_hosts.yaml | 217 ++++++++++ .../examples/custom-elasticsearch-kibana.yaml | 78 ++++ .../examples/elasticsearch/hot-warm-cold.yaml | 199 +++++++++ .../ingress/elasticsearch-ingress-gke.yaml | 40 ++ .../examples/enterprise-search/basic.yaml | 42 ++ .../with-custom-configuration.yaml | 52 +++ .../examples/kibana/http-configuration.yaml | 23 + .../examples/kibana/ingress/kibana-gke.yaml | 80 ++++ .../examples/logstash/basic-eck.yaml | 113 +++++ .../charts/eck-stack/templates/NOTES.txt | 10 + .../charts/eck-stack/templates/_helpers.tpl | 48 +++ .../charts/eck-stack/values.yaml | 50 +++ packs/elastic-stack-0.17.0/logo.png | Bin 0 -> 5810 bytes packs/elastic-stack-0.17.0/pack.json | 36 ++ packs/elastic-stack-0.17.0/presets.yaml | 260 ++++++++++++ packs/elastic-stack-0.17.0/values.yaml | 71 ++++ 114 files changed, 6947 insertions(+) create mode 100644 packs/elastic-stack-0.17.0/README.md create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack-0.17.0.tgz create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/.helmignore create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/Chart.lock create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/Chart.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/README.md create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/.helmignore create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/Chart.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/LICENSE create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/examples/fleet-agents.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/examples/system-integration.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/templates/NOTES.txt create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/templates/_helpers.tpl create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/templates/cluster-role-binding.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/templates/cluster-role.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/templates/elastic-agent.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/templates/service-account.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/values.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/.helmignore create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/Chart.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/LICENSE create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/examples/jaeger-with-http-configuration.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/templates/NOTES.txt create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/templates/_helpers.tpl create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/templates/apmserver.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/values.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/.helmignore create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/Chart.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/LICENSE create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/examples/auditbeat_hosts.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/examples/filebeat_no_autodiscover.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/examples/heartbeat_es_kb_health.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/examples/metricbeat_hosts.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/examples/packetbeat_dns_http.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/templates/NOTES.txt create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/templates/_helpers.tpl create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/templates/beats.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/templates/cluster-role-binding.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/templates/cluster-role.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/templates/service-account.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/values.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/.helmignore create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/Chart.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/LICENSE create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/examples/hot-warm-cold.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-aks.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-eks-alb.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-eks-nlb.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-gke.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/templates/NOTES.txt create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/templates/_helpers.tpl create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/templates/elasticsearch.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/templates/ingress.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/values.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-enterprise-search/.helmignore create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-enterprise-search/Chart.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-enterprise-search/examples/with-custom-configuration.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-enterprise-search/templates/_helpers.tpl create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-enterprise-search/templates/enterprisesearch.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-enterprise-search/values.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/.helmignore create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/Chart.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/LICENSE create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/examples/fleet-server.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/templates/NOTES.txt create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/templates/_helpers.tpl create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/templates/cluster-role-binding.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/templates/cluster-role.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/templates/fleet-server.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/templates/service-account.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/values.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/.helmignore create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/Chart.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/LICENSE create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/examples/http-configuration.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-aks.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-eks.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-gke.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/templates/NOTES.txt create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/templates/_helpers.tpl create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/templates/ingress.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/templates/kibana.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/values.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/.helmignore create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/Chart.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/LICENSE create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/examples/basic-eck.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/examples/es-role.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/examples/monitored.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/examples/multi.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/examples/volumes.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/templates/NOTES.txt create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/templates/_helpers.tpl create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/templates/logstash.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/values.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/examples/agent/fleet-agents.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/examples/apm-server/basic.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/examples/apm-server/jaeger-with-http-configuration.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/examples/beats/metricbeat_hosts.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/examples/custom-elasticsearch-kibana.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/examples/elasticsearch/hot-warm-cold.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/examples/elasticsearch/ingress/elasticsearch-ingress-gke.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/examples/enterprise-search/basic.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/examples/enterprise-search/with-custom-configuration.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/examples/kibana/http-configuration.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/examples/kibana/ingress/kibana-gke.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/examples/logstash/basic-eck.yaml create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/templates/NOTES.txt create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/templates/_helpers.tpl create mode 100644 packs/elastic-stack-0.17.0/charts/eck-stack/values.yaml create mode 100644 packs/elastic-stack-0.17.0/logo.png create mode 100644 packs/elastic-stack-0.17.0/pack.json create mode 100644 packs/elastic-stack-0.17.0/presets.yaml create mode 100644 packs/elastic-stack-0.17.0/values.yaml diff --git a/packs/elastic-stack-0.17.0/README.md b/packs/elastic-stack-0.17.0/README.md new file mode 100644 index 00000000..e14e757b --- /dev/null +++ b/packs/elastic-stack-0.17.0/README.md @@ -0,0 +1,63 @@ +# Elastic Cloud on Kubernetes (ECK) + +Elastic Cloud on Kubernetes automates the deployment, provisioning, management, and orchestration of Elasticsearch, Kibana, APM Server, Enterprise Search, Beats, Elastic Agent, Elastic Maps Server, and Logstash on Kubernetes based on the operator pattern. + +Current features: + +* Elasticsearch, Kibana, APM Server, Enterprise Search, and Beats deployments +* TLS Certificates management +* Safe Elasticsearch cluster configuration & topology changes +* Persistent volumes usage +* Custom node configuration and attributes +* Secure settings keystore updates + +Supported versions: + +* Kubernetes 1.25-1.29 +* Elasticsearch, Kibana, APM Server: 6.8+, 7.1+, 8+, 9+ +* Enterprise Search: 7.7+, 8+ +* Beats: 7.0+, 8+, 9+ +* Elastic Agent: 7.10+ (standalone), 7.14+, 8+ (Fleet), 9+ +* Elastic Maps Server: 7.11+, 8+ +* Logstash 8.7+, 9+ + +Check the [Quickstart](https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-quickstart.html) to deploy your first cluster with ECK. + +For general questions, please see the Elastic [forums](https://discuss.elastic.co/c/eck). + +# ECK-Stack + +ECK Stack is a Helm chart to assist in the deployment of Elastic Stack components, which are +managed by the [ECK Operator](https://www.elastic.co/guide/en/cloud-on-k8s/current/index.html) + +## Supported Elastic Stack Resources + +The following Elastic Stack resources are currently supported. + +- Elasticsearch +- Kibana +- Elastic Agent +- Fleet Server +- Beats +- Logstash +- APM Server + +Additional resources will be supported in future releases of this Helm Chart. + +## Prerequisites + +- Kubernetes 1.27+ +- Elastic ECK Operator + +## Configuration + +The following table lists the configurable parameters of the eck-stack chart and their default values. + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `eck-elasticsearch.enabled` | If `true`, create an Elasticsearch resource (using the eck-elasticsearch Chart) | `true` | +| `eck-kibana.enabled` | If `true`, create a Kibana resource (using the eck-kibana Chart) | `true` | +| `eck-agent.enabled` | If `true`, create an Elastic Agent resource (using the eck-agent Chart) | `false` | +| `eck-fleet-server.enabled` | If `true`, create a Fleet Server resource (using the eck-fleet-server Chart) | `false` | +| `eck-logstash.enabled` | If `true`, create a Logstash resource (using the eck-logstash Chart) | `false` | +| `eck-apm-server.enabled` | If `true`, create a standalone Elastic APM Server resource (using the eck-apm-server Chart) | `false` | diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack-0.17.0.tgz b/packs/elastic-stack-0.17.0/charts/eck-stack-0.17.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..4c436ae0ce48dba73ed38a0022bdb7c324b6d778 GIT binary patch literal 44763 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%0D>yvj;tbLzvn+^_ApV;JywBm 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 UwE{v00|SAo*ip*COrXI2AO1dVY5)KL literal 0 HcmV?d00001 diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/.helmignore b/packs/elastic-stack-0.17.0/charts/eck-stack/.helmignore new file mode 100644 index 00000000..9e40bf01 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/.helmignore @@ -0,0 +1,25 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests +charts/*/templates/tests \ No newline at end of file diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/Chart.lock b/packs/elastic-stack-0.17.0/charts/eck-stack/Chart.lock new file mode 100644 index 00000000..3d08499b --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/Chart.lock @@ -0,0 +1,27 @@ +dependencies: +- name: eck-elasticsearch + repository: "" + version: 0.17.0 +- name: eck-kibana + repository: "" + version: 0.17.0 +- name: eck-agent + repository: "" + version: 0.17.0 +- name: eck-fleet-server + repository: "" + version: 0.17.0 +- name: eck-beats + repository: "" + version: 0.17.0 +- name: eck-logstash + repository: "" + version: 0.17.0 +- name: eck-apm-server + repository: "" + version: 0.17.0 +- name: eck-enterprise-search + repository: "" + version: 0.17.0 +digest: sha256:6f4897978c04b920a6e9cfd47848e91ac44231f2ab1d12bd75532c08426ebcff +generated: "2025-10-30T11:49:28.962352222Z" diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/Chart.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/Chart.yaml new file mode 100644 index 00000000..d9b1336b --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/Chart.yaml @@ -0,0 +1,39 @@ +apiVersion: v2 +dependencies: +- condition: eck-elasticsearch.enabled + name: eck-elasticsearch + repository: "" + version: 0.17.0 +- condition: eck-kibana.enabled + name: eck-kibana + repository: "" + version: 0.17.0 +- condition: eck-agent.enabled + name: eck-agent + repository: "" + version: 0.17.0 +- condition: eck-fleet-server.enabled + name: eck-fleet-server + repository: "" + version: 0.17.0 +- condition: eck-beats.enabled + name: eck-beats + repository: "" + version: 0.17.0 +- condition: eck-logstash.enabled + name: eck-logstash + repository: "" + version: 0.17.0 +- condition: eck-apm-server.enabled + name: eck-apm-server + repository: "" + version: 0.17.0 +- condition: eck-enterprise-search.enabled + name: eck-enterprise-search + repository: "" + version: 0.17.0 +description: Elastic Stack managed by the ECK Operator +kubeVersion: '>= 1.21.0-0' +name: eck-stack +type: application +version: 0.17.0 diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/README.md b/packs/elastic-stack-0.17.0/charts/eck-stack/README.md new file mode 100644 index 00000000..f301bd12 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/README.md @@ -0,0 +1,93 @@ +# ECK-Stack + +ECK Stack is a Helm chart to assist in the deployment of Elastic Stack components, which are +managed by the [ECK Operator](https://www.elastic.co/guide/en/cloud-on-k8s/current/index.html) + +## Supported Elastic Stack Resources + +The following Elastic Stack resources are currently supported. + +- Elasticsearch +- Kibana +- Elastic Agent +- Fleet Server +- Beats +- Logstash +- APM Server + +Additional resources will be supported in future releases of this Helm Chart. + +## Prerequisites + +- Kubernetes 1.21+ +- Elastic ECK Operator + +## Installing the Chart + +### Installing the ECK Operator + +Before using this chart, the Elastic ECK Operator is required to be installed within the Kubernetes cluster. +Full installation instructions can be found within [our documentation](https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-installing-eck.html) + +To install the ECK Operator using Helm. + +```sh +# Add the Elastic Helm Repository +helm repo add elastic https://helm.elastic.co && helm repo update + +# Install the ECK Operator cluster-wide +helm install elastic-operator elastic/eck-operator -n elastic-system --create-namespace +``` + +Additional ECK Operator Helm installation options can be found within [our documentation](https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-install-helm.html) + +### Installing the ECK Stack Chart + +The following will install the ECK-Stack chart using the default values, which will deploy an Elasticsearch [Quickstart Cluster](https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-deploy-elasticsearch.html), and a Kibana [Quickstart Instance](https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-deploy-kibana.html) + +```sh +# Add the Elastic Helm Repository +helm repo add elastic https://helm.elastic.co && helm repo update + +# Install the ECK-Stack helm chart +# This will setup a 'quickstart' Elasticsearch and Kibana resource in the 'elastic-stack' namespace +helm install my-release elastic/eck-stack -n elastic-stack --create-namespace +``` + +More information on the different ways to use the ECK Stack chart to deploy Elastic Stack resources +can be found in [our documentation](https://www.elastic.co/guide/en/cloud-on-k8s/current/index.html). + +## Uninstalling the Chart + +To uninstall/delete the `my-release` deployment from the 'elastic-stack' namespace: + +```console +helm delete my-release -n elastic-stack +``` + +The command removes all the Elastic Stack resources associated with the chart and deletes the release. + +## Configuration + +The following table lists the configurable parameters of the eck-stack chart and their default values. + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `eck-elasticsearch.enabled` | If `true`, create an Elasticsearch resource (using the eck-elasticsearch Chart) | `true` | +| `eck-kibana.enabled` | If `true`, create a Kibana resource (using the eck-kibana Chart) | `true` | +| `eck-agent.enabled` | If `true`, create an Elastic Agent resource (using the eck-agent Chart) | `false` | +| `eck-fleet-server.enabled` | If `true`, create a Fleet Server resource (using the eck-fleet-server Chart) | `false` | +| `eck-logstash.enabled` | If `true`, create a Logstash resource (using the eck-logstash Chart) | `false` | +| `eck-apm-server.enabled` | If `true`, create a standalone Elastic APM Server resource (using the eck-apm-server Chart) | `false` | + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. + +Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example, + +```console +helm install my-release -f values.yaml . +``` + +## Contributing + +This chart is maintained at [github.com/elastic/cloud-on-k8s](https://github.com/elastic/cloud-on-k8s/tree/main/deploy/eck-stack). diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/.helmignore b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/.helmignore new file mode 100644 index 00000000..f1568daf --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/Chart.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/Chart.yaml new file mode 100644 index 00000000..f399f1aa --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/Chart.yaml @@ -0,0 +1,10 @@ +apiVersion: v2 +description: Elastic Agent managed by the ECK operator +icon: https://images.contentstack.io/v3/assets/bltefdd0b53724fa2ce/blt77c2da6e0198746e/620ac24e6662ca0a6f617114/icon-agent-32-color.svg +kubeVersion: '>= 1.21.0-0' +name: eck-agent +sources: +- https://github.com/elastic/cloud-on-k8s +- https://github.com/elastic/elastic-agent +type: application +version: 0.17.0 diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/LICENSE b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/LICENSE new file mode 100644 index 00000000..92503a72 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/LICENSE @@ -0,0 +1,93 @@ +Elastic License 2.0 + +URL: https://www.elastic.co/licensing/elastic-license + +## Acceptance + +By using the software, you agree to all of the terms and conditions below. + +## Copyright License + +The licensor grants you a non-exclusive, royalty-free, worldwide, +non-sublicensable, non-transferable license to use, copy, distribute, make +available, and prepare derivative works of the software, in each case subject to +the limitations and conditions below. + +## Limitations + +You may not provide the software to third parties as a hosted or managed +service, where the service provides users with access to any substantial set of +the features or functionality of the software. + +You may not move, change, disable, or circumvent the license key functionality +in the software, and you may not remove or obscure any functionality in the +software that is protected by the license key. + +You may not alter, remove, or obscure any licensing, copyright, or other notices +of the licensor in the software. Any use of the licensor’s trademarks is subject +to applicable law. + +## Patents + +The licensor grants you a license, under any patent claims the licensor can +license, or becomes able to license, to make, have made, use, sell, offer for +sale, import and have imported the software, in each case subject to the +limitations and conditions in this license. This license does not cover any +patent claims that you cause to be infringed by modifications or additions to +the software. If you or your company make any written claim that the software +infringes or contributes to infringement of any patent, your patent license for +the software granted under these terms ends immediately. If your company makes +such a claim, your patent license ends immediately for work on behalf of your +company. + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you +also gets a copy of these terms. + +If you modify the software, you must include in any modified copies of the +software prominent notices stating that you have modified the software. + +## No Other Rights + +These terms do not imply any licenses other than those expressly granted in +these terms. + +## Termination + +If you use the software in violation of these terms, such use is not licensed, +and your licenses will automatically terminate. If the licensor provides you +with a notice of your violation, and you cease all violation of this license no +later than 30 days after you receive that notice, your licenses will be +reinstated retroactively. However, if you violate these terms after such +reinstatement, any additional violation of these terms will cause your licenses +to terminate automatically and permanently. + +## No Liability + +*As far as the law allows, the software comes as is, without any warranty or +condition, and the licensor will not be liable to you for any damages arising +out of these terms or the use or nature of the software, under any kind of +legal claim.* + +## Definitions + +The **licensor** is the entity offering these terms, and the **software** is the +software the licensor makes available under these terms, including any portion +of it. + +**you** refers to the individual or entity agreeing to these terms. + +**your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control over, +are under the control of, or are under common control with that +organization. **control** means ownership of substantially all the assets of an +entity, or the power to direct its management and policies by vote, contract, or +otherwise. Control can be direct or indirect. + +**your licenses** are all the licenses granted to you for the software under +these terms. + +**use** means anything you do with the software requiring one of your licenses. + +**trademark** means trademarks, service marks, and similar rights. \ No newline at end of file diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/examples/fleet-agents.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/examples/fleet-agents.yaml new file mode 100644 index 00000000..b5aebac5 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/examples/fleet-agents.yaml @@ -0,0 +1,24 @@ +# The following example should only be used in conjunction with the 'eck-fleet-server' Helm Chart, +# and shows how the Agents can be deployed as a daemonset, and controlled by Fleet Server. +# +version: 9.2.0 + +# This must match the name of an Agent policy. +policyID: eck-agent +# This must match the name of the fleet server installed from eck-fleet-server chart. +fleetServerRef: + name: eck-fleet-server +kibanaRef: + name: eck-kibana +mode: fleet +# elasticsearchRefs must be empty when fleet mode is enabled. +elasticsearchRefs: [] +daemonSet: + podTemplate: + spec: + serviceAccountName: elastic-agent + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + automountServiceAccountToken: true + securityContext: + runAsUser: 0 diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/examples/system-integration.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/examples/system-integration.yaml new file mode 100644 index 00000000..010e47ca --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/examples/system-integration.yaml @@ -0,0 +1,133 @@ +# The following example should only be used in Agent "standalone" mode, +# and should not be used when Agent is used with Fleet Server. +# +version: 9.2.0 +elasticsearchRefs: +- name: eck-elasticsearch +daemonSet: + podTemplate: + spec: + containers: + - name: agent + securityContext: + runAsUser: 0 + volumeMounts: + - name: agent-data + mountPath: /usr/share/elastic-agent/data/elastic-agent-08e204/run +config: + id: 488e0b80-3634-11eb-8208-57893829af4e + revision: 2 + agent: + monitoring: + enabled: true + use_output: default + logs: true + metrics: true + inputs: + - id: 4917ade0-3634-11eb-8208-57893829af4e + name: system-1 + revision: 1 + type: system/metrics + use_output: default + meta: + package: + name: system + version: 9.2.0 + data_stream: + namespace: default + streams: + - id: system/metrics-system.cpu + data_stream: + dataset: system.cpu + type: metrics + metricsets: + - cpu + cpu.metrics: + - percentages + - normalized_percentages + period: 10s + - id: system/metrics-system.diskio + data_stream: + dataset: system.diskio + type: metrics + metricsets: + - diskio + diskio.include_devices: null + period: 10s + - id: system/metrics-system.filesystem + data_stream: + dataset: system.filesystem + type: metrics + metricsets: + - filesystem + period: 1m + processors: + - drop_event.when.regexp: + system.filesystem.mount_point: ^/(sys|cgroup|proc|dev|etc|host|lib|snap)($|/) + - id: system/metrics-system.fsstat + data_stream: + dataset: system.fsstat + type: metrics + metricsets: + - fsstat + period: 1m + processors: + - drop_event.when.regexp: + system.fsstat.mount_point: ^/(sys|cgroup|proc|dev|etc|host|lib|snap)($|/) + - id: system/metrics-system.load + data_stream: + dataset: system.load + type: metrics + metricsets: + - load + period: 10s + - id: system/metrics-system.memory + data_stream: + dataset: system.memory + type: metrics + metricsets: + - memory + period: 10s + - id: system/metrics-system.network + data_stream: + dataset: system.network + type: metrics + metricsets: + - network + period: 10s + network.interfaces: null + - id: system/metrics-system.process + data_stream: + dataset: system.process + type: metrics + metricsets: + - process + period: 10s + process.include_top_n.by_cpu: 5 + process.include_top_n.by_memory: 5 + process.cmdline.cache.enabled: true + process.cgroups.enabled: false + process.include_cpu_ticks: false + processes: + - .* + - id: system/metrics-system.process_summary + data_stream: + dataset: system.process_summary + type: metrics + metricsets: + - process_summary + period: 10s + - id: system/metrics-system.socket_summary + data_stream: + dataset: system.socket_summary + type: metrics + metricsets: + - socket_summary + period: 10s + - id: system/metrics-system.uptime + data_stream: + dataset: system.uptime + type: metrics + metricsets: + - uptime + period: 10s diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/templates/NOTES.txt b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/templates/NOTES.txt new file mode 100644 index 00000000..cfd41883 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/templates/NOTES.txt @@ -0,0 +1,6 @@ + +1. Check Elastic Agent status + $ kubectl get agent {{ include "elasticagent.fullname" . }} -n {{ .Release.Namespace }} + +2. Check Elastic Agent pod status + $ kubectl get pods --namespace={{ .Release.Namespace }} -l agent.k8s.elastic.co/name={{ include "elasticagent.fullname" . }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/templates/_helpers.tpl b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/templates/_helpers.tpl new file mode 100644 index 00000000..748ca7dd --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "elasticagent.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "elasticagent.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "elasticagent.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "elasticagent.labels" -}} +helm.sh/chart: {{ include "elasticagent.chart" . }} +{{ include "elasticagent.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.labels }} +{{ toYaml .Values.labels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "elasticagent.selectorLabels" -}} +app.kubernetes.io/name: {{ include "elasticagent.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/templates/cluster-role-binding.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/templates/cluster-role-binding.yaml new file mode 100644 index 00000000..762a59dc --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/templates/cluster-role-binding.yaml @@ -0,0 +1,33 @@ +{{- with .Values.clusterRoleBinding }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .name }} + labels: + {{- include "elasticagent.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or $.Values.annotations .annotations }} + annotations: + {{- with $.Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +{{- with .subjects }} +subjects: +{{- range . }} + - kind: {{ .kind }} + name: {{ .name }} + namespace: {{ .namespace | default $.Release.Namespace | quote }} +{{- end }} +{{- end }} +roleRef: + kind: {{ .roleRef.kind }} + name: {{ .roleRef.name }} + apiGroup: {{ .roleRef.apiGroup }} +{{- end }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/templates/cluster-role.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/templates/cluster-role.yaml new file mode 100644 index 00000000..5d97ec7a --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/templates/cluster-role.yaml @@ -0,0 +1,22 @@ +{{- with .Values.clusterRole }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ .name }} + labels: + {{- include "elasticagent.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or $.Values.annotations .annotations }} + annotations: + {{- with $.Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +rules: {{- toYaml .rules | nindent 2 }} +{{- end }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/templates/elastic-agent.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/templates/elastic-agent.yaml new file mode 100644 index 00000000..9017e5bb --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/templates/elastic-agent.yaml @@ -0,0 +1,89 @@ +--- +apiVersion: agent.k8s.elastic.co/v1alpha1 +kind: Agent +metadata: + name: {{ include "elasticagent.fullname" . }} + labels: + {{- include "elasticagent.labels" $ | nindent 4 }} + annotations: + eck.k8s.elastic.co/license: basic + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + version: {{ required "An Elastic Agent version is required" (or ((.Values.spec).version) (.Values.version)) }} + {{- $daemonSet := (or (hasKey (.Values.spec) "daemonSet") (hasKey .Values "daemonSet")) }} + {{- $deployment := (or (hasKey (.Values.spec) "deployment") (hasKey .Values "deployment")) }} + {{- $statefulSet := (or (hasKey (.Values.spec) "statefulSet") (hasKey .Values "statefulSet")) }} + {{- if and (not $daemonSet) (not $deployment) (not $statefulSet) }} + {{ fail "At least one of daemonSet, deployment or statefulSet is required" }} + {{- end }} + {{- if $daemonSet }} + {{- $ds := or ((.Values.spec).daemonSet) (.Values.daemonSet) }} + daemonSet: + {{- /* This is required to render the empty daemonset ( {} ) properly */}} + {{- $ds | default dict | toYaml | nindent 4 }} + {{- end }} + {{- if $deployment }} + {{- $deploy := or ((.Values.spec).deployment) (.Values.deployment) }} + deployment: + {{- /* This is required to render the empty deployment ( {} ) properly */}} + {{- $deploy | default dict | toYaml | nindent 4 }} + {{- end }} + {{- if $statefulSet }} + {{- $sts := or ((.Values.spec).statefulSet) (.Values.statefulSet) }} + statefulSet: + {{- /* This is required to render the empty statefulSet ( {} ) properly */}} + {{- $sts | default dict | toYaml | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).image) (.Values.image) }} + image: {{ . }} + {{- end }} + {{- with or ((.Values.spec).elasticsearchRefs) (.Values.elasticsearchRefs) }} + elasticsearchRefs: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).kibanaRef) (.Values.kibanaRef) }} + kibanaRef: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).fleetServerRef) (.Values.fleetServerRef) }} + fleetServerRef: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- $config := or ((.Values.spec).config) (.Values.config) }} + {{- $configRef := or ((.Values.spec).configRef) (.Values.configRef) }} + {{- if and $config $configRef }} + {{ fail "Only one of config and configRef can be specified" }} + {{- end }} + {{- with $config }} + config: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $configRef }} + configRef: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).mode) (.Values.mode) }} + mode: {{ . }} + {{- end }} + {{- with or ((.Values.spec).fleetServerEnabled) (.Values.fleetServerEnabled) }} + fleetServerEnabled: {{ . }} + {{- end }} + {{- with or ((.Values.spec).http) (.Values.http) }} + http: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).policyID) (.Values.policyID) }} + policyID: {{ . }} + {{- end }} + {{- with or ((.Values.spec).secureSettings) (.Values.secureSettings) }} + secureSettings: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).revisionHistoryLimit) (.Values.revisionHistoryLimit) }} + revisionHistoryLimit: {{ . }} + {{- end }} + {{- with or (((.Values.spec).serviceAccount).name) ((.Values.serviceAccount).name) }} + serviceAccountName: {{ . }} + {{- end }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/templates/service-account.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/templates/service-account.yaml new file mode 100644 index 00000000..e8bdf0b5 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/templates/service-account.yaml @@ -0,0 +1,22 @@ +{{- with .Values.serviceAccount }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .name }} + namespace: {{ .namespace | default $.Release.Namespace | quote }} + labels: + {{- include "elasticagent.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or $.Values.annotations .annotations }} + annotations: + {{- with $.Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/values.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/values.yaml new file mode 100644 index 00000000..fa62f87c --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-agent/values.yaml @@ -0,0 +1,257 @@ +--- +# Default values for eck-agent. +# This is a YAML-formatted file. + +# Overridable names of the Elastic Agent resource. +# By default, this is the Release name set for the chart, +# followed by 'eck-agent'. +# +# nameOverride will override the name of the Chart with the name set here, +# so nameOverride: quickstart, would convert to '{{ Release.name }}-quickstart' +# +# nameOverride: "quickstart" +# +# fullnameOverride will override both the release name, and the chart name, +# and will name the Fleet Agent resource exactly as specified. +# +# fullnameOverride: "quickstart" + +# Version of Elastic Agent. +# +version: 9.2.0 + +# Labels that will be applied to Elastic Agent. +# +labels: {} + +# Annotations that will be applied to Elastic Agent. +# +annotations: {} + +# Elastic Agent image to deploy. +# +# image: docker.elastic.co/beats/elastic-agent:9.2.0 + +# ** Deprecation Notice ** +# The previous versions of this Helm Chart simply used the `spec` field here +# and allowed the user to specify any fields below `spec` that were templated directly +# into the final Kibana manifest. This is no longer the preferred way to specify these +# fields and each field that is supported underneath `spec` is now directly specified +# in this values file. Currently both patterns are supported for backwards compatibility +# but we plan to remove the `spec` field in the future. +# spec: {} + +# Referenced resources are below and depending on the setup, at least one is required for a functional Agent. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-setting-referenced-resources +# +# Reference to ECK-managed Kibana instance. +# +# kibanaRef: +# name: quickstart + # Optional namespace reference to Kibana instance. + # If not specified, then the namespace of the Agent instance + # will be assumed. + # + # namespace: default + +# Reference to ECK-managed Elasticsearch instance. +# +elasticsearchRefs: +- name: eck-elasticsearch + # Optional namespace reference to Elasticsearch instance. + # If not specified, then the namespace of the Agent instance + # will be assumed. + # + # namespace: default + # + # Optional secretName referencing an existing Kubernetes secret that contains connection information + # for associating an Agent instance to a remote Elasticsearch instance not managed by ECK. + # The referenced secret must contain the following: + # - `url`: the URL to reach the Elastic resource + # - `username`: the username of the user to be authenticated to the Elastic resource + # - `password`: the password of the user to be authenticated to the Elastic resource + # - `ca.crt`: the CA certificate in PEM format (optional) + # - `api-key`: the key to authenticate against the Elastic resource instead of a username and password + # This field cannot be used in combination with the other fields name, namespace or serviceName. + # + # secretName: my-remote-es-credentials + +# Reference to ECK-managed Fleet Server instance. +# +# fleetServerRef: +# name: eck-fleet-server + # Optional namespace reference to Fleet Server instance. + # If not specified, then the namespace of the Agent instance + # will be assumed. + # + # namespace: default + +# The Elastic Agent configuration, the ECK equivalent to agent.yml +# NOTE: The `config` and `configRef` fields are mutually exclusive. Only one of them should be defined at a time, +# as using both may cause conflicts. +# +# Configuration of Agent, specifically used in Agent standalone mode. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-configuration.html +# +config: null + +# Reference a configuration in a Secret. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-configuration.html +# +# configRef: +# secretName: "" + +# The mode of Agent to use. Only set to "fleet" when Fleet Server is enabled. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-fleet-mode-and-fleet-server +# +# mode: "fleet" + +# fleetServerEnabled determines whether the Agent will be run as the Fleet Server. +# +# NOTE: Both `mode: fleet` and `fleetServerEnabled: true` need to be set for Fleet Server to be enabled. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-fleet-mode-and-fleet-server +# +fleetServerEnabled: false + +# The HTTP layer configuration for the Fleet Server Service. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-customize-fleet-server-service +# +# http: + +# policyID determines into which Agent Policy this Agent will be enrolled. +# policyID: eck-agent + +# DaemonSet, StatefulSet, or Deployment specification for Agent. +# At least one is required of [daemonSet, deployment, statefulSet]. +# No default is currently set, refer to https://github.com/elastic/cloud-on-k8s/issues/7429. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-chose-the-deployment-model +# +# deployment: +# podTemplate: +# spec: +# containers: +# - name: agent +# securityContext: +# runAsUser: 0 +# daemonSet: +# podTemplate: +# spec: +# containers: +# - name: agent +# securityContext: +# runAsUser: 0 +# statefulSet: +# podTemplate: +# spec: +# containers: +# - name: agent +# securityContext: +# runAsUser: 0 + +# SecureSettings is a list of references to Kubernetes Secrets containing sensitive configuration options for Elastic Agent. +secureSettings: [] +# - secretName: my-secret-with-secure-settings + +# Number of revisions to retain to allow rollback in the underlying Deployment. +# If not set Kubernetes sets this to 10 by default. +# +# revisionHistoryLimit: 2 + +# ServiceAccount to be used by Elastic Agent. Some Elastic Agent features, such as the Kubernetes integration, +# require that Agent Pods interact with Kubernetes APIs. This functionality requires specific permissions +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-role-based-access-control +# +serviceAccount: + name: elastic-agent + # { .Release.Namespace } is used here by default, but can be specified. + # namespace: optional-namespace + +# ClusterRoleBinding to be used by Elastic Agent. Similar to ServiceAccount, this is required in some scenarios. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-role-based-access-control +# +clusterRoleBinding: + name: elastic-agent + subjects: + - kind: ServiceAccount + name: elastic-agent + # { .Release.Namespace } is used here by default, but can be specified. + # namespace: default + roleRef: + kind: ClusterRole + name: elastic-agent + apiGroup: rbac.authorization.k8s.io + +# ClusterRole to be used by Elastic Agent. Similar to ServiceAccount, this is required in some scenarios. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-role-based-access-control +# +clusterRole: + name: elastic-agent + rules: + - apiGroups: [""] + resources: + - pods + - nodes + - namespaces + - events + - services + - configmaps + verbs: + - get + - watch + - list + - apiGroups: ["coordination.k8s.io"] + resources: + - leases + verbs: + - get + - create + - update + - nonResourceURLs: + - "/metrics" + verbs: + - get + - apiGroups: ["extensions"] + resources: + - replicasets + verbs: + - "get" + - "list" + - "watch" + - apiGroups: + - "apps" + resources: + - statefulsets + - deployments + - replicasets + - daemonsets + verbs: + - "get" + - "list" + - "watch" + - apiGroups: + - "" + resources: + - nodes/stats + verbs: + - get + - nonResourceURLs: + - "/metrics" + verbs: + - get + - apiGroups: + - "batch" + resources: + - jobs + - cronjobs + verbs: + - "get" + - "list" + - "watch" + - apiGroups: + - "storage.k8s.io" + resources: + - storageclasses + verbs: + - "get" + - "list" + - "watch" diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/.helmignore b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/.helmignore new file mode 100644 index 00000000..f1568daf --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/Chart.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/Chart.yaml new file mode 100644 index 00000000..d3d457a1 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/Chart.yaml @@ -0,0 +1,10 @@ +apiVersion: v2 +description: Elastic APM Server managed by the ECK operator +icon: https://helm.elastic.co/icons/apm.png +kubeVersion: '>= 1.21.0-0' +name: eck-apm-server +sources: +- https://github.com/elastic/cloud-on-k8s +- https://github.com/elastic/apm-server +type: application +version: 0.17.0 diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/LICENSE b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/LICENSE new file mode 100644 index 00000000..92503a72 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/LICENSE @@ -0,0 +1,93 @@ +Elastic License 2.0 + +URL: https://www.elastic.co/licensing/elastic-license + +## Acceptance + +By using the software, you agree to all of the terms and conditions below. + +## Copyright License + +The licensor grants you a non-exclusive, royalty-free, worldwide, +non-sublicensable, non-transferable license to use, copy, distribute, make +available, and prepare derivative works of the software, in each case subject to +the limitations and conditions below. + +## Limitations + +You may not provide the software to third parties as a hosted or managed +service, where the service provides users with access to any substantial set of +the features or functionality of the software. + +You may not move, change, disable, or circumvent the license key functionality +in the software, and you may not remove or obscure any functionality in the +software that is protected by the license key. + +You may not alter, remove, or obscure any licensing, copyright, or other notices +of the licensor in the software. Any use of the licensor’s trademarks is subject +to applicable law. + +## Patents + +The licensor grants you a license, under any patent claims the licensor can +license, or becomes able to license, to make, have made, use, sell, offer for +sale, import and have imported the software, in each case subject to the +limitations and conditions in this license. This license does not cover any +patent claims that you cause to be infringed by modifications or additions to +the software. If you or your company make any written claim that the software +infringes or contributes to infringement of any patent, your patent license for +the software granted under these terms ends immediately. If your company makes +such a claim, your patent license ends immediately for work on behalf of your +company. + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you +also gets a copy of these terms. + +If you modify the software, you must include in any modified copies of the +software prominent notices stating that you have modified the software. + +## No Other Rights + +These terms do not imply any licenses other than those expressly granted in +these terms. + +## Termination + +If you use the software in violation of these terms, such use is not licensed, +and your licenses will automatically terminate. If the licensor provides you +with a notice of your violation, and you cease all violation of this license no +later than 30 days after you receive that notice, your licenses will be +reinstated retroactively. However, if you violate these terms after such +reinstatement, any additional violation of these terms will cause your licenses +to terminate automatically and permanently. + +## No Liability + +*As far as the law allows, the software comes as is, without any warranty or +condition, and the licensor will not be liable to you for any damages arising +out of these terms or the use or nature of the software, under any kind of +legal claim.* + +## Definitions + +The **licensor** is the entity offering these terms, and the **software** is the +software the licensor makes available under these terms, including any portion +of it. + +**you** refers to the individual or entity agreeing to these terms. + +**your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control over, +are under the control of, or are under common control with that +organization. **control** means ownership of substantially all the assets of an +entity, or the power to direct its management and policies by vote, contract, or +otherwise. Control can be direct or indirect. + +**your licenses** are all the licenses granted to you for the software under +these terms. + +**use** means anything you do with the software requiring one of your licenses. + +**trademark** means trademarks, service marks, and similar rights. \ No newline at end of file diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/examples/jaeger-with-http-configuration.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/examples/jaeger-with-http-configuration.yaml new file mode 100644 index 00000000..133eb751 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/examples/jaeger-with-http-configuration.yaml @@ -0,0 +1,29 @@ +--- +# Version of APM Server. +# +version: 9.2.0 + +# Count of APM Server replicas to create. +# +count: 1 + +config: + name: elastic-apm + apm-server.jaeger.grpc.enabled: true + apm-server.jaeger.grpc.host: "0.0.0.0:14250" + +# Reference to ECK-managed Elasticsearch resource. +# +elasticsearchRef: + name: eck-elasticsearch +http: + service: + spec: + ports: + - name: http + port: 8200 + targetPort: 8200 + - name: grpc + port: 14250 + targetPort: 14250 + diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/templates/NOTES.txt b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/templates/NOTES.txt new file mode 100644 index 00000000..42ab52cb --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/templates/NOTES.txt @@ -0,0 +1,6 @@ + +1. Check APM Server status + $ kubectl get apmserver {{ include "apm-server.fullname" . }} -n {{ .Release.Namespace }} + +2. Check APM Server pod status + $ kubectl get pods --namespace={{ .Release.Namespace }} -l apm.k8s.elastic.co/name={{ include "apm-server.fullname" . }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/templates/_helpers.tpl b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/templates/_helpers.tpl new file mode 100644 index 00000000..d06ca3f4 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "apm-server.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "apm-server.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "apm-server.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "apm-server.labels" -}} +helm.sh/chart: {{ include "apm-server.chart" . }} +{{ include "apm-server.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.labels }} +{{ toYaml .Values.labels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "apm-server.selectorLabels" -}} +app.kubernetes.io/name: {{ include "apm-server.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/templates/apmserver.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/templates/apmserver.yaml new file mode 100644 index 00000000..f3dd5ba9 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/templates/apmserver.yaml @@ -0,0 +1,53 @@ +--- +apiVersion: apm.k8s.elastic.co/v1 +kind: ApmServer +metadata: + name: {{ include "apm-server.fullname" . }} + labels: + {{- include "apm-server.labels" . | nindent 4 }} + annotations: + eck.k8s.elastic.co/license: basic + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + version: {{ required "An APM Server version is required" .Values.version }} + count: {{ required "A pod count is required" .Values.count }} + {{- with .Values.image }} + image: {{ . }} + {{- end }} + {{- with .Values.serviceAccountName }} + serviceAccountName: {{ . }} + {{- end }} + {{- with .Values.revisionHistoryLimit }} + revisionHistoryLimit: {{ . }} + {{- end }} + + {{- with .Values.config }} + config: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.http }} + http: + {{- toYaml . | nindent 4 }} + {{- end }} + + {{- with .Values.elasticsearchRef }} + elasticsearchRef: + {{- toYaml . | nindent 4 }} + {{- end }} + + {{- with .Values.kibanaRef }} + kibanaRef: + {{- toYaml . | nindent 4 }} + {{- end }} + + {{- with .Values.podTemplate }} + podTemplate: + {{- toYaml . | nindent 4 }} + {{- end }} + + {{- with .Values.secureSettings }} + secureSettings: + {{- toYaml . | nindent 2 }} + {{- end }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/values.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/values.yaml new file mode 100644 index 00000000..0c4c9708 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-apm-server/values.yaml @@ -0,0 +1,108 @@ +--- +# Default values for eck-apm-server. +# This is a YAML-formatted file. + +# Overridable names of the APM Server resource. +# By default, this is the Release name set for the chart, +# followed by 'eck-apm-server'. +# +# nameOverride will override the name of the Chart with the name set here, +# so nameOverride: quickstart, would convert to '{{ Release.name }}-quickstart' +# +# nameOverride: "quickstart" +# +# fullnameOverride will override both the release name, and the chart name, +# and will name the APM Server resource exactly as specified. +# +# fullnameOverride: "quickstart" + +# Version of APM Server. +# +version: 9.2.0 + +# APM Server Docker image to deploy +# +# image: + +# Used to check access from the current resource to a resource (for ex. a remote Elasticsearch cluster) in a different namespace. +# Can only be used if ECK is enforcing RBAC on references. +# +# serviceAccountName: "" + +# Labels that will be applied to APM Server. +# +labels: {} + +# Annotations that will be applied to APM Server. +# +annotations: {} + +# Count of APM Server replicas to create. +# +count: 1 + +# The APM Server configuration, the ECK equivalent to apm-server.yml +# ref: https://www.elastic.co/guide/en/apm/server/current/configuring-howto-apm-server.html +# +config: {} + +# Settings to control how APM Server will be accessed. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-accessing-elastic-services.html +# +http: {} + # service: + # metadata: + # labels: + # my-custom: label + # spec: + # ports: + # - name: http + # port: 8200 + # targetPort: 8200 + +# Reference to ECK-managed Elasticsearch resource. +# +elasticsearchRef: {} + # name: eck-elasticsearch + # Optional namespace reference to Elasticsearch resource. + # If not specified, then the namespace of the APM Server resource + # will be assumed. + # + # namespace: default + # + # Optional secretName referencing an existing Kubernetes secret that contains connection information + # for associating an APM Server instance to a remote Elasticsearch instance not managed by ECK. + # The referenced secret must contain the following: + # - `url`: the URL to reach the Elastic resource + # - `username`: the username of the user to be authenticated to the Elastic resource + # - `password`: the password of the user to be authenticated to the Elastic resource + # - `ca.crt`: the CA certificate in PEM format (optional) + # This field cannot be used in combination with the other fields name, namespace or serviceName. + # + # secretName: my-remote-es-credentials + +# Optional reference to ECK-managed Kibana resource which allows ECK to +# automatically configure the Kibana endpoint as described in +# https://www.elastic.co/guide/en/apm/server/current/setup-kibana-endpoint.html +# +# kibanaRef: +# name: eck-kibana +# # Optional namespace reference to Kibana resource. +# # If not specified, then the namespace of the APM Server resource +# # will be assumed. +# # +# # namespace: default + +# Set podTemplate to customize the pod used by APM Server +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-customize-pods.html +# +podTemplate: {} + +# Number of revisions to retain to allow rollback in the underlying Deployment. +# If not set Kubernetes sets this to 10 by default. +# +# revisionHistoryLimit: 2 + +# SecureSettings is a list of references to Kubernetes Secrets containing sensitive configuration options for APM Server. +secureSettings: [] +# - secretName: my-secret-with-secure-settings diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/.helmignore b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/.helmignore new file mode 100644 index 00000000..f1568daf --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/Chart.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/Chart.yaml new file mode 100644 index 00000000..7a23d60d --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/Chart.yaml @@ -0,0 +1,10 @@ +apiVersion: v2 +description: Elastic Beats managed by the ECK operator +icon: https://helm.elastic.co/icons/beats.png +kubeVersion: '>= 1.20.0-0' +name: eck-beats +sources: +- https://github.com/elastic/cloud-on-k8s +- https://github.com/elastic/beats +type: application +version: 0.17.0 diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/LICENSE b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/LICENSE new file mode 100644 index 00000000..92503a72 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/LICENSE @@ -0,0 +1,93 @@ +Elastic License 2.0 + +URL: https://www.elastic.co/licensing/elastic-license + +## Acceptance + +By using the software, you agree to all of the terms and conditions below. + +## Copyright License + +The licensor grants you a non-exclusive, royalty-free, worldwide, +non-sublicensable, non-transferable license to use, copy, distribute, make +available, and prepare derivative works of the software, in each case subject to +the limitations and conditions below. + +## Limitations + +You may not provide the software to third parties as a hosted or managed +service, where the service provides users with access to any substantial set of +the features or functionality of the software. + +You may not move, change, disable, or circumvent the license key functionality +in the software, and you may not remove or obscure any functionality in the +software that is protected by the license key. + +You may not alter, remove, or obscure any licensing, copyright, or other notices +of the licensor in the software. Any use of the licensor’s trademarks is subject +to applicable law. + +## Patents + +The licensor grants you a license, under any patent claims the licensor can +license, or becomes able to license, to make, have made, use, sell, offer for +sale, import and have imported the software, in each case subject to the +limitations and conditions in this license. This license does not cover any +patent claims that you cause to be infringed by modifications or additions to +the software. If you or your company make any written claim that the software +infringes or contributes to infringement of any patent, your patent license for +the software granted under these terms ends immediately. If your company makes +such a claim, your patent license ends immediately for work on behalf of your +company. + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you +also gets a copy of these terms. + +If you modify the software, you must include in any modified copies of the +software prominent notices stating that you have modified the software. + +## No Other Rights + +These terms do not imply any licenses other than those expressly granted in +these terms. + +## Termination + +If you use the software in violation of these terms, such use is not licensed, +and your licenses will automatically terminate. If the licensor provides you +with a notice of your violation, and you cease all violation of this license no +later than 30 days after you receive that notice, your licenses will be +reinstated retroactively. However, if you violate these terms after such +reinstatement, any additional violation of these terms will cause your licenses +to terminate automatically and permanently. + +## No Liability + +*As far as the law allows, the software comes as is, without any warranty or +condition, and the licensor will not be liable to you for any damages arising +out of these terms or the use or nature of the software, under any kind of +legal claim.* + +## Definitions + +The **licensor** is the entity offering these terms, and the **software** is the +software the licensor makes available under these terms, including any portion +of it. + +**you** refers to the individual or entity agreeing to these terms. + +**your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control over, +are under the control of, or are under common control with that +organization. **control** means ownership of substantially all the assets of an +entity, or the power to direct its management and policies by vote, contract, or +otherwise. Control can be direct or indirect. + +**your licenses** are all the licenses granted to you for the software under +these terms. + +**use** means anything you do with the software requiring one of your licenses. + +**trademark** means trademarks, service marks, and similar rights. \ No newline at end of file diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/examples/auditbeat_hosts.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/examples/auditbeat_hosts.yaml new file mode 100644 index 00000000..806669ac --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/examples/auditbeat_hosts.yaml @@ -0,0 +1,110 @@ +name: auditbeat +version: 9.2.0 +type: auditbeat +elasticsearchRef: + name: eck-elasticsearch +kibanaRef: + name: eck-kibana +config: + auditbeat.modules: + - module: file_integrity + paths: + - /hostfs/bin + - /hostfs/usr/bin + - /hostfs/sbin + - /hostfs/usr/sbin + - /hostfs/etc + exclude_files: + - '(?i)\.sw[nop]$' + - '~$' + - '/\.git($|/)' + scan_at_start: true + scan_rate_per_sec: 50 MiB + max_file_size: 100 MiB + hash_types: [sha1] + recursive: true + - module: auditd + audit_rules: | + # Executions + -a always,exit -F arch=b64 -S execve,execveat -k exec + + # Unauthorized access attempts (amd64 only) + -a always,exit -F arch=b64 -S open,creat,truncate,ftruncate,openat,open_by_handle_at -F exit=-EACCES -k access + -a always,exit -F arch=b64 -S open,creat,truncate,ftruncate,openat,open_by_handle_at -F exit=-EPERM -k access + + processors: + - add_cloud_metadata: {} + - add_host_metadata: {} + - add_process_metadata: + match_pids: ['process.pid'] +daemonSet: + podTemplate: + spec: + hostPID: true # Required by auditd module + dnsPolicy: ClusterFirstWithHostNet + hostNetwork: true # Allows to provide richer host metadata + automountServiceAccountToken: true # some older Beat versions are depending on this settings presence in k8s context + securityContext: + runAsUser: 0 + volumes: + - name: bin + hostPath: + path: /bin + - name: usrbin + hostPath: + path: /usr/bin + - name: sbin + hostPath: + path: /sbin + - name: usrsbin + hostPath: + path: /usr/sbin + - name: etc + hostPath: + path: /etc + - name: run-containerd + hostPath: + path: /run/containerd + type: DirectoryOrCreate + # Uncomment the below when running on GKE. See https://github.com/elastic/beats/issues/8523 for more context. + #- name: run + # hostPath: + # path: /run + #initContainers: + #- name: cos-init + # image: docker.elastic.co/beats/auditbeat:8.3.3 + # volumeMounts: + # - name: run + # mountPath: /run + # command: ['sh', '-c', 'export SYSTEMD_IGNORE_CHROOT=1 && systemctl stop systemd-journald-audit.socket && systemctl mask systemd-journald-audit.socket && systemctl restart systemd-journald'] + containers: + - name: auditbeat + securityContext: + capabilities: + add: + # Capabilities needed for auditd module + - 'AUDIT_READ' + - 'AUDIT_WRITE' + - 'AUDIT_CONTROL' + volumeMounts: + - name: bin + mountPath: /hostfs/bin + readOnly: true + - name: sbin + mountPath: /hostfs/sbin + readOnly: true + - name: usrbin + mountPath: /hostfs/usr/bin + readOnly: true + - name: usrsbin + mountPath: /hostfs/usr/sbin + readOnly: true + - name: etc + mountPath: /hostfs/etc + readOnly: true + # Directory with root filesystems of containers executed with containerd, this can be + # different with other runtimes. This volume is needed to monitor the file integrity + # of files in containers. + - name: run-containerd + mountPath: /run/containerd + readOnly: true diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/examples/filebeat_no_autodiscover.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/examples/filebeat_no_autodiscover.yaml new file mode 100644 index 00000000..6229fc5a --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/examples/filebeat_no_autodiscover.yaml @@ -0,0 +1,52 @@ +name: filebeat +version: 9.2.0 +type: filebeat +elasticsearchRef: + name: eck-elasticsearch +kibanaRef: + name: eck-kibana +config: + filebeat.inputs: + - type: filestream + paths: + - /var/log/containers/*.log + parsers: + - container: ~ + prospector: + scanner: + fingerprint.enabled: true + symlinks: true + file_identity.fingerprint: ~ + processors: + - add_host_metadata: {} + - add_cloud_metadata: {} +daemonSet: + podTemplate: + spec: + automountServiceAccountToken: true + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirstWithHostNet + hostNetwork: true # Allows to provide richer host metadata + containers: + - name: filebeat + securityContext: + runAsUser: 0 + # If using Red Hat OpenShift uncomment this: + #privileged: true + volumeMounts: + - name: varlogcontainers + mountPath: /var/log/containers + - name: varlogpods + mountPath: /var/log/pods + - name: varlibdockercontainers + mountPath: /var/lib/docker/containers + volumes: + - name: varlogcontainers + hostPath: + path: /var/log/containers + - name: varlogpods + hostPath: + path: /var/log/pods + - name: varlibdockercontainers + hostPath: + path: /var/lib/docker/containers diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/examples/heartbeat_es_kb_health.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/examples/heartbeat_es_kb_health.yaml new file mode 100644 index 00000000..4bb85504 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/examples/heartbeat_es_kb_health.yaml @@ -0,0 +1,23 @@ +name: heartbeat +version: 9.2.0 +type: heartbeat +elasticsearchRef: + name: eck-elasticsearch +config: + heartbeat.monitors: + - type: tcp + schedule: '@every 5s' + # This should directly match the name of the Elasticsearch instance + # with "-es-http" appended to the name. + hosts: ["elasticsearch-es-http.default.svc:9200"] + - type: tcp + schedule: '@every 5s' + # This should directly match the names of the Kibana instance + # with "-kb-http" appended to the name. + hosts: ["eck-kibana-kb-http.default.svc:5601"] +deployment: + replicas: 1 + podTemplate: + spec: + securityContext: + runAsUser: 0 diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/examples/metricbeat_hosts.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/examples/metricbeat_hosts.yaml new file mode 100644 index 00000000..0ba57ec6 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/examples/metricbeat_hosts.yaml @@ -0,0 +1,158 @@ +name: metricbeat +type: metricbeat +version: 9.2.0 +elasticsearchRef: + name: eck-elasticsearch +kibanaRef: + name: eck-kibana +config: + metricbeat: + autodiscover: + providers: + - hints: + default_config: {} + enabled: "true" + node: ${NODE_NAME} + type: kubernetes + modules: + - module: system + period: 10s + metricsets: + - cpu + - load + - memory + - network + - process + - process_summary + process: + include_top_n: + by_cpu: 5 + by_memory: 5 + processes: + - .* + - module: system + period: 1m + metricsets: + - filesystem + - fsstat + processors: + - drop_event: + when: + regexp: + system: + filesystem: + mount_point: ^/(sys|cgroup|proc|dev|etc|host|lib)($|/) + - module: kubernetes + period: 10s + node: ${NODE_NAME} + hosts: + - https://${NODE_NAME}:10250 + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + ssl: + verification_mode: none + metricsets: + - node + - system + - pod + - container + - volume + processors: + - add_cloud_metadata: {} + - add_host_metadata: {} +daemonSet: + podTemplate: + spec: + serviceAccountName: metricbeat + automountServiceAccountToken: true # some older Beat versions are depending on this settings presence in k8s context + containers: + - args: + - -e + - -c + - /etc/beat.yml + - --system.hostfs=/hostfs + name: metricbeat + volumeMounts: + - mountPath: /hostfs/sys/fs/cgroup + name: cgroup + - mountPath: /var/run/docker.sock + name: dockersock + - mountPath: /hostfs/proc + name: proc + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + dnsPolicy: ClusterFirstWithHostNet + hostNetwork: true # Allows to provide richer host metadata + securityContext: + runAsUser: 0 + terminationGracePeriodSeconds: 30 + volumes: + - hostPath: + path: /sys/fs/cgroup + name: cgroup + - hostPath: + path: /var/run/docker.sock + name: dockersock + - hostPath: + path: /proc + name: proc + +clusterRole: + # permissions needed for metricbeat + # source: https://www.elastic.co/guide/en/beats/metricbeat/current/metricbeat-module-kubernetes.html + name: metricbeat + rules: + - apiGroups: + - "" + resources: + - nodes + - namespaces + - events + - pods + verbs: + - get + - list + - watch + - apiGroups: + - "extensions" + resources: + - replicasets + verbs: + - get + - list + - watch + - apiGroups: + - apps + resources: + - statefulsets + - deployments + - replicasets + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - nodes/stats + verbs: + - get + - nonResourceURLs: + - /metrics + verbs: + - get + +serviceAccount: + name: metricbeat + +clusterRoleBinding: + name: metricbeat + subjects: + - kind: ServiceAccount + name: metricbeat + roleRef: + kind: ClusterRole + name: metricbeat + apiGroup: rbac.authorization.k8s.io diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/examples/packetbeat_dns_http.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/examples/packetbeat_dns_http.yaml new file mode 100644 index 00000000..cae3e07f --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/examples/packetbeat_dns_http.yaml @@ -0,0 +1,37 @@ +name: packetbeat +type: packetbeat +version: 9.2.0 +elasticsearchRef: + name: eck-elasticsearch +kibanaRef: + name: eck-kibana +config: + packetbeat.interfaces.device: any + packetbeat.protocols: + - type: dns + ports: [53] + include_authorities: true + include_additionals: true + - type: http + ports: [80, 8000, 8080, 9200] + packetbeat.flows: + timeout: 30s + period: 10s + processors: + - add_cloud_metadata: {} + - add_host_metadata: {} +daemonSet: + podTemplate: + spec: + terminationGracePeriodSeconds: 30 + hostNetwork: true + automountServiceAccountToken: true # some older Beat versions are depending on this settings presence in k8s context + dnsPolicy: ClusterFirstWithHostNet + containers: + - name: packetbeat + securityContext: + runAsUser: 0 + capabilities: + add: + - NET_ADMIN + volumes: [] diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/templates/NOTES.txt b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/templates/NOTES.txt new file mode 100644 index 00000000..10d2dac5 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/templates/NOTES.txt @@ -0,0 +1,6 @@ + +1. Check Beat status + $ kubectl get beat {{ include "beat.fullname" . }} -n {{ .Release.Namespace }} + +2. Check Beat pod status + $ kubectl get pods --namespace={{ .Release.Namespace }} -l beat.k8s.elastic.co/name={{ include "beat.fullname" . }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/templates/_helpers.tpl b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/templates/_helpers.tpl new file mode 100644 index 00000000..5e20af14 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "beat.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "beat.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "beat.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "beat.labels" -}} +helm.sh/chart: {{ include "beat.chart" . }} +{{ include "beat.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.labels }} +{{ toYaml .Values.labels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "beat.selectorLabels" -}} +app.kubernetes.io/name: {{ include "beat.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/templates/beats.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/templates/beats.yaml new file mode 100644 index 00000000..a70ac9a6 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/templates/beats.yaml @@ -0,0 +1,75 @@ +--- +apiVersion: beat.k8s.elastic.co/v1beta1 +kind: Beat +metadata: + name: {{ include "beat.fullname" . }} + labels: + {{- include "beat.labels" . | nindent 4 }} + annotations: + eck.k8s.elastic.co/license: basic + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + version: {{ required "A Beat version is required" (or ((.Values.spec).version) (.Values.version)) }} + {{- $daemonSet := (or (hasKey (.Values.spec) "daemonSet") (hasKey .Values "daemonSet")) }} + {{- $deployment := (or (hasKey (.Values.spec) "deployment") (hasKey .Values "deployment")) }} + {{- if and (not $daemonSet) (not $deployment) }} + {{ fail "At least one of daemonSet or deployment is required for a functional Beat" }} + {{- end }} + {{- if not (or ((.Values.spec).type) (.Values.type)) }}{{ fail "A Beat type is required" }}{{- end }} + type: {{ or ((.Values.spec).type) (.Values.type) }} + {{- if $daemonSet }} + {{- $ds := or ((.Values.spec).daemonSet) (.Values.daemonSet) }} + daemonSet: + {{- /* This is required to render the empty daemonset ( {} ) properly */}} + {{- $ds | default dict | toYaml | nindent 4 }} + {{- end }} + {{- if $deployment }} + {{- $deploy := or ((.Values.spec).deployment) (.Values.deployment) }} + deployment: + {{- /* This is required to render the empty deployment ( {} ) properly */}} + {{- $deploy | default dict | toYaml | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).image) (.Values.image) }} + image: {{ . }} + {{- end }} + {{- with or ((.Values.spec).elasticsearchRef) (.Values.elasticsearchRef) }} + elasticsearchRef: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).kibanaRef) (.Values.kibanaRef) }} + kibanaRef: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- $config := or ((.Values.spec).config) (.Values.config) }} + {{- $configRef := or ((.Values.spec).configRef) (.Values.configRef) }} + {{- if and $config $configRef }} + {{ fail "Only one of config and configRef can be specified" }} + {{- end }} + {{- with $config }} + config: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $configRef }} + configRef: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).http) (.Values.http) }} + http: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).monitoring) (.Values.monitoring) }} + monitoring: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).secureSettings) (.Values.secureSettings) }} + secureSettings: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).revisionHistoryLimit) (.Values.revisionHistoryLimit) }} + revisionHistoryLimit: {{ . }} + {{- end }} + {{- with or (((.Values.spec).serviceAccount).name) ((.Values.serviceAccount).name) }} + serviceAccountName: {{ . }} + {{- end }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/templates/cluster-role-binding.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/templates/cluster-role-binding.yaml new file mode 100644 index 00000000..d8fca15f --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/templates/cluster-role-binding.yaml @@ -0,0 +1,35 @@ +{{- with .Values.clusterRoleBinding }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .name }} + labels: + {{- include "beat.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or $.Values.annotations .annotations }} + annotations: + {{- with $.Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +{{- with .subjects }} +subjects: +{{- range . }} + - kind: {{ .kind }} + name: {{ .name }} + namespace: {{ .namespace | default $.Release.Namespace | quote }} +{{- end }} +{{- end }} +{{- with .roleRef }} +roleRef: + kind: {{ .kind }} + name: {{ .name }} + apiGroup: {{ .apiGroup }} +{{- end }} +{{- end }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/templates/cluster-role.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/templates/cluster-role.yaml new file mode 100644 index 00000000..66406f63 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/templates/cluster-role.yaml @@ -0,0 +1,22 @@ +{{- with .Values.clusterRole }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ .name }} + labels: + {{- include "beat.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or $.Values.annotations .annotations }} + annotations: + {{- with $.Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +rules: {{- toYaml .rules | nindent 2 }} +{{- end }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/templates/service-account.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/templates/service-account.yaml new file mode 100644 index 00000000..08f21f7e --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/templates/service-account.yaml @@ -0,0 +1,23 @@ + +{{- with .Values.serviceAccount }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .name }} + namespace: {{ .namespace | default $.Release.Namespace | quote }} + labels: + {{- include "beat.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or $.Values.annotations .annotations }} + annotations: + {{- with $.Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/values.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/values.yaml new file mode 100644 index 00000000..c54abe3b --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-beats/values.yaml @@ -0,0 +1,181 @@ +--- +# Default values for eck-beats. +# This is a YAML-formatted file. + +# Overridable names of the Beats resource. +# By default, this is the Release name set for the chart, +# followed by 'eck-beats'. +# +# nameOverride will override the name of the Chart with the name set here, +# so nameOverride: quickstart, would convert to '{{ Release.name }}-quickstart' +# +# nameOverride: "quickstart" +# +# fullnameOverride will override both the release name, and the chart name, +# and will name the Beats resource exactly as specified. +# +# fullnameOverride: "quickstart" + +# Version of Elastic Beats. +# +version: 9.2.0 + +# Labels that will be applied to Elastic Beats. +# +labels: {} + +# Annotations that will be applied to Elastic Beats. +# +annotations: {} + +# ** Deprecation Notice ** +# The previous versions of this Helm Chart simply used the `spec` field here +# and allowed the user to specify any fields below spec that were templated directly +# into the final Beats manifest. This is no longer the preferred way to specify these +# fields and each field that is supported underneath `spec` is now directly specified +# in this values file. Currently both patterns are supported for backwards compatibility +# but we plan to remove the `spec` field in the future. +# spec: {} + +# Type of Elastic Beats. Standard types of Beat are [filebeat,metricbeat,heartbeat,auditbeat,packetbeat,journalbeat]. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-beat-configuration.html#k8s-beat-deploy-elastic-beat +# +# Note: This is required to be set, or the release install will fail. +# +type: "" + +# Beats image to deploy. +# +# image: docker.elastic.co/beats/metricbeat:9.2.0 + +# Referenced resources are below and depending on the setup, at least elasticsearchRef is required for a functional Beat. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-beat-configuration.html#k8s-beat-connect-es +# +# Reference to ECK-managed Kibana instance. +# +# kibanaRef: +# name: quickstart + # Optional namespace reference to Kibana instance. + # If not specified, then the namespace of the Beats instance + # will be assumed. + # + # namespace: default + +# Reference to ECK-managed Elasticsearch instance. +# *Note* If Beat's output is intended to go to Elasticsearch and not something like Logstash, +# this elasticsearchRef must be updated to the name of the Elasticsearch instance. +# +elasticsearchRef: {} + # name: elasticsearch + # Optional namespace reference to Elasticsearch instance. + # If not specified, then the namespace of the Beats instance + # will be assumed. + # + # namespace: default + # + # Optional secretName referencing an existing Kubernetes secret that contains connection information + # for associating a Beat instance to a remote Elasticsearch instance not managed by ECK. + # The referenced secret must contain the following: + # - `url`: the URL to reach the Elastic resource + # - `username`: the username of the user to be authenticated to the Elastic resource + # - `password`: the password of the user to be authenticated to the Elastic resource + # - `ca.crt`: the CA certificate in PEM format (optional) + # - `api-key`: the key to authenticate against the Elastic resource instead of a username and password + # This field cannot be used in combination with the other fields name, namespace or serviceName. + # + # secretName: my-remote-es-credentials + +# Daemonset, or Deployment specification for the type of Beat specified. +# At least one is required of [daemonSet, deployment]. +# No default is currently set, refer to https://github.com/elastic/cloud-on-k8s/issues/7429. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-beat-configuration.html#k8s-beat-chose-the-deployment-model +# +# deployment: +# podTemplate: +# spec: +# securityContext: +# runAsUser: 0 +# daemonSet: +# podTemplate: +# spec: +# securityContext: +# runAsUser: 0 + +# Configuration of Beat, which is dependent on the `type` of Beat specified. +# NOTE: The `config` and `configRef` fields are mutually exclusive. Only one of them should be defined at a time, +# as using both may cause conflicts. +# +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-beat-configuration.html#k8s-beat-custom-configuration +# +config: {} + +# Reference a configuration in a Secret. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-beat-configuration.html#k8s-beat-custom-configuration +# +# configRef: +# secretName: "" + +# The HTTP layer configuration for the Beats Service. +# +# http: + +# Settings for configuring stack monitoring. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-stack-monitoring.html +# +# monitoring: {} + # metrics: + # elasticsearchRefs: + # - name: monitoring + # namespace: observability + # logs: + # elasticsearchRefs: + # - name: monitoring + # namespace: observability + +# SecureSettings is a list of references to Kubernetes Secrets containing sensitive configuration options for Elastic Beats. +secureSettings: [] +# - secretName: my-secret-with-secure-settings + +# Number of revisions to retain to allow rollback in the underlying Deployment. +# If not set Kubernetes sets this to 10 by default. +# +# revisionHistoryLimit: 2 + +# ServiceAccount to be used by Elastic Beats. Some Beats features (such as autodiscover or Kubernetes module metricsets) +# require that Beat Pods interact with Kubernetes APIs. This functionality requires specific permissions +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-beat-configuration.html#k8s-beat-role-based-access-control-for-beats +# +serviceAccount: {} +# name: elastic-beat-filebeat-quickstart +# namespace: optional-namespace + +# ClusterRoleBinding to be used by Elastic Beats. Similar to ServiceAccount, this is required in some scenarios. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-beat-configuration.html#k8s-beat-role-based-access-control-for-beats +# +clusterRoleBinding: {} +# name: elastic-beat-autodiscover-binding +# subjects: +# - kind: ServiceAccount +# name: elastic-beat-filebeat-quickstart +# namespace: default +# roleRef: +# kind: ClusterRole +# name: elastic-beat-autodiscover +# apiGroup: rbac.authorization.k8s.io + +# ClusterRole to be used by Elastic Beats. Similar to ServiceAccount, this is required in some scenarios. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-beat-configuration.html#k8s-beat-role-based-access-control-for-beats +# +clusterRole: {} +# name: elastic-beat-autodiscover +# rules: +# - apiGroups: [""] +# resources: +# - events +# - pods +# - namespaces +# - nodes +# verbs: +# - get +# - watch +# - list diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/.helmignore b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/.helmignore new file mode 100644 index 00000000..f1568daf --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/Chart.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/Chart.yaml new file mode 100644 index 00000000..c99bff0c --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/Chart.yaml @@ -0,0 +1,10 @@ +apiVersion: v2 +description: Elasticsearch managed by the ECK operator +icon: https://helm.elastic.co/icons/elasticsearch.png +kubeVersion: '>= 1.21.0-0' +name: eck-elasticsearch +sources: +- https://github.com/elastic/cloud-on-k8s +- https://github.com/elastic/elasticsearch/ +type: application +version: 0.17.0 diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/LICENSE b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/LICENSE new file mode 100644 index 00000000..92503a72 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/LICENSE @@ -0,0 +1,93 @@ +Elastic License 2.0 + +URL: https://www.elastic.co/licensing/elastic-license + +## Acceptance + +By using the software, you agree to all of the terms and conditions below. + +## Copyright License + +The licensor grants you a non-exclusive, royalty-free, worldwide, +non-sublicensable, non-transferable license to use, copy, distribute, make +available, and prepare derivative works of the software, in each case subject to +the limitations and conditions below. + +## Limitations + +You may not provide the software to third parties as a hosted or managed +service, where the service provides users with access to any substantial set of +the features or functionality of the software. + +You may not move, change, disable, or circumvent the license key functionality +in the software, and you may not remove or obscure any functionality in the +software that is protected by the license key. + +You may not alter, remove, or obscure any licensing, copyright, or other notices +of the licensor in the software. Any use of the licensor’s trademarks is subject +to applicable law. + +## Patents + +The licensor grants you a license, under any patent claims the licensor can +license, or becomes able to license, to make, have made, use, sell, offer for +sale, import and have imported the software, in each case subject to the +limitations and conditions in this license. This license does not cover any +patent claims that you cause to be infringed by modifications or additions to +the software. If you or your company make any written claim that the software +infringes or contributes to infringement of any patent, your patent license for +the software granted under these terms ends immediately. If your company makes +such a claim, your patent license ends immediately for work on behalf of your +company. + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you +also gets a copy of these terms. + +If you modify the software, you must include in any modified copies of the +software prominent notices stating that you have modified the software. + +## No Other Rights + +These terms do not imply any licenses other than those expressly granted in +these terms. + +## Termination + +If you use the software in violation of these terms, such use is not licensed, +and your licenses will automatically terminate. If the licensor provides you +with a notice of your violation, and you cease all violation of this license no +later than 30 days after you receive that notice, your licenses will be +reinstated retroactively. However, if you violate these terms after such +reinstatement, any additional violation of these terms will cause your licenses +to terminate automatically and permanently. + +## No Liability + +*As far as the law allows, the software comes as is, without any warranty or +condition, and the licensor will not be liable to you for any damages arising +out of these terms or the use or nature of the software, under any kind of +legal claim.* + +## Definitions + +The **licensor** is the entity offering these terms, and the **software** is the +software the licensor makes available under these terms, including any portion +of it. + +**you** refers to the individual or entity agreeing to these terms. + +**your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control over, +are under the control of, or are under common control with that +organization. **control** means ownership of substantially all the assets of an +entity, or the power to direct its management and policies by vote, contract, or +otherwise. Control can be direct or indirect. + +**your licenses** are all the licenses granted to you for the software under +these terms. + +**use** means anything you do with the software requiring one of your licenses. + +**trademark** means trademarks, service marks, and similar rights. \ No newline at end of file diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/examples/hot-warm-cold.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/examples/hot-warm-cold.yaml new file mode 100644 index 00000000..4eb99e60 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/examples/hot-warm-cold.yaml @@ -0,0 +1,198 @@ +--- +nodeSets: +- name: masters + count: 1 + config: + node.roles: ["master"] + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + spec: + containers: + - name: elasticsearch + resources: + limits: + memory: 8Gi + cpu: 2 + # Affinity/Anti-affinity settings for controlling the 'spreading' of Elasticsearch + # pods across existing hosts. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html#k8s-affinity-options + # + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: beta.kubernetes.io/instance-type + # operator: In + # # This should be adjusted to the instance type according to your setup + # # + # values: + # - highio + # Volume Claim settings. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-volume-claim-templates.html + # + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Ti + # Adjust to your storage class name + # + # storageClassName: local-storage +- name: hot + count: 1 + config: + node.roles: ["data_hot", "data_content", "ingest"] + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + spec: + containers: + - name: elasticsearch + resources: + limits: + memory: 16Gi + cpu: 4 + # Affinity/Anti-affinity settings for controlling the 'spreading' of Elasticsearch + # pods across existing hosts. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html#k8s-affinity-options + # + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: beta.kubernetes.io/instance-type + # operator: In + # # This should be adjusted to the instance type according to your setup + # # + # values: + # - highio + # Volume Claim settings. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-volume-claim-templates.html + # + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Ti + # Adjust to your storage class name + # + # storageClassName: local-storage +- name: warm + count: 1 + config: + node.roles: ["data_warm"] + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + spec: + containers: + - name: elasticsearch + resources: + limits: + memory: 16Gi + cpu: 2 + # Affinity/Anti-affinity settings for controlling the 'spreading' of Elasticsearch + # pods across existing hosts. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html#k8s-affinity-options + # + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: beta.kubernetes.io/instance-type + # operator: In + # # This should be adjusted to the instance type according to your setup + # # + # values: + # - highstorage + # Volume Claim settings. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-volume-claim-templates.html + # + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Ti + # Adjust to your storage class name + # + # storageClassName: local-storage +- name: cold + count: 1 + config: + node.roles: ["data_cold"] + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + spec: + containers: + - name: elasticsearch + resources: + limits: + memory: 8Gi + cpu: 2 + # Affinity/Anti-affinity settings for controlling the 'spreading' of Elasticsearch + # pods across existing hosts. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html#k8s-affinity-options + # + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: beta.kubernetes.io/instance-type + # operator: In + # # This should be adjusted to the instance type according to your setup + # # + # values: + # - highstorage + # Volume Claim settings. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-volume-claim-templates.html + # + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 20Ti + # Adjust to your storage class name + # + # storageClassName: local-storage diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-aks.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-aks.yaml new file mode 100644 index 00000000..0ca310c3 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-aks.yaml @@ -0,0 +1,26 @@ +--- +# The following is an example of an Elasticsearch resource that is configured to use an Ingress resource in an AKS cluster. +# +ingress: + enabled: true + className: webapprouting.kubernetes.azure.com + annotations: + # This is required for AKS Loadbalancing to understand that it's communicating with + # an HTTPS backend. + nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" + labels: + my: label + pathType: Prefix + hosts: + - host: "elasticsearch.company.dev" + path: "/" +nodeSets: +- name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-eks-alb.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-eks-alb.yaml new file mode 100644 index 00000000..d3cc4041 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-eks-alb.yaml @@ -0,0 +1,37 @@ +--- +# The following is an example of an Elasticsearch resource that is configured to use an Ingress resource in an EKS cluster +# which provisions an application load balancer. +# +ingress: + enabled: true + className: alb + annotations: + alb.ingress.kubernetes.io/scheme: "internet-facing" + alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]' + alb.ingress.kubernetes.io/backend-protocol: "HTTPS" + alb.ingress.kubernetes.io/target-type: "ip" + # To use an ALB with ECK, you must provide a valid ACM certificate ARN or use certificate discovery. + # There are 2 options for EKS: + # 1. Create a valid ACM certificate, and uncomment the following annotation and update it to the correct ARN. + # 2. Create a valid ACM certificate and ensure that the hosts[0].host matches the certificate's Common Name (CN) and + # certificate discovery *should* find the certificate automatically and use it. + # + # ref: https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.8/guide/ingress/cert_discovery/ + # + # alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:us-east-1:00000000000:certificate/b65be571-8220-4f2e-8cb1-94194535d877" + labels: + my: label + pathType: Prefix + hosts: + - host: "elasticsearch.company.dev" + path: "/" +nodeSets: +- name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-eks-nlb.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-eks-nlb.yaml new file mode 100644 index 00000000..3809e871 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-eks-nlb.yaml @@ -0,0 +1,27 @@ +--- +# The following is an example of an Elasticsearch resource that is configured to deploy a +# network load balancer (NLB) in an EKS cluster. To provision an NLB "ingress" for the +# Elasticsearch cluster, you are required to set annotations on the service, +# and not an Ingress resource. +ingress: + enabled: false +http: + service: + metadata: + annotations: + service.beta.kubernetes.io/aws-load-balancer-type: external + service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip + service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing + service.beta.kubernetes.io/aws-load-balancer-backend-protocol: ssl + spec: + type: LoadBalancer +nodeSets: +- name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-gke.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-gke.yaml new file mode 100644 index 00000000..3adbd29c --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/examples/ingress/elasticsearch-ingress-gke.yaml @@ -0,0 +1,36 @@ +--- +# The following is an example of an Elasticsearch resource that is configured to use an Ingress resource in a GKE cluster. +# +ingress: + enabled: true + annotations: + my: annotation + labels: + my: label + pathType: Prefix + hosts: + - host: "elasticsearch.company.dev" + path: "/" +http: + service: + metadata: + annotations: + # This is required for `ClusterIP` services (which are the default ECK service type) to be used with Ingress in GKE clusters. + cloud.google.com/neg: '{"ingress": true}' + # This is required to enable the GKE Ingress Controller to use HTTPS as the backend protocol. + cloud.google.com/app-protocols: '{"https":"HTTPS"}' +nodeSets: +- name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false + # Enable anonymous access to allow GCLB health probes to succeed + xpack.security.authc: + anonymous: + username: anon + roles: monitoring_user diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/templates/NOTES.txt b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/templates/NOTES.txt new file mode 100644 index 00000000..f6ab0020 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/templates/NOTES.txt @@ -0,0 +1,6 @@ + +1. Check Elasticsearch resource status + $ kubectl get es {{ include "elasticsearch.fullname" . }} -n {{ .Release.Namespace }} + +2. Check Elasticsearch pod status + $ kubectl get pods --namespace={{ .Release.Namespace }} -l elasticsearch.k8s.elastic.co/cluster-name={{ include "elasticsearch.fullname" . }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/templates/_helpers.tpl b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/templates/_helpers.tpl new file mode 100644 index 00000000..8fbf57b3 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "elasticsearch.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "elasticsearch.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "elasticsearch.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "elasticsearch.labels" -}} +helm.sh/chart: {{ include "elasticsearch.chart" . }} +{{ include "elasticsearch.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.labels }} +{{ toYaml .Values.labels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "elasticsearch.selectorLabels" -}} +app.kubernetes.io/name: {{ include "elasticsearch.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/templates/elasticsearch.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/templates/elasticsearch.yaml new file mode 100644 index 00000000..4a4d7465 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/templates/elasticsearch.yaml @@ -0,0 +1,78 @@ +--- +apiVersion: elasticsearch.k8s.elastic.co/v1 +kind: Elasticsearch +metadata: + name: {{ include "elasticsearch.fullname" . }} + labels: + {{- include "elasticsearch.labels" . | nindent 4 }} + annotations: + eck.k8s.elastic.co/license: basic + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .Values.auth }} + auth: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.updateStrategy }} + updateStrategy: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.secureSettings }} + secureSettings: + {{- toYaml . | nindent 2 }} + {{- end }} + {{- with .Values.transport }} + transport: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.http }} + http: + {{- toYaml . | nindent 4 }} + {{- end }} + version: {{ required "An Elasticsearch version is required" .Values.version }} + {{- with .Values.monitoring }} + monitoring: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.remoteClusters }} + remoteClusters: + {{- toYaml . | nindent 2 }} + {{- end }} + {{- with .Values.remoteClusterServer }} + remoteClusterServer: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.volumeClaimDeletePolicy }} + volumeClaimDeletePolicy: + {{- if and (not (eq . "DeleteOnScaledownOnly")) (not (eq . "DeleteOnScaledownAndClusterDeletion")) }} + {{ fail "volumeClaimDeletePolicy can only be one of 'DeleteOnScaledownOnly' or 'DeleteOnScaledownAndClusterDeletion'" }} + {{- end }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if eq (len .Values.nodeSets) 0 }} + {{ fail "At least one nodeSet is required" }} + {{- end }} + nodeSets: + {{ toYaml .Values.nodeSets | nindent 4 }} + {{- with .Values.image }} + image: {{ . }} + {{- end }} + {{- with .Values.podDisruptionBudget }} + {{- if .disabled }} + podDisruptionBudget: {} + {{- else }} + {{- with .spec }} + podDisruptionBudget: + spec: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- end }} + {{- end }} + {{- with .Values.serviceAccountName }} + serviceAccountName: {{ . }} + {{- end }} + {{- with .Values.revisionHistoryLimit }} + revisionHistoryLimit: {{ . }} + {{- end }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/templates/ingress.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/templates/ingress.yaml new file mode 100644 index 00000000..99aa1813 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/templates/ingress.yaml @@ -0,0 +1,48 @@ +{{- if .Values.ingress.enabled -}} +{{- $pathType := .Values.ingress.pathType | default "Prefix" -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "elasticsearch.fullname" . }} + labels: + {{- include "elasticsearch.labels" . | nindent 4 }} + {{- with .Values.ingress.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.ingress.annotations }} + annotations: + {{- with .Values.ingress.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +spec: + {{- if .Values.ingress.className }} + ingressClassName: {{ .Values.ingress.className | quote }} + {{- end }} + {{- if .Values.ingress.tls.enabled }} + tls: + - hosts: + {{- range .Values.ingress.hosts }} + - {{ .host | quote }} + {{- end }} + {{- if .Values.ingress.tls.secretName }} + secretName: {{ .Values.ingress.tls.secretName }} + {{- else }} + secretName: {{ include "elasticsearch.fullname" . }}-es-http-certs-internal + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + {{- $hostPath := .path | default "/" }} + - host: {{ .host | quote }} + http: + paths: + - path: {{ $hostPath }} + pathType: {{ $pathType }} + backend: + service: + name: {{ include "elasticsearch.fullname" $ }}-es-http + port: + number: 9200 + {{- end }} +{{ end }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/values.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/values.yaml new file mode 100644 index 00000000..3a3850fe --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-elasticsearch/values.yaml @@ -0,0 +1,393 @@ +--- +# Default values for eck-elasticsearch. +# This is a YAML-formatted file. + +# Overridable names of the Elasticsearch resource. +# By default, this is the Release name set for the chart, +# followed by 'eck-elasticsearch'. +# +# nameOverride will override the name of the Chart with the name set here, +# so nameOverride: quickstart, would convert to '{{ Release.name }}-quickstart' +# +# nameOverride: "quickstart" +# +# fullnameOverride will override both the release name, and the chart name, +# and will name the Elasticsearch resource exactly as specified. +# +# fullnameOverride: "quickstart" + +# Version of Elasticsearch. +# +version: 9.2.0 + +# Elasticsearch Docker image to deploy +# +# image: + +# Labels that will be applied to Elasticsearch. +# +labels: {} + +# Annotations that will be applied to Elasticsearch. +# +annotations: {} + +# Settings for configuring Elasticsearch users and roles. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-users-and-roles.html +# +auth: {} + +# Settings for configuring stack monitoring. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-stack-monitoring.html +# +monitoring: {} + # metrics: + # elasticsearchRefs: + # - name: monitoring + # namespace: observability + # logs: + # elasticsearchRefs: + # - name: monitoring + # namespace: observability + +# Control the Elasticsearch transport module used for internal communication between nodes. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-transport-settings.html +# +transport: {} + # service: + # metadata: + # labels: + # my-custom: label + # spec: + # type: LoadBalancer + # tls: + # subjectAltNames: + # - ip: 1.2.3.4 + # - dns: hulk.example.com + # certificate: + # secretName: custom-ca + +# Settings to control how Elasticsearch will be accessed. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-accessing-elastic-services.html +# +http: {} + # service: + # metadata: + # labels: + # my-custom: label + # spec: + # type: LoadBalancer + # tls: + # selfSignedCertificate: + # # To fully disable TLS for the HTTP layer of Elasticsearch, simply + # # set the below field to 'true', removing all other fields. + # disabled: false + # subjectAltNames: + # - ip: 1.2.3.4 + # - dns: hulk.example.com + # certificate: + # secretName: custom-ca + +# Control Elasticsearch Secure Settings. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-es-secure-settings.html#k8s-es-secure-settings +# +secureSettings: [] + # - secretName: one-secure-settings-secret + # Projection of secret keys to specific paths + # - secretName: gcs-secure-settings + # entries: + # - key: gcs.client.default.credentials_file + # - key: gcs_client_1 + # path: gcs.client.client_1.credentials_file + # - key: gcs_client_2 + # path: gcs.client.client_2.credentials_file + +# Settings for limiting the number of simultaneous changes to an Elasticsearch resource. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-update-strategy.html +# +updateStrategy: {} + # changeBudget: + # maxSurge: 3 + # maxUnavailable: 1 + +# Controlling of connectivity between remote clusters within the same kubernetes cluster. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-remote-clusters.html +# +remoteClusters: {} + # - name: cluster-two + # elasticsearchRef: + # name: cluster-two + # namespace: ns-two + +# RemoteClusterServer specifies if the remote cluster server should be enabled. +# This must be enabled if this cluster is a remote cluster which is expected to be accessed using API key authentication. +# +remoteClusterServer: {} +# enabled: true + +# VolumeClaimDeletePolicy sets the policy for handling deletion of PersistentVolumeClaims for all NodeSets. +# Possible values are DeleteOnScaledownOnly and DeleteOnScaledownAndClusterDeletion. +# By default, if not set or empty, the operator sets DeleteOnScaledownAndClusterDeletion. +# +volumeClaimDeletePolicy: "" + +# Settings to limit the disruption when pods need to be rescheduled for some reason such as upgrades or routine maintenance. +# By default, if not set, the operator sets a budget that doesn't allow any pod to be removed in case the cluster is not green or if there is only one node of type `data` or `master`. +# In all other cases the default PodDisruptionBudget sets `minUnavailable` equal to the total number of nodes minus 1. +# To completely disable the pod disruption budget set `disabled` to true. +# +# podDisruptionBudget: +# spec: +# minAvailable: 2 +# selector: +# matchLabels: +# elasticsearch.k8s.elastic.co/cluster-name: quickstart +# disabled: true + +# Used to check access from the current resource to a resource (for ex. a remote Elasticsearch cluster) in a different namespace. +# Can only be used if ECK is enforcing RBAC on references. +# +# serviceAccountName: "" + +# Number of revisions to retain to allow rollback in the underlying StatefulSets. +# By default, if not set, Kubernetes sets 10. +# +# revisionHistoryLimit: 2 + +# Node configuration settings. +# The node roles which can be configured here are: +# - "master" +# - "data_hot" +# - "data_cold" +# - "data_frozen" +# - "data_content" +# - "ml" +# - "ingest" +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-node-configuration.html +# +nodeSets: +- name: default + count: 1 + config: + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + # The following spec is exactly the Kubernetes Core V1 PodTemplateSpec. Any fields within the PodTemplateSpec + # are supported within the 'spec' field below. Please see below documentation for the exhaustive list of fields. + # + # https://v1-24.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#podtemplatespec-v1-core + # + # Only the commonly overridden/used fields will be noted below. + # + spec: + + # If specified, the pod's scheduling constraints + # https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html + # https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: topology.kubernetes.io/zone + # operator: In + # values: + # - antarctica-east1 + # - antarctica-west1 + + # Containers array. Should only be used to customize the 'elasticsearch' container using the following fields. + containers: + - name: elasticsearch + + # List of environment variables to set in the 'elasticsearch' container. + # https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/ + # env: + # - name: "my-env-var" + # value: "my-value" + + # Compute Resources required by this container. + resources: + # Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, + # it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. + # + # Defaults used by the ECK Operator, if not specified, are below + limits: + # cpu: 1 + memory: 2Gi + requests: + # cpu: 1 + memory: 2Gi + + # Example increasing both the requests and limits values: + # limits: + # cpu: 4 + # memory: 8Gi + # requests: + # cpu: 1 + # memory: 8Gi + + # SecurityContext defines the security options the container should be run with. + # If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + # + # These typically are set automatically by the ECK Operator, and should only be adjusted + # with the full knowledge of the effects of each field. + # + # securityContext: + + # Whether this container has a read-only root filesystem. Default is false. + # readOnlyRootFilesystem: false + + # The GID to run the entrypoint of the container process. Uses runtime default if unset. + # runAsGroup: 1000 + + # Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure + # that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. + # runAsNonRoot: true + + # The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. + # runAsUser: 1000 + + # ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. + # https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod + # imagePullSecrets: + # - name: "image-pull-secret" + + # List of initialization containers belonging to the pod. + # + # Common initContainers include setting sysctl, or in 7.x versions of Elasticsearch, + # installing Elasticsearch plugins. + # + # https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + # initContainers: + # - command: + # - sh + # - "-c" + # - sysctl -w vm.max_map_count=262144 + # name: sysctl + # securityContext: + # privileged: true + # - command: + # - sh + # - "-c" + # - bin/elasticsearch-plugin remove --purge analysis-icu ; bin/elasticsearch-plugin install --batch analysis-icu + # name: install-plugins + # securityContext: + # privileged: true + + + # NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. + # https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + # https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html + # nodeSelector: + # diskType: ssd + # environment: production + + # If specified, indicates the pod's priority. "system-node-critical" and "system-cluster-critical" are two special keywords which indicate the highest priorities with the former being the highest priority. + # Any other name must be defined by creating a PriorityClass object with that name. If not specified, the pod priority will be default or zero if there is no default. + # https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/ + # priorityClassName: "" + + # SecurityContext holds pod-level security attributes and common container settings. Optional: Defaults to empty. See type description for default values of each field. + # See previously defined 'securityContext' within 'podTemplate' for all available fields. + # securityContext: {} + + # ServiceAccountName is the name of the ServiceAccount to use to run this pod. + # https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + # serviceAccountName: "" + + # Optional duration in seconds to wait for the Elasticsearch pod to terminate gracefully. + # terminationGracePeriodSeconds: 30s + + # If specified, the pod's tolerations that will apply to all containers within the pod. + # https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/ + # tolerations: + # - key: "node-role.kubernetes.io/elasticsearch" + # effect: "NoSchedule" + # operator: "Exists" + + # TopologySpreadConstraints describes how a group of pods ought to spread across topology domains. + # Scheduler will schedule pods in a way which abides by the constraints. All topologySpreadConstraints are ANDed. + # + # These settings are generally applied within each `nodeSets[].podTemplate` field to apply to a specific Elasticsearch nodeset. + # + # https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html + # topologySpreadConstraints: {} + + # List of volumes that can be mounted by containers belonging to the pod. + # https://kubernetes.io/docs/concepts/storage/volumes + # volumes: [] + +# Settings for controlling Elasticsearch ingress. Enabling ingress will expose your Elasticsearch instance +# to the public internet, and as such is disabled by default. +# +# Each Cloud Service Provider has different requirements for setting up Ingress. Some links to common documentation are: +# - AWS: https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html +# - GCP: https://cloud.google.com/kubernetes-engine/docs/concepts/ingress +# - Azure: https://learn.microsoft.com/en-us/azure/aks/app-routing +# - Nginx: https://kubernetes.github.io/ingress-nginx/ +# +ingress: + enabled: false + + # Annotations that will be applied to the Ingress resource. Note that some ingress controllers are controlled via annotations. + # + # Nginx Annotations: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/ + # + # Common annotations: + # kubernetes.io/ingress.class: gce # Configures the Ingress resource to use the GCE ingress controller and create an external Application Load Balancer. + # kubernetes.io/ingress.class: gce-internal # Configures the Ingress resource to use the GCE ingress controller and create an internal Application Load Balancer. + # kubernetes.io/ingress.class: nginx # Configures the Ingress resource to use the NGINX ingress controller. + # + annotations: {} + + # Labels that will be applied to the Ingress resource. + # + labels: {} + + # Some ingress controllers require the use of a specific class name to route traffic to the correct controller, notably AKS and EKS, which + # replaces the use of the 'kubernetes.io/ingress.class' annotation. + # + # className: webapprouting.kubernetes.azure.com | alb + + # Ingress paths are required to have a corresponding path type. Defaults to 'Prefix'. + # + # There are 3 supported path types: + # - ImplementationSpecific + # - Prefix + # - Exact + # + # ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#path-types + # + pathType: Prefix + + # Hosts are a list of hosts included in the Ingress definition, with a corresponding path at which the default Elasticsearch service + # will be exposed. Each host in the list should be a fully qualified DNS name that will resolve to the exposed Ingress object. + # + # ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#name-based-virtual-hosting + # + hosts: + - host: chart-example.local + path: / + + # TLS defines whether TLS will be enabled on the Ingress resource. + # + # *NOTE* Many Cloud Service Providers handle TLS in a custom manner, and as such, it is recommended to consult their documentation. + # Notably GKE and Nginx Ingress Controllers seems to respect the Ingress TLS settings, AKS and EKS ignore it. + # + # - AKS: https://learn.microsoft.com/en-us/azure/aks/app-routing-dns-ssl + # - GKE: https://cloud.google.com/kubernetes-engine/docs/concepts/ingress#options_for_providing_ssl_certificates + # - EKS: https://aws.amazon.com/blogs/containers/serve-distinct-domains-with-tls-powered-by-acm-on-amazon-eks/ + # - Nginx: https://kubernetes.github.io/ingress-nginx/user-guide/tls/ + # + # Kubernetes ingress TLS documentation: + # ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#tls + # + tls: + enabled: false + # Optional Kubernetes secret name that contains a base64 encoded PEM certificate and private key that corresponds to the above 'hosts' definitions. + # If tls is enabled, but this field is not set, the self-signed certificate and key created by the ECK operator will be used. + # secretName: chart-example-tls diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-enterprise-search/.helmignore b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-enterprise-search/.helmignore new file mode 100644 index 00000000..f1568daf --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-enterprise-search/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-enterprise-search/Chart.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-enterprise-search/Chart.yaml new file mode 100644 index 00000000..51b8f297 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-enterprise-search/Chart.yaml @@ -0,0 +1,9 @@ +apiVersion: v2 +description: Elastic Enterprise Search managed by the ECK operator +icon: https://github.com/elastic/ent-search/blob/main/public/app-search-favicon-196x196.png +kubeVersion: '>= 1.21.0-0' +name: eck-enterprise-search +sources: +- https://github.com/elastic/cloud-on-k8s +type: application +version: 0.17.0 diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-enterprise-search/examples/with-custom-configuration.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-enterprise-search/examples/with-custom-configuration.yaml new file mode 100644 index 00000000..4216a112 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-enterprise-search/examples/with-custom-configuration.yaml @@ -0,0 +1,19 @@ +config: + # define the exposed URL at which users will reach Enterprise Search + ent_search.external_url: https://my-custom-domain:3002 + # define the exposed URL at which users will reach Kibana + kibana.host: https://kibana.my-custom-domain:5601 + # configure app search document size limit + app_search.engine.document_size.limit: 100kb + +http: + service: + metadata: + labels: + my-custom: label + tls: + certificate: + secretName: my-cert + +elasticsearchRef: + name: eck-elasticsearch diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-enterprise-search/templates/_helpers.tpl b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-enterprise-search/templates/_helpers.tpl new file mode 100644 index 00000000..21025dc7 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-enterprise-search/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "eck-enterprise-search.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "eck-enterprise-search.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "eck-enterprise-search.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "eck-enterprise-search.labels" -}} +helm.sh/chart: {{ include "eck-enterprise-search.chart" . }} +{{ include "eck-enterprise-search.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "eck-enterprise-search.selectorLabels" -}} +app.kubernetes.io/name: {{ include "eck-enterprise-search.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "eck-enterprise-search.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "eck-enterprise-search.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-enterprise-search/templates/enterprisesearch.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-enterprise-search/templates/enterprisesearch.yaml new file mode 100644 index 00000000..af224e35 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-enterprise-search/templates/enterprisesearch.yaml @@ -0,0 +1,62 @@ +--- +apiVersion: enterprisesearch.k8s.elastic.co/v1 +kind: EnterpriseSearch +metadata: + name: {{ include "eck-enterprise-search.fullname" . }} + labels: + {{- include "eck-enterprise-search.labels" . | nindent 4 }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + eck.k8s.elastic.co/license: basic + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + version: {{ required "An Enterprise Search version is required" .Values.version }} + count: {{ required "A pod count is required" .Values.count }} + + {{- /* + This is complicated, but seems required to catch both the situations where the key does not exist (commented out), and the key exists but is an empty map. + */ -}} + {{- if and (or (and (hasKey .Values "configRef") (eq 0 (len .Values.configRef))) (not (hasKey .Values "configRef"))) (or (and (hasKey .Values "elasticsearchRef") (eq 0 (len .Values.elasticsearchRef))) (not (hasKey .Values "elasticsearchRef"))) }} + {{ fail "At least one of configRef or elasticsearchRef is required" }} + {{- end }} + + {{- with .Values.image }} + image: {{ . }} + {{- end }} + + {{- with .Values.serviceAccountName }} + serviceAccountName: {{ . }} + {{- end }} + + {{- with .Values.revisionHistoryLimit }} + revisionHistoryLimit: {{ . }} + {{- end }} + + {{- with .Values.config }} + config: + {{- toYaml . | nindent 4 }} + {{- end }} + + {{- with .Values.http }} + http: + {{- toYaml . | nindent 4 }} + {{- end }} + + {{- with .Values.elasticsearchRef }} + elasticsearchRef: + {{- toYaml . | nindent 4 }} + {{- end }} + + {{- with .Values.podTemplate }} + podTemplate: + {{- toYaml . | nindent 4 }} + {{- end }} + + {{- with .Values.configRef }} + configRef: + {{- toYaml . | nindent 2 }} + {{- end }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-enterprise-search/values.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-enterprise-search/values.yaml new file mode 100644 index 00000000..24162c68 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-enterprise-search/values.yaml @@ -0,0 +1,108 @@ +--- +# Default values for eck-enterprise-search. +# This is a YAML-formatted file. + +# Overridable names of the Enterprise Search resource. +# By default, this is the Release name set for the chart, +# followed by 'eck-enterprise-search'. +# +# nameOverride will override the name of the Chart with the name set here, +# so nameOverride: quickstart, would convert to '{{ Release.name }}-quickstart' +# +# nameOverride: "quickstart" +# +# fullnameOverride will override both the release name, and the chart name, +# and will name the Enterprise Search resource exactly as specified. +# +# fullnameOverride: "quickstart" + +# Version of Enterprise Search. +# +# 8.19 should be the last minor version in the 8 line. +version: 8.19.0 + +# Enterprise Search Docker image to deploy +# +# image: + +# Used to check access from the current resource to a resource (for ex. a remote Elasticsearch cluster) in a different namespace. +# Can only be used if ECK is enforcing RBAC on references. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-restrict-cross-namespace-associations.html +# +# serviceAccountName: "" + +# Labels that will be applied to Enterprise Search. +# +labels: {} + +# Annotations that will be applied to Enterprise Search. +# +annotations: {} + +# Count of Enterprise Search replicas to create. +# +count: 1 + +# The Enterprise Search configuration, the ECK equivalent to enterprise-search.yml +# ref: https://www.elastic.co/guide/en/enterprise-search/current/configuration.html#configuration-configure +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-enterprise-search-configuration.html +# +# At a minimum, you must specify the external URL and Kibana host. +# +config: {} + # define the exposed URL at which users will reach Enterprise Search + # ent_search.external_url: https://my-custom-domain:3002 + # define the exposed URL at which users will reach Kibana + # kibana.host: https://kibana.my-custom-domain:5601 + +# Settings to control how Enterprise Search will be accessed. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-accessing-elastic-services.html +# +http: {} + # tls: + # certificate: + # secretName: my-cert + # service: + # metadata: + # labels: + # my-custom: label + +# Reference to ECK-managed Elasticsearch resource. +# +elasticsearchRef: {} + # name: eck-elasticsearch + # Optional namespace reference to Elasticsearch resource. + # If not specified, then the namespace of the Enterprise Search resource + # will be assumed. + # + # namespace: default + # + # Optional secretName referencing an existing Kubernetes secret that contains connection information + # for associating an Enterprise Search instance to a remote Elasticsearch instance not managed by ECK. + # The referenced secret must contain the following: + # - `url`: the URL to reach the Elastic resource + # - `username`: the username of the user to be authenticated to the Elastic resource + # - `password`: the password of the user to be authenticated to the Elastic resource + # - `ca.crt`: the CA certificate in PEM format (optional) + # This field cannot be used in combination with the other fields name, namespace or serviceName. + # + # secretName: my-remote-es-credentials + +# Set podTemplate to customize the pod used by Enterprise Search +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-customize-pods.html +# +podTemplate: {} + +# Number of revisions to retain to allow rollback in the underlying Deployment. +# If not set Kubernetes sets this to 10 by default. +# +# revisionHistoryLimit: 2 + +# If you would prefer your sensitive data to be stored in a Secret, you can specify the name of the Secret reference. +# In addition, if you do not want to use the `elasticsearchRef` mechanism or if you want to connect to an Elasticsearch +# cluster not managed by ECK, you can manually configure Enterprise Search to access any available Elasticsearch cluster: +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-enterprise-search-configuration.html#k8s-enterprise-search-secret-configuration +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-enterprise-search-configuration.html#k8s-enterprise-search-connect-non-eck-es +# +configRef: {} + # secretName: enterprise-search-config diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/.helmignore b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/.helmignore new file mode 100644 index 00000000..f1568daf --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/Chart.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/Chart.yaml new file mode 100644 index 00000000..47c2e1cf --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +description: Elastic Fleet Server as an Agent managed by the ECK operator +kubeVersion: '>= 1.21.0-0' +name: eck-fleet-server +sources: +- https://github.com/elastic/cloud-on-k8s +- https://github.com/elastic/elastic-agent +- https://github.com/elastic/fleet-server +- https://www.elastic.co/guide/en/fleet/current/fleet-overview.html +type: application +version: 0.17.0 diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/LICENSE b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/LICENSE new file mode 100644 index 00000000..92503a72 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/LICENSE @@ -0,0 +1,93 @@ +Elastic License 2.0 + +URL: https://www.elastic.co/licensing/elastic-license + +## Acceptance + +By using the software, you agree to all of the terms and conditions below. + +## Copyright License + +The licensor grants you a non-exclusive, royalty-free, worldwide, +non-sublicensable, non-transferable license to use, copy, distribute, make +available, and prepare derivative works of the software, in each case subject to +the limitations and conditions below. + +## Limitations + +You may not provide the software to third parties as a hosted or managed +service, where the service provides users with access to any substantial set of +the features or functionality of the software. + +You may not move, change, disable, or circumvent the license key functionality +in the software, and you may not remove or obscure any functionality in the +software that is protected by the license key. + +You may not alter, remove, or obscure any licensing, copyright, or other notices +of the licensor in the software. Any use of the licensor’s trademarks is subject +to applicable law. + +## Patents + +The licensor grants you a license, under any patent claims the licensor can +license, or becomes able to license, to make, have made, use, sell, offer for +sale, import and have imported the software, in each case subject to the +limitations and conditions in this license. This license does not cover any +patent claims that you cause to be infringed by modifications or additions to +the software. If you or your company make any written claim that the software +infringes or contributes to infringement of any patent, your patent license for +the software granted under these terms ends immediately. If your company makes +such a claim, your patent license ends immediately for work on behalf of your +company. + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you +also gets a copy of these terms. + +If you modify the software, you must include in any modified copies of the +software prominent notices stating that you have modified the software. + +## No Other Rights + +These terms do not imply any licenses other than those expressly granted in +these terms. + +## Termination + +If you use the software in violation of these terms, such use is not licensed, +and your licenses will automatically terminate. If the licensor provides you +with a notice of your violation, and you cease all violation of this license no +later than 30 days after you receive that notice, your licenses will be +reinstated retroactively. However, if you violate these terms after such +reinstatement, any additional violation of these terms will cause your licenses +to terminate automatically and permanently. + +## No Liability + +*As far as the law allows, the software comes as is, without any warranty or +condition, and the licensor will not be liable to you for any damages arising +out of these terms or the use or nature of the software, under any kind of +legal claim.* + +## Definitions + +The **licensor** is the entity offering these terms, and the **software** is the +software the licensor makes available under these terms, including any portion +of it. + +**you** refers to the individual or entity agreeing to these terms. + +**your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control over, +are under the control of, or are under common control with that +organization. **control** means ownership of substantially all the assets of an +entity, or the power to direct its management and policies by vote, contract, or +otherwise. Control can be direct or indirect. + +**your licenses** are all the licenses granted to you for the software under +these terms. + +**use** means anything you do with the software requiring one of your licenses. + +**trademark** means trademarks, service marks, and similar rights. \ No newline at end of file diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/examples/fleet-server.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/examples/fleet-server.yaml new file mode 100644 index 00000000..6fd36206 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/examples/fleet-server.yaml @@ -0,0 +1,17 @@ +version: 9.2.0 +deployment: + replicas: 1 + podTemplate: + spec: + serviceAccountName: fleet-server + automountServiceAccountToken: true +elasticsearchRefs: +- name: eck-elasticsearch +kibanaRef: + name: eck-kibana +http: + service: + spec: + type: ClusterIP +serviceAccount: + name: fleet-server diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/templates/NOTES.txt b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/templates/NOTES.txt new file mode 100644 index 00000000..eb3c879d --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/templates/NOTES.txt @@ -0,0 +1,6 @@ + +1. Check Fleet Server status + $ kubectl get agent {{ include "fleet-server.fullname" . }} -n {{ .Release.Namespace }} + +2. Check Fleet Server pod status + $ kubectl get pods --namespace={{ .Release.Namespace }} -l fleet-server.k8s.elastic.co/name={{ include "fleet-server.fullname" . }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/templates/_helpers.tpl b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/templates/_helpers.tpl new file mode 100644 index 00000000..173f5089 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "fleet-server.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "fleet-server.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "fleet-server.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "fleet-server.labels" -}} +helm.sh/chart: {{ include "fleet-server.chart" . }} +{{ include "fleet-server.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.labels }} +{{ toYaml .Values.labels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "fleet-server.selectorLabels" -}} +app.kubernetes.io/name: {{ include "fleet-server.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/templates/cluster-role-binding.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/templates/cluster-role-binding.yaml new file mode 100644 index 00000000..e5fee457 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/templates/cluster-role-binding.yaml @@ -0,0 +1,33 @@ +{{- with .Values.clusterRoleBinding }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .name }} + labels: + {{- include "fleet-server.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or $.Values.annotations .annotations }} + annotations: + {{- with $.Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +{{- with .subjects }} +subjects: +{{- range . }} + - kind: {{ .kind }} + name: {{ .name }} + namespace: {{ .namespace | default $.Release.Namespace | quote }} +{{- end }} +{{- end }} +roleRef: + kind: {{ .roleRef.kind }} + name: {{ .roleRef.name }} + apiGroup: {{ .roleRef.apiGroup }} +{{- end }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/templates/cluster-role.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/templates/cluster-role.yaml new file mode 100644 index 00000000..f067b628 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/templates/cluster-role.yaml @@ -0,0 +1,22 @@ +{{- with .Values.clusterRole }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ .name }} + labels: + {{- include "fleet-server.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or $.Values.annotations .annotations }} + annotations: + {{- with $.Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +rules: {{- toYaml .rules | nindent 2 }} +{{- end }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/templates/fleet-server.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/templates/fleet-server.yaml new file mode 100644 index 00000000..2eb3b0d3 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/templates/fleet-server.yaml @@ -0,0 +1,64 @@ +--- +apiVersion: agent.k8s.elastic.co/v1alpha1 +kind: Agent +metadata: + name: {{ include "fleet-server.fullname" . }} + labels: + {{- include "fleet-server.labels" . | nindent 4 }} + annotations: + eck.k8s.elastic.co/license: basic + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + version: {{ required "A Fleet Server version is required" (or ((.Values.spec).version) (.Values.version)) }} + mode: fleet + fleetServerEnabled: true + {{- if (or (hasKey (.Values.spec) "mode") (hasKey .Values "mode")) }} + {{- fail "mode cannot be changed" }} + {{- end }} + {{- if (or (hasKey (.Values.spec) "fleetServerEnabled") (hasKey .Values "fleetServerEnabled"))}} + {{- fail "fleetServerEnabled cannot be changed" }} + {{- end }} + + {{- $statefulSet := (or (hasKey (.Values.spec) "statefulSet") (hasKey .Values "statefulSet")) }} + {{- $deployment := (or (hasKey (.Values.spec) "deployment") (hasKey .Values "deployment")) }} + {{- if and (not $statefulSet) (not $deployment) }} + {{ fail "At least one of statefulSet or deployment is required" }} + {{- end }} + {{- if $statefulSet }} + {{- $ss := or ((.Values.spec).statefulSet) (.Values.statefulSet) }} + statefulSet: + {{- /* This is required to render the empty statefulSet ( {} ) properly */}} + {{- $ss | default dict | toYaml | nindent 4 }} + {{- end }} + {{- if $deployment }} + {{- $deploy := or ((.Values.spec).deployment) (.Values.deployment) }} + deployment: + {{- /* This is required to render the empty deployment ( {} ) properly */}} + {{- $deploy | default dict | toYaml | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).image) (.Values.image) }} + image: {{ . }} + {{- end }} + {{- with or ((.Values.spec).elasticsearchRefs) (.Values.elasticsearchRefs) }} + elasticsearchRefs: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).kibanaRef) (.Values.kibanaRef) }} + kibanaRef: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).policyID) (.Values.policyID) }} + policyID: {{ . }} + {{- end }} + {{- with or ((.Values.spec).http) (.Values.http) }} + http: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).revisionHistoryLimit) (.Values.revisionHistoryLimit) }} + revisionHistoryLimit: {{ . }} + {{- end }} + {{- with or (((.Values.spec).serviceAccount).name) ((.Values.serviceAccount).name) }} + serviceAccountName: {{ . }} + {{- end }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/templates/service-account.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/templates/service-account.yaml new file mode 100644 index 00000000..0f8901d9 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/templates/service-account.yaml @@ -0,0 +1,22 @@ +{{- with .Values.serviceAccount }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .name }} + namespace: {{ .namespace | default $.Release.Namespace | quote }} + labels: + {{- include "fleet-server.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or $.Values.annotations .annotations }} + annotations: + {{- with $.Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/values.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/values.yaml new file mode 100644 index 00000000..a5c3484c --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-fleet-server/values.yaml @@ -0,0 +1,169 @@ +--- +# Default values for eck-fleet-server. +# This is a YAML-formatted file. + +# Overridable names of the Fleet Server resource. +# By default, this is the Release name set for the chart, +# followed by 'eck-fleet-server'. +# +# nameOverride will override the name of the Chart with the name set here, +# so nameOverride: quickstart, would convert to '{{ Release.name }}-quickstart' +# +# nameOverride: "quickstart" +# +# fullnameOverride will override both the release name, and the chart name, +# and will name the Fleet Server resource exactly as specified. +# +# fullnameOverride: "quickstart" + +# Version of Elastic Fleet Server. +# +version: 9.2.0 + +# Labels that will be applied to Elastic Fleet Server. +# +labels: {} + +# Annotations that will be applied to Elastic Fleet Server. +# +annotations: {} + +# Elastic Fleet Server Agent image to deploy. +# +# image: docker.elastic.co/beats/elastic-agent:9.2.0 + +# ** Deprecation Notice ** +# The previous versions of this Helm Chart simply used the `spec` field here +# and allowed the user to specify any fields below `spec` that were templated directly +# into the final Agent/Fleet Server manifest. This is no longer the preferred way to specify these +# fields and each field that is supported underneath `spec` is now directly specified +# in this values file. Currently both patterns are supported for backwards compatibility +# but we plan to remove the `spec` field in the future. +# spec: {} + +# Referenced resources are below and both elasticsearchRefs and kibanaRef are required for a functional Fleet Server. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-setting-referenced-resources +# +# Reference to ECK-managed Kibana instance. +# This is required for Fleet Server. +# +# kibanaRef: +# name: quickstart + # Optional namespace reference to Kibana instance. + # If not specified, then the namespace of the Fleet Server resource + # will be assumed. + # + # namespace: default + +# Reference to ECK-managed Elasticsearch instance. +# This is required for Fleet Server. +# +elasticsearchRefs: [] +# - name: eck-elasticsearch + # Optional namespace reference to Elasticsearch instance. + # If not specified, then the namespace of the Fleet Server resource + # will be assumed. + # + # namespace: default + # + # Optional secretName referencing an existing Kubernetes secret that contains connection information + # for associating a Fleet Server instance to a remote Elasticsearch instance not managed by ECK. + # The referenced secret must contain the following: + # - `url`: the URL to reach the Elastic resource + # - `username`: the username of the user to be authenticated to the Elastic resource + # - `password`: the password of the user to be authenticated to the Elastic resource + # - `ca.crt`: the CA certificate in PEM format (optional) + # - `api-key`: the key to authenticate against the Elastic resource instead of a username and password + # This field cannot be used in combination with the other fields name, namespace or serviceName. + # + # secretName: my-remote-es-credentials + +# policyID determines into which Agent Policy this Fleet Server will be enrolled. +policyID: eck-fleet-server + +# The HTTP layer configuration for the Fleet Server Service. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-customize-fleet-server-service +# +# http: + +# Deployment or StatefulSet specification for Fleet Server. +# At least one is required of [deployment, statefulSet]. +# No default is currently set, refer to https://github.com/elastic/cloud-on-k8s/issues/7429. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-chose-the-deployment-model +# +# deployment: +# replicas: 1 +# podTemplate: +# spec: +# serviceAccountName: fleet-server +# automountServiceAccountToken: true +# +# statefulSet: +# podTemplate: +# spec: +# serviceAccountName: fleet-server +# automountServiceAccountToken: true + +# Number of revisions to retain to allow rollback in the underlying Deployment. +# If not set Kubernetes sets this to 10 by default. +# +# revisionHistoryLimit: 2 + +# ServiceAccount to be used by Elastic Fleet Server. Some Fleet Server features (such as autodiscover or Kubernetes module metricsets) +# require that Fleet Server Pods interact with Kubernetes APIs. This functionality requires specific permissions +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-role-based-access-control +# +serviceAccount: + name: fleet-server + # namespace: optional-namespace + +# ClusterRoleBinding to be used by Elastic Fleet Server. Similar to ServiceAccount, this is required in some scenarios. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-role-based-access-control +# +clusterRoleBinding: + name: fleet-server + subjects: + - kind: ServiceAccount + name: fleet-server + # namespace: default + roleRef: + kind: ClusterRole + name: fleet-server + apiGroup: rbac.authorization.k8s.io + +# ClusterRole to be used by Elastic Fleet Server. Similar to ServiceAccount, this is required in some scenarios. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-elastic-agent-fleet-configuration.html#k8s-elastic-agent-fleet-configuration-role-based-access-control +# +clusterRole: + name: fleet-server + rules: + - apiGroups: [""] + resources: + - pods + - namespaces + - nodes + verbs: + - get + - watch + - list + - apiGroups: ["apps"] + resources: + - replicasets + verbs: + - get + - watch + - list + - apiGroups: ["batch"] + resources: + - jobs + verbs: + - get + - watch + - list + - apiGroups: ["coordination.k8s.io"] + resources: + - leases + verbs: + - get + - create + - update diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/.helmignore b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/.helmignore new file mode 100644 index 00000000..f1568daf --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/Chart.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/Chart.yaml new file mode 100644 index 00000000..a49729cf --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/Chart.yaml @@ -0,0 +1,10 @@ +apiVersion: v2 +description: Kibana managed by the ECK operator +icon: https://helm.elastic.co/icons/kibana.png +kubeVersion: '>= 1.21.0-0' +name: eck-kibana +sources: +- https://github.com/elastic/cloud-on-k8s +- https://github.com/elastic/kibana +type: application +version: 0.17.0 diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/LICENSE b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/LICENSE new file mode 100644 index 00000000..92503a72 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/LICENSE @@ -0,0 +1,93 @@ +Elastic License 2.0 + +URL: https://www.elastic.co/licensing/elastic-license + +## Acceptance + +By using the software, you agree to all of the terms and conditions below. + +## Copyright License + +The licensor grants you a non-exclusive, royalty-free, worldwide, +non-sublicensable, non-transferable license to use, copy, distribute, make +available, and prepare derivative works of the software, in each case subject to +the limitations and conditions below. + +## Limitations + +You may not provide the software to third parties as a hosted or managed +service, where the service provides users with access to any substantial set of +the features or functionality of the software. + +You may not move, change, disable, or circumvent the license key functionality +in the software, and you may not remove or obscure any functionality in the +software that is protected by the license key. + +You may not alter, remove, or obscure any licensing, copyright, or other notices +of the licensor in the software. Any use of the licensor’s trademarks is subject +to applicable law. + +## Patents + +The licensor grants you a license, under any patent claims the licensor can +license, or becomes able to license, to make, have made, use, sell, offer for +sale, import and have imported the software, in each case subject to the +limitations and conditions in this license. This license does not cover any +patent claims that you cause to be infringed by modifications or additions to +the software. If you or your company make any written claim that the software +infringes or contributes to infringement of any patent, your patent license for +the software granted under these terms ends immediately. If your company makes +such a claim, your patent license ends immediately for work on behalf of your +company. + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you +also gets a copy of these terms. + +If you modify the software, you must include in any modified copies of the +software prominent notices stating that you have modified the software. + +## No Other Rights + +These terms do not imply any licenses other than those expressly granted in +these terms. + +## Termination + +If you use the software in violation of these terms, such use is not licensed, +and your licenses will automatically terminate. If the licensor provides you +with a notice of your violation, and you cease all violation of this license no +later than 30 days after you receive that notice, your licenses will be +reinstated retroactively. However, if you violate these terms after such +reinstatement, any additional violation of these terms will cause your licenses +to terminate automatically and permanently. + +## No Liability + +*As far as the law allows, the software comes as is, without any warranty or +condition, and the licensor will not be liable to you for any damages arising +out of these terms or the use or nature of the software, under any kind of +legal claim.* + +## Definitions + +The **licensor** is the entity offering these terms, and the **software** is the +software the licensor makes available under these terms, including any portion +of it. + +**you** refers to the individual or entity agreeing to these terms. + +**your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control over, +are under the control of, or are under common control with that +organization. **control** means ownership of substantially all the assets of an +entity, or the power to direct its management and policies by vote, contract, or +otherwise. Control can be direct or indirect. + +**your licenses** are all the licenses granted to you for the software under +these terms. + +**use** means anything you do with the software requiring one of your licenses. + +**trademark** means trademarks, service marks, and similar rights. \ No newline at end of file diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/examples/http-configuration.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/examples/http-configuration.yaml new file mode 100644 index 00000000..d71207e8 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/examples/http-configuration.yaml @@ -0,0 +1,36 @@ +--- +# Version of Kibana. +# +version: 9.2.0 + +# Labels that will be applied to Kibana. +# +labels: {} + # key: value + +# Annotations that will be applied to Kibana. +# +annotations: {} + # key: value + +# Count of Kibana replicas to create. +# +count: 1 + +# Reference to ECK-managed Elasticsearch resource, ideally from {{ "elasticsearch.fullname" }} +# +elasticsearchRef: + name: eck-elasticsearch + # namespace: default +http: + service: + spec: + # Type of service to deploy for Kibana. + # This deploys a load balancer in a cloud service provider, where supported. + # + type: LoadBalancer + # tls: + # selfSignedCertificate: + # subjectAltNames: + # - ip: 1.2.3.4 + # - dns: kibana.example.com diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-aks.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-aks.yaml new file mode 100644 index 00000000..b7363dd0 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-aks.yaml @@ -0,0 +1,28 @@ +# The following is an example of a Kibana resource that is configured to use an Ingress resource in an AKS cluster. +# + +# Name of the Kibana instance. +# +fullnameOverride: kibana + +# Reference to ECK-managed Elasticsearch instance, ideally from {{ "elasticsearch.fullname" }} +# +elasticsearchRef: + name: elasticsearch +config: + server: + publicBaseUrl: "https://kibana.company.dev" + +ingress: + enabled: true + className: webapprouting.kubernetes.azure.com + annotations: + # This is required for AKS Loadbalancing to understand that it's communicating with + # an HTTPS backend. + nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" + labels: + my: label + pathType: Prefix + hosts: + - host: "kibana.company.dev" + path: "/" diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-eks.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-eks.yaml new file mode 100644 index 00000000..c5f2f43b --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-eks.yaml @@ -0,0 +1,48 @@ +# The following is an example of a Kibana resource that is configured to use an Ingress resource in an EKS cluster. +# + +# Name of the Kibana instance. +# +fullnameOverride: kibana + +# Reference to ECK-managed Elasticsearch instance, ideally from {{ "elasticsearch.fullname" }} +# +elasticsearchRef: + name: elasticsearch +config: + server: + publicBaseUrl: "https://kibana.company.dev" + +ingress: + enabled: true + className: alb + annotations: + alb.ingress.kubernetes.io/scheme: "internet-facing" + alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]' + alb.ingress.kubernetes.io/backend-protocol: "HTTPS" + alb.ingress.kubernetes.io/target-type: "ip" + # To use an ALB with ECK, you must provide a valid ACM certificate ARN or use certificate discovery. + # There are 2 options for EKS: + # 1. Create a valid ACM certificate, and uncomment the following annotation and update it to the correct ARN. + # 2. Create a valid ACM certificate and ensure that the hosts[0].host matches the certificate's Common Name (CN) and + # certificate discovery *should* find the certificate automatically and use it. + # + # ref: https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.8/guide/ingress/cert_discovery/ + # + # alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:us-east-1:00000000000:certificate/b65be571-8220-4f2e-8cb1-94194535d877" + labels: + my: label + pathType: Prefix + hosts: + - host: "kibana.company.dev" + path: "/" +nodeSets: +- name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-gke.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-gke.yaml new file mode 100644 index 00000000..61427581 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/examples/ingress/kibana-gke.yaml @@ -0,0 +1,31 @@ +# The following is an example of a Kibana resource that is configured to use an Ingress resource in a GKE cluster. +# + +# Name of the Kibana instance. +# +fullnameOverride: kibana + +# Reference to ECK-managed Elasticsearch instance, ideally from {{ "elasticsearch.fullname" }} +# +elasticsearchRef: + name: elasticsearch +config: + server: + publicBaseUrl: "https://kibana.company.dev" +http: + service: + metadata: + annotations: + # This is required for `ClusterIP` services (which are the default ECK service type) to be used with Ingress in GKE clusters. + cloud.google.com/neg: '{"ingress": true}' + # This is required to enable the GKE Ingress Controller to use HTTPS as the backend protocol. + cloud.google.com/app-protocols: '{"https":"HTTPS"}' + +ingress: + enabled: true + pathType: Prefix + hosts: + - host: "kibana.company.dev" + path: "/" + tls: + enabled: true diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/templates/NOTES.txt b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/templates/NOTES.txt new file mode 100644 index 00000000..9652161c --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/templates/NOTES.txt @@ -0,0 +1,6 @@ + +1. Check Kibana status + $ kubectl get kibana {{ include "kibana.fullname" . }} -n {{ .Release.Namespace }} + +2. Check Kibana pod status + $ kubectl get pods --namespace={{ .Release.Namespace }} -l kibana.k8s.elastic.co/name={{ include "kibana.fullname" . }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/templates/_helpers.tpl b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/templates/_helpers.tpl new file mode 100644 index 00000000..eba5497d --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "kibana.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "kibana.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "kibana.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "kibana.labels" -}} +helm.sh/chart: {{ include "kibana.chart" . }} +{{ include "kibana.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.labels }} +{{ toYaml .Values.labels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "kibana.selectorLabels" -}} +app.kubernetes.io/name: {{ include "kibana.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/templates/ingress.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/templates/ingress.yaml new file mode 100644 index 00000000..171463c0 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/templates/ingress.yaml @@ -0,0 +1,48 @@ +{{- if .Values.ingress.enabled -}} +{{- $pathType := .Values.ingress.pathType | default "Prefix" -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "kibana.fullname" . }} + labels: + {{- include "kibana.labels" . | nindent 4 }} + {{- with .Values.ingress.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.ingress.annotations }} + annotations: + {{- with .Values.ingress.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +spec: + {{- if .Values.ingress.className }} + ingressClassName: {{ .Values.ingress.className | quote }} + {{- end }} + {{- if .Values.ingress.tls.enabled }} + tls: + - hosts: + {{- range .Values.ingress.hosts }} + - {{ .host | quote }} + {{- end }} + {{- if .Values.ingress.tls.secretName }} + secretName: {{ .Values.ingress.tls.secretName }} + {{- else }} + secretName: {{ include "kibana.fullname" . }}-kb-http-certs-internal + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + {{- $hostPath := .path | default "/" }} + - host: {{ .host | quote }} + http: + paths: + - path: {{ $hostPath }} + pathType: {{ $pathType }} + backend: + service: + name: {{ include "kibana.fullname" $ }}-kb-http + port: + number: 5601 + {{- end }} +{{ end }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/templates/kibana.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/templates/kibana.yaml new file mode 100644 index 00000000..0d925001 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/templates/kibana.yaml @@ -0,0 +1,61 @@ +--- +apiVersion: kibana.k8s.elastic.co/v1 +kind: Kibana +metadata: + name: {{ include "kibana.fullname" . }} + labels: + {{- include "kibana.labels" . | nindent 4 }} + annotations: + eck.k8s.elastic.co/license: basic + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + version: {{ required "A Kibana version is required" .Values.version }} + {{- /* + The following templates with 'or' are to allow both .spec.field and .field to be set for backwards + compatibility purposes. See https://github.com/elastic/cloud-on-k8s/pull/8192 for details. + */ -}} + {{- with or ((.Values.spec).image) (.Values.image) }} + image: {{ . }} + {{- end }} + {{- with or ((.Values.spec).count) (.Values.count) }} + count: {{ . }} + {{- end }} + {{- $esRef := or ((.Values.spec).elasticsearchRef) (.Values.elasticsearchRef) }} +{{- if not (or ($esRef).name ($esRef).secretName) }} + {{ fail "An elasticsearchRef name or secretName is required" }} + {{- end }} + elasticsearchRef: + {{- toYaml $esRef | nindent 4 }} + {{- $entsearchRef := or ((.Values.spec).enterpriseSearchRef) (.Values.enterpriseSearchRef) }} + {{- if $entsearchRef }} + enterpriseSearchRef: + {{- toYaml $entsearchRef | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).config) (.Values.config) }} + config: + {{ toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).http) (.Values.http) }} + http: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).podTemplate) (.Values.podTemplate) }} + podTemplate: + {{ toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).revisionHistoryLimit) (.Values.revisionHistoryLimit) }} + revisionHistoryLimit: {{ . }} + {{- end }} + {{- with or ((.Values.spec).secureSettings) (.Values.secureSettings) }} + secureSettings: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with or ((.Values.spec).serviceAccountName) (.Values.serviceAccountName) }} + serviceAccountName: {{ . }} + {{- end }} + {{- with or ((.Values.spec).monitoring) (.Values.monitoring) }} + monitoring: + {{- toYaml . | nindent 4 }} + {{- end }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/values.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/values.yaml new file mode 100644 index 00000000..932b2a4a --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-kibana/values.yaml @@ -0,0 +1,190 @@ +--- +# Default values for eck-kibana. +# This is a YAML-formatted file. + +# Overridable names of the Kibana resource. +# By default, this is the Release name set for the chart, +# followed by 'eck-kibana'. +# +# nameOverride will override the name of the Chart with the name set here, +# so nameOverride: quickstart, would convert to '{{ Release.name }}-quickstart' +# +# nameOverride: "quickstart" +# +# fullnameOverride will override both the release name, and the chart name, +# and will name the Kibana resource exactly as specified. +# +# fullnameOverride: "quickstart" + +# Version of Kibana. +# +version: 9.2.0 + +# Kibana Docker image to deploy +# +# image: docker.elastic.co/kibana/kibana:9.2.0 + +# Labels that will be applied to Kibana. +# +labels: {} + +# Annotations that will be applied to Kibana. +# +annotations: {} + +# ** Deprecation Notice ** +# The previous versions of this Helm Chart simply used the `spec` field here +# and allowed the user to specify any fields below spec that were templated directly +# into the final Kibana manifest. This is no long the preferred way to specify these +# fields and each field that is supported underneath `spec` is now directly specified +# in this values file. Currently both patterns are supported for backwards compatibility +# but we plan to remove the `spec` field in the future. +# spec: {} + +# Count of Kibana replicas to create. +# +count: 1 + +# Reference to ECK-managed Elasticsearch resource. +# +elasticsearchRef: {} + # name: eck-elasticsearch + # Optional namespace reference to Elasticsearch resource. + # If not specified, then the namespace of the Kibana resource + # will be assumed. + # + # namespace: default + # + # Optional secretName referencing an existing Kubernetes secret that contains connection information + # for associating a Kibana instance to a remote Elasticsearch instance not managed by ECK. + # The referenced secret must contain the following: + # - `url`: the URL to reach the Elastic resource + # - `username`: the username of the user to be authenticated to the Elastic resource + # - `password`: the password of the user to be authenticated to the Elastic resource + # - `ca.crt`: the CA certificate in PEM format (optional) + # This field cannot be used in combination with the other fields name, namespace or serviceName. + # + # secretName: my-remote-es-credentials + +# Reference to an EnterpriseSearch running in the same Kubernetes cluster +# +# enterpriseSearchRef: + +# The Kibana configuration (kibana.yml) +# ref: https://www.elastic.co/guide/en/kibana/current/settings.html +# +config: null + +# The HTTP layer configuration for Kibana. +# +# http: + +# PodTemplate provides customisation options (labels, annotations, affinity rules, +# resource requests, and so on) for the Kibana pods +# +# podTemplate: + +# Number of revisions to retain to allow rollback in the underlying deployment. +# By default, if not set, Kubernetes sets 10. +# +# revisionHistoryLimit: 2 + +# Control Kibana Secure Settings. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-kibana-secure-settings.html +# +secureSettings: [] + +# Used to check access from the current resource to a resource (for ex. Elasticsearch) in a different namespace. +# Can only be used if ECK is enforcing RBAC on references. +# +# serviceAccountName: "" + +# Settings for configuring stack monitoring. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-stack-monitoring.html +# +monitoring: {} + # metrics: + # elasticsearchRefs: + # - name: monitoring + # namespace: observability + # logs: + # elasticsearchRefs: + # - name: monitoring + # namespace: observability + +# Settings for controlling Kibana ingress. Enabling ingress will expose your Kibana instance +# to the public internet, and as such is disabled by default. +# +# *NOTE* when configuring Kibana Ingress, ensure that `config.server.publicBaseUrl` setting for +# Kibana is also set, as it is required when exposing Kibana behind a load balancer/ingress. +# Also of note are `server.basePath`, and `server.rewriteBasePath` settings in the Kibana configuration. +# +# ref: https://www.elastic.co/guide/en/kibana/current/settings.html +# +# Each Cloud Service Provider has different requirements for setting up Ingress. Some links to common documentation are: +# - AWS: https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html +# - GCP: https://cloud.google.com/kubernetes-engine/docs/concepts/ingress +# - Azure: https://learn.microsoft.com/en-us/azure/aks/app-routing +# - Nginx: https://kubernetes.github.io/ingress-nginx/ +# +ingress: + enabled: false + + # Annotations that will be applied to the Ingress resource. Note that some ingress controllers are controlled via annotations. + # + # Nginx Annotations: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/ + # + # Common annotations: + # kubernetes.io/ingress.class: gce # Configures the Ingress resource to use the GCE ingress controller and create an external Application Load Balancer. + # kubernetes.io/ingress.class: gce-internal # Configures the Ingress resource to use the GCE ingress controller and create an internal Application Load Balancer. + # kubernetes.io/ingress.class: nginx # Configures the Ingress resource to use the NGINX ingress controller. + # + annotations: {} + + # Labels that will be applied to the Ingress resource. + # + labels: {} + + # Some ingress controllers require the use of a specific class name to route traffic to the correct controller, notably AKS and EKS, which + # replaces the use of the 'kubernetes.io/ingress.class' annotation. + # + # className: webapprouting.kubernetes.azure.com | alb + + # Ingress paths are required to have a corresponding path type. Defaults to 'Prefix'. + # + # There are 3 supported path types: + # - ImplementationSpecific + # - Prefix + # - Exact + # + # ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#path-types + # + pathType: Prefix + + # Hosts are a list of hosts included in the Ingress definition, with a corresponding path at which the Kibana service + # will be exposed. Each host in the list should be a fully qualified DNS name that will resolve to the exposed Ingress object. + # + # ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#name-based-virtual-hosting + # + hosts: + - host: chart-example.local + path: / + + # TLS defines whether TLS will be enabled on the Ingress resource. + # + # *NOTE* Many Cloud Service Providers handle TLS in a custom manner, and as such, it is recommended to consult their documentation. + # Notably GKE and Nginx Ingress Controllers seems to respect the Ingress TLS settings, AKS and EKS ignore it. + # + # - AKS: https://learn.microsoft.com/en-us/azure/aks/app-routing-dns-ssl + # - GKE: https://cloud.google.com/kubernetes-engine/docs/concepts/ingress#options_for_providing_ssl_certificates + # - EKS: https://aws.amazon.com/blogs/containers/serve-distinct-domains-with-tls-powered-by-acm-on-amazon-eks/ + # - Nginx: https://kubernetes.github.io/ingress-nginx/user-guide/tls/ + # + # Kubernetes ingress TLS documentation: + # ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#tls + # + tls: + enabled: false + # Optional Kubernetes secret name that contains a base64 encoded PEM certificate and private key that corresponds to the above 'hosts' definitions. + # If tls is enabled, but this field is not set, the self-signed certificate and key created by the ECK operator will be used. + # secretName: chart-example-tls diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/.helmignore b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/.helmignore new file mode 100644 index 00000000..f1568daf --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +templates/tests diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/Chart.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/Chart.yaml new file mode 100644 index 00000000..089f98c0 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/Chart.yaml @@ -0,0 +1,10 @@ +apiVersion: v2 +description: Logstash managed by the ECK operator +icon: https://helm.elastic.co/icons/logstash.png +kubeVersion: '>= 1.21.0-0' +name: eck-logstash +sources: +- https://github.com/elastic/cloud-on-k8s +- https://github.com/elastic/logstash +type: application +version: 0.17.0 diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/LICENSE b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/LICENSE new file mode 100644 index 00000000..92503a72 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/LICENSE @@ -0,0 +1,93 @@ +Elastic License 2.0 + +URL: https://www.elastic.co/licensing/elastic-license + +## Acceptance + +By using the software, you agree to all of the terms and conditions below. + +## Copyright License + +The licensor grants you a non-exclusive, royalty-free, worldwide, +non-sublicensable, non-transferable license to use, copy, distribute, make +available, and prepare derivative works of the software, in each case subject to +the limitations and conditions below. + +## Limitations + +You may not provide the software to third parties as a hosted or managed +service, where the service provides users with access to any substantial set of +the features or functionality of the software. + +You may not move, change, disable, or circumvent the license key functionality +in the software, and you may not remove or obscure any functionality in the +software that is protected by the license key. + +You may not alter, remove, or obscure any licensing, copyright, or other notices +of the licensor in the software. Any use of the licensor’s trademarks is subject +to applicable law. + +## Patents + +The licensor grants you a license, under any patent claims the licensor can +license, or becomes able to license, to make, have made, use, sell, offer for +sale, import and have imported the software, in each case subject to the +limitations and conditions in this license. This license does not cover any +patent claims that you cause to be infringed by modifications or additions to +the software. If you or your company make any written claim that the software +infringes or contributes to infringement of any patent, your patent license for +the software granted under these terms ends immediately. If your company makes +such a claim, your patent license ends immediately for work on behalf of your +company. + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you +also gets a copy of these terms. + +If you modify the software, you must include in any modified copies of the +software prominent notices stating that you have modified the software. + +## No Other Rights + +These terms do not imply any licenses other than those expressly granted in +these terms. + +## Termination + +If you use the software in violation of these terms, such use is not licensed, +and your licenses will automatically terminate. If the licensor provides you +with a notice of your violation, and you cease all violation of this license no +later than 30 days after you receive that notice, your licenses will be +reinstated retroactively. However, if you violate these terms after such +reinstatement, any additional violation of these terms will cause your licenses +to terminate automatically and permanently. + +## No Liability + +*As far as the law allows, the software comes as is, without any warranty or +condition, and the licensor will not be liable to you for any damages arising +out of these terms or the use or nature of the software, under any kind of +legal claim.* + +## Definitions + +The **licensor** is the entity offering these terms, and the **software** is the +software the licensor makes available under these terms, including any portion +of it. + +**you** refers to the individual or entity agreeing to these terms. + +**your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control over, +are under the control of, or are under common control with that +organization. **control** means ownership of substantially all the assets of an +entity, or the power to direct its management and policies by vote, contract, or +otherwise. Control can be direct or indirect. + +**your licenses** are all the licenses granted to you for the software under +these terms. + +**use** means anything you do with the software requiring one of your licenses. + +**trademark** means trademarks, service marks, and similar rights. \ No newline at end of file diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/examples/basic-eck.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/examples/basic-eck.yaml new file mode 100644 index 00000000..644a44b1 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/examples/basic-eck.yaml @@ -0,0 +1,44 @@ +--- +# values corresponding to config/recipes/logstash/logstash-eck.yaml +version: 9.2.0 + +elasticsearchRefs: + - clusterName: eck + name: elasticsearch + +pipelines: + - pipeline.id: main + config.string: | + input { + beats { + port => 5044 + } + } + filter { + grok { + match => { "message" => "%{HTTPD_COMMONLOG}"} + } + geoip { + source => "[source][address]" + target => "[source]" + } + } + output { + elasticsearch { + hosts => [ "${ECK_ES_HOSTS}" ] + user => "${ECK_ES_USER}" + password => "${ECK_ES_PASSWORD}" + ssl_certificate_authorities => "${ECK_ES_SSL_CERTIFICATE_AUTHORITY}" + } + } + +services: + - name: beats + service: + spec: + type: ClusterIP + ports: + - port: 5044 + name: "filebeat" + protocol: TCP + targetPort: 5044 diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/examples/es-role.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/examples/es-role.yaml new file mode 100644 index 00000000..5f1ddb15 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/examples/es-role.yaml @@ -0,0 +1,25 @@ +--- +# values corresponding to config/recipes/logstash/logstash-es-role.yaml +version: 9.2.0 + +elasticsearchRefs: + - clusterName: eck + name: elasticsearch + +pipelines: + - pipeline.id: main + config.string: | + input { exec { command => "uptime" interval => 10 } } + output { + elasticsearch { + hosts => [ "${ECK_ES_HOSTS}" ] + ssl_enabled => true + ssl_certificate_authorities => "${ECK_ES_SSL_CERTIFICATE_AUTHORITY}" + user => "${ECK_ES_USER}" + password => "${ECK_ES_PASSWORD}" + index => "my-index" + data_stream => false + ilm_enabled => false + manage_template => false + } + } diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/examples/monitored.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/examples/monitored.yaml new file mode 100644 index 00000000..24508ea7 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/examples/monitored.yaml @@ -0,0 +1,49 @@ +--- +# values corresponding to config/recipes/logstash/logstash-monitored.yaml +version: 9.2.0 + +monitoring: + metrics: + elasticsearchRefs: + - name: elasticsearch-monitoring + +pipelines: + - pipeline.id: main + config.string: | + input { + beats { + port => 5044 + } + } + filter { + grok { + match => { "message" => "%{HTTPD_COMMONLOG}"} + } + geoip { + source => "[source][address]" + target => "[source]" + } + } + output { + elasticsearch { + hosts => [ "${ECK_ES_HOSTS}" ] + user => "${ECK_ES_USER}" + password => "${ECK_ES_PASSWORD}" + ssl_certificate_authorities => "${ECK_ES_SSL_CERTIFICATE_AUTHORITY}" + } + } + +elasticsearchRefs: + - clusterName: eck + name: elasticsearch + +services: + - name: beats + service: + spec: + type: ClusterIP + ports: + - port: 5044 + name: "filebeat" + protocol: TCP + targetPort: 5044 diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/examples/multi.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/examples/multi.yaml new file mode 100644 index 00000000..12036d92 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/examples/multi.yaml @@ -0,0 +1,78 @@ +--- +# values corresponding to config/recipes/logstash/logstash-multi.yaml +version: 9.2.0 + +pipelines: + - pipeline.id: main + config.string: | + input { + beats { + port => 5044 + } + } + filter { + grok { + match => { "message" => "%{HTTPD_COMMONLOG}"} + } + geoip { + source => "[source][address]" + target => "[source]" + } + } + output { + pipeline { + send_to => 'prod' + } + pipeline { + send_to => 'qa' + } + } + - pipeline.id: production + config.string: | + input { + pipeline { + address => 'prod' + } + } + output { + elasticsearch { + hosts => [ "${PROD_ES_ES_HOSTS}" ] + user => "${PROD_ES_ES_USER}" + password => "${PROD_ES_ES_PASSWORD}" + ssl_certificate_authorities => "${PROD_ES_ES_SSL_CERTIFICATE_AUTHORITY}" + } + } + - pipeline.id: qa + config.string: | + input { + pipeline { + address => 'qa' + } + } + output { + elasticsearch { + hosts => [ "${QA_ES_ES_HOSTS}" ] + user => "${QA_ES_ES_USER}" + password => "${QA_ES_ES_PASSWORD}" + ssl_certificate_authorities => "${QA_ES_ES_SSL_CERTIFICATE_AUTHORITY}" + } + } + +elasticsearchRefs: + - clusterName: prod-es + name: production + - clusterName: qa-es + name: qa + namespace: qa + +services: + - name: beats + service: + spec: + type: ClusterIP + ports: + - port: 5044 + name: "filebeat" + protocol: TCP + targetPort: 5044 + diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/examples/volumes.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/examples/volumes.yaml new file mode 100644 index 00000000..67cfd133 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/examples/volumes.yaml @@ -0,0 +1,107 @@ +--- +# values corresponding to config/recipes/logstash/logstash-volumes.yaml +version: 9.2.0 + +config: + log.level: info + queue.type: persisted + path.queue: /usr/share/logstash/pq + +podTemplate: + spec: + containers: + - name: logstash + volumeMounts: + - mountPath: /usr/share/logstash/pq + name: pq + readOnly: false + - mountPath: /usr/share/logstash/dlq + name: dlq + readOnly: false + +pipelines: + - pipeline.id: dlq_read + dead_letter_queue.enable: false + config.string: | + input { + dead_letter_queue { + path => "/usr/share/logstash/dlq" + commit_offsets => true + pipeline_id => "beats" + clean_consumed => true + } + } + filter { + mutate { + remove_field => "[geoip][location]" + } + } + output { + elasticsearch { + hosts => [ "${ECK_ES_HOSTS}" ] + user => "${ECK_ES_USER}" + password => "${ECK_ES_PASSWORD}" + ssl_certificate_authorities => "${ECK_ES_SSL_CERTIFICATE_AUTHORITY}" + } + } + - pipeline.id: beats + dead_letter_queue.enable: true + path.dead_letter_queue: /usr/share/logstash/dlq + config.string: | + input { + beats { + port => 5044 + } + } + filter { + grok { + match => { "message" => "%{HTTPD_COMMONLOG}"} + } + geoip { + source => "[source][address]" + target => "[source]" + } + } + output { + elasticsearch { + hosts => [ "${ECK_ES_HOSTS}" ] + user => "${ECK_ES_USER}" + password => "${ECK_ES_PASSWORD}" + ssl_certificate_authorities => "${ECK_ES_SSL_CERTIFICATE_AUTHORITY}" + } + } + +volumeClaimTemplates: + - metadata: + name: pq + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + - metadata: + name: dlq + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi + + +elasticsearchRefs: + - clusterName: eck + name: elasticsearch + +services: + - name: beats + service: + spec: + type: ClusterIP + ports: + - port: 5044 + name: "filebeat" + protocol: TCP + targetPort: 5044 + diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/templates/NOTES.txt b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/templates/NOTES.txt new file mode 100644 index 00000000..c2f255af --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/templates/NOTES.txt @@ -0,0 +1,6 @@ + +1. Check Logstash status + $ kubectl get logstash {{ include "logstash.fullname" . }} -n {{ .Release.Namespace }} + +2. Check Logstash pod status + $ kubectl get pods --namespace={{ .Release.Namespace }} -l logstash.k8s.elastic.co/name={{ include "logstash.fullname" . }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/templates/_helpers.tpl b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/templates/_helpers.tpl new file mode 100644 index 00000000..7efd669f --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "logstash.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "logstash.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "logstash.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "logstash.labels" -}} +helm.sh/chart: {{ include "logstash.chart" . }} +{{ include "logstash.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.labels }} +{{ toYaml .Values.labels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "logstash.selectorLabels" -}} +app.kubernetes.io/name: {{ include "logstash.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/templates/logstash.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/templates/logstash.yaml new file mode 100644 index 00000000..8ba52ef6 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/templates/logstash.yaml @@ -0,0 +1,58 @@ +--- +apiVersion: logstash.k8s.elastic.co/v1alpha1 +kind: Logstash +metadata: + name: {{ include "logstash.fullname" . }} + labels: + {{- include "logstash.labels" . | nindent 4 }} + annotations: + eck.k8s.elastic.co/license: basic + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + version: {{ required "A Logstash version is required" .Values.version }} + count: {{ required "A pod count is required" .Values.count }} + {{- with .Values.image }} + image: {{ . }} + {{- end }} + {{- with .Values.serviceAccountName }} + serviceAccountName: {{ . }} + {{- end }} + {{- with .Values.revisionHistoryLimit }} + revisionHistoryLimit: {{ . }} + {{- end }} + + {{- if and .Values.config .Values.configRef }} + {{- fail "config and configRef are mutually exclusive!" }} + {{- end }} + {{- with .Values.config }} + config: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.configRef }} + configRef: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.podTemplate }} + podTemplate: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.monitoring }} + monitoring: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if and .Values.pipelines .Values.pipelinesRef }} + {{- fail "pipelines and pipelinesRef are mutually exclusive!" }} + {{- end }} + {{- with .Values.pipelinesRef }} + pipelinesRef: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.pipelines }} + pipelines: {{ toYaml .Values.pipelines | nindent 4 }} + {{- end }} + volumeClaimTemplates: {{ toYaml .Values.volumeClaimTemplates | nindent 4 }} + elasticsearchRefs: {{ toYaml .Values.elasticsearchRefs | nindent 4 }} + services: {{ toYaml .Values.services | nindent 4 }} + secureSettings: {{ toYaml .Values.secureSettings | nindent 4 }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/values.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/values.yaml new file mode 100644 index 00000000..f82ad0a5 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/charts/eck-logstash/values.yaml @@ -0,0 +1,115 @@ +--- +# Default values for eck-logstash. +# This is a YAML-formatted file. + +# Overridable names of the Logstash resource. +# By default, this is the Release name set for the chart, +# followed by 'eck-logstash'. +# +# nameOverride will override the name of the Chart with the name set here, +# so nameOverride: quickstart, would convert to '{{ Release.name }}-quickstart' +# +# nameOverride: "quickstart" +# +# fullnameOverride will override both the release name, and the chart name, +# and will name the Logstash resource exactly as specified. +# +# fullnameOverride: "quickstart" + +# Version of Logstash. +# +version: 9.2.0 + +# Logstash Docker image to deploy +# +# image: + +# Used to check access from the current resource to a resource (for ex. a remote Elasticsearch cluster) in a different namespace. +# Can only be used if ECK is enforcing RBAC on references. +# +# serviceAccountName: "" + +# Labels that will be applied to Logstash. +# +labels: {} + +# Annotations that will be applied to Logstash. +# +annotations: {} + +# Number of revisions to retain to allow rollback in the underlying StatefulSets. +# By default, if not set, Kubernetes sets 10. +# +# revisionHistoryLimit: 2 + +# Controlling the number of pods. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-logstash-scaling-logstash.html +# +count: 1 + +# The logstash configuration, the ECK equivalent to logstash.yml +# +# NOTE: The `config` and `configRef` fields are mutually exclusive. Only one of them should be defined at a time, +# as using both may cause conflicts. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-logstash-configuration.html#k8s-logstash-configuring-logstash +# +config: {} + +# Reference a configuration in a Secret. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-logstash-configuration.html#k8s-logstash-configuring-logstash +# +# configRef: +# secretName: '' + +# Set podTemplate to customize the pod used by Logstash +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-customize-pods.html +# +podTemplate: {} + +# Settings for configuring stack monitoring. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-stack-monitoring.html +# +monitoring: {} + # metrics: + # elasticsearchRefs: + # - name: monitoring + # namespace: observability + # logs: + # elasticsearchRefs: + # - name: monitoring + # namespace: observability + +# The Logstash pipelines, the ECK equivalent to pipelines.yml +# +# NOTE: The `pipelines` and `pipelinesRef` fields are mutually exclusive. Only one of them should be defined at a time, +# as using both may cause conflicts. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-logstash-configuration.html#k8s-logstash-pipelines +# +pipelines: [] + +# Reference a pipelines configuration in a Secret. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-logstash-configuration.html#k8s-logstash-pipelines +# +# pipelinesRef: +# secretName: '' + +# volumeClaimTemplates +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-logstash-configuration.html#k8s-volume-claim-settings +# +volumeClaimTemplates: [] + +# ElasticsearchRefs are references to Elasticsearch clusters running in the same Kubernetes cluster. +# Ensure that the 'clusterName' field matches what is referenced in the pipeline. +# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-logstash-configuration.html#k8s-logstash-pipelines-es +# +elasticsearchRefs: [] +# - namespace: '' +# name: '' +# clusterName: '' +# serviceName: '' +# secretName: '' + +services: [] + +# SecureSettings is a list of references to Kubernetes Secrets containing sensitive configuration options for the Logstash +secureSettings: [] diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/examples/agent/fleet-agents.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/examples/agent/fleet-agents.yaml new file mode 100644 index 00000000..4358b6f6 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/examples/agent/fleet-agents.yaml @@ -0,0 +1,122 @@ +--- +eck-elasticsearch: + enabled: true + + # Name of the Elasticsearch instance. + # + fullnameOverride: elasticsearch + + nodeSets: + - name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false + +eck-kibana: + enabled: true + + # Name of the Kibana instance. + # + fullnameOverride: kibana + + # Reference to ECK-managed Elasticsearch instance, ideally from {{ "elasticsearch.fullname" }} + # + elasticsearchRef: + name: elasticsearch + + config: + # Note that these are specific to the namespace into which this example is installed, and are + # using `elastic-stack` as configured here and detailed in the README when installing: + # + # `helm install es-kb-quickstart elastic/eck-stack -n elastic-stack` + # + # If installed outside of the `elastic-stack` namespace, the following 2 lines need modification. + xpack.fleet.agents.elasticsearch.hosts: ["https://elasticsearch-es-http.elastic-stack.svc:9200"] + xpack.fleet.agents.fleet_server.hosts: ["https://fleet-server-agent-http.elastic-stack.svc:8220"] + xpack.fleet.packages: + - name: system + version: latest + - name: elastic_agent + version: latest + - name: fleet_server + version: latest + - name: kubernetes + version: latest + xpack.fleet.agentPolicies: + - name: Fleet Server on ECK policy + id: eck-fleet-server + namespace: default + is_managed: true + monitoring_enabled: + - logs + - metrics + package_policies: + - name: fleet_server-1 + id: fleet_server-1 + package: + name: fleet_server + - name: Elastic Agent on ECK policy + id: eck-agent + namespace: default + is_managed: true + monitoring_enabled: + - logs + - metrics + unenroll_timeout: 900 + package_policies: + - package: + name: system + name: system-1 + - package: + name: kubernetes + name: kubernetes-1 + +eck-agent: + enabled: true + + # Agent policy to be used. + policyID: eck-agent + # Reference to ECK-managed Kibana instance. + # + kibanaRef: + name: kibana + elasticsearchRefs: [] + # Reference to ECK-managed Fleet instance. + # + fleetServerRef: + name: fleet-server + + mode: fleet + daemonSet: + podTemplate: + spec: + serviceAccountName: elastic-agent + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + automountServiceAccountToken: true + securityContext: + runAsUser: 0 + +eck-fleet-server: + enabled: true + + fullnameOverride: "fleet-server" + + deployment: + replicas: 1 + podTemplate: + spec: + serviceAccountName: fleet-server + automountServiceAccountToken: true + + # Agent policy to be used. + policyID: eck-fleet-server + kibanaRef: + name: kibana + elasticsearchRefs: + - name: elasticsearch diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/examples/apm-server/basic.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/examples/apm-server/basic.yaml new file mode 100644 index 00000000..227b5825 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/examples/apm-server/basic.yaml @@ -0,0 +1,52 @@ +--- +eck-elasticsearch: + enabled: true + + # Name of the Elasticsearch instance. + # + fullnameOverride: elasticsearch + + nodeSets: + - name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false + +eck-kibana: + enabled: true + + # Name of the Kibana instance. + # + fullnameOverride: kibana + + spec: + config: + xpack.fleet.packages: + - name: apm + version: latest + +eck-apm-server: + enabled: true + + # Count of APM Server replicas to create. + # + count: 1 + + # Reference to ECK-managed Elasticsearch resource. + # + elasticsearchRef: + name: elasticsearch + kibanaRef: + name: kibana + http: + service: + spec: + ports: + - name: http + port: 8200 + targetPort: 8200 diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/examples/apm-server/jaeger-with-http-configuration.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/examples/apm-server/jaeger-with-http-configuration.yaml new file mode 100644 index 00000000..b694955f --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/examples/apm-server/jaeger-with-http-configuration.yaml @@ -0,0 +1,60 @@ +--- +eck-elasticsearch: + enabled: true + + # Name of the Elasticsearch instance. + # + fullnameOverride: elasticsearch + + nodeSets: + - name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false + +eck-kibana: + enabled: true + + # Name of the Kibana instance. + # + fullnameOverride: kibana + + spec: + config: + xpack.fleet.packages: + - name: apm + version: latest + +eck-apm-server: + enabled: true + + # Count of APM Server replicas to create. + # + count: 1 + + config: + name: elastic-apm + apm-server.jaeger.grpc.enabled: true + apm-server.jaeger.grpc.host: "0.0.0.0:14250" + + # Reference to ECK-managed Elasticsearch resource. + # + elasticsearchRef: + name: elasticsearch + kibanaRef: + name: kibana + http: + service: + spec: + ports: + - name: http + port: 8200 + targetPort: 8200 + - name: grpc + port: 14250 + targetPort: 14250 diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/examples/beats/metricbeat_hosts.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/examples/beats/metricbeat_hosts.yaml new file mode 100644 index 00000000..235aaa6e --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/examples/beats/metricbeat_hosts.yaml @@ -0,0 +1,217 @@ +eck-elasticsearch: + enabled: true + + # Name of the Elasticsearch resource. + # + fullnameOverride: quickstart + + # Version of Elasticsearch. + # + version: 9.2.0 + + nodeSets: + - name: default + count: 3 + config: + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + node.store.allow_mmap: false + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 100Gi + # Adjust to your storage class name + # + # storageClassName: local-storage + +eck-kibana: + enabled: true + + # Name of the Kibana resource. + # + fullnameOverride: quickstart + + # Version of Kibana. + # + version: 9.2.0 + + spec: + # Count of Kibana replicas to create. + # + count: 1 + + # Reference to ECK-managed Elasticsearch resource, ideally from {{ "elasticsearch.fullname" }} + # + elasticsearchRef: + name: quickstart + +eck-beats: + enabled: true + name: metricbeat + type: metricbeat + version: 9.2.0 + elasticsearchRef: + name: quickstart + kibanaRef: + name: quickstart + config: + # Since filebeat is used in the default values, this needs to be removed with an empty list. + filebeat.inputs: [] + metricbeat: + autodiscover: + providers: + - hints: + default_config: {} + enabled: "true" + node: ${NODE_NAME} + type: kubernetes + modules: + - module: system + period: 10s + metricsets: + - cpu + - load + - memory + - network + - process + - process_summary + process: + include_top_n: + by_cpu: 5 + by_memory: 5 + processes: + - .* + - module: system + period: 1m + metricsets: + - filesystem + - fsstat + processors: + - drop_event: + when: + regexp: + system: + filesystem: + mount_point: ^/(sys|cgroup|proc|dev|etc|host|lib)($|/) + - module: kubernetes + period: 10s + node: ${NODE_NAME} + hosts: + - https://${NODE_NAME}:10250 + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + ssl: + verification_mode: none + metricsets: + - node + - system + - pod + - container + - volume + processors: + - add_cloud_metadata: {} + - add_host_metadata: {} + daemonSet: + podTemplate: + spec: + serviceAccountName: metricbeat + automountServiceAccountToken: true # some older Beat versions are depending on this settings presence in k8s context + containers: + - args: + - -e + - -c + - /etc/beat.yml + - --system.hostfs=/hostfs + name: metricbeat + volumeMounts: + - mountPath: /hostfs/sys/fs/cgroup + name: cgroup + - mountPath: /var/run/docker.sock + name: dockersock + - mountPath: /hostfs/proc + name: proc + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + dnsPolicy: ClusterFirstWithHostNet + hostNetwork: true # Allows to provide richer host metadata + securityContext: + runAsUser: 0 + terminationGracePeriodSeconds: 30 + volumes: + - hostPath: + path: /sys/fs/cgroup + name: cgroup + - hostPath: + path: /var/run/docker.sock + name: dockersock + - hostPath: + path: /proc + name: proc + + clusterRole: + # permissions needed for metricbeat + # source: https://www.elastic.co/guide/en/beats/metricbeat/current/metricbeat-module-kubernetes.html + name: metricbeat + rules: + - apiGroups: + - "" + resources: + - nodes + - namespaces + - events + - pods + verbs: + - get + - list + - watch + - apiGroups: + - "extensions" + resources: + - replicasets + verbs: + - get + - list + - watch + - apiGroups: + - apps + resources: + - statefulsets + - deployments + - replicasets + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - nodes/stats + verbs: + - get + - nonResourceURLs: + - /metrics + verbs: + - get + + serviceAccount: + name: metricbeat + + clusterRoleBinding: + name: metricbeat + subjects: + - kind: ServiceAccount + name: metricbeat + roleRef: + kind: ClusterRole + name: metricbeat + apiGroup: rbac.authorization.k8s.io diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/examples/custom-elasticsearch-kibana.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/examples/custom-elasticsearch-kibana.yaml new file mode 100644 index 00000000..1c3adb3e --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/examples/custom-elasticsearch-kibana.yaml @@ -0,0 +1,78 @@ +--- +eck-elasticsearch: + # Name of the Elasticsearch resource. + # + fullnameOverride: quickstart + + # Version of Elasticsearch. + # + version: 9.2.0 + + nodeSets: + - name: default + count: 1 + config: + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 100Gi + # Adjust to your storage class name + # + # storageClassName: local-storage + +eck-kibana: + # Name of the Kibana resource. + # + fullnameOverride: quickstart + + # Version of Kibana. + # + version: 9.2.0 + + spec: + # Count of Kibana replicas to create. + # + count: 1 + + # Reference to ECK-managed Elasticsearch resource, ideally from {{ "elasticsearch.fullname" }} + # + elasticsearchRef: + name: quickstart + # namespace: default + http: + service: + spec: + # Type of service to deploy for Kibana. + # This deploys a load balancer in a cloud service provider, where supported. + # + type: LoadBalancer + # tls: + # selfSignedCertificate: + # subjectAltNames: + # - ip: 1.2.3.4 + # - dns: kibana.example.com + podTemplate: + spec: + containers: + - name: kibana + env: + - name: NODE_OPTIONS + value: "--max-old-space-size=2048" + resources: + requests: + memory: 1Gi + cpu: 0.5 + limits: + memory: 2.5Gi + cpu: 2 diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/examples/elasticsearch/hot-warm-cold.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/examples/elasticsearch/hot-warm-cold.yaml new file mode 100644 index 00000000..919cb4c7 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/examples/elasticsearch/hot-warm-cold.yaml @@ -0,0 +1,199 @@ +--- +eck-elasticsearch: + nodeSets: + - name: masters + count: 1 + config: + node.roles: ["master"] + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + spec: + containers: + - name: elasticsearch + resources: + limits: + memory: 8Gi + cpu: 2 + # Affinity/Anti-affinity settings for controlling the 'spreading' of Elasticsearch + # pods across existing hosts. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html#k8s-affinity-options + # + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: beta.kubernetes.io/instance-type + # operator: In + # # This should be adjusted to the instance type according to your setup + # # + # values: + # - highio + # Volume Claim settings. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-volume-claim-templates.html + # + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Ti + # Adjust to your storage class name + # + # storageClassName: local-storage + - name: hot + count: 1 + config: + node.roles: ["data_hot", "data_content", "ingest"] + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + spec: + containers: + - name: elasticsearch + resources: + limits: + memory: 16Gi + cpu: 4 + # Affinity/Anti-affinity settings for controlling the 'spreading' of Elasticsearch + # pods across existing hosts. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html#k8s-affinity-options + # + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: beta.kubernetes.io/instance-type + # operator: In + # # This should be adjusted to the instance type according to your setup + # # + # values: + # - highio + # Volume Claim settings. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-volume-claim-templates.html + # + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Ti + # Adjust to your storage class name + # + # storageClassName: local-storage + - name: warm + count: 1 + config: + node.roles: ["data_warm"] + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + spec: + containers: + - name: elasticsearch + resources: + limits: + memory: 16Gi + cpu: 2 + # Affinity/Anti-affinity settings for controlling the 'spreading' of Elasticsearch + # pods across existing hosts. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html#k8s-affinity-options + # + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: beta.kubernetes.io/instance-type + # operator: In + # # This should be adjusted to the instance type according to your setup + # # + # values: + # - highstorage + # Volume Claim settings. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-volume-claim-templates.html + # + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Ti + # Adjust to your storage class name + # + # storageClassName: local-storage + - name: cold + count: 1 + config: + node.roles: ["data_cold"] + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + spec: + containers: + - name: elasticsearch + resources: + limits: + memory: 8Gi + cpu: 2 + # Affinity/Anti-affinity settings for controlling the 'spreading' of Elasticsearch + # pods across existing hosts. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-advanced-node-scheduling.html#k8s-affinity-options + # + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: beta.kubernetes.io/instance-type + # operator: In + # # This should be adjusted to the instance type according to your setup + # # + # values: + # - highstorage + # Volume Claim settings. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-volume-claim-templates.html + # + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 20Ti + # Adjust to your storage class name + # + # storageClassName: local-storage diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/examples/elasticsearch/ingress/elasticsearch-ingress-gke.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/examples/elasticsearch/ingress/elasticsearch-ingress-gke.yaml new file mode 100644 index 00000000..0ca2e8a5 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/examples/elasticsearch/ingress/elasticsearch-ingress-gke.yaml @@ -0,0 +1,40 @@ +# The following is an example of an Elasticsearch resource that is configured to use an Ingress resource in a GKE cluster. +# Additional examples of exposing Elasticsearch with Ingress resources can be found in the following location: +# https://github.com/elastic/cloud-on-k8s/tree/main/deploy/eck-stack/charts/eck-elasticsearch/examples/ingress +# +eck-elasticsearch: + enabled: true + + ingress: + enabled: true + annotations: + my: annotation + labels: + my: label + pathType: Prefix + hosts: + - host: "elasticsearch.company.dev" + path: "/" + http: + service: + metadata: + annotations: + # This is required for `ClusterIP` services (which are the default ECK service type) to be used with Ingress in GKE clusters. + cloud.google.com/neg: '{"ingress": true}' + # This is required to enable the GKE Ingress Controller to use HTTPS as the backend protocol. + cloud.google.com/app-protocols: '{"https":"HTTPS"}' + nodeSets: + - name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false + # Enable anonymous access to allow GCLB health probes to succeed + xpack.security.authc: + anonymous: + username: anon + roles: monitoring_user diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/examples/enterprise-search/basic.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/examples/enterprise-search/basic.yaml new file mode 100644 index 00000000..aeb61b06 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/examples/enterprise-search/basic.yaml @@ -0,0 +1,42 @@ +--- +eck-elasticsearch: + enabled: true + + # Name of the Elasticsearch instance. + # + fullnameOverride: elasticsearch + + nodeSets: + - name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false + +eck-kibana: + enabled: true + + # Name of the Kibana instance. + # + fullnameOverride: kibana + + elasticsearchRef: + name: elasticsearch + + spec: + enterpriseSearchRef: + name: enterprise-search + +eck-enterprise-search: + enabled: true + + # Name of the Enterprise Search instance. + # + fullnameOverride: enterprise-search + + elasticsearchRef: + name: elasticsearch diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/examples/enterprise-search/with-custom-configuration.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/examples/enterprise-search/with-custom-configuration.yaml new file mode 100644 index 00000000..a7c3ad49 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/examples/enterprise-search/with-custom-configuration.yaml @@ -0,0 +1,52 @@ +--- +eck-elasticsearch: + enabled: true + + # Name of the Elasticsearch instance. + # + fullnameOverride: elasticsearch + + nodeSets: + - name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false + +eck-kibana: + enabled: true + + # Name of the Kibana instance. + # + fullnameOverride: kibana + + elasticsearchRef: + name: elasticsearch + + spec: + enterpriseSearchRef: + name: enterprise-search + +eck-enterprise-search: + enabled: true + + # Name of the Enterprise Search instance. + # + fullnameOverride: enterprise-search + + config: + # configure app search document size limit + app_search.engine.document_size.limit: 100kb + + http: + service: + metadata: + labels: + my-custom: label + + elasticsearchRef: + name: elasticsearch diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/examples/kibana/http-configuration.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/examples/kibana/http-configuration.yaml new file mode 100644 index 00000000..d8a4831d --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/examples/kibana/http-configuration.yaml @@ -0,0 +1,23 @@ +--- +eck-kibana: + # Count of Kibana replicas to create. + # + count: 1 + + # Reference to ECK-managed Elasticsearch resource, ideally from {{ "elasticsearch.fullname" }} + # + elasticsearchRef: + name: es-quickstart-eck-elasticsearch + # namespace: default + http: + service: + spec: + # Type of service to deploy for Kibana. + # This deploys a load balancer in a cloud service provider, where supported. + # + type: LoadBalancer + # tls: + # selfSignedCertificate: + # subjectAltNames: + # - ip: 1.2.3.4 + # - dns: kibana.example.com diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/examples/kibana/ingress/kibana-gke.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/examples/kibana/ingress/kibana-gke.yaml new file mode 100644 index 00000000..4aa1dc06 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/examples/kibana/ingress/kibana-gke.yaml @@ -0,0 +1,80 @@ +# The following is an example of a Kibana resource that is configured to use an Ingress resource in a GKE cluster. +# Additional examples of exposing Kibana with Ingress resources can be found in the following location: +# https://github.com/elastic/cloud-on-k8s/tree/main/deploy/eck-stack/charts/eck-kibana/examples/ingress +# +eck-elasticsearch: + enabled: true + + # Name of the Elasticsearch instance. + # + fullnameOverride: elasticsearch + + ingress: + enabled: true + annotations: + my: annotation + labels: + my: label + pathType: Prefix + hosts: + - host: "elasticsearch.company.dev" + path: "/" + tls: + enabled: true + + http: + service: + metadata: + annotations: + # This is required for `ClusterIP` services (which are the default ECK service type) to be used with Ingress in GKE clusters. + cloud.google.com/neg: '{"ingress": true}' + cloud.google.com/app-protocols: '{"https":"HTTPS"}' + + nodeSets: + - name: default + count: 3 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false + # Enable anonymous access to allow GCLB health probes to succeed + xpack.security.authc: + anonymous: + username: anon + roles: monitoring_user + +eck-kibana: + enabled: true + + # Name of the Kibana instance. + # + fullnameOverride: kibana + + # Reference to ECK-managed Elasticsearch instance, ideally from {{ "elasticsearch.fullname" }} + # + elasticsearchRef: + name: elasticsearch + + config: + server: + publicBaseUrl: "https://kibana.company.dev" + + http: + service: + metadata: + annotations: + # This is required for `ClusterIP` services (which are the default ECK service type) to be used with Ingress in GKE clusters. + cloud.google.com/neg: '{"ingress": true}' + cloud.google.com/app-protocols: '{"https":"HTTPS"}' + + ingress: + enabled: true + pathType: Prefix + hosts: + - host: "kibana.company.dev" + path: "/" + tls: + enabled: true diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/examples/logstash/basic-eck.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/examples/logstash/basic-eck.yaml new file mode 100644 index 00000000..8c2afa22 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/examples/logstash/basic-eck.yaml @@ -0,0 +1,113 @@ +--- +eck-elasticsearch: + nodeSets: + - name: default + count: 3 + config: + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html + # + node.store.allow_mmap: false + podTemplate: + spec: + containers: + - name: elasticsearch + resources: + limits: + memory: 2Gi + requests: + memory: 2Gi +eck-kibana: + enabled: true + spec: + count: 1 + elasticsearchRef: + name: elasticsearch +eck-beats: + enabled: true + deployment: + podTemplate: + spec: + automountServiceAccountToken: true + initContainers: + - name: download-tutorial + image: curlimages/curl + command: ["/bin/sh"] + args: ["-c", "curl -L https://download.elastic.co/demos/logstash/gettingstarted/logstash-tutorial.log.gz | gunzip -c > /data/logstash-tutorial.log"] + volumeMounts: + - name: data + mountPath: /data + containers: + - name: filebeat + securityContext: + runAsUser: 1000 + volumeMounts: + - name: data + mountPath: /data + - name: beat-data + mountPath: /usr/share/filebeat/data + volumes: + - name: data + emptydir: {} + - name: beat-data + emptydir: {} + type: filebeat + config: + filebeat.inputs: + - type: filestream + id: logstash-tutorial + paths: + - /data/logstash-tutorial.log + processors: + - add_host_metadata: {} + - add_cloud_metadata: {} + output.logstash: + # This needs to be {{logstash-name}}-ls-beats:5044 + hosts: ["logstash-ls-beats-ls-beats:5044"] +eck-logstash: + enabled: true + # This is required to be able to set the logstash + # output of beats in a consistent manner. + fullnameOverride: "logstash-ls-beats" + elasticsearchRefs: + # This clusterName is required to match the environment variables + # used in the below config.string output section. + - clusterName: eck + name: elasticsearch + pipelines: + - pipeline.id: main + config.string: | + input { + beats { + port => 5044 + } + } + filter { + grok { + match => { "message" => "%{HTTPD_COMMONLOG}"} + } + geoip { + source => "[source][address]" + target => "[source]" + } + } + output { + elasticsearch { + hosts => [ "${ECK_ES_HOSTS}" ] + user => "${ECK_ES_USER}" + password => "${ECK_ES_PASSWORD}" + ssl_certificate_authorities => "${ECK_ES_SSL_CERTIFICATE_AUTHORITY}" + } + } + services: + - name: beats + service: + spec: + type: ClusterIP + ports: + - port: 5044 + name: "filebeat" + protocol: TCP + targetPort: 5044 diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/templates/NOTES.txt b/packs/elastic-stack-0.17.0/charts/eck-stack/templates/NOTES.txt new file mode 100644 index 00000000..65cdae60 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/templates/NOTES.txt @@ -0,0 +1,10 @@ +Elasticsearch ECK-Stack {{ .Chart.Version }} has been deployed successfully! + +To see status of all resources, run + +kubectl get elastic -n {{ .Release.Namespace }} -l "app.kubernetes.io/instance"={{ .Release.Name }} + +More information on the Elastic ECK Operator, and its Helm chart can be found +within our documentation. + +https://www.elastic.co/guide/en/cloud-on-k8s/current/index.html diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/templates/_helpers.tpl b/packs/elastic-stack-0.17.0/charts/eck-stack/templates/_helpers.tpl new file mode 100644 index 00000000..cef61bdb --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/templates/_helpers.tpl @@ -0,0 +1,48 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "eck-stack.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "eck-stack.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "eck-stack.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "eck-stack.labels" -}} +helm.sh/chart: {{ include "eck-stack.chart" . }} +{{ include "eck-stack.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "eck-stack.selectorLabels" -}} +app.kubernetes.io/name: {{ include "eck-stack.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/packs/elastic-stack-0.17.0/charts/eck-stack/values.yaml b/packs/elastic-stack-0.17.0/charts/eck-stack/values.yaml new file mode 100644 index 00000000..5d504211 --- /dev/null +++ b/packs/elastic-stack-0.17.0/charts/eck-stack/values.yaml @@ -0,0 +1,50 @@ +--- +# Default values for eck-stack. +# This is a YAML-formatted file. + +# If enabled, will use the eck-elasticsearch chart and deploy an Elasticsearch resource. +# +eck-elasticsearch: + enabled: true + # This is adjusting the full name of the elasticsearch resource so that both the eck-elasticsearch + # and the eck-kibana chart work together by default in the eck-stack chart. + fullnameOverride: elasticsearch + +# If enabled, will use the eck-kibana chart and deploy a Kibana resource. +# +eck-kibana: + enabled: true + # This is also adjusting the kibana reference to the elasticsearch resource named previously so that + # both the eck-elasticsearch and the eck-kibana chart work together by default in the eck-stack chart. + elasticsearchRef: + name: elasticsearch + +# If enabled, will use the eck-agent chart and deploy an Elastic Agent instance. +# +eck-agent: + enabled: false + +# If enabled, will use the eck-fleet-server chart and deploy a Fleet Server resource. +# +eck-fleet-server: + enabled: false + +# If enabled, will use the eck-beats chart and deploy a Beats resource. +# +eck-beats: + enabled: false + +# If enabled, will use the eck-logstash chart and deploy a Logstash resource. +# +eck-logstash: + enabled: false + +# If enabled, will use the eck-apm-server chart and deploy a standalone APM Server resource. +# +eck-apm-server: + enabled: false + +# If enabled, will use the eck-enterprise-search chart and deploy a Enterprise Search resource. +# +eck-enterprise-search: + enabled: false diff --git a/packs/elastic-stack-0.17.0/logo.png b/packs/elastic-stack-0.17.0/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..fa70b78daa45585ec0f802dfe637e4ce2172d6f8 GIT binary patch literal 5810 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 /data/logstash-tutorial.log"] + volumeMounts: + - name: data + mountPath: /data + containers: + - name: filebeat + securityContext: + runAsUser: 1000 + volumeMounts: + - name: data + mountPath: /data + - name: beat-data + mountPath: /usr/share/filebeat/data + volumes: + - name: data + emptydir: {} + - name: beat-data + emptydir: {} + eck-logstash: + enabled: true + # This is required to be able to set the logstash + # output of beats in a consistent manner. + fullnameOverride: "logstash-ls-beats" + elasticsearchRefs: + # This clusterName is required to match the environment variables + # used in the below config.string output section. + - clusterName: eck + name: elasticsearch + pipelines: + - pipeline.id: main + config.string: | + input { + beats { + port => 5044 + } + } + filter { + grok { + match => { "message" => "%{HTTPD_COMMONLOG}"} + } + geoip { + source => "[source][address]" + target => "[source]" + } + } + output { + elasticsearch { + hosts => [ "${ECK_ES_HOSTS}" ] + user => "${ECK_ES_USER}" + password => "${ECK_ES_PASSWORD}" + ssl_certificate_authorities => "${ECK_ES_SSL_CERTIFICATE_AUTHORITY}" + } + } + services: + - name: beats + service: + spec: + type: ClusterIP + ports: + - port: 5044 + name: "filebeat" + protocol: TCP + targetPort: 5044 \ No newline at end of file diff --git a/packs/elastic-stack-0.17.0/values.yaml b/packs/elastic-stack-0.17.0/values.yaml new file mode 100644 index 00000000..52638800 --- /dev/null +++ b/packs/elastic-stack-0.17.0/values.yaml @@ -0,0 +1,71 @@ +# Default values for eck-elastic-operator +# This is a YAML-formatted file +pack: + content: + images: + - image: docker.elastic.co/kibana/kibana:9.2.0 + - image: docker.elastic.co/elasticsearch/elasticsearch:9.2.0 + - image: docker.elastic.co/logstash/logstash:9.2.0 + - image: docker.elastic.co/beats/filebeat:9.2.0 + - image: docker.io/curlimages/curl + + + charts: + - repo: https://helm.elastic.co/ + name: eck-stack + version: 0.17.0 + #The namespace (on the target cluster) to install this chart + #When not found, a new namespace will be created + namespace: "elastic-stack" + +charts: + eck-stack: + # Default values for eck-stack. + # This is a YAML-formatted file. + + # If enabled, will use the eck-elasticsearch chart and deploy an Elasticsearch resource. + # + eck-elasticsearch: + enabled: true + # This is adjusting the full name of the elasticsearch resource so that both the eck-elasticsearch + # and the eck-kibana chart work together by default in the eck-stack chart. + fullnameOverride: elasticsearch + + # If enabled, will use the eck-kibana chart and deploy a Kibana resource. + # + eck-kibana: + enabled: true + # This is also adjusting the kibana reference to the elasticsearch resource named previously so that + # both the eck-elasticsearch and the eck-kibana chart work together by default in the eck-stack chart. + elasticsearchRef: + name: elasticsearch + + # If enabled, will use the eck-agent chart and deploy an Elastic Agent instance. + # + eck-agent: + enabled: false + + # If enabled, will use the eck-fleet-server chart and deploy a Fleet Server resource. + # + eck-fleet-server: + enabled: false + + # If enabled, will use the eck-beats chart and deploy a Beats resource. + # + eck-beats: + enabled: false + + # If enabled, will use the eck-logstash chart and deploy a Logstash resource. + # + eck-logstash: + enabled: false + + # If enabled, will use the eck-apm-server chart and deploy a standalone APM Server resource. + # + eck-apm-server: + enabled: false + + # If enabled, will use the eck-enterprise-search chart and deploy a Enterprise Search resource. + # + eck-enterprise-search: + enabled: false \ No newline at end of file From ede1ae83e98e9b3fa124f02fe74e5128e983ea6a Mon Sep 17 00:00:00 2001 From: svalenciah19 Date: Wed, 12 Nov 2025 01:04:10 -0500 Subject: [PATCH 7/8] Upgrade crossplane pack to version 2.1.0 --- packs/crossplane-2.1.0/README.md | 37 +++ .../charts/crossplane-2.1.0.tgz | Bin 0 -> 14646 bytes .../charts/crossplane/.helmignore | 24 ++ .../charts/crossplane/Chart.yaml | 35 ++ .../charts/crossplane/LICENSE | 201 ++++++++++++ .../charts/crossplane/README.md | 183 +++++++++++ .../charts/crossplane/README.md.gotmpl | 112 +++++++ .../charts/crossplane/templates/NOTES.txt | 8 + .../charts/crossplane/templates/_helpers.tpl | 43 +++ .../crossplane/templates/clusterrole.yaml | 108 +++++++ .../templates/clusterrolebinding.yaml | 19 ++ .../crossplane/templates/deployment.yaml | 300 ++++++++++++++++++ .../crossplane/templates/extra-objects.yaml | 4 + ...-manager-allowed-provider-permissions.yaml | 14 + .../templates/rbac-manager-clusterrole.yaml | 135 ++++++++ .../rbac-manager-clusterrolebinding.yaml | 17 + .../templates/rbac-manager-deployment.yaml | 141 ++++++++ .../rbac-manager-managed-clusterroles.yaml | 227 +++++++++++++ .../rbac-manager-serviceaccount.yaml | 16 + .../charts/crossplane/templates/secret.yaml | 43 +++ .../charts/crossplane/templates/service.yaml | 25 ++ .../crossplane/templates/serviceaccount.yaml | 19 ++ .../charts/crossplane/values.yaml | 215 +++++++++++++ packs/crossplane-2.1.0/logo.png | Bin 0 -> 91169 bytes packs/crossplane-2.1.0/pack.json | 18 ++ packs/crossplane-2.1.0/values.yaml | 226 +++++++++++++ 26 files changed, 2170 insertions(+) create mode 100644 packs/crossplane-2.1.0/README.md create mode 100644 packs/crossplane-2.1.0/charts/crossplane-2.1.0.tgz create mode 100644 packs/crossplane-2.1.0/charts/crossplane/.helmignore create mode 100644 packs/crossplane-2.1.0/charts/crossplane/Chart.yaml create mode 100644 packs/crossplane-2.1.0/charts/crossplane/LICENSE create mode 100644 packs/crossplane-2.1.0/charts/crossplane/README.md create mode 100644 packs/crossplane-2.1.0/charts/crossplane/README.md.gotmpl create mode 100644 packs/crossplane-2.1.0/charts/crossplane/templates/NOTES.txt create mode 100644 packs/crossplane-2.1.0/charts/crossplane/templates/_helpers.tpl create mode 100644 packs/crossplane-2.1.0/charts/crossplane/templates/clusterrole.yaml create mode 100644 packs/crossplane-2.1.0/charts/crossplane/templates/clusterrolebinding.yaml create mode 100644 packs/crossplane-2.1.0/charts/crossplane/templates/deployment.yaml create mode 100644 packs/crossplane-2.1.0/charts/crossplane/templates/extra-objects.yaml create mode 100644 packs/crossplane-2.1.0/charts/crossplane/templates/rbac-manager-allowed-provider-permissions.yaml create mode 100644 packs/crossplane-2.1.0/charts/crossplane/templates/rbac-manager-clusterrole.yaml create mode 100644 packs/crossplane-2.1.0/charts/crossplane/templates/rbac-manager-clusterrolebinding.yaml create mode 100644 packs/crossplane-2.1.0/charts/crossplane/templates/rbac-manager-deployment.yaml create mode 100644 packs/crossplane-2.1.0/charts/crossplane/templates/rbac-manager-managed-clusterroles.yaml create mode 100644 packs/crossplane-2.1.0/charts/crossplane/templates/rbac-manager-serviceaccount.yaml create mode 100644 packs/crossplane-2.1.0/charts/crossplane/templates/secret.yaml create mode 100644 packs/crossplane-2.1.0/charts/crossplane/templates/service.yaml create mode 100644 packs/crossplane-2.1.0/charts/crossplane/templates/serviceaccount.yaml create mode 100644 packs/crossplane-2.1.0/charts/crossplane/values.yaml create mode 100644 packs/crossplane-2.1.0/logo.png create mode 100644 packs/crossplane-2.1.0/pack.json create mode 100644 packs/crossplane-2.1.0/values.yaml diff --git a/packs/crossplane-2.1.0/README.md b/packs/crossplane-2.1.0/README.md new file mode 100644 index 00000000..0c5d3648 --- /dev/null +++ b/packs/crossplane-2.1.0/README.md @@ -0,0 +1,37 @@ +# Crossplane + +Crossplane is an open source Kubernetes extension that transforms your Kubernetes cluster into a universal control plane. + +Crossplane lets you manage anything, anywhere, all through standard Kubernetes APIs. Crossplane can even let you order a pizza directly from Kubernetes. If it has an API, Crossplane can connect to it. + +With Crossplane, platform teams can create new abstractions and custom APIs with the full power of Kubernetes policies, namespaces, role based access controls and more. Crossplane brings all your non-Kubernetes resources under one roof. + +Custom APIs, created by platform teams, allow security and compliance enforcement across resources or clouds, without exposing any complexity to the developers. A single API call can create multiple resources, in multiple clouds and use Kubernetes as the control plane for everything. + +## Prerequisites + +Kubernetes >= 1.27.0 + +## Usage + +Installing a provider creates new Kubernetes resources representing the Provider’s APIs. Installing a provider also creates a Provider pod that’s responsible for reconciling the Provider’s APIs into the Kubernetes cluster. Providers constantly watch the state of the desired managed resources and create any external resources that are missing. + +Install a Provider with a Crossplane Provider object setting the spec.package value to the location of the provider package. Additional providers can be found in the [Upboud Marketplace](https://marketplace.upbound.io/) + +*For Example* +Install the [Palette Provider](https://marketplace.upbound.io/providers/crossplane-contrib/provider-palette/v0.19.2) + +```yaml +apiVersion: pkg.crossplane.io/v1 +kind: Provider +metadata: + name: provider-palette +spec: + package: xpkg.upbound.io/crossplane-contrib/provider-palette:v0.23.5 +``` + +## References + +Crossplane Provider Guide - +Crossplane Concepts - +Upbound Marketplace - diff --git a/packs/crossplane-2.1.0/charts/crossplane-2.1.0.tgz b/packs/crossplane-2.1.0/charts/crossplane-2.1.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..976d731756be06534d367c04f950e9380270d8e3 GIT binary patch literal 14646 zcmV-6ImyN!iwG0|00000|0w_~VMtOiV@ORlOnEsqVl!4SWK%V1T2nbTPgYhoO;>Dc zVQyr3R8em|NM&qo0PMZ}bKEwP0J=Z(ufWNBb#`us`mii#b(gEBNb*K+ZCNGB$)-{% z4~FcS!HEPI0F*qj{r>h>XaFS0;e5%ml+B4h*cuXOG#ZWmLIX&oP^!o%ht0zYl{%i% zJp0StK3iK`TYI~^`2W_{R{Q_$ot@`@*?zITwexa!`}x++U$(ZNKY#xGFJ$YE@#uU? zrK$YO))%+c?%cn~LkspJNW}!-C)e8%EsE;rPP`p&MJcF6vO?pl!-`u7Q-pFN3gASE zQYJwDQ4T?J(4YuS)4t$DPpBrq=`aIDij3-!kavSth!a zKt@vJBrh|~iVVm#@Ki|EBb28EJ`_R$nXvH$B+1|!vWO4`*{H8TUb6(q!P$u-BOwVb zii{=H;9j?x2(HQ;;%Fjr*e4UM3$?$wSx5%&N)o)qUCo(mk)N@}tXo#wUN}3K0xGQ{d zWy->pigL=hri_Ec{ywalXH<} zjE~XaWoy1&z~LYsL=DG)V7qxsg%sL zz{XrixHOoLXr{o8`$3wL0T(G;Kn95x(sEwMVASIqM`4A1^6_&3ON$I7>hF~x1;zKt zFTVzW=xD?^(+pOE<4R9wuqi|)#?y;J0!5i13X&+W z(rA!!Ww{HxJvhutr9r-8Qt6+Vp8Q~29~d*R!lTJ27X>72G{tsX;D%s%eK_qPXdG3A zamv(Vlaxw}oD4ELglwhpur*#|c^v0iV3c#ASLZ%k?Vzq?!8&{NAW1~YbtSMY4HzgR z-nFr~1JDCHs&1PZM-jfmWQVj=WBglBV9MjY9K$F7_scDt8Uj!Uc0J9#9Is2salUf2PW z6&D;3W8j-{a$_e+L6a*w2871A(lpCZsJqt)$P029F%AT{mWGjhFH)!aiXWli4 zl7#6ADftyQ2BeUrgqIy;q3 z-(1s8fo;fM2&u6j4mkD)B=R<3FL5desV!~fkS5OJ+ph(IQ9}r&Z4p}BwDCclXqO@b zH+@a5CPqhs|A+Q{A#^;JFm5Xir}57{9CgKtgQ{fs)vNuWyS1Y+gK4+Ff(Co#u`Gu) z$7wNO=DID-QU015rrl|SSf`em)uuCgrVCc3Yl8Z7O!67}hsF#cGiG@RvCA-D0<0N@ivT%04fC&)(HWg#9|#WHObKqTDAhwzl#b#2d(s zZ@vzc9INb;?X8{NHw-86ZzZVtnECI^aob*q+e&aeb~`Wj-Y}!Fk`f0}a19@Hlc3db zmI@>}Ia=uA5Hsip>YW0)PxfBCc)k-t7)wzWD}wmDDcgeKT}+x~;^s`UYnH(nj#WZ4 zoSU8grk5>q>a?W%1?VnUNeZFKh-E<3RB6ZwH9Co=eZey)=4onl_qh=I70bXDbK)>^ zy7Z7HlbWX3lpq5;f;ht`B1^G(SHZ^m3FCy4^Mf~JNRul_Lqss}HY&5WQcvL;GEsQB zkVDGKylpfo_Pb-|ig1mF(ZaS>(QT?QHLkCzjB02=5^D4=d`JLNaw<}A42JsE7uzR0 zTR0PH9q7G0at2bN#h`x_S&37f<%S@ovD;M_W=Blf1*FhvXp(IJd7-CAOb&}^GbwV=6DSoasGjt!?`BLcl}K7Nz0+Vx9gBUt_3ak+c_{Q`MYAn%8)qD; z%5QYYF7+FMri_D9`<+lQMELtMAZ?!n_%)M)8(By*a!n<3Vq;0Plo;dP#~47y(G&FB zXaa_CQ!hcV_!dX-K}&kfuYaU6uzgRsk)⩔9GYy%#-+o_4ZahUFbVKT(3e=*z8snyBf5l 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
?> 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 literal 0 HcmV?d00001 diff --git a/packs/crossplane-2.1.0/charts/crossplane/.helmignore b/packs/crossplane-2.1.0/charts/crossplane/.helmignore new file mode 100644 index 00000000..f70b97c6 --- /dev/null +++ b/packs/crossplane-2.1.0/charts/crossplane/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +# Templates +values.yaml.tmpl +README.md.tmpl diff --git a/packs/crossplane-2.1.0/charts/crossplane/Chart.yaml b/packs/crossplane-2.1.0/charts/crossplane/Chart.yaml new file mode 100644 index 00000000..4fbd5c4b --- /dev/null +++ b/packs/crossplane-2.1.0/charts/crossplane/Chart.yaml @@ -0,0 +1,35 @@ +apiVersion: v1 +appVersion: 2.1.0 +description: Crossplane is an open source Kubernetes add-on that enables platform + teams to assemble infrastructure from multiple vendors, and expose higher level + self-service APIs for application teams to consume. +home: https://crossplane.io +icon: https://docs.crossplane.io/android-chrome-192x192.png +keywords: +- cloud +- infrastructure +- services +- application +- database +- cache +- bucket +- infra +- app +- ops +- gcp +- azure +- aws +- alibaba +- cloudsql +- rds +- s3 +- azuredatabase +- asparadb +- gke +- aks +- eks +maintainers: +- email: crossplane-info@lists.cncf.io + name: Crossplane Maintainers +name: crossplane +version: 2.1.0 diff --git a/packs/crossplane-2.1.0/charts/crossplane/LICENSE b/packs/crossplane-2.1.0/charts/crossplane/LICENSE new file mode 100644 index 00000000..ef10385c --- /dev/null +++ b/packs/crossplane-2.1.0/charts/crossplane/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2016 The Crossplane Authors. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packs/crossplane-2.1.0/charts/crossplane/README.md b/packs/crossplane-2.1.0/charts/crossplane/README.md new file mode 100644 index 00000000..985602a1 --- /dev/null +++ b/packs/crossplane-2.1.0/charts/crossplane/README.md @@ -0,0 +1,183 @@ + +Crossplane can be easily installed into any existing Kubernetes cluster using +the regularly published Helm chart. The Helm chart contains all the custom +resources and controllers needed to deploy and configure Crossplane. + +## Pre-requisites + +* [Kubernetes cluster], minimum version `v1.16.0+` +* [Helm], minimum version `v3.0.0+`. + +## Installation + +Helm charts for Crossplane are currently published to the `stable` and `master` +channels. + +### Stable + +The stable channel is the most recent release of Crossplane that is considered +ready for the community. + +```console +kubectl create namespace crossplane-system + +helm repo add crossplane-stable https://charts.crossplane.io/stable +helm repo update + +helm install crossplane --namespace crossplane-system crossplane-stable/crossplane +``` + +### Master + +The `master` channel contains the latest commits, with all automated tests +passing. `master` is subject to instability, incompatibility, and features may +be added or removed without much prior notice. It is recommended to use one of +the more stable channels, but if you want the absolute newest Crossplane +installed, then you can use the `master` channel. + +To install the Helm chart from master, you will need to pass the specific +version returned by the `search` command: + +```console +kubectl create namespace crossplane-system +helm repo add crossplane-master https://charts.crossplane.io/master/ +helm repo update +helm search repo crossplane-master --devel + +helm install crossplane --namespace crossplane-system crossplane-master/crossplane --devel --version +``` + +## Uninstalling the Chart + +To uninstall/delete the `crossplane` deployment: + +```console +helm delete crossplane --namespace crossplane-system +``` + +That command removes all Kubernetes components associated with Crossplane, +including all the custom resources and controllers. + +## Configuration + +The following tables lists the configurable parameters of the Crossplane chart +and their default values. + +| Parameter | Description | Default | +| --- | --- | --- | +| `affinity` | Add `affinities` to the Crossplane pod deployment. | `{}` | +| `args` | Add custom arguments to the Crossplane pod. | `[]` | +| `configuration.packages` | A list of Configuration packages to install. | `[]` | +| `customAnnotations` | Add custom `annotations` to the Crossplane pod deployment. | `{}` | +| `customLabels` | Add custom `labels` to the Crossplane pod deployment. | `{}` | +| `deploymentStrategy` | The deployment strategy for the Crossplane and RBAC Manager pods. | `"RollingUpdate"` | +| `dnsPolicy` | Specify the `dnsPolicy` to be used by the Crossplane pod. | `""` | +| `extraEnvVarsCrossplane` | Add custom environmental variables to the Crossplane pod deployment application container. Replaces any `.` in a variable name with `_`. For example, `SAMPLE.KEY=value1` becomes `SAMPLE_KEY=value1`. | `{}` | +| `extraEnvVarsCrossplaneInit` | Add custom environmental variables to the Crossplane pod deployment init container. Replaces any `.` in a variable name with `_`. For example, `SAMPLE.KEY=value1` becomes `SAMPLE_KEY=value1`. | `{}` | +| `extraEnvVarsRBACManager` | Add custom environmental variables to the RBAC Manager pod deployment. Replaces any `.` in a variable name with `_`. For example, `SAMPLE.KEY=value1` becomes `SAMPLE_KEY=value1`. | `{}` | +| `extraObjects` | To add arbitrary Kubernetes Objects during a Helm Install | `[]` | +| `extraVolumeMountsCrossplane` | Add custom `volumeMounts` to the Crossplane pod. | `{}` | +| `extraVolumesCrossplane` | Add custom `volumes` to the Crossplane pod. | `{}` | +| `function.packages` | A list of Function packages to install | `[]` | +| `functionCache.medium` | Set to `Memory` to hold the function cache in a RAM backed file system. Useful for Crossplane development. | `""` | +| `functionCache.pvc` | The name of a PersistentVolumeClaim to use as the function cache. Disables the default function cache `emptyDir` Volume. | `""` | +| `functionCache.sizeLimit` | The size limit for the function cache. If medium is `Memory` the `sizeLimit` can't exceed Node memory. | `"512Mi"` | +| `hostNetwork` | Enable `hostNetwork` for the Crossplane deployment. Caution: enabling `hostNetwork` grants the Crossplane Pod access to the host network namespace. Consider setting `dnsPolicy` to `ClusterFirstWithHostNet`. | `false` | +| `image.ignoreTag` | Do not use the {{ .image.tag }} value to compute the image uri. | `false` | +| `image.pullPolicy` | The image pull policy used for Crossplane and RBAC Manager pods. | `"IfNotPresent"` | +| `image.repository` | Repository for the Crossplane pod image. | `"xpkg.crossplane.io/crossplane/crossplane"` | +| `image.tag` | The Crossplane image tag. Defaults to the value of `appVersion` in `Chart.yaml`. | `""` | +| `imagePullSecrets` | The imagePullSecret names to add to the Crossplane ServiceAccount. | `[]` | +| `leaderElection` | Enable [leader election](https://docs.crossplane.io/latest/concepts/pods/#leader-election) for the Crossplane pod. | `true` | +| `metrics.enabled` | Enable Prometheus path, port and scrape annotations and expose port 8080 for both the Crossplane and RBAC Manager pods. | `false` | +| `metrics.port` | The port the metrics server listens on. | `""` | +| `nodeSelector` | Add `nodeSelectors` to the Crossplane pod deployment. | `{}` | +| `packageCache.configMap` | The name of a ConfigMap to use as the package cache. Disables the default package cache `emptyDir` Volume. | `""` | +| `packageCache.medium` | Set to `Memory` to hold the package cache in a RAM backed file system. Useful for Crossplane development. | `""` | +| `packageCache.pvc` | The name of a PersistentVolumeClaim to use as the package cache. Disables the default package cache `emptyDir` Volume. | `""` | +| `packageCache.sizeLimit` | The size limit for the package cache. If medium is `Memory` the `sizeLimit` can't exceed Node memory. | `"20Mi"` | +| `podSecurityContextCrossplane` | Add a custom `securityContext` to the Crossplane pod. | `{}` | +| `podSecurityContextRBACManager` | Add a custom `securityContext` to the RBAC Manager pod. | `{}` | +| `priorityClassName` | The PriorityClass name to apply to the Crossplane and RBAC Manager pods. | `""` | +| `provider.defaultActivations` | Define entries for the default managed resource activation policy. If defined, a default MRAP will contain these activations. | `["*"]` | +| `provider.packages` | A list of Provider packages to install. | `[]` | +| `rbacManager.affinity` | Add `affinities` to the RBAC Manager pod deployment. | `{}` | +| `rbacManager.args` | Add custom arguments to the RBAC Manager pod. | `[]` | +| `rbacManager.deploy` | Deploy the RBAC Manager pod and its required roles. | `true` | +| `rbacManager.leaderElection` | Enable [leader election](https://docs.crossplane.io/latest/concepts/pods/#leader-election) for the RBAC Manager pod. | `true` | +| `rbacManager.nodeSelector` | Add `nodeSelectors` to the RBAC Manager pod deployment. | `{}` | +| `rbacManager.replicas` | The number of RBAC Manager pod `replicas` to deploy. | `1` | +| `rbacManager.revisionHistoryLimit` | The number of RBAC Manager ReplicaSets to retain. | `nil` | +| `rbacManager.skipAggregatedClusterRoles` | Don't install aggregated Crossplane ClusterRoles. | `false` | +| `rbacManager.tolerations` | Add `tolerations` to the RBAC Manager pod deployment. | `[]` | +| `rbacManager.topologySpreadConstraints` | Add `topologySpreadConstraints` to the RBAC Manager pod deployment. | `[]` | +| `readiness.port` | The port the readyz server listens on. | `""` | +| `registryCaBundleConfig.key` | The ConfigMap key containing a custom CA bundle to enable fetching packages from registries with unknown or untrusted certificates. | `""` | +| `registryCaBundleConfig.name` | The ConfigMap name containing a custom CA bundle to enable fetching packages from registries with unknown or untrusted certificates. | `""` | +| `replicas` | The number of Crossplane pod `replicas` to deploy. | `1` | +| `resourcesCrossplane.limits.cpu` | CPU resource limits for the Crossplane pod. | `"500m"` | +| `resourcesCrossplane.limits.memory` | Memory resource limits for the Crossplane pod. | `"1024Mi"` | +| `resourcesCrossplane.requests.cpu` | CPU resource requests for the Crossplane pod. | `"100m"` | +| `resourcesCrossplane.requests.memory` | Memory resource requests for the Crossplane pod. | `"256Mi"` | +| `resourcesRBACManager.limits.cpu` | CPU resource limits for the RBAC Manager pod. | `"100m"` | +| `resourcesRBACManager.limits.memory` | Memory resource limits for the RBAC Manager pod. | `"512Mi"` | +| `resourcesRBACManager.requests.cpu` | CPU resource requests for the RBAC Manager pod. | `"100m"` | +| `resourcesRBACManager.requests.memory` | Memory resource requests for the RBAC Manager pod. | `"256Mi"` | +| `revisionHistoryLimit` | The number of Crossplane ReplicaSets to retain. | `nil` | +| `runtimeClassName` | The runtimeClassName name to apply to the Crossplane and RBAC Manager pods. | `""` | +| `securityContextCrossplane.allowPrivilegeEscalation` | Enable `allowPrivilegeEscalation` for the Crossplane pod. | `false` | +| `securityContextCrossplane.readOnlyRootFilesystem` | Set the Crossplane pod root file system as read-only. | `true` | +| `securityContextCrossplane.runAsGroup` | The group ID used by the Crossplane pod. | `65532` | +| `securityContextCrossplane.runAsUser` | The user ID used by the Crossplane pod. | `65532` | +| `securityContextRBACManager.allowPrivilegeEscalation` | Enable `allowPrivilegeEscalation` for the RBAC Manager pod. | `false` | +| `securityContextRBACManager.readOnlyRootFilesystem` | Set the RBAC Manager pod root file system as read-only. | `true` | +| `securityContextRBACManager.runAsGroup` | The group ID used by the RBAC Manager pod. | `65532` | +| `securityContextRBACManager.runAsUser` | The user ID used by the RBAC Manager pod. | `65532` | +| `service.customAnnotations` | Configure annotations on the service object. Only enabled when webhooks.enabled = true | `{}` | +| `serviceAccount.create` | Specifies whether Crossplane ServiceAccount should be created | `true` | +| `serviceAccount.customAnnotations` | Add custom `annotations` to the Crossplane ServiceAccount. | `{}` | +| `serviceAccount.name` | Provide the name of an already created Crossplane ServiceAccount. Required when `serviceAccount.create` is `false` | `""` | +| `tolerations` | Add `tolerations` to the Crossplane pod deployment. | `[]` | +| `topologySpreadConstraints` | Add `topologySpreadConstraints` to the Crossplane pod deployment. | `[]` | +| `webhooks.enabled` | Enable webhooks for Crossplane and installed Provider packages. | `true` | +| `webhooks.port` | The port the webhook server listens on. | `""` | + +### Command Line + +You can pass the settings with helm command line parameters. Specify each +parameter using the `--set key=value[,key=value]` argument to `helm install`. +For example, the following command will install Crossplane with an image pull +policy of `IfNotPresent`. + +```console +helm install --namespace crossplane-system crossplane-stable/crossplane --set image.pullPolicy=IfNotPresent +``` + +### Settings File + +Alternatively, a yaml file that specifies the values for the above parameters +(`values.yaml`) can be provided while installing the chart. + +```console +helm install crossplane --namespace crossplane-system crossplane-stable/crossplane -f values.yaml +``` + +Here are the sample settings to get you started. + +```yaml +replicas: 1 + +deploymentStrategy: RollingUpdate + +image: + repository: xpkg.crossplane.io/crossplane/crossplane + tag: alpha + pullPolicy: Always +``` + + + +[Kubernetes cluster]: https://kubernetes.io/docs/setup/ +[Minikube]: https://kubernetes.io/docs/tasks/tools/install-minikube/ +[Helm]: https://docs.helm.sh/using_helm/ + diff --git a/packs/crossplane-2.1.0/charts/crossplane/README.md.gotmpl b/packs/crossplane-2.1.0/charts/crossplane/README.md.gotmpl new file mode 100644 index 00000000..bc6f2b18 --- /dev/null +++ b/packs/crossplane-2.1.0/charts/crossplane/README.md.gotmpl @@ -0,0 +1,112 @@ + +Crossplane can be easily installed into any existing Kubernetes cluster using +the regularly published Helm chart. The Helm chart contains all the custom +resources and controllers needed to deploy and configure Crossplane. + +## Pre-requisites + +* [Kubernetes cluster], minimum version `v1.16.0+` +* [Helm], minimum version `v3.0.0+`. + +## Installation + +Helm charts for Crossplane are currently published to the `stable` and `master` +channels. + +### Stable + +The stable channel is the most recent release of Crossplane that is considered +ready for the community. + +```console +kubectl create namespace crossplane-system + +helm repo add crossplane-stable https://charts.crossplane.io/stable +helm repo update + +helm install crossplane --namespace crossplane-system crossplane-stable/crossplane +``` + +### Master + +The `master` channel contains the latest commits, with all automated tests +passing. `master` is subject to instability, incompatibility, and features may +be added or removed without much prior notice. It is recommended to use one of +the more stable channels, but if you want the absolute newest Crossplane +installed, then you can use the `master` channel. + +To install the Helm chart from master, you will need to pass the specific +version returned by the `search` command: + +```console +kubectl create namespace crossplane-system +helm repo add crossplane-master https://charts.crossplane.io/master/ +helm repo update +helm search repo crossplane-master --devel + +helm install crossplane --namespace crossplane-system crossplane-master/crossplane --devel --version +``` + +## Uninstalling the Chart + +To uninstall/delete the `crossplane` deployment: + +```console +helm delete crossplane --namespace crossplane-system +``` + +That command removes all Kubernetes components associated with Crossplane, +including all the custom resources and controllers. + +## Configuration + +The following tables lists the configurable parameters of the Crossplane chart +and their default values. + +{{ template "chart.valuesTable" . }} + +### Command Line + +You can pass the settings with helm command line parameters. Specify each +parameter using the `--set key=value[,key=value]` argument to `helm install`. +For example, the following command will install Crossplane with an image pull +policy of `IfNotPresent`. + +```console +helm install --namespace crossplane-system crossplane-stable/crossplane --set image.pullPolicy=IfNotPresent +``` + +### Settings File + +Alternatively, a yaml file that specifies the values for the above parameters +(`values.yaml`) can be provided while installing the chart. + +```console +helm install crossplane --namespace crossplane-system crossplane-stable/crossplane -f values.yaml +``` + +Here are the sample settings to get you started. + +```yaml +replicas: 1 + +deploymentStrategy: RollingUpdate + +image: + repository: xpkg.crossplane.io/crossplane/crossplane + tag: alpha + pullPolicy: Always +``` + + + +[Kubernetes cluster]: https://kubernetes.io/docs/setup/ +[Minikube]: https://kubernetes.io/docs/tasks/tools/install-minikube/ +[Helm]: https://docs.helm.sh/using_helm/ +{{ define "chart.valuesTable" }} +| Parameter | Description | Default | +| --- | --- | --- | + {{- range .Values }} +| `{{ .Key }}` | {{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }} | {{ if .Default }}{{ .Default }}{{ else }}{{ .AutoDefault }}{{ end }} | + {{- end }} +{{ end }} diff --git a/packs/crossplane-2.1.0/charts/crossplane/templates/NOTES.txt b/packs/crossplane-2.1.0/charts/crossplane/templates/NOTES.txt new file mode 100644 index 00000000..f1c8a0c6 --- /dev/null +++ b/packs/crossplane-2.1.0/charts/crossplane/templates/NOTES.txt @@ -0,0 +1,8 @@ +Release: {{.Release.Name}} + +Chart Name: {{.Chart.Name}} +Chart Description: {{.Chart.Description}} +Chart Version: {{.Chart.Version}} +Chart Application Version: {{.Chart.AppVersion}} + +Kube Version: {{.Capabilities.KubeVersion}} diff --git a/packs/crossplane-2.1.0/charts/crossplane/templates/_helpers.tpl b/packs/crossplane-2.1.0/charts/crossplane/templates/_helpers.tpl new file mode 100644 index 00000000..ef1c0d4a --- /dev/null +++ b/packs/crossplane-2.1.0/charts/crossplane/templates/_helpers.tpl @@ -0,0 +1,43 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "crossplane.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "crossplane.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Generate basic labels +*/}} +{{- define "crossplane.labels" }} +helm.sh/chart: {{ include "crossplane.chart" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/component: cloud-infrastructure-controller +app.kubernetes.io/part-of: {{ template "crossplane.name" . }} +app.kubernetes.io/name: {{ include "crossplane.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +{{- if .Values.customLabels }} +{{ toYaml .Values.customLabels }} +{{- end }} +{{- end }} + +{{/* +Define ExternalSecretStoreEnabled Feature Flag +*/}} +{{- define "crossplane.externalSecretStoresEnabled" -}} +{{- if has "--enable-external-secret-stores" .Values.args -}} +true +{{- else -}} +false +{{- end -}} +{{- end -}} diff --git a/packs/crossplane-2.1.0/charts/crossplane/templates/clusterrole.yaml b/packs/crossplane-2.1.0/charts/crossplane/templates/clusterrole.yaml new file mode 100644 index 00000000..bc0b3285 --- /dev/null +++ b/packs/crossplane-2.1.0/charts/crossplane/templates/clusterrole.yaml @@ -0,0 +1,108 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "crossplane.name" . }} + labels: + app: {{ template "crossplane.name" . }} + {{- include "crossplane.labels" . | indent 4 }} +{{- if .Values.rbacManager.deploy }} +aggregationRule: + clusterRoleSelectors: + - matchLabels: + rbac.crossplane.io/aggregate-to-crossplane: "true" +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "crossplane.name" . }}:system:aggregate-to-crossplane + labels: + app: {{ template "crossplane.name" . }} + {{- include "crossplane.labels" . | indent 4 }} + crossplane.io/scope: "system" + rbac.crossplane.io/aggregate-to-crossplane: "true" +{{- end }} +rules: +- apiGroups: + - "" + resources: + - events + verbs: + - create + - update + - patch + - delete +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + - customresourcedefinitions/status + verbs: + - "*" +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - serviceaccounts + - services + verbs: + - "*" +- apiGroups: + - apiextensions.crossplane.io + - ops.crossplane.io + - pkg.crossplane.io + - protection.crossplane.io + resources: + - "*" + verbs: + - "*" +- apiGroups: + - extensions + - apps + resources: + - deployments + verbs: + - get + - list + - create + - update + - patch + - delete + - watch +- apiGroups: + - "" + - coordination.k8s.io + resources: + - configmaps + - leases + verbs: + - get + - list + - create + - update + - patch + - watch + - delete +- apiGroups: + - admissionregistration.k8s.io + resources: + - validatingwebhookconfigurations + - mutatingwebhookconfigurations + verbs: + - get + - list + - create + - update + - patch + - watch + - delete diff --git a/packs/crossplane-2.1.0/charts/crossplane/templates/clusterrolebinding.yaml b/packs/crossplane-2.1.0/charts/crossplane/templates/clusterrolebinding.yaml new file mode 100644 index 00000000..9864fe58 --- /dev/null +++ b/packs/crossplane-2.1.0/charts/crossplane/templates/clusterrolebinding.yaml @@ -0,0 +1,19 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "crossplane.name" . }} + labels: + app: {{ template "crossplane.name" . }} + {{- include "crossplane.labels" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "crossplane.name" . }} +subjects: +- kind: ServiceAccount + {{- if not .Values.serviceAccount.create }} + name: {{ .Values.serviceAccount.name }} + {{- else }} + name: {{ template "crossplane.name" . }} + {{- end }} + namespace: {{ .Release.Namespace }} diff --git a/packs/crossplane-2.1.0/charts/crossplane/templates/deployment.yaml b/packs/crossplane-2.1.0/charts/crossplane/templates/deployment.yaml new file mode 100644 index 00000000..b527952b --- /dev/null +++ b/packs/crossplane-2.1.0/charts/crossplane/templates/deployment.yaml @@ -0,0 +1,300 @@ +{{- $externalSecretStoresEnabled := include "crossplane.externalSecretStoresEnabled" . | eq "true" -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "crossplane.name" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "crossplane.name" . }} + release: {{ .Release.Name }} + {{- include "crossplane.labels" . | indent 4 }} + {{- with .Values.customAnnotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.replicas }} + selector: + matchLabels: + app: {{ template "crossplane.name" . }} + release: {{ .Release.Name }} + strategy: + type: {{ .Values.deploymentStrategy }} + {{- if .Values.revisionHistoryLimit }} + revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} + {{- end }} + template: + metadata: + {{- if or .Values.metrics.enabled .Values.customAnnotations }} + annotations: + {{- end }} + {{- if .Values.metrics.enabled }} + prometheus.io/path: /metrics + prometheus.io/port: "8080" + prometheus.io/scrape: "true" + {{- end }} + {{- with .Values.customAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + app: {{ template "crossplane.name" . }} + release: {{ .Release.Name }} + {{- include "crossplane.labels" . | indent 8 }} + spec: + {{- with .Values.podSecurityContextCrossplane }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName | quote }} + {{- end }} + {{- if .Values.runtimeClassName }} + runtimeClassName: {{ .Values.runtimeClassName | quote }} + {{- end }} + {{- if not .Values.serviceAccount.create }} + serviceAccountName: {{ .Values.serviceAccount.name }} + {{- else }} + serviceAccountName: {{ template "crossplane.name" . }} + {{- end }} + hostNetwork: {{ .Values.hostNetwork }} + initContainers: + - name: {{ .Chart.Name }}-init + {{- if .Values.image.ignoreTag }} + image: "{{ .Values.image.repository }}" + {{- else }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default (printf "v%s" .Chart.AppVersion) }}" + {{- end }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - core + - init + {{- range $arg := .Values.provider.packages }} + - --provider + - "{{ $arg }}" + {{- end }} + {{- range $arg := .Values.configuration.packages }} + - --configuration + - "{{ $arg }}" + {{- end }} + {{- range $arg := .Values.function.packages }} + - --function + - "{{ $arg }}" + {{- end }} + {{- range $arg := .Values.provider.defaultActivations }} + - --activation + - "{{ $arg }}" + {{- end }} + resources: + {{- toYaml .Values.resourcesCrossplane | nindent 12 }} + {{- with .Values.securityContextCrossplane }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + env: + - name: GOMAXPROCS + valueFrom: + resourceFieldRef: + containerName: {{ .Chart.Name }}-init + resource: limits.cpu + divisor: "1" + - name: GOMEMLIMIT + valueFrom: + resourceFieldRef: + containerName: {{ .Chart.Name }}-init + resource: limits.memory + divisor: "1" + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + {{- if .Values.webhooks.enabled }} + - name: "WEBHOOK_SERVICE_NAME" + value: {{ template "crossplane.name" . }}-webhooks + - name: "WEBHOOK_SERVICE_NAMESPACE" + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: "WEBHOOK_SERVICE_PORT" + value: "9443" + {{- else }} + - name: "ENABLE_WEBHOOKS" + value: "false" + {{- end }} + {{- if $externalSecretStoresEnabled }} + - name: "ESS_TLS_SERVER_SECRET_NAME" + value: ess-server-certs + {{- end }} + - name: "TLS_CA_SECRET_NAME" + value: crossplane-root-ca + - name: "TLS_SERVER_SECRET_NAME" + value: crossplane-tls-server + - name: "TLS_CLIENT_SECRET_NAME" + value: crossplane-tls-client + {{- range $key, $value := .Values.extraEnvVarsCrossplaneInit }} + - name: {{ $key | replace "." "_" }} + value: {{ $value | quote }} + {{- end}} + containers: + - name: {{ .Chart.Name }} + {{- if .Values.image.ignoreTag }} + image: "{{ .Values.image.repository }}" + {{- else }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default (printf "v%s" .Chart.AppVersion) }}" + {{- end }} + args: + - core + - start + {{- range $arg := .Values.args }} + - {{ $arg }} + {{- end }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + resources: + {{- toYaml .Values.resourcesCrossplane | nindent 12 }} + startupProbe: + failureThreshold: 30 + periodSeconds: 2 + tcpSocket: + port: readyz + ports: + - name: readyz + containerPort: {{ .Values.readiness.port | default 8081 }} + {{- if .Values.metrics.enabled }} + - name: metrics + containerPort: {{ .Values.metrics.port | default 8080 }} + {{- end }} + {{- if .Values.webhooks.enabled }} + - name: webhooks + containerPort: {{ .Values.webhooks.port | default 9443 }} + {{- end }} + {{- with .Values.securityContextCrossplane }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + env: + - name: GOMAXPROCS + valueFrom: + resourceFieldRef: + containerName: {{ .Chart.Name }} + resource: limits.cpu + divisor: "1" + - name: GOMEMLIMIT + valueFrom: + resourceFieldRef: + containerName: {{ .Chart.Name }} + resource: limits.memory + divisor: "1" + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: LEADER_ELECTION + value: "{{ .Values.leaderElection }}" + {{- if .Values.registryCaBundleConfig.key }} + - name: CA_BUNDLE_PATH + value: "/certs/{{ .Values.registryCaBundleConfig.key }}" + {{- end}} + {{- if not .Values.webhooks.enabled }} + - name: "ENABLE_WEBHOOKS" + value: "false" + {{- end }} + {{- if and .Values.webhooks.enabled .Values.webhooks.port }} + - name: "WEBHOOK_PORT" + value: "{{ .Values.webhooks.port }}" + {{- end}} + {{- if and .Values.metrics.enabled .Values.metrics.port }} + - name: "METRICS_PORT" + value: "{{ .Values.metrics.port }}" + {{- end}} + {{- if .Values.readiness.port }} + - name: "HEALTH_PROBE_PORT" + value: "{{ .Values.readiness.port }}" + {{- end}} + - name: "TLS_SERVER_SECRET_NAME" + value: crossplane-tls-server + - name: "TLS_SERVER_CERTS_DIR" + value: /tls/server + - name: "TLS_CLIENT_SECRET_NAME" + value: crossplane-tls-client + - name: "TLS_CLIENT_CERTS_DIR" + value: /tls/client + {{- range $key, $value := .Values.extraEnvVarsCrossplane }} + - name: {{ $key | replace "." "_" }} + value: {{ $value | quote }} + {{- end}} + volumeMounts: + - mountPath: /cache/xpkg + name: package-cache + - mountPath: /cache/xfn + name: function-cache + {{- if .Values.registryCaBundleConfig.name }} + - mountPath: /certs + name: ca-certs + {{- end }} + {{- if .Values.extraVolumeMountsCrossplane }} + {{- toYaml .Values.extraVolumeMountsCrossplane | nindent 10 }} + {{- end }} + - mountPath: /tls/server + name: tls-server-certs + - mountPath: /tls/client + name: tls-client-certs + volumes: + - name: package-cache + {{- if .Values.packageCache.pvc }} + persistentVolumeClaim: + claimName: {{ .Values.packageCache.pvc }} + {{- else if .Values.packageCache.configMap }} + configMap: + name: {{ .Values.packageCache.configMap }} + {{- else }} + emptyDir: + medium: {{ .Values.packageCache.medium }} + sizeLimit: {{ .Values.packageCache.sizeLimit }} + {{- end }} + - name: function-cache + {{- if .Values.functionCache.pvc }} + persistentVolumeClaim: + claimName: {{ .Values.functionCache.pvc }} + {{- else }} + emptyDir: + medium: {{ .Values.functionCache.medium }} + sizeLimit: {{ .Values.functionCache.sizeLimit }} + {{- end }} + {{- if .Values.registryCaBundleConfig.name }} + - name: ca-certs + configMap: + name: {{ .Values.registryCaBundleConfig.name }} + items: + - key: {{ .Values.registryCaBundleConfig.key }} + path: {{ .Values.registryCaBundleConfig.key }} + {{- end }} + - name: tls-server-certs + secret: + secretName: crossplane-tls-server + - name: tls-client-certs + secret: + secretName: crossplane-tls-client + {{- if .Values.extraVolumesCrossplane }} + {{- toYaml .Values.extraVolumesCrossplane | nindent 6 }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: {{ toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} + {{- if .Values.tolerations }} + tolerations: {{ toYaml .Values.tolerations | nindent 6 }} + {{- end }} + {{- if .Values.affinity }} + affinity: {{ toYaml .Values.affinity | nindent 8 }} + {{- end }} + {{- if .Values.topologySpreadConstraints }} + topologySpreadConstraints: {{ toYaml .Values.topologySpreadConstraints | nindent 8 }} + {{- end }} + {{- with .Values.dnsPolicy }} + dnsPolicy: {{ . }} + {{- end }} diff --git a/packs/crossplane-2.1.0/charts/crossplane/templates/extra-objects.yaml b/packs/crossplane-2.1.0/charts/crossplane/templates/extra-objects.yaml new file mode 100644 index 00000000..a9bb3b6b --- /dev/null +++ b/packs/crossplane-2.1.0/charts/crossplane/templates/extra-objects.yaml @@ -0,0 +1,4 @@ +{{ range .Values.extraObjects }} +--- +{{ tpl (toYaml .) $ }} +{{ end }} diff --git a/packs/crossplane-2.1.0/charts/crossplane/templates/rbac-manager-allowed-provider-permissions.yaml b/packs/crossplane-2.1.0/charts/crossplane/templates/rbac-manager-allowed-provider-permissions.yaml new file mode 100644 index 00000000..9a373fff --- /dev/null +++ b/packs/crossplane-2.1.0/charts/crossplane/templates/rbac-manager-allowed-provider-permissions.yaml @@ -0,0 +1,14 @@ +{{- if .Values.rbacManager.deploy }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "crossplane.name" . }}:allowed-provider-permissions + labels: + app: {{ template "crossplane.name" . }} + {{- include "crossplane.labels" . | indent 4 }} +aggregationRule: + clusterRoleSelectors: + - matchLabels: + rbac.crossplane.io/aggregate-to-allowed-provider-permissions: "true" +{{- end}} \ No newline at end of file diff --git a/packs/crossplane-2.1.0/charts/crossplane/templates/rbac-manager-clusterrole.yaml b/packs/crossplane-2.1.0/charts/crossplane/templates/rbac-manager-clusterrole.yaml new file mode 100644 index 00000000..8943b5f5 --- /dev/null +++ b/packs/crossplane-2.1.0/charts/crossplane/templates/rbac-manager-clusterrole.yaml @@ -0,0 +1,135 @@ +{{- if .Values.rbacManager.deploy }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "crossplane.name" . }}-rbac-manager + labels: + app: {{ template "crossplane.name" . }} + {{- include "crossplane.labels" . | indent 4 }} +rules: +- apiGroups: + - "" + resources: + - events + verbs: + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - list + - watch +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - watch +# The RBAC manager creates a series of RBAC roles for each namespace it sees. +# These RBAC roles are controlled (in the owner reference sense) by the namespace. +# The RBAC manager needs permission to set finalizers on Namespaces in order to +# create resources that block their deletion when the +# OwnerReferencesPermissionEnforcement admission controller is enabled. +# See https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#ownerreferencespermissionenforcement +- apiGroups: + - "" + resources: + - namespaces/finalizers + verbs: + - update +- apiGroups: + - apiextensions.crossplane.io + resources: + - compositeresourcedefinitions + verbs: + - get + - list + - watch +# The RBAC manager creates a series of RBAC cluster roles for each XRD it sees. +# These cluster roles are controlled (in the owner reference sense) by the XRD. +# The RBAC manager needs permission to set finalizers on XRDs in order to +# create resources that block their deletion when the +# OwnerReferencesPermissionEnforcement admission controller is enabled. +# See https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#ownerreferencespermissionenforcement +- apiGroups: + - apiextensions.crossplane.io + resources: + - compositeresourcedefinitions/finalizers + verbs: + - update +- apiGroups: + - pkg.crossplane.io + resources: + - providerrevisions + verbs: + - get + - list + - watch +# The RBAC manager creates a series of RBAC cluster roles for each ProviderRevision +# it sees. These cluster roles are controlled (in the owner reference sense) by the +# ProviderRevision. The RBAC manager needs permission to set finalizers on +# ProviderRevisions in order to create resources that block their deletion when the +# OwnerReferencesPermissionEnforcement admission controller is enabled. +# See https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#ownerreferencespermissionenforcement +- apiGroups: + - pkg.crossplane.io + resources: + - providerrevisions/finalizers + verbs: + - update +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - get + - list + - watch +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterroles + - roles + verbs: + - get + - list + - watch + - create + - update + - patch + # The RBAC manager may grant access it does not have. + - escalate +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterroles + verbs: + - bind +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + verbs: + - "*" +- apiGroups: + - "" + - coordination.k8s.io + resources: + - configmaps + - leases + verbs: + - get + - list + - create + - update + - patch + - watch + - delete +{{- end}} diff --git a/packs/crossplane-2.1.0/charts/crossplane/templates/rbac-manager-clusterrolebinding.yaml b/packs/crossplane-2.1.0/charts/crossplane/templates/rbac-manager-clusterrolebinding.yaml new file mode 100644 index 00000000..56e0300b --- /dev/null +++ b/packs/crossplane-2.1.0/charts/crossplane/templates/rbac-manager-clusterrolebinding.yaml @@ -0,0 +1,17 @@ +{{- if .Values.rbacManager.deploy }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "crossplane.name" . }}-rbac-manager + labels: + app: {{ template "crossplane.name" . }} + {{- include "crossplane.labels" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "crossplane.name" . }}-rbac-manager +subjects: +- kind: ServiceAccount + name: rbac-manager + namespace: {{ .Release.Namespace }} +{{- end}} \ No newline at end of file diff --git a/packs/crossplane-2.1.0/charts/crossplane/templates/rbac-manager-deployment.yaml b/packs/crossplane-2.1.0/charts/crossplane/templates/rbac-manager-deployment.yaml new file mode 100644 index 00000000..f2a85e53 --- /dev/null +++ b/packs/crossplane-2.1.0/charts/crossplane/templates/rbac-manager-deployment.yaml @@ -0,0 +1,141 @@ +{{- if .Values.rbacManager.deploy }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "crossplane.name" . }}-rbac-manager + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "crossplane.name" . }}-rbac-manager + release: {{ .Release.Name }} + {{- include "crossplane.labels" . | indent 4 }} + {{- with .Values.customAnnotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.rbacManager.replicas }} + selector: + matchLabels: + app: {{ template "crossplane.name" . }}-rbac-manager + release: {{ .Release.Name }} + strategy: + type: {{ .Values.deploymentStrategy }} + {{- if .Values.rbacManager.revisionHistoryLimit }} + revisionHistoryLimit: {{ .Values.rbacManager.revisionHistoryLimit }} + {{- end }} + template: + metadata: + {{- if or .Values.metrics.enabled .Values.customAnnotations }} + annotations: + {{- end }} + {{- if .Values.metrics.enabled }} + prometheus.io/path: /metrics + prometheus.io/port: "8080" + prometheus.io/scrape: "true" + {{- end }} + {{- with .Values.customAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + app: {{ template "crossplane.name" . }}-rbac-manager + release: {{ .Release.Name }} + {{- include "crossplane.labels" . | indent 8 }} + spec: + {{- with .Values.podSecurityContextRBACManager }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName | quote }} + {{- end }} + serviceAccountName: rbac-manager + {{- if .Values.runtimeClassName }} + runtimeClassName: {{ .Values.runtimeClassName | quote }} + {{- end }} + initContainers: + - name: {{ .Chart.Name }}-init + {{- if .Values.image.ignoreTag }} + image: "{{ .Values.image.repository }}" + {{- else }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default (printf "v%s" .Chart.AppVersion) }}" + {{- end }} + args: + - rbac + - init + imagePullPolicy: {{ .Values.image.pullPolicy }} + resources: + {{- toYaml .Values.resourcesRBACManager | nindent 12 }} + {{- with .Values.securityContextRBACManager }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + env: + - name: GOMAXPROCS + valueFrom: + resourceFieldRef: + containerName: {{ .Chart.Name }}-init + resource: limits.cpu + divisor: "1" + - name: GOMEMLIMIT + valueFrom: + resourceFieldRef: + containerName: {{ .Chart.Name }}-init + resource: limits.memory + divisor: "1" + containers: + - name: {{ .Chart.Name }} + {{- if .Values.image.ignoreTag }} + image: "{{ .Values.image.repository }}" + {{- else }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default (printf "v%s" .Chart.AppVersion) }}" + {{- end }} + args: + - rbac + - start + {{- range $arg := .Values.rbacManager.args }} + - {{ $arg }} + {{- end }} + - --provider-clusterrole={{ template "crossplane.name" . }}:allowed-provider-permissions + imagePullPolicy: {{ .Values.image.pullPolicy }} + resources: + {{- toYaml .Values.resourcesRBACManager | nindent 12 }} + {{- if .Values.metrics.enabled }} + ports: + - name: metrics + containerPort: 8080 + {{- end }} + {{- with .Values.securityContextRBACManager }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + env: + - name: GOMAXPROCS + valueFrom: + resourceFieldRef: + containerName: {{ .Chart.Name }} + resource: limits.cpu + divisor: "1" + - name: GOMEMLIMIT + valueFrom: + resourceFieldRef: + containerName: {{ .Chart.Name }} + resource: limits.memory + divisor: "1" + - name: LEADER_ELECTION + value: "{{ .Values.rbacManager.leaderElection }}" + {{- range $key, $value := .Values.extraEnvVarsRBACManager }} + - name: {{ $key | replace "." "_" }} + value: {{ $value | quote }} + {{- end}} + {{- if .Values.rbacManager.nodeSelector }} + nodeSelector: {{ toYaml .Values.rbacManager.nodeSelector | nindent 8 }} + {{- end }} + {{- if .Values.rbacManager.tolerations }} + tolerations: {{ toYaml .Values.rbacManager.tolerations | nindent 6 }} + {{- end }} + {{- if .Values.rbacManager.topologySpreadConstraints }} + topologySpreadConstraints: {{ toYaml .Values.rbacManager.topologySpreadConstraints | nindent 6 }} + {{- end }} + {{- if .Values.rbacManager.affinity }} + affinity: {{ toYaml .Values.rbacManager.affinity | nindent 8 }} + {{- end }} +{{- end}} diff --git a/packs/crossplane-2.1.0/charts/crossplane/templates/rbac-manager-managed-clusterroles.yaml b/packs/crossplane-2.1.0/charts/crossplane/templates/rbac-manager-managed-clusterroles.yaml new file mode 100644 index 00000000..14fb96f6 --- /dev/null +++ b/packs/crossplane-2.1.0/charts/crossplane/templates/rbac-manager-managed-clusterroles.yaml @@ -0,0 +1,227 @@ +{{- if .Values.rbacManager.deploy }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "crossplane.name" . }}-admin + labels: + app: {{ template "crossplane.name" . }} + {{- include "crossplane.labels" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "crossplane.name" . }}-admin +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: Group + name: {{ template "crossplane.name" . }}:masters +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "crossplane.name" . }}-admin + labels: + app: {{ template "crossplane.name" . }} + {{- include "crossplane.labels" . | indent 4 }} +aggregationRule: + clusterRoleSelectors: + - matchLabels: + rbac.crossplane.io/aggregate-to-admin: "true" +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "crossplane.name" . }}-edit + labels: + app: {{ template "crossplane.name" . }} + {{- include "crossplane.labels" . | indent 4 }} +aggregationRule: + clusterRoleSelectors: + - matchLabels: + rbac.crossplane.io/aggregate-to-edit: "true" +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "crossplane.name" . }}-view + labels: + app: {{ template "crossplane.name" . }} + {{- include "crossplane.labels" . | indent 4 }} +aggregationRule: + clusterRoleSelectors: + - matchLabels: + rbac.crossplane.io/aggregate-to-view: "true" +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "crossplane.name" . }}-browse + labels: + app: {{ template "crossplane.name" . }} + {{- include "crossplane.labels" . | indent 4 }} +aggregationRule: + clusterRoleSelectors: + - matchLabels: + rbac.crossplane.io/aggregate-to-browse: "true" +{{- if not .Values.rbacManager.skipAggregatedClusterRoles }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "crossplane.name" . }}:aggregate-to-admin + labels: + rbac.crossplane.io/aggregate-to-admin: "true" + app: {{ template "crossplane.name" . }} + {{- include "crossplane.labels" . | indent 4 }} +rules: +# Crossplane administrators have access to view events. +- apiGroups: [""] + resources: [events] + verbs: [get, list, watch] +# Crossplane administrators must create provider credential secrets, and may +# need to read or otherwise interact with connection secrets. They may also need +# to create or annotate namespaces. +- apiGroups: [""] + resources: [secrets, namespaces] + verbs: ["*"] +# Crossplane administrators have access to view the roles that they may be able +# to grant to other subjects. +- apiGroups: [rbac.authorization.k8s.io] + resources: [clusterroles, roles] + verbs: [get, list, watch] +# Crossplane administrators have access to grant the access they have to other +# subjects. +- apiGroups: [rbac.authorization.k8s.io] + resources: [clusterrolebindings, rolebindings] + verbs: ["*"] +# Crossplane administrators have full access to built in Crossplane types. +- apiGroups: + - apiextensions.crossplane.io + resources: ["*"] + verbs: ["*"] +- apiGroups: + - pkg.crossplane.io + resources: ["*"] + verbs: ["*"] +- apiGroups: + - secrets.crossplane.io + resources: ["*"] + verbs: ["*"] +# Crossplane administrators have access to view CRDs in order to debug XRDs. +- apiGroups: [apiextensions.k8s.io] + resources: [customresourcedefinitions] + verbs: [get, list, watch] +- apiGroups: + - protection.crossplane.io + resources: ["*"] + verbs: ["*"] +- apiGroups: + - ops.crossplane.io + resources: ["*"] + verbs: ["*"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "crossplane.name" . }}:aggregate-to-edit + labels: + rbac.crossplane.io/aggregate-to-edit: "true" + app: {{ template "crossplane.name" . }} + {{- include "crossplane.labels" . | indent 4 }} +rules: +# Crossplane editors have access to view events. +- apiGroups: [""] + resources: [events] + verbs: [get, list, watch] +# Crossplane editors must create provider credential secrets, and may need to +# read or otherwise interact with connection secrets. +- apiGroups: [""] + resources: [secrets] + verbs: ["*"] +# Crossplane editors may see which namespaces exist, but not edit them. +- apiGroups: [""] + resources: [namespaces] + verbs: [get, list, watch] +# Crossplane editors have full access to built in Crossplane types. +- apiGroups: + - apiextensions.crossplane.io + resources: ["*"] + verbs: ["*"] +- apiGroups: + - pkg.crossplane.io + resources: ["*"] + verbs: ["*"] +- apiGroups: + - secrets.crossplane.io + resources: ["*"] + verbs: ["*"] +- apiGroups: + - protection.crossplane.io + resources: ["*"] + verbs: ["*"] +- apiGroups: + - ops.crossplane.io + resources: ["*"] + verbs: ["*"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "crossplane.name" . }}:aggregate-to-view + labels: + rbac.crossplane.io/aggregate-to-view: "true" + app: {{ template "crossplane.name" . }} + {{- include "crossplane.labels" . | indent 4 }} +rules: +# Crossplane viewers have access to view events. +- apiGroups: [""] + resources: [events] + verbs: [get, list, watch] +# Crossplane viewers may see which namespaces exist. +- apiGroups: [""] + resources: [namespaces] + verbs: [get, list, watch] +# Crossplane viewers have read-only access to built in Crossplane types. +- apiGroups: + - apiextensions.crossplane.io + resources: ["*"] + verbs: [get, list, watch] +- apiGroups: + - pkg.crossplane.io + resources: ["*"] + verbs: [get, list, watch] +- apiGroups: + - secrets.crossplane.io + resources: ["*"] + verbs: [get, list, watch] +- apiGroups: + - protection.crossplane.io + resources: ["*"] + verbs: [get, list, watch] +- apiGroups: + - ops.crossplane.io + resources: ["*"] + verbs: [get, list, watch] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "crossplane.name" . }}:aggregate-to-browse + labels: + rbac.crossplane.io/aggregate-to-browse: "true" + app: {{ template "crossplane.name" . }} + {{- include "crossplane.labels" . | indent 4 }} +rules: +# Crossplane browsers have access to view events. +- apiGroups: [""] + resources: [events] + verbs: [get, list, watch] +# Crossplane browsers have read-only access to compositions and XRDs. This +# allows them to discover and select an appropriate composition when creating a +# resource claim. +- apiGroups: + - apiextensions.crossplane.io + resources: ["*"] + verbs: [get, list, watch] +{{- end }} +{{- end }} diff --git a/packs/crossplane-2.1.0/charts/crossplane/templates/rbac-manager-serviceaccount.yaml b/packs/crossplane-2.1.0/charts/crossplane/templates/rbac-manager-serviceaccount.yaml new file mode 100644 index 00000000..fd1dcc97 --- /dev/null +++ b/packs/crossplane-2.1.0/charts/crossplane/templates/rbac-manager-serviceaccount.yaml @@ -0,0 +1,16 @@ +{{- if .Values.rbacManager.deploy }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: rbac-manager + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "crossplane.name" . }} + {{- include "crossplane.labels" . | indent 4 }} +{{- with .Values.imagePullSecrets }} +imagePullSecrets: +{{- range $index, $secret := . }} +- name: {{ $secret }} +{{- end }} +{{- end }} +{{- end}} \ No newline at end of file diff --git a/packs/crossplane-2.1.0/charts/crossplane/templates/secret.yaml b/packs/crossplane-2.1.0/charts/crossplane/templates/secret.yaml new file mode 100644 index 00000000..78d05eb7 --- /dev/null +++ b/packs/crossplane-2.1.0/charts/crossplane/templates/secret.yaml @@ -0,0 +1,43 @@ +{{- $externalSecretStoresEnabled := include "crossplane.externalSecretStoresEnabled" . | eq "true" -}} +{{- if $externalSecretStoresEnabled }} +--- +# The reason this is created empty and filled by the init container is we want +# to manage the lifecycle of the secret via Helm. This way whenever Crossplane +# is deleted, the secret is deleted as well. +apiVersion: v1 +kind: Secret +metadata: + name: ess-server-certs + namespace: {{ .Release.Namespace }} +type: Opaque +{{- end }} +--- +# The reason this is created empty and filled by the init container is we want +# to manage the lifecycle of the secret via Helm. This way whenever Crossplane +# is deleted, the secret is deleted as well. +apiVersion: v1 +kind: Secret +metadata: + name: crossplane-root-ca + namespace: {{ .Release.Namespace }} +type: Opaque +--- +# The reason this is created empty and filled by the init container is we want +# to manage the lifecycle of the secret via Helm. This way whenever Crossplane +# is deleted, the secret is deleted as well. +apiVersion: v1 +kind: Secret +metadata: + name: crossplane-tls-server + namespace: {{ .Release.Namespace }} +type: Opaque +--- +# The reason this is created empty and filled by the init container is we want +# to manage the lifecycle of the secret via Helm. This way whenever Crossplane +# is deleted, the secret is deleted as well. +apiVersion: v1 +kind: Secret +metadata: + name: crossplane-tls-client + namespace: {{ .Release.Namespace }} +type: Opaque \ No newline at end of file diff --git a/packs/crossplane-2.1.0/charts/crossplane/templates/service.yaml b/packs/crossplane-2.1.0/charts/crossplane/templates/service.yaml new file mode 100644 index 00000000..c807e7be --- /dev/null +++ b/packs/crossplane-2.1.0/charts/crossplane/templates/service.yaml @@ -0,0 +1,25 @@ +{{- if .Values.webhooks.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "crossplane.name" . }}-webhooks + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "crossplane.name" . }} + release: {{ .Release.Name }} + {{- include "crossplane.labels" . | indent 4 }} + annotations: + {{- with .Values.service.customAnnotations }} + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +spec: + selector: + app: {{ template "crossplane.name" . }} + release: {{ .Release.Name }} + ports: + - protocol: TCP + port: 9443 + targetPort: {{ .Values.webhooks.port | default 9443 }} +{{- end }} diff --git a/packs/crossplane-2.1.0/charts/crossplane/templates/serviceaccount.yaml b/packs/crossplane-2.1.0/charts/crossplane/templates/serviceaccount.yaml new file mode 100644 index 00000000..e711adf8 --- /dev/null +++ b/packs/crossplane-2.1.0/charts/crossplane/templates/serviceaccount.yaml @@ -0,0 +1,19 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "crossplane.name" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "crossplane.name" . }} + {{- include "crossplane.labels" . | indent 4 }} + {{- with .Values.serviceAccount.customAnnotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} +{{- with .Values.imagePullSecrets }} +imagePullSecrets: +{{- range $index, $secret := . }} +- name: {{ $secret }} +{{- end }} +{{ end }} +{{- end }} \ No newline at end of file diff --git a/packs/crossplane-2.1.0/charts/crossplane/values.yaml b/packs/crossplane-2.1.0/charts/crossplane/values.yaml new file mode 100644 index 00000000..2f7afb91 --- /dev/null +++ b/packs/crossplane-2.1.0/charts/crossplane/values.yaml @@ -0,0 +1,215 @@ +# helm-docs renders these comments into markdown. Use markdown formatting where +# appropiate. +# +# -- The number of Crossplane pod `replicas` to deploy. +replicas: 1 + +# -- The number of Crossplane ReplicaSets to retain. +revisionHistoryLimit: null + +# -- The deployment strategy for the Crossplane and RBAC Manager pods. +deploymentStrategy: RollingUpdate + +image: + # -- Repository for the Crossplane pod image. + repository: xpkg.crossplane.io/crossplane/crossplane + # -- The Crossplane image tag. Defaults to the value of `appVersion` in `Chart.yaml`. + tag: "" + # -- The image pull policy used for Crossplane and RBAC Manager pods. + pullPolicy: IfNotPresent + # -- Do not use the {{ .image.tag }} value to compute the image uri. + ignoreTag: false + +# -- Add `nodeSelectors` to the Crossplane pod deployment. +nodeSelector: {} +# -- Add `tolerations` to the Crossplane pod deployment. +tolerations: [] +# -- Add `affinities` to the Crossplane pod deployment. +affinity: {} +# -- Add `topologySpreadConstraints` to the Crossplane pod deployment. +topologySpreadConstraints: [] + +# -- Enable `hostNetwork` for the Crossplane deployment. Caution: enabling `hostNetwork` grants the Crossplane Pod access to the host network namespace. Consider setting `dnsPolicy` to `ClusterFirstWithHostNet`. +hostNetwork: false + +# -- Specify the `dnsPolicy` to be used by the Crossplane pod. +dnsPolicy: "" + +# -- Add custom `labels` to the Crossplane pod deployment. +customLabels: {} + +# -- Add custom `annotations` to the Crossplane pod deployment. +customAnnotations: {} + +serviceAccount: + # -- Specifies whether Crossplane ServiceAccount should be created + create: true + # -- Provide the name of an already created Crossplane ServiceAccount. Required when `serviceAccount.create` is `false` + name: "" + # -- Add custom `annotations` to the Crossplane ServiceAccount. + customAnnotations: {} + +# -- Enable [leader election](https://docs.crossplane.io/latest/concepts/pods/#leader-election) for the Crossplane pod. +leaderElection: true +# -- Add custom arguments to the Crossplane pod. +args: [] + +provider: + # -- A list of Provider packages to install. + packages: [] + # -- Define entries for the default managed resource activation policy. If defined, a default MRAP will contain these activations. + defaultActivations: ["*"] + +configuration: + # -- A list of Configuration packages to install. + packages: [] + +function: + # -- A list of Function packages to install + packages: [] + +# -- The imagePullSecret names to add to the Crossplane ServiceAccount. +imagePullSecrets: [] + +registryCaBundleConfig: + # -- The ConfigMap name containing a custom CA bundle to enable fetching packages from registries with unknown or untrusted certificates. + name: "" + # -- The ConfigMap key containing a custom CA bundle to enable fetching packages from registries with unknown or untrusted certificates. + key: "" + +service: + # -- Configure annotations on the service object. Only enabled when webhooks.enabled = true + customAnnotations: {} + +webhooks: + # -- Enable webhooks for Crossplane and installed Provider packages. + enabled: true + # -- The port the webhook server listens on. + port: "" + +rbacManager: + # -- Deploy the RBAC Manager pod and its required roles. + deploy: true + # -- Don't install aggregated Crossplane ClusterRoles. + skipAggregatedClusterRoles: false + # -- The number of RBAC Manager pod `replicas` to deploy. + replicas: 1 + # -- The number of RBAC Manager ReplicaSets to retain. + revisionHistoryLimit: null + # -- Enable [leader election](https://docs.crossplane.io/latest/concepts/pods/#leader-election) for the RBAC Manager pod. + leaderElection: true + # -- Add custom arguments to the RBAC Manager pod. + args: [] + # -- Add `nodeSelectors` to the RBAC Manager pod deployment. + nodeSelector: {} + # -- Add `tolerations` to the RBAC Manager pod deployment. + tolerations: [] + # -- Add `affinities` to the RBAC Manager pod deployment. + affinity: {} + # -- Add `topologySpreadConstraints` to the RBAC Manager pod deployment. + topologySpreadConstraints: [] + +# -- The PriorityClass name to apply to the Crossplane and RBAC Manager pods. +priorityClassName: "" + +# -- The runtimeClassName name to apply to the Crossplane and RBAC Manager pods. +runtimeClassName: "" + +resourcesCrossplane: + limits: + # -- CPU resource limits for the Crossplane pod. + cpu: 500m + # -- Memory resource limits for the Crossplane pod. + memory: 1024Mi + requests: + # -- CPU resource requests for the Crossplane pod. + cpu: 100m + # -- Memory resource requests for the Crossplane pod. + memory: 256Mi + +securityContextCrossplane: + # -- The user ID used by the Crossplane pod. + runAsUser: 65532 + # -- The group ID used by the Crossplane pod. + runAsGroup: 65532 + # -- Enable `allowPrivilegeEscalation` for the Crossplane pod. + allowPrivilegeEscalation: false + # -- Set the Crossplane pod root file system as read-only. + readOnlyRootFilesystem: true + +packageCache: + # -- Set to `Memory` to hold the package cache in a RAM backed file system. Useful for Crossplane development. + medium: "" + # -- The size limit for the package cache. If medium is `Memory` the `sizeLimit` can't exceed Node memory. + sizeLimit: 20Mi + # -- The name of a PersistentVolumeClaim to use as the package cache. Disables the default package cache `emptyDir` Volume. + pvc: "" + # -- The name of a ConfigMap to use as the package cache. Disables the default package cache `emptyDir` Volume. + configMap: "" + +functionCache: + # -- Set to `Memory` to hold the function cache in a RAM backed file system. Useful for Crossplane development. + medium: "" + # -- The size limit for the function cache. If medium is `Memory` the `sizeLimit` can't exceed Node memory. + sizeLimit: 512Mi + # -- The name of a PersistentVolumeClaim to use as the function cache. Disables the default function cache `emptyDir` Volume. + pvc: "" + +resourcesRBACManager: + limits: + # -- CPU resource limits for the RBAC Manager pod. + cpu: 100m + # -- Memory resource limits for the RBAC Manager pod. + memory: 512Mi + requests: + # -- CPU resource requests for the RBAC Manager pod. + cpu: 100m + # -- Memory resource requests for the RBAC Manager pod. + memory: 256Mi + +securityContextRBACManager: + # -- The user ID used by the RBAC Manager pod. + runAsUser: 65532 + # -- The group ID used by the RBAC Manager pod. + runAsGroup: 65532 + # -- Enable `allowPrivilegeEscalation` for the RBAC Manager pod. + allowPrivilegeEscalation: false + # -- Set the RBAC Manager pod root file system as read-only. + readOnlyRootFilesystem: true + +metrics: + # -- Enable Prometheus path, port and scrape annotations and expose port 8080 for both the Crossplane and RBAC Manager pods. + enabled: false + # -- The port the metrics server listens on. + port: "" + +readiness: + # -- The port the readyz server listens on. + port: "" + +# -- Add custom environmental variables to the Crossplane pod deployment init container. +# Replaces any `.` in a variable name with `_`. For example, `SAMPLE.KEY=value1` becomes `SAMPLE_KEY=value1`. +extraEnvVarsCrossplaneInit: {} + +# -- Add custom environmental variables to the Crossplane pod deployment application container. +# Replaces any `.` in a variable name with `_`. For example, `SAMPLE.KEY=value1` becomes `SAMPLE_KEY=value1`. +extraEnvVarsCrossplane: {} + +# -- Add custom environmental variables to the RBAC Manager pod deployment. +# Replaces any `.` in a variable name with `_`. For example, `SAMPLE.KEY=value1` becomes `SAMPLE_KEY=value1`. +extraEnvVarsRBACManager: {} + +# -- Add a custom `securityContext` to the Crossplane pod. +podSecurityContextCrossplane: {} + +# -- Add a custom `securityContext` to the RBAC Manager pod. +podSecurityContextRBACManager: {} + +# -- Add custom `volumes` to the Crossplane pod. +extraVolumesCrossplane: {} + +# -- Add custom `volumeMounts` to the Crossplane pod. +extraVolumeMountsCrossplane: {} + +# -- To add arbitrary Kubernetes Objects during a Helm Install +extraObjects: [] diff --git a/packs/crossplane-2.1.0/logo.png b/packs/crossplane-2.1.0/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..94280b87bc667f8700a8c06d52561f7354f3b6a8 GIT binary patch literal 91169 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 A!T Date: Fri, 14 Nov 2025 02:17:33 -0500 Subject: [PATCH 8/8] add constraints pack --- packs/crossplane-2.1.0/pack.json | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/packs/crossplane-2.1.0/pack.json b/packs/crossplane-2.1.0/pack.json index 9683b680..3bff9b17 100644 --- a/packs/crossplane-2.1.0/pack.json +++ b/packs/crossplane-2.1.0/pack.json @@ -13,6 +13,26 @@ ], "layer":"addon", "name": "crossplane", - "version": "2.1.0" + "version": "2.1.0", + "constraints": { + "dependencies": [ + { + "packName": "kubernetes", + "layer": "k8s", + "minVersion": "1.27", + "maxVersion": "", + "type": "optional" + } + ], + "resources": [ + { + "type": "cpu", + "minLimit": 100 + }, + { + "type": "memory", + "minLimit": 256 + } + ] } - \ No newline at end of file +} \ No newline at end of file