Skip to content

Commit 9d130e7

Browse files
chore: Move restarter annotation code to the framework module; Define the security managing role group in the test explicitly
1 parent 9ca72d2 commit 9d130e7

5 files changed

Lines changed: 137 additions & 51 deletions

File tree

rust/operator-binary/src/controller/build/role_group_builder.rs

Lines changed: 8 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ use crate::{
6565
container::{EnvVarName, EnvVarSet, new_container_builder},
6666
volume::{ListenerReference, listener_operator_volume_source_builder_build_pvc},
6767
},
68+
statefulset::{
69+
restarter_ignore_configmap_annotations, restarter_ignore_secret_annotations,
70+
},
6871
},
6972
kvp::label::{recommended_labels, role_group_selector, role_selector},
7073
product_logging::framework::{
@@ -381,36 +384,11 @@ impl<'a> RoleGroupBuilder<'a> {
381384
let (security_settings_config_maps, security_settings_secrets) =
382385
self.security_settings_resource_names();
383386

384-
let restarter_ignore_config_maps_annotations = security_settings_config_maps
385-
.iter()
386-
.enumerate()
387-
.map(|(i, config_map_name)| {
388-
(
389-
format!("restarter.stackable.tech/ignore-configmap.{i}"),
390-
config_map_name.to_string(),
391-
)
392-
});
393-
let restarter_ignore_secrets_annotations = security_settings_secrets
394-
.iter()
395-
.enumerate()
396-
.map(|(i, secret_name)| {
397-
(
398-
format!("restarter.stackable.tech/ignore-secret.{i}"),
399-
secret_name.to_string(),
400-
)
401-
});
402-
403-
// The expectation is tested in the unit tests.
404-
Annotations::try_from(
405-
restarter_ignore_config_maps_annotations
406-
.chain(restarter_ignore_secrets_annotations)
407-
.collect::<BTreeMap<_, _>>(),
408-
)
409-
.expect(
410-
"should contain only valid annotations because the annotation keys are statically \
411-
defined apart from the index number and the names of ConfigMaps and Secrets are valid \
412-
annotation values.",
413-
)
387+
let mut annotations = restarter_ignore_configmap_annotations(security_settings_config_maps);
388+
annotations.extend(restarter_ignore_secret_annotations(
389+
security_settings_secrets,
390+
));
391+
annotations
414392
}
415393

416394
/// Builds the [`PodTemplateSpec`] for the [`StatefulSet`] of the role group
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
pub mod meta;
22
pub mod pdb;
33
pub mod pod;
4+
pub mod statefulset;
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
use std::collections::BTreeMap;
2+
3+
use stackable_operator::kvp::Annotations;
4+
5+
use crate::framework::types::kubernetes::{ConfigMapName, SecretName};
6+
7+
/// Creates `restarter.stackable.tech/ignore-configmap.{i}` annotations for each given ConfigMap.
8+
///
9+
/// The restarter uses these annotations to skip restarting Pods when specific ConfigMaps change.
10+
/// Indices start at 0 and are assigned in iteration order, so **do not merge the result with
11+
/// annotations from another call** — duplicate indices would overwrite each other.
12+
pub fn restarter_ignore_configmap_annotations(
13+
ignored_config_maps: impl IntoIterator<Item = ConfigMapName>,
14+
) -> Annotations {
15+
let annotation_key_values = ignored_config_maps
16+
.into_iter()
17+
.enumerate()
18+
.map(|(i, config_map_name)| {
19+
(
20+
format!("restarter.stackable.tech/ignore-configmap.{i}"),
21+
config_map_name.to_string(),
22+
)
23+
})
24+
.collect::<BTreeMap<_, _>>();
25+
26+
Annotations::try_from(annotation_key_values).expect(
27+
"should contain only valid annotations because the annotation keys are statically \
28+
defined apart from the index number and the names of ConfigMaps are valid annotation \
29+
values.",
30+
)
31+
}
32+
33+
/// Creates `restarter.stackable.tech/ignore-secret.{i}` annotations for each given Secret.
34+
///
35+
/// The restarter uses these annotations to skip restarting Pods when specific Secrets change.
36+
/// Indices start at 0 and are assigned in iteration order, so **do not merge the result with
37+
/// annotations from another call** — duplicate indices would overwrite each other.
38+
pub fn restarter_ignore_secret_annotations(
39+
ignored_secrets: impl IntoIterator<Item = SecretName>,
40+
) -> Annotations {
41+
let annotation_key_values = ignored_secrets
42+
.into_iter()
43+
.enumerate()
44+
.map(|(i, secret_name)| {
45+
(
46+
format!("restarter.stackable.tech/ignore-secret.{i}"),
47+
secret_name.to_string(),
48+
)
49+
})
50+
.collect::<BTreeMap<_, _>>();
51+
52+
Annotations::try_from(annotation_key_values).expect(
53+
"should contain only valid annotations because the annotation keys are statically \
54+
defined apart from the index number and the names of Secrets are valid annotation \
55+
values.",
56+
)
57+
}
58+
59+
#[cfg(test)]
60+
mod tests {
61+
use super::*;
62+
63+
#[test]
64+
fn multiple_config_maps_produce_indexed_annotations() {
65+
let ignored_config_maps = [
66+
ConfigMapName::from_str_unsafe("first-config"),
67+
ConfigMapName::from_str_unsafe("second-config"),
68+
ConfigMapName::from_str_unsafe("third-config"),
69+
];
70+
71+
let actual_annotations = restarter_ignore_configmap_annotations(ignored_config_maps);
72+
73+
let expected_annotations = BTreeMap::from([
74+
(
75+
"restarter.stackable.tech/ignore-configmap.0".to_owned(),
76+
"first-config".to_owned(),
77+
),
78+
(
79+
"restarter.stackable.tech/ignore-configmap.1".to_owned(),
80+
"second-config".to_owned(),
81+
),
82+
(
83+
"restarter.stackable.tech/ignore-configmap.2".to_owned(),
84+
"third-config".to_owned(),
85+
),
86+
]);
87+
88+
assert_eq!(expected_annotations, actual_annotations.into());
89+
}
90+
91+
#[test]
92+
fn multiple_secrets_produce_indexed_annotations() {
93+
let ignored_secrets = [
94+
SecretName::from_str_unsafe("first-secret"),
95+
SecretName::from_str_unsafe("second-secret"),
96+
SecretName::from_str_unsafe("third-secret"),
97+
];
98+
99+
let actual_annotations = restarter_ignore_secret_annotations(ignored_secrets);
100+
101+
let expected_annotations = BTreeMap::from([
102+
(
103+
"restarter.stackable.tech/ignore-secret.0".to_owned(),
104+
"first-secret".to_owned(),
105+
),
106+
(
107+
"restarter.stackable.tech/ignore-secret.1".to_owned(),
108+
"second-secret".to_owned(),
109+
),
110+
(
111+
"restarter.stackable.tech/ignore-secret.2".to_owned(),
112+
"third-secret".to_owned(),
113+
),
114+
]);
115+
116+
assert_eq!(expected_annotations, actual_annotations.into());
117+
}
118+
}

tests/templates/kuttl/security-config/11-assert.yaml

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,15 @@ timeout: 600
66
apiVersion: apps/v1
77
kind: StatefulSet
88
metadata:
9-
name: opensearch-nodes-cluster-manager
9+
name: opensearch-nodes-default
1010
status:
1111
readyReplicas: 3
1212
replicas: 3
1313
---
1414
apiVersion: apps/v1
1515
kind: StatefulSet
1616
metadata:
17-
name: opensearch-nodes-data
18-
status:
19-
readyReplicas: 2
20-
replicas: 2
21-
---
22-
apiVersion: apps/v1
23-
kind: StatefulSet
24-
metadata:
25-
name: opensearch-nodes-security-config
17+
name: opensearch-nodes-security-coord
2618
annotations:
2719
restarter.stackable.tech/ignore-configmap.0: opensearch-security-config
2820
restarter.stackable.tech/ignore-configmap.1: security-config
@@ -33,13 +25,13 @@ spec:
3325
template:
3426
metadata:
3527
annotations:
36-
# configmap.restarter.stackable.tech/opensearch-nodes-security-config: <uid>/<resourceVersion>
28+
# configmap.restarter.stackable.tech/opensearch-nodes-security-coord: <uid>/<resourceVersion>
3729
configmap.restarter.stackable.tech/opensearch-security-config: changes-ignored
3830
configmap.restarter.stackable.tech/security-config: changes-ignored
3931
secret.restarter.stackable.tech/security-config-file-internal-users: changes-ignored
4032
status:
41-
readyReplicas: 1
42-
replicas: 1
33+
readyReplicas: 2
34+
replicas: 2
4335
---
4436
apiVersion: v1
4537
kind: ConfigMap

tests/templates/kuttl/security-config/11-install-opensearch.yaml.j2

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ spec:
1212
pullPolicy: IfNotPresent
1313
clusterConfig:
1414
security:
15+
managingRoleGroup: security-coord
1516
settings:
1617
config:
1718
managedBy: operator
@@ -67,27 +68,23 @@ spec:
6768
roleConfig:
6869
discoveryServiceListenerClass: external-unstable
6970
roleGroups:
70-
cluster-manager:
71+
default:
7172
config:
7273
discoveryServiceExposed: true
73-
nodeRoles:
74-
- cluster_manager
7574
resources:
7675
storage:
7776
data:
7877
capacity: 100Mi
7978
replicas: 3
80-
data:
79+
security-coord:
8180
config:
8281
discoveryServiceExposed: false
8382
nodeRoles:
84-
- ingest
85-
- data
86-
- remote_cluster_client
83+
- coordinating_only
8784
resources:
8885
storage:
8986
data:
90-
capacity: 2Gi
87+
capacity: 100Mi
9188
replicas: 2
9289
configOverrides:
9390
opensearch.yml:

0 commit comments

Comments
 (0)