Skip to content

Commit dcd94b0

Browse files
razvansbernauer
andauthored
feat: Support setting TLS certificate lifetimes (#598)
* feat: `requestedSecretLifetime` role group property added * Update rust/crd/src/lib.rs Co-authored-by: Sebastian Bernauer <sebastian.bernauer@stackable.de> * Update CHANGELOG.md Co-authored-by: Sebastian Bernauer <sebastian.bernauer@stackable.de> * implement review feedback * Update CHANGELOG.md Co-authored-by: Sebastian Bernauer <sebastian.bernauer@stackable.de> * point to op-rs main * apply review patch * apply review patch 2 * chore: bump op-rs * cargo update -p rustls --------- Co-authored-by: Sebastian Bernauer <sebastian.bernauer@stackable.de>
1 parent af18193 commit dcd94b0

File tree

7 files changed

+89
-38
lines changed

7 files changed

+89
-38
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,19 @@
22

33
## [Unreleased]
44

5+
### Added
6+
7+
- The lifetime of auto generated TLS certificates is now configurable with the role and roleGroup
8+
config property `requestedSecretLifetime`. This helps reducing frequent Pod restarts ([#598]).
9+
510
### Fixed
611

712
- BREAKING: Use distinct ServiceAccounts for the Stacklets, so that multiple Stacklets can be
813
deployed in one namespace. Existing Stacklets will use the newly created ServiceAccounts after
914
restart ([#594]).
1015

1116
[#594]: https://github.com/stackabletech/hbase-operator/pull/594
17+
[#598]: https://github.com/stackabletech/hbase-operator/pull/598
1218

1319
## [24.11.0] - 2024-11-18
1420

Cargo.lock

Lines changed: 7 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ serde = { version = "1.0", features = ["derive"] }
2121
serde_json = "1.0"
2222
serde_yaml = "0.9"
2323
snafu = "0.8"
24-
stackable-operator = { git = "https://github.com/stackabletech/operator-rs.git", tag = "stackable-operator-0.82.0" }
24+
stackable-operator = { git = "https://github.com/stackabletech/operator-rs.git", tag = "stackable-operator-0.83.0" }
2525
product-config = { git = "https://github.com/stackabletech/product-config.git", tag = "0.7.0" }
2626
strum = { version = "0.26", features = ["derive"] }
2727
tokio = { version = "1.40", features = ["full"] }
2828
tracing = "0.1"
2929

30-
#[patch."https://github.com/stackabletech/operator-rs.git"]
31-
#stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "main" }
30+
# [patch."https://github.com/stackabletech/operator-rs.git"]
31+
# stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "main" }

deploy/helm/hbase-operator/crds/crds.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,10 @@ spec:
297297
nullable: true
298298
type: boolean
299299
type: object
300+
requestedSecretLifetime:
301+
description: Request secret (currently only autoTls certificates) lifetime from the secret operator, e.g. `7d`, or `30d`. Please note that this can be shortened by the `maxCertificateLifetime` setting on the SecretClass issuing the TLS certificate.
302+
nullable: true
303+
type: string
300304
resources:
301305
default:
302306
cpu:
@@ -520,6 +524,10 @@ spec:
520524
nullable: true
521525
type: boolean
522526
type: object
527+
requestedSecretLifetime:
528+
description: Request secret (currently only autoTls certificates) lifetime from the secret operator, e.g. `7d`, or `30d`. Please note that this can be shortened by the `maxCertificateLifetime` setting on the SecretClass issuing the TLS certificate.
529+
nullable: true
530+
type: string
523531
resources:
524532
default:
525533
cpu:
@@ -724,6 +732,10 @@ spec:
724732
nullable: true
725733
type: boolean
726734
type: object
735+
requestedSecretLifetime:
736+
description: Request secret (currently only autoTls certificates) lifetime from the secret operator, e.g. `7d`, or `30d`. Please note that this can be shortened by the `maxCertificateLifetime` setting on the SecretClass issuing the TLS certificate.
737+
nullable: true
738+
type: string
727739
resources:
728740
default:
729741
cpu:
@@ -947,6 +959,10 @@ spec:
947959
nullable: true
948960
type: boolean
949961
type: object
962+
requestedSecretLifetime:
963+
description: Request secret (currently only autoTls certificates) lifetime from the secret operator, e.g. `7d`, or `30d`. Please note that this can be shortened by the `maxCertificateLifetime` setting on the SecretClass issuing the TLS certificate.
964+
nullable: true
965+
type: string
950966
resources:
951967
default:
952968
cpu:
@@ -1151,6 +1167,10 @@ spec:
11511167
nullable: true
11521168
type: boolean
11531169
type: object
1170+
requestedSecretLifetime:
1171+
description: Request secret (currently only autoTls certificates) lifetime from the secret operator, e.g. `7d`, or `30d`. Please note that this can be shortened by the `maxCertificateLifetime` setting on the SecretClass issuing the TLS certificate.
1172+
nullable: true
1173+
type: string
11541174
resources:
11551175
default:
11561176
cpu:
@@ -1374,6 +1394,10 @@ spec:
13741394
nullable: true
13751395
type: boolean
13761396
type: object
1397+
requestedSecretLifetime:
1398+
description: Request secret (currently only autoTls certificates) lifetime from the secret operator, e.g. `7d`, or `30d`. Please note that this can be shortened by the `maxCertificateLifetime` setting on the SecretClass issuing the TLS certificate.
1399+
nullable: true
1400+
type: string
13771401
resources:
13781402
default:
13791403
cpu:

rust/crd/src/lib.rs

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,6 @@ pub const METRICS_PORT: u16 = 9100;
8181

8282
pub const JVM_HEAP_FACTOR: f32 = 0.8;
8383

84-
const DEFAULT_MASTER_GRACEFUL_SHUTDOWN_TIMEOUT: Duration = Duration::from_minutes_unchecked(20);
85-
const DEFAULT_REGION_SERVER_GRACEFUL_SHUTDOWN_TIMEOUT: Duration =
86-
Duration::from_minutes_unchecked(60);
87-
const DEFAULT_REST_SERVER_GRACEFUL_SHUTDOWN_TIMEOUT: Duration = Duration::from_minutes_unchecked(5);
88-
8984
#[derive(Snafu, Debug)]
9085
pub enum Error {
9186
#[snafu(display("the role [{role}] is invalid and does not exist in HBase"))]
@@ -262,6 +257,17 @@ pub enum HbaseRole {
262257
}
263258

264259
impl HbaseRole {
260+
const DEFAULT_MASTER_GRACEFUL_SHUTDOWN_TIMEOUT: Duration = Duration::from_minutes_unchecked(20);
261+
const DEFAULT_REGION_SERVER_GRACEFUL_SHUTDOWN_TIMEOUT: Duration =
262+
Duration::from_minutes_unchecked(60);
263+
const DEFAULT_REST_SERVER_GRACEFUL_SHUTDOWN_TIMEOUT: Duration =
264+
Duration::from_minutes_unchecked(5);
265+
266+
// Auto TLS certificate lifetime
267+
const DEFAULT_MASTER_SECRET_LIFETIME: Duration = Duration::from_days_unchecked(7);
268+
const DEFAULT_REGION_SECRET_LIFETIME: Duration = Duration::from_days_unchecked(7);
269+
const DEFAULT_REST_SECRET_LIFETIME: Duration = Duration::from_days_unchecked(7);
270+
265271
pub fn default_config(
266272
&self,
267273
cluster_name: &str,
@@ -304,9 +310,15 @@ impl HbaseRole {
304310
};
305311

306312
let graceful_shutdown_timeout = match &self {
307-
HbaseRole::Master => DEFAULT_MASTER_GRACEFUL_SHUTDOWN_TIMEOUT,
308-
HbaseRole::RegionServer => DEFAULT_REGION_SERVER_GRACEFUL_SHUTDOWN_TIMEOUT,
309-
HbaseRole::RestServer => DEFAULT_REST_SERVER_GRACEFUL_SHUTDOWN_TIMEOUT,
313+
HbaseRole::Master => Self::DEFAULT_MASTER_GRACEFUL_SHUTDOWN_TIMEOUT,
314+
HbaseRole::RegionServer => Self::DEFAULT_REGION_SERVER_GRACEFUL_SHUTDOWN_TIMEOUT,
315+
HbaseRole::RestServer => Self::DEFAULT_REST_SERVER_GRACEFUL_SHUTDOWN_TIMEOUT,
316+
};
317+
318+
let requested_secret_lifetime = match &self {
319+
HbaseRole::Master => Self::DEFAULT_MASTER_SECRET_LIFETIME,
320+
HbaseRole::RegionServer => Self::DEFAULT_REGION_SECRET_LIFETIME,
321+
HbaseRole::RestServer => Self::DEFAULT_REST_SECRET_LIFETIME,
310322
};
311323

312324
HbaseConfigFragment {
@@ -316,6 +328,7 @@ impl HbaseRole {
316328
logging: product_logging::spec::default_logging(),
317329
affinity: get_affinity(cluster_name, self, hdfs_discovery_cm_name),
318330
graceful_shutdown_timeout: Some(graceful_shutdown_timeout),
331+
requested_secret_lifetime: Some(requested_secret_lifetime),
319332
}
320333
}
321334

@@ -410,6 +423,11 @@ pub struct HbaseConfig {
410423
/// Time period Pods have to gracefully shut down, e.g. `30m`, `1h` or `2d`. Consult the operator documentation for details.
411424
#[fragment_attrs(serde(default))]
412425
pub graceful_shutdown_timeout: Option<Duration>,
426+
427+
/// Request secret (currently only autoTls certificates) lifetime from the secret operator, e.g. `7d`, or `30d`.
428+
/// Please note that this can be shortened by the `maxCertificateLifetime` setting on the SecretClass issuing the TLS certificate.
429+
#[fragment_attrs(serde(default))]
430+
pub requested_secret_lifetime: Option<Duration>,
413431
}
414432

415433
impl Configuration for HbaseConfigFragment {

rust/operator-binary/src/hbase_controller.rs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ pub struct Ctx {
113113
#[strum_discriminants(derive(IntoStaticStr))]
114114
#[allow(clippy::enum_variant_names)]
115115
pub enum Error {
116+
#[snafu(display("missing secret lifetime"))]
117+
MissingSecretLifetime,
118+
116119
#[snafu(display("object defines no version"))]
117120
ObjectHasNoVersion,
118121

@@ -777,7 +780,7 @@ fn build_rolegroup_statefulset(
777780
hbase_role: &HbaseRole,
778781
rolegroup_ref: &RoleGroupRef<HbaseCluster>,
779782
rolegroup_config: &HashMap<PropertyNameKind, BTreeMap<String, String>>,
780-
config: &HbaseConfig,
783+
merged_config: &HbaseConfig,
781784
resolved_product_image: &ResolvedProductImage,
782785
service_account: &ServiceAccount,
783786
) -> Result<StatefulSet> {
@@ -899,7 +902,7 @@ fn build_rolegroup_statefulset(
899902
.add_volume_mount("log", STACKABLE_LOG_DIR)
900903
.context(AddVolumeMountSnafu)?
901904
.add_container_ports(ports)
902-
.resources(config.resources.clone().into())
905+
.resources(merged_config.resources.clone().into())
903906
.startup_probe(startup_probe)
904907
.liveness_probe(liveness_probe)
905908
.readiness_probe(readiness_probe);
@@ -919,7 +922,7 @@ fn build_rolegroup_statefulset(
919922
pod_builder
920923
.metadata(pb_metadata)
921924
.image_pull_secrets_from_product_image(resolved_product_image)
922-
.affinity(&config.affinity)
925+
.affinity(&merged_config.affinity)
923926
.add_volume(stackable_operator::k8s_openapi::api::core::v1::Volume {
924927
name: "hbase-config".to_string(),
925928
config_map: Some(ConfigMapVolumeSource {
@@ -959,7 +962,7 @@ fn build_rolegroup_statefulset(
959962
Some(ContainerLogConfigChoice::Custom(CustomContainerLogConfig {
960963
custom: ConfigMapLogConfig { config_map },
961964
})),
962-
}) = config.logging.containers.get(&Container::Hbase)
965+
}) = merged_config.logging.containers.get(&Container::Hbase)
963966
{
964967
pod_builder
965968
.add_volume(Volume {
@@ -984,21 +987,29 @@ fn build_rolegroup_statefulset(
984987
.context(AddVolumeSnafu)?;
985988
}
986989

987-
add_graceful_shutdown_config(config, &mut pod_builder).context(GracefulShutdownSnafu)?;
990+
add_graceful_shutdown_config(merged_config, &mut pod_builder).context(GracefulShutdownSnafu)?;
988991
if hbase.has_kerberos_enabled() {
989-
add_kerberos_pod_config(hbase, hbase_role, &mut hbase_container, &mut pod_builder)
990-
.context(AddKerberosConfigSnafu)?;
992+
add_kerberos_pod_config(
993+
hbase,
994+
hbase_role,
995+
&mut hbase_container,
996+
&mut pod_builder,
997+
merged_config
998+
.requested_secret_lifetime
999+
.context(MissingSecretLifetimeSnafu)?,
1000+
)
1001+
.context(AddKerberosConfigSnafu)?;
9911002
}
9921003
pod_builder.add_container(hbase_container.build());
9931004

9941005
// Vector sidecar shall be the last container in the list
995-
if config.logging.enable_vector_agent {
1006+
if merged_config.logging.enable_vector_agent {
9961007
pod_builder.add_container(
9971008
product_logging::framework::vector_container(
9981009
resolved_product_image,
9991010
"hbase-config",
10001011
"log",
1001-
config.logging.containers.get(&Container::Vector),
1012+
merged_config.logging.containers.get(&Container::Vector),
10021013
ResourceRequirementsBuilder::new()
10031014
.with_cpu_request("250m")
10041015
.with_cpu_limit("500m")

rust/operator-binary/src/kerberos.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use stackable_operator::{
1515
},
1616
},
1717
kube::{runtime::reflector::ObjectRef, ResourceExt},
18+
time::Duration,
1819
utils::cluster_info::KubernetesClusterInfo,
1920
};
2021

@@ -232,6 +233,7 @@ pub fn add_kerberos_pod_config(
232233
role: &HbaseRole,
233234
cb: &mut ContainerBuilder,
234235
pb: &mut PodBuilder,
236+
requested_secret_lifetime: Duration,
235237
) -> Result<(), Error> {
236238
if let Some(kerberos_secret_class) = hbase.kerberos_secret_class() {
237239
// Mount keytab
@@ -270,6 +272,7 @@ pub fn add_kerberos_pod_config(
270272
.with_node_scope()
271273
.with_format(SecretFormat::TlsPkcs12)
272274
.with_tls_pkcs12_password(TLS_STORE_PASSWORD)
275+
.with_auto_tls_cert_lifetime(requested_secret_lifetime)
273276
.build()
274277
.context(AddTlsSecretVolumeSnafu)?,
275278
)

0 commit comments

Comments
 (0)