Compare commits

..

9 Commits

Author SHA1 Message Date
gitea-actions[bot] f2a2176eb6 ci: update artifact hub metadata for v0.2.0-dev.5 2026-02-09 18:48:56 +00:00
Chris Farhood 73939e66ad chore: update workflow to use 'dev' branch name
Updated GITEA_BRANCH reference from 'dev/namespace-drawer' to 'dev'
to match the renamed long-lived development branch.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-09 13:46:47 -05:00
Chris Farhood 2c26d49bf9 docs: add dev/preview version installation instructions
Documents how to install dev preview versions using direct URLs since
they are not published to ArtifactHub. Includes sidecar pattern example
and manual download instructions.
2026-02-09 13:41:30 -05:00
Chris Farhood 679be5dedc fix: only update GitHub main for stable releases 2026-02-09 13:03:07 -05:00
Chris Farhood c67bcb1804 chore: bump version to 0.1.6 2026-02-07 22:13:19 -05:00
Chris Farhood c19bb2fa87 fix: use "Polaris" as plugin settings display name
Changed from "headlamp-polaris-plugin" to "Polaris" in the
registerPluginSettings call. This makes the plugin name appear
cleanly in Settings > Plugins.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-07 22:12:55 -05:00
Chris Farhood 253d1277d9 docs: document skipped count limitation
Added "Known Limitations" section explaining that the skipped count
only reflects Severity=ignore checks and does not include
annotation-based exemptions.

Explains why (exempted checks omitted from results.json) and what
would be required to support exemption counting (direct K8s resource
queries with broader RBAC).

