diff --git a/bin/list_app_versions.py b/bin/list_app_versions.py new file mode 100755 index 0000000..44bfac1 --- /dev/null +++ b/bin/list_app_versions.py @@ -0,0 +1,85 @@ +#! /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", + "targetRevision": 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["spec"]["source"]["targetRevision"] + latest = get_latest_version(repo_url, chart) + + print("{:<20}{:<15}{:<10}".format(name, installed, latest)) + + +if __name__ == "__main__": + main()