"""Generate Kubernetes manifests for a deployed agent. Targets the existing local cluster: namespace ``agents``, registry at ``localhost:30500``, traefik ingress at ``.127-0-0-1.nip.io``. """ from __future__ import annotations from typing import Any import yaml from ..agent import A2AAgent NAMESPACE = "agents" INGRESS_HOST_TEMPLATE = "{name}.127-0-0-1.nip.io" def render_manifests( agent_cls: type[A2AAgent], *, image: str, public: bool = True, ) -> str: """Return a multi-doc YAML string ready for ``kubectl apply -f -``.""" rt = agent_cls.runtime() name = agent_cls.name docs: list[dict[str, Any]] = [] docs.append( { "apiVersion": "v1", "kind": "Namespace", "metadata": {"name": NAMESPACE}, } ) docs.append( { "apiVersion": "apps/v1", "kind": "Deployment", "metadata": { "name": name, "namespace": NAMESPACE, "labels": { "app": name, "a2a/version": agent_cls.version, "a2a/lifecycle": rt.lifecycle.value, }, }, "spec": { "replicas": 1, "selector": {"matchLabels": {"app": name}}, "template": { "metadata": {"labels": {"app": name}}, "spec": { "containers": [ { "name": "agent", "image": image, "imagePullPolicy": "Always", "ports": [{"containerPort": 8000, "name": "http"}], "readinessProbe": { "httpGet": {"path": "/healthz", "port": 8000}, "initialDelaySeconds": 2, "periodSeconds": 5, }, "livenessProbe": { "httpGet": {"path": "/healthz", "port": 8000}, "initialDelaySeconds": 10, "periodSeconds": 15, }, "resources": { "requests": { "cpu": rt.resources.cpu, "memory": rt.resources.memory, }, "limits": { "cpu": rt.resources.cpu, "memory": rt.resources.memory, }, }, } ] }, }, }, } ) docs.append( { "apiVersion": "v1", "kind": "Service", "metadata": {"name": name, "namespace": NAMESPACE}, "spec": { "type": "ClusterIP", "selector": {"app": name}, "ports": [{"name": "http", "port": 80, "targetPort": 8000}], }, } ) if public: docs.append( { "apiVersion": "networking.k8s.io/v1", "kind": "Ingress", "metadata": {"name": name, "namespace": NAMESPACE}, "spec": { "rules": [ { "host": INGRESS_HOST_TEMPLATE.format(name=name), "http": { "paths": [ { "path": "/", "pathType": "Prefix", "backend": { "service": { "name": name, "port": {"number": 80}, } }, } ] }, } ] }, } ) return "---\n".join(yaml.safe_dump(d, sort_keys=False) for d in docs)