diff --git a/CHANGELOG.md b/CHANGELOG.md index 13f9bb7..1369d85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,11 +6,13 @@ All notable changes to this project will be documented in this file. ### Added -- Add the role group as a node attribute ([#63]). - Allow the configuration of TLS for the HTTP and TRANSPORT ports with the operator ([#55]). +- Add the role group as a node attribute ([#63]). +- Allow adding entries to the OpenSearch keystore ([#76]). [#55]: https://github.com/stackabletech/opensearch-operator/pull/55 [#63]: https://github.com/stackabletech/opensearch-operator/pull/63 +[#76]: https://github.com/stackabletech/opensearch-operator/pull/76 ## [25.11.0] - 2025-11-07 diff --git a/deploy/helm/opensearch-operator/crds/crds.yaml b/deploy/helm/opensearch-operator/crds/crds.yaml index e29d34d..4f61101 100644 --- a/deploy/helm/opensearch-operator/crds/crds.yaml +++ b/deploy/helm/opensearch-operator/crds/crds.yaml @@ -30,11 +30,46 @@ spec: properties: clusterConfig: default: + keystore: [] tls: internalSecretClass: tls serverSecretClass: tls description: Configuration that applies to all roles and role groups properties: + keystore: + default: [] + description: Entries to add to the OpenSearch keystore. + items: + properties: + key: + description: Key in the OpenSearch keystore + minLength: 1 + pattern: ^[A-Za-z0-9_\-.]+$ + type: string + secretKeyRef: + description: Reference to the Secret containing the value which will be stored in the OpenSearch keystore + properties: + key: + description: Key in the Secret that contains the value + maxLength: 253 + minLength: 1 + pattern: ^[-._a-zA-Z0-9]+$ + type: string + name: + description: Name of the Secret + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - key + - name + type: object + required: + - key + - secretKeyRef + type: object + type: array tls: default: internalSecretClass: tls diff --git a/docs/modules/opensearch/pages/usage-guide/keystore.adoc b/docs/modules/opensearch/pages/usage-guide/keystore.adoc new file mode 100644 index 0000000..88e13ed --- /dev/null +++ b/docs/modules/opensearch/pages/usage-guide/keystore.adoc @@ -0,0 +1,37 @@ += Add entries to the OpenSearch Keystore +:description: Add entries to the OpenSearch Keystore + +The OpenSearch keystore provides secure storage for sensitive configuration settings such as credentials and API keys. +You can populate the keystore by referencing Secrets within your OpenSearch configuration. + +[source,yaml] +---- +--- +apiVersion: opensearch.stackable.tech/v1alpha1 +kind: OpenSearchCluster +metadata: + name: opensearch +spec: + clusterConfig: + keystore: + - key: s3.client.default.access_key # <1> + secretKeyRef: + name: s3-credentials # <2> + key: accessKey # <3> + - key: s3.client.default.secret_key + secretKeyRef: + name: s3-credentials + key: secretKey +... +--- +apiVersion: v1 +kind: Secret +metadata: + name: s3-credentials +stringData: + accessKey: my-access-key + secretKey: my-secret-key +---- +<1> The key in the OpenSearch keystore which corresponds to a setting in OpenSearch (e.g. `s3.client.default.access_key`). +<2> The name of the Secret containing the value +<3> The key within that Secret diff --git a/docs/modules/opensearch/partials/nav.adoc b/docs/modules/opensearch/partials/nav.adoc index c279825..9183f5b 100644 --- a/docs/modules/opensearch/partials/nav.adoc +++ b/docs/modules/opensearch/partials/nav.adoc @@ -10,6 +10,7 @@ ** xref:opensearch:usage-guide/logging.adoc[] ** xref:opensearch:usage-guide/opensearch-dashboards.adoc[] ** xref:opensearch:usage-guide/scaling.adoc[] +** xref:opensearch:usage-guide/keystore.adoc[] ** xref:opensearch:usage-guide/security.adoc[] ** xref:opensearch:usage-guide/operations/index.adoc[] *** xref:opensearch:usage-guide/operations/cluster-operations.adoc[] diff --git a/rust/operator-binary/src/controller.rs b/rust/operator-binary/src/controller.rs index 5822917..958fb0b 100644 --- a/rust/operator-binary/src/controller.rs +++ b/rust/operator-binary/src/controller.rs @@ -171,6 +171,7 @@ pub struct ValidatedCluster { pub role_config: GenericRoleConfig, pub role_group_configs: BTreeMap, pub tls_config: v1alpha1::OpenSearchTls, + pub keystores: Vec, } impl ValidatedCluster { @@ -184,6 +185,7 @@ impl ValidatedCluster { role_config: GenericRoleConfig, role_group_configs: BTreeMap, tls_config: v1alpha1::OpenSearchTls, + keystores: Vec, ) -> Self { let uid = uid.into(); ValidatedCluster { @@ -201,6 +203,7 @@ impl ValidatedCluster { role_config, role_group_configs, tls_config, + keystores, } } @@ -507,6 +510,7 @@ mod tests { ] .into(), v1alpha1::OpenSearchTls::default(), + vec![], ) } diff --git a/rust/operator-binary/src/controller/build.rs b/rust/operator-binary/src/controller/build.rs index bc14fb0..b0f84c5 100644 --- a/rust/operator-binary/src/controller/build.rs +++ b/rust/operator-binary/src/controller/build.rs @@ -199,6 +199,7 @@ mod tests { ] .into(), v1alpha1::OpenSearchTls::default(), + vec![], ) } diff --git a/rust/operator-binary/src/controller/build/node_config.rs b/rust/operator-binary/src/controller/build/node_config.rs index 60dd738..b58dcd6 100644 --- a/rust/operator-binary/src/controller/build/node_config.rs +++ b/rust/operator-binary/src/controller/build/node_config.rs @@ -502,6 +502,7 @@ mod tests { )] .into(), v1alpha1::OpenSearchTls::default(), + vec![], ); NodeConfig::new( diff --git a/rust/operator-binary/src/controller/build/role_builder.rs b/rust/operator-binary/src/controller/build/role_builder.rs index a78d62a..c2b8376 100644 --- a/rust/operator-binary/src/controller/build/role_builder.rs +++ b/rust/operator-binary/src/controller/build/role_builder.rs @@ -315,6 +315,7 @@ mod tests { )] .into(), v1alpha1::OpenSearchTls::default(), + vec![], ); RoleBuilder::new(cluster, context_names) diff --git a/rust/operator-binary/src/controller/build/role_group_builder.rs b/rust/operator-binary/src/controller/build/role_group_builder.rs index e52480e..4bb8e1a 100644 --- a/rust/operator-binary/src/controller/build/role_group_builder.rs +++ b/rust/operator-binary/src/controller/build/role_group_builder.rs @@ -14,12 +14,14 @@ use stackable_operator::{ apps::v1::{StatefulSet, StatefulSetSpec}, core::v1::{ Affinity, ConfigMap, ConfigMapVolumeSource, Container, ContainerPort, - EmptyDirVolumeSource, PersistentVolumeClaim, PodSecurityContext, PodSpec, - PodTemplateSpec, Probe, Service, ServicePort, ServiceSpec, TCPSocketAction, Volume, - VolumeMount, + EmptyDirVolumeSource, KeyToPath, PersistentVolumeClaim, PodSecurityContext, + PodSpec, PodTemplateSpec, Probe, SecretVolumeSource, Service, ServicePort, + ServiceSpec, TCPSocketAction, Volume, VolumeMount, }, }, - apimachinery::pkg::{apis::meta::v1::LabelSelector, util::intstr::IntOrString}, + apimachinery::pkg::{ + api::resource::Quantity, apis::meta::v1::LabelSelector, util::intstr::IntOrString, + }, }, kvp::{Annotation, Annotations, Label, Labels}, product_logging::framework::{ @@ -87,6 +89,12 @@ constant!(TLS_INTERNAL_VOLUME_NAME: VolumeName = "tls-internal"); constant!(LOG_VOLUME_NAME: VolumeName = "log"); const LOG_VOLUME_DIR: &str = "/stackable/log"; +const OPENSEARCH_KEYSTORE_FILE_NAME: &str = "opensearch.keystore"; +const OPENSEARCH_INITIALIZED_KEYSTORE_DIRECTORY_NAME: &str = "initialized-keystore"; +const OPENSEARCH_KEYSTORE_SECRETS_DIRECTORY: &str = "keystore-secrets"; +constant!(OPENSEARCH_KEYSTORE_VOLUME_NAME: VolumeName = "keystore"); +const OPENSEARCH_KEYSTORE_VOLUME_SIZE: &str = "1Mi"; + /// Builder for role-group resources pub struct RoleGroupBuilder<'a> { service_account_name: ServiceAccountName, @@ -261,6 +269,11 @@ impl<'a> RoleGroupBuilder<'a> { ) }); + let mut init_containers = vec![]; + if let Some(keystore_init_container) = self.build_maybe_keystore_init_container() { + init_containers.push(keystore_init_container); + } + let log_config_volume_config_map = if let ValidatedContainerLogConfigChoice::Custom(config_map_name) = &self.role_group_config.config.logging.opensearch_container @@ -320,6 +333,34 @@ impl<'a> RoleGroupBuilder<'a> { )) }; + if !self.cluster.keystores.is_empty() { + volumes.push(Volume { + name: OPENSEARCH_KEYSTORE_VOLUME_NAME.to_string(), + empty_dir: Some(EmptyDirVolumeSource { + size_limit: Some(Quantity(OPENSEARCH_KEYSTORE_VOLUME_SIZE.to_owned())), + ..EmptyDirVolumeSource::default() + }), + ..Volume::default() + }) + } + + for (index, keystore) in self.cluster.keystores.iter().enumerate() { + volumes.push(Volume { + name: format!("keystore-{index}"), + secret: Some(SecretVolumeSource { + default_mode: Some(0o660), + secret_name: Some(keystore.secret_key_ref.name.to_string()), + items: Some(vec![KeyToPath { + key: keystore.secret_key_ref.key.to_string(), + path: keystore.secret_key_ref.key.to_string(), + ..KeyToPath::default() + }]), + ..SecretVolumeSource::default() + }), + ..Volume::default() + }); + } + // The PodBuilder is not used because it re-validates the values which are already // validated. For instance, it would be necessary to convert the // termination_grace_period_seconds into a Duration, the PodBuilder parses the Duration, @@ -341,6 +382,7 @@ impl<'a> RoleGroupBuilder<'a> { .into_iter() .flatten() .collect(), + init_containers: Some(init_containers), node_selector: self .role_group_config .config @@ -400,6 +442,58 @@ impl<'a> RoleGroupBuilder<'a> { .expect("should be a valid label") } + /// Builds the container for the [`PodTemplateSpec`] + fn build_maybe_keystore_init_container(&self) -> Option { + if self.cluster.keystores.is_empty() { + return None; + } + let opensearch_home = self.node_config.opensearch_home(); + let mut volume_mounts = vec![VolumeMount { + mount_path: format!( + "{opensearch_home}/{OPENSEARCH_INITIALIZED_KEYSTORE_DIRECTORY_NAME}" + ), + name: OPENSEARCH_KEYSTORE_VOLUME_NAME.to_string(), + ..VolumeMount::default() + }]; + + for (index, keystore) in self.cluster.keystores.iter().enumerate() { + volume_mounts.push(VolumeMount { + mount_path: format!( + "{opensearch_home}/{OPENSEARCH_KEYSTORE_SECRETS_DIRECTORY}/{}", + keystore.key + ), + name: format!("keystore-{index}"), + read_only: Some(true), + sub_path: Some(keystore.secret_key_ref.key.to_string()), + ..VolumeMount::default() + }); + } + + Some( + new_container_builder(&v1alpha1::Container::InitKeystore.to_container_name()) + .image_from_product_image(&self.cluster.image) + .command(vec![ + "/bin/bash".to_string(), + "-x".to_string(), + "-euo".to_string(), + "pipefail".to_string(), + "-c".to_string(), + ]) + .args(vec![format!( + "bin/opensearch-keystore create +for i in keystore-secrets/*; do + key=$(basename $i) + bin/opensearch-keystore add-file \"$key\" \"$i\" +done +cp --archive config/opensearch.keystore {OPENSEARCH_INITIALIZED_KEYSTORE_DIRECTORY_NAME}", + )]) + .add_volume_mounts(volume_mounts) + .expect("The mount paths are statically defined and there should be no duplicates.") + .resources(self.role_group_config.config.resources.clone().into()) + .build(), + ) + } + /// Builds the container for the [`PodTemplateSpec`] fn build_opensearch_container(&self) -> Container { // Probe values taken from the official Helm chart @@ -475,6 +569,16 @@ impl<'a> RoleGroupBuilder<'a> { }) } + if !self.cluster.keystores.is_empty() { + volume_mounts.push(VolumeMount { + mount_path: format!("{opensearch_path_conf}/{OPENSEARCH_KEYSTORE_FILE_NAME}"), + name: OPENSEARCH_KEYSTORE_VOLUME_NAME.to_string(), + sub_path: Some(OPENSEARCH_KEYSTORE_FILE_NAME.to_owned()), + read_only: Some(true), + ..VolumeMount::default() + }) + } + new_container_builder(&v1alpha1::Container::OpenSearch.to_container_name()) .image_from_product_image(&self.cluster.image) .command(vec![ @@ -725,15 +829,15 @@ mod tests { ContextNames, OpenSearchRoleGroupConfig, ValidatedCluster, ValidatedContainerLogConfigChoice, ValidatedLogging, ValidatedOpenSearchConfig, }, - crd::{NodeRoles, v1alpha1}, + crd::{NodeRoles, OpenSearchKeystoreKey, v1alpha1}, framework::{ builder::pod::container::EnvVarSet, product_logging::framework::VectorContainerLogConfig, role_utils::GenericProductSpecificCommonConfig, types::{ kubernetes::{ - ConfigMapName, ListenerClassName, NamespaceName, ServiceAccountName, - ServiceName, + ConfigMapName, ListenerClassName, NamespaceName, SecretKey, SecretName, + ServiceAccountName, ServiceName, }, operator::{ ClusterName, ControllerName, OperatorName, ProductName, ProductVersion, @@ -820,6 +924,13 @@ mod tests { )] .into(), v1alpha1::OpenSearchTls::default(), + vec![v1alpha1::OpenSearchKeystore { + key: OpenSearchKeystoreKey::from_str_unsafe("Keystore1"), + secret_key_ref: v1alpha1::SecretKeyRef { + name: SecretName::from_str_unsafe("my-keystore-secret"), + key: SecretKey::from_str_unsafe("my-keystore-file"), + }, + }], ) } @@ -1102,6 +1213,12 @@ mod tests { { "mountPath": "/stackable/opensearch/config/tls/server", "name": "tls-server", + }, + { + "mountPath": "/stackable/opensearch/config/opensearch.keystore", + "name": "keystore", + "readOnly": true, + "subPath": "opensearch.keystore", } ] }, @@ -1203,6 +1320,43 @@ mod tests { ], }, ], + "initContainers": [ + { + "args": [ + concat!( + "bin/opensearch-keystore create\n", + "for i in keystore-secrets/*; do\n", + " key=$(basename $i)\n", + " bin/opensearch-keystore add-file \"$key\" \"$i\"\n", + "done\n", + "cp --archive config/opensearch.keystore initialized-keystore" + ), + ], + "command": [ + "/bin/bash", + "-x", + "-euo", + "pipefail", + "-c" + ], + "image": "oci.stackable.tech/sdp/opensearch:3.1.0-stackable0.0.0-dev", + "imagePullPolicy": "Always", + "name": "init-keystore", + "resources": {}, + "volumeMounts": [ + { + "mountPath": "/stackable/opensearch/initialized-keystore", + "name": "keystore", + }, + { + "mountPath": "/stackable/opensearch/keystore-secrets/Keystore1", + "name": "keystore-0", + "readOnly": true, + "subPath": "my-keystore-file" + } + ] + } + ], "securityContext": { "fsGroup": 1000 }, @@ -1280,6 +1434,25 @@ mod tests { } }, "name": "tls-server" + }, + { + "emptyDir": { + "sizeLimit": "1Mi" + }, + "name": "keystore" + }, + { + "name": "keystore-0", + "secret": { + "defaultMode": 0o660, + "items": [ + { + "key": "my-keystore-file", + "path": "my-keystore-file" + } + ], + "secretName": "my-keystore-secret" + } } ] } diff --git a/rust/operator-binary/src/controller/validate.rs b/rust/operator-binary/src/controller/validate.rs index 2433e15..e492590 100644 --- a/rust/operator-binary/src/controller/validate.rs +++ b/rust/operator-binary/src/controller/validate.rs @@ -154,6 +154,7 @@ pub fn validate( cluster.spec.nodes.role_config.clone(), role_group_configs, cluster.spec.cluster_config.tls.clone(), + cluster.spec.cluster_config.keystore.clone(), )) } @@ -287,7 +288,7 @@ mod tests { use crate::{ built_info, controller::{ContextNames, ValidatedCluster, ValidatedLogging, ValidatedOpenSearchConfig}, - crd::{NodeRoles, v1alpha1}, + crd::{NodeRoles, OpenSearchKeystoreKey, v1alpha1}, framework::{ builder::pod::container::{EnvVarName, EnvVarSet}, product_logging::framework::{ @@ -295,7 +296,10 @@ mod tests { }, role_utils::{GenericProductSpecificCommonConfig, RoleGroupConfig}, types::{ - kubernetes::{ConfigMapName, ListenerClassName, NamespaceName, SecretClassName}, + kubernetes::{ + ConfigMapName, ListenerClassName, NamespaceName, SecretClassName, SecretKey, + SecretName, + }, operator::{ ClusterName, ControllerName, OperatorName, ProductName, ProductVersion, RoleGroupName, @@ -515,6 +519,13 @@ mod tests { server_secret_class: Some(SecretClassName::from_str_unsafe("tls")), internal_secret_class: SecretClassName::from_str_unsafe("tls") }, + vec![v1alpha1::OpenSearchKeystore { + key: OpenSearchKeystoreKey::from_str_unsafe("Keystore1"), + secret_key_ref: v1alpha1::SecretKeyRef { + name: SecretName::from_str_unsafe("my-keystore-secret"), + key: SecretKey::from_str_unsafe("my-keystore-file") + } + }] )), result.ok() ); @@ -693,6 +704,13 @@ mod tests { .expect("should be a valid ProductImage structure"), cluster_config: v1alpha1::OpenSearchClusterConfig { tls: v1alpha1::OpenSearchTls::default(), + keystore: vec![v1alpha1::OpenSearchKeystore { + key: OpenSearchKeystoreKey::from_str_unsafe("Keystore1"), + secret_key_ref: v1alpha1::SecretKeyRef { + name: SecretName::from_str_unsafe("my-keystore-secret"), + key: SecretKey::from_str_unsafe("my-keystore-file"), + }, + }], vector_aggregator_config_map_name: Some(ConfigMapName::from_str_unsafe( "vector-aggregator", )), diff --git a/rust/operator-binary/src/crd/mod.rs b/rust/operator-binary/src/crd/mod.rs index 89bc7de..f909f24 100644 --- a/rust/operator-binary/src/crd/mod.rs +++ b/rust/operator-binary/src/crd/mod.rs @@ -27,12 +27,15 @@ use stackable_operator::{ use strum::{Display, EnumIter}; use crate::{ - constant, + attributed_string_type, constant, framework::{ NameIsValidLabelValue, role_utils::GenericProductSpecificCommonConfig, types::{ - kubernetes::{ConfigMapName, ContainerName, ListenerClassName, SecretClassName}, + kubernetes::{ + ConfigMapName, ContainerName, ListenerClassName, SecretClassName, SecretKey, + SecretName, + }, operator::{ClusterName, ProductName, RoleName}, }, }, @@ -85,6 +88,10 @@ pub mod versioned { #[derive(Clone, Debug, Default, Deserialize, Eq, JsonSchema, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] pub struct OpenSearchClusterConfig { + /// Entries to add to the OpenSearch keystore. + #[serde(default)] + pub keystore: Vec, + /// TLS configuration options for the server (REST API) and internal communication (transport). #[serde(default)] pub tls: OpenSearchTls, @@ -97,6 +104,24 @@ pub mod versioned { pub vector_aggregator_config_map_name: Option, } + #[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)] + #[serde(rename_all = "camelCase")] + pub struct OpenSearchKeystore { + /// Key in the OpenSearch keystore + pub key: OpenSearchKeystoreKey, + + /// Reference to the Secret containing the value which will be stored in the OpenSearch keystore + pub secret_key_ref: SecretKeyRef, + } + + #[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)] + pub struct SecretKeyRef { + /// Name of the Secret + pub name: SecretName, + /// Key in the Secret that contains the value + pub key: SecretKey, + } + #[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] pub struct OpenSearchTls { @@ -228,6 +253,9 @@ pub mod versioned { #[serde(rename = "vector")] Vector, + + #[serde(rename = "init-keystore")] + InitKeystore, } #[derive(Clone, Debug, Default, JsonSchema, PartialEq, Fragment)] @@ -380,11 +408,21 @@ impl v1alpha1::Container { ContainerName::from_str(match self { v1alpha1::Container::OpenSearch => "opensearch", v1alpha1::Container::Vector => "vector", + v1alpha1::Container::InitKeystore => "init-keystore", }) .expect("should be a valid container name") } } +// See https://github.com/opensearch-project/OpenSearch/blob/8ff7c6ee924a49f0f59f80a6e1c73073c8904214/server/src/main/java/org/opensearch/common/settings/KeyStoreWrapper.java#L125 +attributed_string_type! { + OpenSearchKeystoreKey, + "Key in an OpenSearch keystore", + "s3.client.default.access_key", + (min_length = 1), + (regex = "[A-Za-z0-9_\\-.]+") +} + #[cfg(test)] mod tests { use strum::IntoEnumIterator; diff --git a/tests/templates/kuttl/backup-restore/10-install-s3-credentials-secret.yaml b/tests/templates/kuttl/backup-restore/10-install-s3-credentials-secret.yaml index ee58ffb..9b71b36 100644 --- a/tests/templates/kuttl/backup-restore/10-install-s3-credentials-secret.yaml +++ b/tests/templates/kuttl/backup-restore/10-install-s3-credentials-secret.yaml @@ -4,5 +4,5 @@ kind: Secret metadata: name: s3-credentials stringData: - s3.client.default.access_key: openSearchAccessKey - s3.client.default.secret_key: openSearchSecretKey + ACCESS_KEY: openSearchAccessKey + SECRET_KEY: openSearchSecretKey diff --git a/tests/templates/kuttl/backup-restore/11_minio-values.yaml b/tests/templates/kuttl/backup-restore/11_minio-values.yaml index da257f2..1f361bc 100644 --- a/tests/templates/kuttl/backup-restore/11_minio-values.yaml +++ b/tests/templates/kuttl/backup-restore/11_minio-values.yaml @@ -36,8 +36,8 @@ provisioning: extraCommands: - >- mc admin user svcacct add - --access-key "$(cat /tmp/s3-credentials/s3.client.default.access_key)" - --secret-key "$(cat /tmp/s3-credentials/s3.client.default.secret_key)" + --access-key "$(cat /tmp/s3-credentials/ACCESS_KEY)" + --secret-key "$(cat /tmp/s3-credentials/SECRET_KEY)" provisioning integrationtest extraVolumeMounts: - name: s3-credentials diff --git a/tests/templates/kuttl/backup-restore/21-install-opensearch-1.yaml.j2 b/tests/templates/kuttl/backup-restore/21-install-opensearch-1.yaml.j2 index 0535e0c..52b8e4b 100644 --- a/tests/templates/kuttl/backup-restore/21-install-opensearch-1.yaml.j2 +++ b/tests/templates/kuttl/backup-restore/21-install-opensearch-1.yaml.j2 @@ -10,8 +10,17 @@ spec: {% endif %} productVersion: "{{ test_scenario['values']['opensearch'].split(',')[0] }}" pullPolicy: IfNotPresent -{% if lookup('env', 'VECTOR_AGGREGATOR') %} clusterConfig: + keystore: + - key: s3.client.default.access_key + secretKeyRef: + name: s3-credentials + key: ACCESS_KEY + - key: s3.client.default.secret_key + secretKeyRef: + name: s3-credentials + key: SECRET_KEY +{% if lookup('env', 'VECTOR_AGGREGATOR') %} vectorAggregatorConfigMapName: vector-aggregator-discovery {% endif %} nodes: @@ -43,34 +52,6 @@ spec: podOverrides: spec: initContainers: - - name: init-keystore -{% if test_scenario['values']['opensearch'].find(",") > 0 %} - image: "{{ test_scenario['values']['opensearch'].split(',')[1] }}" -{% else %} - image: oci.stackable.tech/sdp/opensearch:{{ test_scenario['values']['opensearch'].split(',')[0] }}-stackable{{ test_scenario['values']['release'] }} -{% endif %} - command: - - /bin/bash - - -euxo - - pipefail - - -c - args: - - | - bin/opensearch-keystore create - - for i in keystore-secrets/*; do - key=$(basename $i) - bin/opensearch-keystore add-file "$key" "$i" - done - - cp --archive config/opensearch.keystore initialized-keystore - volumeMounts: - - name: keystore - mountPath: /stackable/opensearch/initialized-keystore - readOnly: false - - name: keystore-secrets - mountPath: /stackable/opensearch/keystore-secrets - readOnly: true - name: init-system-keystore {% if test_scenario['values']['opensearch'].find(",") > 0 %} image: "{{ test_scenario['values']['opensearch'].split(',')[1] }}" @@ -132,18 +113,7 @@ spec: - name: tls-concatenated mountPath: /stackable/opensearch/config/tls/concatenated readOnly: true - - name: keystore - mountPath: /stackable/opensearch/config/opensearch.keystore - subPath: opensearch.keystore - readOnly: true volumes: - - name: keystore - emptyDir: - sizeLimit: 1Mi - - name: keystore-secrets - secret: - secretName: s3-credentials - defaultMode: 0o660 - name: s3-ca-crt secret: secretName: minio-ca-crt diff --git a/tests/templates/kuttl/backup-restore/31-backup-security-indices.yaml.j2 b/tests/templates/kuttl/backup-restore/31-backup-security-indices.yaml.j2 index 645d701..f46c65b 100644 --- a/tests/templates/kuttl/backup-restore/31-backup-security-indices.yaml.j2 +++ b/tests/templates/kuttl/backup-restore/31-backup-security-indices.yaml.j2 @@ -53,12 +53,12 @@ spec: valueFrom: secretKeyRef: name: s3-credentials - key: s3.client.default.access_key + key: ACCESS_KEY - name: S3_SECRET_KEY valueFrom: secretKeyRef: name: s3-credentials - key: s3.client.default.secret_key + key: SECRET_KEY volumeMounts: - name: scripts mountPath: /root/scripts diff --git a/tests/templates/kuttl/backup-restore/51-install-opensearch-2.yaml.j2 b/tests/templates/kuttl/backup-restore/51-install-opensearch-2.yaml.j2 index a2b4ee9..76dec7d 100644 --- a/tests/templates/kuttl/backup-restore/51-install-opensearch-2.yaml.j2 +++ b/tests/templates/kuttl/backup-restore/51-install-opensearch-2.yaml.j2 @@ -10,8 +10,17 @@ spec: {% endif %} productVersion: "{{ test_scenario['values']['opensearch'].split(',')[0] }}" pullPolicy: IfNotPresent -{% if lookup('env', 'VECTOR_AGGREGATOR') %} clusterConfig: + keystore: + - key: s3.client.default.access_key + secretKeyRef: + name: s3-credentials + key: ACCESS_KEY + - key: s3.client.default.secret_key + secretKeyRef: + name: s3-credentials + key: SECRET_KEY +{% if lookup('env', 'VECTOR_AGGREGATOR') %} vectorAggregatorConfigMapName: vector-aggregator-discovery {% endif %} nodes: @@ -43,34 +52,6 @@ spec: podOverrides: spec: initContainers: - - name: init-keystore -{% if test_scenario['values']['opensearch'].find(",") > 0 %} - image: "{{ test_scenario['values']['opensearch'].split(',')[1] }}" -{% else %} - image: oci.stackable.tech/sdp/opensearch:{{ test_scenario['values']['opensearch'].split(',')[0] }}-stackable{{ test_scenario['values']['release'] }} -{% endif %} - command: - - /bin/bash - - -euxo - - pipefail - - -c - args: - - | - bin/opensearch-keystore create - - for i in keystore-secrets/*; do - key=$(basename $i) - bin/opensearch-keystore add-file "$key" "$i" - done - - cp --archive config/opensearch.keystore initialized-keystore - volumeMounts: - - name: keystore - mountPath: /stackable/opensearch/initialized-keystore - readOnly: false - - name: keystore-secrets - mountPath: /stackable/opensearch/keystore-secrets - readOnly: true - name: init-system-keystore {% if test_scenario['values']['opensearch'].find(",") > 0 %} image: "{{ test_scenario['values']['opensearch'].split(',')[1] }}" @@ -132,18 +113,7 @@ spec: - name: tls-concatenated mountPath: /stackable/opensearch/config/tls/concatenated readOnly: true - - name: keystore - mountPath: /stackable/opensearch/config/opensearch.keystore - subPath: opensearch.keystore - readOnly: true volumes: - - name: keystore - emptyDir: - sizeLimit: 1Mi - - name: keystore-secrets - secret: - secretName: s3-credentials - defaultMode: 0o660 - name: s3-ca-crt secret: secretName: minio-ca-crt diff --git a/tests/templates/kuttl/backup-restore/60-restore-security-indices.yaml.j2 b/tests/templates/kuttl/backup-restore/60-restore-security-indices.yaml.j2 index 2ccaca8..e3100bb 100644 --- a/tests/templates/kuttl/backup-restore/60-restore-security-indices.yaml.j2 +++ b/tests/templates/kuttl/backup-restore/60-restore-security-indices.yaml.j2 @@ -16,12 +16,12 @@ spec: valueFrom: secretKeyRef: name: s3-credentials - key: s3.client.default.access_key + key: ACCESS_KEY - name: S3_SECRET_KEY valueFrom: secretKeyRef: name: s3-credentials - key: s3.client.default.secret_key + key: SECRET_KEY volumeMounts: - name: scripts mountPath: /root/scripts