Skip to content

Releases: opscart/opscart-k8s-watcher

v1.10.2 - Persistence & Authentication Recovery

Choose a tag to compare

@opscart opscart released this 30 Jul 04:56

OpsCart v1.10.2

This recovery release retains all v1.10.1 functionality while correcting persistence, authentication, security, and container-platform issues.

Fixed

  • Graceful scanner and HTTP shutdown before closing SQLite
  • WAL checkpointing during controlled shutdown
  • Required persistence now fails startup instead of silently entering ephemeral mode
  • Contextual SQLite startup diagnostics and bounded retry handling
  • Helm-generated credentials now survive pod restarts and upgrades
  • Existing auth.existingSecret behavior remains supported
  • Correct native Linux AMD64 and ARM64 container builds
  • Updated golang.org/x/text to v0.39.0

Helm authentication

When auth.existingSecret is empty, Helm creates and preserves a release-managed Secret. Retrieve credentials using the commands printed by helm install or helm upgrade.

Important storage note

Multi-node Minikube commonly uses node-local hostPath storage. A PVC backed by hostPath is not shared across nodes. Pin the workload to the storage node for local testing, or use genuinely shared/durable storage.

Image

ghcr.io/opscart/opscart-dashboard:v1.10.2

Supported platforms:

  • linux/amd64
  • linux/arm64

OCI index:

sha256:623e77263aa1702de2b069daff574c147485fb5dfaa504161fcaba020c9f6010

v1.10.0 — Workload-Scoped Incidents

Choose a tag to compare

@opscart opscart released this 29 Jul 18:02

v1.10.0 — Workload-Scoped Incidents
The Investigation and Incidents pages no longer anchor on the Pod — the most ephemeral object in Kubernetes — they anchor on the workload that actually owns the problem.

The problem this fixes

