Skip to content

Commit 58eeb42

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

File tree

8 files changed

+77
-19
lines changed

8 files changed

+77
-19
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,19 @@ 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 ([#619]).
11+
712
### Fixed
813

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

1318
[#616]: https://github.com/stackabletech/hdfs-operator/pull/616
19+
[#619]: https://github.com/stackabletech/hdfs-operator/pull/619
1420

1521
## [24.11.0] - 2024-11-18
1622

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: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ 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"] }

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,10 @@ spec:
261261
nullable: true
262262
type: boolean
263263
type: object
264+
requestedSecretLifetime:
265+
description: Request secret (currently only autoTls certificates) lifetime from the secret operator, e.g. `7d`, or `30d`. This can be shortened by the `maxCertificateLifetime` setting on the SecretClass issuing the TLS certificate.
266+
nullable: true
267+
type: string
264268
resources:
265269
default:
266270
cpu:
@@ -538,6 +542,10 @@ spec:
538542
nullable: true
539543
type: boolean
540544
type: object
545+
requestedSecretLifetime:
546+
description: Request secret (currently only autoTls certificates) lifetime from the secret operator, e.g. `7d`, or `30d`. This can be shortened by the `maxCertificateLifetime` setting on the SecretClass issuing the TLS certificate.
547+
nullable: true
548+
type: string
541549
resources:
542550
default:
543551
cpu:
@@ -840,6 +848,10 @@ spec:
840848
nullable: true
841849
type: boolean
842850
type: object
851+
requestedSecretLifetime:
852+
description: Request secret (currently only autoTls certificates) lifetime from the secret operator, e.g. `7d`, or `30d`. This can be shortened by the `maxCertificateLifetime` setting on the SecretClass issuing the TLS certificate.
853+
nullable: true
854+
type: string
843855
resources:
844856
default:
845857
cpu:
@@ -1104,6 +1116,10 @@ spec:
11041116
nullable: true
11051117
type: boolean
11061118
type: object
1119+
requestedSecretLifetime:
1120+
description: Request secret (currently only autoTls certificates) lifetime from the secret operator, e.g. `7d`, or `30d`. This can be shortened by the `maxCertificateLifetime` setting on the SecretClass issuing the TLS certificate.
1121+
nullable: true
1122+
type: string
11071123
resources:
11081124
default:
11091125
cpu:
@@ -1353,6 +1369,10 @@ spec:
13531369
nullable: true
13541370
type: boolean
13551371
type: object
1372+
requestedSecretLifetime:
1373+
description: Request secret (currently only autoTls certificates) lifetime from the secret operator, e.g. `7d`, or `30d`. This can be shortened by the `maxCertificateLifetime` setting on the SecretClass issuing the TLS certificate.
1374+
nullable: true
1375+
type: string
13561376
resources:
13571377
default:
13581378
cpu:
@@ -1621,6 +1641,10 @@ spec:
16211641
nullable: true
16221642
type: boolean
16231643
type: object
1644+
requestedSecretLifetime:
1645+
description: Request secret (currently only autoTls certificates) lifetime from the secret operator, e.g. `7d`, or `30d`. This can be shortened by the `maxCertificateLifetime` setting on the SecretClass issuing the TLS certificate.
1646+
nullable: true
1647+
type: string
16241648
resources:
16251649
default:
16261650
cpu:

rust/crd/src/lib.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,11 @@ pub struct CommonNodeConfig {
238238
/// Time period Pods have to gracefully shut down, e.g. `30m`, `1h` or `2d`. Consult the operator documentation for details.
239239
#[fragment_attrs(serde(default))]
240240
pub graceful_shutdown_timeout: Option<Duration>,
241+
242+
/// Request secret (currently only autoTls certificates) lifetime from the secret operator, e.g. `7d`, or `30d`.
243+
/// This can be shortened by the `maxCertificateLifetime` setting on the SecretClass issuing the TLS certificate.
244+
#[fragment_attrs(serde(default))]
245+
pub requested_secret_lifetime: Option<Duration>,
241246
}
242247

243248
/// Configuration for a rolegroup of an unknown type.
@@ -310,6 +315,13 @@ impl AnyNodeConfig {
310315
AnyNodeConfig::JournalNode(node) => node.logging.enable_vector_agent,
311316
}
312317
}
318+
pub fn requested_secret_lifetime(&self) -> Option<Duration> {
319+
match self {
320+
AnyNodeConfig::NameNode(node) => node.common.requested_secret_lifetime,
321+
AnyNodeConfig::DataNode(node) => node.common.requested_secret_lifetime,
322+
AnyNodeConfig::JournalNode(node) => node.common.requested_secret_lifetime,
323+
}
324+
}
313325
}
314326

315327
#[derive(
@@ -1074,6 +1086,8 @@ pub struct NameNodeConfig {
10741086
}
10751087

10761088
impl NameNodeConfigFragment {
1089+
const DEFAULT_NAME_NODE_SECRET_LIFETIME: Duration = Duration::from_days_unchecked(7);
1090+
10771091
pub fn default_config(cluster_name: &str, role: &HdfsRole) -> Self {
10781092
Self {
10791093
resources: ResourcesFragment {
@@ -1098,6 +1112,7 @@ impl NameNodeConfigFragment {
10981112
common: CommonNodeConfigFragment {
10991113
affinity: get_affinity(cluster_name, role),
11001114
graceful_shutdown_timeout: Some(DEFAULT_NAME_NODE_GRACEFUL_SHUTDOWN_TIMEOUT),
1115+
requested_secret_lifetime: Some(Self::DEFAULT_NAME_NODE_SECRET_LIFETIME),
11011116
},
11021117
}
11031118
}
@@ -1208,6 +1223,8 @@ pub struct DataNodeConfig {
12081223
}
12091224

12101225
impl DataNodeConfigFragment {
1226+
const DEFAULT_DATA_NODE_SECRET_LIFETIME: Duration = Duration::from_days_unchecked(7);
1227+
12111228
pub fn default_config(cluster_name: &str, role: &HdfsRole) -> Self {
12121229
Self {
12131230
resources: ResourcesFragment {
@@ -1237,6 +1254,7 @@ impl DataNodeConfigFragment {
12371254
common: CommonNodeConfigFragment {
12381255
affinity: get_affinity(cluster_name, role),
12391256
graceful_shutdown_timeout: Some(DEFAULT_DATA_NODE_GRACEFUL_SHUTDOWN_TIMEOUT),
1257+
requested_secret_lifetime: Some(Self::DEFAULT_DATA_NODE_SECRET_LIFETIME),
12401258
},
12411259
}
12421260
}
@@ -1324,6 +1342,7 @@ pub struct JournalNodeConfig {
13241342
}
13251343

13261344
impl JournalNodeConfigFragment {
1345+
const DEFAULT_JOURNAL_NODE_SECRET_LIFETIME: Duration = Duration::from_days_unchecked(7);
13271346
pub fn default_config(cluster_name: &str, role: &HdfsRole) -> Self {
13281347
Self {
13291348
resources: ResourcesFragment {
@@ -1347,6 +1366,7 @@ impl JournalNodeConfigFragment {
13471366
common: CommonNodeConfigFragment {
13481367
affinity: get_affinity(cluster_name, role),
13491368
graceful_shutdown_timeout: Some(DEFAULT_JOURNAL_NODE_GRACEFUL_SHUTDOWN_TIMEOUT),
1369+
requested_secret_lifetime: Some(Self::DEFAULT_JOURNAL_NODE_SECRET_LIFETIME),
13501370
},
13511371
}
13521372
}

rust/operator-binary/src/container.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ type Result<T, E = Error> = std::result::Result<T, E>;
8989
#[derive(Snafu, Debug, EnumDiscriminants)]
9090
#[strum_discriminants(derive(IntoStaticStr))]
9191
pub enum Error {
92+
#[snafu(display("missing secret lifetime"))]
93+
MissingSecretLifetime,
94+
9295
#[snafu(display("object has no namespace"))]
9396
ObjectHasNoNamespace,
9497

@@ -272,6 +275,11 @@ impl ContainerConfig {
272275
.with_node_scope()
273276
.with_format(SecretFormat::TlsPkcs12)
274277
.with_tls_pkcs12_password(TLS_STORE_PASSWORD)
278+
.with_auto_tls_cert_lifetime(
279+
merged_config
280+
.requested_secret_lifetime()
281+
.context(MissingSecretLifetimeSnafu)?,
282+
)
275283
.build()
276284
.context(BuildSecretVolumeSnafu {
277285
volume_name: TLS_STORE_VOLUME_NAME,

tests/templates/kuttl/kerberos/20-assert.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,11 @@ metadata:
2626
status:
2727
readyReplicas: 2
2828
replicas: 2
29+
---
30+
apiVersion: kuttl.dev/v1beta1
31+
kind: TestAssert
32+
timeout: 600
33+
commands:
34+
- script: kubectl -n $NAMESPACE get sts/hdfs-namenode-default -o yaml | yq -e '.spec.template.spec.volumes.[] | select(.name == "tls" and .ephemeral.volumeClaimTemplate.metadata.annotations."secrets.stackable.tech/backend.autotls.cert.lifetime" == "7d")'
35+
- script: kubectl -n $NAMESPACE get sts/hdfs-datanode-default -o yaml | yq -e '.spec.template.spec.volumes.[] | select(.name == "tls" and .ephemeral.volumeClaimTemplate.metadata.annotations."secrets.stackable.tech/backend.autotls.cert.lifetime" == "1d")'
36+
- script: kubectl -n $NAMESPACE get sts/hdfs-journalnode-default -o yaml | yq -e '.spec.template.spec.volumes.[] | select(.name == "tls" and .ephemeral.volumeClaimTemplate.metadata.annotations."secrets.stackable.tech/backend.autotls.cert.lifetime" == "2d")'

tests/templates/kuttl/kerberos/20-install-hdfs.txt.j2

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ spec:
4444
replicas: 2
4545
dataNodes:
4646
config:
47+
requestedSecretLifetime: 1d
4748
logging:
4849
enableVectorAgent: {{ lookup('env', 'VECTOR_AGGREGATOR') | length > 0 }}
4950
roleGroups:
@@ -56,3 +57,5 @@ spec:
5657
roleGroups:
5758
default:
5859
replicas: 3
60+
config:
61+
requestedSecretLifetime: 2d

0 commit comments

Comments
 (0)