From 8019862c29746d090acf5871171934d5c2dc7685 Mon Sep 17 00:00:00 2001 From: Njal Karevoll Date: Fri, 7 Jun 2019 22:48:19 +0200 Subject: [PATCH 1/8] Add an elstic-internal prefix to the init container names. The new names are defined as consts to provide a slightly better overview. --- .../elasticsearch/initcontainer/initcontainer.go | 12 ++++++++++-- .../{inject_pm.go => inject_process_manager.go} | 2 +- .../elasticsearch/initcontainer/os_settings.go | 3 ++- .../elasticsearch/initcontainer/prepare_fs.go | 2 +- .../{script.go => prepare_fs_script.go} | 0 .../{script_test.go => prepare_fs_script_test.go} | 0 6 files changed, 14 insertions(+), 5 deletions(-) rename operators/pkg/controller/elasticsearch/initcontainer/{inject_pm.go => inject_process_manager.go} (95%) rename operators/pkg/controller/elasticsearch/initcontainer/{script.go => prepare_fs_script.go} (100%) rename operators/pkg/controller/elasticsearch/initcontainer/{script_test.go => prepare_fs_script_test.go} (100%) diff --git a/operators/pkg/controller/elasticsearch/initcontainer/initcontainer.go b/operators/pkg/controller/elasticsearch/initcontainer/initcontainer.go index 1e3bf49293..c0c5302fff 100644 --- a/operators/pkg/controller/elasticsearch/initcontainer/initcontainer.go +++ b/operators/pkg/controller/elasticsearch/initcontainer/initcontainer.go @@ -12,6 +12,15 @@ import ( // defaultInitContainerRunAsUser is the user id the init container should run as const defaultInitContainerRunAsUser int64 = 0 +const ( + // injectProcessManagerContainerName is the name of the container that injects the process manager + injectProcessManagerContainerName = "elastic-internal-init-process-manager" + // osSettingsContainerName is the name of the container that tweaks os-level settings + osSettingsContainerName = "elastic-internal-init-os-settings" + // prepareFilesystemContainerName is the name of the container that prepares the filesystem + prepareFilesystemContainerName = "elastic-internal-init-filesystem" +) + // NewInitContainers creates init containers according to the given parameters func NewInitContainers( elasticsearchImage string, @@ -19,7 +28,6 @@ func NewInitContainers( linkedFiles LinkedFilesArray, setVMMaxMapCount *bool, transportCertificatesVolume volume.SecretVolume, - additional ...corev1.Container, ) ([]corev1.Container, error) { var containers []corev1.Container // create the privileged init container if not explicitly disabled by the user @@ -41,6 +49,6 @@ func NewInitContainers( } containers = append(containers, prepareFsContainer, injectProcessManager) - containers = append(containers, additional...) + return containers, nil } diff --git a/operators/pkg/controller/elasticsearch/initcontainer/inject_pm.go b/operators/pkg/controller/elasticsearch/initcontainer/inject_process_manager.go similarity index 95% rename from operators/pkg/controller/elasticsearch/initcontainer/inject_pm.go rename to operators/pkg/controller/elasticsearch/initcontainer/inject_process_manager.go index 7f75aea088..f2ca601448 100644 --- a/operators/pkg/controller/elasticsearch/initcontainer/inject_pm.go +++ b/operators/pkg/controller/elasticsearch/initcontainer/inject_process_manager.go @@ -29,7 +29,7 @@ func NewInjectProcessManagerInitContainer(imageName string) (corev1.Container, e Env: []corev1.EnvVar{ {Name: envBinDirectoryPath, Value: ProcessManagerVolume.InitContainerMountPath}, }, - Name: "inject-process-manager", + Name: injectProcessManagerContainerName, Command: []string{"bash", "-c", script}, VolumeMounts: []corev1.VolumeMount{ProcessManagerVolume.InitContainerVolumeMount()}, } diff --git a/operators/pkg/controller/elasticsearch/initcontainer/os_settings.go b/operators/pkg/controller/elasticsearch/initcontainer/os_settings.go index 3962f43015..69d57aa749 100644 --- a/operators/pkg/controller/elasticsearch/initcontainer/os_settings.go +++ b/operators/pkg/controller/elasticsearch/initcontainer/os_settings.go @@ -19,10 +19,11 @@ const VMMaxMapCount = 262144 func NewOSSettingsInitContainer(imageName string) (corev1.Container, error) { privileged := true initContainerRunAsUser := defaultInitContainerRunAsUser + container := corev1.Container{ Image: imageName, ImagePullPolicy: corev1.PullIfNotPresent, - Name: "tweak-os-settings", + Name: osSettingsContainerName, SecurityContext: &corev1.SecurityContext{ Privileged: &privileged, RunAsUser: &initContainerRunAsUser, diff --git a/operators/pkg/controller/elasticsearch/initcontainer/prepare_fs.go b/operators/pkg/controller/elasticsearch/initcontainer/prepare_fs.go index 82ed5889c4..7376bd976c 100644 --- a/operators/pkg/controller/elasticsearch/initcontainer/prepare_fs.go +++ b/operators/pkg/controller/elasticsearch/initcontainer/prepare_fs.go @@ -92,7 +92,7 @@ func NewPrepareFSInitContainer( container := corev1.Container{ Image: imageName, ImagePullPolicy: corev1.PullIfNotPresent, - Name: "prepare-fs", + Name: prepareFilesystemContainerName, SecurityContext: &corev1.SecurityContext{ Privileged: &privileged, RunAsUser: &initContainerRunAsUser, diff --git a/operators/pkg/controller/elasticsearch/initcontainer/script.go b/operators/pkg/controller/elasticsearch/initcontainer/prepare_fs_script.go similarity index 100% rename from operators/pkg/controller/elasticsearch/initcontainer/script.go rename to operators/pkg/controller/elasticsearch/initcontainer/prepare_fs_script.go diff --git a/operators/pkg/controller/elasticsearch/initcontainer/script_test.go b/operators/pkg/controller/elasticsearch/initcontainer/prepare_fs_script_test.go similarity index 100% rename from operators/pkg/controller/elasticsearch/initcontainer/script_test.go rename to operators/pkg/controller/elasticsearch/initcontainer/prepare_fs_script_test.go From 9f8969a5b8b8fa4fe3a35974e76a1e3907b28505 Mon Sep 17 00:00:00 2001 From: Njal Karevoll Date: Sat, 8 Jun 2019 00:29:51 +0200 Subject: [PATCH 2/8] Normalize volumes, mounts, users and roles for ES Adds `-internal` to several things that should be considered internals. Removes some no longer used (and mislabeled) "version specific" resources, such as a generic ConfigMap and Secret. Internal mounts are now mounted to directories under `/mnt/elastic-internal`. Internal users has the `elastic-internal-` prefix and roles has the `elastic_internal_` prefix. Since data and logs directories for ES are not considered internals, they now have the canonical names `elasticsearch-data` and `elasticsearch-logs` (previously just `data` and `logs`) Example Volume Mounts: ``` /mnt/elastic-internal/elasticsearch-config-managed from elastic-internal-elasticsearch-config-managed (ro) /mnt/elastic-internal/keystore-user from elsatic-internal-keystore-user (ro) /mnt/elastic-internal/probe-user from elastic-internal-probe-user (ro) /mnt/elastic-internal/process-manager from elastic-internal-process-manager (rw) /mnt/elastic-internal/secure-settings from elastic-internal-secure-settings (ro) /mnt/elastic-internal/unicast-hosts from elastic-internal-unicast-hosts (ro) /usr/share/elasticsearch/bin from elastic-internal-elasticsearch-bin-local (rw) /usr/share/elasticsearch/config from elastic-internal-elasticsearch-config-local (rw) /usr/share/elasticsearch/config/http-certs from elastic-internal-http-certificates (ro) /usr/share/elasticsearch/config/transport-certs from elastic-internal-transport-certificates (ro) /usr/share/elasticsearch/data from elasticsearch-data (rw) /usr/share/elasticsearch/logs from elasticsearch-logs (rw) /usr/share/elasticsearch/plugins from elastic-internal-elasticsearch-plugins-local (rw) ``` Example Volumes ``` elastic-internal-elasticsearch-config-local: Type: EmptyDir (a temporary directory that shares a pod's lifetime) Medium: SizeLimit: elastic-internal-elasticsearch-plugins-local: Type: EmptyDir (a temporary directory that shares a pod's lifetime) Medium: SizeLimit: elastic-internal-elasticsearch-bin-local: Type: EmptyDir (a temporary directory that shares a pod's lifetime) Medium: SizeLimit: elasticsearch-data: Type: EmptyDir (a temporary directory that shares a pod's lifetime) Medium: SizeLimit: elasticsearch-logs: Type: EmptyDir (a temporary directory that shares a pod's lifetime) Medium: SizeLimit: elastic-internal-process-manager: Type: EmptyDir (a temporary directory that shares a pod's lifetime) Medium: SizeLimit: elastic-internal-unicast-hosts: Type: ConfigMap (a volume populated by a ConfigMap) Name: elasticsearch-sample-es-unicast-hosts Optional: false elastic-internal-probe-user: Type: Secret (a volume populated by a Secret) SecretName: elasticsearch-sample-es-internal-users Optional: false elsatic-internal-keystore-user: Type: Secret (a volume populated by a Secret) SecretName: elasticsearch-sample-es-internal-users Optional: false elastic-internal-secure-settings: Type: Secret (a volume populated by a Secret) SecretName: elasticsearch-sample-es-secure-settings Optional: false elastic-internal-http-certificates: Type: Secret (a volume populated by a Secret) SecretName: elasticsearch-sample-es-http-certs-internal Optional: false elastic-internal-transport-certificates: Type: Secret (a volume populated by a Secret) SecretName: elasticsearch-sample-es-xdcbcdndf4-certs Optional: false elastic-internal-elasticsearch-config-managed: Type: Secret (a volume populated by a Secret) SecretName: elasticsearch-sample-es-xdcbcdndf4-config Optional: false ``` --- docs/k8s-quickstart.asciidoc | 2 +- .../config/samples/apm/apm_es_kibana.yaml | 19 +--- operators/config/samples/apm/apmserver.yaml | 6 -- .../elasticsearch/cross-cluster/remote.yml | 39 +-------- .../samples/elasticsearch/elasticsearch.yaml | 10 +-- .../elasticsearch_local_volume.yaml | 17 +--- operators/config/samples/kibana/kibana.yaml | 2 - .../config/samples/kibana/kibana_es.yaml | 64 +------------- .../elasticsearch/configmap/configmap.go | 24 ------ .../configmap/configmap_control.go | 46 ---------- .../elasticsearch/driver/default.go | 25 ++---- .../controller/elasticsearch/driver/driver.go | 2 - .../elasticsearch/driver/pods_test.go | 4 +- .../driver/version_wide_resources.go | 86 ------------------- .../initcontainer/inject_process_manager.go | 4 +- .../elasticsearch/initcontainer/prepare_fs.go | 44 +++++----- .../initcontainer/prepare_fs_script_test.go | 6 +- .../mutation/comparison/pod_test.go | 12 +-- .../pkg/controller/elasticsearch/name/name.go | 5 -- .../pkg/controller/elasticsearch/pod/pod.go | 9 +- .../elasticsearch/processmanager/state.go | 2 +- .../processmanager/tests/Dockerfile | 2 +- .../controller/elasticsearch/pvc/pvc_test.go | 30 +++---- .../elasticsearch/settings/config_volume.go | 4 +- .../elasticsearch/settings/configmap.go | 20 ----- .../elasticsearch/settings/settings.go | 2 +- .../elasticsearch/user/credentials_test.go | 2 +- .../elasticsearch/user/predefined_users.go | 26 +++--- .../elasticsearch/user/reconciler_test.go | 2 +- .../elasticsearch/version/common.go | 29 ++----- .../version/version6/podspecs.go | 33 ++++--- .../version/version6/podspecs_test.go | 32 +++---- .../elasticsearch/volume/configmap.go | 16 ++-- .../controller/elasticsearch/volume/secret.go | 5 -- .../elasticsearch/volume/secret_test.go | 2 +- .../controller/elasticsearch/volume/volume.go | 27 +++--- 36 files changed, 155 insertions(+), 505 deletions(-) delete mode 100644 operators/pkg/controller/elasticsearch/configmap/configmap.go delete mode 100644 operators/pkg/controller/elasticsearch/configmap/configmap_control.go delete mode 100644 operators/pkg/controller/elasticsearch/driver/version_wide_resources.go delete mode 100644 operators/pkg/controller/elasticsearch/settings/configmap.go diff --git a/docs/k8s-quickstart.asciidoc b/docs/k8s-quickstart.asciidoc index 3784b80ca6..eb2187b56f 100644 --- a/docs/k8s-quickstart.asciidoc +++ b/docs/k8s-quickstart.asciidoc @@ -285,7 +285,7 @@ spec: node.ingest: true volumeClaimTemplates: - metadata: - name: data + name: elasticsearch-data spec: accessModes: - ReadWriteOnce diff --git a/operators/config/samples/apm/apm_es_kibana.yaml b/operators/config/samples/apm/apm_es_kibana.yaml index b2fa5f0b40..9c02076b06 100644 --- a/operators/config/samples/apm/apm_es_kibana.yaml +++ b/operators/config/samples/apm/apm_es_kibana.yaml @@ -3,30 +3,15 @@ apiVersion: elasticsearch.k8s.elastic.co/v1alpha1 kind: Elasticsearch metadata: - labels: - controller-tools.k8s.io: "1.0" name: elasticsearch-sample spec: version: "7.1.0" nodes: - - config: - node.master: true - node.data: true - node.ingest: true - podTemplate: - spec: - containers: - - name: elasticsearch - resources: - limits: - memory: 2Gi - nodeCount: 3 + - nodeCount: 3 --- apiVersion: apm.k8s.elastic.co/v1alpha1 kind: ApmServer metadata: - labels: - controller-tools.k8s.io: "1.0" name: apm-server-sample spec: version: "7.1.0" @@ -40,8 +25,6 @@ spec: apiVersion: kibana.k8s.elastic.co/v1alpha1 kind: Kibana metadata: - labels: - controller-tools.k8s.io: "1.0" name: kibana-sample spec: version: "7.1.0" diff --git a/operators/config/samples/apm/apmserver.yaml b/operators/config/samples/apm/apmserver.yaml index a3207920b4..e66e4a837c 100644 --- a/operators/config/samples/apm/apmserver.yaml +++ b/operators/config/samples/apm/apmserver.yaml @@ -1,13 +1,7 @@ apiVersion: apm.k8s.elastic.co/v1alpha1 kind: ApmServer metadata: - labels: - controller-tools.k8s.io: "1.0" name: apmserver-sample spec: version: "7.1.0" nodeCount: 1 - http: - service: - spec: - type: ClusterIP diff --git a/operators/config/samples/elasticsearch/cross-cluster/remote.yml b/operators/config/samples/elasticsearch/cross-cluster/remote.yml index 323e306a84..7979d9a464 100644 --- a/operators/config/samples/elasticsearch/cross-cluster/remote.yml +++ b/operators/config/samples/elasticsearch/cross-cluster/remote.yml @@ -2,59 +2,24 @@ apiVersion: elasticsearch.k8s.elastic.co/v1alpha1 kind: Elasticsearch metadata: name: trust-one - labels: spec: version: "7.1.0" nodes: - - config: - node.master: true - node.data: true - node.ingest: true - podTemplate: - spec: - containers: - - name: elasticsearch - resources: - limits: - memory: 2Gi - cpu: 1 - nodeCount: 1 - http: - service: - spec: - type: ClusterIP + - nodeCount: 1 --- apiVersion: elasticsearch.k8s.elastic.co/v1alpha1 kind: Elasticsearch metadata: name: trust-two - labels: spec: version: "7.1.0" nodes: - - config: - node.master: true - node.data: true - node.ingest: true - podTemplate: - spec: - containers: - - name: elasticsearch - resources: - limits: - memory: 2Gi - cpu: 1 - nodeCount: 1 - http: - service: - spec: - type: ClusterIP + - nodeCount: 1 --- apiVersion: elasticsearch.k8s.elastic.co/v1alpha1 kind: RemoteCluster metadata: labels: - controller-tools.k8s.io: "1.0" elasticsearch.k8s.elastic.co/cluster-name: trust-one name: remotecluster-sample-1-2 spec: diff --git a/operators/config/samples/elasticsearch/elasticsearch.yaml b/operators/config/samples/elasticsearch/elasticsearch.yaml index faf104c444..4adf61b4d9 100644 --- a/operators/config/samples/elasticsearch/elasticsearch.yaml +++ b/operators/config/samples/elasticsearch/elasticsearch.yaml @@ -2,32 +2,32 @@ apiVersion: elasticsearch.k8s.elastic.co/v1alpha1 kind: Elasticsearch metadata: - labels: - controller-tools.k8s.io: "1.0" name: elasticsearch-sample spec: version: "7.1.0" nodes: - config: - node.master: true - node.data: true + # most Elasticsearch configuration parameters are possible to set, e.g: node.attr.attr_name: attr_value podTemplate: metadata: labels: + # additional labels for pods foo: bar spec: containers: - name: elasticsearch resources: + # specify resource limits and requests limits: + # by default, we will size the heap size of ES to half of the memory limit memory: 2Gi cpu: 1 nodeCount: 3 ## this shows how to request 2Gi of persistent data storage for pods in this topology element #volumeClaimTemplates: #- metadata: - # name: data + # name: elasticsearch-data # spec: # accessModes: # - ReadWriteOnce diff --git a/operators/config/samples/elasticsearch/elasticsearch_local_volume.yaml b/operators/config/samples/elasticsearch/elasticsearch_local_volume.yaml index a8f949bc77..1d0afb4de8 100644 --- a/operators/config/samples/elasticsearch/elasticsearch_local_volume.yaml +++ b/operators/config/samples/elasticsearch/elasticsearch_local_volume.yaml @@ -3,27 +3,14 @@ apiVersion: elasticsearch.k8s.elastic.co/v1alpha1 kind: Elasticsearch metadata: - labels: - controller-tools.k8s.io: "1.0" name: es-local-volume-sample spec: version: "7.1.0" nodes: - - config: - node.master: true - node.data: true - podTemplate: - spec: - containers: - - name: elasticsearch - resources: - limits: - memory: 2Gi - cpu: 1 - nodeCount: 3 + - nodeCount: 3 volumeClaimTemplates: - metadata: - name: data + name: elasticsearch-data spec: accessModes: - ReadWriteOnce diff --git a/operators/config/samples/kibana/kibana.yaml b/operators/config/samples/kibana/kibana.yaml index 32a017bba7..0c7f9f61fa 100644 --- a/operators/config/samples/kibana/kibana.yaml +++ b/operators/config/samples/kibana/kibana.yaml @@ -2,8 +2,6 @@ apiVersion: kibana.k8s.elastic.co/v1alpha1 kind: Kibana metadata: - labels: - controller-tools.k8s.io: "1.0" name: kibana-sample spec: version: "7.1.0" diff --git a/operators/config/samples/kibana/kibana_es.yaml b/operators/config/samples/kibana/kibana_es.yaml index 1dbbf201ca..bd41d230ef 100644 --- a/operators/config/samples/kibana/kibana_es.yaml +++ b/operators/config/samples/kibana/kibana_es.yaml @@ -5,70 +5,8 @@ metadata: name: elasticsearch-sample spec: version: "7.1.0" - updateStrategy: - groups: - # give each failure domain a chance to reconcile failures before regular changes: - - selector: - matchLabels: - failure-domain.beta.kubernetes.io/zone: europe-west3-a - - selector: - matchLabels: - failure-domain.beta.kubernetes.io/zone: europe-west3-b - - selector: - matchLabels: - failure-domain.beta.kubernetes.io/zone: europe-west3-c - changeBudget: - # this is the equivalent of the default change budget - maxSurge: 1 - maxUnavailable: 1 nodes: - - config: - node.master: true - node.data: true - node.attr.attr_name: attr_value - # this shows how to customize the Elasticsearch pod - # with labels and resource limits - podTemplate: - metadata: - labels: - foo: bar - spec: - containers: - - name: elasticsearch - resources: - limits: - memory: 2Gi - cpu: 1 - nodeCount: 3 - ## this shows how to request 2Gi of persistent data storage for pods in this topology element - #volumeClaimTemplates: - #- metadata: - # name: data - # spec: - # accessModes: - # - ReadWriteOnce - # resources: - # requests: - # storage: 2Gi - # storageClassName: elastic-local # or eg. gcePersistentDisk - # dedicated masters: - - config: - node.master: true - node.data: false - node.ingest: false - node.attr.attr_name: attr_value - nodeCount: 0 - # dedicated data nodes - - config: - node.master: false - node.data: true - node.ingest: false - node.attr.attr_name: attr_value - nodeCount: 0 - #http: - # service: - # spec: - # type: LoadBalancer + - nodeCount: 1 --- apiVersion: kibana.k8s.elastic.co/v1alpha1 kind: Kibana diff --git a/operators/pkg/controller/elasticsearch/configmap/configmap.go b/operators/pkg/controller/elasticsearch/configmap/configmap.go deleted file mode 100644 index a3520662cb..0000000000 --- a/operators/pkg/controller/elasticsearch/configmap/configmap.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one -// or more contributor license agreements. Licensed under the Elastic License; -// you may not use this file except in compliance with the Elastic License. - -package configmap - -import ( - "github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/label" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" -) - -// NewConfigMapWithData constructs a new config map with the given data -func NewConfigMapWithData(es types.NamespacedName, data map[string]string) corev1.ConfigMap { - return corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: es.Name, - Namespace: es.Namespace, - Labels: label.NewLabels(es), - }, - Data: data, - } -} diff --git a/operators/pkg/controller/elasticsearch/configmap/configmap_control.go b/operators/pkg/controller/elasticsearch/configmap/configmap_control.go deleted file mode 100644 index ef7e3d4b6a..0000000000 --- a/operators/pkg/controller/elasticsearch/configmap/configmap_control.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one -// or more contributor license agreements. Licensed under the Elastic License; -// you may not use this file except in compliance with the Elastic License. - -package configmap - -import ( - "reflect" - - "github.com/elastic/cloud-on-k8s/operators/pkg/apis/elasticsearch/v1alpha1" - "github.com/elastic/cloud-on-k8s/operators/pkg/controller/common/reconciler" - "github.com/elastic/cloud-on-k8s/operators/pkg/utils/k8s" - - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/runtime" - logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" -) - -var ( - log = logf.Log.WithName("configmap") -) - -// ReconcileConfigMap checks for an existing config map and updates it or creates one if it does not exist. -func ReconcileConfigMap( - c k8s.Client, - scheme *runtime.Scheme, - es v1alpha1.Elasticsearch, - expected corev1.ConfigMap, -) error { - reconciled := &corev1.ConfigMap{} - return reconciler.ReconcileResource( - reconciler.Params{ - Client: c, - Scheme: scheme, - Owner: &es, - Expected: &expected, - Reconciled: reconciled, - NeedsUpdate: func() bool { - return !reflect.DeepEqual(expected.Data, reconciled.Data) - }, - UpdateReconciled: func() { - reconciled.Data = expected.Data - }, - }, - ) -} diff --git a/operators/pkg/controller/elasticsearch/driver/default.go b/operators/pkg/controller/elasticsearch/driver/default.go index 4f79154e02..ec9d71df2d 100644 --- a/operators/pkg/controller/elasticsearch/driver/default.go +++ b/operators/pkg/controller/elasticsearch/driver/default.go @@ -53,13 +53,6 @@ type defaultDriver struct { es v1alpha1.Elasticsearch, ) (*user.InternalUsers, error) - // versionWideResourcesReconciler reconciles resources that may be specific to a version - versionWideResourcesReconciler func( - c k8s.Client, - scheme *runtime.Scheme, - es v1alpha1.Elasticsearch, - ) (*VersionWideResources, error) - // expectedPodsAndResourcesResolver returns a list of pod specs with context that we would expect to find in the // Elasticsearch cluster. // @@ -194,11 +187,6 @@ func (d *defaultDriver) Reconcile( return results.WithError(err) } - versionWideResources, err := d.versionWideResourcesReconciler(d.Client, d.Scheme, es) - if err != nil { - return results.WithError(err) - } - // TODO: support user-supplied certificate (non-ca) esClient := d.newElasticsearchClient( genericResources.ExternalService, @@ -234,7 +222,7 @@ func (d *defaultDriver) Reconcile( return results.WithResult(defaultRequeue) } - changes, err := d.calculateChanges(versionWideResources, internalUsers, es, *resourcesState) + changes, err := d.calculateChanges(internalUsers, es, *resourcesState) if err != nil { return results.WithError(err) } @@ -486,7 +474,6 @@ func removePodFromList(pods []corev1.Pod, pod corev1.Pod) []corev1.Pod { // calculateChanges calculates the changes we'd need to perform to go from the current cluster configuration to the // desired one. func (d *defaultDriver) calculateChanges( - versionWideResources *VersionWideResources, internalUsers *user.InternalUsers, es v1alpha1.Elasticsearch, resourcesState reconcile.ResourcesState, @@ -494,11 +481,11 @@ func (d *defaultDriver) calculateChanges( expectedPodSpecCtxs, err := d.expectedPodsAndResourcesResolver( es, pod.NewPodSpecParams{ - ClusterSecretsRef: k8s.ExtractNamespacedName(&versionWideResources.ClusterSecrets), - ProbeUser: internalUsers.ProbeUser.Auth(), - ReloadCredsUser: internalUsers.ReloadCredsUser.Auth(), - ConfigMapVolume: volume.NewConfigMapVolume(versionWideResources.GenericUnencryptedConfigurationFiles.Name, settings.ManagedConfigPath), - UnicastHostsVolume: volume.NewConfigMapVolume(name.UnicastHostsConfigMap(es.Name), volume.UnicastHostsVolumeMountPath), + ProbeUser: internalUsers.ProbeUser.Auth(), + KeystoreUser: internalUsers.KeystoreUser.Auth(), + UnicastHostsVolume: volume.NewConfigMapVolume( + name.UnicastHostsConfigMap(es.Name), volume.UnicastHostsVolumeName, volume.UnicastHostsVolumeMountPath, + ), }, d.OperatorImage, ) diff --git a/operators/pkg/controller/elasticsearch/driver/driver.go b/operators/pkg/controller/elasticsearch/driver/driver.go index 49e972d255..c459328742 100644 --- a/operators/pkg/controller/elasticsearch/driver/driver.go +++ b/operators/pkg/controller/elasticsearch/driver/driver.go @@ -66,8 +66,6 @@ func NewDriver(opts Options) (Driver, error) { driver := &defaultDriver{ Options: opts, - versionWideResourcesReconciler: reconcileVersionWideResources, - observedStateResolver: opts.Observers.ObservedStateResolver, resourcesStateResolver: esreconcile.NewResourcesStateFromAPI, usersReconciler: user.ReconcileUsers, diff --git a/operators/pkg/controller/elasticsearch/driver/pods_test.go b/operators/pkg/controller/elasticsearch/driver/pods_test.go index 9c77ff6b75..ccf8c2cd35 100644 --- a/operators/pkg/controller/elasticsearch/driver/pods_test.go +++ b/operators/pkg/controller/elasticsearch/driver/pods_test.go @@ -28,7 +28,7 @@ func Test_newPVCFromTemplate(t *testing.T) { args: args{ claimTemplate: corev1.PersistentVolumeClaim{ ObjectMeta: metav1.ObjectMeta{ - Name: "data", + Name: "elasticsearch-data", }, }, pod: &corev1.Pod{ @@ -43,7 +43,7 @@ func Test_newPVCFromTemplate(t *testing.T) { }, want: &corev1.PersistentVolumeClaim{ ObjectMeta: metav1.ObjectMeta{ - Name: "elasticsearch-sample-es-6bw9qkw77k-data", + Name: "elasticsearch-sample-es-6bw9qkw77k-elasticsearch-data", Labels: map[string]string{ "l1": "v1", "l2": "v2", diff --git a/operators/pkg/controller/elasticsearch/driver/version_wide_resources.go b/operators/pkg/controller/elasticsearch/driver/version_wide_resources.go deleted file mode 100644 index cfeca5e3c1..0000000000 --- a/operators/pkg/controller/elasticsearch/driver/version_wide_resources.go +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one -// or more contributor license agreements. Licensed under the Elastic License; -// you may not use this file except in compliance with the Elastic License. - -package driver - -import ( - "github.com/elastic/cloud-on-k8s/operators/pkg/apis/elasticsearch/v1alpha1" - "github.com/elastic/cloud-on-k8s/operators/pkg/controller/common/annotation" - "github.com/elastic/cloud-on-k8s/operators/pkg/controller/common/reconciler" - "github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/configmap" - "github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/label" - "github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/name" - "github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/settings" - "github.com/elastic/cloud-on-k8s/operators/pkg/utils/k8s" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -// VersionWideResources are resources that are tied to a version, but no specific pod within that version -type VersionWideResources struct { - // ClusterSecrets contains possible user-defined secret files we want to have access to in the containers. - ClusterSecrets corev1.Secret - // GenericUnencryptedConfigurationFiles contains non-secret files Pods with this version should have access to. - GenericUnencryptedConfigurationFiles corev1.ConfigMap -} - -func reconcileVersionWideResources( - c k8s.Client, - scheme *runtime.Scheme, - es v1alpha1.Elasticsearch, -) (*VersionWideResources, error) { - expectedConfigMap := configmap.NewConfigMapWithData(k8s.ExtractNamespacedName(&es), settings.DefaultConfigMapData) - err := configmap.ReconcileConfigMap(c, scheme, es, expectedConfigMap) - if err != nil { - return nil, err - } - - // TODO: this may not exactly fit the bill of being specific to a version - expectedClusterSecretsSecret := corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: es.Namespace, - Name: name.ClusterSecretsSecret(es.Name), - }, - Data: map[string][]byte{}, - } - - var reconciledClusterSecretsSecret corev1.Secret - - if err := reconciler.ReconcileResource(reconciler.Params{ - Client: c, - Scheme: scheme, - Owner: &es, - Expected: &expectedClusterSecretsSecret, - Reconciled: &reconciledClusterSecretsSecret, - NeedsUpdate: func() bool { - // .Data might be nil in the secret, so make sure to initialize it - if reconciledClusterSecretsSecret.Data == nil { - reconciledClusterSecretsSecret.Data = make(map[string][]byte, 0) - } - - // TODO: compare items that we may want to reconcile here - - return false - }, - UpdateReconciled: func() { - // TODO: add items to reconcile here - }, - PostUpdate: func() { - annotation.MarkPodsAsUpdated(c, - client.ListOptions{ - Namespace: es.Namespace, - LabelSelector: label.NewLabelSelectorForElasticsearch(es), - }) - }, - }); err != nil { - return nil, err - } - - return &VersionWideResources{ - GenericUnencryptedConfigurationFiles: expectedConfigMap, - ClusterSecrets: reconciledClusterSecretsSecret, - }, nil -} diff --git a/operators/pkg/controller/elasticsearch/initcontainer/inject_process_manager.go b/operators/pkg/controller/elasticsearch/initcontainer/inject_process_manager.go index f2ca601448..9dd2dd057a 100644 --- a/operators/pkg/controller/elasticsearch/initcontainer/inject_process_manager.go +++ b/operators/pkg/controller/elasticsearch/initcontainer/inject_process_manager.go @@ -18,8 +18,8 @@ const ( ) var ProcessManagerVolume = SharedVolume{ - Name: "local-bin-volume", - InitContainerMountPath: "/volume/bin", + Name: "elastic-internal-process-manager", + InitContainerMountPath: volume.ProcessManagerEmptyDirMountPath, EsContainerMountPath: volume.ProcessManagerEmptyDirMountPath, } diff --git a/operators/pkg/controller/elasticsearch/initcontainer/prepare_fs.go b/operators/pkg/controller/elasticsearch/initcontainer/prepare_fs.go index 7376bd976c..e58b43f98d 100644 --- a/operators/pkg/controller/elasticsearch/initcontainer/prepare_fs.go +++ b/operators/pkg/controller/elasticsearch/initcontainer/prepare_fs.go @@ -15,38 +15,42 @@ import ( // Volumes that are shared between the prepare-fs init container and the ES container var ( DataSharedVolume = SharedVolume{ - Name: "data", - InitContainerMountPath: "/volume/data", + Name: "elasticsearch-data", + InitContainerMountPath: "/usr/share/elasticsearch/data", EsContainerMountPath: "/usr/share/elasticsearch/data", } LogsSharedVolume = SharedVolume{ - Name: "logs", - InitContainerMountPath: "/volume/logs", + Name: "elasticsearch-logs", + InitContainerMountPath: "/usr/share/elasticsearch/logs", EsContainerMountPath: "/usr/share/elasticsearch/logs", } + // EsBinSharedVolume contains the ES bin/ directory EsBinSharedVolume = SharedVolume{ - Name: "bin-volume", - InitContainerMountPath: "/volume/bin", + Name: "elastic-internal-elasticsearch-bin-local", + InitContainerMountPath: "/mnt/elastic-internal/elasticsearch-bin-local", EsContainerMountPath: "/usr/share/elasticsearch/bin", } + // EsConfigSharedVolume contains the ES config/ directory + EsConfigSharedVolume = SharedVolume{ + Name: "elastic-internal-elasticsearch-config-local", + InitContainerMountPath: "/mnt/elastic-internal/elasticsearch-config-local", + EsContainerMountPath: "/usr/share/elasticsearch/config", + } + + // EsPluginsSharedVolume contains the ES plugins/ directory + EsPluginsSharedVolume = SharedVolume{ + Name: "elastic-internal-elasticsearch-plugins-local", + InitContainerMountPath: "/mnt/elastic-internal/elasticsearch-plugins-local", + EsContainerMountPath: "/usr/share/elasticsearch/plugins", + } + PrepareFsSharedVolumes = SharedVolumeArray{ Array: []SharedVolume{ - // Contains configuration (elasticsearch.yml) and plugins configuration subdirs - SharedVolume{ - Name: "config-volume", - InitContainerMountPath: "/volume/config", - EsContainerMountPath: "/usr/share/elasticsearch/config", - }, - // Contains plugins data - SharedVolume{ - Name: "plugins-volume", - InitContainerMountPath: "/volume/plugins", - EsContainerMountPath: "/usr/share/elasticsearch/plugins", - }, - // Plugins may have binaries installed in /bin + EsConfigSharedVolume, + EsPluginsSharedVolume, EsBinSharedVolume, DataSharedVolume, LogsSharedVolume, @@ -71,7 +75,7 @@ func NewPrepareFSInitContainer( // will attempt to move all the files under the configuration directory to a different volume, and it should not // be attempting to move files from this secret volume mount (any attempt to do so will be logged as errors). certificatesVolumeMount := transportCertificatesVolume.VolumeMount() - certificatesVolumeMount.MountPath = "/volume/transport-certificates" + certificatesVolumeMount.MountPath = "/mnt/elastic-internal/transport-certificates" script, err := RenderScriptTemplate(TemplateParams{ Plugins: defaultInstalledPlugins, diff --git a/operators/pkg/controller/elasticsearch/initcontainer/prepare_fs_script_test.go b/operators/pkg/controller/elasticsearch/initcontainer/prepare_fs_script_test.go index d23a45e5ad..6b69021248 100644 --- a/operators/pkg/controller/elasticsearch/initcontainer/prepare_fs_script_test.go +++ b/operators/pkg/controller/elasticsearch/initcontainer/prepare_fs_script_test.go @@ -31,9 +31,9 @@ func TestRenderScriptTemplate(t *testing.T) { wantSubstr: []string{ "$PLUGIN_BIN install --batch repository-s3", "$PLUGIN_BIN install --batch repository-gcs", - "mv /usr/share/elasticsearch/config/* /volume/config/", - "mv /usr/share/elasticsearch/bin/* /volume/bin/", - "mv /usr/share/elasticsearch/plugins/* /volume/plugins/", + "mv /usr/share/elasticsearch/config/* /mnt/elastic-internal/elasticsearch-config-local/", + "mv /usr/share/elasticsearch/bin/* /mnt/elastic-internal/elasticsearch-bin-local/", + "mv /usr/share/elasticsearch/plugins/* /mnt/elastic-internal/elasticsearch-plugins-local/", "ln -sf /secrets/users /usr/share/elasticsearch/users", }, }, diff --git a/operators/pkg/controller/elasticsearch/mutation/comparison/pod_test.go b/operators/pkg/controller/elasticsearch/mutation/comparison/pod_test.go index cf7f66fd00..c78690c9e0 100644 --- a/operators/pkg/controller/elasticsearch/mutation/comparison/pod_test.go +++ b/operators/pkg/controller/elasticsearch/mutation/comparison/pod_test.go @@ -318,14 +318,14 @@ func Test_PodMatchesSpec(t *testing.T) { { name: "Pod has a PVC with an empty VolumeMode", args: args{ - pod: withPVCs(ESPodWithConfig(defaultImage, defaultCPULimit), "data", "elasticsearch-sample-es-7gnc85w7ll-data"), + pod: withPVCs(ESPodWithConfig(defaultImage, defaultCPULimit), "elasticsearch-data", "elasticsearch-sample-es-7gnc85w7ll-elasticsearch-data"), spec: pod.PodSpecContext{ PodSpec: ESPodSpecContext(defaultImage, defaultCPULimit).PodSpec, NodeSpec: v1alpha1.NodeSpec{ VolumeClaimTemplates: []corev1.PersistentVolumeClaim{ { ObjectMeta: metav1.ObjectMeta{ - Name: "data", + Name: "elasticsearch-data", }, Spec: corev1.PersistentVolumeClaimSpec{ VolumeMode: nil, @@ -337,7 +337,7 @@ func Test_PodMatchesSpec(t *testing.T) { state: reconcile.ResourcesState{ PVCs: []corev1.PersistentVolumeClaim{ { - ObjectMeta: metav1.ObjectMeta{Name: "elasticsearch-sample-es-7gnc85w7ll-data"}, + ObjectMeta: metav1.ObjectMeta{Name: "elasticsearch-sample-es-7gnc85w7ll-elasticsearch-data"}, Spec: corev1.PersistentVolumeClaimSpec{ VolumeMode: &fs, }, @@ -351,14 +351,14 @@ func Test_PodMatchesSpec(t *testing.T) { { name: "Pod has a PVC with a VolumeMode set to something else than default setting", args: args{ - pod: withPVCs(ESPodWithConfig(defaultImage, defaultCPULimit), "data", "elasticsearch-sample-es-7gnc85w7ll-data"), + pod: withPVCs(ESPodWithConfig(defaultImage, defaultCPULimit), "elasticsearch-data", "elasticsearch-sample-es-7gnc85w7ll-elasticsearch-data"), spec: pod.PodSpecContext{ PodSpec: ESPodSpecContext(defaultImage, defaultCPULimit).PodSpec, NodeSpec: v1alpha1.NodeSpec{ VolumeClaimTemplates: []corev1.PersistentVolumeClaim{ { ObjectMeta: metav1.ObjectMeta{ - Name: "data", + Name: "elasticsearch-data", }, Spec: corev1.PersistentVolumeClaimSpec{ VolumeMode: &block, @@ -370,7 +370,7 @@ func Test_PodMatchesSpec(t *testing.T) { state: reconcile.ResourcesState{ PVCs: []corev1.PersistentVolumeClaim{ { - ObjectMeta: metav1.ObjectMeta{Name: "elasticsearch-sample-es-7gnc85w7ll-data"}, + ObjectMeta: metav1.ObjectMeta{Name: "elasticsearch-sample-es-7gnc85w7ll-elasticsearch-data"}, Spec: corev1.PersistentVolumeClaimSpec{ VolumeMode: &block, }, diff --git a/operators/pkg/controller/elasticsearch/name/name.go b/operators/pkg/controller/elasticsearch/name/name.go index e8eba2442c..5f5767574b 100644 --- a/operators/pkg/controller/elasticsearch/name/name.go +++ b/operators/pkg/controller/elasticsearch/name/name.go @@ -30,7 +30,6 @@ const ( httpServiceSuffix = "http" elasticUserSecretSuffix = "elastic-user" esRolesUsersSecretSuffix = "roles-users" - clusterSecretsSecretSuffix = "secrets" internalUsersSecretSuffix = "internal-users" unicastHostsConfigMapSuffix = "unicast-hosts" licenseSecretSuffix = "license" @@ -110,10 +109,6 @@ func EsRolesUsersSecret(esName string) string { return ESNamer.Suffix(esName, esRolesUsersSecretSuffix) } -func ClusterSecretsSecret(esName string) string { - return ESNamer.Suffix(esName, clusterSecretsSecretSuffix) -} - func InternalUsersSecret(esName string) string { return ESNamer.Suffix(esName, internalUsersSecretSuffix) } diff --git a/operators/pkg/controller/elasticsearch/pod/pod.go b/operators/pkg/controller/elasticsearch/pod/pod.go index 974a50ff1b..97071e4aa0 100644 --- a/operators/pkg/controller/elasticsearch/pod/pod.go +++ b/operators/pkg/controller/elasticsearch/pod/pod.go @@ -12,7 +12,6 @@ import ( "github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/settings" "github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/volume" corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" ) const ( @@ -74,14 +73,10 @@ type NewPodSpecParams struct { ESConfigVolume volume.SecretVolume // UsersSecretVolume is the volume that contains x-pack configuration (users, users_roles) UsersSecretVolume volume.SecretVolume - // ConfigMapVolume is a volume containing a config map with configuration files - ConfigMapVolume volume.ConfigMapVolume - // ClusterSecretsRef is a reference to a secret containing generic secrets shared between pods in the cluster. - ClusterSecretsRef types.NamespacedName // ProbeUser is the user that should be used for the readiness probes. ProbeUser client.UserAuth - // ReloadCredsUser is the user that should be used for reloading the credentials. - ReloadCredsUser client.UserAuth + // KeystoreUser is the user that should be used for reloading the credentials. + KeystoreUser client.UserAuth // UnicastHostsVolume contains a file with the seed hosts. UnicastHostsVolume volume.ConfigMapVolume } diff --git a/operators/pkg/controller/elasticsearch/processmanager/state.go b/operators/pkg/controller/elasticsearch/processmanager/state.go index b9414f22bd..9b4492f955 100644 --- a/operators/pkg/controller/elasticsearch/processmanager/state.go +++ b/operators/pkg/controller/elasticsearch/processmanager/state.go @@ -101,7 +101,7 @@ func (p *Process) updateState(action string, signal syscall.Signal, lastErr erro err := p.state.Write() if err != nil { - Exit("Failed to write process state", 1) + Exit(fmt.Sprintf("Failed to write process state: %s", err), 1) } kv := []interface{}{"action", action, "id", p.id, "state", p.state, "pid", p.pid} diff --git a/operators/pkg/controller/elasticsearch/processmanager/tests/Dockerfile b/operators/pkg/controller/elasticsearch/processmanager/tests/Dockerfile index ab98957d65..07808bc95e 100644 --- a/operators/pkg/controller/elasticsearch/processmanager/tests/Dockerfile +++ b/operators/pkg/controller/elasticsearch/processmanager/tests/Dockerfile @@ -13,7 +13,7 @@ RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o process-manager github. # Copy the controller-manager into a thin image FROM docker.elastic.co/elasticsearch/elasticsearch:6.7.0 -VOLUME ["/mnt/elastic/process-manager"] +VOLUME ["/mnt/elastic-internal/process-manager"] COPY --from=builder /go/src/github.com/elastic/cloud-on-k8s/operators/process-manager /process-manager ENTRYPOINT ["/process-manager"] diff --git a/operators/pkg/controller/elasticsearch/pvc/pvc_test.go b/operators/pkg/controller/elasticsearch/pvc/pvc_test.go index 73b3820f2b..a071f5a7af 100644 --- a/operators/pkg/controller/elasticsearch/pvc/pvc_test.go +++ b/operators/pkg/controller/elasticsearch/pvc/pvc_test.go @@ -84,9 +84,9 @@ func withPVC(pod *corev1.Pod, volumeName string, claimName string) *corev1.Pod { } func TestFindOrphanedVolumeClaims(t *testing.T) { - pvc1 := newPVC("elasticsearch-sample-es-2l59jptdq6", "elasticsearch-sample-es-2l59jptdq6-data", sampleLabels1, "1Gi", nil) - pvc2 := newPVC("elasticsearch-sample-es-6bw9qkw77k", "elasticsearch-sample-es-6bw9qkw77k-data", sampleLabels1, "1Gi", nil) - pvc3 := newPVC("elasticsearch-sample-es-6qg4hmd9dj", "elasticsearch-sample-es-6qg4hmd9dj-data", sampleLabels2, "1Gi", nil) + pvc1 := newPVC("elasticsearch-sample-es-2l59jptdq6", "elasticsearch-sample-es-2l59jptdq6-elasticsearch-data", sampleLabels1, "1Gi", nil) + pvc2 := newPVC("elasticsearch-sample-es-6bw9qkw77k", "elasticsearch-sample-es-6bw9qkw77k-elasticsearch-data", sampleLabels1, "1Gi", nil) + pvc3 := newPVC("elasticsearch-sample-es-6qg4hmd9dj", "elasticsearch-sample-es-6qg4hmd9dj-elasticsearch-data", sampleLabels2, "1Gi", nil) type args struct { initialObjects []runtime.Object es v1alpha1.Elasticsearch @@ -103,7 +103,7 @@ func TestFindOrphanedVolumeClaims(t *testing.T) { initialObjects: []runtime.Object{ // create 1 Pod withPVC(newPod("elasticsearch-sample-es-2l59jptdq6", sampleLabels1), - "data", "elasticsearch-sample-es-2l59jptdq6-data"), + "elasticsearch-data", "elasticsearch-sample-es-2l59jptdq6-elasticsearch-data"), // create 3 PVCs pvc1, pvc2, @@ -124,7 +124,7 @@ func TestFindOrphanedVolumeClaims(t *testing.T) { initialObjects: []runtime.Object{ // create 1 Pod withPVC(newPod("elasticsearch-sample-es-2l59jptdq6", sampleLabels1), - "data", "elasticsearch-sample-es-2l59jptdq6-data"), + "elasticsearch-data", "elasticsearch-sample-es-2l59jptdq6-elasticsearch-data"), // create 3 PVCs, but one of them is scheduled to be deleted pvc1, pvc2, @@ -173,8 +173,8 @@ func TestOrphanedPersistentVolumeClaims_FindOrphanedVolumeClaim(t *testing.T) { name: "Simple test with a standard storage class and 1Gi of storage", fields: fields{ []corev1.PersistentVolumeClaim{ - *newPVC("elasticsearch-sample-es-6bw9qkw77k", "elasticsearch-sample-es-6bw9qkw77k-data", sampleLabels1, "1Gi", &standardStorageClassname), - *newPVC("elasticsearch-sample-es-6qg4hmd9dj", "elasticsearch-sample-es-6qg4hmd9dj-data", sampleLabels1, "1Gi", &standardStorageClassname), + *newPVC("elasticsearch-sample-es-6bw9qkw77k", "elasticsearch-sample-es-6bw9qkw77k-elasticsearch-data", sampleLabels1, "1Gi", &standardStorageClassname), + *newPVC("elasticsearch-sample-es-6qg4hmd9dj", "elasticsearch-sample-es-6qg4hmd9dj-elasticsearch-data", sampleLabels1, "1Gi", &standardStorageClassname), }}, args: args{ expectedLabels: newPodLabel("elasticsearch-sample-es-2l59jptdq6", sampleLabels1), @@ -188,13 +188,13 @@ func TestOrphanedPersistentVolumeClaims_FindOrphanedVolumeClaim(t *testing.T) { }, }, }, - want: newPVC("elasticsearch-sample-es-6bw9qkw77k", "elasticsearch-sample-es-6bw9qkw77k-data", sampleLabels1, "1Gi", &standardStorageClassname), + want: newPVC("elasticsearch-sample-es-6bw9qkw77k", "elasticsearch-sample-es-6bw9qkw77k-elasticsearch-data", sampleLabels1, "1Gi", &standardStorageClassname), }, { name: "Labels mismatch", fields: fields{ []corev1.PersistentVolumeClaim{ - *newPVC("elasticsearch-sample-es-6bw9qkw77k", "elasticsearch-sample-es-6bw9qkw77k-data", sampleLabels2, "1Gi", &standardStorageClassname), - *newPVC("elasticsearch-sample-es-6qg4hmd9dj", "elasticsearch-sample-es-6qg4hmd9dj-data", sampleLabels2, "1Gi", &standardStorageClassname), + *newPVC("elasticsearch-sample-es-6bw9qkw77k", "elasticsearch-sample-es-6bw9qkw77k-elasticsearch-data", sampleLabels2, "1Gi", &standardStorageClassname), + *newPVC("elasticsearch-sample-es-6qg4hmd9dj", "elasticsearch-sample-es-6qg4hmd9dj-elasticsearch-data", sampleLabels2, "1Gi", &standardStorageClassname), }}, args: args{ expectedLabels: newPodLabel("elasticsearch-sample-es-2l59jptdq6", sampleLabels1), @@ -213,8 +213,8 @@ func TestOrphanedPersistentVolumeClaims_FindOrphanedVolumeClaim(t *testing.T) { name: "Matching storage class", fields: fields{ []corev1.PersistentVolumeClaim{ - *newPVC("elasticsearch-sample-es-6bw9qkw77k", "elasticsearch-sample-es-6bw9qkw77k-data", sampleLabels1, "1Gi", &fastStorageClassname), - *newPVC("elasticsearch-sample-es-6qg4hmd9dj", "elasticsearch-sample-es-6qg4hmd9dj-data", sampleLabels1, "1Gi", &fastStorageClassname), + *newPVC("elasticsearch-sample-es-6bw9qkw77k", "elasticsearch-sample-es-6bw9qkw77k-elasticsearch-data", sampleLabels1, "1Gi", &fastStorageClassname), + *newPVC("elasticsearch-sample-es-6qg4hmd9dj", "elasticsearch-sample-es-6qg4hmd9dj-elasticsearch-data", sampleLabels1, "1Gi", &fastStorageClassname), }}, args: args{ expectedLabels: newPodLabel("elasticsearch-sample-es-2l59jptdq6", sampleLabels1), @@ -229,14 +229,14 @@ func TestOrphanedPersistentVolumeClaims_FindOrphanedVolumeClaim(t *testing.T) { }, }, }, - want: newPVC("elasticsearch-sample-es-6bw9qkw77k", "elasticsearch-sample-es-6bw9qkw77k-data", sampleLabels1, "1Gi", &fastStorageClassname), + want: newPVC("elasticsearch-sample-es-6bw9qkw77k", "elasticsearch-sample-es-6bw9qkw77k-elasticsearch-data", sampleLabels1, "1Gi", &fastStorageClassname), }, { name: "Storage class mismatch", fields: fields{ []corev1.PersistentVolumeClaim{ - *newPVC("elasticsearch-sample-es-6bw9qkw77k", "elasticsearch-sample-es-6bw9qkw77k-data", sampleLabels1, "1Gi", &standardStorageClassname), - *newPVC("elasticsearch-sample-es-6qg4hmd9dj", "elasticsearch-sample-es-6qg4hmd9dj-data", sampleLabels1, "1Gi", &standardStorageClassname), + *newPVC("elasticsearch-sample-es-6bw9qkw77k", "elasticsearch-sample-es-6bw9qkw77k-elasticsearch-data", sampleLabels1, "1Gi", &standardStorageClassname), + *newPVC("elasticsearch-sample-es-6qg4hmd9dj", "elasticsearch-sample-es-6qg4hmd9dj-elasticsearch-data", sampleLabels1, "1Gi", &standardStorageClassname), }}, args: args{ expectedLabels: newPodLabel("elasticsearch-sample-es-2l59jptdq6", sampleLabels1), diff --git a/operators/pkg/controller/elasticsearch/settings/config_volume.go b/operators/pkg/controller/elasticsearch/settings/config_volume.go index 3f2ce92382..298ace5d71 100644 --- a/operators/pkg/controller/elasticsearch/settings/config_volume.go +++ b/operators/pkg/controller/elasticsearch/settings/config_volume.go @@ -24,8 +24,8 @@ import ( // Constants to use for the `elasticsearch.yml` config file in an ES pod. const ( ConfigFileName = "elasticsearch.yml" - ConfigVolumeName = "es-config" - ConfigVolumeMountPath = "/mnt/elastic/" + ConfigVolumeName + ConfigVolumeName = "elastic-internal-elasticsearch-config-managed" + ConfigVolumeMountPath = "/mnt/elastic-internal/elasticsearch-config-managed" ) // ConfigSecretName is the name of the secret that holds the ES config for the given pod. diff --git a/operators/pkg/controller/elasticsearch/settings/configmap.go b/operators/pkg/controller/elasticsearch/settings/configmap.go deleted file mode 100644 index 5f518693da..0000000000 --- a/operators/pkg/controller/elasticsearch/settings/configmap.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one -// or more contributor license agreements. Licensed under the Elastic License; -// you may not use this file except in compliance with the Elastic License. - -package settings - -const ( - // SecurityPropsFile is the name of the security properties files - SecurityPropsFile = "security.properties" - // ManagedConfigPath is the path to our managed configuration files within the ES container - ManagedConfigPath = "/usr/share/elasticsearch/config/managed" -) - -// DefaultConfigMapData is the default config map to create for every ES pod -var DefaultConfigMapData = map[string]string{ - // With a security manager present the JVM will cache hostname lookup results indefinitely. - // This will limit the caching to 60 seconds as we are relying on DNS for discovery in k8s. - // See also: https://github.com/elastic/elasticsearch/pull/36570 - SecurityPropsFile: "networkaddress.cache.ttl=60\n", -} diff --git a/operators/pkg/controller/elasticsearch/settings/settings.go b/operators/pkg/controller/elasticsearch/settings/settings.go index 1c08644c56..19ab5bef10 100644 --- a/operators/pkg/controller/elasticsearch/settings/settings.go +++ b/operators/pkg/controller/elasticsearch/settings/settings.go @@ -8,4 +8,4 @@ import ( logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" ) -var log = logf.Log.WithName("es-settings") +var log = logf.Log.WithName("settings") diff --git a/operators/pkg/controller/elasticsearch/user/credentials_test.go b/operators/pkg/controller/elasticsearch/user/credentials_test.go index 88bfcc8376..d10f870aa8 100644 --- a/operators/pkg/controller/elasticsearch/user/credentials_test.go +++ b/operators/pkg/controller/elasticsearch/user/credentials_test.go @@ -41,7 +41,7 @@ func TestNewUserSecrets(t *testing.T) { { subject: NewInternalUserCredentials(testES), expectedName: "my-cluster-es-internal-users", - expectedKeys: []string{InternalControllerUserName, InternalProbeUserName, InternalReloadCredsUserName}, + expectedKeys: []string{InternalControllerUserName, InternalKeystoreUserName, InternalProbeUserName}, }, { subject: NewExternalUserCredentials(testES), diff --git a/operators/pkg/controller/elasticsearch/user/predefined_users.go b/operators/pkg/controller/elasticsearch/user/predefined_users.go index 96a5234e1a..61cece2c90 100644 --- a/operators/pkg/controller/elasticsearch/user/predefined_users.go +++ b/operators/pkg/controller/elasticsearch/user/predefined_users.go @@ -13,17 +13,17 @@ const ( InternalControllerUserName = "elastic-internal" // InternalProbeUserName is a user to be used from the liveness/readiness probes when interacting with ES. InternalProbeUserName = "elastic-internal-probe" - // InternalReloadCredsUserName is a user to be used for reloading ES credentials. - InternalReloadCredsUserName = "elastic-internal-reload-creds" + // InternalKeystoreUserName is a user to be used for reloading ES secure settings from the keystore. + InternalKeystoreUserName = "elastic-internal-keystore" // SuperUserBuiltinRole is the name of the built-in superuser role SuperUserBuiltinRole = "superuser" // KibanaSystemUserBuiltinRole is the name of the built-in role for the Kibana system user KibanaSystemUserBuiltinRole = "kibana_system" - // ProbeUserRole is the name of the custom probe_user role - ProbeUserRole = "probe_user" - // ReloadCredsUserRole is the name of the custom reload_creds_user role - ReloadCredsUserRole = "reload_creds_user" + // ProbeUserRole is the name of the custom elastic_internal_probe_user role + ProbeUserRole = "elastic_internal_probe_user" + // KeystoreUserRole is the name of the custom elastic_internal_keystore_user role + KeystoreUserRole = "elastic_internal_keystore_user" ) // Predefined roles. @@ -32,7 +32,7 @@ var ( ProbeUserRole: { Cluster: []string{"monitor"}, }, - ReloadCredsUserRole: { + KeystoreUserRole: { Cluster: []string{"all"}, }, } @@ -50,15 +50,15 @@ func newInternalUsers() []User { return []User{ New(InternalControllerUserName, Roles(SuperUserBuiltinRole)), New(InternalProbeUserName, Roles(ProbeUserRole)), - New(InternalReloadCredsUserName, Roles(ReloadCredsUserRole)), + New(InternalKeystoreUserName, Roles(KeystoreUserRole)), } } // InternalUsers are Elasticsearch users intended for system use. type InternalUsers struct { - ControllerUser User - ProbeUser User - ReloadCredsUser User + ControllerUser User + ProbeUser User + KeystoreUser User } // NewInternalUsersFrom constructs a new struct with internal users from the given credentials of those users. @@ -71,8 +71,8 @@ func NewInternalUsersFrom(users ClearTextCredentials) *InternalUsers { if user.Id() == InternalProbeUserName { internalUsers.ProbeUser = user } - if user.Id() == InternalReloadCredsUserName { - internalUsers.ReloadCredsUser = user + if user.Id() == InternalKeystoreUserName { + internalUsers.KeystoreUser = user } } return &internalUsers diff --git a/operators/pkg/controller/elasticsearch/user/reconciler_test.go b/operators/pkg/controller/elasticsearch/user/reconciler_test.go index 100ae1c468..ffa75312f5 100644 --- a/operators/pkg/controller/elasticsearch/user/reconciler_test.go +++ b/operators/pkg/controller/elasticsearch/user/reconciler_test.go @@ -62,7 +62,7 @@ func Test_aggregateAllUsers(t *testing.T) { []string{ "kibana-user", ExternalUserName, - InternalControllerUserName, InternalProbeUserName, InternalReloadCredsUserName, + InternalControllerUserName, InternalProbeUserName, InternalKeystoreUserName, }, users, ) diff --git a/operators/pkg/controller/elasticsearch/version/common.go b/operators/pkg/controller/elasticsearch/version/common.go index 7a0ad01593..e294bc6660 100644 --- a/operators/pkg/controller/elasticsearch/version/common.go +++ b/operators/pkg/controller/elasticsearch/version/common.go @@ -5,8 +5,6 @@ package version import ( - "path" - "github.com/elastic/cloud-on-k8s/operators/pkg/apis/elasticsearch/v1alpha1" "github.com/elastic/cloud-on-k8s/operators/pkg/controller/common/defaults" "github.com/elastic/cloud-on-k8s/operators/pkg/controller/common/version" @@ -19,14 +17,12 @@ import ( "github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/user" "github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/volume" "github.com/elastic/cloud-on-k8s/operators/pkg/utils/stringsutil" - corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" ) var ( DefaultMemoryLimits = resource.MustParse("2Gi") - SecurityPropsFile = path.Join(settings.ManagedConfigPath, settings.SecurityPropsFile) ) // NewExpectedPodSpecs creates PodSpecContexts for all Elasticsearch nodes in the given Elasticsearch cluster @@ -50,10 +46,8 @@ func NewExpectedPodSpecs( SetVMMaxMapCount: es.Spec.SetVMMaxMapCount, // volumes UsersSecretVolume: paramsTmpl.UsersSecretVolume, - ConfigMapVolume: paramsTmpl.ConfigMapVolume, - ClusterSecretsRef: paramsTmpl.ClusterSecretsRef, ProbeUser: paramsTmpl.ProbeUser, - ReloadCredsUser: paramsTmpl.ReloadCredsUser, + KeystoreUser: paramsTmpl.KeystoreUser, UnicastHostsVolume: paramsTmpl.UnicastHostsVolume, // pod params NodeSpec: node, @@ -89,14 +83,9 @@ func podSpec( user.ElasticInternalUsersSecretName(p.ClusterName), volume.ProbeUserVolumeName, volume.ProbeUserSecretMountPath, []string{p.ProbeUser.Name}, ) - reloadCredsSecret := volume.NewSelectiveSecretVolumeWithMountPath( - user.ElasticInternalUsersSecretName(p.ClusterName), volume.ReloadCredsUserVolumeName, - volume.ReloadCredsUserSecretMountPath, []string{p.ReloadCredsUser.Name}, - ) - clusterSecretsSecretVolume := volume.NewSecretVolumeWithMountPath( - p.ClusterSecretsRef.Name, - "secrets", - volume.ClusterSecretsVolumeMountPath, + keystoreUserSecret := volume.NewSelectiveSecretVolumeWithMountPath( + user.ElasticInternalUsersSecretName(p.ClusterName), volume.KeystoreUserVolumeName, + volume.KeystoreUserSecretMountPath, []string{p.KeystoreUser.Name}, ) // we don't have a secret name for this, this will be injected as a volume for us upon creation, this is fine // because we will not be adding this to the container Volumes, only the VolumeMounts section. @@ -130,7 +119,7 @@ func podSpec( // setup heap size based on memory limits heapSize := MemoryLimitsToHeapSize(*builder.Container.Resources.Limits.Memory()) - builder = builder.WithEnv(newEnvironmentVarsFn(p, heapSize, httpCertificatesVolume, reloadCredsSecret, secureSettingsVolume)...) + builder = builder.WithEnv(newEnvironmentVarsFn(p, heapSize, httpCertificatesVolume, keystoreUserSecret, secureSettingsVolume)...) // setup init containers initContainers, err := newInitContainersFn(builder.Container.Image, operatorImage, p.SetVMMaxMapCount, transportCertificatesVolume) @@ -143,11 +132,9 @@ func podSpec( append(initcontainer.PrepareFsSharedVolumes.Volumes(), initcontainer.ProcessManagerVolume.Volume(), p.UsersSecretVolume.Volume(), - p.ConfigMapVolume.Volume(), p.UnicastHostsVolume.Volume(), probeSecret.Volume(), - clusterSecretsSecretVolume.Volume(), - reloadCredsSecret.Volume(), + keystoreUserSecret.Volume(), secureSettingsVolume.Volume(), httpCertificatesVolume.Volume(), )...). @@ -155,12 +142,10 @@ func podSpec( append(initcontainer.PrepareFsSharedVolumes.EsContainerVolumeMounts(), initcontainer.ProcessManagerVolume.EsContainerVolumeMount(), p.UsersSecretVolume.VolumeMount(), - p.ConfigMapVolume.VolumeMount(), p.UnicastHostsVolume.VolumeMount(), probeSecret.VolumeMount(), - clusterSecretsSecretVolume.VolumeMount(), transportCertificatesVolume.VolumeMount(), - reloadCredsSecret.VolumeMount(), + keystoreUserSecret.VolumeMount(), secureSettingsVolume.VolumeMount(), httpCertificatesVolume.VolumeMount(), )...). diff --git a/operators/pkg/controller/elasticsearch/version/version6/podspecs.go b/operators/pkg/controller/elasticsearch/version/version6/podspecs.go index f748ed8354..a0b0fb58ba 100644 --- a/operators/pkg/controller/elasticsearch/version/version6/podspecs.go +++ b/operators/pkg/controller/elasticsearch/version/version6/podspecs.go @@ -27,24 +27,24 @@ var ( linkedFiles6 = initcontainer.LinkedFilesArray{ Array: []initcontainer.LinkedFile{ { - Source: stringsutil.Concat(volume.DefaultSecretMountPath, "/", user.ElasticUsersFile), - Target: stringsutil.Concat("/usr/share/elasticsearch/config", "/", user.ElasticUsersFile), + Source: stringsutil.Concat(volume.XPackFileRealmVolumeMountPath, "/", user.ElasticUsersFile), + Target: stringsutil.Concat(initcontainer.EsConfigSharedVolume.EsContainerMountPath, "/", user.ElasticUsersFile), }, { - Source: stringsutil.Concat(volume.DefaultSecretMountPath, "/", user.ElasticRolesFile), - Target: stringsutil.Concat("/usr/share/elasticsearch/config", "/", user.ElasticRolesFile), + Source: stringsutil.Concat(volume.XPackFileRealmVolumeMountPath, "/", user.ElasticRolesFile), + Target: stringsutil.Concat(initcontainer.EsConfigSharedVolume.EsContainerMountPath, "/", user.ElasticRolesFile), }, { - Source: stringsutil.Concat(volume.DefaultSecretMountPath, "/", user.ElasticUsersRolesFile), - Target: stringsutil.Concat("/usr/share/elasticsearch/config", "/", user.ElasticUsersRolesFile), + Source: stringsutil.Concat(volume.XPackFileRealmVolumeMountPath, "/", user.ElasticUsersRolesFile), + Target: stringsutil.Concat(initcontainer.EsConfigSharedVolume.EsContainerMountPath, "/", user.ElasticUsersRolesFile), }, { Source: stringsutil.Concat(settings.ConfigVolumeMountPath, "/", settings.ConfigFileName), - Target: stringsutil.Concat("/usr/share/elasticsearch/config", "/", settings.ConfigFileName), + Target: stringsutil.Concat(initcontainer.EsConfigSharedVolume.EsContainerMountPath, "/", settings.ConfigFileName), }, { Source: stringsutil.Concat(volume.UnicastHostsVolumeMountPath, "/", volume.UnicastHostsFile), - Target: stringsutil.Concat("/usr/share/elasticsearch/config", "/", volume.UnicastHostsFile), + Target: stringsutil.Concat(initcontainer.EsConfigSharedVolume.EsContainerMountPath, "/", volume.UnicastHostsFile), }, }, } @@ -56,12 +56,11 @@ func ExpectedPodSpecs( paramsTmpl pod.NewPodSpecParams, operatorImage string, ) ([]pod.PodSpecContext, error) { - // we mount the elastic users secret over at /secrets, which needs to match the "linkedFiles" in the init-container - // creation below. - // TODO: make this association clearer. - paramsTmpl.UsersSecretVolume = volume.NewSecretVolume( + // the contents of the file realm volume needs to be symlinked into place + paramsTmpl.UsersSecretVolume = volume.NewSecretVolumeWithMountPath( user.ElasticUsersRolesSecretName(es.Name), - "users", + volume.XPackFileRealmVolumeName, + volume.XPackFileRealmVolumeMountPath, ) return version.NewExpectedPodSpecs( @@ -95,7 +94,7 @@ func newEnvironmentVars( p pod.NewPodSpecParams, heapSize int, httpCertificatesVolume volume.SecretVolume, - reloadCredsUserSecretVolume volume.SecretVolume, + keystoreUserSecretVolume volume.SecretVolume, secureSettingsSecretVolume volume.SecretVolume, ) []corev1.EnvVar { vars := []corev1.EnvVar{ @@ -109,7 +108,7 @@ func newEnvironmentVars( }}, // TODO: the JVM options are hardcoded, but should be configurable - {Name: settings.EnvEsJavaOpts, Value: fmt.Sprintf("-Xms%dM -Xmx%dM -Djava.security.properties=%s", heapSize, heapSize, version.SecurityPropsFile)}, + {Name: settings.EnvEsJavaOpts, Value: fmt.Sprintf("-Xms%dM -Xmx%dM", heapSize, heapSize)}, {Name: settings.EnvReadinessProbeProtocol, Value: "https"}, {Name: settings.EnvProbeUsername, Value: p.ProbeUser.Name}, @@ -120,8 +119,8 @@ func newEnvironmentVars( vars = append(vars, keystore.NewEnvVars( keystore.NewEnvVarsParams{ SourceDir: secureSettingsSecretVolume.VolumeMount().MountPath, - ESUsername: p.ReloadCredsUser.Name, - ESPasswordFilepath: path.Join(reloadCredsUserSecretVolume.VolumeMount().MountPath, p.ReloadCredsUser.Name), + ESUsername: p.KeystoreUser.Name, + ESPasswordFilepath: path.Join(keystoreUserSecretVolume.VolumeMount().MountPath, p.KeystoreUser.Name), ESCaCertPath: path.Join(httpCertificatesVolume.VolumeMount().MountPath, certificates.CertFileName), ESVersion: p.Version, })...) diff --git a/operators/pkg/controller/elasticsearch/version/version6/podspecs_test.go b/operators/pkg/controller/elasticsearch/version/version6/podspecs_test.go index cd16544c53..fa8fd80adb 100644 --- a/operators/pkg/controller/elasticsearch/version/version6/podspecs_test.go +++ b/operators/pkg/controller/elasticsearch/version/version6/podspecs_test.go @@ -17,7 +17,6 @@ import ( "github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/pod" "github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/processmanager" "github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/settings" - "github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/version" "github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/volume" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" @@ -25,7 +24,7 @@ import ( ) var testProbeUser = client.UserAuth{Name: "username1", Password: "supersecure"} -var testReloadCredsUser = client.UserAuth{Name: "username2", Password: "supersecure"} +var testKeystoreUser = client.UserAuth{Name: "username2", Password: "supersecure"} var testObjectMeta = metav1.ObjectMeta{ Name: "my-es", Namespace: "default", @@ -37,7 +36,7 @@ func TestNewEnvironmentVars(t *testing.T) { heapSize int httpCertificatesVolume volume.SecretVolume privateKeyVolume volume.SecretVolume - reloadCredsUserVolume volume.SecretVolume + keystoreUserVolume volume.SecretVolume secureSettingsVolume volume.SecretVolume } tests := []struct { @@ -49,14 +48,14 @@ func TestNewEnvironmentVars(t *testing.T) { name: "2 nodes", args: args{ p: pod.NewPodSpecParams{ - ProbeUser: testProbeUser, - ReloadCredsUser: testReloadCredsUser, - Version: "6", + ProbeUser: testProbeUser, + KeystoreUser: testKeystoreUser, + Version: "6", }, heapSize: 1024, httpCertificatesVolume: volume.NewSecretVolumeWithMountPath("certs", "/certs", "/certs"), privateKeyVolume: volume.NewSecretVolumeWithMountPath("key", "/key", "/key"), - reloadCredsUserVolume: volume.NewSecretVolumeWithMountPath("creds", "/creds", "/creds"), + keystoreUserVolume: volume.NewSecretVolumeWithMountPath("creds", "/creds", "/creds"), secureSettingsVolume: volume.NewSecretVolumeWithMountPath("secure-settings", "/secure-settings", "/secure-settings"), }, wantEnv: []corev1.EnvVar{ @@ -66,7 +65,7 @@ func TestNewEnvironmentVars(t *testing.T) { {Name: settings.EnvPodIP, Value: "", ValueFrom: &corev1.EnvVarSource{ FieldRef: &corev1.ObjectFieldSelector{APIVersion: "v1", FieldPath: "status.podIP"}, }}, - {Name: settings.EnvEsJavaOpts, Value: fmt.Sprintf("-Xms%dM -Xmx%dM -Djava.security.properties=%s", 1024, 1024, version.SecurityPropsFile)}, + {Name: settings.EnvEsJavaOpts, Value: fmt.Sprintf("-Xms%dM -Xmx%dM", 1024, 1024)}, {Name: settings.EnvReadinessProbeProtocol, Value: "https"}, {Name: settings.EnvProbeUsername, Value: "username1"}, {Name: settings.EnvProbePasswordFile, Value: path.Join(volume.ProbeUserSecretMountPath, "username1")}, @@ -88,7 +87,7 @@ func TestNewEnvironmentVars(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := newEnvironmentVars(tt.args.p, tt.args.heapSize, tt.args.httpCertificatesVolume, - tt.args.reloadCredsUserVolume, tt.args.secureSettingsVolume) + tt.args.keystoreUserVolume, tt.args.secureSettingsVolume) assert.Equal(t, tt.wantEnv, got) }) } @@ -176,10 +175,13 @@ func TestCreateExpectedPodSpecsReturnsCorrectPodSpec(t *testing.T) { podSpec, err := ExpectedPodSpecs( es, pod.NewPodSpecParams{ - ProbeUser: testProbeUser, - UsersSecretVolume: volume.NewSecretVolumeWithMountPath("", "user-secret-vol", "/mount/path"), - ConfigMapVolume: volume.NewConfigMapVolume("config-map-volume", settings.ManagedConfigPath), - UnicastHostsVolume: volume.NewConfigMapVolume(name.UnicastHostsConfigMap(es.Name), volume.UnicastHostsVolumeMountPath), + ProbeUser: testProbeUser, + UsersSecretVolume: volume.NewSecretVolumeWithMountPath("", "user-secret-vol", "/mount/path"), + UnicastHostsVolume: volume.NewConfigMapVolume( + name.UnicastHostsConfigMap(es.Name), + volume.UnicastHostsVolumeName, + volume.UnicastHostsVolumeMountPath, + ), }, "operator-image-dummy", ) @@ -189,7 +191,7 @@ func TestCreateExpectedPodSpecsReturnsCorrectPodSpec(t *testing.T) { esPodSpec := podSpec[0].PodSpec assert.Equal(t, 1, len(esPodSpec.Containers)) assert.Equal(t, 3, len(esPodSpec.InitContainers)) - assert.Equal(t, 14, len(esPodSpec.Volumes)) + assert.Equal(t, 12, len(esPodSpec.Volumes)) esContainer := esPodSpec.Containers[0] assert.NotEqual(t, 0, esContainer.Env) @@ -199,6 +201,6 @@ func TestCreateExpectedPodSpecsReturnsCorrectPodSpec(t *testing.T) { assert.ElementsMatch(t, pod.DefaultContainerPorts, esContainer.Ports) // volume mounts is one less than volumes because we're not mounting the transport certs secret until pod creation // time - assert.Equal(t, 15, len(esContainer.VolumeMounts)) + assert.Equal(t, 13, len(esContainer.VolumeMounts)) assert.NotEmpty(t, esContainer.ReadinessProbe.Handler.Exec.Command) } diff --git a/operators/pkg/controller/elasticsearch/volume/configmap.go b/operators/pkg/controller/elasticsearch/volume/configmap.go index c93956659d..1dc86f415d 100644 --- a/operators/pkg/controller/elasticsearch/volume/configmap.go +++ b/operators/pkg/controller/elasticsearch/volume/configmap.go @@ -9,18 +9,20 @@ import ( ) // NewConfigMapVolume creates a new ConfigMapVolume struct -func NewConfigMapVolume(name, mountPath string) ConfigMapVolume { +func NewConfigMapVolume(configMapName, name, mountPath string) ConfigMapVolume { return ConfigMapVolume{ - name: name, - mountPath: mountPath, + configMapName: configMapName, + name: name, + mountPath: mountPath, } } // ConfigMapVolume defines a volume to expose a configmap type ConfigMapVolume struct { - name string - mountPath string - items []corev1.KeyToPath + configMapName string + name string + mountPath string + items []corev1.KeyToPath } // VolumeMount returns the k8s volume mount. @@ -39,7 +41,7 @@ func (cm ConfigMapVolume) Volume() corev1.Volume { VolumeSource: corev1.VolumeSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ - Name: cm.name, + Name: cm.configMapName, }, Items: cm.items, Optional: &defaultOptional, diff --git a/operators/pkg/controller/elasticsearch/volume/secret.go b/operators/pkg/controller/elasticsearch/volume/secret.go index 0ac78e3bd9..2b933d6808 100644 --- a/operators/pkg/controller/elasticsearch/volume/secret.go +++ b/operators/pkg/controller/elasticsearch/volume/secret.go @@ -16,11 +16,6 @@ type SecretVolume struct { items []corev1.KeyToPath } -// NewSecretVolume creates a new SecretVolume with default mount path. -func NewSecretVolume(secretName string, name string) SecretVolume { - return NewSecretVolumeWithMountPath(secretName, name, DefaultSecretMountPath) -} - // NewSecretVolumeWithMountPath creates a new SecretVolume func NewSecretVolumeWithMountPath(secretName string, name string, mountPath string) SecretVolume { return SecretVolume{ diff --git a/operators/pkg/controller/elasticsearch/volume/secret_test.go b/operators/pkg/controller/elasticsearch/volume/secret_test.go index eb43e2a2ae..e6d56c196c 100644 --- a/operators/pkg/controller/elasticsearch/volume/secret_test.go +++ b/operators/pkg/controller/elasticsearch/volume/secret_test.go @@ -19,7 +19,7 @@ func TestSecretVolumeItemProjection(t *testing.T) { expected []corev1.KeyToPath }{ { - volume: NewSecretVolume("secret", "/secrets"), + volume: NewSecretVolumeWithMountPath("secret", "secrets", "/secrets"), expected: nil, }, { diff --git a/operators/pkg/controller/elasticsearch/volume/volume.go b/operators/pkg/controller/elasticsearch/volume/volume.go index 07511bbc5a..bfc16c23e1 100644 --- a/operators/pkg/controller/elasticsearch/volume/volume.go +++ b/operators/pkg/controller/elasticsearch/volume/volume.go @@ -10,30 +10,29 @@ import ( // Default values for the volume name and paths const ( - // DefaultSecretMountPath where secrets are mounted if not specified otherwise. - DefaultSecretMountPath = "/mnt/elastic/secrets" + ProbeUserSecretMountPath = "/mnt/elastic-internal/probe-user" + ProbeUserVolumeName = "elastic-internal-probe-user" - ProbeUserSecretMountPath = "/mnt/elastic/probe-user" - ProbeUserVolumeName = "probe-user" + KeystoreUserSecretMountPath = "/mnt/elastic-internal/keystore-user" + KeystoreUserVolumeName = "elsatic-internal-keystore-user" - ReloadCredsUserSecretMountPath = "/mnt/elastic/reload-creds-user" - ReloadCredsUserVolumeName = "reload-creds-user" - - TransportCertificatesSecretVolumeName = "transport-certificates" + TransportCertificatesSecretVolumeName = "elastic-internal-transport-certificates" TransportCertificatesSecretVolumeMountPath = "/usr/share/elasticsearch/config/transport-certs" - HTTPCertificatesSecretVolumeName = "http-certificates" + HTTPCertificatesSecretVolumeName = "elastic-internal-http-certificates" HTTPCertificatesSecretVolumeMountPath = "/usr/share/elasticsearch/config/http-certs" - SecureSettingsVolumeName = "secure-settings" - SecureSettingsVolumeMountPath = "/mnt/elastic/secure-settings" + SecureSettingsVolumeName = "elastic-internal-secure-settings" + SecureSettingsVolumeMountPath = "/mnt/elastic-internal/secure-settings" - ClusterSecretsVolumeMountPath = "/usr/share/elasticsearch/config/secrets" + XPackFileRealmVolumeName = "elastic-internal-xpack-file-realm" + XPackFileRealmVolumeMountPath = "/mnt/elastic-internal/xpack-file-realm" - UnicastHostsVolumeMountPath = "/mnt/elastic/unicast-hosts" + UnicastHostsVolumeName = "elastic-internal-unicast-hosts" + UnicastHostsVolumeMountPath = "/mnt/elastic-internal/unicast-hosts" UnicastHostsFile = "unicast_hosts.txt" - ProcessManagerEmptyDirMountPath = "/mnt/elastic/process-manager" + ProcessManagerEmptyDirMountPath = "/mnt/elastic-internal/process-manager" ) var ( From 0d2f7fcaefa6ce03f3bbc56f40f38691f3f0cb1b Mon Sep 17 00:00:00 2001 From: Njal Karevoll Date: Sat, 8 Jun 2019 01:02:38 +0200 Subject: [PATCH 3/8] Rename secret -roles-users to -xpack-file-realm --- operators/pkg/controller/elasticsearch/name/name.go | 6 +++--- .../pkg/controller/elasticsearch/user/credentials.go | 8 ++++---- .../pkg/controller/elasticsearch/user/credentials_test.go | 2 +- .../controller/elasticsearch/version/version6/podspecs.go | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/operators/pkg/controller/elasticsearch/name/name.go b/operators/pkg/controller/elasticsearch/name/name.go index 5f5767574b..8556140d22 100644 --- a/operators/pkg/controller/elasticsearch/name/name.go +++ b/operators/pkg/controller/elasticsearch/name/name.go @@ -29,7 +29,7 @@ const ( certsSecretSuffix = "certs" httpServiceSuffix = "http" elasticUserSecretSuffix = "elastic-user" - esRolesUsersSecretSuffix = "roles-users" + xpackFileRealmSecretSuffix = "xpack-file-realm" internalUsersSecretSuffix = "internal-users" unicastHostsConfigMapSuffix = "unicast-hosts" licenseSecretSuffix = "license" @@ -105,8 +105,8 @@ func ElasticUserSecret(esName string) string { return ESNamer.Suffix(esName, elasticUserSecretSuffix) } -func EsRolesUsersSecret(esName string) string { - return ESNamer.Suffix(esName, esRolesUsersSecretSuffix) +func XPackFileRealmSecret(esName string) string { + return ESNamer.Suffix(esName, xpackFileRealmSecretSuffix) } func InternalUsersSecret(esName string) string { diff --git a/operators/pkg/controller/elasticsearch/user/credentials.go b/operators/pkg/controller/elasticsearch/user/credentials.go index d725a99dc8..f38b413a0c 100644 --- a/operators/pkg/controller/elasticsearch/user/credentials.go +++ b/operators/pkg/controller/elasticsearch/user/credentials.go @@ -29,9 +29,9 @@ const ( ElasticRolesFile = "roles.yml" ) -// ElasticUsersRolesSecretName is the name of the secret containing all users and roles information in ES format. -func ElasticUsersRolesSecretName(ownerName string) string { - return name.EsRolesUsersSecret(ownerName) +// XPackFileRealmSecretName is the name of the secret containing all users and roles information in ES format. +func XPackFileRealmSecretName(ownerName string) string { + return name.XPackFileRealmSecret(ownerName) } // ElasticInternalUsersSecretName is the name of the secret containing the internal users' credentials. @@ -228,7 +228,7 @@ func NewElasticUsersCredentialsAndRoles( secret: corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Namespace: es.Namespace, - Name: ElasticUsersRolesSecretName(es.Name), + Name: XPackFileRealmSecretName(es.Name), Labels: label.NewLabels(es), }, Data: map[string][]byte{ diff --git a/operators/pkg/controller/elasticsearch/user/credentials_test.go b/operators/pkg/controller/elasticsearch/user/credentials_test.go index d10f870aa8..571b0e9601 100644 --- a/operators/pkg/controller/elasticsearch/user/credentials_test.go +++ b/operators/pkg/controller/elasticsearch/user/credentials_test.go @@ -50,7 +50,7 @@ func TestNewUserSecrets(t *testing.T) { }, { subject: elasticUsers, - expectedName: "my-cluster-es-roles-users", + expectedName: "my-cluster-es-xpack-file-realm", expectedKeys: []string{ElasticRolesFile, ElasticUsersFile, ElasticUsersRolesFile}, }, } diff --git a/operators/pkg/controller/elasticsearch/version/version6/podspecs.go b/operators/pkg/controller/elasticsearch/version/version6/podspecs.go index a0b0fb58ba..bcef1dbabe 100644 --- a/operators/pkg/controller/elasticsearch/version/version6/podspecs.go +++ b/operators/pkg/controller/elasticsearch/version/version6/podspecs.go @@ -58,7 +58,7 @@ func ExpectedPodSpecs( ) ([]pod.PodSpecContext, error) { // the contents of the file realm volume needs to be symlinked into place paramsTmpl.UsersSecretVolume = volume.NewSecretVolumeWithMountPath( - user.ElasticUsersRolesSecretName(es.Name), + user.XPackFileRealmSecretName(es.Name), volume.XPackFileRealmVolumeName, volume.XPackFileRealmVolumeMountPath, ) From 451783a901166c0d764b16810529ef33d557d360 Mon Sep 17 00:00:00 2001 From: Njal Karevoll Date: Sat, 8 Jun 2019 15:22:42 +0200 Subject: [PATCH 4/8] Use persistent storage by default for ES data. By default they will get a 1Gi volume, which is chosen because matches roughly 1:1 vs the default heap. Users can opt out of this behavior by specifying the data volume in the Elasticsearch resource directly ```yaml apiVersion: elasticsearch.k8s.elastic.co/v1alpha1 kind: Elasticsearch metadata: name: elasticsearch-sample spec: version: "7.1.0" nodes: - nodeCount: 1 podTemplate: spec: volumes: - name: elasticsearch-data emptyDir: {} ``` Builds on top of https://github.com/elastic/cloud-on-k8s/pull/1024 Closes: https://github.com/elastic/cloud-on-k8s/issues/913 --- .../pkg/controller/common/defaults/pvc.go | 27 ++++++ .../controller/common/defaults/pvc_test.go | 73 ++++++++++++++++ .../pkg/controller/elasticsearch/pod/pod.go | 21 +++++ .../elasticsearch/version/common.go | 24 ++++++ .../elasticsearch/version/common_test.go | 85 +++++++++++++++++++ 5 files changed, 230 insertions(+) create mode 100644 operators/pkg/controller/common/defaults/pvc.go create mode 100644 operators/pkg/controller/common/defaults/pvc_test.go diff --git a/operators/pkg/controller/common/defaults/pvc.go b/operators/pkg/controller/common/defaults/pvc.go new file mode 100644 index 0000000000..ddf688cb1c --- /dev/null +++ b/operators/pkg/controller/common/defaults/pvc.go @@ -0,0 +1,27 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +package defaults + +import v1 "k8s.io/api/core/v1" + +// AppendDefaultPVCs appends PVCs from defaults if a PVC with the same metadata.name is not found in existing. +func AppendDefaultPVCs( + existing []v1.PersistentVolumeClaim, + defaults ...v1.PersistentVolumeClaim, +) []v1.PersistentVolumeClaim { +defaults: + for _, defaultPVC := range defaults { + for _, existingPVC := range existing { + if existingPVC.Name == defaultPVC.Name { + // a PVC with that name already exists, skip. + continue defaults + } + } + + existing = append(existing, defaultPVC) + } + + return existing +} diff --git a/operators/pkg/controller/common/defaults/pvc_test.go b/operators/pkg/controller/common/defaults/pvc_test.go new file mode 100644 index 0000000000..b0ee8452d9 --- /dev/null +++ b/operators/pkg/controller/common/defaults/pvc_test.go @@ -0,0 +1,73 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +package defaults + +import ( + "reflect" + "testing" + + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestAppendDefaultPVCs(t *testing.T) { + foo := v1.PersistentVolumeClaim{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + }, + } + bar := v1.PersistentVolumeClaim{ + ObjectMeta: metav1.ObjectMeta{ + Name: "bar", + }, + } + + strRef := func(s string) *string { + return &s + } + + type args struct { + existing []v1.PersistentVolumeClaim + defaults []v1.PersistentVolumeClaim + } + tests := []struct { + name string + args args + want []v1.PersistentVolumeClaim + }{ + { + name: "append new pvcs", + args: args{ + existing: []v1.PersistentVolumeClaim{foo}, + defaults: []v1.PersistentVolumeClaim{bar}, + }, + want: []v1.PersistentVolumeClaim{foo, bar}, + }, + { + name: "do not overwrite or duplicate existing", + args: args{ + existing: []v1.PersistentVolumeClaim{foo}, + defaults: []v1.PersistentVolumeClaim{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + }, + Spec: v1.PersistentVolumeClaimSpec{ + StorageClassName: strRef("custom"), + }, + }, + }, + }, + want: []v1.PersistentVolumeClaim{foo}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := AppendDefaultPVCs(tt.args.existing, tt.args.defaults...); !reflect.DeepEqual(got, tt.want) { + t.Errorf("AppendDefaultPVCs() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/operators/pkg/controller/elasticsearch/pod/pod.go b/operators/pkg/controller/elasticsearch/pod/pod.go index 97071e4aa0..47875c3b40 100644 --- a/operators/pkg/controller/elasticsearch/pod/pod.go +++ b/operators/pkg/controller/elasticsearch/pod/pod.go @@ -12,6 +12,8 @@ import ( "github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/settings" "github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/volume" corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) const ( @@ -29,6 +31,25 @@ var ( {Name: "transport", ContainerPort: network.TransportPort, Protocol: corev1.ProtocolTCP}, {Name: "process-manager", ContainerPort: processmanager.DefaultPort, Protocol: corev1.ProtocolTCP}, } + + // DefaultVolumeClaimsTemplates is the default volume claim templates for Elasticsearch pods + DefaultVolumeClaimsTemplates = []corev1.PersistentVolumeClaim{ + { + ObjectMeta: v1.ObjectMeta{ + Name: "elasticsearch-data", + }, + Spec: corev1.PersistentVolumeClaimSpec{ + AccessModes: []corev1.PersistentVolumeAccessMode{ + corev1.ReadWriteOnce, + }, + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceStorage: resource.MustParse("1Gi"), + }, + }, + }, + }, + } ) // PodWithConfig contains a pod and its configuration diff --git a/operators/pkg/controller/elasticsearch/version/common.go b/operators/pkg/controller/elasticsearch/version/common.go index e294bc6660..651f12bc04 100644 --- a/operators/pkg/controller/elasticsearch/version/common.go +++ b/operators/pkg/controller/elasticsearch/version/common.go @@ -37,6 +37,15 @@ func NewExpectedPodSpecs( podSpecs := make([]pod.PodSpecContext, 0, es.Spec.NodeCount()) for _, node := range es.Spec.Nodes { + // add default PVCs to the node spec + for _, defaultPVC := range pod.DefaultVolumeClaimsTemplates { + if shouldAddDefaultPVCToNodeSpec(defaultPVC, node) { + node.VolumeClaimTemplates = defaults.AppendDefaultPVCs( + node.VolumeClaimTemplates, defaultPVC, + ) + } + } + for i := int32(0); i < node.NodeCount; i++ { params := pod.NewPodSpecParams{ // cluster-wide params @@ -70,6 +79,21 @@ func NewExpectedPodSpecs( return podSpecs, nil } +// shouldAddDefaultPVCToNodeSpec returns true if the provided default PVC should be added to the NodeSpec +func shouldAddDefaultPVCToNodeSpec(defaultPVC corev1.PersistentVolumeClaim, node v1alpha1.NodeSpec) bool { + for _, volume := range node.PodTemplate.Spec.Volumes { + if volume.Name == defaultPVC.Name { + if volume.PersistentVolumeClaim == nil { + // the template contains a custom volume which is not a PVC, so we should not add this + // defaulted PVC template + return false + } + } + } + + return true +} + // podSpec creates a new PodSpec for an Elasticsearch node func podSpec( p pod.NewPodSpecParams, diff --git a/operators/pkg/controller/elasticsearch/version/common_test.go b/operators/pkg/controller/elasticsearch/version/common_test.go index 771c53c8d0..cd968e1fe1 100644 --- a/operators/pkg/controller/elasticsearch/version/common_test.go +++ b/operators/pkg/controller/elasticsearch/version/common_test.go @@ -478,3 +478,88 @@ func Test_podSpec(t *testing.T) { }) } } + +func Test_shouldAddDefaultPVCToNodeSpec(t *testing.T) { + foo := corev1.PersistentVolumeClaim{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + }, + } + + type args struct { + defaultPVC corev1.PersistentVolumeClaim + node v1alpha1.NodeSpec + } + tests := []struct { + name string + args args + want bool + }{ + { + name: "volume of pvc type already exists", + args: args{ + defaultPVC: foo, + node: v1alpha1.NodeSpec{ + PodTemplate: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Volumes: []corev1.Volume{ + { + Name: "foo", + VolumeSource: corev1.VolumeSource{ + PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{}, + }, + }, + }, + }, + }, + }, + }, + want: true, + }, + { + name: "volume of non-pvc type already exists", + args: args{ + defaultPVC: foo, + node: v1alpha1.NodeSpec{ + PodTemplate: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Volumes: []corev1.Volume{ + { + Name: "foo", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}, + }, + }, + }, + }, + }, + }, + want: false, + }, + { + name: "volume of non-pvc type already exists with different name", + args: args{ + defaultPVC: foo, + node: v1alpha1.NodeSpec{ + PodTemplate: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Volumes: []corev1.Volume{ + { + Name: "bar", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}, + }, + }, + }, + }, + }, + }, + want: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := shouldAddDefaultPVCToNodeSpec(tt.args.defaultPVC, tt.args.node); got != tt.want { + t.Errorf("shouldAddDefaultPVCToNodeSpec() = %v, want %v", got, tt.want) + } + }) + } +} From f5f7405aec9f9ec31cbe0225e96b75539ebcab3e Mon Sep 17 00:00:00 2001 From: Njal Karevoll Date: Mon, 10 Jun 2019 14:07:44 +0200 Subject: [PATCH 5/8] Move PVC defaults podSpec volume matching into defaults package --- .../pkg/controller/common/defaults/pvc.go | 22 ++++- .../controller/common/defaults/pvc_test.go | 53 +++++++++++- .../pkg/controller/elasticsearch/pod/pod.go | 4 +- .../elasticsearch/version/common.go | 25 +----- .../elasticsearch/version/common_test.go | 85 ------------------- 5 files changed, 78 insertions(+), 111 deletions(-) diff --git a/operators/pkg/controller/common/defaults/pvc.go b/operators/pkg/controller/common/defaults/pvc.go index ddf688cb1c..670a5dabe7 100644 --- a/operators/pkg/controller/common/defaults/pvc.go +++ b/operators/pkg/controller/common/defaults/pvc.go @@ -6,11 +6,27 @@ package defaults import v1 "k8s.io/api/core/v1" -// AppendDefaultPVCs appends PVCs from defaults if a PVC with the same metadata.name is not found in existing. +// AppendDefaultPVCs appends defaults PVCs to a set of existing ones. +// +// The default not appended if: +// - a Volume with a the same .name is found in podSpec.Volumes, and that volume is not a PVC volume +// - a PVC with the same metadata.name is found in existing. func AppendDefaultPVCs( existing []v1.PersistentVolumeClaim, + podSpec v1.PodSpec, defaults ...v1.PersistentVolumeClaim, ) []v1.PersistentVolumeClaim { + // create a set of volume names that are not PVC-volumes for efficient testing + nonPVCvolumes := map[string]struct{}{} + + for _, volume := range podSpec.Volumes { + if volume.PersistentVolumeClaim == nil { + // this volume is not a PVC + nonPVCvolumes[volume.Name] = struct{}{} + + } + } + defaults: for _, defaultPVC := range defaults { for _, existingPVC := range existing { @@ -18,6 +34,10 @@ defaults: // a PVC with that name already exists, skip. continue defaults } + if _, isNonPVCVolume := nonPVCvolumes[defaultPVC.Name]; isNonPVCVolume { + // the corresponding volume is not a PVC + continue defaults + } } existing = append(existing, defaultPVC) diff --git a/operators/pkg/controller/common/defaults/pvc_test.go b/operators/pkg/controller/common/defaults/pvc_test.go index b0ee8452d9..7992fe3cb1 100644 --- a/operators/pkg/controller/common/defaults/pvc_test.go +++ b/operators/pkg/controller/common/defaults/pvc_test.go @@ -30,6 +30,7 @@ func TestAppendDefaultPVCs(t *testing.T) { type args struct { existing []v1.PersistentVolumeClaim + podSpec v1.PodSpec defaults []v1.PersistentVolumeClaim } tests := []struct { @@ -62,10 +63,60 @@ func TestAppendDefaultPVCs(t *testing.T) { }, want: []v1.PersistentVolumeClaim{foo}, }, + { + name: "not add a default pvc if a non-pvc volume with the same name exists", + args: args{ + existing: []v1.PersistentVolumeClaim{foo}, + podSpec: v1.PodSpec{ + Volumes: []v1.Volume{ + { + Name: bar.Name, + VolumeSource: v1.VolumeSource{EmptyDir: &v1.EmptyDirVolumeSource{}}, + }, + }, + }, + defaults: []v1.PersistentVolumeClaim{bar}, + }, + want: []v1.PersistentVolumeClaim{foo}, + }, + { + name: "add a default pvc if a pvcvolume with the same name exists", + args: args{ + existing: []v1.PersistentVolumeClaim{foo}, + podSpec: v1.PodSpec{ + Volumes: []v1.Volume{ + { + Name: bar.Name, + VolumeSource: v1.VolumeSource{ + PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{}, + }, + }, + }, + }, + defaults: []v1.PersistentVolumeClaim{bar}, + }, + want: []v1.PersistentVolumeClaim{foo, bar}, + }, + { + name: "add a default pvc if a non-pvc volume with a different name exists", + args: args{ + existing: []v1.PersistentVolumeClaim{foo}, + podSpec: v1.PodSpec{ + Volumes: []v1.Volume{ + { + Name: "not" + bar.Name, + VolumeSource: v1.VolumeSource{EmptyDir: &v1.EmptyDirVolumeSource{}}, + }, + }, + }, + defaults: []v1.PersistentVolumeClaim{bar}, + }, + want: []v1.PersistentVolumeClaim{foo, bar}, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := AppendDefaultPVCs(tt.args.existing, tt.args.defaults...); !reflect.DeepEqual(got, tt.want) { + if got := AppendDefaultPVCs(tt.args.existing, tt.args.podSpec, tt.args.defaults...); !reflect.DeepEqual(got, tt.want) { t.Errorf("AppendDefaultPVCs() = %v, want %v", got, tt.want) } }) diff --git a/operators/pkg/controller/elasticsearch/pod/pod.go b/operators/pkg/controller/elasticsearch/pod/pod.go index 47875c3b40..adcc1a88e1 100644 --- a/operators/pkg/controller/elasticsearch/pod/pod.go +++ b/operators/pkg/controller/elasticsearch/pod/pod.go @@ -13,7 +13,7 @@ import ( "github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/volume" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) const ( @@ -35,7 +35,7 @@ var ( // DefaultVolumeClaimsTemplates is the default volume claim templates for Elasticsearch pods DefaultVolumeClaimsTemplates = []corev1.PersistentVolumeClaim{ { - ObjectMeta: v1.ObjectMeta{ + ObjectMeta: metav1.ObjectMeta{ Name: "elasticsearch-data", }, Spec: corev1.PersistentVolumeClaimSpec{ diff --git a/operators/pkg/controller/elasticsearch/version/common.go b/operators/pkg/controller/elasticsearch/version/common.go index 651f12bc04..5a964ba15c 100644 --- a/operators/pkg/controller/elasticsearch/version/common.go +++ b/operators/pkg/controller/elasticsearch/version/common.go @@ -38,13 +38,9 @@ func NewExpectedPodSpecs( for _, node := range es.Spec.Nodes { // add default PVCs to the node spec - for _, defaultPVC := range pod.DefaultVolumeClaimsTemplates { - if shouldAddDefaultPVCToNodeSpec(defaultPVC, node) { - node.VolumeClaimTemplates = defaults.AppendDefaultPVCs( - node.VolumeClaimTemplates, defaultPVC, - ) - } - } + node.VolumeClaimTemplates = defaults.AppendDefaultPVCs( + node.VolumeClaimTemplates, node.PodTemplate.Spec, pod.DefaultVolumeClaimsTemplates..., + ) for i := int32(0); i < node.NodeCount; i++ { params := pod.NewPodSpecParams{ @@ -79,21 +75,6 @@ func NewExpectedPodSpecs( return podSpecs, nil } -// shouldAddDefaultPVCToNodeSpec returns true if the provided default PVC should be added to the NodeSpec -func shouldAddDefaultPVCToNodeSpec(defaultPVC corev1.PersistentVolumeClaim, node v1alpha1.NodeSpec) bool { - for _, volume := range node.PodTemplate.Spec.Volumes { - if volume.Name == defaultPVC.Name { - if volume.PersistentVolumeClaim == nil { - // the template contains a custom volume which is not a PVC, so we should not add this - // defaulted PVC template - return false - } - } - } - - return true -} - // podSpec creates a new PodSpec for an Elasticsearch node func podSpec( p pod.NewPodSpecParams, diff --git a/operators/pkg/controller/elasticsearch/version/common_test.go b/operators/pkg/controller/elasticsearch/version/common_test.go index cd968e1fe1..771c53c8d0 100644 --- a/operators/pkg/controller/elasticsearch/version/common_test.go +++ b/operators/pkg/controller/elasticsearch/version/common_test.go @@ -478,88 +478,3 @@ func Test_podSpec(t *testing.T) { }) } } - -func Test_shouldAddDefaultPVCToNodeSpec(t *testing.T) { - foo := corev1.PersistentVolumeClaim{ - ObjectMeta: metav1.ObjectMeta{ - Name: "foo", - }, - } - - type args struct { - defaultPVC corev1.PersistentVolumeClaim - node v1alpha1.NodeSpec - } - tests := []struct { - name string - args args - want bool - }{ - { - name: "volume of pvc type already exists", - args: args{ - defaultPVC: foo, - node: v1alpha1.NodeSpec{ - PodTemplate: corev1.PodTemplateSpec{ - Spec: corev1.PodSpec{ - Volumes: []corev1.Volume{ - { - Name: "foo", - VolumeSource: corev1.VolumeSource{ - PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{}, - }, - }, - }, - }, - }, - }, - }, - want: true, - }, - { - name: "volume of non-pvc type already exists", - args: args{ - defaultPVC: foo, - node: v1alpha1.NodeSpec{ - PodTemplate: corev1.PodTemplateSpec{ - Spec: corev1.PodSpec{ - Volumes: []corev1.Volume{ - { - Name: "foo", - VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}, - }, - }, - }, - }, - }, - }, - want: false, - }, - { - name: "volume of non-pvc type already exists with different name", - args: args{ - defaultPVC: foo, - node: v1alpha1.NodeSpec{ - PodTemplate: corev1.PodTemplateSpec{ - Spec: corev1.PodSpec{ - Volumes: []corev1.Volume{ - { - Name: "bar", - VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}, - }, - }, - }, - }, - }, - }, - want: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := shouldAddDefaultPVCToNodeSpec(tt.args.defaultPVC, tt.args.node); got != tt.want { - t.Errorf("shouldAddDefaultPVCToNodeSpec() = %v, want %v", got, tt.want) - } - }) - } -} From 20ea05d4e5f477240bd3335630053f212a785b12 Mon Sep 17 00:00:00 2001 From: Njal Karevoll Date: Mon, 10 Jun 2019 14:35:18 +0200 Subject: [PATCH 6/8] Introduce a const for the "elasticsearch-data" volume name. --- .../elasticsearch/driver/pods_test.go | 5 +- .../elasticsearch/initcontainer/prepare_fs.go | 4 +- .../mutation/comparison/pod_test.go | 25 +++- .../pkg/controller/elasticsearch/pod/pod.go | 2 +- .../controller/elasticsearch/pvc/pvc_test.go | 119 +++++++++++++++--- .../controller/elasticsearch/volume/volume.go | 3 + 6 files changed, 130 insertions(+), 28 deletions(-) diff --git a/operators/pkg/controller/elasticsearch/driver/pods_test.go b/operators/pkg/controller/elasticsearch/driver/pods_test.go index ccf8c2cd35..894c732483 100644 --- a/operators/pkg/controller/elasticsearch/driver/pods_test.go +++ b/operators/pkg/controller/elasticsearch/driver/pods_test.go @@ -9,6 +9,7 @@ import ( "testing" "github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/label" + "github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/volume" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -28,7 +29,7 @@ func Test_newPVCFromTemplate(t *testing.T) { args: args{ claimTemplate: corev1.PersistentVolumeClaim{ ObjectMeta: metav1.ObjectMeta{ - Name: "elasticsearch-data", + Name: volume.ElasticsearchDataVolumeName, }, }, pod: &corev1.Pod{ @@ -43,7 +44,7 @@ func Test_newPVCFromTemplate(t *testing.T) { }, want: &corev1.PersistentVolumeClaim{ ObjectMeta: metav1.ObjectMeta{ - Name: "elasticsearch-sample-es-6bw9qkw77k-elasticsearch-data", + Name: "elasticsearch-sample-es-6bw9qkw77k-" + volume.ElasticsearchDataVolumeName, Labels: map[string]string{ "l1": "v1", "l2": "v2", diff --git a/operators/pkg/controller/elasticsearch/initcontainer/prepare_fs.go b/operators/pkg/controller/elasticsearch/initcontainer/prepare_fs.go index e58b43f98d..701f3d897f 100644 --- a/operators/pkg/controller/elasticsearch/initcontainer/prepare_fs.go +++ b/operators/pkg/controller/elasticsearch/initcontainer/prepare_fs.go @@ -15,13 +15,13 @@ import ( // Volumes that are shared between the prepare-fs init container and the ES container var ( DataSharedVolume = SharedVolume{ - Name: "elasticsearch-data", + Name: volume.ElasticsearchDataVolumeName, InitContainerMountPath: "/usr/share/elasticsearch/data", EsContainerMountPath: "/usr/share/elasticsearch/data", } LogsSharedVolume = SharedVolume{ - Name: "elasticsearch-logs", + Name: volume.ElasticsearchLogsVolumeName, InitContainerMountPath: "/usr/share/elasticsearch/logs", EsContainerMountPath: "/usr/share/elasticsearch/logs", } diff --git a/operators/pkg/controller/elasticsearch/mutation/comparison/pod_test.go b/operators/pkg/controller/elasticsearch/mutation/comparison/pod_test.go index f2795a8d00..6a90df2117 100644 --- a/operators/pkg/controller/elasticsearch/mutation/comparison/pod_test.go +++ b/operators/pkg/controller/elasticsearch/mutation/comparison/pod_test.go @@ -13,6 +13,7 @@ import ( "github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/name" "github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/pod" "github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/reconcile" + "github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/volume" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" @@ -317,14 +318,18 @@ func Test_PodMatchesSpec(t *testing.T) { { name: "Pod has a PVC with an empty VolumeMode", args: args{ - pod: withPVCs(ESPodWithConfig(defaultImage, defaultCPULimit), "elasticsearch-data", "elasticsearch-sample-es-7gnc85w7ll-elasticsearch-data"), + pod: withPVCs( + ESPodWithConfig(defaultImage, defaultCPULimit), + volume.ElasticsearchDataVolumeName, + "elasticsearch-sample-es-7gnc85w7ll-"+volume.ElasticsearchDataVolumeName, + ), spec: pod.PodSpecContext{ PodSpec: ESPodSpecContext(defaultImage, defaultCPULimit).PodSpec, NodeSpec: v1alpha1.NodeSpec{ VolumeClaimTemplates: []corev1.PersistentVolumeClaim{ { ObjectMeta: metav1.ObjectMeta{ - Name: "elasticsearch-data", + Name: volume.ElasticsearchDataVolumeName, }, Spec: corev1.PersistentVolumeClaimSpec{ VolumeMode: nil, @@ -336,7 +341,9 @@ func Test_PodMatchesSpec(t *testing.T) { state: reconcile.ResourcesState{ PVCs: []corev1.PersistentVolumeClaim{ { - ObjectMeta: metav1.ObjectMeta{Name: "elasticsearch-sample-es-7gnc85w7ll-elasticsearch-data"}, + ObjectMeta: metav1.ObjectMeta{ + Name: "elasticsearch-sample-es-7gnc85w7ll-" + volume.ElasticsearchDataVolumeName, + }, Spec: corev1.PersistentVolumeClaimSpec{ VolumeMode: &fs, }, @@ -350,14 +357,18 @@ func Test_PodMatchesSpec(t *testing.T) { { name: "Pod has a PVC with a VolumeMode set to something else than default setting", args: args{ - pod: withPVCs(ESPodWithConfig(defaultImage, defaultCPULimit), "elasticsearch-data", "elasticsearch-sample-es-7gnc85w7ll-elasticsearch-data"), + pod: withPVCs( + ESPodWithConfig(defaultImage, defaultCPULimit), + volume.ElasticsearchDataVolumeName, + "elasticsearch-sample-es-7gnc85w7ll-"+volume.ElasticsearchDataVolumeName, + ), spec: pod.PodSpecContext{ PodSpec: ESPodSpecContext(defaultImage, defaultCPULimit).PodSpec, NodeSpec: v1alpha1.NodeSpec{ VolumeClaimTemplates: []corev1.PersistentVolumeClaim{ { ObjectMeta: metav1.ObjectMeta{ - Name: "elasticsearch-data", + Name: volume.ElasticsearchDataVolumeName, }, Spec: corev1.PersistentVolumeClaimSpec{ VolumeMode: &block, @@ -369,7 +380,9 @@ func Test_PodMatchesSpec(t *testing.T) { state: reconcile.ResourcesState{ PVCs: []corev1.PersistentVolumeClaim{ { - ObjectMeta: metav1.ObjectMeta{Name: "elasticsearch-sample-es-7gnc85w7ll-elasticsearch-data"}, + ObjectMeta: metav1.ObjectMeta{ + Name: "elasticsearch-sample-es-7gnc85w7ll-" + volume.ElasticsearchDataVolumeName, + }, Spec: corev1.PersistentVolumeClaimSpec{ VolumeMode: &block, }, diff --git a/operators/pkg/controller/elasticsearch/pod/pod.go b/operators/pkg/controller/elasticsearch/pod/pod.go index 4747aa40b8..36e076ca67 100644 --- a/operators/pkg/controller/elasticsearch/pod/pod.go +++ b/operators/pkg/controller/elasticsearch/pod/pod.go @@ -37,7 +37,7 @@ var ( DefaultVolumeClaimsTemplates = []corev1.PersistentVolumeClaim{ { ObjectMeta: metav1.ObjectMeta{ - Name: "elasticsearch-data", + Name: volume.ElasticsearchDataVolumeName, }, Spec: corev1.PersistentVolumeClaimSpec{ AccessModes: []corev1.PersistentVolumeAccessMode{ diff --git a/operators/pkg/controller/elasticsearch/pvc/pvc_test.go b/operators/pkg/controller/elasticsearch/pvc/pvc_test.go index a071f5a7af..4200ecd000 100644 --- a/operators/pkg/controller/elasticsearch/pvc/pvc_test.go +++ b/operators/pkg/controller/elasticsearch/pvc/pvc_test.go @@ -10,6 +10,7 @@ import ( "github.com/elastic/cloud-on-k8s/operators/pkg/apis/elasticsearch/v1alpha1" "github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/label" + "github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/volume" "github.com/elastic/cloud-on-k8s/operators/pkg/utils/k8s" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" @@ -84,9 +85,27 @@ func withPVC(pod *corev1.Pod, volumeName string, claimName string) *corev1.Pod { } func TestFindOrphanedVolumeClaims(t *testing.T) { - pvc1 := newPVC("elasticsearch-sample-es-2l59jptdq6", "elasticsearch-sample-es-2l59jptdq6-elasticsearch-data", sampleLabels1, "1Gi", nil) - pvc2 := newPVC("elasticsearch-sample-es-6bw9qkw77k", "elasticsearch-sample-es-6bw9qkw77k-elasticsearch-data", sampleLabels1, "1Gi", nil) - pvc3 := newPVC("elasticsearch-sample-es-6qg4hmd9dj", "elasticsearch-sample-es-6qg4hmd9dj-elasticsearch-data", sampleLabels2, "1Gi", nil) + pvc1 := newPVC( + "elasticsearch-sample-es-2l59jptdq6", + "elasticsearch-sample-es-2l59jptdq6-"+volume.ElasticsearchDataVolumeName, + sampleLabels1, + "1Gi", + nil, + ) + pvc2 := newPVC( + "elasticsearch-sample-es-6bw9qkw77k", + "elasticsearch-sample-es-6bw9qkw77k-"+volume.ElasticsearchDataVolumeName, + sampleLabels1, + "1Gi", + nil, + ) + pvc3 := newPVC( + "elasticsearch-sample-es-6qg4hmd9dj", + "elasticsearch-sample-es-6qg4hmd9dj-"+volume.ElasticsearchDataVolumeName, + sampleLabels2, + "1Gi", + nil, + ) type args struct { initialObjects []runtime.Object es v1alpha1.Elasticsearch @@ -102,8 +121,11 @@ func TestFindOrphanedVolumeClaims(t *testing.T) { args: args{ initialObjects: []runtime.Object{ // create 1 Pod - withPVC(newPod("elasticsearch-sample-es-2l59jptdq6", sampleLabels1), - "elasticsearch-data", "elasticsearch-sample-es-2l59jptdq6-elasticsearch-data"), + withPVC( + newPod("elasticsearch-sample-es-2l59jptdq6", sampleLabels1), + volume.ElasticsearchDataVolumeName, + "elasticsearch-sample-es-2l59jptdq6-"+volume.ElasticsearchDataVolumeName, + ), // create 3 PVCs pvc1, pvc2, @@ -123,8 +145,11 @@ func TestFindOrphanedVolumeClaims(t *testing.T) { args: args{ initialObjects: []runtime.Object{ // create 1 Pod - withPVC(newPod("elasticsearch-sample-es-2l59jptdq6", sampleLabels1), - "elasticsearch-data", "elasticsearch-sample-es-2l59jptdq6-elasticsearch-data"), + withPVC( + newPod("elasticsearch-sample-es-2l59jptdq6", sampleLabels1), + volume.ElasticsearchDataVolumeName, + "elasticsearch-sample-es-2l59jptdq6-"+volume.ElasticsearchDataVolumeName, + ), // create 3 PVCs, but one of them is scheduled to be deleted pvc1, pvc2, @@ -173,8 +198,20 @@ func TestOrphanedPersistentVolumeClaims_FindOrphanedVolumeClaim(t *testing.T) { name: "Simple test with a standard storage class and 1Gi of storage", fields: fields{ []corev1.PersistentVolumeClaim{ - *newPVC("elasticsearch-sample-es-6bw9qkw77k", "elasticsearch-sample-es-6bw9qkw77k-elasticsearch-data", sampleLabels1, "1Gi", &standardStorageClassname), - *newPVC("elasticsearch-sample-es-6qg4hmd9dj", "elasticsearch-sample-es-6qg4hmd9dj-elasticsearch-data", sampleLabels1, "1Gi", &standardStorageClassname), + *newPVC( + "elasticsearch-sample-es-6bw9qkw77k", + "elasticsearch-sample-es-6bw9qkw77k-"+volume.ElasticsearchDataVolumeName, + sampleLabels1, + "1Gi", + &standardStorageClassname, + ), + *newPVC( + "elasticsearch-sample-es-6qg4hmd9dj", + "elasticsearch-sample-es-6qg4hmd9dj-"+volume.ElasticsearchDataVolumeName, + sampleLabels1, + "1Gi", + &standardStorageClassname, + ), }}, args: args{ expectedLabels: newPodLabel("elasticsearch-sample-es-2l59jptdq6", sampleLabels1), @@ -188,13 +225,31 @@ func TestOrphanedPersistentVolumeClaims_FindOrphanedVolumeClaim(t *testing.T) { }, }, }, - want: newPVC("elasticsearch-sample-es-6bw9qkw77k", "elasticsearch-sample-es-6bw9qkw77k-elasticsearch-data", sampleLabels1, "1Gi", &standardStorageClassname), + want: newPVC( + "elasticsearch-sample-es-6bw9qkw77k", + "elasticsearch-sample-es-6bw9qkw77k-"+volume.ElasticsearchDataVolumeName, + sampleLabels1, + "1Gi", + &standardStorageClassname, + ), }, { name: "Labels mismatch", fields: fields{ []corev1.PersistentVolumeClaim{ - *newPVC("elasticsearch-sample-es-6bw9qkw77k", "elasticsearch-sample-es-6bw9qkw77k-elasticsearch-data", sampleLabels2, "1Gi", &standardStorageClassname), - *newPVC("elasticsearch-sample-es-6qg4hmd9dj", "elasticsearch-sample-es-6qg4hmd9dj-elasticsearch-data", sampleLabels2, "1Gi", &standardStorageClassname), + *newPVC( + "elasticsearch-sample-es-6bw9qkw77k", + "elasticsearch-sample-es-6bw9qkw77k-"+volume.ElasticsearchDataVolumeName, + sampleLabels2, + "1Gi", + &standardStorageClassname, + ), + *newPVC( + "elasticsearch-sample-es-6qg4hmd9dj", + "elasticsearch-sample-es-6qg4hmd9dj-"+volume.ElasticsearchDataVolumeName, + sampleLabels2, + "1Gi", + &standardStorageClassname, + ), }}, args: args{ expectedLabels: newPodLabel("elasticsearch-sample-es-2l59jptdq6", sampleLabels1), @@ -213,8 +268,20 @@ func TestOrphanedPersistentVolumeClaims_FindOrphanedVolumeClaim(t *testing.T) { name: "Matching storage class", fields: fields{ []corev1.PersistentVolumeClaim{ - *newPVC("elasticsearch-sample-es-6bw9qkw77k", "elasticsearch-sample-es-6bw9qkw77k-elasticsearch-data", sampleLabels1, "1Gi", &fastStorageClassname), - *newPVC("elasticsearch-sample-es-6qg4hmd9dj", "elasticsearch-sample-es-6qg4hmd9dj-elasticsearch-data", sampleLabels1, "1Gi", &fastStorageClassname), + *newPVC( + "elasticsearch-sample-es-6bw9qkw77k", + "elasticsearch-sample-es-6bw9qkw77k-"+volume.ElasticsearchDataVolumeName, + sampleLabels1, + "1Gi", + &fastStorageClassname, + ), + *newPVC( + "elasticsearch-sample-es-6qg4hmd9dj", + "elasticsearch-sample-es-6qg4hmd9dj-"+volume.ElasticsearchDataVolumeName, + sampleLabels1, + "1Gi", + &fastStorageClassname, + ), }}, args: args{ expectedLabels: newPodLabel("elasticsearch-sample-es-2l59jptdq6", sampleLabels1), @@ -229,14 +296,32 @@ func TestOrphanedPersistentVolumeClaims_FindOrphanedVolumeClaim(t *testing.T) { }, }, }, - want: newPVC("elasticsearch-sample-es-6bw9qkw77k", "elasticsearch-sample-es-6bw9qkw77k-elasticsearch-data", sampleLabels1, "1Gi", &fastStorageClassname), + want: newPVC( + "elasticsearch-sample-es-6bw9qkw77k", + "elasticsearch-sample-es-6bw9qkw77k-"+volume.ElasticsearchDataVolumeName, + sampleLabels1, + "1Gi", + &fastStorageClassname, + ), }, { name: "Storage class mismatch", fields: fields{ []corev1.PersistentVolumeClaim{ - *newPVC("elasticsearch-sample-es-6bw9qkw77k", "elasticsearch-sample-es-6bw9qkw77k-elasticsearch-data", sampleLabels1, "1Gi", &standardStorageClassname), - *newPVC("elasticsearch-sample-es-6qg4hmd9dj", "elasticsearch-sample-es-6qg4hmd9dj-elasticsearch-data", sampleLabels1, "1Gi", &standardStorageClassname), + *newPVC( + "elasticsearch-sample-es-6bw9qkw77k", + "elasticsearch-sample-es-6bw9qkw77k-"+volume.ElasticsearchDataVolumeName, + sampleLabels1, + "1Gi", + &standardStorageClassname, + ), + *newPVC( + "elasticsearch-sample-es-6qg4hmd9dj", + "elasticsearch-sample-es-6qg4hmd9dj-"+volume.ElasticsearchDataVolumeName, + sampleLabels1, + "1Gi", + &standardStorageClassname, + ), }}, args: args{ expectedLabels: newPodLabel("elasticsearch-sample-es-2l59jptdq6", sampleLabels1), diff --git a/operators/pkg/controller/elasticsearch/volume/volume.go b/operators/pkg/controller/elasticsearch/volume/volume.go index 46c69ab31a..394bb799fa 100644 --- a/operators/pkg/controller/elasticsearch/volume/volume.go +++ b/operators/pkg/controller/elasticsearch/volume/volume.go @@ -33,6 +33,9 @@ const ( UnicastHostsFile = "unicast_hosts.txt" ProcessManagerEmptyDirMountPath = "/mnt/elastic-internal/process-manager" + + ElasticsearchDataVolumeName = "elasticsearch-data" + ElasticsearchLogsVolumeName = "elasticsearch-logs" ) var ( From 9f14563fe70123509e6ece03f0eab83bf84dfe20 Mon Sep 17 00:00:00 2001 From: Njal Karevoll Date: Mon, 10 Jun 2019 15:00:19 +0200 Subject: [PATCH 7/8] Improve AppendDefaultPVCs godoc --- operators/pkg/controller/common/defaults/pvc.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/operators/pkg/controller/common/defaults/pvc.go b/operators/pkg/controller/common/defaults/pvc.go index 670a5dabe7..400fca15e3 100644 --- a/operators/pkg/controller/common/defaults/pvc.go +++ b/operators/pkg/controller/common/defaults/pvc.go @@ -8,9 +8,9 @@ import v1 "k8s.io/api/core/v1" // AppendDefaultPVCs appends defaults PVCs to a set of existing ones. // -// The default not appended if: -// - a Volume with a the same .name is found in podSpec.Volumes, and that volume is not a PVC volume -// - a PVC with the same metadata.name is found in existing. +// The default PVC is not appended if: +// - a Volume with the same .Name is found in podSpec.Volumes, and that volume is not a PVC volume +// - a PVC with the same .Metadata.Name is found in existing. func AppendDefaultPVCs( existing []v1.PersistentVolumeClaim, podSpec v1.PodSpec, From 19f15173fb67f8a12fb9afa5d9c703c2710d667b Mon Sep 17 00:00:00 2001 From: Njal Karevoll Date: Mon, 10 Jun 2019 15:47:17 +0200 Subject: [PATCH 8/8] Refactor DefaultVolumeClaimsTemplates to DefaultVolumeClaimTemplates --- operators/pkg/controller/common/defaults/pvc.go | 1 - operators/pkg/controller/elasticsearch/pod/pod.go | 4 ++-- operators/pkg/controller/elasticsearch/version/common.go | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/operators/pkg/controller/common/defaults/pvc.go b/operators/pkg/controller/common/defaults/pvc.go index 400fca15e3..47c40db9f3 100644 --- a/operators/pkg/controller/common/defaults/pvc.go +++ b/operators/pkg/controller/common/defaults/pvc.go @@ -23,7 +23,6 @@ func AppendDefaultPVCs( if volume.PersistentVolumeClaim == nil { // this volume is not a PVC nonPVCvolumes[volume.Name] = struct{}{} - } } diff --git a/operators/pkg/controller/elasticsearch/pod/pod.go b/operators/pkg/controller/elasticsearch/pod/pod.go index 36e076ca67..b53b0798ec 100644 --- a/operators/pkg/controller/elasticsearch/pod/pod.go +++ b/operators/pkg/controller/elasticsearch/pod/pod.go @@ -33,8 +33,8 @@ var ( {Name: "process-manager", ContainerPort: processmanager.DefaultPort, Protocol: corev1.ProtocolTCP}, } - // DefaultVolumeClaimsTemplates is the default volume claim templates for Elasticsearch pods - DefaultVolumeClaimsTemplates = []corev1.PersistentVolumeClaim{ + // DefaultVolumeClaimTemplates is the default volume claim templates for Elasticsearch pods + DefaultVolumeClaimTemplates = []corev1.PersistentVolumeClaim{ { ObjectMeta: metav1.ObjectMeta{ Name: volume.ElasticsearchDataVolumeName, diff --git a/operators/pkg/controller/elasticsearch/version/common.go b/operators/pkg/controller/elasticsearch/version/common.go index 32d351cf95..64f06307d0 100644 --- a/operators/pkg/controller/elasticsearch/version/common.go +++ b/operators/pkg/controller/elasticsearch/version/common.go @@ -35,7 +35,7 @@ func NewExpectedPodSpecs( for _, node := range es.Spec.Nodes { // add default PVCs to the node spec node.VolumeClaimTemplates = defaults.AppendDefaultPVCs( - node.VolumeClaimTemplates, node.PodTemplate.Spec, pod.DefaultVolumeClaimsTemplates..., + node.VolumeClaimTemplates, node.PodTemplate.Spec, pod.DefaultVolumeClaimTemplates..., ) for i := int32(0); i < node.NodeCount; i++ {