6c7064faf0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
129 lines
5.3 KiB
Markdown
129 lines
5.3 KiB
Markdown
# ADR-002: Service Proxy as Single Data Source
|
|
|
|
**Status:** Accepted
|
|
**Date:** 2026-03-05
|
|
**Deciders:** Plugin maintainers
|
|
|
|
## Context
|
|
|
|
The Polaris plugin needs audit data from the Polaris dashboard. Polaris dashboard exposes a `/results.json` endpoint containing pre-computed audit results for all workloads in the cluster.
|
|
|
|
Several approaches were considered for obtaining this data:
|
|
|
|
1. Query Kubernetes resources directly and re-implement Polaris audit logic
|
|
2. Use the Polaris CLI as a sidecar container
|
|
3. Use the Polaris dashboard's REST API via Kubernetes service proxy
|
|
4. Embed Polaris as a Go/JS library
|
|
|
|
The service proxy approach uses the Kubernetes API server's built-in service proxy capability to reach the Polaris dashboard at `/api/v1/namespaces/polaris/services/polaris-dashboard:80/proxy/results.json`. This means the plugin receives pre-computed audit results without needing to understand Polaris internals.
|
|
|
|
**Constraints:**
|
|
|
|
- Headlamp plugins can make API calls via `ApiProxy.request()` (proxied through the Headlamp backend) or direct `fetch()` for external URLs
|
|
- The Polaris dashboard service name, namespace, and port may vary across cluster setups
|
|
- Some users may run Polaris externally (not in-cluster)
|
|
|
|
**Requirements:**
|
|
|
|
- Retrieve all audit data in a single API call
|
|
- Support configurable endpoint URL for different cluster configurations
|
|
- Support external Polaris instances via full HTTP/HTTPS URLs
|
|
- Work through existing Kubernetes RBAC without additional configuration
|
|
|
|
## Decision
|
|
|
|
Use **`ApiProxy.request()`** to fetch from the Polaris dashboard service proxy as the single data source for all audit data.
|
|
|
|
**Implementation:**
|
|
|
|
- Default endpoint: `/api/v1/namespaces/polaris/services/polaris-dashboard:80/proxy/results.json`
|
|
- URL is configurable via plugin settings stored in `localStorage` (key: `polaris-plugin-dashboard-url`)
|
|
- For full URLs starting with `http://` or `https://`, use browser `fetch()` directly to support external Polaris instances
|
|
- `getPolarisApiPath()` in `polaris.ts` resolves the configured URL, with `isFullUrl()` determining the fetch strategy
|
|
- Single fetch shared across all views via `PolarisDataProvider` (see ADR-001)
|
|
|
|
## Consequences
|
|
|
|
### Positive
|
|
|
|
- ✅ **Single API call gets all audit data** - One request to `/results.json` returns scores for every workload
|
|
- ✅ **No need to understand Polaris internals** - Plugin receives pre-computed results, no audit logic duplication
|
|
- ✅ **Works through existing K8s RBAC** - Service proxy uses standard Kubernetes RBAC (`get` on `services/proxy`)
|
|
- ✅ **Configurable endpoint** - Users can customize namespace, service name, or point to an external instance
|
|
- ✅ **Minimal plugin complexity** - No CRD watches, no custom controllers, no library dependencies
|
|
|
|
### Negative
|
|
|
|
- ❌ **Requires Polaris dashboard to be deployed and accessible** - Plugin has no data without the dashboard
|
|
- **Mitigated by:** Clear error messages guiding users to install Polaris (404/503 → install guidance)
|
|
- ❌ **Single point of failure** - If the dashboard service is down, the plugin shows no data
|
|
- **Mitigated by:** Status-code-specific error messages (403 → RBAC guidance, 404/503 → deployment guidance)
|
|
- ❌ **Dashboard must be running continuously** - Unlike CRD-based approaches where data persists
|
|
- **Mitigated by:** Polaris dashboard is typically deployed as a long-running service
|
|
|
|
### Neutral
|
|
|
|
- The Polaris dashboard is a lightweight Go service with minimal resource requirements
|
|
- Service proxy is a standard Kubernetes pattern used by many tools (kubectl port-forward, dashboard proxying)
|
|
- The configurable URL approach supports both in-cluster and external Polaris deployments
|
|
|
|
## Alternatives Considered
|
|
|
|
### Option 1: Query Polaris CRDs Directly
|
|
|
|
**Pros:**
|
|
|
|
- No dependency on Polaris dashboard being running
|
|
- Data persists in CRDs even if dashboard restarts
|
|
|
|
**Cons:**
|
|
|
|
- Polaris audit logic is complex and would need to be duplicated in the plugin
|
|
- Would require watching multiple CRD types
|
|
- Plugin would need to be updated whenever Polaris changes its audit rules
|
|
|
|
**Decision:** Rejected (would duplicate Polaris internals, maintenance burden)
|
|
|
|
### Option 2: Use Polaris CLI as a Sidecar
|
|
|
|
**Pros:**
|
|
|
|
- CLI has full audit capability
|
|
- Could run audits on-demand
|
|
|
|
**Cons:**
|
|
|
|
- Adds operational complexity (sidecar container management)
|
|
- Not suitable for a browser-based plugin (CLI runs server-side)
|
|
- Would require a separate backend service to bridge CLI output to the plugin
|
|
|
|
**Decision:** Rejected (operational complexity, not suitable for plugin architecture)
|
|
|
|
### Option 3: Embed Polaris as a Library
|
|
|
|
**Pros:**
|
|
|
|
- Full control over audit execution
|
|
- No external service dependency
|
|
|
|
**Cons:**
|
|
|
|
- Polaris is a Go library, not available in JavaScript/TypeScript plugin runtime
|
|
- Would massively increase bundle size
|
|
- Would duplicate the entire Polaris engine
|
|
|
|
**Decision:** Rejected (not available in plugin runtime, massive dependency)
|
|
|
|
## References
|
|
|
|
- [Kubernetes Service Proxy](https://kubernetes.io/docs/tasks/access-application-cluster/access-cluster-services/)
|
|
- [Polaris Dashboard](https://polaris.docs.fairwinds.com/dashboard/)
|
|
- [Plugin Implementation](../../api/polaris.ts)
|
|
- [Data Context](../../api/PolarisDataContext.tsx)
|
|
|
|
## Revision History
|
|
|
|
| Date | Author | Change |
|
|
| ---------- | ----------- | ---------------- |
|
|
| 2026-03-05 | Plugin Team | Initial decision |
|