From aa61bed1b6db37da08cf6550f5036576117e3e23 Mon Sep 17 00:00:00 2001 From: Jacob Tomlinson Date: Tue, 10 Sep 2024 11:12:32 +0100 Subject: [PATCH] Extend Kubernetes version support to match cloud support (#489) --- ci/update-kubernetes.py | 109 +++++++++++++++++++++++++++++++++++----- docs/installation.md | 13 ++++- 2 files changed, 108 insertions(+), 14 deletions(-) diff --git a/ci/update-kubernetes.py b/ci/update-kubernetes.py index 08448fda..5e4c9016 100755 --- a/ci/update-kubernetes.py +++ b/ci/update-kubernetes.py @@ -3,6 +3,7 @@ # SPDX-FileCopyrightText: Copyright (c) 2024, Kr8s Developers (See LICENSE for list) # SPDX-License-Identifier: BSD 3-Clause License import json +import os import re import urllib.request from datetime import datetime @@ -18,7 +19,7 @@ DATE_FORMAT = "%Y-%m-%d" -def get_versions(): +def get_kubernetes_oss_versions(): print( "Loading Kubernetes versions from https://endoflife.date/api/kubernetes.json..." ) @@ -34,9 +35,78 @@ def get_versions(): if datetime.strptime(x["eol"], DATE_FORMAT) > datetime.now() ] data.sort(key=lambda x: x["eol"], reverse=True) + return data + + +def get_azure_aks_versions(): + url = "https://endoflife.date/api/azure-kubernetes-service.json" + print(f"Loading Azure AKS versions from {url}...") + with urllib.request.urlopen(url) as payload: + data = json.load(payload) + data = [ + { + "cycle": x["cycle"], + "eol": datetime.strptime( + x["eol"] if not x["lts"] else x["support"], DATE_FORMAT + ), + } + for x in data + if datetime.strptime(x["eol"], DATE_FORMAT) > datetime.now() + ] + data.sort(key=lambda x: x["eol"], reverse=True) + return data - print("Loading Kubernetes tags from https://hub.docker.com/r/kindest/node/tags...") +def get_amazon_eks_versions(): + url = "https://endoflife.date/api/amazon-eks.json" + print(f"Loading Amazon EKS versions from {url}...") + with urllib.request.urlopen(url) as payload: + data = json.load(payload) + data = [ + { + "cycle": x["cycle"], + "eol": datetime.strptime(x["eol"], DATE_FORMAT), + } + for x in data + if datetime.strptime(x["eol"], DATE_FORMAT) > datetime.now() + ] + data.sort(key=lambda x: x["eol"], reverse=True) + return data + + +def get_google_kubernetes_engine_versions(): + url = "https://endoflife.date/api/google-kubernetes-engine.json" + print(f"Loading Google Kubernetes Engine versions from {url}...") + with urllib.request.urlopen(url) as payload: + data = json.load(payload) + data = [ + { + "cycle": x["cycle"], + "eol": datetime.strptime(x["eol"], DATE_FORMAT), + } + for x in data + if datetime.strptime(x["eol"], DATE_FORMAT) > datetime.now() + ] + data.sort(key=lambda x: x["eol"], reverse=True) + return data + + +def extend_versions(versions, extended_versions, provider): + print(f"Extending EOL dates with {provider} support dates...") + for extended_version in extended_versions: + for version in versions: + if version["cycle"] == extended_version["cycle"]: + if version["eol"] < extended_version["eol"]: + print( + f"Extending EOL date for {version['cycle']} from {version['eol']:%Y-%m-%d} to " + f"{provider} support date {extended_version['eol']:%Y-%m-%d}" + ) + version["eol"] = extended_version["eol"] + return versions + + +def get_kind_versions(): + print("Loading Kubernetes tags from https://hub.docker.com/r/kindest/node/tags...") container_tags = [] next_url = "https://hub.docker.com/v2/repositories/kindest/node/tags" while next_url: @@ -47,8 +117,19 @@ def get_versions(): next_url = results["next"] else: next_url = None + return container_tags + - for version in data: +def get_versions(): + oss_versions = get_kubernetes_oss_versions() + versions = extend_versions(oss_versions, get_azure_aks_versions(), "Azure AKS") + versions = extend_versions(versions, get_amazon_eks_versions(), "Amazon EKS") + versions = extend_versions( + versions, get_google_kubernetes_engine_versions(), "Google Kubernetes Engine" + ) + container_tags = get_kind_versions() + + for version in versions: try: version["latest_kind_container"] = [ x["name"] @@ -58,11 +139,11 @@ def get_versions(): except IndexError: version["latest_kind_container"] = None - before_length = len(data) + before_length = len(versions) print("Pruning versions that do not have a kind release yet...") - data[:] = [x for x in data if x["latest_kind_container"] is not None] - print(f"Pruned {before_length - len(data)} versions") - return data + versions[:] = [x for x in versions if x["latest_kind_container"] is not None] + print(f"Pruned {before_length - len(versions)} versions") + return versions def update_workflow(versions, workflow_path): @@ -102,13 +183,17 @@ def main(): print("Supported versions:") for version in versions: print( - f"For {version['cycle']} using kindest/node {version['latest_kind_container']} until {version['eol']}" + f"For {version['cycle']} using kindest/node {version['latest_kind_container']}" + f" until {version['eol']:%Y-%m-%d}" ) - update_workflow(versions, ".github/workflows/test-kr8s.yaml") - update_workflow(versions, ".github/workflows/test-kubectl-ng.yaml") - update_badges("README.md", versions) - update_badges("docs/index.md", versions) + if not os.environ.get("DEBUG"): + update_workflow(versions, ".github/workflows/test-kr8s.yaml") + update_workflow(versions, ".github/workflows/test-kubectl-ng.yaml") + update_badges("README.md", versions) + update_badges("docs/index.md", versions) + else: + print("DEBUG env var set, skipping file updates") if __name__ == "__main__": diff --git a/docs/installation.md b/docs/installation.md index 2dc11ea8..916afb30 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -18,5 +18,14 @@ $ conda install -c conda-forge kr8s ## Supported Kubernetes Versions -We endeavor to support all Kubernetes versions that are [actively supported by the Kubernetes community](https://kubernetes.io/releases/). -Kubernetes typically releases 3-4 times a year and provides 1 year of patch support. +We endeavor to support all Kubernetes versions that are [actively supported by the Kubernetes community](https://kubernetes.io/releases/) and popular cloud hosted Kubernetes platforms. + +For each version of Kubernetes we check the following end of life dates: +- [Open Source Kubernetes Maintenance Support](https://endoflife.date/kubernetes) +- [Google Kubernetes Engine Maintenance Support](https://endoflife.date/google-kubernetes-engine) +- [Amazon EKS End of Support](https://endoflife.date/amazon-eks) +- [Azure Kubernetes Service End of Support (not including LTS extensions)](https://endoflife.date/azure-kubernetes-service) + +Once a version has reached end of life from all providers we remove it from our CI/testing matrix. + +Typically new versions are released 3-4 times a year and each version receives 12-15 months of support.