Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions static/compatibilities.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
35 changes: 35 additions & 0 deletions static/compatibilities/karmada.yaml
Original file line number Diff line number Diff line change
@@ -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']
1 change: 1 addition & 0 deletions static/compatibilities/manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ names:
- rabbitmq-cluster-operator
- kserve
- kubescape-operator
- karmada
127 changes: 127 additions & 0 deletions utils/compatibility/scrapers/karmada.py
Original file line number Diff line number Diff line change
@@ -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)
Loading