-
-
Notifications
You must be signed in to change notification settings - Fork 0
feat: TLS support #55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
d45f8fb
c489b44
ffa0585
aaa560f
4d7496c
7f805b8
c6db525
1c3e672
bbbdbb6
1aeb4db
ab42f5a
97681a3
815d243
95986a5
910a58d
9252b06
beb2aff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -58,6 +58,41 @@ 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"; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| /// Path to the cert PEM file used for TLS on the HTTP PORT. | ||||||||||||||||||||||||
| /// type: string | ||||||||||||||||||||||||
| pub const CONFIG_OPTION_PLUGINS_SECURITY_SSL_HTTP_PEMCERT_FILEPATH: &str = | ||||||||||||||||||||||||
| "plugins.security.ssl.http.pemcert_filepath"; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| /// Path to the key PEM file used for TLS on the HTTP PORT. | ||||||||||||||||||||||||
| /// type: string | ||||||||||||||||||||||||
| pub const CONFIG_OPTION_PLUGINS_SECURITY_SSL_HTTP_PEMKEY_FILEPATH: &str = | ||||||||||||||||||||||||
| "plugins.security.ssl.http.pemkey_filepath"; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| /// Path to the trusted CAs PEM file used for TLS on the HTTP PORT. | ||||||||||||||||||||||||
| /// type: string | ||||||||||||||||||||||||
| pub const CONFIG_OPTION_PLUGINS_SECURITY_SSL_HTTP_PEMTRUSTEDCAS_FILEPATH: &str = | ||||||||||||||||||||||||
| "plugins.security.ssl.http.pemtrustedcas_filepath"; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| /// Whether to enable TLS on internal node-to-node communication using the transport port. | ||||||||||||||||||||||||
| /// type: boolean | ||||||||||||||||||||||||
| pub const CONFIG_OPTION_PLUGINS_SECURITY_SSL_TRANSPORT_ENABLED: &str = | ||||||||||||||||||||||||
| "plugins.security.ssl.transport.enabled"; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| /// Path to the cert PEM file used for TLS on the transport PORT. | ||||||||||||||||||||||||
| /// type: string | ||||||||||||||||||||||||
| pub const CONFIG_OPTION_PLUGINS_SECURITY_SSL_TRANSPORT_PEMCERT_FILEPATH: &str = | ||||||||||||||||||||||||
| "plugins.security.ssl.transport.pemcert_filepath"; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| /// Path to the key PEM file used for TLS on the transport PORT. | ||||||||||||||||||||||||
| /// type: string | ||||||||||||||||||||||||
| pub const CONFIG_OPTION_PLUGINS_SECURITY_SSL_TRANSPORT_PEMKEY_FILEPATH: &str = | ||||||||||||||||||||||||
| "plugins.security.ssl.transport.pemkey_filepath"; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| /// Path to the trusted CAs PEM file used for TLS on the transport PORT. | ||||||||||||||||||||||||
| /// type: string | ||||||||||||||||||||||||
| pub const CONFIG_OPTION_PLUGINS_SECURITY_SSL_TRANSPORT_PEMTRUSTEDCAS_FILEPATH: &str = | ||||||||||||||||||||||||
| "plugins.security.ssl.transport.pemtrustedcas_filepath"; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| /// Configuration of an OpenSearch node based on the cluster and role-group configuration | ||||||||||||||||||||||||
| pub struct NodeConfig { | ||||||||||||||||||||||||
| cluster: ValidatedCluster, | ||||||||||||||||||||||||
|
|
@@ -81,8 +116,31 @@ impl NodeConfig { | |||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| /// Creates the main OpenSearch configuration file in YAML format | ||||||||||||||||||||||||
| pub fn static_opensearch_config_file_content(&self) -> String { | ||||||||||||||||||||||||
| Self::to_yaml(self.static_opensearch_config()) | ||||||||||||||||||||||||
| pub fn opensearch_config_file_content(&self) -> String { | ||||||||||||||||||||||||
| Self::to_yaml(self.opensearch_config()) | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| pub fn opensearch_config(&self) -> serde_json::Map<String, Value> { | ||||||||||||||||||||||||
| let mut config = self.static_opensearch_config(); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| if self.cluster.cluster_config.tls.secret_class.is_some() { | ||||||||||||||||||||||||
| config.append(&mut self.tls_config()); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| for (setting, value) in self | ||||||||||||||||||||||||
| .role_group_config | ||||||||||||||||||||||||
| .config_overrides | ||||||||||||||||||||||||
| .get(CONFIGURATION_FILE_OPENSEARCH_YML) | ||||||||||||||||||||||||
| .into_iter() | ||||||||||||||||||||||||
| .flatten() | ||||||||||||||||||||||||
| { | ||||||||||||||||||||||||
| config.insert(setting.to_owned(), json!(value)); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| // Ensure a deterministic result | ||||||||||||||||||||||||
| config.sort_keys(); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| config | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| /// Creates the main OpenSearch configuration file as JSON map | ||||||||||||||||||||||||
|
|
@@ -112,25 +170,53 @@ impl NodeConfig { | |||||||||||||||||||||||
| json!(["CN=generated certificate for pod".to_owned()]), | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| for (setting, value) in self | ||||||||||||||||||||||||
| .role_group_config | ||||||||||||||||||||||||
| .config_overrides | ||||||||||||||||||||||||
| .get(CONFIGURATION_FILE_OPENSEARCH_YML) | ||||||||||||||||||||||||
| .into_iter() | ||||||||||||||||||||||||
| .flatten() | ||||||||||||||||||||||||
| { | ||||||||||||||||||||||||
| config.insert(setting.to_owned(), json!(value)); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| config | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| // Ensure a deterministic result | ||||||||||||||||||||||||
| config.sort_keys(); | ||||||||||||||||||||||||
| pub fn tls_config(&self) -> serde_json::Map<String, Value> { | ||||||||||||||||||||||||
| let mut config = serde_json::Map::new(); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| // TLS config for HTTP port | ||||||||||||||||||||||||
| config.insert( | ||||||||||||||||||||||||
| CONFIG_OPTION_PLUGINS_SECURITY_SSL_HTTP_ENABLED.to_owned(), | ||||||||||||||||||||||||
| json!("true".to_string()), | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| config.insert( | ||||||||||||||||||||||||
| CONFIG_OPTION_PLUGINS_SECURITY_SSL_HTTP_PEMCERT_FILEPATH.to_owned(), | ||||||||||||||||||||||||
| json!("${OPENSEARCH_PATH_CONF}/tls/tls.crt".to_string()), | ||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using the value of Currently, this exception is thrown in the integration tests: The resolution of the actual path is already done in opensearch-operator/rust/operator-binary/src/controller/build/role_group_builder.rs Lines 397 to 407 in 2f4fb8a
But if the location is decided in the volume mount then it is wrong to depend on an environment variable here. Therefore, it would be better to move the mentioned code to this module. The code depends anyway only on the environment variables in this module. Then the resolved path can be used here. |
||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| config.insert( | ||||||||||||||||||||||||
| CONFIG_OPTION_PLUGINS_SECURITY_SSL_HTTP_PEMKEY_FILEPATH.to_owned(), | ||||||||||||||||||||||||
| json!("${OPENSEARCH_PATH_CONF}/tls/tls.key".to_string()), | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| config.insert( | ||||||||||||||||||||||||
| CONFIG_OPTION_PLUGINS_SECURITY_SSL_HTTP_PEMTRUSTEDCAS_FILEPATH.to_owned(), | ||||||||||||||||||||||||
| json!("${OPENSEARCH_PATH_CONF}/tls/ca.crt".to_string()), | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| // TLS config for TRANSPORT port | ||||||||||||||||||||||||
| config.insert( | ||||||||||||||||||||||||
| CONFIG_OPTION_PLUGINS_SECURITY_SSL_TRANSPORT_ENABLED.to_owned(), | ||||||||||||||||||||||||
| json!("true".to_string()), | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| config.insert( | ||||||||||||||||||||||||
| CONFIG_OPTION_PLUGINS_SECURITY_SSL_TRANSPORT_PEMCERT_FILEPATH.to_owned(), | ||||||||||||||||||||||||
| json!("${OPENSEARCH_PATH_CONF}/tls/tls.crt".to_string()), | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| config.insert( | ||||||||||||||||||||||||
| CONFIG_OPTION_PLUGINS_SECURITY_SSL_TRANSPORT_PEMKEY_FILEPATH.to_owned(), | ||||||||||||||||||||||||
| json!("${OPENSEARCH_PATH_CONF}/tls/tls.key".to_string()), | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| config.insert( | ||||||||||||||||||||||||
| CONFIG_OPTION_PLUGINS_SECURITY_SSL_TRANSPORT_PEMTRUSTEDCAS_FILEPATH.to_owned(), | ||||||||||||||||||||||||
| json!("${OPENSEARCH_PATH_CONF}/tls/ca.crt".to_string()), | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| config | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| /// Returns `true` if TLS is enabled on the HTTP port | ||||||||||||||||||||||||
| pub fn tls_on_http_port_enabled(&self) -> bool { | ||||||||||||||||||||||||
| self.static_opensearch_config() | ||||||||||||||||||||||||
| self.opensearch_config() | ||||||||||||||||||||||||
| .get(CONFIG_OPTION_PLUGINS_SECURITY_SSL_HTTP_ENABLED) | ||||||||||||||||||||||||
| .and_then(Self::value_as_bool) | ||||||||||||||||||||||||
| == Some(true) | ||||||||||||||||||||||||
|
|
@@ -277,13 +363,14 @@ mod tests { | |||||||||||||||||||||||
| kvp::LabelValue, | ||||||||||||||||||||||||
| product_logging::spec::AutomaticContainerLogConfig, | ||||||||||||||||||||||||
| role_utils::GenericRoleConfig, | ||||||||||||||||||||||||
| shared::time::Duration, | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
| use uuid::uuid; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| use super::*; | ||||||||||||||||||||||||
| use crate::{ | ||||||||||||||||||||||||
| controller::{ValidatedLogging, ValidatedOpenSearchConfig}, | ||||||||||||||||||||||||
| crd::NodeRoles, | ||||||||||||||||||||||||
| crd::{NodeRoles, v1alpha1::OpenSearchClusterConfig}, | ||||||||||||||||||||||||
| framework::{ | ||||||||||||||||||||||||
| ClusterName, ListenerClassName, NamespaceName, ProductVersion, RoleGroupName, | ||||||||||||||||||||||||
| product_logging::framework::ValidatedContainerLogConfigChoice, | ||||||||||||||||||||||||
|
|
@@ -328,6 +415,8 @@ mod tests { | |||||||||||||||||||||||
| v1alpha1::NodeRole::Ingest, | ||||||||||||||||||||||||
| v1alpha1::NodeRole::RemoteClusterClient, | ||||||||||||||||||||||||
| ]), | ||||||||||||||||||||||||
| requested_secret_lifetime: Duration::from_str("15d") | ||||||||||||||||||||||||
| .expect("should be a valid duration"), | ||||||||||||||||||||||||
| resources: Resources::default(), | ||||||||||||||||||||||||
| termination_grace_period_seconds: 30, | ||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||
|
|
@@ -364,6 +453,7 @@ mod tests { | |||||||||||||||||||||||
| ClusterName::from_str_unsafe("my-opensearch-cluster"), | ||||||||||||||||||||||||
| NamespaceName::from_str_unsafe("default"), | ||||||||||||||||||||||||
| uuid!("0b1e30e6-326e-4c1a-868d-ad6598b49e8b"), | ||||||||||||||||||||||||
| OpenSearchClusterConfig::default(), | ||||||||||||||||||||||||
| GenericRoleConfig::default(), | ||||||||||||||||||||||||
| [( | ||||||||||||||||||||||||
| RoleGroupName::from_str_unsafe("default"), | ||||||||||||||||||||||||
|
|
@@ -395,7 +485,7 @@ mod tests { | |||||||||||||||||||||||
| "test: \"value\"" | ||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||
| .to_owned(), | ||||||||||||||||||||||||
| node_config.static_opensearch_config_file_content() | ||||||||||||||||||||||||
| node_config.opensearch_config_file_content() | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If
OpenSearchClusterConfigis extended in the future, then it will probably contain unvalidated entries. If the whole structure is added now toValidatedCluster, then it will have to be removed again and all the TLS related code has to be refactored.Additionally,
OpenSearchClusterConfigcontainsvector_aggregator_config_map_namewhich is already contained inrole_group_configs.logging.vector_container.vector_aggregator_config_map_name.I would directly add the
OpenSearchTlsstructure here.