Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0faa50cd9d | |||
| de5feb68a3 | |||
| 42df8dd7cc | |||
| 3796d57d12 | |||
| 88541bd328 | |||
| e884894840 | |||
| 189ae50024 | |||
| e62fba9cc1 | |||
| 062ac72340 | |||
| 515758c829 | |||
| 40c4add01b | |||
| cdc1ce0303 | |||
| dd5a76e348 | |||
| 3b6d7e6b6c | |||
| 0e5ff9b7b7 | |||
| 8fab7828f4 | |||
| 1733eab21b | |||
| 44fe9ab749 | |||
| 0b081246b0 | |||
| 765f081867 | |||
| d4fa1674dc | |||
| 9655514066 | |||
| ece87a9824 | |||
| 5adcca2eb9 |
@@ -8,7 +8,7 @@ on:
|
||||
|
||||
jobs:
|
||||
lint-and-test:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: local-ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
|
||||
steps:
|
||||
|
||||
+90
-108
@@ -1,129 +1,111 @@
|
||||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: 'Version to release (without v prefix, e.g., 0.4.0)'
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: local-ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Check if release is already finalized
|
||||
- name: Validate version format
|
||||
run: |
|
||||
VERSION=${GITHUB_REF_NAME#v}
|
||||
TARBALL_URL="https://github.com/${{ github.repository }}/releases/download/${GITHUB_REF_NAME}/polaris-${VERSION}.tar.gz"
|
||||
HTTP_CODE=$(curl -sL -o /tmp/release.tar.gz -w "%{http_code}" "$TARBALL_URL" 2>/dev/null)
|
||||
if [ "$HTTP_CODE" = "200" ]; then
|
||||
ACTUAL="sha256:$(sha256sum /tmp/release.tar.gz | awk '{print $1}')"
|
||||
EXPECTED=$(grep 'archive-checksum' artifacthub-pkg.yml | awk '{print $2}')
|
||||
echo "Release tarball checksum: $ACTUAL"
|
||||
echo "Metadata checksum: $EXPECTED"
|
||||
if [ "$ACTUAL" = "$EXPECTED" ]; then
|
||||
echo "SKIP_BUILD=true" >> $GITHUB_ENV
|
||||
echo "Checksums match - release is finalized, nothing to do"
|
||||
fi
|
||||
else
|
||||
echo "No existing release (HTTP $HTTP_CODE) - will build"
|
||||
fi
|
||||
rm -f /tmp/release.tar.gz
|
||||
|
||||
- name: Setup Node.js
|
||||
if: env.SKIP_BUILD != 'true'
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
|
||||
- name: Install dependencies
|
||||
if: env.SKIP_BUILD != 'true'
|
||||
run: npm ci
|
||||
|
||||
- name: Build plugin
|
||||
if: env.SKIP_BUILD != 'true'
|
||||
run: npx @kinvolk/headlamp-plugin build
|
||||
|
||||
- name: Package tarball
|
||||
if: env.SKIP_BUILD != 'true'
|
||||
run: npx @kinvolk/headlamp-plugin package
|
||||
|
||||
- name: Validate tarball name matches package.json
|
||||
if: env.SKIP_BUILD != 'true'
|
||||
run: |
|
||||
PACKAGE_NAME=$(jq -r '.name' package.json)
|
||||
VERSION=${GITHUB_REF_NAME#v}
|
||||
EXPECTED_TARBALL="${PACKAGE_NAME}-${VERSION}.tar.gz"
|
||||
ACTUAL_TARBALL=$(ls *.tar.gz)
|
||||
|
||||
if [ "$EXPECTED_TARBALL" != "$ACTUAL_TARBALL" ]; then
|
||||
echo "::error::Tarball name mismatch!"
|
||||
echo "Expected: $EXPECTED_TARBALL"
|
||||
echo "Actual: $ACTUAL_TARBALL"
|
||||
echo "Update workflow to use correct tarball name pattern"
|
||||
if ! echo "${{ inputs.version }}" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
|
||||
echo "::error::Version must be in format X.Y.Z (e.g., 0.4.0)"
|
||||
exit 1
|
||||
fi
|
||||
echo "✓ Tarball name validation passed: $ACTUAL_TARBALL"
|
||||
|
||||
- name: Compute tarball checksum
|
||||
if: env.SKIP_BUILD != 'true'
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Configure git
|
||||
run: |
|
||||
TARBALL=$(ls *.tar.gz)
|
||||
CHECKSUM=$(sha256sum "$TARBALL" | awk '{print $1}')
|
||||
echo "TARBALL=$TARBALL" >> $GITHUB_ENV
|
||||
echo "CHECKSUM=$CHECKSUM" >> $GITHUB_ENV
|
||||
echo "Tarball: $TARBALL"
|
||||
echo "Checksum: sha256:$CHECKSUM"
|
||||
|
||||
- name: Create draft release and upload tarball
|
||||
if: env.SKIP_BUILD != 'true'
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: ${{ env.TARBALL }}
|
||||
fail_on_unmatched_files: true
|
||||
draft: true
|
||||
prerelease: false
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Publish release
|
||||
if: env.SKIP_BUILD != 'true'
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
draft: false
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Update metadata and align tag
|
||||
if: env.SKIP_BUILD != 'true'
|
||||
run: |
|
||||
VERSION=${GITHUB_REF_NAME#v}
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
# Update metadata
|
||||
git fetch origin main
|
||||
git checkout origin/main -B temp-update
|
||||
sed -i "s|headlamp/plugin/archive-checksum:.*|headlamp/plugin/archive-checksum: sha256:${CHECKSUM}|" artifacthub-pkg.yml
|
||||
sed -i "s|headlamp/plugin/archive-url:.*|headlamp/plugin/archive-url: \"https://github.com/${{ github.repository }}/releases/download/${GITHUB_REF_NAME}/polaris-${VERSION}.tar.gz\"|" artifacthub-pkg.yml
|
||||
- name: Update package.json version
|
||||
run: |
|
||||
jq --arg version "${{ inputs.version }}" '.version = $version' package.json > package.json.tmp
|
||||
mv package.json.tmp package.json
|
||||
|
||||
- name: Update artifacthub-pkg.yml version
|
||||
run: |
|
||||
VERSION="${{ inputs.version }}"
|
||||
RELEASE_URL="https://github.com/${{ github.repository }}/releases/download/v${VERSION}/polaris-${VERSION}.tar.gz"
|
||||
|
||||
sed -i "s|^version:.*|version: ${VERSION}|" artifacthub-pkg.yml
|
||||
git add artifacthub-pkg.yml
|
||||
sed -i "s|headlamp/plugin/archive-url:.*|headlamp/plugin/archive-url: \"${RELEASE_URL}\"|" artifacthub-pkg.yml
|
||||
|
||||
if ! git diff --cached --quiet; then
|
||||
git commit -m "ci: update artifact hub metadata for ${GITHUB_REF_NAME}"
|
||||
git push origin temp-update:main
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build plugin
|
||||
run: npx @kinvolk/headlamp-plugin build
|
||||
|
||||
- name: Package plugin
|
||||
run: npx @kinvolk/headlamp-plugin package
|
||||
|
||||
- name: Validate tarball name
|
||||
run: |
|
||||
EXPECTED="polaris-${{ inputs.version }}.tar.gz"
|
||||
ACTUAL=$(ls *.tar.gz)
|
||||
if [ "$EXPECTED" != "$ACTUAL" ]; then
|
||||
echo "::error::Tarball name mismatch! Expected: $EXPECTED, Got: $ACTUAL"
|
||||
exit 1
|
||||
fi
|
||||
echo "✓ Tarball name validated: $ACTUAL"
|
||||
|
||||
# Force-move tag to the commit with correct checksum.
|
||||
# This triggers a new CI run, but the guard step will detect
|
||||
# that the release checksum already matches and skip the build.
|
||||
git tag -f ${GITHUB_REF_NAME}
|
||||
git push -f origin ${GITHUB_REF_NAME}
|
||||
echo "Tag ${GITHUB_REF_NAME} aligned with updated metadata"
|
||||
- name: Compute checksum
|
||||
id: compute_checksum
|
||||
run: |
|
||||
TARBALL="polaris-${{ inputs.version }}.tar.gz"
|
||||
CHECKSUM=$(sha256sum "$TARBALL" | awk '{print $1}')
|
||||
echo "checksum=${CHECKSUM}" >> $GITHUB_OUTPUT
|
||||
echo "Checksum: sha256:${CHECKSUM}"
|
||||
|
||||
- name: Update checksum in metadata
|
||||
run: |
|
||||
CHECKSUM="${{ steps.compute_checksum.outputs.checksum }}"
|
||||
sed -i "s|headlamp/plugin/archive-checksum:.*|headlamp/plugin/archive-checksum: sha256:${CHECKSUM}|" artifacthub-pkg.yml
|
||||
|
||||
- name: Commit version bump and metadata
|
||||
run: |
|
||||
git add package.json artifacthub-pkg.yml
|
||||
git commit -m "chore: release v${{ inputs.version }}"
|
||||
git push origin main
|
||||
|
||||
- name: Create and push tag
|
||||
run: |
|
||||
git tag "v${{ inputs.version }}"
|
||||
git push origin "v${{ inputs.version }}"
|
||||
|
||||
- name: Create GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag_name: "v${{ inputs.version }}"
|
||||
files: polaris-${{ inputs.version }}.tar.gz
|
||||
fail_on_unmatched_files: true
|
||||
draft: false
|
||||
prerelease: false
|
||||
generate_release_notes: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Summary
|
||||
run: |
|
||||
echo "✓ Version bumped to ${{ inputs.version }}"
|
||||
echo "✓ Metadata updated with checksum sha256:${{ steps.compute_checksum.outputs.checksum }}"
|
||||
echo "✓ Tag v${{ inputs.version }} created"
|
||||
echo "✓ GitHub release published with tarball"
|
||||
|
||||
+31
-32
@@ -31,7 +31,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- App bar badge, settings buttons, and UI elements now use theme-aware CSS variables
|
||||
|
||||
### Infrastructure
|
||||
- Migrated from Gitea to GitHub Actions exclusively
|
||||
- Added CI workflow for lint, type-check, build, and test
|
||||
- Enhanced E2E testing documentation with comprehensive guides
|
||||
- Added documentation-engineer subagent
|
||||
@@ -243,34 +242,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Automated release workflow
|
||||
- Basic CI/CD pipeline
|
||||
|
||||
[Unreleased]: https://github.com/cpfarhood/headlamp-polaris-plugin/compare/v0.3.5...HEAD
|
||||
[0.3.5]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.3.5
|
||||
[0.3.4]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.3.4
|
||||
[0.3.3]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.3.3
|
||||
[0.3.2]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.3.2
|
||||
[0.3.1]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.3.1
|
||||
[0.3.0]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.3.0
|
||||
[0.2.5]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.2.5
|
||||
[0.2.4]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.2.4
|
||||
[0.2.3]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.2.3
|
||||
[0.2.2]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.2.2
|
||||
[0.2.1]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.2.1
|
||||
[0.2.0]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.2.0
|
||||
[0.1.7]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.1.7
|
||||
[0.1.6]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.1.6
|
||||
[0.1.5]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.1.5
|
||||
[0.1.4]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.1.4
|
||||
[0.1.3]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.1.3
|
||||
[0.1.2]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.1.2
|
||||
[0.1.1]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.1.1
|
||||
[0.1.0]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.1.0
|
||||
[0.0.10]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.0.10
|
||||
[0.0.9]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.0.9
|
||||
[0.0.8]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.0.8
|
||||
[0.0.7]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.0.7
|
||||
[0.0.6]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.0.6
|
||||
[0.0.5]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.0.5
|
||||
[0.0.4]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.0.4
|
||||
[0.0.3]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.0.3
|
||||
[0.0.2]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.0.2
|
||||
[0.0.1]: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/tag/v0.0.1
|
||||
[Unreleased]: https://github.com/privilegedescalation/headlamp-polaris-plugin/compare/v0.3.5...HEAD
|
||||
[0.3.5]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.3.5
|
||||
[0.3.4]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.3.4
|
||||
[0.3.3]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.3.3
|
||||
[0.3.2]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.3.2
|
||||
[0.3.1]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.3.1
|
||||
[0.3.0]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.3.0
|
||||
[0.2.5]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.2.5
|
||||
[0.2.4]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.2.4
|
||||
[0.2.3]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.2.3
|
||||
[0.2.2]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.2.2
|
||||
[0.2.1]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.2.1
|
||||
[0.2.0]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.2.0
|
||||
[0.1.7]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.1.7
|
||||
[0.1.6]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.1.6
|
||||
[0.1.5]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.1.5
|
||||
[0.1.4]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.1.4
|
||||
[0.1.3]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.1.3
|
||||
[0.1.2]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.1.2
|
||||
[0.1.1]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.1.1
|
||||
[0.1.0]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.1.0
|
||||
[0.0.10]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.0.10
|
||||
[0.0.9]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.0.9
|
||||
[0.0.8]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.0.8
|
||||
[0.0.7]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.0.7
|
||||
[0.0.6]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.0.6
|
||||
[0.0.5]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.0.5
|
||||
[0.0.4]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.0.4
|
||||
[0.0.3]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.0.3
|
||||
[0.0.2]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.0.2
|
||||
[0.0.1]: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/tag/v0.0.1
|
||||
|
||||
+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
|
||||
+3
-3
@@ -447,11 +447,11 @@ For testing before stable release:
|
||||
|
||||
## Getting Help
|
||||
|
||||
- **Questions:** Open a [GitHub Discussion](https://github.com/cpfarhood/headlamp-polaris-plugin/discussions)
|
||||
- **Bugs:** Open a [GitHub Issue](https://github.com/cpfarhood/headlamp-polaris-plugin/issues)
|
||||
- **Questions:** Open a [GitHub Discussion](https://github.com/privilegedescalation/headlamp-polaris-plugin/discussions)
|
||||
- **Bugs:** Open a [GitHub Issue](https://github.com/privilegedescalation/headlamp-polaris-plugin/issues)
|
||||
- **E2E Testing:** See [e2e/README.md](e2e/README.md)
|
||||
- **Architecture:** See [CLAUDE.md](CLAUDE.md)
|
||||
|
||||
## License
|
||||
|
||||
By contributing, you agree that your contributions will be licensed under the MIT License.
|
||||
By contributing, you agree that your contributions will be licensed under the Apache-2.0 License.
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
# Headlamp Polaris Plugin
|
||||
|
||||
[](https://artifacthub.io/packages/headlamp/polaris/headlamp-polaris-plugin)
|
||||
[](https://github.com/cpfarhood/headlamp-polaris-plugin/actions/workflows/ci.yaml)
|
||||
[](https://github.com/cpfarhood/headlamp-polaris-plugin/actions/workflows/e2e.yaml)
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
[](https://github.com/privilegedescalation/headlamp-polaris-plugin/actions/workflows/ci.yaml)
|
||||
[](https://github.com/privilegedescalation/headlamp-polaris-plugin/actions/workflows/e2e.yaml)
|
||||
[](https://opensource.org/licenses/Apache-2.0)
|
||||
|
||||
A [Headlamp](https://headlamp.dev/) plugin that surfaces [Fairwinds Polaris](https://polaris.docs.fairwinds.com/) audit results directly in the Headlamp UI.
|
||||
|
||||
**📚 [Documentation](#documentation) | 🚀 [Installation](#installing) | 🔒 [Security](#rbac--security-setup) | 🛠️ [Development](#development)**
|
||||
**[Documentation](#documentation) | [Installation](#installing) | [Security](#rbac--security-setup) | [Development](#development)**
|
||||
|
||||
## What It Does
|
||||
|
||||
@@ -62,7 +62,7 @@ config:
|
||||
pluginsManager:
|
||||
sources:
|
||||
- name: headlamp-polaris-plugin
|
||||
url: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/download/v0.3.5/headlamp-polaris-plugin-0.3.5.tar.gz
|
||||
url: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/download/v0.3.10/polaris-0.3.10.tar.gz
|
||||
```
|
||||
|
||||
Or install via the Headlamp UI:
|
||||
@@ -96,17 +96,17 @@ sidecars:
|
||||
|
||||
### Option 3: Manual Tarball Install
|
||||
|
||||
Download the `.tar.gz` from the [GitHub releases page](https://github.com/cpfarhood/headlamp-polaris-plugin/releases), then extract into Headlamp's plugin directory:
|
||||
Download the `.tar.gz` from the [GitHub releases page](https://github.com/privilegedescalation/headlamp-polaris-plugin/releases), then extract into Headlamp's plugin directory:
|
||||
|
||||
```bash
|
||||
wget https://github.com/cpfarhood/headlamp-polaris-plugin/releases/download/v0.3.5/headlamp-polaris-plugin-0.3.5.tar.gz
|
||||
tar xzf headlamp-polaris-plugin-0.3.5.tar.gz -C /headlamp/plugins/
|
||||
wget https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/download/v0.3.10/polaris-0.3.10.tar.gz
|
||||
tar xzf polaris-0.3.10.tar.gz -C /headlamp/plugins/
|
||||
```
|
||||
|
||||
### Option 4: Build from Source
|
||||
|
||||
```bash
|
||||
git clone https://github.com/cpfarhood/headlamp-polaris-plugin.git
|
||||
git clone https://github.com/privilegedescalation/headlamp-polaris-plugin.git
|
||||
cd headlamp-polaris-plugin
|
||||
npm install
|
||||
npm run build
|
||||
@@ -172,7 +172,7 @@ Every proxied request is recorded in Kubernetes API audit logs as a `get` on `se
|
||||
|
||||
## Documentation
|
||||
|
||||
📚 **[Complete Documentation](docs/README.md)** - Documentation hub with all guides
|
||||
**[Complete Documentation](docs/README.md)** - Documentation hub with all guides
|
||||
|
||||
### Quick Links
|
||||
|
||||
@@ -214,7 +214,7 @@ Quick reference:
|
||||
|
||||
```bash
|
||||
# Clone repository
|
||||
git clone https://github.com/cpfarhood/headlamp-polaris-plugin.git
|
||||
git clone https://github.com/privilegedescalation/headlamp-polaris-plugin.git
|
||||
cd headlamp-polaris-plugin
|
||||
|
||||
# Install dependencies
|
||||
@@ -365,15 +365,12 @@ Contributions are welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) for:
|
||||
|
||||
## Links
|
||||
|
||||
- **[GitHub Repository](https://github.com/cpfarhood/headlamp-polaris-plugin)** - Source code, issues, releases
|
||||
- **[GitHub Repository](https://github.com/privilegedescalation/headlamp-polaris-plugin)** - Source code, issues, releases
|
||||
- **[Artifact Hub](https://artifacthub.io/packages/headlamp/polaris/headlamp-polaris-plugin)** - Plugin catalog listing
|
||||
- **[Headlamp](https://headlamp.dev/)** - Kubernetes web UI
|
||||
- **[Fairwinds Polaris](https://polaris.docs.fairwinds.com/)** - Kubernetes best practices audit tool
|
||||
|
||||
## License
|
||||
|
||||
[MIT License](LICENSE) - see LICENSE file for details.
|
||||
[Apache-2.0 License](LICENSE) - see LICENSE file for details.
|
||||
|
||||
---
|
||||
|
||||
**Made with ❤️ for the Kubernetes community**
|
||||
|
||||
+6
-6
@@ -194,7 +194,7 @@ We apply security updates to the latest release only. Please ensure you are runn
|
||||
|
||||
If you discover a security vulnerability in this plugin, please report it via:
|
||||
|
||||
1. **GitHub Security Advisories**: [Report a vulnerability](https://github.com/cpfarhood/headlamp-polaris-plugin/security/advisories/new)
|
||||
1. **GitHub Security Advisories**: [Report a vulnerability](https://github.com/privilegedescalation/headlamp-polaris-plugin/security/advisories/new)
|
||||
2. **Email**: Create a GitHub issue and mark it as "security" if advisories are not available
|
||||
|
||||
**Please do not:**
|
||||
@@ -334,7 +334,7 @@ The plugin processes only technical metadata (resource names, namespaces, check
|
||||
Subscribe to security updates via:
|
||||
|
||||
1. **GitHub Watch**: Click "Watch" → "Custom" → "Security alerts"
|
||||
2. **GitHub Releases**: Monitor [releases page](https://github.com/cpfarhood/headlamp-polaris-plugin/releases)
|
||||
2. **GitHub Releases**: Monitor [releases page](https://github.com/privilegedescalation/headlamp-polaris-plugin/releases)
|
||||
3. **ArtifactHub**: Follow package at [ArtifactHub](https://artifacthub.io/packages/headlamp/headlamp-polaris-plugin/headlamp-polaris-plugin)
|
||||
|
||||
### Security Patch Process
|
||||
@@ -349,10 +349,10 @@ When a security vulnerability is identified:
|
||||
|
||||
## Contact
|
||||
|
||||
- **Security Issues**: [GitHub Security Advisories](https://github.com/cpfarhood/headlamp-polaris-plugin/security/advisories)
|
||||
- **General Questions**: [GitHub Discussions](https://github.com/cpfarhood/headlamp-polaris-plugin/discussions)
|
||||
- **Bug Reports**: [GitHub Issues](https://github.com/cpfarhood/headlamp-polaris-plugin/issues)
|
||||
- **Security Issues**: [GitHub Security Advisories](https://github.com/privilegedescalation/headlamp-polaris-plugin/security/advisories)
|
||||
- **General Questions**: [GitHub Discussions](https://github.com/privilegedescalation/headlamp-polaris-plugin/discussions)
|
||||
- **Bug Reports**: [GitHub Issues](https://github.com/privilegedescalation/headlamp-polaris-plugin/issues)
|
||||
|
||||
## License
|
||||
|
||||
This plugin is provided under the MIT License. See [LICENSE](LICENSE) for details.
|
||||
This plugin is provided under the Apache-2.0 License. See [LICENSE](LICENSE) for details.
|
||||
|
||||
+7
-7
@@ -1,4 +1,4 @@
|
||||
version: 0.3.9
|
||||
version: 0.5.0
|
||||
name: headlamp-polaris-plugin
|
||||
displayName: Polaris
|
||||
createdAt: "2026-02-05T19:00:00Z"
|
||||
@@ -9,8 +9,8 @@ description: >-
|
||||
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: MIT
|
||||
homeURL: "https://github.com/cpfarhood/headlamp-polaris-plugin"
|
||||
license: Apache-2.0
|
||||
homeURL: "https://github.com/privilegedescalation/headlamp-polaris-plugin"
|
||||
category: security
|
||||
keywords:
|
||||
- polaris
|
||||
@@ -21,14 +21,14 @@ keywords:
|
||||
- kubernetes
|
||||
links:
|
||||
- name: Source
|
||||
url: "https://github.com/cpfarhood/headlamp-polaris-plugin"
|
||||
url: "https://github.com/privilegedescalation/headlamp-polaris-plugin"
|
||||
- name: Polaris
|
||||
url: "https://polaris.docs.fairwinds.com/"
|
||||
maintainers:
|
||||
- name: cpfarhood
|
||||
- name: privilegedescalation
|
||||
email: "chris@farhood.org"
|
||||
annotations:
|
||||
headlamp/plugin/archive-url: "https://github.com/cpfarhood/headlamp-polaris-plugin/releases/download/v0.3.9/polaris-0.3.9.tar.gz"
|
||||
headlamp/plugin/archive-url: "https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/download/v0.5.0/polaris-0.5.0.tar.gz"
|
||||
headlamp/plugin/version-compat: ">=0.26"
|
||||
headlamp/plugin/archive-checksum: sha256:4447bff847623dbab0d0cde739f17e5b2888bf95e1f152fa217274004775823d
|
||||
headlamp/plugin/archive-checksum: sha256:d00b9d068a32f01cf1584465c24e96b66eec60ea80be14f07433530780584451
|
||||
headlamp/plugin/distro-compat: in-cluster
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
repositoryID: fc3397f6-a75a-4950-ab50-da75c08a8089
|
||||
owners:
|
||||
- name: cpfarhood
|
||||
- name: privilegedescalation
|
||||
email: "chris@farhood.org"
|
||||
|
||||
@@ -104,6 +104,7 @@ Additional considerations:
|
||||
## MCP Servers
|
||||
|
||||
The project has MCP server integrations configured in `.mcp.json`:
|
||||
- **Gitea** (git.farh.net): Source control via `gitea-mcp-server`
|
||||
- **GitHub**: Source control via `github-mcp-server`
|
||||
- **Kubernetes** (local): Cluster access via `kubernetes-mcp-server`
|
||||
- **Flux** (local): Flux Operator access via `flux-operator-mcp`
|
||||
- **Playwright**: Browser automation via `@playwright/mcp`
|
||||
|
||||
@@ -43,7 +43,7 @@ The Headlamp Polaris Plugin is a **read-only dashboard** that surfaces Fairwinds
|
||||
│ └────────┬────────┘ │
|
||||
│ │ │
|
||||
│ ┌─────────────▼──────────────┐ │
|
||||
│ │ Polaris Plugin (This!) │ │
|
||||
│ │ Polaris Plugin │ │
|
||||
│ ├────────────────────────────┤ │
|
||||
│ │ • registerSidebarEntry │ │
|
||||
│ │ • registerRoute │ │
|
||||
|
||||
+1
-1
@@ -113,7 +113,7 @@ data:
|
||||
plugin.yml: |
|
||||
- name: headlamp-polaris-plugin
|
||||
version: 0.3.4
|
||||
url: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/download/v0.3.4/headlamp-polaris-plugin-0.3.4.tar.gz
|
||||
url: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/download/v0.3.10/polaris-0.3.10.tar.gz
|
||||
```
|
||||
|
||||
### Method 3: Volume Mount (Development)
|
||||
|
||||
@@ -54,7 +54,7 @@ README.md # Main entry point with badges, quick links
|
||||
CHANGELOG.md # Keep a Changelog format, semantic versioning
|
||||
CONTRIBUTING.md # Development workflow, branching, PR process
|
||||
SECURITY.md # Security model, vulnerability reporting, RBAC
|
||||
LICENSE # MIT License
|
||||
LICENSE # Apache-2.0 License
|
||||
package.json # Plugin metadata
|
||||
```
|
||||
|
||||
|
||||
+6
-6
@@ -4,11 +4,11 @@ Central hub for Headlamp Polaris Plugin documentation.
|
||||
|
||||
## Quick Links
|
||||
|
||||
- 🚀 [Quick Start](getting-started/quick-start.md)
|
||||
- 📖 [Installation Guide](getting-started/installation.md)
|
||||
- 🔧 [Troubleshooting](troubleshooting/README.md)
|
||||
- 🏗️ [Architecture](architecture/overview.md)
|
||||
- 💻 [Development](development/workflow.md)
|
||||
- [Quick Start](getting-started/quick-start.md)
|
||||
- [Installation Guide](getting-started/installation.md)
|
||||
- [Troubleshooting](troubleshooting/README.md)
|
||||
- [Architecture](architecture/overview.md)
|
||||
- [Development](development/workflow.md)
|
||||
|
||||
## Getting Started
|
||||
|
||||
@@ -68,4 +68,4 @@ Production deployment guides:
|
||||
|
||||
---
|
||||
|
||||
**Need help?** Open an issue on [GitHub](https://github.com/cpfarhood/headlamp-polaris-plugin/issues) or check [CONTRIBUTING.md](../CONTRIBUTING.md) for development guidelines.
|
||||
**Need help?** Open an issue on [GitHub](https://github.com/privilegedescalation/headlamp-polaris-plugin/issues) or check [CONTRIBUTING.md](../CONTRIBUTING.md) for development guidelines.
|
||||
|
||||
@@ -572,7 +572,7 @@ kubectl get configmap headlamp-plugin-config -n kube-system -o yaml
|
||||
|
||||
Expected format:
|
||||
```
|
||||
https://github.com/cpfarhood/headlamp-polaris-plugin/releases/download/v0.3.5/headlamp-polaris-plugin-0.3.5.tar.gz
|
||||
https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/download/v0.3.10/polaris-0.3.10.tar.gz
|
||||
```
|
||||
|
||||
---
|
||||
@@ -672,7 +672,7 @@ If none of these solutions work, gather debugging information and open an issue:
|
||||
|
||||
### Where to Get Help
|
||||
|
||||
- **GitHub Issues**: [https://github.com/cpfarhood/headlamp-polaris-plugin/issues](https://github.com/cpfarhood/headlamp-polaris-plugin/issues)
|
||||
- **GitHub Discussions**: [https://github.com/cpfarhood/headlamp-polaris-plugin/discussions](https://github.com/cpfarhood/headlamp-polaris-plugin/discussions)
|
||||
- **GitHub Issues**: [https://github.com/privilegedescalation/headlamp-polaris-plugin/issues](https://github.com/privilegedescalation/headlamp-polaris-plugin/issues)
|
||||
- **GitHub Discussions**: [https://github.com/privilegedescalation/headlamp-polaris-plugin/discussions](https://github.com/privilegedescalation/headlamp-polaris-plugin/discussions)
|
||||
|
||||
Include the debugging information above when opening an issue.
|
||||
|
||||
@@ -32,7 +32,7 @@ The Headlamp Polaris Plugin is a **read-only dashboard** that surfaces Fairwinds
|
||||
│ └────────┬────────┘ │
|
||||
│ │ │
|
||||
│ ┌─────────────▼──────────────┐ │
|
||||
│ │ Polaris Plugin (This!) │ │
|
||||
│ │ Polaris Plugin │ │
|
||||
│ ├────────────────────────────┤ │
|
||||
│ │ • registerSidebarEntry │ │
|
||||
│ │ • registerRoute │ │
|
||||
|
||||
@@ -185,7 +185,7 @@ data:
|
||||
plugin.yml: |
|
||||
- name: headlamp-polaris-plugin
|
||||
version: 0.3.5
|
||||
url: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/download/v0.3.5/headlamp-polaris-plugin-0.3.5.tar.gz
|
||||
url: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/download/v0.3.10/polaris-0.3.10.tar.gz
|
||||
```
|
||||
|
||||
Apply ConfigMap then deploy Headlamp:
|
||||
@@ -373,7 +373,7 @@ kubectl -n kube-system edit configmap headlamp-plugin-config
|
||||
|
||||
# Update version and URL:
|
||||
# version: 0.3.6
|
||||
# url: https://github.com/.../v0.3.6/headlamp-polaris-plugin-0.3.6.tar.gz
|
||||
# url: https://github.com/.../v0.3.6/polaris-0.3.10.tar.gz
|
||||
|
||||
# Restart deployment to trigger init container
|
||||
kubectl -n kube-system rollout restart deployment/headlamp
|
||||
|
||||
@@ -98,7 +98,7 @@ data:
|
||||
plugin.yml: |
|
||||
- name: headlamp-polaris-plugin
|
||||
version: 0.3.5
|
||||
url: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/download/v0.3.5/headlamp-polaris-plugin-0.3.5.tar.gz
|
||||
url: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/download/v0.3.10/polaris-0.3.10.tar.gz
|
||||
```
|
||||
|
||||
### Headlamp Deployment with Plugin Init Container
|
||||
@@ -414,7 +414,7 @@ kubectl -n kube-system edit configmap headlamp-plugin-config
|
||||
|
||||
# Update version and URL:
|
||||
# version: 0.3.6
|
||||
# url: https://github.com/.../v0.3.6/headlamp-polaris-plugin-0.3.6.tar.gz
|
||||
# url: https://github.com/.../v0.3.6/polaris-0.3.10.tar.gz
|
||||
|
||||
# Restart deployment to trigger init container
|
||||
kubectl -n kube-system rollout restart deployment/headlamp
|
||||
|
||||
@@ -143,7 +143,7 @@ data:
|
||||
plugin.yml: |
|
||||
- name: headlamp-polaris-plugin
|
||||
version: 0.3.5
|
||||
url: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/download/v0.3.5/headlamp-polaris-plugin-0.3.5.tar.gz
|
||||
url: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/download/v0.3.10/polaris-0.3.10.tar.gz
|
||||
```
|
||||
|
||||
#### Apply Configuration
|
||||
@@ -179,7 +179,7 @@ Download the plugin tarball and extract it into Headlamp's plugin directory.
|
||||
```bash
|
||||
# Download latest release
|
||||
VERSION=0.3.5
|
||||
wget https://github.com/cpfarhood/headlamp-polaris-plugin/releases/download/v${VERSION}/headlamp-polaris-plugin-${VERSION}.tar.gz
|
||||
wget https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/download/v${VERSION}/headlamp-polaris-plugin-${VERSION}.tar.gz
|
||||
|
||||
# Extract to plugin directory
|
||||
tar xzf headlamp-polaris-plugin-${VERSION}.tar.gz -C /headlamp/plugins/
|
||||
@@ -225,7 +225,7 @@ Clone the repository and build the plugin from source.
|
||||
|
||||
```bash
|
||||
# Clone repository
|
||||
git clone https://github.com/cpfarhood/headlamp-polaris-plugin.git
|
||||
git clone https://github.com/privilegedescalation/headlamp-polaris-plugin.git
|
||||
cd headlamp-polaris-plugin
|
||||
|
||||
# Install dependencies
|
||||
|
||||
@@ -6,9 +6,9 @@ Get the Headlamp Polaris Plugin up and running in 5 minutes.
|
||||
|
||||
Before starting, ensure:
|
||||
|
||||
- ✅ Kubernetes cluster is running
|
||||
- ✅ Headlamp v0.26+ is deployed
|
||||
- ✅ Polaris is installed with dashboard enabled
|
||||
- Kubernetes cluster is running
|
||||
- Headlamp v0.26+ is deployed
|
||||
- Polaris is installed with dashboard enabled
|
||||
|
||||
Don't have these? See [Prerequisites](prerequisites.md) for installation instructions.
|
||||
|
||||
@@ -276,6 +276,4 @@ If test fails, see [Troubleshooting](../troubleshooting/README.md).
|
||||
|
||||
---
|
||||
|
||||
**Congratulations!** You're now running the Headlamp Polaris Plugin. 🎉
|
||||
|
||||
Visit the **Polaris** section in Headlamp to explore your cluster's security, reliability, and efficiency audit results.
|
||||
You're now running the Headlamp Polaris Plugin. Visit the **Polaris** section in Headlamp to explore your cluster's security, reliability, and efficiency audit results.
|
||||
|
||||
@@ -155,7 +155,7 @@ If the quick diagnosis doesn't resolve your issue:
|
||||
- [Deployment Guide](../deployment/kubernetes.md)
|
||||
|
||||
3. **Open a GitHub issue:**
|
||||
- [GitHub Issues](https://github.com/cpfarhood/headlamp-polaris-plugin/issues)
|
||||
- [GitHub Issues](https://github.com/privilegedescalation/headlamp-polaris-plugin/issues)
|
||||
- Include: Headlamp version, plugin version, error messages, logs
|
||||
|
||||
## References
|
||||
|
||||
@@ -572,7 +572,7 @@ kubectl get configmap headlamp-plugin-config -n kube-system -o yaml
|
||||
|
||||
Expected format:
|
||||
```
|
||||
https://github.com/cpfarhood/headlamp-polaris-plugin/releases/download/v0.3.5/headlamp-polaris-plugin-0.3.5.tar.gz
|
||||
https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/download/v0.3.10/polaris-0.3.10.tar.gz
|
||||
```
|
||||
|
||||
---
|
||||
@@ -672,7 +672,7 @@ If none of these solutions work, gather debugging information and open an issue:
|
||||
|
||||
### Where to Get Help
|
||||
|
||||
- **GitHub Issues**: [https://github.com/cpfarhood/headlamp-polaris-plugin/issues](https://github.com/cpfarhood/headlamp-polaris-plugin/issues)
|
||||
- **GitHub Discussions**: [https://github.com/cpfarhood/headlamp-polaris-plugin/discussions](https://github.com/cpfarhood/headlamp-polaris-plugin/discussions)
|
||||
- **GitHub Issues**: [https://github.com/privilegedescalation/headlamp-polaris-plugin/issues](https://github.com/privilegedescalation/headlamp-polaris-plugin/issues)
|
||||
- **GitHub Discussions**: [https://github.com/privilegedescalation/headlamp-polaris-plugin/discussions](https://github.com/privilegedescalation/headlamp-polaris-plugin/discussions)
|
||||
|
||||
Include the debugging information above when opening an issue.
|
||||
|
||||
@@ -117,13 +117,13 @@ Top-right corner of Headlamp shows a persistent cluster score badge.
|
||||
|
||||
**Features:**
|
||||
- **Color-Coded Chip** - Green/Yellow/Red based on score
|
||||
- **Shield Emoji (🛡️)** - Visual indicator
|
||||
- **Shield Icon** - Visual indicator
|
||||
- **Score Percentage** - e.g., "85%"
|
||||
- **Clickable** - Click to navigate to Polaris overview
|
||||
- **Real-Time Updates** - Updates on auto-refresh interval
|
||||
- **Always Visible** - Appears on all Headlamp pages
|
||||
|
||||
**Example:** `🛡️ 85%` (green chip)
|
||||
**Example:** Shield icon with "85%" (green chip)
|
||||
|
||||
## Settings & Configuration
|
||||
|
||||
|
||||
+5
-5
@@ -1,16 +1,16 @@
|
||||
{
|
||||
"name": "polaris",
|
||||
"version": "0.3.9",
|
||||
"version": "0.5.0",
|
||||
"description": "Headlamp plugin for Fairwinds Polaris audit results",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/cpfarhood/headlamp-polaris-plugin.git"
|
||||
"url": "https://github.com/privilegedescalation/headlamp-polaris-plugin.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/cpfarhood/headlamp-polaris-plugin/issues"
|
||||
"url": "https://github.com/privilegedescalation/headlamp-polaris-plugin/issues"
|
||||
},
|
||||
"homepage": "https://github.com/cpfarhood/headlamp-polaris-plugin#readme",
|
||||
"author": "cpfarhood",
|
||||
"homepage": "https://github.com/privilegedescalation/headlamp-polaris-plugin#readme",
|
||||
"author": "privilegedescalation",
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
"start": "headlamp-plugin start",
|
||||
|
||||
@@ -35,8 +35,20 @@ const PolarisDataContext = React.createContext<PolarisDataContextValue | null>(n
|
||||
* ```
|
||||
*/
|
||||
export function PolarisDataProvider(props: { children: React.ReactNode }) {
|
||||
const interval = getRefreshInterval();
|
||||
const state = usePolarisData(interval);
|
||||
// Re-read interval on every render to pick up changes from settings
|
||||
const [refreshInterval, setRefreshInterval] = React.useState(getRefreshInterval());
|
||||
|
||||
// Poll for interval changes (localStorage changes from settings)
|
||||
React.useEffect(() => {
|
||||
const intervalId = window.setInterval(() => {
|
||||
const newInterval = getRefreshInterval();
|
||||
setRefreshInterval(prev => (prev !== newInterval ? newInterval : prev));
|
||||
}, 1000); // Check every second
|
||||
|
||||
return () => window.clearInterval(intervalId);
|
||||
}, []);
|
||||
|
||||
const state = usePolarisData(refreshInterval);
|
||||
|
||||
// Rename triggerRefresh to refresh for consistency
|
||||
const value = React.useMemo(
|
||||
|
||||
+3
-1
@@ -373,7 +373,9 @@ export function usePolarisData(refreshIntervalSeconds: number): PolarisDataState
|
||||
result = await response.json();
|
||||
} else {
|
||||
// Kubernetes proxy for relative URLs
|
||||
result = await ApiProxy.request(apiPath);
|
||||
result = await ApiProxy.request(apiPath, {
|
||||
method: 'GET',
|
||||
});
|
||||
}
|
||||
|
||||
if (!cancelled) {
|
||||
|
||||
@@ -44,6 +44,7 @@ interface NamespaceDetailPanelProps {
|
||||
}
|
||||
|
||||
function NamespaceDetailPanel({ namespace, onClose }: NamespaceDetailPanelProps) {
|
||||
const [isMaximized, setIsMaximized] = React.useState(false);
|
||||
const { data, loading, error } = usePolarisDataContext();
|
||||
|
||||
if (loading) {
|
||||
@@ -107,13 +108,14 @@ function NamespaceDetailPanel({ namespace, onClose }: NamespaceDetailPanelProps)
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 1000px;
|
||||
width: ${isMaximized ? 'calc(100vw - 240px)' : '1000px'};
|
||||
background-color: var(--mui-palette-background-default, #fafafa);
|
||||
color: var(--mui-palette-text-primary);
|
||||
box-shadow: -2px 0 8px rgba(0,0,0,0.15);
|
||||
overflow-y: auto;
|
||||
z-index: 1200;
|
||||
padding: 20px;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
@@ -129,20 +131,54 @@ function NamespaceDetailPanel({ namespace, onClose }: NamespaceDetailPanelProps)
|
||||
<h2 style={{ margin: 0, color: 'var(--mui-palette-text-primary)' }}>
|
||||
Polaris — {namespace}
|
||||
</h2>
|
||||
<button
|
||||
onClick={onClose}
|
||||
style={{
|
||||
border: 'none',
|
||||
background: 'transparent',
|
||||
fontSize: '24px',
|
||||
cursor: 'pointer',
|
||||
padding: '0 8px',
|
||||
color: 'var(--mui-palette-text-primary)',
|
||||
}}
|
||||
aria-label="Close panel"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
<div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>
|
||||
<button
|
||||
onClick={() => setIsMaximized(!isMaximized)}
|
||||
style={{
|
||||
border: 'none',
|
||||
background: 'transparent',
|
||||
fontSize: '20px',
|
||||
cursor: 'pointer',
|
||||
padding: '4px 8px',
|
||||
color: 'var(--mui-palette-text-secondary, #666)',
|
||||
borderRadius: '4px',
|
||||
}}
|
||||
onMouseEnter={e => {
|
||||
e.currentTarget.style.backgroundColor =
|
||||
'var(--mui-palette-action-hover, rgba(0, 0, 0, 0.04))';
|
||||
}}
|
||||
onMouseLeave={e => {
|
||||
e.currentTarget.style.backgroundColor = 'transparent';
|
||||
}}
|
||||
aria-label={isMaximized ? 'Minimize panel' : 'Maximize panel'}
|
||||
title={isMaximized ? 'Minimize' : 'Maximize'}
|
||||
>
|
||||
{isMaximized ? '⊟' : '⊡'}
|
||||
</button>
|
||||
<button
|
||||
onClick={onClose}
|
||||
style={{
|
||||
border: 'none',
|
||||
background: 'transparent',
|
||||
fontSize: '24px',
|
||||
cursor: 'pointer',
|
||||
padding: '4px 8px',
|
||||
color: 'var(--mui-palette-text-secondary, #666)',
|
||||
borderRadius: '4px',
|
||||
}}
|
||||
onMouseEnter={e => {
|
||||
e.currentTarget.style.backgroundColor =
|
||||
'var(--mui-palette-action-hover, rgba(0, 0, 0, 0.04))';
|
||||
}}
|
||||
onMouseLeave={e => {
|
||||
e.currentTarget.style.backgroundColor = 'transparent';
|
||||
}}
|
||||
aria-label="Close panel"
|
||||
title="Close"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<SectionBox title="External">
|
||||
|
||||
@@ -58,7 +58,9 @@ export default function PolarisSettings(props: PluginSettingsProps) {
|
||||
}
|
||||
result = await response.json();
|
||||
} else {
|
||||
result = await ApiProxy.request(apiPath);
|
||||
result = await ApiProxy.request(apiPath, {
|
||||
method: 'GET',
|
||||
});
|
||||
}
|
||||
|
||||
setTestResult({
|
||||
|
||||
+1
-1
@@ -66,7 +66,7 @@ registerRoute({
|
||||
});
|
||||
|
||||
// Register plugin settings
|
||||
registerPluginSettings('headlamp-polaris-plugin', PolarisSettings, true);
|
||||
registerPluginSettings('polaris', PolarisSettings, true);
|
||||
|
||||
// Register details view section for supported controller types
|
||||
registerDetailsViewSection(({ resource }) => {
|
||||
|
||||
Reference in New Issue
Block a user