Compare commits

..

16 Commits

Author SHA1 Message Date
Chris Farhood b9e9484bf0 Merge pull request 'chore: bump version to 0.1.7' (#24) from release/0.1.7 into main
Reviewed-on: farhoodliquor/headlamp-polaris-plugin#24
2026-02-09 21:01:24 -05:00
Chris Farhood 22d88cfca4 Merge pull request 'docs: remove incorrect dev installation instructions' (#23) from docs/remove-sidecar-instructions into main
Reviewed-on: farhoodliquor/headlamp-polaris-plugin#23
2026-02-09 21:01:18 -05:00
Chris Farhood 48dcb214b9 chore: bump version to 0.1.7 2026-02-09 20:58:41 -05:00
Chris Farhood 762056e46c docs: remove incorrect dev installation instructions 2026-02-09 17:50:08 -05:00
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
gitea-actions[bot] 6ae632f577 ci: update artifact hub metadata for v0.1.5 2026-02-08 01:48:09 +00:00
Chris Farhood e0cfb4e808 chore: bump version to 0.1.5 2026-02-07 20:46:32 -05:00
Chris Farhood c4c43cef40 fix: restore :80 port in service proxy URL
The removal of :80 in commit 39d85a3 broke service proxy requests.
Kubernetes API requires explicit port specification when services
have named ports. Without it, the API server returns "no endpoints
available" even though endpoints exist.

Root cause: polaris-dashboard service defines port as named
"http-dashboard" on port 80. The proxy sub-resource requires
either :80 or :http-dashboard suffix to resolve correctly.

Fixes the "Polaris dashboard not reachable" error on v0.1.4.

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 20:46:13 -05:00
8 changed files with 66 additions and 14 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"
+24
View File
@@ -83,6 +83,10 @@ npm run build
npx @kinvolk/headlamp-plugin extract . /headlamp/plugins
```
## Installing Dev/Preview Versions
Dev preview versions are **not currently available** through the Headlamp plugin manager. Stable versions can be installed from ArtifactHub via the plugin manager UI.
## 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 +226,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.4
version: 0.1.7
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.4/headlamp-polaris-plugin-0.1.4.tar.gz"
headlamp/plugin/archive-url: "https://github.com/cpfarhood/headlamp-polaris-plugin/releases/download/v0.1.7/headlamp-polaris-plugin-0.1.7.tar.gz"
headlamp/plugin/version-compat: ">=0.26"
headlamp/plugin/archive-checksum: sha256:932e875310e1d3cd51a2b87ceff457582f6877395d2c521b75501849ac4af0ae
headlamp/plugin/archive-checksum: sha256:0000000000000000000000000000000000000000000000000000000000000000
headlamp/plugin/distro-compat: in-cluster
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "headlamp-polaris-plugin",
"version": "0.1.4",
"version": "0.1.7",
"description": "Headlamp plugin for Fairwinds Polaris audit results",
"scripts": {
"start": "headlamp-plugin start",
+3 -2
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 ---
@@ -157,7 +157,8 @@ export function computeScore(counts: ResultCounts): number {
// --- Data fetching hook ---
const POLARIS_API_PATH = '/api/v1/namespaces/polaris/services/polaris-dashboard/proxy/results.json';
const POLARIS_API_PATH =
'/api/v1/namespaces/polaris/services/polaris-dashboard:80/proxy/results.json';
interface PolarisDataState {
data: AuditData | null;
+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);