Points users to the "View in Polaris Dashboard" link as a workaround.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-07 22:12:55 -05:00
Chris Farhood f69c91acf9 feat: add tooltip to skipped count explaining limitation
The skipped count only reflects checks with Severity=ignore from
the Polaris API. Annotation-based exemptions (e.g.,
polaris.fairwinds.com/*-exempt) are not included because:

1. Exempted checks are completely omitted from results.json
2. The Polaris dashboard UI counts exemptions client-side by
   querying Kubernetes resources for annotations
3. Our plugin only has access to the processed audit results

Added HTML title tooltip to explain this limitation to users.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-07 22:12:55 -05:00
Chris Farhood 5659026959 fix: add :80 port to dashboard proxy constant
The POLARIS_DASHBOARD_PROXY constant was missing :80, causing
dashboard links in the UI to fail with "no endpoints available".
This matches the fix already applied to POLARIS_API_PATH.

Fixes external dashboard link in namespace detail view.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-07 22:12:55 -05:00
8 changed files with 113 additions and 13 deletions
+21 -5
View File
@@ -115,6 +115,9 @@ jobs:
continue-on-error: true
run: |
[ "$SKIP_BUILD" = "true" ] && exit 0
# Push tag to GitHub first so it exists before creating the release
git remote add github-release https://x-access-token:${{ secrets.GH_PAT }}@github.com/cpfarhood/headlamp-polaris-plugin.git 2>/dev/null || true
git push -f github-release ${GITHUB_REF_NAME} 2>/dev/null || true
GH_API="https://api.github.com/repos/cpfarhood/headlamp-polaris-plugin"
# Create release or fetch existing one
BODY=$(curl -s -X POST \
@@ -163,23 +166,36 @@ jobs:
VERSION=${GITHUB_REF_NAME#v}
git config user.name "gitea-actions[bot]"
git config user.email "gitea-actions[bot]@git.farh.net"
git fetch origin main
git checkout origin/main -B main
# Determine which Gitea branch to update based on version suffix
if [[ "$VERSION" == *"-dev."* ]]; then
GITEA_BRANCH="dev"
else
GITEA_BRANCH="main"
fi
git fetch origin ${GITEA_BRANCH}
git checkout origin/${GITEA_BRANCH} -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/cpfarhood/headlamp-polaris-plugin/releases/download/${GITHUB_REF_NAME}/headlamp-polaris-plugin-${VERSION}.tar.gz\"|" artifacthub-pkg.yml
sed -i "s|^version:.*|version: ${VERSION}|" artifacthub-pkg.yml
git add artifacthub-pkg.yml
git diff --cached --quiet || {
git commit -m "ci: update artifact hub metadata for ${GITHUB_REF_NAME}"
git push origin main
git push origin temp-update:${GITEA_BRANCH}
}
# 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}
# Also push to GitHub directly to avoid waiting for mirror sync
# Only push to GitHub main branch for STABLE releases
# Dev releases only create GitHub releases, don't update main branch
# This keeps GitHub main branch at latest stable for ArtifactHub
git remote add github https://x-access-token:${{ secrets.GH_PAT }}@github.com/cpfarhood/headlamp-polaris-plugin.git 2>/dev/null || true
git push github main 2>/dev/null || true
if [[ "$VERSION" != *"-dev."* ]]; then
echo "Stable release detected - pushing to GitHub main branch"
git push github temp-update:main 2>/dev/null || true
else
echo "Dev release detected - skipping GitHub main branch update"
fi
git push -f github ${GITHUB_REF_NAME} 2>/dev/null || true
echo "Tag ${GITHUB_REF_NAME} aligned with updated metadata"
+73
View File
@@ -83,6 +83,59 @@ npm run build
npx @kinvolk/headlamp-plugin extract . /headlamp/plugins
```
## Installing Dev/Preview Versions
Dev preview versions (e.g., `v0.2.0-dev.4`) are published to [GitHub Releases](https://github.com/cpfarhood/headlamp-polaris-plugin/releases) but are **not available via ArtifactHub**. These versions contain experimental features and are intended for testing.
To install a dev version, use the direct URL method:
### Sidecar container pattern (recommended)
Create a ConfigMap with the dev version URL:
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: headlamp-plugin-config
namespace: kube-system
data:
plugin.yml: |
plugins:
- url: https://github.com/cpfarhood/headlamp-polaris-plugin/releases/download/v0.2.0-dev.4/headlamp-polaris-plugin-0.2.0-dev.4.tar.gz
```
Then configure Headlamp to use a sidecar container that installs from this config:
```yaml
# In Headlamp Helm values or deployment
containers:
- name: headlamp-plugin-installer
image: node:lts-alpine
command: ["/bin/sh", "-c"]
args:
- |
npm install -g @kinvolk/headlamp-plugin
headlamp-plugin install --config /config/plugin.yml
volumeMounts:
- name: plugins
mountPath: /headlamp/plugins
- name: plugin-config
mountPath: /config
volumes:
- name: plugins
emptyDir: {}
- name: plugin-config
configMap:
name: headlamp-plugin-config
```
### Manual download
Browse [GitHub Releases](https://github.com/cpfarhood/headlamp-polaris-plugin/releases), download the dev version tarball, and extract it to your Headlamp plugins directory.
**Note:** Dev versions are tagged with the `-dev.N` suffix and may introduce breaking changes or unstable features. Use stable versions for production deployments.
## RBAC / Security Setup
The plugin fetches audit data through the Kubernetes API server's **service proxy** sub-resource. The identity making the request (Headlamp's service account, or the user's own token in token-auth mode) must be granted:
@@ -222,6 +275,26 @@ AuditData
Each check in a `ResultSet` has `Success` (bool) and `Severity` (`"warning"`, `"danger"`, or `"ignore"`). Checks with `Severity: "ignore"` and `Success: false` are counted as skipped. The cluster score is computed client-side as `pass / total * 100`.
## Known Limitations
### Skipped Count and Annotation-Based Exemptions
The **Skipped** count shown in the plugin only reflects checks with `Severity: "ignore"` in the Polaris API response. It does **not** include annotation-based exemptions (e.g., `polaris.fairwinds.com/privilegeEscalationAllowed-exempt: "true"`).
**Why?** Polaris completely omits exempted checks from the `results.json` endpoint. The native Polaris dashboard UI computes the "skipped" count client-side by:
1. Querying Kubernetes resources (Deployments, DaemonSets, StatefulSets, Pods) directly
2. Parsing their annotations for `polaris.fairwinds.com/*-exempt` keys
3. Counting how many checks were exempted
This plugin only has access to the processed audit results via the service proxy and does not query raw Kubernetes resources. To show accurate exemption counts, the plugin would need to:
- Request cluster-wide read access to all workload types (requires additional RBAC grants beyond `services/proxy`)
- Parse annotations on every workload in every namespace
- Cross-reference with the Polaris check catalog to count exemptions
This is a significant architectural change and is not currently implemented. Hover over the "Skipped" count in the UI to see a tooltip explaining this limitation.
**Workaround:** Use the "View in Polaris Dashboard" link from any namespace detail view to see the full exemption count in the native dashboard.
## Releasing
Releases are automated via CI. To cut a release:
+3 -3
View File
@@ -1,4 +1,4 @@
version: 0.1.5
version: 0.2.0-dev.5
name: headlamp-polaris-plugin
displayName: Polaris
createdAt: "2026-02-05T19:00:00Z"
@@ -28,7 +28,7 @@ maintainers:
- name: cpfarhood
email: "chris@farhood.org"
annotations:
headlamp/plugin/archive-url: "https://github.com/cpfarhood/headlamp-polaris-plugin/releases/download/v0.1.5/headlamp-polaris-plugin-0.1.5.tar.gz"
headlamp/plugin/archive-url: "https://github.com/cpfarhood/headlamp-polaris-plugin/releases/download/v0.2.0-dev.5/headlamp-polaris-plugin-0.2.0-dev.5.tar.gz"
headlamp/plugin/version-compat: ">=0.26"
headlamp/plugin/archive-checksum: sha256:7e56af04bcd9121e09eab092608c774b3aa2137d1e0338f1bb06149dd3f5c3ce
headlamp/plugin/archive-checksum: sha256:cb8d03f52022590fce5565b4f08a3fb99d0e264f3ff6a1c99ab59bf48b33ef79
headlamp/plugin/distro-compat: in-cluster
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "headlamp-polaris-plugin",
"version": "0.1.5",
"version": "0.1.6",
"description": "Headlamp plugin for Fairwinds Polaris audit results",
"scripts": {
"start": "headlamp-plugin start",
+1 -1
View File
@@ -146,7 +146,7 @@ export function setRefreshInterval(seconds: number): void {
// --- Polaris dashboard proxy URL ---
export const POLARIS_DASHBOARD_PROXY =
'/api/v1/namespaces/polaris/services/polaris-dashboard/proxy/';
'/api/v1/namespaces/polaris/services/polaris-dashboard:80/proxy/';
// --- Score computation ---
+8 -1
View File
@@ -51,7 +51,14 @@ function OverviewSection(props: { data: AuditData; counts: ResultCounts }) {
name: 'Danger',
value: <StatusLabel status="error">{counts.danger}</StatusLabel>,
},
{ name: 'Skipped', value: String(counts.skipped) },
{
name: 'Skipped',
value: (
<span title="Only counts checks with Severity=ignore. Annotation-based exemptions are not included.">
{counts.skipped}
</span>
),
},
]}
/>
</SectionBox>
+5 -1
View File
@@ -120,7 +120,11 @@ export default function NamespaceDetailView() {
},
{
name: 'Skipped',
value: String(counts.skipped),
value: (
<span title="Only counts checks with Severity=ignore. Annotation-based exemptions are not included.">
{counts.skipped}
</span>
),
},
]}
/>
+1 -1
View File
@@ -74,4 +74,4 @@ registerRoute({
),
});
registerPluginSettings('headlamp-polaris-plugin', PolarisSettings, true);
registerPluginSettings('polaris', PolarisSettings, true);