Skip to content

Commit 578ee86

Browse files
authored
feat: drop guards around k8s versions (#761)
* fix: default autoscaler image to .0 instead of hardcoding autoscaler images, we can simply assume .0 release exists for the requested version instead of full on failing. Signed-off-by: Mohammed Naser <[email protected]> * ci: add automation to keep cluster-autoscaler updated Signed-off-by: Mohammed Naser <[email protected]> * fix: enable cloud-provider option <1.29.0 Signed-off-by: Mohammed Naser <[email protected]> * chore: remove unused get_image functions Signed-off-by: Mohammed Naser <[email protected]> * fix: remove unused autoscaler options Signed-off-by: Mohammed Naser <[email protected]> * fix: remove cloud-provider only after 1.33 Signed-off-by: Mohammed Naser <[email protected]> --------- Signed-off-by: Mohammed Naser <[email protected]>
1 parent c82d0bc commit 578ee86

File tree

17 files changed

+364
-186
lines changed

17 files changed

+364
-186
lines changed

.github/workflows/bump.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: bump
2+
3+
on:
4+
workflow_dispatch:
5+
schedule:
6+
- cron: '0 0 * * *'
7+
8+
jobs:
9+
cluster-autoscaler:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
13+
with:
14+
token: ${{ secrets.VEXXHOST_BOT_PAT }}
15+
- run: ./hack/bump/cluster-autoscaler.sh
16+
- uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
17+
with:
18+
token: ${{ secrets.VEXXHOST_BOT_PAT }}
19+
commit-message: "chore(deps): update cluster-autoscaler"
20+
signoff: true
21+
title: "chore(deps): update cluster-autoscaler"
22+
body: |
23+
## Automated `cluster-autoscaler` update
24+
This PR updates the `cluster-autoscaler` images to the latest versions.
25+
delete-branch: true
26+
branch: bump/cluster-autoscaler

Cargo.lock

Lines changed: 1 addition & 0 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 & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ http = "1.3.1"
5252
mockall = "0.13.1"
5353
pretty_assertions = "1.4.1"
5454
rstest = "0.25.0"
55+
semver = "1.0.26"
5556
serde_gtmpl = { path = "crates/serde_gtmpl" }
5657
tower-test = "0.4.0"
5758

crates/serde_gtmpl/src/lib.rs

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ use serde::{de::DeserializeOwned, Serialize};
22
use serde_json::json;
33

44
pub trait ToGtmplValue {
5-
fn to_gtmpl_value(&self) -> gtmpl_value::Value;
5+
fn to_gtmpl_value(&self, version: &str) -> gtmpl_value::Value;
66
}
77

8-
fn json_to_gtmpl_value(json: &serde_json::Value) -> gtmpl_value::Value {
8+
fn json_to_gtmpl_value(json: &serde_json::Value, version: &str) -> gtmpl_value::Value {
99
match json {
1010
serde_json::Value::Null => unimplemented!(),
1111
serde_json::Value::Bool(b) => (*b).into(),
@@ -23,36 +23,49 @@ fn json_to_gtmpl_value(json: &serde_json::Value) -> gtmpl_value::Value {
2323
serde_json::Value::String(s) => s.into(),
2424
serde_json::Value::Array(arr) => arr
2525
.iter()
26-
.map(json_to_gtmpl_value)
26+
.map(|v| json_to_gtmpl_value(v, version))
2727
.collect::<Vec<_>>()
2828
.into(),
2929
serde_json::Value::Object(map) => {
3030
let mut object = map
3131
.iter()
32-
.map(|(k, v)| (k.clone(), json_to_gtmpl_value(v)))
32+
.map(|(k, v)| (k.clone(), json_to_gtmpl_value(v, version)))
3333
.collect::<std::collections::HashMap<_, _>>();
3434

3535
// XXX(mnaser): This is stinky, but we only use this in test anyways.
3636
object.insert(
3737
"builtin".to_string(),
3838
gtmpl_value::Value::Object(
39-
vec![(
40-
"cluster".to_string(),
41-
gtmpl_value::Value::Object(
42-
vec![
43-
(
44-
"name".to_string(),
45-
gtmpl_value::Value::String("kube-abcde".to_string()),
46-
),
47-
(
48-
"namespace".to_string(),
49-
gtmpl_value::Value::String("magnum-system".to_string()),
50-
),
51-
]
52-
.into_iter()
53-
.collect(),
39+
vec![
40+
(
41+
"cluster".to_string(),
42+
gtmpl_value::Value::Object(
43+
vec![
44+
(
45+
"name".to_string(),
46+
gtmpl_value::Value::String("kube-abcde".to_string()),
47+
),
48+
(
49+
"namespace".to_string(),
50+
gtmpl_value::Value::String("magnum-system".to_string()),
51+
),
52+
]
53+
.into_iter()
54+
.collect(),
55+
),
5456
),
55-
)]
57+
(
58+
"controlPlane".to_string(),
59+
gtmpl_value::Value::Object(
60+
vec![(
61+
"version".to_string(),
62+
gtmpl_value::Value::String(version.to_string()),
63+
)]
64+
.into_iter()
65+
.collect(),
66+
),
67+
),
68+
]
5669
.into_iter()
5770
.collect(),
5871
),
@@ -64,9 +77,9 @@ fn json_to_gtmpl_value(json: &serde_json::Value) -> gtmpl_value::Value {
6477
}
6578

6679
impl<T: Serialize + DeserializeOwned> ToGtmplValue for T {
67-
fn to_gtmpl_value(&self) -> gtmpl_value::Value {
80+
fn to_gtmpl_value(&self, version: &str) -> gtmpl_value::Value {
6881
let json = json!(self);
69-
json_to_gtmpl_value(&json)
82+
json_to_gtmpl_value(&json, version)
7083
}
7184
}
7285

@@ -77,19 +90,19 @@ mod tests {
7790
#[test]
7891
fn test_to_gtmpl_value() {
7992
let s = "hello".to_string();
80-
let v = s.to_gtmpl_value();
93+
let v = s.to_gtmpl_value("v1.0.0");
8194
assert_eq!(v, gtmpl_value::Value::String("hello".to_string()));
8295

8396
let n = 42;
84-
let v = n.to_gtmpl_value();
97+
let v = n.to_gtmpl_value("v1.0.0");
8598
assert_eq!(v, gtmpl_value::Value::Number(42.into()));
8699

87100
let b = true;
88-
let v = b.to_gtmpl_value();
101+
let v = b.to_gtmpl_value("v1.0.0");
89102
assert_eq!(v, gtmpl_value::Value::Bool(true));
90103

91104
let arr = vec![1, 2, 3];
92-
let v = arr.to_gtmpl_value();
105+
let v = arr.to_gtmpl_value("v1.0.0");
93106
assert_eq!(
94107
v,
95108
gtmpl_value::Value::Array(vec![

hack/bump/cluster-autoscaler.sh

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
set -euo pipefail
2+
3+
FILE=${1:-magnum_cluster_api/images.py}
4+
5+
# Build block with 4 spaces + trailing comma, sorted by minor asc.
6+
# We join with literal "\n" so awk can turn it into real newlines.
7+
BLOCK=$(
8+
gh api repos/kubernetes/autoscaler/tags --paginate \
9+
| jq -r '
10+
[ .[].name
11+
| select(test("^cluster-autoscaler-1\\.[0-9]+\\.[0-9]+$"))
12+
| capture("^cluster-autoscaler-(?<major>1)\\.(?<minor>\\d+)\\.(?<patch>\\d+)$")
13+
| .minor |= tonumber
14+
| .patch |= tonumber
15+
]
16+
| map(select(.minor >= 22))
17+
| group_by(.minor)
18+
| map(max_by(.patch))
19+
| sort_by(.minor)
20+
| map({("1."+(.minor|tostring)): (.major+"."+(.minor|tostring)+"."+(.patch|tostring))})
21+
| add
22+
| to_entries
23+
| sort_by((.key|split(".")[1]|tonumber))
24+
| map(" \"" + .key + "\": \"" + .value + "\",")
25+
| join("\\n")
26+
'
27+
)
28+
29+
# In-place replace contents of the dict block using awk.
30+
awk -i inplace -v block="$BLOCK" '
31+
function print_block() {
32+
tmp = block
33+
gsub(/\\n/, "\n", tmp) # turn literal \n into real newlines
34+
printf "%s\n", tmp
35+
}
36+
# Detect the start of the dict
37+
/^CLUSTER_AUTOSCALER_LATEST_BY_MINOR = \{$/ {
38+
print # keep the opening line
39+
in_block = 1
40+
printed = 0
41+
next
42+
}
43+
# Detect the closing brace of the dict
44+
in_block && /^\}/ {
45+
if (!printed) { print_block(); printed = 1 }
46+
in_block = 0
47+
print # keep the closing brace
48+
next
49+
}
50+
# Skip old lines inside the block
51+
in_block { next }
52+
53+
# Everything else prints as-is
54+
{ print }
55+
' "$FILE"
56+
57+
echo "Updated $FILE"

magnum_cluster_api/conf.py

Lines changed: 3 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -33,57 +33,7 @@
3333
"image_repository",
3434
default="registry.k8s.io/autoscaling",
3535
help="Image repository for the cluster auto-scaler.",
36-
),
37-
cfg.StrOpt(
38-
"v1_22_image",
39-
default="$image_repository/cluster-autoscaler:v1.22.3",
40-
help="Image for the cluster auto-scaler for Kubernetes v1.22.",
41-
),
42-
cfg.StrOpt(
43-
"v1_23_image",
44-
default="$image_repository/cluster-autoscaler:v1.23.1",
45-
help="Image for the cluster auto-scaler for Kubernetes v1.23.",
46-
),
47-
cfg.StrOpt(
48-
"v1_24_image",
49-
default="$image_repository/cluster-autoscaler:v1.24.2",
50-
help="Image for the cluster auto-scaler for Kubernetes v1.24.",
51-
),
52-
cfg.StrOpt(
53-
"v1_25_image",
54-
default="$image_repository/cluster-autoscaler:v1.25.2",
55-
help="Image for the cluster auto-scaler for Kubernetes v1.25.",
56-
),
57-
cfg.StrOpt(
58-
"v1_26_image",
59-
default="$image_repository/cluster-autoscaler:v1.26.3",
60-
help="Image for the cluster auto-scaler for Kubernetes v1.26.",
61-
),
62-
cfg.StrOpt(
63-
"v1_27_image",
64-
default="$image_repository/cluster-autoscaler:v1.27.2",
65-
help="Image for the cluster auto-scaler for Kubernetes v1.27.",
66-
),
67-
cfg.StrOpt(
68-
"v1_28_image",
69-
default="$image_repository/cluster-autoscaler:v1.28.5",
70-
help="Image for the cluster auto-scaler for Kubernetes v1.28.",
71-
),
72-
cfg.StrOpt(
73-
"v1_29_image",
74-
default="$image_repository/cluster-autoscaler:v1.29.3",
75-
help="Image for the cluster auto-scaler for Kubernetes v1.29.",
76-
),
77-
cfg.StrOpt(
78-
"v1_30_image",
79-
default="$image_repository/cluster-autoscaler:v1.30.1",
80-
help="Image for the cluster auto-scaler for Kubernetes v1.30.",
81-
),
82-
cfg.StrOpt(
83-
"v1_31_image",
84-
default="$image_repository/cluster-autoscaler:v1.31.0",
85-
help="Image for the cluster auto-scaler for Kubernetes v1.31.",
86-
),
36+
)
8737
]
8838

8939

@@ -137,12 +87,12 @@
13787
cfg.StrOpt("cert_file", help=_("Optional PEM-formatted certificate chain file.")),
13888
cfg.StrOpt(
13989
"key_file",
140-
help=_("Optional PEM-formatted file that contains the " "private key."),
90+
help=_("Optional PEM-formatted file that contains the private key."),
14191
),
14292
cfg.BoolOpt(
14393
"insecure",
14494
default=False,
145-
help=_("If set, then the server's certificate will not " "be verified."),
95+
help=_("If set, then the server's certificate will not be verified."),
14696
),
14797
]
14898

magnum_cluster_api/images.py

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,27 @@
2020

2121
PAUSE = "registry.k8s.io/pause:3.9"
2222

23+
CLUSTER_AUTOSCALER_LATEST_BY_MINOR = {
24+
"1.22": "1.22.3",
25+
"1.23": "1.23.1",
26+
"1.24": "1.24.3",
27+
"1.25": "1.25.3",
28+
"1.26": "1.26.8",
29+
"1.27": "1.27.8",
30+
"1.28": "1.28.7",
31+
"1.29": "1.29.5",
32+
"1.30": "1.30.5",
33+
"1.31": "1.31.3",
34+
"1.32": "1.32.2",
35+
"1.33": "1.33.0",
36+
}
37+
2338

2439
def get_cluster_autoscaler_image(version: str):
2540
parsed_version = semver.VersionInfo.parse(version[1:])
26-
config_option = f"v{parsed_version.major}_{parsed_version.minor}_image"
27-
28-
if hasattr(CONF.auto_scaling, config_option):
29-
return getattr(CONF.auto_scaling, config_option)
30-
31-
raise ValueError(
32-
f"Unsupported Kubernetes version: {version}. "
33-
"Please specify a supported version in the cluster template."
41+
cluster_autoscaler_version = CLUSTER_AUTOSCALER_LATEST_BY_MINOR.get(
42+
f"{parsed_version.major}.{parsed_version.minor}",
43+
f"{parsed_version.major}.{parsed_version.minor}.0",
3444
)
45+
46+
return f"{CONF.auto_scaling.image_repository}/cluster-autoscaler:v{cluster_autoscaler_version}"

magnum_cluster_api/integrations/cinder.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,6 @@ def is_enabled(cluster: objects.Cluster) -> bool:
2828
) or common.is_enabled(cluster, "cinder_csi_enabled", "block-storage")
2929

3030

31-
def get_image(cluster: objects.Cluster) -> str:
32-
return common.get_cloud_provider_image(
33-
cluster, "cinder_csi_plugin_tag", "cinder-csi-plugin"
34-
)
35-
36-
3731
def get_default_boot_volume_type(context):
3832
"""
3933
Get the default boot volume type since the existing function

0 commit comments

Comments
 (0)