Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a051ffafed | |||
| 7f03ae6265 | |||
| 483348aef0 | |||
| 9502ca804d | |||
| cd1fa2613d | |||
| bfeb1068bb | |||
| 2aff05b632 | |||
| d37431ce8c | |||
| 36e220660d | |||
| 48d704a6b6 |
@@ -15,15 +15,20 @@ jobs:
|
||||
promotion-gate:
|
||||
name: Promotion Gate
|
||||
runs-on: ubuntu-latest
|
||||
container: ubuntu:latest
|
||||
timeout-minutes: 5
|
||||
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: apt-get update -qq && apt-get install -y --no-install-recommends ca-certificates curl jq
|
||||
|
||||
- name: Check promotion approval
|
||||
env:
|
||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
REPO: ${{ github.repository }}
|
||||
BASE_REF: ${{ github.base_ref }}
|
||||
HEAD_REF: ${{ github.head_ref }}
|
||||
run: |
|
||||
if [ -z "${PR_NUMBER}" ] || [ "${PR_NUMBER}" = "null" ]; then
|
||||
echo "::notice::No PR number in context. Skipping promotion gate."
|
||||
@@ -55,10 +60,7 @@ jobs:
|
||||
GATE_NAME="QA"
|
||||
# For plugin repos (Pipeline A), UAT approval is needed for uat→main
|
||||
# Check if the source branch is uat
|
||||
SOURCE_REF=$(curl -sf \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-H "Accept: application/json" \
|
||||
"https://git.farh.net/api/v1/repos/${REPO}/pulls/${PR_NUMBER}" | jq -r '.head.ref')
|
||||
SOURCE_REF="${HEAD_REF}"
|
||||
|
||||
if [ "${SOURCE_REF}" = "uat" ]; then
|
||||
REQUIRED_REVIEWER="pe_patty"
|
||||
@@ -109,4 +111,4 @@ jobs:
|
||||
else
|
||||
echo "Promotion gate failed: waiting for ${GATE_NAME} approval from ${REQUIRED_REVIEWER}."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
+575
@@ -0,0 +1,575 @@
|
||||
# CONTEXT.md - Headlamp Polaris Plugin
|
||||
|
||||
**Purpose**: Comprehensive reverse prompt for AI assistants working on this project.
|
||||
|
||||
---
|
||||
|
||||
## Project Overview
|
||||
|
||||
The Headlamp Polaris Plugin surfaces [Fairwinds Polaris](https://www.fairwinds.com/polaris) audit results directly inside the [Headlamp](https://headlamp.dev) Kubernetes UI. It provides a read-only dashboard showing cluster-wide security, reliability, and efficiency scores derived from Polaris policy checks.
|
||||
|
||||
- **Stack**: React + TypeScript plugin for Headlamp (v0.26+)
|
||||
- **Data Source**: Polaris dashboard API via Kubernetes service proxy (read-only)
|
||||
- **Current Version**: v0.4.1
|
||||
- **Key Constraint**: No direct Kubernetes resource access - all data fetched through service proxy
|
||||
|
||||
## Architecture & Data Flow
|
||||
|
||||
### Component Hierarchy
|
||||
|
||||
```
|
||||
src/index.tsx # Entry point: registers routes, sidebar, settings
|
||||
├── PolarisDataContext.tsx # Shared data fetch with auto-refresh
|
||||
├── components/
|
||||
│ ├── DashboardView.tsx # Overview (score, checks, top issues)
|
||||
│ ├── NamespacesListView.tsx # Namespace list with scores
|
||||
│ ├── NamespaceDetailView.tsx # Per-namespace drill-down (drawer)
|
||||
│ ├── PolarisSettings.tsx # Settings (refresh interval, URL, test)
|
||||
│ ├── AppBarScoreBadge.tsx # Cluster score badge in top nav
|
||||
│ └── InlineAuditSection.tsx # Injected into workload detail views
|
||||
└── api/
|
||||
└── polaris.ts # Types, hooks, utilities
|
||||
```
|
||||
|
||||
### Data Source
|
||||
|
||||
- **Service Proxy Path**: `/api/v1/namespaces/polaris/services/polaris-dashboard:80/proxy/results.json`
|
||||
- **Schema**: `AuditData` with `ClusterInfo`, `Results[]` containing nested `PodResult` and `ContainerResults`
|
||||
- **Method**: `ApiProxy.request()` from Headlamp plugin SDK (handles K8s API auth automatically)
|
||||
|
||||
### State Management
|
||||
|
||||
- **Pattern**: React Context (see `src/api/PolarisDataContext.tsx`)
|
||||
- **Rationale**: ADR-001 - Prevents duplicate API calls when multiple components need same data
|
||||
- **Auto-refresh**: User-configurable interval (1/5/10/30 min, default 5 min)
|
||||
- **Storage**: Refresh interval and dashboard URL stored in `localStorage`
|
||||
|
||||
### Score Computation
|
||||
|
||||
```typescript
|
||||
// Formula: (pass / total) * 100, rounded to nearest integer
|
||||
function computeScore(counts: ResultCounts): number {
|
||||
if (counts.total === 0) return 0;
|
||||
return Math.round((counts.pass / counts.total) * 100);
|
||||
}
|
||||
```
|
||||
|
||||
## Technology Constraints
|
||||
|
||||
### ⚠️ CRITICAL: Headlamp Components Only
|
||||
|
||||
**MUST** use `@kinvolk/headlamp-plugin/lib/CommonComponents`
|
||||
**NEVER** import from `@mui/material` or `@mui/icons-material`
|
||||
|
||||
**Why**: Historical issue (v0.3.2) - MUI imports caused plugin load failures. Headlamp provides all needed components as re-exports.
|
||||
|
||||
```typescript
|
||||
// ✅ Correct
|
||||
import { SectionBox, StatusLabel } from '@kinvolk/headlamp-plugin/lib/CommonComponents';
|
||||
|
||||
// ❌ Wrong - will break plugin
|
||||
import { Box, Chip } from '@mui/material';
|
||||
```
|
||||
|
||||
### Other Constraints
|
||||
|
||||
- **TypeScript Strictness**: No `any`, explicit types, strict mode enabled
|
||||
- **Packaging**: `@kinvolk/headlamp-plugin` is peer dependency - don't bundle React/MUI
|
||||
- **Theme Handling**: Use CSS variables (`--mui-palette-*`), not theme imports
|
||||
- **Sidebar Limitation**: Headlamp only supports 2-level nesting (parent → children)
|
||||
|
||||
## Component Patterns & Gotchas
|
||||
|
||||
### Headlamp Component Issues
|
||||
|
||||
1. **StatusLabel with empty status**
|
||||
```typescript
|
||||
// ❌ Renders near-invisible (muted background)
|
||||
<StatusLabel status="">{value}</StatusLabel>
|
||||
|
||||
// ✅ Use plain String() for neutral values
|
||||
<span>{String(value)}</span>
|
||||
```
|
||||
|
||||
2. **Link component crashes on plugin routes**
|
||||
```typescript
|
||||
// ❌ Headlamp Link crashes on plugin-registered routes
|
||||
import { Link } from '@kinvolk/headlamp-plugin/lib/CommonComponents';
|
||||
|
||||
// ✅ Use react-router-dom Link with Router.createRouteURL
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Router } from '@kinvolk/headlamp-plugin/lib';
|
||||
|
||||
<Link to={Router.createRouteURL('/polaris/namespaces')}>View</Link>
|
||||
```
|
||||
|
||||
3. **Visual components that work well**
|
||||
- `PercentageCircle` - Great for score display
|
||||
- `PercentageBar` - Great for check distribution
|
||||
- `SimpleTable` - Fast, clean tables
|
||||
- `NameValueTable` - Key-value pairs
|
||||
- `SectionBox` - Card containers with titles
|
||||
|
||||
### Code Conventions
|
||||
|
||||
- **Functional Components**: Always use function components with hooks
|
||||
- **Named Exports**: Prefer named exports over default exports
|
||||
- **Props Interfaces**: Define as TypeScript interfaces, not inline types
|
||||
- **Import Order**: React → third-party → Headlamp → local (auto-sorted by eslint)
|
||||
|
||||
## RBAC & Security
|
||||
|
||||
### Minimal Permission Required
|
||||
|
||||
The plugin requires **only** this RBAC permission:
|
||||
|
||||
| Verb | API Group | Resource | Resource Name | Namespace |
|
||||
|------|-----------|----------|---------------|-----------|
|
||||
| `get` | `""` (core) | `services/proxy` | `polaris-dashboard` | `polaris` |
|
||||
|
||||
### Example Role
|
||||
|
||||
```yaml
|
||||
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
|
||||
namespace: kube-system
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: polaris-proxy-reader
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
```
|
||||
|
||||
### Security Notes
|
||||
|
||||
- **Namespaced Role**: MUST be namespaced Role, NOT ClusterRole
|
||||
- **ResourceNames Required**: Always specify `resourceNames: ["polaris-dashboard"]`
|
||||
- **No Write Operations**: Plugin only performs GET, never create/update/delete
|
||||
- **Token-Auth Mode**: When Headlamp uses user tokens, each user needs the RoleBinding
|
||||
- **Network Policy**: If enforced, allow API server → `polaris-dashboard:80` ingress
|
||||
- **Audit Logging**: Every proxy request logged as K8s API audit event
|
||||
|
||||
## Development Workflow
|
||||
|
||||
### Commands
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
npm install
|
||||
|
||||
# Start development mode (hot reload at localhost:4466)
|
||||
npm start
|
||||
|
||||
# Build plugin
|
||||
npm run build
|
||||
|
||||
# Create tarball for distribution
|
||||
npm run package
|
||||
|
||||
# Type-check without emitting
|
||||
npm run tsc
|
||||
|
||||
# Lint
|
||||
npm run lint
|
||||
|
||||
# Run unit tests
|
||||
npm test
|
||||
|
||||
# Run E2E tests (requires cluster access)
|
||||
npm run e2e
|
||||
|
||||
# Format code
|
||||
npm run format
|
||||
|
||||
# Check formatting (CI)
|
||||
npm run format:check
|
||||
```
|
||||
|
||||
### Branching Strategy
|
||||
|
||||
- ✅ **ALWAYS use feature branches** for code changes (`feat/*`, `fix/*`, `docs/*`)
|
||||
- ✅ **MAY push directly to main** for: documentation-only changes, version bump commits
|
||||
- ❌ **NEVER push code changes directly to main**
|
||||
|
||||
### Commit Convention
|
||||
|
||||
Use Conventional Commits:
|
||||
- `feat:` - New feature
|
||||
- `fix:` - Bug fix
|
||||
- `docs:` - Documentation only
|
||||
- `chore:` - Maintenance (deps, config)
|
||||
- `test:` - Test changes
|
||||
- `ci:` - CI/CD changes
|
||||
|
||||
### PR Process
|
||||
|
||||
All PRs must pass:
|
||||
1. Build (`npm run build`)
|
||||
2. Lint (`npm run lint`)
|
||||
3. Type-check (`npm run tsc`)
|
||||
4. Unit tests (`npm test`)
|
||||
5. Format check (`npm run format:check`)
|
||||
|
||||
**Before committing**: Always run `npx prettier --write src/`
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### Unit Tests (Vitest)
|
||||
|
||||
```bash
|
||||
npm test # Run once
|
||||
npm run test:watch # Watch mode
|
||||
```
|
||||
|
||||
- **Framework**: Vitest with jsdom environment
|
||||
- **Test files**: `*.test.ts`, `*.test.tsx` in `src/`
|
||||
- **Setup**: `vitest.setup.ts` with `@testing-library/jest-dom`
|
||||
- **Coverage**: Focus on meaningful tests, not just numbers
|
||||
- **Test utilities**: `src/test-utils.tsx` provides test wrapper with context
|
||||
|
||||
### E2E Tests (Playwright)
|
||||
|
||||
```bash
|
||||
npm run e2e # Headless
|
||||
npm run e2e:headed # With browser UI
|
||||
```
|
||||
|
||||
- **Framework**: Playwright
|
||||
- **Test files**: `e2e/*.spec.ts`
|
||||
- `polaris.spec.ts` - Sidebar, overview, namespaces, detail drawer
|
||||
- `settings.spec.ts` - Plugin settings page
|
||||
- `appbar.spec.ts` - App bar score badge
|
||||
- **Auth**: Supports both OIDC (Authentik) and token-based auth (see `e2e/auth.setup.ts`)
|
||||
- **CI**: Runs on GitHub Actions with `k3s-animaniacs` runner
|
||||
|
||||
### Local E2E Setup
|
||||
|
||||
```bash
|
||||
# Token-based auth
|
||||
export HEADLAMP_TOKEN=$(kubectl create token headlamp -n kube-system --duration=24h)
|
||||
npm run e2e
|
||||
|
||||
# OIDC auth (Authentik)
|
||||
export AUTHENTIK_USERNAME=your-username
|
||||
export AUTHENTIK_PASSWORD=your-password
|
||||
npm run e2e
|
||||
```
|
||||
|
||||
## CI/CD & Release
|
||||
|
||||
### CI Workflow (`.github/workflows/ci.yaml`)
|
||||
|
||||
Runs on push to main and all PRs:
|
||||
1. Checkout
|
||||
2. `npm ci`
|
||||
3. `npm run build`
|
||||
4. `npm run lint`
|
||||
5. `npm run tsc`
|
||||
6. `npm run format:check`
|
||||
7. `npm test`
|
||||
|
||||
Runner: `local-ubuntu-latest`
|
||||
|
||||
### E2E Workflow (`.github/workflows/e2e.yaml`)
|
||||
|
||||
Runs on push, PR, and manual trigger:
|
||||
1. Checkout
|
||||
2. `npm ci`
|
||||
3. `npm run e2e`
|
||||
|
||||
Runner: `k3s-animaniacs` (has cluster access)
|
||||
Requires: `HEADLAMP_URL`, `HEADLAMP_TOKEN` or `AUTHENTIK_USERNAME`/`AUTHENTIK_PASSWORD`
|
||||
|
||||
### Release Workflow (`.github/workflows/release.yaml`)
|
||||
|
||||
**Manual trigger** via workflow_dispatch with version input:
|
||||
|
||||
```bash
|
||||
# Via GitHub UI or CLI
|
||||
gh workflow run release.yaml -f version=0.4.2
|
||||
```
|
||||
|
||||
Steps:
|
||||
1. Validate version format (semver)
|
||||
2. Bump `package.json` + `artifacthub-pkg.yml`
|
||||
3. Build plugin
|
||||
4. Package tarball
|
||||
5. Compute SHA256 checksum
|
||||
6. Commit version bump
|
||||
7. Create git tag
|
||||
8. Create GitHub release
|
||||
9. Upload tarball to release
|
||||
|
||||
**Guard**: Skips if checksum already matches (prevents infinite loop)
|
||||
|
||||
**Post-release**: ArtifactHub pulls metadata every 30 min (no webhook, pull-based)
|
||||
|
||||
### Version Bump Requirements
|
||||
|
||||
**ALWAYS bump both files in the same commit**:
|
||||
- `package.json` - `version` field
|
||||
- `artifacthub-pkg.yml` - `version` field + `digest` (checksum) + `archive.url`
|
||||
|
||||
## Known Issues & Workarounds
|
||||
|
||||
### ⚠️ Headlamp v0.39.0 Known Issues
|
||||
|
||||
**AutoSizer JavaScript Error**
|
||||
- **Symptom**: Console shows `TypeError: undefined is not an object (evaluating 'io.AutoSizer')`
|
||||
- **Impact**: Cosmetic error in Settings page, doesn't break functionality
|
||||
- **Root Cause**: Headlamp core bug, not plugin-related
|
||||
- **Workaround**: None needed, can be ignored
|
||||
|
||||
**Plugin Loading (RESOLVED)**
|
||||
- **Old Issue**: Previously thought `config.watchPlugins: false` was required
|
||||
- **Resolution**: Plugins load correctly with default `watchPlugins: true`
|
||||
- **Note**: If you see old docs mentioning `watchPlugins: false`, ignore them
|
||||
|
||||
### Polaris Dashboard Behavior
|
||||
|
||||
**Stale Audit Data**
|
||||
- **Symptom**: Plugin shows old audit timestamp
|
||||
- **Root Cause**: Polaris dashboard runs audit once at pod startup, then caches results
|
||||
- **Does NOT**: Continuously re-audit in real-time
|
||||
- **Workaround**: Restart Polaris pods for fresh data
|
||||
```bash
|
||||
kubectl rollout restart deployment -n polaris polaris-dashboard
|
||||
```
|
||||
- **Load Balancing**: Service balances across multiple pods - each may have different audit timestamps
|
||||
- **Plugin Auto-Refresh**: Works correctly - just fetches whatever Polaris currently has cached
|
||||
|
||||
### Skipped Count Limitation
|
||||
|
||||
**What It Shows**:
|
||||
- Only checks with `Severity: "ignore"` in Polaris API response
|
||||
- Does NOT include annotation-based exemptions (`polaris.fairwinds.com/*-exempt`)
|
||||
|
||||
**Why**:
|
||||
- Polaris omits exempted checks from `results.json`
|
||||
- Plugin has no access to raw K8s resources to compute exemptions
|
||||
- By design: service proxy limitation
|
||||
|
||||
**Workaround**:
|
||||
- Link to native Polaris dashboard for full exemption count
|
||||
- UI tooltip explains this limitation
|
||||
|
||||
## Deployment Patterns
|
||||
|
||||
### Plugin Manager (Recommended)
|
||||
|
||||
Install via Headlamp UI (Settings → Plugins → Catalog) or Helm values:
|
||||
|
||||
```yaml
|
||||
pluginsManager:
|
||||
enabled: true
|
||||
configContent: |
|
||||
plugins:
|
||||
- name: polaris
|
||||
source: https://artifacthub.io/packages/headlamp/polaris/headlamp-polaris-plugin
|
||||
```
|
||||
|
||||
### Sidecar Container (Alternative)
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
containers:
|
||||
- name: headlamp
|
||||
# ... main container
|
||||
- name: headlamp-plugin
|
||||
image: node:lts-alpine
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- |
|
||||
npx @headlamp-k8s/pluginctl@latest install \
|
||||
--config /config/plugin.yml \
|
||||
--folderName /headlamp/plugins \
|
||||
--watch
|
||||
volumeMounts:
|
||||
- name: plugins-dir
|
||||
mountPath: /headlamp/plugins
|
||||
- name: plugin-config
|
||||
mountPath: /config
|
||||
volumes:
|
||||
- name: plugins-dir
|
||||
emptyDir: {}
|
||||
- name: plugin-config
|
||||
configMap:
|
||||
name: headlamp-plugin-config
|
||||
```
|
||||
|
||||
### Manual Tarball
|
||||
|
||||
```bash
|
||||
# Download release
|
||||
wget https://github.com/cpfarhood/headlamp-polaris-plugin/releases/download/v0.4.1/headlamp-polaris-plugin-0.4.1.tgz
|
||||
|
||||
# Extract to plugin directory
|
||||
tar -xzf headlamp-polaris-plugin-0.4.1.tgz -C /headlamp/plugins/
|
||||
|
||||
# Restart Headlamp
|
||||
kubectl rollout restart deployment headlamp -n kube-system
|
||||
```
|
||||
|
||||
## Project Files Reference
|
||||
|
||||
```
|
||||
src/
|
||||
index.tsx # Entry point: registers sidebar, routes, settings, etc.
|
||||
api/
|
||||
polaris.ts # Core types, usePolarisData hook, utilities
|
||||
PolarisDataContext.tsx # React Context provider for shared data
|
||||
components/
|
||||
DashboardView.tsx # Overview page (score, checks, top issues)
|
||||
NamespacesListView.tsx # Namespace table with scores
|
||||
NamespaceDetailView.tsx # Drawer panel with per-namespace drill-down
|
||||
PolarisSettings.tsx # Settings page (refresh, URL, test)
|
||||
AppBarScoreBadge.tsx # Cluster score chip in top nav bar
|
||||
InlineAuditSection.tsx # Injected into resource detail views
|
||||
test-utils.tsx # Test helpers (wrapper with context)
|
||||
|
||||
.github/workflows/
|
||||
ci.yaml # Lint, type-check, build, test
|
||||
e2e.yaml # Playwright E2E tests
|
||||
release.yaml # Automated releases
|
||||
|
||||
e2e/ # Playwright tests
|
||||
polaris.spec.ts # Main plugin functionality
|
||||
settings.spec.ts # Settings page
|
||||
appbar.spec.ts # App bar badge
|
||||
auth.setup.ts # OIDC/token auth setup
|
||||
|
||||
docs/ # Comprehensive documentation
|
||||
architecture/ # Overview, design decisions, ADRs
|
||||
deployment/ # Helm, Kubernetes, production guides
|
||||
troubleshooting/ # Common issues, RBAC, network problems
|
||||
getting-started/ # Quick start, prerequisites, installation
|
||||
|
||||
package.json # Version, scripts, dependencies
|
||||
artifacthub-pkg.yml # ArtifactHub metadata (version, checksum)
|
||||
tsconfig.json # Extends @kinvolk/headlamp-plugin config
|
||||
vitest.config.mts # Vitest config (jsdom, excludes e2e/)
|
||||
.eslintrc.js # Extends @headlamp-k8s/eslint-config
|
||||
.prettierrc.js # Uses @headlamp-k8s prettier config
|
||||
```
|
||||
|
||||
## MCP Servers (Claude Code)
|
||||
|
||||
- **GitHub**: Source control (`github-mcp-server`), repo at `cpfarhood/headlamp-polaris-plugin`
|
||||
- **Kubernetes (local)**: Cluster access via `kubernetes-mcp-server`
|
||||
- **Flux (local)**: Flux Operator access via `flux-operator-mcp`
|
||||
- **Playwright**: Browser automation via `@playwright/mcp`
|
||||
|
||||
## Common Tasks Quick Reference
|
||||
|
||||
```bash
|
||||
# Start development
|
||||
npm install && npm start
|
||||
|
||||
# Run all checks before PR
|
||||
npm run build && npm run lint && npm run tsc && npm test && npm run format
|
||||
|
||||
# Create release (maintainers only)
|
||||
# 1. Edit CHANGELOG.md
|
||||
# 2. Trigger release workflow:
|
||||
gh workflow run release.yaml -f version=0.4.2
|
||||
|
||||
# Run E2E tests locally
|
||||
export HEADLAMP_TOKEN=$(kubectl create token headlamp -n kube-system --duration=24h)
|
||||
npm run e2e
|
||||
|
||||
# Fix formatting issues
|
||||
npx prettier --write src/
|
||||
|
||||
# Check Polaris audit freshness
|
||||
kubectl get --raw "/api/v1/namespaces/polaris/services/polaris-dashboard:80/proxy/results.json" | jq -r '.AuditTime'
|
||||
|
||||
# Restart Polaris for fresh audit
|
||||
kubectl rollout restart deployment -n polaris polaris-dashboard
|
||||
```
|
||||
|
||||
## Anti-Patterns (What NOT to Do)
|
||||
|
||||
- ❌ Import from `@mui/material` or `@mui/icons-material` → breaks plugin
|
||||
- ❌ Use `any` type → strict TypeScript required
|
||||
- ❌ Push code changes directly to main → always use feature branches
|
||||
- ❌ Grant broader RBAC than `get services/proxy` → security risk
|
||||
- ❌ Use ClusterRole instead of namespaced Role → violates least privilege
|
||||
- ❌ Forget to run `npx prettier --write src/` → CI will fail
|
||||
- ❌ Use inline styles without CSS variables → breaks dark mode
|
||||
- ❌ Try to query K8s resources directly → plugin only has service proxy access
|
||||
- ❌ Import Headlamp `Link` for plugin routes → use react-router-dom `Link` + `Router.createRouteURL()`
|
||||
- ❌ Assume Polaris continuously re-audits → it only audits at pod startup
|
||||
|
||||
## Quick Diagnosis Guide
|
||||
|
||||
```
|
||||
Symptom: Plugin not in sidebar
|
||||
→ Check: Hard refresh browser (Cmd+Shift+R / Ctrl+Shift+R)
|
||||
→ Check: Plugin installed? kubectl get configmap headlamp-plugin-config -n kube-system
|
||||
|
||||
Symptom: 403 Access Denied
|
||||
→ Check: RBAC binding exists? kubectl get role,rolebinding -n polaris
|
||||
→ Fix: Apply RBAC example from docs/deployment/rbac.md
|
||||
|
||||
Symptom: 404 or 503
|
||||
→ Check: Polaris installed? kubectl get pods -n polaris
|
||||
→ Check: Service exists? kubectl get svc polaris-dashboard -n polaris
|
||||
|
||||
Symptom: Stale audit data
|
||||
→ Fix: kubectl rollout restart deployment -n polaris polaris-dashboard
|
||||
→ Verify: Check AuditTime in UI matches current date
|
||||
|
||||
Symptom: Settings page empty or broken
|
||||
→ Check: Plugin version ≥ v0.3.3?
|
||||
→ Fix: Upgrade plugin and hard refresh browser
|
||||
|
||||
Symptom: CI prettier check fails
|
||||
→ Fix: npx prettier --write src/
|
||||
→ Commit: Include formatting fixes in your PR
|
||||
|
||||
Symptom: Dark mode white backgrounds
|
||||
→ Check: Plugin version ≥ v0.3.5?
|
||||
→ Fix: Upgrade and hard refresh browser
|
||||
```
|
||||
|
||||
## Historical Context
|
||||
|
||||
### Why Service Proxy Instead of ConfigMaps?
|
||||
|
||||
Early versions (< v0.0.10) incorrectly documented ConfigMap RBAC. The plugin **never** accessed ConfigMaps - it always used the service proxy. This was clarified in v0.0.10.
|
||||
|
||||
### Why No MUI Imports?
|
||||
|
||||
v0.3.2 removed direct MUI imports because they caused plugin load failures. Headlamp provides all needed MUI components as re-exports through `CommonComponents`.
|
||||
|
||||
### Why React Context?
|
||||
|
||||
ADR-001 documents the switch to React Context. Before v0.3.0, each component called `usePolarisData()` independently, causing duplicate API requests. Context ensures a single shared fetch.
|
||||
|
||||
### Why No Continuous Polaris Audits?
|
||||
|
||||
Polaris dashboard mode runs a one-time audit at pod startup and caches results. This is by design in Polaris itself. For continuous auditing, Polaris would need to be configured in webhook mode (admission controller), which is a different deployment pattern.
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2026-02-12
|
||||
**Version**: v0.4.1
|
||||
**Target Headlamp**: v0.26+
|
||||
**Target Polaris**: v9.x
|
||||
@@ -0,0 +1,290 @@
|
||||
# Headlamp Polaris Plugin - Project Assessment
|
||||
|
||||
**Date:** 2026-02-11
|
||||
**Version:** v0.3.0
|
||||
**Status:** Active Development
|
||||
|
||||
## Executive Summary
|
||||
|
||||
This assessment identifies critical issues and improvement opportunities for the headlamp-polaris-plugin project. The plugin is currently non-functional in production due to Headlamp v0.39.0 compatibility issues, and has several TypeScript compilation errors that need immediate attention.
|
||||
|
||||
---
|
||||
|
||||
## 🔴 Critical Issues (Must Fix Immediately)
|
||||
|
||||
### 1. TypeScript Compilation Errors
|
||||
**Severity:** CRITICAL
|
||||
**Impact:** Build failures, type safety compromised
|
||||
|
||||
**Issues:**
|
||||
- `src/index.tsx:72` - `registerDetailsViewSection` expects 1 argument, got 2
|
||||
- `src/index.tsx:87` - `registerAppBarAction` expects 1 argument, got 2
|
||||
|
||||
**Recommendation:**
|
||||
Update Headlamp plugin API calls to match the current version. Check @kinvolk/headlamp-plugin version compatibility.
|
||||
|
||||
**Action Items:**
|
||||
- [ ] Review Headlamp plugin API documentation
|
||||
- [ ] Update `registerDetailsViewSection` and `registerAppBarAction` calls
|
||||
- [ ] Run `npm run tsc` to verify fixes
|
||||
- [ ] Update CI to fail on TypeScript errors
|
||||
|
||||
---
|
||||
|
||||
### 2. Production Plugin Loading Failure
|
||||
**Severity:** CRITICAL
|
||||
**Impact:** Plugin is completely non-functional in production
|
||||
|
||||
**Root Cause:**
|
||||
Headlamp v0.39.0 with default `watchPlugins: true` treats catalog-managed plugins as "development directory" plugins, preventing frontend JavaScript execution.
|
||||
|
||||
**Current Status:**
|
||||
- Deployment patched to install plugins to `/headlamp/static-plugins`
|
||||
- `watchPlugins: false` configured
|
||||
- Waiting for user to test if plugins now load
|
||||
|
||||
**Action Items:**
|
||||
- [ ] Confirm plugins load after recent deployment changes
|
||||
- [ ] Document the fix in deployment guide
|
||||
- [ ] Update MEMORY.md with final resolution
|
||||
- [ ] Consider downgrading Headlamp if issue persists
|
||||
|
||||
---
|
||||
|
||||
### 3. Test Failures
|
||||
**Severity:** HIGH
|
||||
**Impact:** CI failures, reduced confidence in changes
|
||||
|
||||
**Current Status:**
|
||||
- 1 test file failing (DashboardView)
|
||||
- 49 tests passing
|
||||
- Error related to `SimpleTable` component mock
|
||||
|
||||
**Action Items:**
|
||||
- [ ] Fix DashboardView test mocking
|
||||
- [ ] Ensure all tests pass before merging PRs
|
||||
- [ ] Add test for top issues feature
|
||||
- [ ] Increase test coverage to >80%
|
||||
|
||||
---
|
||||
|
||||
## 🟡 High Priority Improvements
|
||||
|
||||
### 4. Type Safety Enhancements
|
||||
**Severity:** HIGH
|
||||
**Impact:** Better developer experience, catch errors earlier
|
||||
|
||||
**Recommendations:**
|
||||
- Enable stricter TypeScript checks in `tsconfig.json`
|
||||
- Add type definitions for all Headlamp plugin APIs
|
||||
- Ensure no `any` types in production code
|
||||
- Add JSDoc comments for complex types
|
||||
|
||||
**Action Items:**
|
||||
- [ ] Audit codebase for `any` types
|
||||
- [ ] Enable `noImplicitAny` and `strictNullChecks`
|
||||
- [ ] Add type guards for API responses
|
||||
- [ ] Document complex type structures
|
||||
|
||||
---
|
||||
|
||||
### 5. Security Hardening
|
||||
**Severity:** HIGH
|
||||
**Impact:** Prevent vulnerabilities, protect user data
|
||||
|
||||
**Current Risks:**
|
||||
- Direct Kubernetes API access via service proxy
|
||||
- User input in exemption annotations (potential injection)
|
||||
- External URL configuration for Polaris dashboard
|
||||
|
||||
**Recommendations:**
|
||||
- Validate and sanitize all user inputs
|
||||
- Implement input validation for dashboard URL
|
||||
- Add CSRF protection for exemption management
|
||||
- Audit dependencies for known vulnerabilities
|
||||
|
||||
**Action Items:**
|
||||
- [ ] Add input validation utilities
|
||||
- [ ] Sanitize exemption annotation values
|
||||
- [ ] Validate URL format for dashboard configuration
|
||||
- [ ] Run `npm audit` and fix vulnerabilities
|
||||
- [ ] Add security testing to CI/CD
|
||||
|
||||
---
|
||||
|
||||
### 6. Error Handling & User Experience
|
||||
**Severity:** MEDIUM
|
||||
**Impact:** Better error messages, improved debugging
|
||||
|
||||
**Current Gaps:**
|
||||
- Generic error messages don't help users troubleshoot
|
||||
- No retry logic for transient API failures
|
||||
- Missing loading states in some components
|
||||
|
||||
**Recommendations:**
|
||||
- Provide specific, actionable error messages
|
||||
- Implement retry logic with exponential backoff
|
||||
- Add loading skeletons for all async operations
|
||||
- Show connection test results with specific failure reasons
|
||||
|
||||
**Action Items:**
|
||||
- [ ] Create error message constants with solutions
|
||||
- [ ] Add retry logic to API calls
|
||||
- [ ] Implement loading skeletons
|
||||
- [ ] Improve connection test error messages
|
||||
|
||||
---
|
||||
|
||||
## 🟢 Medium Priority Enhancements
|
||||
|
||||
### 7. Testing Coverage
|
||||
**Severity:** MEDIUM
|
||||
**Impact:** Confidence in changes, regression prevention
|
||||
|
||||
**Current Coverage:**
|
||||
- Unit tests: Good coverage for API utilities
|
||||
- Component tests: Some coverage, gaps exist
|
||||
- E2E tests: Minimal (Playwright configured but underutilized)
|
||||
|
||||
**Recommendations:**
|
||||
- Add E2E tests for critical user flows
|
||||
- Test error scenarios and edge cases
|
||||
- Add visual regression tests
|
||||
- Test RBAC permission denied scenarios
|
||||
|
||||
**Action Items:**
|
||||
- [ ] Write E2E test for complete audit workflow
|
||||
- [ ] Add tests for error states
|
||||
- [ ] Test exemption management flow
|
||||
- [ ] Add Playwright tests to CI
|
||||
|
||||
---
|
||||
|
||||
### 8. Performance Optimization
|
||||
**Severity:** MEDIUM
|
||||
**Impact:** Faster load times, better UX
|
||||
|
||||
**Opportunities:**
|
||||
- Memoize expensive calculations (score computation)
|
||||
- Lazy load namespace detail views
|
||||
- Debounce search/filter operations
|
||||
- Cache Polaris data with stale-while-revalidate
|
||||
|
||||
**Action Items:**
|
||||
- [ ] Add React.memo to pure components
|
||||
- [ ] Memoize score calculations
|
||||
- [ ] Implement data caching strategy
|
||||
- [ ] Profile component render times
|
||||
|
||||
---
|
||||
|
||||
### 9. Code Quality & Maintainability
|
||||
**Severity:** MEDIUM
|
||||
**Impact:** Easier maintenance, onboarding
|
||||
|
||||
**Recommendations:**
|
||||
- Extract magic strings to constants
|
||||
- Reduce component complexity
|
||||
- Add JSDoc comments for public APIs
|
||||
- Improve code organization
|
||||
|
||||
**Action Items:**
|
||||
- [ ] Create constants file for check IDs
|
||||
- [ ] Split large components (DashboardView, NamespaceDetailView)
|
||||
- [ ] Add comments for complex logic
|
||||
- [ ] Establish code review checklist
|
||||
|
||||
---
|
||||
|
||||
## 🔵 Low Priority / Future Enhancements
|
||||
|
||||
### 10. Documentation
|
||||
**Severity:** LOW
|
||||
**Impact:** Better onboarding, user adoption
|
||||
|
||||
**Gaps:**
|
||||
- No architecture documentation
|
||||
- Limited inline code comments
|
||||
- Missing troubleshooting guide
|
||||
- No contributor guidelines
|
||||
|
||||
**Action Items:**
|
||||
- [ ] Create architecture diagram
|
||||
- [ ] Document component hierarchy
|
||||
- [ ] Add troubleshooting section to README
|
||||
- [ ] Create CONTRIBUTING.md
|
||||
|
||||
---
|
||||
|
||||
### 11. CI/CD Pipeline Optimization
|
||||
**Severity:** LOW
|
||||
**Impact:** Faster feedback, automated releases
|
||||
|
||||
**Opportunities:**
|
||||
- Run tests in parallel
|
||||
- Cache npm dependencies
|
||||
- Add automated security scanning
|
||||
- Implement semantic versioning
|
||||
|
||||
**Action Items:**
|
||||
- [ ] Parallelize test execution
|
||||
- [ ] Add npm cache to GitHub Actions
|
||||
- [x] Renovate is configured org-wide via `github>privilegedescalation/.github:renovate-config`
|
||||
- [ ] Add semantic-release
|
||||
|
||||
---
|
||||
|
||||
## Summary & Prioritization
|
||||
|
||||
### Week 1 (Immediate)
|
||||
1. ✅ Fix TypeScript compilation errors
|
||||
2. ✅ Resolve production plugin loading issue
|
||||
3. ✅ Fix failing DashboardView test
|
||||
|
||||
### Week 2 (High Priority)
|
||||
4. Enhance type safety (strict mode)
|
||||
5. Implement security hardening
|
||||
6. Improve error handling and UX
|
||||
|
||||
### Week 3-4 (Medium Priority)
|
||||
7. Increase test coverage to >80%
|
||||
8. Optimize performance (memoization, caching)
|
||||
9. Refactor for maintainability
|
||||
|
||||
### Ongoing (Low Priority)
|
||||
10. Documentation improvements
|
||||
11. CI/CD optimizations
|
||||
|
||||
---
|
||||
|
||||
## Success Metrics
|
||||
|
||||
**Code Quality:**
|
||||
- ✅ Zero TypeScript errors
|
||||
- ✅ All tests passing
|
||||
- 🎯 Test coverage >80%
|
||||
- 🎯 No high/critical security vulnerabilities
|
||||
|
||||
**Production Readiness:**
|
||||
- ✅ Plugin loads successfully in Headlamp
|
||||
- ✅ All features functional
|
||||
- 🎯 Error rate <1%
|
||||
- 🎯 Average response time <500ms
|
||||
|
||||
**Developer Experience:**
|
||||
- ✅ Clear documentation
|
||||
- ✅ Easy local setup
|
||||
- 🎯 Fast CI/CD (<5 min)
|
||||
- 🎯 Automated releases
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. **Immediate:** Fix TypeScript errors and verify plugin loads
|
||||
2. **Short-term:** Complete Week 1-2 priorities
|
||||
3. **Long-term:** Address medium and low priority items
|
||||
4. **Continuous:** Monitor metrics and iterate
|
||||
|
||||
**Recommended First Action:**
|
||||
Fix the TypeScript compilation errors in `src/index.tsx` by updating the Headlamp plugin API calls.
|
||||
@@ -0,0 +1,98 @@
|
||||
# PRI-324 Spec: Make E2E Workflow Self-Sufficient with RBAC
|
||||
|
||||
## Context
|
||||
|
||||
PR #123 introduced an RBAC pre-flight check to the E2E workflow. QA (Nancy, acting as QA) verified the "fails fast without RBAC" path works, but found that the "with RBAC passes" path had no green CI evidence — the workflow did not apply RBAC before the pre-flight check.
|
||||
|
||||
PR #131 attempted to fix this by adding `kubectl apply` steps and extending the CI runner RBAC, but its merge commit (739db6fe) was reverted by the next commit on main (aa1db921) due to a vulnerability fix PR (#128).
|
||||
|
||||
The current E2E workflow on `main` lacks the RBAC apply steps and CI runner permissions needed to make the pre-flight check meaningful.
|
||||
|
||||
## Required Changes
|
||||
|
||||
### 1. `.github/workflows/e2e.yaml`
|
||||
|
||||
Add between the "Setup kubectl" and "Install dependencies" steps:
|
||||
|
||||
```yaml
|
||||
- name: Apply RBAC for E2E pipeline
|
||||
run: |
|
||||
set -x
|
||||
kubectl apply -f deployment/e2e-ci-runner-rbac.yaml --dry-run=server 2>&1 || true
|
||||
kubectl apply -f deployment/e2e-ci-runner-rbac.yaml 2>&1
|
||||
echo "exit code: $?"
|
||||
echo "Waiting for RBAC propagation..."
|
||||
sleep 5
|
||||
echo "Verifying CI runner permissions..."
|
||||
kubectl auth can-i create roles -n headlamp-dev --as="system:serviceaccount:arc-runners:runners-privilegedescalation-gha-rs-no-permission" 2>&1 || { echo "::error::CI runner still lacks roles permission after propagation wait"; exit 1; }
|
||||
set +x
|
||||
|
||||
- name: Apply Polaris dashboard RBAC
|
||||
run: kubectl apply -f deployment/polaris-rbac.yaml
|
||||
|
||||
- name: RBAC pre-flight check
|
||||
run: |
|
||||
echo "Checking RBAC resources..."
|
||||
MISSING=0
|
||||
kubectl get role polaris-dashboard-proxy-reader -n polaris -o name >/dev/null 2>&1 || MISSING=1
|
||||
kubectl get rolebinding polaris-dashboard-proxy-reader -n polaris -o name >/dev/null 2>&1 || MISSING=1
|
||||
kubectl auth can-i delete configmaps -n "$E2E_NAMESPACE" --quiet 2>/dev/null || MISSING=1
|
||||
if [ "$MISSING" -eq 0 ]; then
|
||||
echo "RBAC pre-flight check passed."
|
||||
else
|
||||
echo "::error::RBAC pre-flight check failed. Missing required permissions."
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
### 2. `deployment/e2e-ci-runner-rbac.yaml`
|
||||
|
||||
Add a new Role + RoleBinding for the `polaris` namespace (from PR #131):
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: e2e-ci-runner-polaris
|
||||
namespace: polaris
|
||||
rules:
|
||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
||||
resources: ["roles", "rolebindings"]
|
||||
verbs: ["get", "list", "create", "update", "patch", "delete"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: e2e-ci-runner-polaris
|
||||
namespace: polaris
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: runners-privilegedescalation-gha-rs-no-permission
|
||||
namespace: arc-runners
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: e2e-ci-runner-polaris
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
```
|
||||
|
||||
And add to the existing `e2e-ci-runner` Role in the `headlamp-dev` namespace:
|
||||
```yaml
|
||||
# Apply Polaris dashboard RBAC in the polaris namespace
|
||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
||||
resources: ["roles", "rolebindings"]
|
||||
verbs: ["get", "list", "create", "update", "patch", "delete"]
|
||||
```
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] Workflow applies `deployment/e2e-ci-runner-rbac.yaml` before the pre-flight check
|
||||
- [ ] Workflow applies `deployment/polaris-rbac.yaml` before the pre-flight check
|
||||
- [ ] CI runner has RBAC to apply the manifests (added via new Role+RoleBinding in polaris namespace)
|
||||
- [ ] E2E pipeline passes on the PR branch (proof of green path)
|
||||
- [ ] `kubectl get … --quiet` flag removed (QA nit)
|
||||
- [ ] `MISSING_ROLE`/`MISSING_ROLEBINDING` collapsed to single `MISSING` flag (QA nit)
|
||||
|
||||
## Definition of Done
|
||||
|
||||
PR #123 QA changes-requested are addressed: the workflow is self-sufficient (applies its own RBAC), the green path is demonstrated, and QA review is re-requested.
|
||||
+43
-48
@@ -1,28 +1,30 @@
|
||||
version: 1.0.1
|
||||
version: "1.0.0"
|
||||
name: headlamp-polaris
|
||||
displayName: Polaris
|
||||
createdAt: '2026-05-20T00:00:00Z'
|
||||
description: Surfaces Fairwinds Polaris audit results inside the Headlamp UI. Shows
|
||||
cluster score, check summary, and per-namespace drill-downs with per-resource pass/warning/danger
|
||||
breakdowns. Data is fetched read-only via the Kubernetes service proxy to the Polaris
|
||||
dashboard. Requires a Role granting `get` on `services/proxy` for the `polaris-dashboard`
|
||||
service in the `polaris` namespace.
|
||||
createdAt: "2026-02-05T19:00:00Z"
|
||||
description: >-
|
||||
Surfaces Fairwinds Polaris audit results inside the Headlamp UI.
|
||||
Shows cluster score, check summary, and per-namespace drill-downs
|
||||
with per-resource pass/warning/danger breakdowns. Data is fetched
|
||||
read-only via the Kubernetes service proxy to the Polaris dashboard.
|
||||
Requires a Role granting `get` on `services/proxy` for the
|
||||
`polaris-dashboard` service in the `polaris` namespace.
|
||||
license: Apache-2.0
|
||||
homeURL: https://github.com/privilegedescalation/headlamp-polaris-plugin
|
||||
appVersion: 10.1.6
|
||||
homeURL: "https://github.com/privilegedescalation/headlamp-polaris-plugin"
|
||||
appVersion: "10.1.6"
|
||||
category: security
|
||||
keywords:
|
||||
- polaris
|
||||
- fairwinds
|
||||
- security
|
||||
- audit
|
||||
- headlamp
|
||||
- kubernetes
|
||||
- polaris
|
||||
- fairwinds
|
||||
- security
|
||||
- audit
|
||||
- headlamp
|
||||
- kubernetes
|
||||
links:
|
||||
- name: Source
|
||||
url: https://github.com/privilegedescalation/headlamp-polaris-plugin
|
||||
- name: Polaris
|
||||
url: https://polaris.docs.fairwinds.com/
|
||||
- name: Source
|
||||
url: "https://github.com/privilegedescalation/headlamp-polaris-plugin"
|
||||
- name: Polaris
|
||||
url: "https://polaris.docs.fairwinds.com/"
|
||||
install: |
|
||||
## Installation
|
||||
|
||||
@@ -48,34 +50,27 @@ install: |
|
||||
|
||||
For more information, see the [README](https://github.com/privilegedescalation/headlamp-polaris-plugin/blob/main/README.md).
|
||||
changes:
|
||||
- kind: security
|
||||
description: Patched 8 npm audit vulnerabilities via pnpm.overrides
|
||||
- kind: added
|
||||
description: Dual-approval required CI check — PRs must be approved by both CTO
|
||||
and QA before merge
|
||||
- kind: added
|
||||
description: ExemptionManager test suite — full coverage of annotation-based exemption
|
||||
flows
|
||||
- kind: fixed
|
||||
description: E2E infrastructure overhauled — ConfigMap volume mount replaces Dockerfile-based
|
||||
approach, tests run in privilegedescalation-dev namespace
|
||||
- kind: fixed
|
||||
description: E2E workflow uses token auth and waits for HTTP reachability before
|
||||
running tests
|
||||
- kind: fixed
|
||||
description: Added explicit direct devDependencies (typescript, eslint, prettier,
|
||||
@headlamp-k8s/eslint-config) to prevent phantom dep failures
|
||||
- kind: changed
|
||||
description: pnpm version pinned via packageManager field; GitHub Actions SHA-pinned
|
||||
via Renovate pinDigests
|
||||
- kind: changed
|
||||
description: v1.0.0 stable release — plugin API (routes, sidebar, settings schema,
|
||||
app bar action) is stable and will not change without a major version bump
|
||||
- kind: security
|
||||
description: Patched 8 npm audit vulnerabilities via pnpm.overrides
|
||||
- kind: added
|
||||
description: Dual-approval required CI check — PRs must be approved by both CTO and QA before merge
|
||||
- kind: added
|
||||
description: ExemptionManager test suite — full coverage of annotation-based exemption flows
|
||||
- kind: fixed
|
||||
description: E2E infrastructure overhauled — ConfigMap volume mount replaces Dockerfile-based approach, tests run in privilegedescalation-dev namespace
|
||||
- kind: fixed
|
||||
description: E2E workflow uses token auth and waits for HTTP reachability before running tests
|
||||
- kind: fixed
|
||||
description: Added explicit direct devDependencies (typescript, eslint, prettier, @headlamp-k8s/eslint-config) to prevent phantom dep failures
|
||||
- kind: changed
|
||||
description: pnpm version pinned via packageManager field; GitHub Actions SHA-pinned via Renovate pinDigests
|
||||
- kind: changed
|
||||
description: v1.0.0 stable release — plugin API (routes, sidebar, settings schema, app bar action) is stable and will not change without a major version bump
|
||||
maintainers:
|
||||
- name: privilegedescalation
|
||||
email: chris@farhood.org
|
||||
- name: privilegedescalation
|
||||
email: "chris@farhood.org"
|
||||
annotations:
|
||||
headlamp/plugin/archive-url: https://git.farh.net/privilegedescalation/headlamp-polaris-plugin/releases/download/v1.0.1/headlamp-polaris-1.0.1.tar.gz
|
||||
headlamp/plugin/version-compat: '>=0.26'
|
||||
headlamp/plugin/archive-checksum: sha256:1e05d079c7032cf55ebde85e116cb65b686d207f4b6a3b0f716f0af93f933e7e
|
||||
headlamp/plugin/distro-compat: in-cluster,web,desktop
|
||||
headlamp/plugin/archive-url: "https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/download/v1.0.0/headlamp-polaris-1.0.0.tar.gz"
|
||||
headlamp/plugin/version-compat: ">=0.26"
|
||||
headlamp/plugin/archive-checksum: sha256:a165e871b40f11a44950aa9f10eb7f7883276f749026ae7a4f886278ecd9bd7d
|
||||
headlamp/plugin/distro-compat: "in-cluster,web,desktop"
|
||||
|
||||
Reference in New Issue
Block a user