Skip to content

Commit 505b00a

Browse files
committed
refactor!: remove HashMap default for ConfigOverrides type parameter
1 parent 8d9c6cd commit 505b00a

6 files changed

Lines changed: 257 additions & 144 deletions

File tree

crates/stackable-operator/crds/DummyCluster.yaml

Lines changed: 143 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,59 @@ spec:
8282
and `stopped` will take no effect until `reconciliationPaused` is set to false or removed.
8383
type: boolean
8484
type: object
85+
configOverrides:
86+
default: {}
87+
description: |-
88+
Typed config override strategies for Dummy config files.
89+
90+
Demonstrates both JSON-formatted (`config.json`) and key-value-formatted
91+
(`dummy.properties`) config file overrides.
92+
properties:
93+
config.json:
94+
description: Overrides for the `config.json` file.
95+
nullable: true
96+
oneOf:
97+
- required:
98+
- jsonMergePatch
99+
- required:
100+
- jsonPatches
101+
- required:
102+
- userProvided
103+
properties:
104+
jsonMergePatch:
105+
description: |-
106+
Can be set to arbitrary YAML content, which is converted to JSON and used as
107+
[RFC 7396](https://datatracker.ietf.org/doc/html/rfc7396) JSON merge patch.
108+
type: object
109+
x-kubernetes-preserve-unknown-fields: true
110+
jsonPatches:
111+
description: |-
112+
List of [RFC 6902](https://datatracker.ietf.org/doc/html/rfc6902) JSON patches.
113+
114+
Can be used when more flexibility is needed, e.g. to only modify elements
115+
in a list based on a condition.
116+
117+
A patch looks something like
118+
119+
`{"op": "test", "path": "/0/name", "value": "Andrew"}`
120+
121+
or
122+
123+
`{"op": "add", "path": "/0/happy", "value": true}`
124+
items:
125+
type: string
126+
type: array
127+
userProvided:
128+
description: Override the entire config file with the specified String.
129+
type: string
130+
type: object
131+
dummy.properties:
132+
additionalProperties:
133+
type: string
134+
description: Overrides for the `dummy.properties` file.
135+
nullable: true
136+
type: object
137+
type: object
85138
domainName:
86139
description: A validated domain name type conforming to RFC 1123, so e.g. not an IP address
87140
type: string
@@ -164,56 +217,9 @@ spec:
164217
type: object
165218
hostName:
166219
type: string
167-
jsonConfigOverrides:
168-
nullable: true
169-
oneOf:
170-
- required:
171-
- jsonMergePatch
172-
- required:
173-
- jsonPatches
174-
- required:
175-
- userProvided
176-
properties:
177-
jsonMergePatch:
178-
description: |-
179-
Can be set to arbitrary YAML content, which is converted to JSON and used as
180-
[RFC 7396](https://datatracker.ietf.org/doc/html/rfc7396) JSON merge patch.
181-
type: object
182-
x-kubernetes-preserve-unknown-fields: true
183-
jsonPatches:
184-
description: |-
185-
List of [RFC 6902](https://datatracker.ietf.org/doc/html/rfc6902) JSON patches.
186-
187-
Can be used when more flexibility is needed, e.g. to only modify elements
188-
in a list based on a condition.
189-
190-
A patch looks something like
191-
192-
`{"op": "test", "path": "/0/name", "value": "Andrew"}`
193-
194-
or
195-
196-
`{"op": "add", "path": "/0/happy", "value": true}`
197-
items:
198-
type: string
199-
type: array
200-
userProvided:
201-
description: Override the entire config file with the specified String.
202-
type: string
203-
type: object
204220
kerberosRealmName:
205221
description: A validated kerberos realm name type, for use in CRDs.
206222
type: string
207-
keyValueConfigOverrides:
208-
additionalProperties:
209-
type: string
210-
description: |-
211-
Flat key-value overrides for `*.properties`, Hadoop XML, etc.
212-
213-
This is backwards-compatible with the existing flat key-value YAML format
214-
used by `HashMap<String, String>`.
215-
nullable: true
216-
type: object
217223
nodes:
218224
description: |-
219225
This struct represents a role - e.g. HDFS datanodes or Trino workers. It has a key-value-map containing
@@ -760,16 +766,57 @@ spec:
760766
type: object
761767
type: object
762768
configOverrides:
763-
additionalProperties:
764-
additionalProperties:
765-
type: string
766-
type: object
767769
description: |-
768770
The `configOverrides` can be used to configure properties in product config files
769771
that are not exposed in the CRD. Read the
770772
[config overrides documentation](https://docs.stackable.tech/home/nightly/concepts/overrides#config-overrides)
771773
and consult the operator specific usage guide documentation for details on the
772774
available config files and settings for the specific product.
775+
properties:
776+
config.json:
777+
description: Overrides for the `config.json` file.
778+
nullable: true
779+
oneOf:
780+
- required:
781+
- jsonMergePatch
782+
- required:
783+
- jsonPatches
784+
- required:
785+
- userProvided
786+
properties:
787+
jsonMergePatch:
788+
description: |-
789+
Can be set to arbitrary YAML content, which is converted to JSON and used as
790+
[RFC 7396](https://datatracker.ietf.org/doc/html/rfc7396) JSON merge patch.
791+
type: object
792+
x-kubernetes-preserve-unknown-fields: true
793+
jsonPatches:
794+
description: |-
795+
List of [RFC 6902](https://datatracker.ietf.org/doc/html/rfc6902) JSON patches.
796+
797+
Can be used when more flexibility is needed, e.g. to only modify elements
798+
in a list based on a condition.
799+
800+
A patch looks something like
801+
802+
`{"op": "test", "path": "/0/name", "value": "Andrew"}`
803+
804+
or
805+
806+
`{"op": "add", "path": "/0/happy", "value": true}`
807+
items:
808+
type: string
809+
type: array
810+
userProvided:
811+
description: Override the entire config file with the specified String.
812+
type: string
813+
type: object
814+
dummy.properties:
815+
additionalProperties:
816+
type: string
817+
description: Overrides for the `dummy.properties` file.
818+
nullable: true
819+
type: object
773820
type: object
774821
envOverrides:
775822
additionalProperties:
@@ -1371,16 +1418,57 @@ spec:
13711418
type: object
13721419
type: object
13731420
configOverrides:
1374-
additionalProperties:
1375-
additionalProperties:
1376-
type: string
1377-
type: object
13781421
description: |-
13791422
The `configOverrides` can be used to configure properties in product config files
13801423
that are not exposed in the CRD. Read the
13811424
[config overrides documentation](https://docs.stackable.tech/home/nightly/concepts/overrides#config-overrides)
13821425
and consult the operator specific usage guide documentation for details on the
13831426
available config files and settings for the specific product.
1427+
properties:
1428+
config.json:
1429+
description: Overrides for the `config.json` file.
1430+
nullable: true
1431+
oneOf:
1432+
- required:
1433+
- jsonMergePatch
1434+
- required:
1435+
- jsonPatches
1436+
- required:
1437+
- userProvided
1438+
properties:
1439+
jsonMergePatch:
1440+
description: |-
1441+
Can be set to arbitrary YAML content, which is converted to JSON and used as
1442+
[RFC 7396](https://datatracker.ietf.org/doc/html/rfc7396) JSON merge patch.
1443+
type: object
1444+
x-kubernetes-preserve-unknown-fields: true
1445+
jsonPatches:
1446+
description: |-
1447+
List of [RFC 6902](https://datatracker.ietf.org/doc/html/rfc6902) JSON patches.
1448+
1449+
Can be used when more flexibility is needed, e.g. to only modify elements
1450+
in a list based on a condition.
1451+
1452+
A patch looks something like
1453+
1454+
`{"op": "test", "path": "/0/name", "value": "Andrew"}`
1455+
1456+
or
1457+
1458+
`{"op": "add", "path": "/0/happy", "value": true}`
1459+
items:
1460+
type: string
1461+
type: array
1462+
userProvided:
1463+
description: Override the entire config file with the specified String.
1464+
type: string
1465+
type: object
1466+
dummy.properties:
1467+
additionalProperties:
1468+
type: string
1469+
description: Overrides for the `dummy.properties` file.
1470+
nullable: true
1471+
type: object
13841472
type: object
13851473
envOverrides:
13861474
additionalProperties:

crates/stackable-operator/src/commons/resources.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
//! role_utils::Role,
3131
//! };
3232
//!
33+
//! #[derive(Clone, Debug, Default, Deserialize, JsonSchema, PartialEq, Serialize)]
34+
//! pub struct ProductConfigOverrides {}
35+
//!
3336
//! #[derive(Clone, CustomResource, Debug, Deserialize, JsonSchema, Serialize)]
3437
//! #[kube(
3538
//! group = "product.stackable.tech",
@@ -46,7 +49,7 @@
4649
//! #[serde(rename_all = "camelCase")]
4750
//! pub struct ProductSpec {
4851
//! #[serde(default, skip_serializing_if = "Option::is_none")]
49-
//! pub nodes: Option<Role<ProductConfigFragment>>,
52+
//! pub nodes: Option<Role<ProductConfigFragment, ProductConfigOverrides>>,
5053
//! }
5154
//!
5255
//! #[derive(Debug, Default, PartialEq, Fragment, JsonSchema)]

crates/stackable-operator/src/config_overrides.rs

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
//! properties files). The types here are composed by each operator into its
66
//! CRD-specific `configOverrides` struct.
77
8-
use std::collections::{BTreeMap, HashMap};
8+
use std::collections::BTreeMap;
99

1010
use schemars::JsonSchema;
1111
use serde::{Deserialize, Serialize};
@@ -34,29 +34,14 @@ pub enum Error {
3434
/// Trait that allows the product config pipeline to extract flat key-value
3535
/// overrides from any `configOverrides` type.
3636
///
37-
/// The default `HashMap<String, HashMap<String, String>>` implements this
38-
/// by looking up the file name and returning its entries. Typed override
39-
/// structs that have no key-value files can use the default implementation,
40-
/// which returns an empty map.
37+
/// Typed override structs that have no key-value files can use the default
38+
/// implementation, which returns an empty map.
4139
pub trait KeyValueOverridesProvider {
4240
fn get_key_value_overrides(&self, _file: &str) -> BTreeMap<String, Option<String>> {
4341
BTreeMap::new()
4442
}
4543
}
4644

47-
impl KeyValueOverridesProvider for HashMap<String, HashMap<String, String>> {
48-
fn get_key_value_overrides(&self, file: &str) -> BTreeMap<String, Option<String>> {
49-
self.get(file)
50-
.map(|entries| {
51-
entries
52-
.iter()
53-
.map(|(k, v)| (k.clone(), Some(v.clone())))
54-
.collect()
55-
})
56-
.unwrap_or_default()
57-
}
58-
}
59-
6045
/// Flat key-value overrides for `*.properties`, Hadoop XML, etc.
6146
///
6247
/// This is backwards-compatible with the existing flat key-value YAML format
@@ -147,8 +132,6 @@ impl JsonConfigOverrides {
147132

148133
#[cfg(test)]
149134
mod tests {
150-
use std::collections::HashMap;
151-
152135
use serde_json::json;
153136

154137
use super::*;
@@ -290,20 +273,4 @@ mod tests {
290273
assert_eq!(result.get("key2"), Some(&Some("value2".to_owned())));
291274
}
292275

293-
#[test]
294-
fn key_value_overrides_provider_for_hashmap() {
295-
let mut config_overrides = HashMap::<String, HashMap<String, String>>::new();
296-
let mut file_overrides = HashMap::new();
297-
file_overrides.insert("key1".to_owned(), "value1".to_owned());
298-
file_overrides.insert("key2".to_owned(), "value2".to_owned());
299-
config_overrides.insert("myfile.properties".to_owned(), file_overrides);
300-
301-
let result = config_overrides.get_key_value_overrides("myfile.properties");
302-
assert_eq!(result.len(), 2);
303-
assert_eq!(result.get("key1"), Some(&Some("value1".to_owned())));
304-
assert_eq!(result.get("key2"), Some(&Some("value2".to_owned())));
305-
306-
let empty = config_overrides.get_key_value_overrides("nonexistent.properties");
307-
assert!(empty.is_empty());
308-
}
309276
}

0 commit comments

Comments
 (0)