Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ All notable changes to this project will be documented in this file.
### Added

- Add the role group as a node attribute ([#63]).
- Allow adding entries to the OpenSearch keystore ([#76]).

[#63]: https://github.com/stackabletech/opensearch-operator/pull/63
[#76]: https://github.com/stackabletech/opensearch-operator/pull/76

## [25.11.0] - 2025-11-07

Expand Down
33 changes: 32 additions & 1 deletion deploy/helm/opensearch-operator/crds/crds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,40 @@ spec:
generates in the [operator documentation](https://docs.stackable.tech/home/nightly/opensearch/).
properties:
clusterConfig:
default: {}
default:
keystore: []
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
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
type: string
name:
description: Name of the Secret
maxLength: 253
minLength: 1
type: string
required:
- key
- name
type: object
required:
- key
- secretKeyRef
type: object
type: array
vectorAggregatorConfigMapName:
description: |-
Name of the Vector aggregator [discovery ConfigMap](https://docs.stackable.tech/home/nightly/concepts/service_discovery).
Expand Down
40 changes: 40 additions & 0 deletions docs/modules/opensearch/pages/usage-guide/keystore.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
= 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 from in 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
nodes:
roleGroups:
default:
replicas: 1
---
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
1 change: 1 addition & 0 deletions docs/modules/opensearch/partials/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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/operations/index.adoc[]
*** xref:opensearch:usage-guide/operations/cluster-operations.adoc[]
*** xref:opensearch:usage-guide/operations/pod-placement.adoc[]
Expand Down
20 changes: 17 additions & 3 deletions rust/operator-binary/src/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use validate::validate;
use crate::{
crd::{
NodeRoles,
v1alpha1::{self},
v1alpha1::{self, OpenSearchKeystore},
},
framework::{
ClusterName, ControllerName, HasName, HasUid, ListenerClassName, NameIsValidLabelValue,
Expand Down Expand Up @@ -166,9 +166,11 @@ pub struct ValidatedCluster {
pub uid: Uid,
pub role_config: GenericRoleConfig,
pub role_group_configs: BTreeMap<RoleGroupName, OpenSearchRoleGroupConfig>,
pub keystores: Vec<OpenSearchKeystore>,
}

impl ValidatedCluster {
#[allow(clippy::too_many_arguments)]
pub fn new(
image: ResolvedProductImage,
product_version: ProductVersion,
Expand All @@ -177,6 +179,7 @@ impl ValidatedCluster {
uid: impl Into<Uid>,
role_config: GenericRoleConfig,
role_group_configs: BTreeMap<RoleGroupName, OpenSearchRoleGroupConfig>,
keystores: Vec<OpenSearchKeystore>,
) -> Self {
let uid = uid.into();
ValidatedCluster {
Expand All @@ -193,6 +196,7 @@ impl ValidatedCluster {
uid,
role_config,
role_group_configs,
keystores,
}
}

Expand Down Expand Up @@ -378,10 +382,13 @@ mod tests {
use super::{Context, OpenSearchRoleGroupConfig, ValidatedCluster, ValidatedLogging};
use crate::{
controller::{OpenSearchNodeResources, ValidatedOpenSearchConfig},
crd::{NodeRoles, v1alpha1},
crd::{
NodeRoles,
v1alpha1::{self, OpenSearchKeystore, SecretKeyRef},
},
framework::{
ClusterName, ListenerClassName, NamespaceName, OperatorName, ProductVersion,
RoleGroupName, builder::pod::container::EnvVarSet,
RoleGroupName, SecretKey, SecretName, builder::pod::container::EnvVarSet,
product_logging::framework::ValidatedContainerLogConfigChoice,
role_utils::GenericProductSpecificCommonConfig,
},
Expand Down Expand Up @@ -494,6 +501,13 @@ mod tests {
),
]
.into(),
vec![OpenSearchKeystore {
key: "Keystore1".to_string(),
secret_key_ref: SecretKeyRef {
name: SecretName::from_str_unsafe("my-keystore-secret"),
key: SecretKey::from_str_unsafe("my-keystore-file"),
},
}],
)
}

Expand Down
16 changes: 13 additions & 3 deletions rust/operator-binary/src/controller/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,14 @@ mod tests {
ContextNames, OpenSearchNodeResources, OpenSearchRoleGroupConfig, ValidatedCluster,
ValidatedContainerLogConfigChoice, ValidatedLogging, ValidatedOpenSearchConfig,
},
crd::{NodeRoles, v1alpha1},
crd::{
NodeRoles,
v1alpha1::{self, OpenSearchKeystore, SecretKeyRef},
},
framework::{
ClusterName, ControllerName, ListenerClassName, NamespaceName, OperatorName,
ProductName, ProductVersion, RoleGroupName, builder::pod::container::EnvVarSet,
role_utils::GenericProductSpecificCommonConfig,
ProductName, ProductVersion, RoleGroupName, SecretKey, SecretName,
builder::pod::container::EnvVarSet, role_utils::GenericProductSpecificCommonConfig,
},
};

Expand Down Expand Up @@ -191,6 +194,13 @@ mod tests {
),
]
.into(),
vec![OpenSearchKeystore {
key: "Keystore1".to_string(),
secret_key_ref: SecretKeyRef {
name: SecretName::from_str_unsafe("my-keystore-secret"),
key: SecretKey::from_str_unsafe("my-keystore-file"),
},
}],
)
}

Expand Down
20 changes: 20 additions & 0 deletions rust/operator-binary/src/controller/build/node_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ pub const CONFIG_OPTION_PLUGINS_SECURITY_NODES_DN: &str = "plugins.security.node
pub const CONFIG_OPTION_PLUGINS_SECURITY_SSL_HTTP_ENABLED: &str =
"plugins.security.ssl.http.enabled";

const DEFAULT_OPENSEARCH_HOME: &str = "/stackable/opensearch";

/// Configuration of an OpenSearch node based on the cluster and role-group configuration
pub struct NodeConfig {
cluster: ValidatedCluster,
Expand Down Expand Up @@ -272,6 +274,23 @@ impl NodeConfig {
String::new()
}
}

/// Return content of the `OPENSEARCH_HOME` environment variable from envOverrides or default to `DEFAULT_OPENSEARCH_HOME`
pub fn opensearch_home(&self) -> String {
self.environment_variables()
.get(&EnvVarName::from_str_unsafe("OPENSEARCH_HOME"))
.and_then(|env_var| env_var.value.clone())
.unwrap_or(DEFAULT_OPENSEARCH_HOME.to_owned())
}

/// Return content of the `OPENSEARCH_PATH_CONF` environment variable from envOverrides or default to `OPENSEARCH_HOME/config`
pub fn opensearch_path_conf(&self) -> String {
let opensearch_home = self.opensearch_home();
self.environment_variables()
.get(&EnvVarName::from_str_unsafe("OPENSEARCH_PATH_CONF"))
.and_then(|env_var| env_var.value.clone())
.unwrap_or(format!("{opensearch_home}/config"))
}
}

#[cfg(test)]
Expand Down Expand Up @@ -383,6 +402,7 @@ mod tests {
role_group_config.clone(),
)]
.into(),
vec![],
);

NodeConfig::new(
Expand Down
1 change: 1 addition & 0 deletions rust/operator-binary/src/controller/build/role_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ mod tests {
role_group_config.clone(),
)]
.into(),
vec![],
);

RoleBuilder::new(cluster, context_names)
Expand Down
Loading
Loading