Files
headlamp-polaris-plugin/claude.md
T
2026-02-07 10:35:51 -05:00

5.1 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

Headlamp plugin that surfaces Fairwinds Polaris audit results inside the Headlamp UI. Queries the Polaris dashboard API via the Kubernetes service proxy (/api/v1/namespaces/polaris/services/polaris-dashboard:80/proxy/results.json). Target Headlamp ≥ v0.26.

Build & Development Commands

# Install dependencies
npm install

# Build the plugin (standard Headlamp plugin build)
npx @kinvolk/headlamp-plugin build

# Start development mode with hot reload
npx @kinvolk/headlamp-plugin start

# Type-check without emitting
npx tsc --noEmit

# Lint
npx eslint src/

Architecture

src/
├── index.tsx                           # Entry point: registers sidebar entries + routes
├── api/
│   ├── polaris.ts                      # Types (AuditData schema), usePolarisData hook, countResults utilities, refresh settings
│   └── PolarisDataContext.tsx           # React context provider for shared data fetch
└── components/
    ├── DashboardView.tsx                # Overview / Full Audit page (score, check summary, cluster info)
    ├── NamespaceDetailView.tsx          # Per-namespace drill-down with resource table
    ├── DynamicSidebarRegistrar.tsx       # Registers namespace sidebar entries from live audit data
    └── PolarisSettings.tsx              # Plugin settings (refresh interval selector)

Top-level sidebar section at /polaris with sub-routes for full audit (/polaris/full-audit) and per-namespace views (/polaris/ns/:namespace). Data is fetched via ApiProxy.request to the Polaris dashboard service proxy and refreshed on a user-configurable interval (stored in localStorage under polaris-plugin-refresh-interval, default 5 minutes). Score is computed from result counts (pass/total).

Security / RBAC Requirements

The plugin reaches Polaris through the Kubernetes API server's service proxy sub-resource (/api/v1/namespaces/polaris/services/polaris-dashboard:80/proxy/...). The Headlamp service account (or the user's bearer token when Headlamp runs in token-auth mode) must be granted:

Verb API Group Resource Resource Name Namespace
get "" (core) services/proxy polaris-dashboard polaris

Minimal RBAC example:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: polaris-proxy-reader
  namespace: polaris
rules:
  - apiGroups: [""]
    resources: ["services/proxy"]
    resourceNames: ["polaris-dashboard"]
    verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: headlamp-polaris-proxy
  namespace: polaris
subjects:
  - kind: ServiceAccount
    name: headlamp            # adjust to match your Headlamp SA
    namespace: kube-system
roleRef:
  kind: Role
  name: polaris-proxy-reader
  apiGroup: rbac.authorization.k8s.io

Additional considerations:

  • NetworkPolicy: If the polaris namespace enforces network policies, allow ingress from the Headlamp pod (or the API server, since it performs the proxy hop) to polaris-dashboard on port 80.
  • Polaris dashboard listen address: The Polaris Helm chart exposes the dashboard on a ClusterIP service (polaris-dashboard:80). If the chart is installed with dashboard.enabled: false, the service will not be created, resulting in a 404 error for proxy requests.
  • No write operations: The plugin only performs GET requests through the proxy. No create, update, or delete verbs are required. Do not grant broader service proxy access than get.
  • Token-auth mode: When Headlamp is configured for user-supplied tokens (rather than a fixed service account), each user's own RBAC bindings must include the role above. A 403 from the plugin means the logged-in user lacks the binding.
  • Audit logging: Kubernetes API audit logs will record every proxied request as a get on services/proxy in the polaris namespace. Set an appropriate audit policy level if request volume from the auto-refresh interval is a concern.

Key Constraints

  • Data source: Polaris dashboard API via K8s service proxy. Requires Polaris deployed in the polaris namespace with a polaris-dashboard service. No CRDs, no cluster write operations.
  • UI components: Use only Headlamp-provided components (@kinvolk/headlamp-plugin/lib/CommonComponents). Do not import raw MUI packages. No custom theming.
  • Error handling: Must handle 403 (RBAC denied), 404 (Polaris not installed), malformed JSON, and loading states with distinct visual states.
  • TypeScript strictness: No any, no implicit unknown casting, no dead code, no unused imports.
  • Packaging: @kinvolk/headlamp-plugin is a peer dependency. Do not bundle React or MUI.

MCP Servers

The project has MCP server integrations configured in .mcp.json:

  • Gitea (git.farh.net): Source control via gitea-mcp-server
  • Kubernetes (local): Cluster access via kubernetes-mcp-server
  • Flux (local): Flux Operator access via flux-operator-mcp