Radar automatically discovers and displays any Custom Resource Definition (CRD) in your cluster — no configuration needed. For popular tools, Radar provides dedicated detail views, topology edges, smart table columns, and AI-optimized summaries for seamless integration.
Karpenter is the standard node autoscaler for Kubernetes, replacing Cluster Autoscaler on AWS (EKS), Azure (AKS NAP), and generic clusters.
Capacity view: When Radar discovers Karpenter NodePools (and the current identity can list them), a cluster-wide Capacity view appears in navigation — a read-only diagnosis surface across four screens:
- Overview — fleet KPIs with claim lifecycle detail, a cluster scheduling-capacity bar (scheduled requests vs allocatable, in-flight claim capacity beyond the allocatable edge, pending demand as a not-to-scale count), prioritized operational signals, and the NodePool inventory
- NodePool detail — the capacity ledger (configured limit, provisioned, headroom, allocatable, scheduled requests, unallocated, actual usage) plus claim lifecycle, fleet composition, and workload attribution
- Demand — pending pods grouped by scheduling signature, each group evaluated against every NodePool's declared constraints with per-predicate evidence
- Activity — provisioning, disruption, interruption, and termination episodes classified from Karpenter's exact event vocabulary
Every quantity carries per-value certainty (= ≥ ≤ ?): unavailable is never rendered as zero, partial is never rendered as exact, and scheduling capacity is kept structurally distinct from actual usage — Karpenter schedules on pod requests, so usage is an efficiency signal, never scheduler headroom. Issues, Pending-pod drawers, and the Home posture card deep-link into the right diagnosis. Full reference: Capacity documentation.
Topology: Full provisioning chain — NodePool → NodeClaim → Node → Pod. See which NodePool owns which NodeClaims, which Nodes they provisioned, and what Pods are running on them. NodePool → NodeClass edges show the provider-specific configuration each pool uses.
Karpenter in Topology View — NodePool → NodeClaim provisioning chain
NodePool Detail View:
- Status conditions (Ready)
- Clickable NodeClass reference (EC2NodeClass, AKSNodeClass, or generic)
- Resource limits (CPU, memory)
- Disruption policy and consolidation settings
- Disruption budget reasons, termination grace period, and requirement
minValues - Instance requirements (types, zones, architectures)
- Template labels applied to provisioned nodes
NodePool Detail View — Status, related NodeClaims, and full specification
NodeClaim Detail View:
- Provisioning timeline with timestamps
- Status conditions (Initialized, Launched, Registered, Ready)
- Instance type, capacity, and zone
- Requirements (instance types, architectures, OS)
- Clickable Node and NodeClass references
NodeClass Detail View (EC2NodeClass, AKSNodeClass, etc.):
- AMI selector terms and aliases
- Block device mappings (volume type, size, encryption)
- IAM role configuration
- Subnet and security group discovery tags
- Instance metadata options (IMDS configuration)
Resource Browser: Smart columns show status, NodeClass reference, limits, and disruption policy at a glance.
NodePool Resource Browser — Status, NodeClass, limits, and disruption policy at a glance
| CRD | Group | Topology | Detail View | AI Summary |
|---|---|---|---|---|
| NodePool | karpenter.sh/v1 |
Yes | Yes | Yes |
| NodeClaim | karpenter.sh/v1 |
Yes | Yes | Yes |
| EC2NodeClass | karpenter.k8s.aws/v1 |
Yes | Yes | Yes |
| AKSNodeClass | karpenter.azure.com/v1alpha2 |
Yes | Generic | Yes |
| GCENodeClass | karpenter.k8s.gcp/v1alpha1 |
Yes | Generic | Yes |
All provider-specific NodeClass variants are automatically detected and supported.
Cluster API is the Kubernetes sub-project for declarative cluster lifecycle management. Used by platform teams to provision and manage workload clusters.
Topology: Full CAPI ownership chain — ClusterClass → Cluster → KubeadmControlPlane → Machine → Node, and Cluster → MachineDeployment → MachineSet → Machine → Node. MachineHealthCheck → Cluster protection edges. Machine → Node edges use status.nodeRef (semantic, not owner-ref).
Cluster Detail View:
- Phase, version, cluster class, control plane endpoint
- Control plane and worker replica counts (v1beta2-aware)
- Control plane and infrastructure references (clickable)
- ClusterClass topology section (worker MachineDeployments table)
- "Connect to Cluster" button — auto-connects Radar to the workload cluster
- "Download Kubeconfig" button
- Conditions
Machine Detail View:
- Phase, role (Control Plane / Worker), version, provider ID
- Clickable Node reference (via status.nodeRef)
- Addresses table, node info (OS, architecture, kernel, kubelet)
- Bootstrap and infrastructure references
MachineDeployment Detail View:
- Phase, replicas (desired/ready/available/up-to-date), strategy
- Version, cluster name
- Machine template references
- Owned machines label hint (copyable)
KubeadmControlPlane Detail View:
- Replicas, version, initialized status (v1beta2-aware)
- Machine template with drain/volume detach/deletion timeouts
- Kubeadm config highlights (cert SANs)
- Last remediation info
- Owned machines label hint
ClusterClass Detail View:
- Infrastructure, control plane, worker topology tables
- Variables with schema types
- Patches with definitions and enabledIf expressions
MachineHealthCheck Detail View:
- Expected/healthy machine counts, remediations allowed
- Label selector display
- Unhealthy conditions tables (v1beta1 + v1beta2 formats)
- Remediation template
Additional renderers: MachineSet, MachinePool, MachineDrainRule, KubeadmConfig/Template
Resource Browser: Smart columns for all CAPI kinds — phase badges, replica counts, cluster names, roles, versions.
Topology-controlled badge: Resources managed by ClusterClass (label topology.cluster.x-k8s.io/owned) show a warning banner.
Fleet topology mode: Dedicated "Fleet" view filters to CAPI and infrastructure provider resources only, giving a clean cluster-management view without application workload noise. Groups start expanded by default.
Resource browser with smart columns per CAPI kind — Provider detection, phase badges, replica counts:
Cluster detail view with Connect to Cluster and Download Kubeconfig actions, provider detection, and clickable references to infrastructure resources:
Radar has first-class renderers for AWS (CAPA), GCP (CAPG), and Azure (CAPZ) infrastructure provider resources. These surface provider-specific operational data — instance types, scaling config, VPC/subnet topology, managed service addons — that would otherwise be buried in raw YAML.
AWS EKS control plane — VPC topology with subnets (Public/Private badges), security groups, EKS addons, IAM roles:
GCP GKE control plane — project, location, release channel, and conditions timeline with left-aligned timestamps:
Managed machine pools: Instance/VM types, scaling config (autoscaling min/max), capacity type badges (On-Demand/Spot), node management (auto-repair/upgrade), labels and taints.
Azure AKS: Location, resource group, SKU tier, network plugin/policy, System/User mode badges, Regular/Spot priority, availability zones.
Individual machines: Instance type/state badges, provider IDs, addresses, conditions.
Templates and cluster stubs: Lightweight renderers for instance templates (with resolved capacity) and cluster infrastructure stubs (endpoint + failure domains).
| CRD | Group | Topology | Detail View | AI Summary |
|---|---|---|---|---|
| Cluster | cluster.x-k8s.io |
Yes | Yes | Yes |
| ClusterClass | cluster.x-k8s.io |
Yes | Yes | Yes |
| Machine | cluster.x-k8s.io |
Yes | Yes | Yes |
| MachineSet | cluster.x-k8s.io |
Yes | Yes | Yes |
| MachineDeployment | cluster.x-k8s.io |
Yes | Yes | Yes |
| MachinePool | cluster.x-k8s.io |
Yes | Yes | Yes |
| MachineHealthCheck | cluster.x-k8s.io |
Yes | Yes | Yes |
| MachineDrainRule | cluster.x-k8s.io |
No | Yes | No |
| KubeadmControlPlane | controlplane.cluster.x-k8s.io |
Yes | Yes | Yes |
| KubeadmControlPlaneTemplate | controlplane.cluster.x-k8s.io |
No | Generic | No |
| KubeadmConfig | bootstrap.cluster.x-k8s.io |
No | Yes | No |
| KubeadmConfigTemplate | bootstrap.cluster.x-k8s.io |
No | Generic | No |
| AWSManagedControlPlane | controlplane.cluster.x-k8s.io |
Yes | Yes | No |
| AWSManagedMachinePool | infrastructure.cluster.x-k8s.io |
Yes | Yes | No |
| AWSMachine | infrastructure.cluster.x-k8s.io |
Yes | Yes | No |
| AWSMachineTemplate | infrastructure.cluster.x-k8s.io |
No | Yes | No |
| AWSManagedCluster | infrastructure.cluster.x-k8s.io |
No | Yes | No |
KEDA (Kubernetes Event-Driven Autoscaling) is a CNCF graduated project that scales workloads based on external event sources — queues, streams, cron schedules, Prometheus metrics, and 60+ other triggers.
Topology: ScaledObject → target workload (Deployment, StatefulSet, or Rollout). See which workloads are managed by KEDA and trace the scaling relationship.
KEDA in Topology View — ScaledObject → Deployment → Pod scaling chain
ScaledObject Detail View:
- Status conditions (Ready, Active, Paused, Fallback)
- Target workload reference
- Min/Max/Idle replica configuration
- Polling interval and cooldown period
- Trigger list with type and metadata
- Generated HPA name
- Pause state detection (supports all 3 annotation variants)
ScaledObject Detail View — Status conditions, target workload, triggers, and replica configuration
ScaledJob Detail View:
- Status conditions
- Job target reference
- Scaling strategy (default, custom, accurate, eager)
- Success/failure limits
- Trigger list
TriggerAuthentication Detail View:
- Pod identity provider and configuration
- Secret references with linked Secret navigation
- Environment variable mappings
- External secret providers (HashiCorp Vault, Azure Key Vault, AWS Secrets Manager)
Resource Browser: Smart columns show status, target workload, trigger count, and replica range at a glance.
ScaledObject Resource Browser — Status, target workload, trigger count, and replica range
| CRD | Group | Topology | Detail View | AI Summary |
|---|---|---|---|---|
| ScaledObject | keda.sh/v1alpha1 |
Yes | Yes | Yes |
| ScaledJob | keda.sh/v1alpha1 |
Yes | Yes | Yes |
| TriggerAuthentication | keda.sh/v1alpha1 |
— | Yes | Yes |
| ClusterTriggerAuthentication | keda.sh/v1alpha1 |
— | Yes | Yes |
VPA automatically adjusts CPU and memory requests/limits for pods based on observed usage.
Topology: VPA nodes appear in the Resources view with EdgeUses edges to target workloads, grouped in the Scalers section alongside HPA and KEDA.
Detail View: Target workload, update mode, per-container resource recommendations (target, lower bound, upper bound, uncapped), resource policy, and conditions.
Problem Detection: Alerts for unsupported configurations, missing recommendations, and low confidence scores.
| CRD | Group | Topology | Detail View | AI Summary |
|---|---|---|---|---|
| VerticalPodAutoscaler | autoscaling.k8s.io/v1 |
Yes | Yes | — |
Gateway API is the next-generation Kubernetes networking API, replacing Ingress with more expressive routing, traffic splitting, and multi-tenant support.
Topology: Full network path — GatewayClass → Gateway → HTTPRoute/GRPCRoute/TCPRoute/TLSRoute → Service → Pod. Visualize how traffic flows from the gateway controller through routes to your backend services.
Gateway API in Topology View — GatewayClass → Gateway → HTTPRoute → Service traffic path
Gateway Detail View: Listeners, addresses, attached routes, and status conditions.
GatewayClass Detail View: Controller name, description, parameters reference, and status conditions.
HTTPRoute Detail View: Rules with path/header matching, backend references, filters, and weights.
GRPCRoute Detail View: Service/method matching, backend references, and filters.
| CRD | Group | Topology | Detail View | AI Summary |
|---|---|---|---|---|
| GatewayClass | gateway.networking.k8s.io/v1 |
Yes | Yes | Yes |
| Gateway | gateway.networking.k8s.io/v1 |
Yes | Yes | Yes |
| HTTPRoute | gateway.networking.k8s.io/v1 |
Yes | Yes | Yes |
| GRPCRoute | gateway.networking.k8s.io/v1 |
Yes | Yes | Yes |
| TCPRoute | gateway.networking.k8s.io/v1alpha2 |
Yes | Yes | Yes |
| TLSRoute | gateway.networking.k8s.io/v1alpha2 |
Yes | Yes | Yes |
Traefik is a modern reverse proxy and ingress controller for Kubernetes, with dynamic configuration, middleware chains, and advanced traffic management via CRDs.
Topology: Full Traefik routing path — IngressRoute → Middleware → Service (or TraefikService → Service) with TLS and transport configuration edges. See how traffic flows from entrypoints through middleware chains and weighted/mirroring TraefikServices to backend Kubernetes Services. Both Resources and Traffic view modes are supported.
IngressRoute / IngressRouteTCP / IngressRouteUDP Detail View:
- Entry points and TLS configuration (secret, cert resolver, TLS options/stores)
- Route match expressions with priority and kind badges
- Per-route services with port, weight, and ServersTransport links
- Per-route middleware references with cross-namespace indicators
- Aggregated middleware chain with numbered ordering
- Alert banners for no-route or no-service configurations
Resource Browser: Smart columns show entry points, hosts (extracted from match expressions), route summaries, TLS status, and middleware counts. All 10 Traefik kinds have dedicated table columns — Middleware shows type, TraefikService shows type and targets, ServersTransport shows insecure/serverName, TLSOption shows min TLS version.
Middleware / MiddlewareTCP Detail View: type-aware rendering — chain links its member middlewares, auth middlewares (basicAuth/digestAuth/forwardAuth) show secret references only, never values, errors shows its service and status mapping, and unknown/plugin types fall back to a key/value view with nested credential keys redacted.
TraefikService Detail View: weighted backends with weight bars, mirroring (primary plus mirrors with percentages), and the load-balancing strategy.
TLSOption Detail View: minimum/maximum TLS versions, cipher suites, and client-auth configuration.
ServersTransport / ServersTransportTCP Detail View: SNI, an insecureSkipVerify warning banner, CA/client-cert secret references, and timeouts.
Secret safety: inline credentials in a Traefik CRD spec are redacted in the AI/MCP context (get_resource) — credential keys and high-confidence secret patterns are masked — and the Middleware detail renderer shows secret references only, never values. Reference names (secretName, basicAuth.secret, rootCAsSecrets) are preserved so you can still diagnose a bad reference. The raw YAML view still shows the object as stored in the cluster.
Traefik ships no admission webhook or linter, so a typo'd reference is accepted silently and the route or middleware just doesn't do what you wrote. Radar's Cluster Audit catches the common dangling-reference cases as Reliability checks:
| Check | What it catches |
|---|---|
traefikRouteMissingService |
An IngressRoute referencing a Service or TraefikService that doesn't exist |
traefikRouteMissingMiddleware |
An IngressRoute referencing a Middleware that doesn't exist |
traefikChainMissingMiddleware |
A chain Middleware listing a member Middleware that doesn't exist |
traefikErrorsMissingService |
An errors Middleware whose errors.service references a Service that doesn't exist |
These checks are inventory-authoritative: a "missing X" finding is asserted only when that target kind is served by a cluster-wide synced informer, so a namespace-scoped (RBAC-limited) cache skips the check rather than fabricating a false positive. Matching is group-aware — a traefik.io reference is not satisfied by a traefik.containo.us object — and cross-namespace references resolve correctly.
| CRD | Group | Topology | Detail View | AI Summary |
|---|---|---|---|---|
| IngressRoute | traefik.io/v1alpha1 |
Yes | Yes | — |
| IngressRouteTCP | traefik.io/v1alpha1 |
Yes | Yes | — |
| IngressRouteUDP | traefik.io/v1alpha1 |
Yes | Yes | — |
| Middleware | traefik.io/v1alpha1 |
Yes | Yes | — |
| MiddlewareTCP | traefik.io/v1alpha1 |
Yes | Yes | — |
| TraefikService | traefik.io/v1alpha1 |
Yes | Yes | — |
| ServersTransport | traefik.io/v1alpha1 |
Yes | Yes | — |
| ServersTransportTCP | traefik.io/v1alpha1 |
Yes | Yes | — |
| TLSOption | traefik.io/v1alpha1 |
Yes | Yes | — |
| TLSStore | traefik.io/v1alpha1 |
Yes | Generic | — |
The legacy traefik.containo.us API group (pre-v2.11) is warm-listed alongside traefik.io so older clusters don't pay first-list latency.
Contour is a Kubernetes ingress controller using Envoy proxy, providing a powerful HTTPProxy CRD with route delegation, weighted routing, TLS termination, and TCP proxying.
Topology: Full Contour routing path — HTTPProxy (root) → HTTPProxy (child, via delegation) → Service, with TLS secret configuration edges. Root proxies with spec.virtualhost appear as entry points; child proxies referenced via spec.includes are connected via delegation edges. Both Resources and Traffic view modes are supported.
Contour in Topology View — HTTPProxy → Service routing with delegation
HTTPProxy Detail View:
- Status banner for invalid or orphaned proxies
- Virtual host FQDN and TLS configuration with clickable Secret links
- Routes with prefix/header conditions and backend services (name, port, weight)
- Delegation includes with cross-namespace indicators and condition prefixes
- TCP proxy services for passthrough configurations
- Status conditions (Valid/Invalid/Orphaned)
Resource Browser: Smart columns show FQDN, route count, include count, TLS status (shield icon), and validity status at a glance.
| CRD | Group | Topology | Detail View | AI Summary |
|---|---|---|---|---|
| HTTPProxy | projectcontour.io/v1 |
Yes | Yes | Yes |
cert-manager automates TLS certificate management — issuing, renewing, and revoking certificates from Let's Encrypt, Vault, Venafi, and other issuers.
Topology: Certificate → Issuer/ClusterIssuer edges show which issuer manages each certificate. The full provisioning chain (Certificate → CertificateRequest → Order → Challenge) is connected via owner references.
cert-manager in Topology View — Certificate → CertificateRequest provisioning chain
Certificate Detail View:
- Status conditions (Ready) with color-coded expiry warnings
- Validity period with progress bar (green → yellow → red as expiry approaches)
- Subject, DNS names, issuer reference
- Renewal time and last failure
Dashboard: Certificate health card showing healthy/warning/critical/expired certificate counts across all namespaces.
TLS Secret Parsing: Click any TLS Secret to see the X.509 certificate details — subject, issuer, validity dates, SANs — parsed directly from the secret data.
Certificate Detail View — Validity progress bar, DNS names, issuer reference, and status conditions
Certificate Resource Browser — Ready status, domains, issuer, and expiry date at a glance
| CRD | Group | Topology | Detail View | AI Summary |
|---|---|---|---|---|
| Certificate | cert-manager.io/v1 |
Yes | Yes | — |
| CertificateRequest | cert-manager.io/v1 |
Yes | Yes | — |
| Issuer | cert-manager.io/v1 |
Yes | Yes | — |
| ClusterIssuer | cert-manager.io/v1 |
Yes | Yes | — |
| Order | acme.cert-manager.io/v1 |
Yes | Yes | — |
| Challenge | acme.cert-manager.io/v1 |
Yes | Yes | — |
Prometheus Operator simplifies Prometheus setup on Kubernetes, providing CRDs for defining monitoring targets, alerting rules, and scrape configurations declaratively.
ServiceMonitor Detail View:
- Status conditions
- Job label and scrape endpoint configuration (port, path, interval, scheme)
- Service selector (matchLabels)
- Namespace selector scope
PrometheusRule Detail View:
- Rule group breakdown with per-group rule counts
- Alert rules vs recording rules summary
- Group evaluation intervals
PodMonitor Detail View:
- Pod metrics endpoint configuration (port, path, interval, scheme)
- Pod selector (matchLabels)
- Namespace selector scope
Resource Browser: Smart columns show status, endpoint count, selectors, and job labels at a glance.
| CRD | Group | Topology | Detail View | AI Summary |
|---|---|---|---|---|
| ServiceMonitor | monitoring.coreos.com/v1 |
Service selection and scrape configuration | Yes | — |
| PodMonitor | monitoring.coreos.com/v1 |
Pod selection and scrape configuration | Yes | — |
| PrometheusRule | monitoring.coreos.com/v1 |
— | Yes | — |
| Alertmanager | monitoring.coreos.com/v1 |
— | Generic | — |
Trivy Operator continuously scans your cluster for vulnerabilities, misconfigurations, exposed secrets, and license compliance issues.
VulnerabilityReport Detail View: Severity breakdown (Critical/High/Medium/Low), affected images, and CVE counts.
ConfigAuditReport Detail View: Pass/fail checks with severity levels.
Resource Browser: Smart columns show severity counts and scan status at a glance.
| CRD | Group | Topology | Detail View | AI Summary |
|---|---|---|---|---|
| VulnerabilityReport | aquasecurity.github.io/v1alpha1 |
— | Yes | — |
| ConfigAuditReport | aquasecurity.github.io/v1alpha1 |
— | Yes | — |
| ExposedSecretReport | aquasecurity.github.io/v1alpha1 |
— | Yes | — |
| ClusterComplianceReport | aquasecurity.github.io/v1alpha1 |
— | Yes | — |
| SbomReport | aquasecurity.github.io/v1alpha1 |
— | Yes | — |
| RbacAssessmentReport | aquasecurity.github.io/v1alpha1 |
— | Yes | — |
| ClusterRbacAssessmentReport | aquasecurity.github.io/v1alpha1 |
— | Yes | — |
| InfraAssessmentReport | aquasecurity.github.io/v1alpha1 |
— | Yes | — |
| ClusterInfraAssessmentReport | aquasecurity.github.io/v1alpha1 |
— | Yes | — |
| ClusterSbomReport | aquasecurity.github.io/v1alpha1 |
— | Yes | — |
Sealed Secrets encrypts Kubernetes Secrets so they can be safely stored in Git. The controller decrypts them in-cluster at deploy time.
Topology: SealedSecret → Secret → workload when Secret metadata is visible, or SealedSecret → workload when Secret reads are restricted. Only SealedSecrets that configure a visible workload are included.
SealedSecret Detail View: Encrypted data keys, template metadata, and the target Secret's scope and namespace.
| CRD | Group | Topology | Detail View | AI Summary |
|---|---|---|---|---|
| SealedSecret | bitnami.com/v1alpha1 |
Yes | Yes | — |
See the main README for the user-facing overview. This section covers integration coverage and capabilities.
| CRD | Group | Topology | Detail View | AI Summary |
|---|---|---|---|---|
| GitRepository | source.toolkit.fluxcd.io/v1 |
Yes | Yes | — |
| OCIRepository | source.toolkit.fluxcd.io/v1beta2 |
Yes | Yes | — |
| HelmRepository | source.toolkit.fluxcd.io/v1 |
Yes | Yes | — |
| Kustomization | kustomize.toolkit.fluxcd.io/v1 |
Yes | Yes | Yes |
| HelmRelease | helm.toolkit.fluxcd.io/v2 |
Yes | Yes | Yes |
| Alert | notification.toolkit.fluxcd.io/v1beta3 |
— | Yes | — |
Workflow operations: Reconcile, Reconcile-with-source (Kustomization/HelmRelease), Suspend/Resume.
Diagnosis: Conditions extracted to issues (Ready=False, Stalled=True, Reconciling=True). Per-resource diff and recent events not yet available for Flux (HelmRelease-installed resources don't carry last-applied-configuration; tracked in #601).
| CRD | Group | Topology | Detail View | AI Summary |
|---|---|---|---|---|
| Application | argoproj.io/v1alpha1 |
Yes | Yes | Yes |
| ApplicationSet | argoproj.io/v1alpha1 |
— | Generic | — |
| AppProject | argoproj.io/v1alpha1 |
— | Generic | — |
Workflow operations: Sync (with options dialog: prune, dry-run, apply-only, force, replace, server-side apply, sync-options), Refresh, Hard refresh, Terminate, Suspend/Resume auto-sync, Rollback to historical revision, Selective sync of marked resources.
Diagnosis:
- Per-resource field diff computed from each resource's
kubectl.kubernetes.io/last-applied-configurationannotation vs live spec — works for any Argo client-side-applied resource without calling the Argo API - Recent events surfaced inline per managed resource (5 most recent, namespace-RBAC-filtered)
- Stuck-drift-loop detector — flags
sync=OutOfSync ∧ opPhase=Succeeded ∧ auto-sync on ∧ reconciledAt<30minwith the likely cause (mutating webhook, sibling controller, schema migration) - Manual-drift detector — calls out OutOfSync apps with auto-sync disabled
- Argo Application conditions extracted to issues (ComparisonError, OrphanedResourceWarning, etc.) with type-aware severity and per-condition action text
- Operation-failure parser recognizes 11 patterns: annotation-too-large, label-too-long, hook failure, admission webhook denial, RBAC, conflict, immutable field, schema migration, connectivity, etc.
Limitations:
- SSA-applied resources (
ServerSideApply=truesync-option) lack thelast-applied-configurationannotation, so the local diff described above is unavailable for those rows. Configuring the Argo CD API integration covers them: Radar then asks argocd-server for the Git-rendered desired state and diffs against that, which is canonical rather than annotation-derived. An annotation-free local fallback viametadata.managedFieldsis still tracked in #601. - Single-cluster only: Application↔resource edges only render when Radar is connected to the cluster where the managed resources live (not necessarily the cluster running the Argo controller).
Argo Rollouts provides progressive delivery strategies including blue-green and canary deployments.
| CRD | Group | Topology | Detail View | AI Summary |
|---|---|---|---|---|
| Rollout | argoproj.io/v1alpha1 |
Yes | Yes | Yes |
| AnalysisRun | argoproj.io/v1alpha1 |
Yes | Yes | Yes |
| AnalysisTemplate | argoproj.io/v1alpha1 |
— | Generic | — |
| ClusterAnalysisTemplate | argoproj.io/v1alpha1 |
— | Generic | — |
| Experiment | argoproj.io/v1alpha1 |
— | Generic | — |
Control surface: Promote, Promote full, Skip step, Retry, and Abort on the Rollout detail page, each gated on a live capability probe (patch rollouts and patch rollouts/status are separate grants). Rollback goes through revision history, with an opt-in "skip canary steps" follow-up for hotfixes.
Why it's stuck: InconclusiveAnalysisRun names nothing on its own, so Radar resolves the AnalysisRun the controller recorded and surfaces the deciding metric — its success/failure condition, latest measured value, and message. The same verdict reaches AI agents through the Rollout's issue field.
Topology: Rollout → active AnalysisRun (uses), labelled by trigger (step / background / pre-promotion / post-promotion). Only the runs the Rollout's status points at are graphed — historical runs would grow the graph without bound.
Timeline: Step index, traffic weights, pause conditions, abort/promote-full, and stable-ReplicaSet moves are all recorded as distinct events; a Rollout sits in Progressing for the whole canary, so phase alone would show nothing.
Argo Workflows is a container-native workflow engine for orchestrating parallel jobs on Kubernetes.
| CRD | Group | Topology | Detail View | AI Summary |
|---|---|---|---|---|
| Workflow | argoproj.io/v1alpha1 |
— | Yes | — |
| WorkflowTemplate | argoproj.io/v1alpha1 |
— | Yes | — |
| CronWorkflow | argoproj.io/v1alpha1 |
— | Generic | — |
Istio is the most widely adopted service mesh, providing traffic management, security (mTLS), and observability for microservices.
Topology: Full Istio traffic path — IstioGateway → VirtualService → Service, and DestinationRule → Service configuration edges. See how traffic flows through gateway listeners, virtual service routing rules, and into backend services.
VirtualService Detail View:
- HTTP/TCP/TLS routing rules with match conditions
- Destinations with weight distribution bars
- Fault injection and traffic mirroring detection (AlertBanner warnings)
- Retry policies, timeouts, and CORS settings
- Gateway references with clickable links
DestinationRule Detail View:
- Target service host with clickable link
- Traffic policy: connection pool (TCP/HTTP limits), load balancer algorithm, outlier detection (ejection settings), TLS mode
- Subset definitions with labels and per-subset traffic policy overrides
Gateway Detail View (networking.istio.io):
- Server configurations with port, protocol, and hosts
- TLS settings per server (mode, credential references)
- Workload selector labels
ServiceEntry Detail View:
- Hosts, location (MESH_EXTERNAL/MESH_INTERNAL), resolution strategy
- Ports with protocol badges
- Endpoint addresses with port mappings and labels
PeerAuthentication Detail View:
- mTLS mode with color-coded badges (STRICT/PERMISSIVE/DISABLE)
- Scope indicator (workload-scoped vs namespace-wide)
- Port-level mTLS overrides
AuthorizationPolicy Detail View:
- Action badge (ALLOW/DENY/CUSTOM/AUDIT) with rule breakdown
- Source principals, namespaces, IP blocks
- Operation matching (hosts, ports, methods, paths)
- Deny-all and allow-nothing detection (AlertBanner)
Resource Browser: Smart columns show status badges, hosts, gateways, route counts, mTLS modes, actions, and load balancer algorithms at a glance.
| CRD | Group | Topology | Detail View | AI Summary |
|---|---|---|---|---|
| VirtualService | networking.istio.io/v1 |
Yes | Yes | — |
| DestinationRule | networking.istio.io/v1 |
Yes | Yes | — |
| Gateway | networking.istio.io/v1 |
Yes | Yes | — |
| ServiceEntry | networking.istio.io/v1 |
— | Yes | — |
| PeerAuthentication | security.istio.io/v1 |
— | Yes | — |
| AuthorizationPolicy | security.istio.io/v1 |
— | Yes | — |
Velero provides backup and restore capabilities for Kubernetes cluster resources and persistent volumes.
Backup Detail View:
- Phase with color-coded badge, start/completion timestamps, duration
- Progress bar during in-progress backups (items backed up percentage)
- Scope filters: included/excluded namespaces and resources, label selectors
- Storage location and volume snapshot locations
- Options: TTL, snapshot volumes, default filesystem backup
- Error/warning detection (AlertBanner for failed or partial backups with validation errors)
Restore Detail View:
- Phase badge, source backup reference, duration
- Progress bar during in-progress restores
- Scope filters: included/excluded namespaces and resources
- Restore options: PV restoration, existing resource policy
- Error detection (AlertBanner for failed or partial restores)
Schedule Detail View:
- Cron schedule (monospace), last backup timestamp
- Pause state detection (AlertBanner when paused)
- Validation failure detection (AlertBanner)
- Backup template: storage location, TTL, namespace/resource filters, snapshot settings
BackupStorageLocation Detail View:
- Phase (Available/Unavailable), last validation and sync times
- Provider configuration: bucket, prefix, region, access mode
- Provider-specific config key-value pairs
VolumeSnapshotLocation Detail View:
- Provider name and configuration parameters
Resource Browser: Smart columns show phase badges, storage location, namespace counts, duration, expiry (with color-coded warnings), and error/warning counts. VolumeSnapshotLocation shows provider and config — deliberately no status column, since the VSL controller never populates status.phase.
Velero reports every outcome through status.phase and has no status.conditions on any of its CRDs, so Radar reads phases directly rather than through the generic CRD-condition fallback. These become Issues (/api/issues, the Problems surface, MCP issues):
| Detection | Trigger | Severity |
|---|---|---|
BackupFailed |
Backup.status.phase == Failed |
critical |
BackupValidationFailed |
phase == FailedValidation; message from status.validationErrors |
critical |
BackupPartiallyFailed |
PartiallyFailed, FinalizingPartiallyFailed, WaitingForPluginOperationsPartiallyFailed |
warning |
RestoreFailed / RestoreValidationFailed / RestorePartiallyFailed |
the same phases on Restore |
critical / critical / warning |
ScheduleValidationFailed |
phase == FailedValidation, or non-empty status.validationErrors |
critical |
BackupStorageLocationUnavailable |
BSL.status.phase == Unavailable |
critical |
BackupRepositoryNotReady |
BackupRepository.status.phase == NotReady |
warning |
VeleroRunStalled |
a Backup or Restore still in InProgress, WaitingForPluginOperations or Finalizing whose status.startTimestamp is older than its spec.itemOperationTimeout (Velero's built-in four hours when it declares none). Deleting is excluded — its startTimestamp belongs to the original run. The message is worded per phase: see the limitation below |
warning |
They roll up under three categories, split by what you'd go and look at: backup_failed for runs that already have an outcome, backup_target_unavailable for the location/repository kinds, and backup_stalled for VeleroRunStalled. A run with no verdict is not a failed run — it has no error to read, only a controller to check — and calling it one puts "Backup failed" above a message saying it is still in progress.
Supersession. Velero retains failed Backup objects until their TTL expires, so a raw phase-to-issue mapping would keep one bad night red for days. Backups group by the velero.io/schedule-name label; only the newest run that already has an outcome raises an issue (the two *PartiallyFailed phases count — the partial failure is a fact even though Velero is still finalizing), a later Completed clears the series, and an in-progress run neither clears nor raises. Ad-hoc (unlabelled) backups are their own series, so nothing supersedes them. Restores get no supersession — they are one-off operator actions, not a recurring series.
A paused Schedule is not an issue. Pausing is operator intent; the Schedule list and detail view show the state without adding queue noise.
Namespace attribution. Issues attribute to the Velero object's own namespace (velero, or kommander on NKP). They are therefore admin-visible, but not visible to a user whose namespace view-filter excludes the Velero namespace — including one scoped only to the namespace whose data was lost. Surfacing a failure against the protected namespaces needs the protection-coverage model and is not part of this.
What is not detected yet. Every detection above is driven by something Velero wrote — a phase, or in the stalled case a startTimestamp measured against the run's own budget. Radar does not yet detect the absence of a run: a schedule that quietly stopped firing (controller down, wrong cron, schedule deleted) leaves its last run Completed, so no issue is raised even though backups have silently stopped. That needs the schedule cadence modelled against Velero's real controller semantics (a due run is skipped while a prior backup is in flight), which is tracked separately. Treat "no Velero issues" as "nothing Velero recorded looks wrong", not as "backups are healthy."
| CRD | Group | Topology | Detail View | Issues | AI Summary |
|---|---|---|---|---|---|
| Backup | velero.io/v1 |
— | Yes | Yes | — |
| Restore | velero.io/v1 |
— | Yes | Yes | — |
| Schedule | velero.io/v1 |
— | Yes | Yes | — |
| BackupStorageLocation | velero.io/v1 |
— | Yes | Yes | — |
| VolumeSnapshotLocation | velero.io/v1 |
— | Yes | — | — |
| BackupRepository | velero.io/v1 |
— | Yes | Yes | — |
Kind collisions. restores and schedules are shared plurals — rancher/backup-restore-operator ships restores.resources.cattle.io, and several operators ship their own schedules kind. For those two, Radar's renderers, status readers, column sets and cells all select on the velero.io group, so a foreign resource with the same plural falls through to the generic renderer instead of being dressed up as a backup. backupstoragelocations, volumesnapshotlocations and backuprepositories are keyed on the plural alone — no other operator is known to claim those names — though their renderers and cells still group-guard, and each is listed in the fall-through so a foreign CRD with the plural reaches the generic renderer rather than a blank drawer. The kind→colour and kind→icon tables have no group awareness at all, so only Velero-unique kinds appear in them: Backup, Restore and Schedule are deliberately left unstyled rather than risk decorating a foreign resource.
Limitations:
- A backup's phase is not its restorability.
Completedsays the run finished, which stays true after the storage location holding it goes Unavailable or its TTL expires. The BackupStorageLocation page carries the consequence — what it holds and how much of it is worth planning a recovery around — because the Backup's own status cannot observe it. The two are distinguished deliberately: an Unavailable location means a restore cannot happen now, while an expired backup means Velero intends to delete it. Velero's restore controller does not check expiration, so until the garbage collector reaches it the data is still there and a restore would work; it is excluded from the restorable count because it is not something to depend on, not because it is already gone. - A stalled run is inferred from elapsed time, and only one phase is measured against a real limit.
spec.itemOperationTimeoutis, in Velero's own words, "the time used to wait for asynchronous BackupItemAction operations" — so it governsWaitingForPluginOperationsand nothing else. A run past it there has outlived a limit Velero set, and the message says so. A run past it inInProgressorFinalizinghas only been running a while: Velero puts no bound on walking and writing items, and a large cluster legitimately takes hours, so the message reports the elapsed time, states that Velero sets no limit on the phase, and offers the timeout only as a yardstick. Where the number comes from is named either way — the run's own field, or Velero's built-in four hours, which the controller's--default-item-operation-timeoutcan change and which is not readable from the CRs. Radar also does not check whether the Velero controller is running, so no message names a cause. - The messages behind a run's counts need a live controller and reachable storage.
POST /api/velero/{backups|restores}/{ns}/{name}/messagesfetches them on demand: Radar creates aDownloadRequest, Velero answers with a pre-signed URL, and Radar reads the results file from object storage. Both preconditions are real and are reported rather than hidden — a stopped controller never answers, and a URL signed for a host only the cluster can resolve cannot be fetched from a laptop (Velero'spublicUrlon the storage location is what makes it reachable). Data-mover objects (DataUpload/DataDownload), full backup logs, and progress counters while a run is in flight remain out of reach. The final item count is not in that list —livetakes a real backup and the count Radar renders is Velero's own. - Partly verified against fixtures.
./scripts/velero-demo.sh liveruns Velero against in-cluster object storage, so the restorability claims above are exercised against work Velero really did: a backup written to a bucket, a restore that recreated a deleted namespace, a location markedUnavailableby Velero's own validation while still holding aCompletedbackup, and a run left in flight past its ownitemOperationTimeout.PartiallyFailedis produced there too, by a pre-backup hook that exits non-zero, andFailedValidationby aiming a backup at the location Velero has just markedUnavailable. The data-mover objects (DataUpload/DataDownload) appear in neither mode —updeliberately does not fake them, andlivehas no snapshot-capable CSI driver to make Velero emit them. Coverage matrix:scripts/velero-demo/README.md.
External Secrets Operator (ESO) synchronizes secrets from external providers (AWS Secrets Manager, HashiCorp Vault, Azure Key Vault, GCP Secret Manager, and more) into Kubernetes Secrets.
ExternalSecret Detail View:
- Sync status badge, last sync time, refresh interval
- Store reference with clickable link and kind indicator
- Secret mappings table (secret key → remote key, property, version)
- Data sources with type badges
- Target secret configuration and creation policies
- Sync failure detection (AlertBanner when Ready condition is False)
ClusterExternalSecret Detail View:
- Overview: provisioned vs failed namespace counts
- Namespace selection: explicit list or label selector
- Provisioned namespaces (green badges)
- Failed namespaces with per-namespace error details (AlertBanner)
- ExternalSecret spec: refresh interval, store reference, data/source counts
SecretStore / ClusterSecretStore Detail View:
- Provider with color-coded badge (AWS orange, Azure/GCP blue, Vault purple, etc.)
- Provider-specific details: region, vault URL, project ID, authentication method
- Connection status with reason and last transition
- Retry settings
- Readiness detection (AlertBanner when not Ready)
Resource Browser: Smart columns show sync status, store reference, provider type, refresh interval, and last sync time.
| CRD | Group | Topology | Detail View | AI Summary |
|---|---|---|---|---|
| ExternalSecret | external-secrets.io/v1beta1 |
— | Yes | — |
| ClusterExternalSecret | external-secrets.io/v1beta1 |
— | Yes | — |
| SecretStore | external-secrets.io/v1beta1 |
— | Yes | — |
| ClusterSecretStore | external-secrets.io/v1beta1 |
— | Yes | — |
CloudNativePG (CNPG) is the Kubernetes operator for PostgreSQL, covering the full lifecycle from bootstrapping to monitoring, with high availability, automated failover, and backup management.
Cluster Detail View:
- Phase, instances ready/desired, primary instance, image version
- Instance node distribution (which K8s nodes run each PostgreSQL instance)
- Storage configuration: data size, storage class, WAL storage
- Backup configuration: destination, retention policy, last successful backup, recovery point
- Monitoring: PodMonitor integration, custom query ConfigMaps
- Replication settings (for replica clusters), with per-instance role and timeline ID
- PostgreSQL parameters
- Health detection (AlertBanner for degraded clusters, failover/switchover in progress)
- WAL archiving failure — a first-class AlertBanner driven by the
ContinuousArchivingcondition. This is the classic silent CNPG incident: the cluster keeps serving traffic normally while the recovery point stops advancing. The condition proves the last archive attempt failed, so Radar reports "archiving failing since <time> — the recovery point may not be advancing" and deliberately does not claim an exact RPO - Last-backup failure — driven by the
LastBackupSucceededcondition. CNPG also sets this condition False with reasonBackupStartedwhile a backup is merely in flight; Radar ignores that state rather than alerting on every backup run
Backup Detail View:
- Phase, backup method, duration, start/stop timestamps
- Cluster reference with clickable link
- Destination path and server name
- Recovery target
- Failure detection (AlertBanner with error message)
ScheduledBackup Detail View:
- Cron schedule, last/next schedule timestamps
- Suspension detection (AlertBanner when paused)
- Backup configuration: cluster reference, method, owner reference settings
Pooler Detail View:
- Type (read-write/read-only) with colored badge, pool mode
- Instances scheduled/desired (not readiness — see below)
- Cluster reference with clickable link
- PgBouncer parameters
- Degraded state detection (AlertBanner when not all instances are scheduled)
Note Pooler.status.instances counts pods trying to be scheduled, not ready pods — a Pooler whose PgBouncer pods are all Pending still reports the full count. Radar therefore labels the healthy state Scheduled rather than Ready; actual readiness lives on the Deployment CNPG generates for the Pooler (same name, same namespace).
Resource Browser: Smart columns show status, instance counts (with degraded highlighting), primary instance, image tag, storage size, cluster reference, and schedule expressions.
Cluster phases are full English sentences (Cluster is unrecoverable and needs manual intervention), not enum tokens, and are matched on equality. They are bucketed as healthy / transient / failing / terminal / attention; terminal phases outrank instance counts, so an unrecoverable cluster whose pods happen to still be Ready is still rendered red. An unrecognized phase from a newer CNPG minor surfaces verbatim as unknown rather than being guessed at.
Backup phases are lowercase tokens. walArchivingFailing is treated as a cluster-level signal, not an ordinary backup failure — archiving is broken upstream of that Backup, so the whole recovery window is affected.
The taxonomy is defined twice — TypeScript for the badge, Go for the issue detector — and pinned by TestCNPGPhaseTaxonomyMatchesFrontend, which fails if the two drift.
In-tree spec.backup.barmanObjectStore is deprecated as of CNPG 1.26. Clusters migrated to the barman-cloud plugin keep their config in an ObjectStore CR (barmancloud.cnpg.io/v1), and CNPG stops populating status.lastSuccessfulBackup / firstRecoverabilityPoint by design. Radar detects the plugin from spec.plugins[], names the ObjectStore and resolved server key, and says so explicitly — rather than rendering an empty backup section that reads identically to "no backups configured".
The ObjectStore itself is rendered: destination and credential provider (never the credentials), retention, and status.serverRecoveryWindow per PostgreSQL server — firstRecoverabilityPoint, lastSuccessfulBackupTime, lastFailedBackupTime. Note the field names differ from the Cluster's (lastSuccessfulBackupTime, not lastSuccessfulBackup); reading the Cluster's spelling off an ObjectStore silently yields nothing.
Two states carry the weight. A failure newer than the last success means the window has stopped advancing while its oldest point still ages out under retention — shrinking from both ends, so it is called out rather than left to be inferred from two timestamps. An ObjectStore with an empty serverRecoveryWindow is reported as holding nothing restorable rather than as healthy: on the plugin path the Cluster publishes no recovery point of its own, so a green badge here would be the only claim on screen and it would be wrong.
Backup and ScheduledBackup with spec.method: plugin name the plugin and link to the ObjectStore they write into, and suppress the in-tree destinationPath / serverName rows, which are never populated on that path.
CNPG can manage PostgreSQL-side objects from Kubernetes. All three report through status.applied, and it has three values, not two: true, false with the operator's message, and absent — meaning not reconciled yet. Absent is rendered as pending rather than failed; treating it as failure condemns every object in its first seconds.
The names in these specs are PostgreSQL names, not Kubernetes names: a Publication demo-app-pub declares dbname: demo_app, and the Database CR that owns demo_app is called demo-app. Radar resolves them back to the CRs so the reference is a link rather than a dead string, and falls back to plain text when nothing matches. The Database detail runs the lookup in the other direction, listing what publishes from and subscribes into it — a link the API only models one way.
databaseReclaimPolicy (and its publication/subscription twins) decides whether deleting the manifest drops the real object. delete is called out as destructive; CNPG defaults to retain, and defaulting the other way in the UI would warn about data loss that is not going to happen.
A declared object the operator could not apply raises an Issue (CNPGDeclarativeNotApplied, warning) carrying the operator's own message. This is the one CNPG failure with no other signal: the CR exists, the cluster is healthy, every count is green, and the database simply is not there. Only applied: false raises it — an absent applied means not yet reconciled, and reporting that would flag every declarative object for the first seconds of its life.
databases, publications and subscriptions are crowded plurals — Knative owns subscriptions, and several database operators ship the other two — so the column sets are group-qualified and a foreign CRD gets the generic columns instead of a Cluster column it can never fill.
ImageCatalog and ClusterImageCatalog pin one PostgreSQL image per major version. A Cluster that references one carries no spec.imageName at all; the resolved image lives in status.image, so anything reading spec alone shows a dash where an image is running.
A cluster asking for a major the catalog does not list reports "incomplete or invalid image catalog" and stops — and that is invisible from the cluster side, where the reference looks fine. The catalog page lists the clusters pinned to it and separates out those asking for a version it does not carry.
| Check | What it catches |
|---|---|
cnpgNoDeclarativeBackup |
A CNPG Cluster with no ScheduledBackup targeting it |
Deliberately narrow: the absence of a ScheduledBackup does not prove a cluster is unprotected (on-demand Backups, volume snapshots and external schedulers all exist), so the finding asserts only that no schedule is declared, at posture severity. All three spec.method values — barmanObjectStore, volumeSnapshot and plugin — count as a declared schedule. Suspended schedules count as present, since suspension is deliberate operator intent. The check does not run at all unless a synced cluster-wide ScheduledBackup informer backs the inventory, because absence would otherwise be unprovable.
| CRD | Group | Topology | Detail View | AI Summary |
|---|---|---|---|---|
| Cluster | postgresql.cnpg.io/v1 |
— | Yes | — |
| Backup | postgresql.cnpg.io/v1 |
— | Yes | — |
| ScheduledBackup | postgresql.cnpg.io/v1 |
— | Yes | — |
| Pooler | postgresql.cnpg.io/v1 |
— | Yes | — |
| ObjectStore | barmancloud.cnpg.io/v1 |
— | Yes | — |
| Database | postgresql.cnpg.io/v1 |
— | Yes | — |
| Publication | postgresql.cnpg.io/v1 |
— | Yes | — |
| Subscription | postgresql.cnpg.io/v1 |
— | Yes | — |
| ImageCatalog | postgresql.cnpg.io/v1 |
— | Yes | — |
| ClusterImageCatalog | postgresql.cnpg.io/v1 |
— | Yes | — |
The clusters and backups plurals collide with Cluster API and Velero respectively, and the declarative types add more: subscriptions is also Knative messaging's, while databases and publications are generic enough that several database operators ship them. Radar resolves all of them with positive API-group guards, so a third operator's CRD sharing any of these plurals (KubeBlocks, Redis/Valkey operators) falls through to the generic renderer instead of inheriting a fabricated PostgreSQL status.
Limitations:
- The image-catalog and backup views describe what the cluster reports. A
ScheduledBackup's cron is CloudNativePG's six-field form (seconds first) and is shown verbatim rather than translated, because reading it as a five-field expression would state the wrong time. - Verified against clusters of a few hundred resources. Neither the recovery-window table nor the declarative-object lists have been exercised on a fleet with thousands of Postgres clusters.
Crossplane extends Kubernetes with declarative cloud-resource management. Operators define platform APIs (CompositeResourceDefinitions + Compositions), and provider packages reconcile real cloud resources from Managed Resource CRs in any cloud or SaaS. Radar treats every provider as a first-class integration without needing per-provider code — detection is heuristic, based on spec shape.
Sidebar: All Crossplane resources land under a single "Crossplane" group, including provider-shipped MR groups (*.upbound.io, *.crossplane.io subgroups). Provider-Kubernetes and Provider-Helm config groups are first-class.
Managed Resource Detail View (the generic MR renderer — works for every provider, including Upbound AWS/GCP/Azure, provider-kubernetes, provider-helm, and any community provider):
- Kind, API group, external-name annotation, deletion + management policies
- Paused banner (
crossplane.io/paused: "true") — reconciliation suppressed by operator intent - Alert banner when
Synced=FalseorReady=Falsewith the upstream cloud error verbatim - Linked
ProviderConfigand (when this MR is composed) linked parent Composite via owner-ref walk - Collapsed
spec.forProviderandstatus.atProviderJSON for deep diagnosis
Composite / Claim Detail View — the killer feature:
- Linked Composition and CompositionRevision (when pinned)
- Composed Resources list — every entry in
spec.crossplane.resourceRefs(v2) orspec.resourceRefs(v1) rendered as a clickable row with its own live status badge, fetched per-row via React Query. Clicking opens the composed resource's drawer. - Paused banner when
crossplane.io/paused: "true" - For v1 Claims: linked bound XR
Composition Detail View:
- Mode badge (
Pipelineviolet vsResourcesneutral) - Backed by linked XRD
- Pipeline mode: numbered step cards, each with linked Function package, input kind, and expandable raw input
- Resources mode: list of composed-resource templates with patch counts
XRD Detail View:
- Generated CR section: kind, plural, group, scope (v2 only —
ClustervsNamespacedbadge) - Claim names (v1)
- Versions table with
served/referenceable/deprecatedbadges - Default + enforced Composition links
- Connection-secret keys
Established/Offeredconditions
Provider / Function / Configuration Detail View (shared renderer):
- Package OCI image, pull policy, revision activation policy
- Current revision + identifier
- Linked DeploymentRuntimeConfig (when set)
- Linked package dependencies
- For Configurations: list of installed XRDs/Compositions/Functions from
status.objectRefs - Alert banners for
Installed=False(install failed) orHealthy=False(controller unhealthy)
ProviderConfig Detail View:
- API group, credentials source (
InjectedIdentity,Secret, etc.) - "N in use" status badge from
status.users - Linked credentials Secret when applicable
Resource Browser: MR list shows kind / external name / provider config / status; Provider list shows package, revision, status; Composition list shows mode, composite kind, function count; XRD list shows generated kind and claim kind.
Cluster Audit: New crossplaneStuck check flags MRs/XRs/Claims reporting Ready=False or Synced=False for more than 5 minutes (Medium) or 30 minutes (High). Synced=False takes priority over Ready=False because it usually indicates the actionable problem (bad ProviderConfig, malformed spec, missing IAM). Same severity ramp as stuckTerminating for cross-surface consistency. Paused resources are deliberately suppressed.
Crossplane v2 moved several fields under spec.crossplane.*. Radar's renderers and detectors check the v2 path first, fall back to v1 — no version detection needed. Fields handled this way:
spec.crossplane.providerConfigRef↔spec.providerConfigRefspec.crossplane.resourceRefs↔spec.resourceRefsspec.crossplane.compositionRef↔spec.compositionRefspec.crossplane.compositionRevisionRef↔spec.compositionRevisionRefspec.crossplane.managementPolicies↔spec.managementPoliciesspec.crossplane.deletionPolicy↔spec.deletionPolicy
- Managed Resource: presence of
spec.providerConfigRef(v1 or v2 path) - Composite / Claim: presence of
spec.resourceRefs(v1 or v2 path) AND not an MR - v1 Claim: also has
spec.resourceRef(singular, pointing at the bound XR) +spec.compositionRef
The set of MR CRD kinds is unbounded — every provider ships its own. Detection by spec shape lets Radar handle providers it has never seen without per-provider code.
The Helm chart's rbac.crdGroups.crossplane: true toggle grants read access to:
crossplane.io,pkg.crossplane.io,apiextensions.crossplane.io(Crossplane core)kubernetes.crossplane.io,helm.crossplane.io(provider-kubernetes + provider-helm — useful in non-cloud installs)
For Upbound provider CRDs (s3.aws.upbound.io, compute.gcp.upbound.io, etc.), list them in rbac.additionalCrdGroups — Kubernetes RBAC has no apiGroups wildcards. Alternative: set rbac.crdGroups.all: true to grant cluster-wide read on every CRD (simpler, broader).
| CRD | Group | Topology | Detail View | AI Summary |
|---|---|---|---|---|
| Managed Resources (any provider) | *.upbound.io, kubernetes.crossplane.io, helm.crossplane.io, *.crossplane.io |
— | Yes | — |
| Composite Resources (XRs) | user-defined groups | — | Yes | — |
| Claims (v1) | user-defined groups | — | Yes | — |
| CompositeResourceDefinition | apiextensions.crossplane.io/v1, v2 |
— | Yes | — |
| Composition | apiextensions.crossplane.io/v1 |
— | Yes | — |
| CompositionRevision | apiextensions.crossplane.io/v1 |
— | Yes | — |
| Provider | pkg.crossplane.io/v1 |
— | Yes | — |
| Function | pkg.crossplane.io/v1 |
— | Yes | — |
| Configuration | pkg.crossplane.io/v1 |
— | Yes | — |
| ProviderConfig | per-provider group | — | Yes | — |
Deferred to a future "full Crossplane" pass:
- Topology edges (XR → composed MRs in the graph view)
Usage/ClusterUsagerendering (delete-protection visualization)- Cloud-console deep links from
external-name - Provider controller pod link with one-click log access
- Connection-secret link on XRs
- Mutating actions (force-reconcile, pause/unpause via
crossplane.io/paused, manual sync) - Composition revision diff view (compare adjacent
CompositionRevisions) - Per-XR insights pipeline (drift / events / plan / history surface — same shape as the GitOps detail page)
- Per-provider specialized renderers (e.g. an S3-specific section that calls out bucket policy / versioning) — generic MR renderer covers the daily need; specialize on user demand
Kyverno is a Kubernetes-native policy engine for validation, mutation, generation, and image verification — no new language required, policies are written as Kubernetes resources.
Policy / ClusterPolicy Detail View:
- Failure action badge (Enforce in red, Audit in yellow)
- Configuration: background scanning, webhook timeout, failure policy, schema validation
- Rule type summary (validate/mutate/generate/verifyImages counts)
- Individual rules with type badges and match/exclude indicators
- Auto-generated rules list
PolicyReport / ClusterPolicyReport Detail View:
- Visual result bar chart (pass/fail/warn/error/skip proportions)
- Scope and source information
- Individual results with status badges, severity levels, policy/rule names
- Expandable details: message, category, source, affected resources
- Problem detection (AlertBanner for failures or errors)
Resource Browser: Smart columns show status (colored by worst outcome), failure action, rule counts, and pass/fail/warn/error/skip breakdowns.
A resource page answers "which policies does this break". The policy page answers the other direction: which resources does this policy cover, and what happens to them — served by /api/policy/policies/{policy} off a reverse index built when reports are replaced, never per request.
Four things make it harder than a lookup:
results[].policyis producer-defined. It is not guaranteed to name a policy object; Trivy and Falco write their own identifiers into the same field. When results under this name came from another engine, the page says so rather than presenting them as this policy's own.- The counts are cluster-true, the list is not. Totals are taken before the namespace view filter and before RBAC, so the headline states the ground it covers first; what is hidden, and why, is named under the list.
faildoes not mean the same thing per family. A mutating policy'sfailcarries "mutation is not applied" — nothing violated anything. On the legacykyverno.iokinds the family is not in the kind at all: one ClusterPolicy carries any mix of validate, mutate and generate rules, so the vocabulary is resolved per rule from the rule block. A generate rule'spassreads "generated", not "passing".- What enforcing would do depends on declared operations. A policy matching CREATE only never rejects a change to something that already exists, so resources currently failing it are grandfathered until recreated. Verified on Kyverno 1.18.2: annotating a ConfigMap that fails a CREATE-only Deny policy is admitted; creating an identical one is rejected.
Passing resources are listed too, behind a disclosure — "all N passing" with no way to see which N is a dead end on the page that raises the question.
Authorization is resolved per subject scope, not once per policy, and the resource name follows the scope. A ClusterPolicy has no namespace of its own, so asking the question once against "" gates the whole view on cluster-scoped permission and withholds findings a namespace-restricted caller is entitled to see. And the two families serve findings from two resources each — policyreports / clusterpolicyreports and reports / clusterreports — so authorizing a cluster-scoped finding against the namespaced resource asks about the wrong object, and a grant of policyreports cluster-wide does not imply clusterpolicyreports. The per-resource view filters by the same families as the per-policy view; anything reading findings without their provenance cannot filter at all.
The per-rule subject list is bounded so an ordinary drawer open stays small, and that bound is liftable: ?limit= raises it to a server ceiling, and the footer offers it rather than ending at a sentence. A count with no way to reach what it counts is the same dead end in a different place.
GlobalContextEntry gets its own view because a policy referencing an entry that never resolves fails at evaluation time with no obvious cause. Kyverno records success as status.lastRefreshTime and records failure as nothing at all — no message, no condition, no reason. So the page reports "has refreshed" versus "has never refreshed" (with the entry's age turning the second into a diagnosis) and says outright that Kyverno records no reason, rather than inventing one.
The count of queued work also appears on the policy itself, above its configuration. The requests have their own page, but the failure worth catching is a backlog rather than one request — upstream reports describe thousands stuck in Pending, never cleaned up, taken up again on every reconcile — and nobody watches a page that is empty most of the time. The section is silent when a policy has queued nothing, so it never appears on the majority that only validate.
UpdateRequest is where a generation or a mutate-existing that silently stopped is diagnosed: the policy reports Ready, the target never appears, and the only evidence is a request sitting in Pending. The two request types share a kind and almost nothing else — a generate request leaves spec.resource empty and spec.rule blank, carrying every trigger in spec.ruleContext[]; a mutate request is one-per-trigger with spec.resource populated and no ruleContext at all. Reading the documented field alone renders half of them blank.
EphemeralReport holds a background scan's findings for one resource before they are folded into a PolicyReport. Its findings live in spec, not status; its spec.owner is present and blank, so the subject comes from the owner reference (and from the audit.kyverno.io/resource.* labels once the subject is gone); and its result timestamps are {seconds, nanos} objects rather than RFC 3339 strings. Both kinds are deleted within seconds of finishing, so an empty list is completed work, not an outage — which is what the empty states say.
| CRD | Group | Topology | Detail View | AI Summary |
|---|---|---|---|---|
| Policy | kyverno.io/v1 |
— | Yes | — |
| ClusterPolicy | kyverno.io/v1 |
— | Yes | — |
| PolicyReport | wgpolicyk8s.io/v1alpha2 |
— | Yes | Yes |
| ClusterPolicyReport | wgpolicyk8s.io/v1alpha2 |
— | Yes | Yes |
| UpdateRequest | kyverno.io/v2 |
— | Yes | — |
| GlobalContextEntry | kyverno.io/v2 |
— | Yes | — |
| EphemeralReport | reports.kyverno.io/v1 |
— | Yes | — |
| ClusterEphemeralReport | reports.kyverno.io/v1 |
— | Yes | — |
PolicyReport findings are policy posture, not live operational failure, so they are not part of the /api/issues stream. They surface per-resource: the PolicyReport detail view (above) and the resourceContext policy rollup on a resource fetched via get_resource. (The cluster audit — /api/audit + MCP get_cluster_audit — is radar's own static best-practice scanner and does not include PolicyReport results.)
Limitations:
- Queued work (
UpdateRequest) is only shown for policies that generate or mutate existing resources, and only while it is in flight — Kyverno deletes these seconds after the work completes, so an empty section is the normal resting state rather than evidence that nothing ran. - Coverage counts describe the whole cluster; the per-rule subject lists are capped by the server and follow the caller's namespace view filter. The screen states which number it is showing, but the two are not interchangeable.
- Findings from a report family the caller cannot read are withheld from both lists and counts, and the number withheld is reported. A caller entitled to no family at all is told so rather than shown an empty result.
- Verified against a cluster with a few hundred policy results. The 200-subject cap and its Load the rest control are unproven on a cluster with tens of thousands of findings; the load-test harness cannot synthesize PolicyReports.
Knative extends Kubernetes with serverless capabilities: scale-to-zero, request-driven autoscaling, event-driven architectures, and simplified service deployment.
Topology: Full Knative Serving chain — Route → KnativeService → Configuration → Revision → Deployment → Pod. Eventing flow — PingSource → Broker → Trigger → subscriber target. See how traffic is split across revisions, which configurations are active, and how events flow from sources through brokers to triggers.
Knative in Topology View — Serving chain and Eventing flow
KnativeService Detail View:
- Status with URL and ingress readiness
- Latest ready and latest created revision links
- Scaling configuration (min/max scale, concurrency, timeout)
- Traffic split across revisions with percentage bars
- Container template (image, ports, env, resources)
- Conditions (Ready, RoutesReady, ConfigurationsReady)
KnativeService Detail View — URL, scaling, traffic splits, and conditions
Revision Detail View:
- Container image with tag
- Concurrency model and container concurrency limit
- Timeout and scaling bounds (min/max)
- Traffic percentage (active vs inactive)
- Conditions (Ready, ContainerHealthy, ResourcesAvailable, Active)
Route Detail View:
- URL and domain
- Traffic targets with revision names and percentage distribution
- Conditions (Ready, AllTrafficAssigned, IngressReady)
Configuration Detail View:
- Latest created and latest ready revision references
- Generation tracking
- Conditions (Ready)
Broker Detail View:
- Address (internal URL for event delivery)
- Delivery configuration (dead letter sink, retry, backoff)
- Conditions (Ready, Addressable, FilterReady, IngressReady, TriggerChannelReady)
Trigger Detail View:
- Broker reference
- Subscriber target (service, URI, or Kubernetes reference)
- Event filter attributes
- Delivery configuration (dead letter sink)
- Conditions (Ready, BrokerReady, SubscriberResolved, DependencyReady)
Source Detail Views (PingSource, ApiServerSource, ContainerSource, SinkBinding):
- Sink target reference
- Source-specific configuration:
- PingSource: cron schedule, data payload, content type
- ApiServerSource: API resources watched, event mode, service account
- ContainerSource: container image and arguments
- SinkBinding: subject reference (Deployment, Job, etc.)
- Conditions (Ready, Deployed, SinkProvided)
Networking Detail Views (Ingress, Certificate, ServerlessService):
- KnativeIngress: ingress class, visibility, TLS hosts, rules with path/host routing
- KnativeCertificate: domain names, DNS names, not-after expiry
- ServerlessService: mode (Proxy/Serve), network status
Flow Detail Views (Sequence, Parallel):
- Sequence: ordered list of steps with subscriber references
- Parallel: branches with filter and subscriber configurations
- Reply/channel template settings
Resource Browser: Smart columns show status, URLs, latest revisions, traffic splits, schedules, sinks, brokers, subscribers, and filters at a glance.
| CRD | Group | Topology | Detail View | AI Summary |
|---|---|---|---|---|
| Service | serving.knative.dev/v1 |
Yes | Yes | — |
| Configuration | serving.knative.dev/v1 |
Yes | Yes | — |
| Revision | serving.knative.dev/v1 |
Yes | Yes | — |
| Route | serving.knative.dev/v1 |
Yes | Yes | — |
| DomainMapping | serving.knative.dev/v1beta1 |
— | Yes | — |
| Broker | eventing.knative.dev/v1 |
Yes | Yes | — |
| Trigger | eventing.knative.dev/v1 |
Yes | Yes | — |
| EventType | eventing.knative.dev/v1beta2 |
— | Yes | — |
| Channel | messaging.knative.dev/v1 |
— | Yes | — |
| InMemoryChannel | messaging.knative.dev/v1 |
— | Yes | — |
| Subscription | messaging.knative.dev/v1 |
— | Yes | — |
| PingSource | sources.knative.dev/v1 |
Yes | Yes | — |
| ApiServerSource | sources.knative.dev/v1 |
Yes | Yes | — |
| ContainerSource | sources.knative.dev/v1 |
Yes | Yes | — |
| SinkBinding | sources.knative.dev/v1 |
Yes | Yes | — |
| Sequence | flows.knative.dev/v1 |
— | Yes | — |
| Parallel | flows.knative.dev/v1 |
— | Yes | — |
| Ingress | networking.internal.knative.dev/v1alpha1 |
— | Yes | — |
| Certificate | networking.internal.knative.dev/v1alpha1 |
— | Yes | — |
| ServerlessService | networking.internal.knative.dev/v1alpha1 |
— | Yes | — |
OpenCost is a CNCF tool for Kubernetes cost monitoring, exposing cloud provider pricing and workload resource allocation as Prometheus metrics.
Radar discovers if OpenCost metrics are available in the already-discovered Prometheus. If OpenCost is installed and scraping into Prometheus, cost data appears automatically with no additional configuration. The integration is passive and read-only.
Resource Costs
Dashboard Cost Card: Cluster hourly cost and projected monthly cost, top 5 most expensive namespaces with a horizontal bar chart. Clicking navigates to the full Cost Insights view.
Cost Insights View (/cost):
- Header: cluster hourly/monthly cost, efficiency %, idle cost projection
- Resource cost split bar: CPU / Memory / Storage percentage breakdown
- Cost trend chart with 6h/24h/7d range selector and per-namespace hover tooltips
- Namespace breakdown table (sortable by cost, efficiency, CPU/memory split) — click any row to expand per-workload costs on demand
- Node costs table: instance type, region, and hourly/monthly pricing per machine
- Efficiency color coding: green (50%+), amber (25–50%), red (below 25%)
- OpenCost (or Kubecost) deployed in your cluster, with its metrics being scraped by Prometheus
OpenCost cost data is not CRD-based — no custom resources are required. Cost views appear automatically when metrics are detected; they are hidden when no OpenCost metrics are found in Prometheus.
Dynamic Resource Allocation is Kubernetes' structured device-allocation API (GA in 1.34), replacing opaque extended-resource integers for GPUs and other accelerators. These are built-in resource.k8s.io APIs, not CRDs — Radar discovers them automatically when the cluster serves the group.
ResourceClaim Detail View: Allocation lifecycle status (Pending → Allocated → reserved), device requests with their DeviceClass (handles v1 exactly/firstAvailable and v1beta1 request shapes), allocated driver/pool/device results, reserved-for consumers with Pod links, and per-device health conditions when drivers report them. An allocated-but-unreserved claim is flagged — long-lived, it leaks a device.
Related Resources: Pods show their ResourceClaims (direct and template-generated); ResourceClaims link back to their DeviceClasses and the Pods holding the reservation.
Resource Browser: Claims list with allocation status, device class, allocated driver, and reservation columns. ResourceSlices list the per-node device inventory each driver publishes (driver, pool, node, device count).
| Kind | Group | Topology | Detail View | AI Summary |
|---|---|---|---|---|
| ResourceClaim | resource.k8s.io (v1, v1beta2) |
Relationships | Yes | Yes |
| ResourceClaimTemplate | resource.k8s.io (v1, v1beta2) |
— | Yes | Yes |
| DeviceClass | resource.k8s.io (v1, v1beta2) |
Relationships | Yes | Yes |
| ResourceSlice | resource.k8s.io (v1, v1beta2) |
— | Yes | Yes |
The NVIDIA GPU Operator manages the GPU software stack (driver, container toolkit, device plugin, DCGM) on Kubernetes.
ClusterPolicy Detail View: Operator state (ready / notReady / disabled), enabled components (driver, toolkit, device plugin, DCGM exporter, GFD, MIG manager, …), and MIG strategy. NVIDIA's ClusterPolicy shares its kind name with Kyverno's — Radar disambiguates by API group everywhere.
NVIDIADriver Detail View: Driver rollout state, type, version, image/repository, precompiled flag, and node selector.
| CRD | Group | Topology | Detail View | AI Summary |
|---|---|---|---|---|
| ClusterPolicy | nvidia.com/v1 |
— | Yes | Yes |
| NVIDIADriver | nvidia.com/v1alpha1 |
— | Yes | Yes |
Network Policies control pod-to-pod and pod-to-external traffic at the network level. Radar supports standard Kubernetes NetworkPolicy, Cilium policies, and Calico policies, providing visibility into what traffic is allowed, denied, and which workloads are unprotected.
Topology: Kubernetes, Cilium, and Calico policy nodes appear in the topology graph with edges connecting them to the Deployments, StatefulSets, and DaemonSets they protect. Calico matching evaluates workload, namespace, and service-account selectors. Staged Calico policies use dashed edges and preview styling so they are not mistaken for enforced protection; a staged policy whose stagedAction is Delete or Ignore draws no edge at all, because promoting it would remove protection rather than add it.
Calico policy topology — enforced relationships use solid edges; staged previews use dashed edges
Policy Flow Diagram: Each NetworkPolicy detail drawer includes a visual flow diagram showing ingress and egress rules as a directional graph — sources on the left, targets on the right, with ports and protocols labeled. Quickly understand what a policy allows without reading YAML.
Policy Flow Diagram — visual representation of ingress and egress rules
Dashboard Coverage Card: The home dashboard includes a Network Policy Coverage card showing total policy count, the percentage of workloads covered by at least one enforced policy, and a count of uncovered workloads. When staged Calico policies exist, it separately shows projected coverage if those policies were applied. That projection can be lower than today's coverage — a staged deletion removes the protection of the policy it names — and the bar marks the part that would be lost.
Dashboard coverage separates enforced protection from the projected result of applying staged policies
Cilium Policy Detail View:
- Endpoint selector targeting
- Ingress/egress rules with allow and deny semantics
- Cilium-specific entity selectors (world, cluster, host)
- CIDR rules, port/protocol specifications
- Related workloads with clickable links
Calico Policy Detail View:
- Flow diagram for ordered ingress and egress rules, including Allow, Deny, Log, and Pass actions
- Workload, namespace, and service-account selectors
- Tier, order, policy types, pre-DNAT, apply-on-forward, and do-not-track settings
- Calico entities, CIDRs, ports, protocols, HTTP matches, and ICMP matches
- Staged action and preview styling for staged policy variants
Enforced and staged policy flows — staged rules are explicitly marked as evaluated but not enforced
Calico Infrastructure Detail Views: IPPool details show CIDR, encapsulation, NAT, block size, assignment mode, and node selectors. HostEndpoints show interface, expected IP addresses, profiles, and a link to the owning Node. Tier details show order and default action, and policies link back to their Tier.
Radar recognizes both projectcalico.org and crd.projectcalico.org. A cluster
running the Calico API server serves the same stored policies under both, so each
policy appears once, identified by kind, namespace and name. The API group stays
part of resource navigation and authorization — it is what keeps Calico
NetworkPolicy distinct from Kubernetes networking.k8s.io NetworkPolicy — and
a policy is shown to anyone authorized to list it under either group, since
either grant is enough to read it.
CiliumNetworkPolicy Detail — endpoint selector, ingress deny from world, egress allow to cluster
Standard NetworkPolicy Detail View:
- Pod selector and namespace selector rules
- Ingress and egress rules with CIDR blocks, ports, and protocols
- Policy type indicators (Ingress, Egress, or both)
- Related resources showing protected workloads
Traffic View Integration: When Hubble is available, dropped flows are correlated with the network policies that caused them, showing which policy denied specific traffic in real time.
Traffic View — dropped flow with POLICY_DENIED reason and selecting policy correlation
| Resource | Group | Topology | Detail View | AI Summary |
|---|---|---|---|---|
| NetworkPolicy | networking.k8s.io/v1 |
Yes | Yes | Yes |
| CiliumNetworkPolicy | cilium.io/v2 |
Yes | Yes | Yes |
| CiliumClusterwideNetworkPolicy | cilium.io/v2 |
Yes | Yes | Yes |
| NetworkPolicy | projectcalico.org/v3, crd.projectcalico.org/v1 |
Yes | Yes | Yes |
| GlobalNetworkPolicy | projectcalico.org/v3, crd.projectcalico.org/v1 |
Yes | Yes | Yes |
| StagedNetworkPolicy | projectcalico.org/v3, crd.projectcalico.org/v1 |
Yes (preview) | Yes | Yes |
| StagedGlobalNetworkPolicy | projectcalico.org/v3, crd.projectcalico.org/v1 |
Yes (preview) | Yes | Yes |
| StagedKubernetesNetworkPolicy | projectcalico.org/v3, crd.projectcalico.org/v1 |
Yes (preview) | Yes | Yes |
| IPPool | projectcalico.org/v3, crd.projectcalico.org/v1 |
No | Yes | Yes |
| HostEndpoint | projectcalico.org/v3, crd.projectcalico.org/v1 |
No | Yes | Yes |
| Tier | projectcalico.org/v3, crd.projectcalico.org/v1 |
No | Yes | Yes |
Radar statically evaluates Calico selectors against workload pod templates and the Namespace and ServiceAccount objects it can read. The result describes declared policy coverage, not live CNI enforcement or packet-level behavior. Missing labels or RBAC-restricted resources can prevent a relationship from being inferred, and staged policies are never included in enforced coverage. The projected "if staged" figure assumes every staged policy is promoted at once; it is a projection of the declared rules, not a simulation of what the data plane would do.
Radar automatically discovers and displays every CRD installed in your cluster — no configuration or plugins required. Resources appear in the sidebar, can be filtered and searched, and show full YAML with syntax highlighting in the detail drawer. The integrations above add richer presentation, but every CRD is browsable out of the box.




