From b881ef92711db997641b1f2f27532f3f6cd5d29c Mon Sep 17 00:00:00 2001 From: Smyja Date: Wed, 11 Feb 2026 22:42:31 +0100 Subject: [PATCH 1/2] feat: added karmada compatibility and scraper --- static/compatibilities.yaml | 39 ++++++++ static/compatibilities/karmada.yaml | 35 +++++++ static/compatibilities/manifest.yaml | 1 + utils/compatibility/scrapers/karmada.py | 127 ++++++++++++++++++++++++ 4 files changed, 202 insertions(+) create mode 100644 static/compatibilities/karmada.yaml create mode 100644 utils/compatibility/scrapers/karmada.py diff --git a/static/compatibilities.yaml b/static/compatibilities.yaml index d7b82299d6..96cde1e8ea 100644 --- a/static/compatibilities.yaml +++ b/static/compatibilities.yaml @@ -15793,3 +15793,42 @@ addons: chart_version: 0.29.6 images: [] name: kubescape-operator +- icon: https://raw.githubusercontent.com/karmada-io/karmada/master/docs/images/Karmada-logo-horizontal-color.png + git_url: https://github.com/karmada-io/karmada + release_url: https://github.com/karmada-io/karmada/releases/tag/v{vsn} + helm_repository_url: https://raw.githubusercontent.com/karmada-io/karmada/master/charts + versions: + - version: 1.16.0 + kube: ['1.34', '1.33', '1.32', '1.31', '1.30', '1.29', '1.28', '1.27', '1.26', + '1.25'] + requirements: [] + incompatibilities: [] + summary: null + chart_version: 1.16.0 + images: ['docker.io/bitnamisecure/kubectl:latest', 'docker.io/cfssl/cfssl:latest', + 'docker.io/karmada/karmada-aggregated-apiserver:v1.16.0', 'docker.io/karmada/karmada-controller-manager:v1.16.0', + 'docker.io/karmada/karmada-scheduler:v1.16.0', 'docker.io/karmada/karmada-webhook:v1.16.0', + 'registry.k8s.io/etcd:3.6.0-0', 'registry.k8s.io/kube-apiserver:v1.34.1', 'registry.k8s.io/kube-controller-manager:v1.34.1'] + - version: 1.15.0 + kube: ['1.33', '1.32', '1.31', '1.30', '1.29', '1.28', '1.27', '1.26', '1.25', + '1.24'] + requirements: [] + incompatibilities: [] + summary: null + chart_version: 1.15.0 + images: ['docker.io/bitnami/kubectl:latest', 'docker.io/cfssl/cfssl:latest', 'docker.io/karmada/karmada-aggregated-apiserver:v1.15.0', + 'docker.io/karmada/karmada-controller-manager:v1.15.0', 'docker.io/karmada/karmada-scheduler:v1.15.0', + 'docker.io/karmada/karmada-webhook:v1.15.0', 'registry.k8s.io/etcd:3.5.16-0', + 'registry.k8s.io/kube-apiserver:v1.31.3', 'registry.k8s.io/kube-controller-manager:v1.31.3'] + - version: 1.14.0 + kube: ['1.32', '1.31', '1.30', '1.29', '1.28', '1.27', '1.26', '1.25', '1.24', + '1.23'] + requirements: [] + incompatibilities: [] + summary: null + chart_version: 1.14.0 + images: ['docker.io/bitnami/kubectl:latest', 'docker.io/cfssl/cfssl:latest', 'docker.io/karmada/karmada-aggregated-apiserver:v1.14.0', + 'docker.io/karmada/karmada-controller-manager:v1.14.0', 'docker.io/karmada/karmada-scheduler:v1.14.0', + 'docker.io/karmada/karmada-webhook:v1.14.0', 'registry.k8s.io/etcd:3.5.16-0', + 'registry.k8s.io/kube-apiserver:v1.31.3', 'registry.k8s.io/kube-controller-manager:v1.31.3'] + name: karmada diff --git a/static/compatibilities/karmada.yaml b/static/compatibilities/karmada.yaml new file mode 100644 index 0000000000..36d2c2ae3c --- /dev/null +++ b/static/compatibilities/karmada.yaml @@ -0,0 +1,35 @@ +icon: https://raw.githubusercontent.com/karmada-io/karmada/master/docs/images/Karmada-logo-horizontal-color.png +git_url: https://github.com/karmada-io/karmada +release_url: https://github.com/karmada-io/karmada/releases/tag/v{vsn} +helm_repository_url: https://raw.githubusercontent.com/karmada-io/karmada/master/charts +versions: +- version: 1.16.0 + kube: ['1.34', '1.33', '1.32', '1.31', '1.30', '1.29', '1.28', '1.27', '1.26', '1.25'] + requirements: [] + incompatibilities: [] + summary: null + chart_version: 1.16.0 + images: ['docker.io/bitnamisecure/kubectl:latest', 'docker.io/cfssl/cfssl:latest', + 'docker.io/karmada/karmada-aggregated-apiserver:v1.16.0', 'docker.io/karmada/karmada-controller-manager:v1.16.0', + 'docker.io/karmada/karmada-scheduler:v1.16.0', 'docker.io/karmada/karmada-webhook:v1.16.0', + 'registry.k8s.io/etcd:3.6.0-0', 'registry.k8s.io/kube-apiserver:v1.34.1', 'registry.k8s.io/kube-controller-manager:v1.34.1'] +- version: 1.15.0 + kube: ['1.33', '1.32', '1.31', '1.30', '1.29', '1.28', '1.27', '1.26', '1.25', '1.24'] + requirements: [] + incompatibilities: [] + summary: null + chart_version: 1.15.0 + images: ['docker.io/bitnami/kubectl:latest', 'docker.io/cfssl/cfssl:latest', 'docker.io/karmada/karmada-aggregated-apiserver:v1.15.0', + 'docker.io/karmada/karmada-controller-manager:v1.15.0', 'docker.io/karmada/karmada-scheduler:v1.15.0', + 'docker.io/karmada/karmada-webhook:v1.15.0', 'registry.k8s.io/etcd:3.5.16-0', + 'registry.k8s.io/kube-apiserver:v1.31.3', 'registry.k8s.io/kube-controller-manager:v1.31.3'] +- version: 1.14.0 + kube: ['1.32', '1.31', '1.30', '1.29', '1.28', '1.27', '1.26', '1.25', '1.24', '1.23'] + requirements: [] + incompatibilities: [] + summary: null + chart_version: 1.14.0 + images: ['docker.io/bitnami/kubectl:latest', 'docker.io/cfssl/cfssl:latest', 'docker.io/karmada/karmada-aggregated-apiserver:v1.14.0', + 'docker.io/karmada/karmada-controller-manager:v1.14.0', 'docker.io/karmada/karmada-scheduler:v1.14.0', + 'docker.io/karmada/karmada-webhook:v1.14.0', 'registry.k8s.io/etcd:3.5.16-0', + 'registry.k8s.io/kube-apiserver:v1.31.3', 'registry.k8s.io/kube-controller-manager:v1.31.3'] diff --git a/static/compatibilities/manifest.yaml b/static/compatibilities/manifest.yaml index 5b4adc4112..a11e3e60c3 100644 --- a/static/compatibilities/manifest.yaml +++ b/static/compatibilities/manifest.yaml @@ -39,3 +39,4 @@ names: - rabbitmq-cluster-operator - kserve - kubescape-operator +- karmada diff --git a/utils/compatibility/scrapers/karmada.py b/utils/compatibility/scrapers/karmada.py new file mode 100644 index 0000000000..12035f14af --- /dev/null +++ b/utils/compatibility/scrapers/karmada.py @@ -0,0 +1,127 @@ +import re +from collections import OrderedDict + +from utils import ( + fetch_page, + get_chart_versions, + print_error, + update_compatibility_info, + validate_semver, +) + +APP_NAME = "karmada" +README_URL = "https://raw.githubusercontent.com/karmada-io/karmada/master/README.md" +HELM_REPO_URL = "https://raw.githubusercontent.com/karmada-io/karmada/master/charts" +TARGET_FILE = f"../../static/compatibilities/{APP_NAME}.yaml" +SUPPORTED_MARKERS = {"✓", "+", "✔"} + + +def extract_table_lines(markdown: str) -> list[str]: + if "## Kubernetes compatibility" not in markdown: + return [] + + section = markdown.split("## Kubernetes compatibility", 1)[1] + lines: list[str] = [] + for line in section.splitlines(): + stripped = line.strip() + if stripped.startswith("|"): + lines.append(stripped) + elif lines: + break + return lines + + +def parse_header(line: str) -> list[str]: + cells = [cell.strip() for cell in line.strip("|").split("|")] + kube_headers: list[str] = [] + for cell in cells[1:]: + match = re.search(r"(\d+\.\d+)", cell) + if match: + kube_headers.append(match.group(1)) + return kube_headers + + +def normalize_version(label: str) -> str | None: + match = re.search(r"(\d+\.\d+)", label) + if not match: + return None + + version = f"{match.group(1)}.0" + semver = validate_semver(version) + if not semver: + return None + return str(semver) + + +def parse_versions(markdown: str) -> list[OrderedDict]: + lines = extract_table_lines(markdown) + if len(lines) < 3: + return [] + + header = parse_header(lines[0]) + if not header: + return [] + + versions: list[OrderedDict] = [] + for row in lines[2:]: + stripped = row.replace("|", "").strip() + if not stripped or all(ch in "-:" for ch in stripped): + continue + + cells = [cell.strip() for cell in row.strip("|").split("|")] + if not cells: + continue + + version = normalize_version(cells[0]) + if not version: + continue + + kube_list: list[str] = [] + for kube, cell in zip(header, cells[1:]): + marker = cell.strip() + if any(symbol in marker for symbol in SUPPORTED_MARKERS): + kube_list.append(kube) + + if not kube_list: + continue + + kube_unique = sorted( + set(kube_list), + key=lambda v: tuple(map(int, v.split("."))), + reverse=True, + ) + + versions.append( + OrderedDict( + [ + ("version", version), + ("kube", kube_unique), + ("requirements", []), + ("incompatibilities", []), + ] + ) + ) + + return versions + + +def scrape(): + content = fetch_page(README_URL) + if not content: + print_error("Failed to download Karmada README.") + return + + markdown = content.decode("utf-8", errors="replace") + versions = parse_versions(markdown) + if not versions: + print_error("No Karmada compatibility data extracted.") + return + + chart_versions = get_chart_versions(APP_NAME) + if chart_versions: + for entry in versions: + chart_version = chart_versions.get(entry["version"]) + if chart_version: + entry["chart_version"] = chart_version + + update_compatibility_info(TARGET_FILE, versions) From be3773dd001b89da6f7c2d32a703c98102f12254 Mon Sep 17 00:00:00 2001 From: Smyja Date: Sun, 15 Feb 2026 21:30:12 +0100 Subject: [PATCH 2/2] Align compatibility addon order with manifest --- static/compatibilities.yaml | 78 ++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/static/compatibilities.yaml b/static/compatibilities.yaml index 5de3408a69..b8ffaaec6d 100644 --- a/static/compatibilities.yaml +++ b/static/compatibilities.yaml @@ -15874,45 +15874,6 @@ addons: chart_version: 0.29.6 images: [] name: kubescape-operator -- icon: https://raw.githubusercontent.com/karmada-io/karmada/master/docs/images/Karmada-logo-horizontal-color.png - git_url: https://github.com/karmada-io/karmada - release_url: https://github.com/karmada-io/karmada/releases/tag/v{vsn} - helm_repository_url: https://raw.githubusercontent.com/karmada-io/karmada/master/charts - versions: - - version: 1.16.0 - kube: ['1.34', '1.33', '1.32', '1.31', '1.30', '1.29', '1.28', '1.27', '1.26', - '1.25'] - requirements: [] - incompatibilities: [] - summary: null - chart_version: 1.16.0 - images: ['docker.io/bitnamisecure/kubectl:latest', 'docker.io/cfssl/cfssl:latest', - 'docker.io/karmada/karmada-aggregated-apiserver:v1.16.0', 'docker.io/karmada/karmada-controller-manager:v1.16.0', - 'docker.io/karmada/karmada-scheduler:v1.16.0', 'docker.io/karmada/karmada-webhook:v1.16.0', - 'registry.k8s.io/etcd:3.6.0-0', 'registry.k8s.io/kube-apiserver:v1.34.1', 'registry.k8s.io/kube-controller-manager:v1.34.1'] - - version: 1.15.0 - kube: ['1.33', '1.32', '1.31', '1.30', '1.29', '1.28', '1.27', '1.26', '1.25', - '1.24'] - requirements: [] - incompatibilities: [] - summary: null - chart_version: 1.15.0 - images: ['docker.io/bitnami/kubectl:latest', 'docker.io/cfssl/cfssl:latest', 'docker.io/karmada/karmada-aggregated-apiserver:v1.15.0', - 'docker.io/karmada/karmada-controller-manager:v1.15.0', 'docker.io/karmada/karmada-scheduler:v1.15.0', - 'docker.io/karmada/karmada-webhook:v1.15.0', 'registry.k8s.io/etcd:3.5.16-0', - 'registry.k8s.io/kube-apiserver:v1.31.3', 'registry.k8s.io/kube-controller-manager:v1.31.3'] - - version: 1.14.0 - kube: ['1.32', '1.31', '1.30', '1.29', '1.28', '1.27', '1.26', '1.25', '1.24', - '1.23'] - requirements: [] - incompatibilities: [] - summary: null - chart_version: 1.14.0 - images: ['docker.io/bitnami/kubectl:latest', 'docker.io/cfssl/cfssl:latest', 'docker.io/karmada/karmada-aggregated-apiserver:v1.14.0', - 'docker.io/karmada/karmada-controller-manager:v1.14.0', 'docker.io/karmada/karmada-scheduler:v1.14.0', - 'docker.io/karmada/karmada-webhook:v1.14.0', 'registry.k8s.io/etcd:3.5.16-0', - 'registry.k8s.io/kube-apiserver:v1.31.3', 'registry.k8s.io/kube-controller-manager:v1.31.3'] - name: karmada - icon: https://assets.dynatrace.com/global/resources/Signet_Logo_RGB_CP_512x512px.png git_url: https://github.com/Dynatrace/dynatrace-operator release_url: https://github.com/Dynatrace/dynatrace-operator/releases/tag/v{vsn} @@ -15975,3 +15936,42 @@ addons: chart_version: 0.6.0 images: [] name: dynatrace-operator +- icon: https://raw.githubusercontent.com/karmada-io/karmada/master/docs/images/Karmada-logo-horizontal-color.png + git_url: https://github.com/karmada-io/karmada + release_url: https://github.com/karmada-io/karmada/releases/tag/v{vsn} + helm_repository_url: https://raw.githubusercontent.com/karmada-io/karmada/master/charts + versions: + - version: 1.16.0 + kube: ['1.34', '1.33', '1.32', '1.31', '1.30', '1.29', '1.28', '1.27', '1.26', + '1.25'] + requirements: [] + incompatibilities: [] + summary: null + chart_version: 1.16.0 + images: ['docker.io/bitnamisecure/kubectl:latest', 'docker.io/cfssl/cfssl:latest', + 'docker.io/karmada/karmada-aggregated-apiserver:v1.16.0', 'docker.io/karmada/karmada-controller-manager:v1.16.0', + 'docker.io/karmada/karmada-scheduler:v1.16.0', 'docker.io/karmada/karmada-webhook:v1.16.0', + 'registry.k8s.io/etcd:3.6.0-0', 'registry.k8s.io/kube-apiserver:v1.34.1', 'registry.k8s.io/kube-controller-manager:v1.34.1'] + - version: 1.15.0 + kube: ['1.33', '1.32', '1.31', '1.30', '1.29', '1.28', '1.27', '1.26', '1.25', + '1.24'] + requirements: [] + incompatibilities: [] + summary: null + chart_version: 1.15.0 + images: ['docker.io/bitnami/kubectl:latest', 'docker.io/cfssl/cfssl:latest', 'docker.io/karmada/karmada-aggregated-apiserver:v1.15.0', + 'docker.io/karmada/karmada-controller-manager:v1.15.0', 'docker.io/karmada/karmada-scheduler:v1.15.0', + 'docker.io/karmada/karmada-webhook:v1.15.0', 'registry.k8s.io/etcd:3.5.16-0', + 'registry.k8s.io/kube-apiserver:v1.31.3', 'registry.k8s.io/kube-controller-manager:v1.31.3'] + - version: 1.14.0 + kube: ['1.32', '1.31', '1.30', '1.29', '1.28', '1.27', '1.26', '1.25', '1.24', + '1.23'] + requirements: [] + incompatibilities: [] + summary: null + chart_version: 1.14.0 + images: ['docker.io/bitnami/kubectl:latest', 'docker.io/cfssl/cfssl:latest', 'docker.io/karmada/karmada-aggregated-apiserver:v1.14.0', + 'docker.io/karmada/karmada-controller-manager:v1.14.0', 'docker.io/karmada/karmada-scheduler:v1.14.0', + 'docker.io/karmada/karmada-webhook:v1.14.0', 'registry.k8s.io/etcd:3.5.16-0', + 'registry.k8s.io/kube-apiserver:v1.31.3', 'registry.k8s.io/kube-controller-manager:v1.31.3'] + name: karmada