Skip to content

Commit 0043157

Browse files
feat: Add AZ, Flavor, and Floating IP labels for apiServerLoadBalancer #510 (#798)
Signed-off-by: okozachenko1203 <[email protected]>
1 parent 91da05c commit 0043157

File tree

6 files changed

+161
-10
lines changed

6 files changed

+161
-10
lines changed

crates/serde_gtmpl/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ pub trait ToGtmplValue {
77

88
fn json_to_gtmpl_value(json: &serde_json::Value, version: &str) -> gtmpl_value::Value {
99
match json {
10-
serde_json::Value::Null => unimplemented!(),
10+
serde_json::Value::Null => gtmpl_value::Value::Nil,
1111
serde_json::Value::Bool(b) => (*b).into(),
1212
serde_json::Value::Number(n) => {
1313
if let Some(i) = n.as_i64() {

magnum_cluster_api/resources.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,15 @@ def get_object(self) -> dict:
928928
worker_flavor = utils.lookup_flavor(osc, self.cluster.flavor_id)
929929
image = utils.lookup_image(osc, self.cluster.default_ng_master.image_id)
930930

931+
api_server_load_balancer = {
932+
"enabled": self.cluster.master_lb_enabled,
933+
"provider": self.cluster.labels.get("octavia_provider", "amphora"),
934+
"availabilityZone": self.cluster.labels.get(
935+
"api_server_lb_availability_zone", ""
936+
),
937+
"flavor": self.cluster.labels.get("api_server_lb_flavor", ""),
938+
}
939+
931940
return {
932941
"metadata": {
933942
"labels": self.labels,
@@ -970,12 +979,7 @@ def get_object(self) -> dict:
970979
"variables": [
971980
{
972981
"name": "apiServerLoadBalancer",
973-
"value": {
974-
"enabled": self.cluster.master_lb_enabled,
975-
"provider": self.cluster.labels.get(
976-
"octavia_provider", "amphora"
977-
),
978-
},
982+
"value": api_server_load_balancer,
979983
},
980984
{
981985
"name": "apiServerTLSCipherSuites",
@@ -984,6 +988,12 @@ def get_object(self) -> dict:
984988
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", # noqa: E501
985989
),
986990
},
991+
{
992+
"name": "apiServerFloatingIP",
993+
"value": self.cluster.labels.get(
994+
"api_server_floating_ip", ""
995+
),
996+
},
987997
{
988998
"name": "openidConnect",
989999
"value": {
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
use crate::{
2+
cluster_api::{
3+
clusterclasses::{
4+
ClusterClassPatches, ClusterClassPatchesDefinitions,
5+
ClusterClassPatchesDefinitionsJsonPatches,
6+
ClusterClassPatchesDefinitionsJsonPatchesValueFrom,
7+
ClusterClassPatchesDefinitionsSelector,
8+
ClusterClassPatchesDefinitionsSelectorMatchResources, ClusterClassVariables,
9+
ClusterClassVariablesSchema,
10+
},
11+
openstackclustertemplates::OpenStackClusterTemplate,
12+
},
13+
features::{
14+
ClusterClassVariablesSchemaExt, ClusterFeatureEntry, ClusterFeaturePatches,
15+
ClusterFeatureVariables,
16+
},
17+
};
18+
use cluster_feature_derive::ClusterFeatureValues;
19+
use kube::CustomResourceExt;
20+
use serde::{Deserialize, Serialize};
21+
22+
#[derive(Serialize, Deserialize, ClusterFeatureValues)]
23+
pub struct FeatureValues {
24+
#[serde(rename = "apiServerFloatingIP")]
25+
pub api_server_floating_ip: String,
26+
}
27+
28+
pub struct Feature {}
29+
30+
impl ClusterFeaturePatches for Feature {
31+
fn patches(&self) -> Vec<ClusterClassPatches> {
32+
vec![ClusterClassPatches {
33+
name: "apiServerFloatingIP".into(),
34+
enabled_if: Some(r#"{{ if ne .apiServerFloatingIP "" }}true{{end}}"#.into()),
35+
definitions: Some(vec![ClusterClassPatchesDefinitions {
36+
selector: ClusterClassPatchesDefinitionsSelector {
37+
api_version: OpenStackClusterTemplate::api_resource().api_version,
38+
kind: OpenStackClusterTemplate::api_resource().kind,
39+
match_resources: ClusterClassPatchesDefinitionsSelectorMatchResources {
40+
infrastructure_cluster: Some(true),
41+
..Default::default()
42+
},
43+
},
44+
json_patches: vec![ClusterClassPatchesDefinitionsJsonPatches {
45+
op: "add".into(),
46+
path: "/spec/template/spec/apiServerFloatingIP".into(),
47+
value_from: Some(ClusterClassPatchesDefinitionsJsonPatchesValueFrom {
48+
variable: Some("apiServerFloatingIP".into()),
49+
..Default::default()
50+
}),
51+
..Default::default()
52+
}],
53+
}]),
54+
..Default::default()
55+
}]
56+
}
57+
}
58+
59+
inventory::submit! {
60+
ClusterFeatureEntry{ feature: &Feature {} }
61+
}
62+
63+
#[cfg(test)]
64+
mod tests {
65+
use super::*;
66+
use crate::features::test::TestClusterResources;
67+
use crate::resources::fixtures::default_values;
68+
use pretty_assertions::assert_eq;
69+
70+
#[test]
71+
fn test_patches_if_enabled() {
72+
let feature = Feature {};
73+
74+
let mut values = default_values();
75+
values.api_server_floating_ip = "1.2.3.4".to_string();
76+
77+
let patches = feature.patches();
78+
79+
let mut resources = TestClusterResources::new();
80+
resources.apply_patches(&patches, &values);
81+
82+
assert_eq!(
83+
resources
84+
.openstack_cluster_template
85+
.spec
86+
.template
87+
.spec
88+
.api_server_floating_ip,
89+
Some("1.2.3.4".into())
90+
);
91+
}
92+
93+
#[test]
94+
fn test_patches_if_disabled() {
95+
let feature = Feature {};
96+
97+
let values = default_values();
98+
let patches = feature.patches();
99+
100+
let mut resources = TestClusterResources::new();
101+
resources.apply_patches(&patches, &values);
102+
103+
assert_eq!(
104+
resources
105+
.openstack_cluster_template
106+
.spec
107+
.template
108+
.spec
109+
.api_server_floating_ip,
110+
None
111+
);
112+
}
113+
}

src/features/api_server_load_balancer.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,13 @@ use typed_builder::TypedBuilder;
2424
#[derive(Clone, Serialize, Deserialize, JsonSchema, TypedBuilder)]
2525
pub struct APIServerLoadBalancerConfig {
2626
pub enabled: bool,
27+
2728
pub provider: String,
29+
30+
pub flavor: String,
31+
32+
#[serde(rename = "availabilityZone")]
33+
pub availability_zone: String,
2834
}
2935

3036
#[derive(Serialize, Deserialize, ClusterFeatureValues)]
@@ -78,7 +84,14 @@ mod tests {
7884
fn test_patches() {
7985
let feature = Feature {};
8086

81-
let values = default_values();
87+
let mut values = default_values();
88+
values.api_server_load_balancer = APIServerLoadBalancerConfig::builder()
89+
.enabled(true)
90+
.provider("octavia".to_string())
91+
.flavor("ha".to_string())
92+
.availability_zone("zone-1".to_string())
93+
.build();
94+
8295
let patches = feature.patches();
8396

8497
let mut resources = TestClusterResources::new();
@@ -100,5 +113,13 @@ mod tests {
100113
api_server_load_balancer.provider,
101114
Some(values.api_server_load_balancer.provider)
102115
);
116+
assert_eq!(
117+
api_server_load_balancer.flavor,
118+
Some(values.api_server_load_balancer.flavor)
119+
);
120+
assert_eq!(
121+
api_server_load_balancer.availability_zone,
122+
Some(values.api_server_load_balancer.availability_zone)
123+
);
103124
}
104125
}

src/features/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ use schemars::{gen::SchemaGenerator, JsonSchema};
4949
use std::sync::LazyLock;
5050

5151
pub mod admission_plugins;
52+
pub mod api_server_floating_ip;
5253
pub mod api_server_load_balancer;
5354
pub mod audit_log;
5455
pub mod boot_volume;

src/resources.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,13 @@ pub mod fixtures {
186186

187187
pub fn default_values() -> Values {
188188
Values::builder()
189+
.api_server_floating_ip("".to_string())
189190
.api_server_load_balancer(
190191
api_server_load_balancer::APIServerLoadBalancerConfig::builder()
191192
.enabled(true)
192-
.provider("amphora".into())
193+
.provider("amphora".to_string())
194+
.flavor("worker".to_string())
195+
.availability_zone("zone1".to_string())
193196
.build(),
194197
)
195198
.audit_log(
@@ -306,10 +309,13 @@ mod tests {
306309
let values = default_values();
307310
let variables: Vec<ClusterTopologyVariables> = values.into();
308311

309-
assert_eq!(variables.len(), 36);
312+
assert_eq!(variables.len(), 37);
310313

311314
for var in &variables {
312315
match var.name.as_str() {
316+
"apiServerFloatingIP" => {
317+
assert_eq!(var.value, json!(default_values().api_server_floating_ip));
318+
}
313319
"apiServerLoadBalancer" => {
314320
assert_eq!(var.value, json!(&default_values().api_server_load_balancer));
315321
}

0 commit comments

Comments
 (0)