#! /usr/bin/env python # -*- encoding: utf-8; py-indent-offset: 4 -*- # Author: Sebastian Mark # CC-BY-SA (https://creativecommons.org/licenses/by-sa/4.0/deed.de) # for civil use only import os from urllib.request import Request, urlopen import pandas as pd import yaml def kubectl(cmd: str) -> str: cmd = f"kubectl -n argocd {cmd}" return os.popen(cmd).read() def get_latest_version(repo_url: str, chart: str) -> str: req = Request( repo_url + "/index.yaml", headers={"User-Agent": "Mozilla/5.0"}, ) with urlopen(req) as response: body = response.read() repos = yaml.safe_load(body) chart_df = pd.DataFrame(repos["entries"][chart]) chart_df = chart_df[ ~chart_df.version.str.contains("alpha") & ~chart_df.version.str.contains("beta") ] # remove alpha versions return chart_df.version.iloc[0] def get_argo_as_app() -> dict: cm = kubectl("get configmaps argocd-cm -o yaml") cm_formatted = yaml.safe_load(cm) version = cm_formatted["metadata"]["labels"]["helm.sh/chart"].lstrip("argo-cd-") return dict( { "metadata": { "name": "argocd", }, "spec": { "source": { "chart": "argo-cd", "repoURL": "https://argoproj.github.io/argo-helm", }, }, "status": { "sync": { "revision": version, } }, } ) def get_apps() -> list: apps = kubectl("get applications -o yaml") app_list = yaml.safe_load(apps)["items"] app_list.append(get_argo_as_app()) return app_list def main(): print("{:<20}{:<15}{:<10}".format("name", "installed", "latest")) for app in get_apps(): try: app["spec"]["source"]["chart"] # skip non-helm apps except KeyError: continue name = app["metadata"]["name"] chart = app["spec"]["source"]["chart"] repo_url = app["spec"]["source"]["repoURL"] installed = app["status"]["sync"]["revision"] latest = get_latest_version(repo_url, chart) print("{:<20}{:<15}{:<10}".format(name, installed, latest)) if __name__ == "__main__": main()