A 5-minute-old pod could display a 26-day-old incident timeline. The underlying tracking was correct (an incident should persist across pod replacements — that's what makes it memory), but the presentation wasn't: AGE: 0d sitting beside FIRST DETECTED: 26 days ago read as a contradiction, not as "this Deployment has been unstable for weeks across several pod replacements."

What's new

Deterministic focus selection. When multiple pods briefly match the same incident fingerprint (a pod mid-termination alongside its replacement), OpsCart now selects one canonical Focus Pod — highest restart count wins, pod name breaks ties — instead of the previous arbitrary, scan-order-dependent choice.

Cross-pod contamination fixed. Restart-milestone and drift comparisons now check whether the Focus Pod actually stayed the same between scans. Previously, a pod replacement (249 restarts → 2 restarts) could be misread as a trend on the same object; now a resource change correctly resets the comparison instead of producing a false signal.

Workload-first Incidents table. The Incident column is now Workload, showing the owning Deployment/StatefulSet/DaemonSet as the primary identity with the current pod as a secondary line — matching what the Investigation page shows when you click through.

Investigation page redesign:

Situation Briefing — observational only, no causal claims ("has been observed in a critical state since Jul 10," not "root cause is X" or "never resolved")
Operational Identity card — Classification, Severity, Tracking scope (accurately labeled per controller type: Deployment-wide, StatefulSet-instance-scoped, etc.), Open Since
Current Observation card — Namespace, Workload, Focus Pod, Pod Age, Restart Count, Container, live status, with a ready-to-copy kubectl describe command
Namespace-scoped findings (missing NetworkPolicy, idle namespaces) preserved exactly as before — no pod-shaped data forced onto them
Removed the raw timeline event count, since it was inflated by a still-open flapping investigation — no numbers shown that aren't currently trustworthy

Fixed: Incidents and War Room links no longer pass a synthetic pod parameter for namespace-level findings, and no longer leak the internal current-context placeholder into shareable URLs.

Not in this release

Recurrence statistics (recovered/reopened counts) and pod-replacement timeline events are intentionally held back until an ongoing flapping investigation is resolved — shipping derived stats on top of unverified data would be worse than not shipping them at all.

v1.9.0 — Verdict-First Overview: Operational Memory, Finally Visible

Choose a tag to compare

@opscart opscart released this 19 Jul 16:54

The Overview page no longer opens with a KPI grid — it opens with a written verdict.
New:

Situation Briefing — a two-sentence cluster assessment ("what's wrong, what's improved") backed by real incident data
Operational Memory scoreboard — total seen, resolved, reopened, accelerating, longest-running incident, most unstable namespace
What's Changed Since Last Scan — shows only what happened since your last visit
Top 5 Things To Fix — now shows first-detected age, reopen count, trend; routes correctly (single incident → Investigate, multi-pod group → filtered Incidents view)
Cluster / Namespace / Security health cards, capped with "View all" links
Bottom strip shows real trend deltas ("+8 since yesterday") on cost, waste, and scores

Fixed: Top 5 links were hardcoded to War Room regardless of the issue; the verdict could disagree with Top 5 about the worst issue; a few UI/data inconsistencies found via live testing.
No changes to War Room, Incidents, or Investigation. Standard helm upgrade — no new config required.

Operational memory now survives pod restarts and helm uninstall

Choose a tag to compare

@opscart opscart released this 11 Jul 15:55
f4679f6

Chart parity with deploy/dashboard.yaml plus hardening from in-cluster
verification on multi-node minikube:

  • Persistence: templated PVC (persistence.enabled/size/storageClassName/
    existingClaim), annotated helm.sh/resource-policy: keep so operational
    memory survives helm uninstall; strategy Recreate when enabled (RWO)
  • Namespace: remove templated namespace (use --create-namespace);
    namespace helper resolves .Release.Namespace so -n is honored
  • Volume ownership: fsGroup 65534; values-toggled volumePermissions
    init container for provisioners that ignore fsGroup on hostPath
    (minikube default) — symptom was silent NullStore fallback
  • nodeSelector support — required on multi-node minikube where hostPath
    PVs have no node affinity (rescheduled pod mounts empty dir)
  • NOTES.txt, chart README (persistence, minikube gotchas, local image
    workflow, full values table), root README refreshed (timeline, blast
    radius, operational memory; chart declared canonical)
  • Chart 0.1.0 → 0.2.0, appVersion → v1.7.0; dashboard.yaml image bumped

v1.3.0 — Operational Memory

Choose a tag to compare

@opscart opscart released this 03 Jul 03:39

What's New

Operational Memory (SQLite)

OpsCart now remembers what happened. A lightweight local database tracks cluster
snapshots, incident history, and scan metadata across scans.

  • Trend arrows on all KPI cards — up/down/flat with correct semantics
    (green when improving, red when degrading)
  • 7-point sparkline on Incident Score showing recent history
  • Incident tracking — first seen, last seen, active/resolved status per fingerprint
  • NullStore fallback — persistence is never required; degrades gracefully if DB unavailable

Investigation Page v2

  • OpsCart Assessment — rules-based operational summary paragraph
  • Evidence section — restarts, state, age, owner chips before recommendations
  • Confidence-rated hints — High / Medium / Low with color coding
  • Each hint includes a specific kubectl command

War Room Visual Differentiation

  • Per-type card accent colors (red for CrashLoop, yellow for ImagePullBackOff, purple for Privileged, blue for NetworkPolicy)
  • SVG icons per issue type

Install

# Helm
helm install opscart-watcher ./helm/opscart-watcher \
  --namespace opscart-system \
  --create-namespace

# kubectl
kubectl apply -f https://raw.githubusercontent.com/opscart/opscart-k8s-watcher/main/deploy/dashboard.yaml

Security

  • Trivy scan: 0 vulnerabilities
  • Scratch image, non-root UID 65534
  • Pure Go SQLite (modernc.org/sqlite, CGO_ENABLED=0 compatible)

What's Next

  • PVC-backed persistence (persistence.enabled=true in Helm)
  • Blast radius analysis
  • Change detection ("new since yesterday")

v1.1.0 — Operational Intelligence Navigation

Choose a tag to compare

@opscart opscart released this 27 Jun 18:28

v1.1.0 — Operational Intelligence Navigation

New Pages

  • Incidents — Full grid view of all War Room issues (Critical + High Severity)
  • Security Posture — CIS Kubernetes Benchmark v1.8 controls, risk breakdown, priority actions
  • Waste & Drift — Zombie pods, orphaned PVCs, zero-replica workloads, abandoned namespaces

New Features

  • Incident Score (0-100) — Composite score aggregating crash loops, image pulls, OOM kills, security posture, and waste
  • War Room panel — Multi-card scrollable layout showing top 4 critical issues with kubectl quick fixes
  • Sidebar restructured — Overview/War Room → Investigate → Analyze → Configure

Security

  • Scratch image, non-root (UID 65534)
  • Trivy scan: 0 vulnerabilities
  • Read-only ClusterRole

Deploy

kubectl apply -f https://raw.githubusercontent.com/opscart/opscart-k8s-watcher/main/deploy/dashboard.yaml

New in v1.1.0:

  • Incident Score (0-100)
  • Incidents page
  • Security Posture page
  • Waste & Drift page
  • Sidebar restructure
  • War Room multi-card panel

v1.0.0 - Operational Intelligence

Choose a tag to compare

@opscart opscart released this 20 Jun 01:51
3ffd69a

Major Features:

  • New Overview page: Top 5 Things to Fix + War Room featured panel
  • Sidebar restructure: Overview → Operations → Analysis
  • Critical Issues as primary KPI (replaces Running Pods)
  • Trust badges: Read-only, No agents, No cloud credentials
  • Issue grouping with severity-based prioritization

Engineering:

  • Complete CLI refactor: cmd/opscart-scan/main.go 1682 → 724 lines (57% reduction)
  • Dashboard refactor: templates extracted, main.go 2428 → 1867 lines
  • 46 unit tests passing
  • Trivy scan: 0 vulnerabilities

Security:

  • Scratch image (~50MB)
  • Non-root (UID 65534)
  • Read-only ClusterRole (no mutations)
  • No external dependencies
  • All Go deps updated to latest

Tested on:

  • Real production cluster (53 namespaces, 17 critical issues found)
  • Minikube opscart development cluster"

v0.9.0 — Kubernetes Intelligence Dashboard

Choose a tag to compare

@opscart opscart released this 13 Jun 15:28

🎯 OpsCart K8s Watcher v0.9.0 — Full Kubernetes Intelligence Dashboard

Five working tabs. One kubectl apply. Zero dependencies.


What's New

🖥️ Infrastructure Tab

Node pool deep-dive with VM SKU detection, CPU/memory utilization
bars, $/node/month, pool totals, and Reserved Instance savings
potential (1yr and 3yr).

📦 Namespaces Tab

The only view that cross-references cost + network policy + waste
per namespace. See exactly which namespaces are unprotected,
how much they cost, and how many waste items they contain.

💡 Optimizations Tab

  • Reserved Instance opportunities with projected savings
  • Waste by category: orphaned PVCs, zombie pods, zero-replica
    workloads, abandoned namespaces
  • Right-sizing candidates (namespaces with <0.5 CPU cores)

⚔️ War Room Full Page

Real-time critical issues with per-card kubectl commands:

  • Critical: CrashLoopBackOff, OOMKilled, ImagePullBackOff pods
  • Warnings: unprotected namespaces, orphaned PVCs, zero-replica workloads
  • One-click copy kubectl commands for immediate investigation

🔧 Bug Fixes

  • Fixed War Room silently returning empty results (limit=0 bug)
  • Fixed pods in default namespace being skipped by waste detector
  • Zombie pods now bypass minAgeDays filter — a crashing pod is
    a crashing pod regardless of age
  • Optimizations tab now reads correct waste data from WasteAudit

Deploy in 60 Seconds

kubectl apply -f https://raw.githubusercontent.com/opscart/opscart-k8s-watcher/main/deploy/dashboard.yaml
kubectl port-forward -n opscart-system svc/opscart-dashboard 8080:80
open http://localhost:8080

What Each Tab Shows

Tab Data Source Key Insight
Cost Overview Azure pricing catalog Real $/mo from node labels
Infrastructure NodePoolCosts VM SKU, utilization, RI savings
Namespaces Cost + NetPol + Waste Cross-referenced per namespace
Optimizations All analyzers Actionable savings opportunities
War Room Waste + Network audits Critical issues needing action now

Tested On

  • Azure AKS multi-node-pool clusters
  • Minikube (local development)

What's Next (v1.0)

  • SQLite 30-day cost history + trend charts
  • Helm chart (helm install opscart-dashboard)
  • GitHub Actions auto-build on release tag
  • AWS/GCP pricing catalog

Docker image: ghcr.io/opscart/opscart-dashboard:v0.9.0
Full changelog: Compare v0.8.0...v0.9.0

v0.7.0 — Cloud Cost Analysis

Choose a tag to compare

@opscart opscart released this 09 Jun 15:35

Accurate cloud cost estimation from real AKS node pool VM pricing.
No external API calls — embedded Azure retail price catalog.

Highlights:
• Detects VM SKUs from node labels automatically
• 40+ Azure VM SKUs with PAYG/RI-1yr/RI-3yr/Spot pricing
• Region-aware multipliers (15+ regions)
• Namespace + deployment cost allocation
• Enterprise HTML dashboard (dark theme, SVG charts)
• Optimization scenarios with projected savings
• Multi-cluster support

FinOps grade cost analysis v0.6.0

Choose a tag to compare

@opscart opscart released this 27 May 04:03
  • Add --breakdown deployment flag: per-Deployment/StatefulSet/DaemonSet cost drill-down in CLI
  • Add HTML cost dashboard (--format html): KPI cards, share bars, waste, score bars, optimization scenario cards, assumptions footnotes
  • Remove spot instance scenarios; replace with right-sizing, idle workload, and namespace consolidation scenarios
  • Exclude system namespaces (kube-system, cert-manager, istio-system, monitoring, flux-system, etc.) from optimization recommendations and deployment breakdown
  • Make --monthly-cost optional: resource-share mode when no billing data
  • Add unallocated row reconciling namespace allocations vs cluster total
  • Fix idle pod detection: allow up to 5 restarts (was 0, broke all
    production pods); require 7+ day age threshold
  • Fix confidence scoring: 3-signal model (share size + pod count +
    waste); replaces share-size-only logic that returned Medium for ~95% of namespaces
  • Add wasteColor, mul template FuncMap helpers in costs_html.go
  • Bump version to 0.6.0; update README with all changes

What's Changed

Full Changelog: v0.5.3...v0.6.0