commit efdaf72b360f98bb5f3431c1f452e632227472da Author: Waylon S. Walker Date: Thu Apr 24 14:12:37 2025 -0500 init diff --git a/main.py b/main.py new file mode 100755 index 0000000..d9f45e7 --- /dev/null +++ b/main.py @@ -0,0 +1,90 @@ +#!/usr/bin/env -S uv run --quiet --script +# /// script +# requires-python = ">=3.12" +# dependencies = [ +# "kubernetes", +# "typer", +# ] +# /// + +import typer +from kubernetes import client, config +from typing import Optional + +app = typer.Typer( + help="Analyze Kubernetes Ingress resources and list hosts with annotations." +) + + +def load_k8s_config(kubeconfig: Optional[str]): + """ + Load Kubernetes configuration. If `kubeconfig` is provided, use it; otherwise + try the default kubeconfig, falling back to in-cluster config. + """ + try: + if kubeconfig: + config.load_kube_config(config_file=kubeconfig) + else: + config.load_kube_config() + except Exception: + config.load_incluster_config() + + +@app.command() +def analyze( + namespace: Optional[str] = typer.Option( + None, + "--namespace", + "-n", + help="Namespace to analyze (defaults to all namespaces)", + ), + kubeconfig: Optional[str] = typer.Option( + None, "--kubeconfig", "-k", help="Path to kubeconfig file" + ), +): + """ + Fetch Ingress resources and print for each: + - Namespace and name + - Hosts defined in .spec.rules + - Annotations on the Ingress + """ + load_k8s_config(kubeconfig) + api = client.NetworkingV1Api() + if namespace: + ingress_list = api.list_namespaced_ingress(namespace) + else: + ingress_list = api.list_ingress_for_all_namespaces() + output = [] + for ing in ingress_list.items: + ing_output = {} + ns = ing.metadata.namespace + name = ing.metadata.name + annotations = ing.metadata.annotations or {} + hosts = [rule.host for rule in (ing.spec.rules or []) if rule.host] + if "kompose.cmd" not in annotations: + continue + + # typer.echo(f"{ns}/{name}") + ing_output["namespace"] = ns + ing_output["name"] = name + # typer.echo(f" hosts: {', '.join(hosts) if hosts else ''}") + ing_output["hosts"] = hosts + + ing_output["annotations"] = {} + if annotations: + # typer.echo(" annotations:") + for key, val in annotations.items(): + if "last-applied-configuration" not in key: + ing_output["annotations"][key] = val + # typer.echo(f" {key}: {val}") + + output.append(ing_output) + # typer.echo() + + import json + + typer.echo(json.dumps(output, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + app()