Skip to content

Commit a695dbc

Browse files
committed
feat: Support setting TLS certificate lifetimes
1 parent 852cdf0 commit a695dbc

File tree

9 files changed

+58
-26
lines changed

9 files changed

+58
-26
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
44

55
## [Unreleased]
66

7+
### Added
8+
9+
- The lifetime of auto generated TLS certificates is now configurable with the role and roleGroup
10+
config property `requestedSecretLifetime`. This helps reducing frequent Pod restarts ([#721]).
11+
712
### Fixed
813

914
- Fix OIDC endpoint construction in case the `rootPath` does not have a trailing slash ([#718]).
@@ -13,6 +18,7 @@ All notable changes to this project will be documented in this file.
1318

1419
[#717]: https://github.com/stackabletech/nifi-operator/pull/717
1520
[#718]: https://github.com/stackabletech/nifi-operator/pull/718
21+
[#721]: https://github.com/stackabletech/nifi-operator/pull/721
1622

1723
## [24.11.0] - 2024-11-18
1824

Cargo.lock

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

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,6 @@ tracing = "0.1"
3232
url = { version = "2.5.2" }
3333
xml-rs = "0.8"
3434

35-
# [patch."https://github.com/stackabletech/operator-rs.git"]
36-
# stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "main" }
35+
[patch."https://github.com/stackabletech/operator-rs.git"]
36+
stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "main" }
3737
# stackable-operator = { path = "../operator-rs/crates/stackable-operator" }

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,10 @@ spec:
358358
nullable: true
359359
type: boolean
360360
type: object
361+
requestedSecretLifetime:
362+
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.
363+
nullable: true
364+
type: string
361365
resources:
362366
default:
363367
cpu:
@@ -815,6 +819,10 @@ spec:
815819
nullable: true
816820
type: boolean
817821
type: object
822+
requestedSecretLifetime:
823+
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.
824+
nullable: true
825+
type: string
818826
resources:
819827
default:
820828
cpu:

rust/crd/src/lib.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,10 +411,16 @@ pub struct NifiConfig {
411411
/// Time period Pods have to gracefully shut down, e.g. `30m`, `1h` or `2d`. Consult the operator documentation for details.
412412
#[fragment_attrs(serde(default))]
413413
pub graceful_shutdown_timeout: Option<Duration>,
414+
415+
/// Request secret (currently only autoTls certificates) lifetime from the secret operator, e.g. `7d`, or `30d`.
416+
/// Please note that this can be shortened by the `maxCertificateLifetime` setting on the SecretClass issuing the TLS certificate.
417+
#[fragment_attrs(serde(default))]
418+
pub requested_secret_lifetime: Option<Duration>,
414419
}
415420

416421
impl NifiConfig {
417-
pub const NIFI_SENSITIVE_PROPS_KEY: &'static str = "NIFI_SENSITIVE_PROPS_KEY";
422+
// Auto TLS certificate lifetime
423+
const DEFAULT_NODE_SECRET_LIFETIME: Duration = Duration::from_days_unchecked(7);
418424

419425
pub fn default_config(cluster_name: &str, role: &NifiRole) -> NifiConfigFragment {
420426
NifiConfigFragment {
@@ -458,6 +464,7 @@ impl NifiConfig {
458464
},
459465
affinity: get_affinity(cluster_name, role),
460466
graceful_shutdown_timeout: Some(DEFAULT_NODE_GRACEFUL_SHUTDOWN_TIMEOUT),
467+
requested_secret_lifetime: Some(Self::DEFAULT_NODE_SECRET_LIFETIME),
461468
}
462469
}
463470
}

rust/operator-binary/src/controller.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ pub struct Ctx {
112112
#[strum_discriminants(derive(IntoStaticStr))]
113113
#[allow(clippy::enum_variant_names)]
114114
pub enum Error {
115+
#[snafu(display("missing secret lifetime"))]
116+
MissingSecretLifetime,
117+
115118
#[snafu(display("NifiCluster object is invalid"))]
116119
InvalidNifiCluster {
117120
source: error_boundary::InvalidObject,
@@ -1253,6 +1256,9 @@ async fn build_node_rolegroup_statefulset(
12531256
.context(MetadataBuildSnafu)?
12541257
.build();
12551258

1259+
let requested_secret_lifetime = merged_config
1260+
.requested_secret_lifetime
1261+
.context(MissingSecretLifetimeSnafu)?;
12561262
let nifi_cluster_name = nifi.name_any();
12571263
pod_builder
12581264
.metadata(metadata)
@@ -1301,6 +1307,7 @@ async fn build_node_rolegroup_statefulset(
13011307
&build_reporting_task_service_name(&nifi_cluster_name),
13021308
],
13031309
SecretFormat::TlsPkcs12,
1310+
&requested_secret_lifetime,
13041311
)
13051312
.context(SecuritySnafu)?,
13061313
)

rust/operator-binary/src/reporting_task/mod.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,15 @@
2424
//!
2525
use std::collections::BTreeMap;
2626

27+
use crate::security::{
28+
authentication::{NifiAuthenticationConfig, STACKABLE_ADMIN_USERNAME},
29+
build_tls_volume,
30+
};
2731
use snafu::{OptionExt, ResultExt, Snafu};
2832
use stackable_nifi_crd::{
2933
NifiCluster, NifiRole, APP_NAME, HTTPS_PORT, HTTPS_PORT_NAME, METRICS_PORT,
3034
};
35+
use stackable_operator::time::Duration;
3136
use stackable_operator::{
3237
builder::{
3338
self,
@@ -50,11 +55,6 @@ use stackable_operator::{
5055
utils::cluster_info::KubernetesClusterInfo,
5156
};
5257

53-
use crate::security::{
54-
authentication::{NifiAuthenticationConfig, STACKABLE_ADMIN_USERNAME},
55-
build_tls_volume,
56-
};
57-
5858
use super::controller::{build_recommended_labels, NIFI_UID};
5959

6060
const REPORTING_TASK_CERT_VOLUME_NAME: &str = "tls";
@@ -359,6 +359,10 @@ fn build_reporting_task_job(
359359
REPORTING_TASK_CERT_VOLUME_NAME,
360360
vec![],
361361
SecretFormat::TlsPem,
362+
// The certificate is only used for the REST API call, so a short lifetime is sufficient.
363+
// There is no correct way to configure this job since it's an implementation detail.
364+
// Also it will be dropped when support for 1.x is removed.
365+
&Duration::from_days_unchecked(1),
362366
)
363367
.context(SecretVolumeBuildFailureSnafu)?,
364368
)

rust/operator-binary/src/security/mod.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use snafu::{ResultExt, Snafu};
22
use stackable_nifi_crd::NifiCluster;
33
use stackable_operator::client::Client;
4+
use stackable_operator::time::Duration;
45
use stackable_operator::{builder::pod::volume::SecretFormat, k8s_openapi::api::core::v1::Volume};
56

67
pub mod authentication;
@@ -42,6 +43,14 @@ pub fn build_tls_volume(
4243
volume_name: &str,
4344
service_scopes: Vec<&str>,
4445
secret_format: SecretFormat,
46+
requested_secret_lifetime: &Duration,
4547
) -> Result<Volume> {
46-
tls::build_tls_volume(nifi, volume_name, service_scopes, secret_format).context(TlsSnafu)
48+
tls::build_tls_volume(
49+
nifi,
50+
volume_name,
51+
service_scopes,
52+
secret_format,
53+
requested_secret_lifetime,
54+
)
55+
.context(TlsSnafu)
4756
}

rust/operator-binary/src/security/tls.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1+
use crate::security::authentication::STACKABLE_TLS_STORE_PASSWORD;
12
use snafu::{ResultExt, Snafu};
23
use stackable_nifi_crd::NifiCluster;
4+
use stackable_operator::time::Duration;
35
use stackable_operator::{
46
builder::pod::volume::{SecretFormat, SecretOperatorVolumeSourceBuilder, VolumeBuilder},
57
k8s_openapi::api::core::v1::Volume,
68
};
79

8-
use crate::security::authentication::STACKABLE_TLS_STORE_PASSWORD;
9-
1010
pub const KEYSTORE_VOLUME_NAME: &str = "keystore";
1111
pub const KEYSTORE_NIFI_CONTAINER_MOUNT: &str = "/stackable/keystore";
1212
pub const TRUSTSTORE_VOLUME_NAME: &str = "truststore";
@@ -26,6 +26,7 @@ pub(crate) fn build_tls_volume(
2626
volume_name: &str,
2727
service_scopes: Vec<&str>,
2828
secret_format: SecretFormat,
29+
requested_secret_lifetime: &Duration,
2930
) -> Result<Volume> {
3031
let mut secret_volume_source_builder =
3132
SecretOperatorVolumeSourceBuilder::new(nifi.server_tls_secret_class());
@@ -44,6 +45,7 @@ pub(crate) fn build_tls_volume(
4445
.with_node_scope()
4546
.with_pod_scope()
4647
.with_format(secret_format)
48+
.with_auto_tls_cert_lifetime(*requested_secret_lifetime)
4749
.build()
4850
.context(TlsCertSecretClassVolumeBuildSnafu)?,
4951
)

0 commit comments

Comments
 (0)