Skip to content

Kubernetes - #107

Open
adamkinniburgh wants to merge 1 commit into
mainfrom
work/ak/kubernetes
Open

Kubernetes#107
adamkinniburgh wants to merge 1 commit into
mainfrom
work/ak/kubernetes

Conversation

@adamkinniburgh

@adamkinniburgh adamkinniburgh commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

🔌 Plugin overview

  • Plugin name: Kubernetes
  • Purpose / problem solved: Auto-discovered, live service map of a Kubernetes cluster — namespaces, nodes, workloads (deployments/replicasets/daemonsets/statefulsets/pods), networking (services/ingresses), storage (persistent volumes/claims), and per-namespace resource guardrails (resource quotas/limit ranges) — with real control-plane health straight from the API (no Prometheus dependency), live CPU/memory usage via the standard Metrics API, and a live cluster events feed.
  • Primary audience: Platform teams / SREs monitoring Kubernetes clusters alongside their other infrastructure in SquaredUp.
  • Authentication method(s): ServiceAccount Bearer Token (cluster-wide read-only RBAC — manifest provided in the README) against the cluster's API server. Hybrid plugin: supports both cloud mode (direct) and relay agent mode (for private/firewalled clusters).

🖼️ Plugin screenshots

Plugin configuration

image

Default dashboards

image image

🧪 Testing

Tested end-to-end against a real cluster (OrbStack locally / GKE remotely). Created disposable test workloads (DaemonSet, StatefulSet, PVC + consuming pod, Ingress) to exercise object types the base cluster didn't otherwise have.

  • Verified import for all 12 object types and the full correlation graph (pod → node/replicaset/service/ingress/namespace, etc.)
  • Verified control-plane health signals (node pressure/readiness, workload availability, pod crash-loop/OOM detection) against induced failure states
  • Installed metrics-server (with --kubelet-insecure-tls for the local cluster's self-signed kubelet certs) and verified live CPU/memory usage tiles on Node and Pod perspectives
  • Verified all 11 OOB dashboards (Cluster Overview + Node/Namespace/Deployment/DaemonSet/StatefulSet/Pod/Service/Ingress/Persistent Volume perspectives), including drilldowns
  • Reviewed and corrected unit formatting across tiles (millicores, megabytes) and column visibility choices (hiding redundant/constant columns on already-scoped perspectives, keeping genuinely varying columns visible)
  • Consolidated several scoped drilldown data streams into their unscoped counterparts using an optional objects UI filter, reducing the stream count while keeping the same dashboard behavior

⚠️ Known limitations

  • CPU/memory usage requires metrics-server in the cluster (standard lightweight Kubernetes Metrics API, not Prometheus) — usage tiles show no data without it, rest of the plugin unaffected
  • Label-selector Service→Pod matching is a single-key approximation (app / app.kubernetes.io/name / k8s-app), not full subset matching
  • Ingress→Service correlation follows one "primary" backend (default backend, or first rule's first path) rather than modeling every path individually
  • Cluster-wide read RBAC required — no per-namespace fan-out in this version
  • No historical metrics — every stream is a current-state snapshot; pair with a Prometheus-based plugin for trends
  • No mTLS/client-certificate auth — bearer token only
  • Jobs/CronJobs are not yet imported (planned future addition)
  • Read-only — never creates, modifies, or deletes anything in the cluster

📚 Checklist

  • Plugin, datastream and UI naming follow SquaredUp guidelines
  • Logo added
  • One or more dashboards added
  • README added including configuration guidance
  • No secrets or credentials included
  • I agree to the Code of Conduct

Summary by CodeRabbit

  • New Features

    • Added Kubernetes monitoring with support for workloads, pods, nodes, services, storage, namespaces, events, quotas, and limits.
    • Added cluster version, CPU, and memory metrics visibility.
    • Added automatic relationships between Kubernetes resources, including ownership, scheduling, routing, and namespace membership.
    • Added dashboards for common Kubernetes resources with health, capacity, status, and related-object views.
    • Added API server authentication and connection validation.
  • Documentation

    • Added setup guidance, access requirements, supported resources, dashboards, relationships, and known limitations.

@adamkinniburgh
adamkinniburgh requested a review from a team August 5, 2026 11:55
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

🧩 Plugin PR Summary

📦 Modified Plugins

  • plugins/Kubernetes/v1

📋 Results

Step Status
Validation ✅ Passed
Deployment 🚀 Deployed

🔍 Validation Details

kubernetes
{
  "valid": true,
  "pluginName": "kubernetes",
  "pluginType": "hybrid",
  "summary": {
    "Data Streams": 19,
    "Import Definitions": 1,
    "Correlation Rules": 8,
    "UI Configuration": true,
    "Has Icon": true,
    "Has Default Content": true,
    "Config Validation": true,
    "Custom Types": true
  }
}

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a complete Kubernetes plugin with API authentication, resource data streams, normalized metrics and health data, object relationships, indexed resources, dashboards, scopes, and setup documentation.

Changes

Kubernetes plugin foundation

Layer / File(s) Summary
Plugin contract and resource types
plugins/Kubernetes/v1/{configValidation.json,metadata.json,ui.json,custom_types.json}
Defines Kubernetes connection fields, bearer-token authentication, API validation, plugin metadata, and custom resource types.
Data stream contracts
plugins/Kubernetes/v1/dataStreams/*.json
Adds data streams for Kubernetes resources, namespace contents, events, cluster version, node metrics, and pod metrics.
Record transformations
plugins/Kubernetes/v1/dataStreams/scripts/*.js
Normalizes API responses, parses CPU and memory quantities, calculates health and resource values, aggregates metrics, and applies parent-resource filters.
Object relationships and indexing
plugins/Kubernetes/v1/correlationRules/*.json, plugins/Kubernetes/v1/indexDefinitions/default.json
Adds relationships among namespaces, workloads, pods, nodes, services, ingresses, and storage. Defines indexed object properties and collection dependencies.
Scopes and dashboards
plugins/Kubernetes/v1/defaultContent/*
Adds resource scopes and dashboards for Kubernetes namespaces, nodes, workloads, pods, services, ingresses, and persistent volumes.
Kubernetes documentation
plugins/Kubernetes/v1/docs/README.md
Documents setup, RBAC, authentication, monitored resources, data streams, relationships, dashboards, and known limitations.

Sequence Diagram(s)

sequenceDiagram
  participant PluginConfiguration
  participant KubernetesAPI
  participant DataStreamScripts
  participant IndexedObjects
  participant Perspectives
  PluginConfiguration->>KubernetesAPI: Validate bearer-token access through /version
  KubernetesAPI->>DataStreamScripts: Return resource and metric responses
  DataStreamScripts->>IndexedObjects: Emit normalized resource records
  IndexedObjects->>Perspectives: Provide scoped data for dashboard tiles
Loading
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title identifies the Kubernetes plugin but does not state the primary change, so it is too broad to be useful in project history. Use a specific title such as "Add Kubernetes monitoring plugin" to describe the main change.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The description covers the plugin purpose, configuration, screenshots, testing, limitations, and checklist required for a new plugin.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands.

@adamkinniburgh adamkinniburgh changed the title feat: Kubernetes plugin Kubernetes Aug 5, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 29

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@plugins/Kubernetes/v1/configValidation.json`:
- Around line 4-10: Update the Kubernetes config validation for the Authenticate
data stream so it no longer relies on the non-resource `/version` endpoint in
the dataStream.name field. Use a protected read-only resource path or add an
explicit RBAC permission check in the validation flow around the Authenticate
configuration so success only means the cluster can actually read a protected
resource.

In `@plugins/Kubernetes/v1/correlationRules/relate-ingress-to-service.json`:
- Around line 9-14: Update the conditions arrays in
plugins/Kubernetes/v1/correlationRules/relate-ingress-to-service.json (lines
9-14) and plugins/Kubernetes/v1/correlationRules/relate-service-to-pod.json
(lines 9-14) to add a second condition matching sourceProperty "namespace" to
targetProperty "namespace" in addition to the existing name-based condition.

In `@plugins/Kubernetes/v1/dataStreams/daemonsets.json`:
- Around line 5-7: Replace the plugin-name tag "Kubernetes" with the applicable
existing reusable category in the tags arrays for
plugins/Kubernetes/v1/dataStreams/daemonsets.json lines 5-7, deployments.json
lines 5-7, events.json lines 5-7, ingresses.json lines 5-7, limitranges.json
lines 5-7, namespaceContents.json lines 5-7, and namespaces.json lines 5-7;
preserve the existing tags structure and do not use the plugin name as a
category.

In `@plugins/Kubernetes/v1/dataStreams/limitranges.json`:
- Around line 39-76: Update the limit-range fields defaultMemoryMi,
defaultRequestMemoryMi, maxMemoryMi, and minMemoryMi in
plugins/Kubernetes/v1/dataStreams/limitranges.json (lines 39-76) to byte-based
names, emit raw numeric byte values, and use shape "bytes". Apply the same field
renaming and bytes-shape contract in
plugins/Kubernetes/v1/dataStreams/namespaceContents.json (lines 254-357), and
update the namespaceContents script to emit byte values for those fields.

In `@plugins/Kubernetes/v1/dataStreams/namespaceContents.json`:
- Line 11: Replace the nested detailType ternary in endpointPath with a
dedicated map that explicitly associates each supported resource type with its
API-group path, including the core api/v1 fallback as appropriate. Update the
endpoint construction to look up the mapped path, making unsupported detailType
values explicit while preserving the existing namespace and resource suffixes.

In `@plugins/Kubernetes/v1/dataStreams/nodeMetrics.json`:
- Around line 5-7: Replace the plugin-name value in the tags array with an
existing non-plugin category, keeping the tag structure unchanged and following
the repository’s established category vocabulary.
- Around line 36-50: Update the cpuUsageMillicores field to emit raw numeric
values by removing its suffix and decimal formatting from shape, leaving only
the numeric semantic. Change the memory field contract from memoryUsageMi to a
byte-based field name such as memoryUsageBytes and set its shape to bytes.
Update every dependent dashboard column to use the renamed field and apply CPU
and memory presentation formatting there.

In `@plugins/Kubernetes/v1/dataStreams/nodes.json`:
- Around line 5-7: Replace the plugin-name tag "Kubernetes" with applicable
existing repository category tags in the tags arrays for
plugins/Kubernetes/v1/dataStreams/nodes.json:5-7,
plugins/Kubernetes/v1/dataStreams/persistentvolumes.json:5-7,
plugins/Kubernetes/v1/dataStreams/podMetrics.json:5-7,
plugins/Kubernetes/v1/dataStreams/pods.json:5-7,
plugins/Kubernetes/v1/dataStreams/podsByParent.json:5-7, and
plugins/Kubernetes/v1/dataStreams/pvClaims.json:5-7. Keep tags mandatory, reuse
established categories consistently across these data streams, and do not use
the plugin name.

In `@plugins/Kubernetes/v1/dataStreams/podsByParent.json`:
- Around line 11-14: Replace the conditional mustache expressions in the
pods-by-parent data stream’s endpointPath and getArgs with supported map
transformations, preserving the namespace-specific versus cluster-wide pod
endpoint and the node fieldSelector behavior. Use the schema’s mapped-value form
for both request variants and keep the resulting requests declarative.

In `@plugins/Kubernetes/v1/dataStreams/replicasets.json`:
- Around line 5-7: Replace the plugin-name tag "Kubernetes" with an applicable
existing generic category in the tags arrays for
plugins/Kubernetes/v1/dataStreams/replicasets.json lines 5-7,
plugins/Kubernetes/v1/dataStreams/resourcequotas.json lines 5-7,
plugins/Kubernetes/v1/dataStreams/services.json lines 5-7, and
plugins/Kubernetes/v1/dataStreams/statefulsets.json lines 5-7; keep tags present
and use the same suitable category consistently without introducing new
categories.

In `@plugins/Kubernetes/v1/dataStreams/resourcequotas.json`:
- Around line 44-71: The Kubernetes resource quota memory fields currently
expose Mi values under a megabytes contract. Rename the memory quota fields to
their ...Bytes equivalents, convert values to raw bytes in resourcequotas.js,
and change their shapes to bytes; update all consumers including
namespaceContents, index definitions, and dashboards. Preserve v1 and add the
contract change in a new major-version folder with the corresponding
metadata.json version increment.

In `@plugins/Kubernetes/v1/dataStreams/scripts/ingresses.js`:
- Around line 15-28: Add a brief intent comment immediately above
primaryBackendServiceName explaining that it exposes only the default backend or
the service from the first rule path, and does not select later rules or paths.

In `@plugins/Kubernetes/v1/dataStreams/scripts/limitranges.js`:
- Around line 1-30: Update the Kubernetes Quantity parsers in
plugins/Kubernetes/v1/dataStreams/scripts/limitranges.js:1-30,
namespaceContents.js:1-30, nodeMetrics.js:1-30, and nodes.js:1-30, plus the
memory parser in persistentvolumes.js:1-18, to support exponential notation,
valid binary/decimal suffixes, and milli semantics for CPU and memory; return
undefined or raise an error for unknown suffixes instead of treating them as
dimensionless. Add the requested fixtures for 129e6, 400m, 1Ei, 1k, and 250m,
document the conversion logic with a comment, and increment the plugin version
in plugins/Kubernetes/v1/metadata.json from 1.0.0.

In `@plugins/Kubernetes/v1/dataStreams/scripts/podMetrics.js`:
- Around line 13-56: Retain all v1 files unchanged, including
plugins/Kubernetes/v1/dataStreams/scripts/podMetrics.js:13-56,
plugins/Kubernetes/v1/dataStreams/podMetrics.json:43-57,
plugins/Kubernetes/v1/dataStreams/nodes.json:149-171,
plugins/Kubernetes/v1/dataStreams/persistentvolumes.json:50-52,
plugins/Kubernetes/v1/dataStreams/pods.json:102-114, and
plugins/Kubernetes/v1/dataStreams/pvClaims.json:51-53. Add the next
major-version folder with copied equivalents, update parseMemoryMi and the
affected summation/field names to produce byte values with correct decimal
conversions, rename *Mi fields to *Bytes, and use bytes shapes in all listed
streams and dashboard metadata. Remove the CPU display-format tuple from the new
podMetrics.json and update the new metadata.json version.

In `@plugins/Kubernetes/v1/dataStreams/scripts/pods.js`:
- Around line 1-29: Replace the ad hoc parsing in parseCpuMillicores and
parseMemoryMi with a shared Kubernetes Quantity parser that accepts exponent
notation and all valid decimal/binary SI suffixes, including milli-byte values.
Convert parsed quantities to millicores or Mi using the correct base-unit
semantics, especially treating memory suffix m as 0.001 byte, and reuse the same
parser across all duplicated resource parsing paths. Add fixtures covering
exponent, decimal-SI, binary-SI, and milli-byte quantities.

In `@plugins/Kubernetes/v1/dataStreams/scripts/replicasets.js`:
- Around line 2-8: Update the owner selection in the replicasets mapping to
search item.metadata.ownerReferences for the reference whose controller field is
true, rather than taking the first entry. Keep ownerUid undefined when no
controller reference exists so the existing filter behavior remains correct.

In `@plugins/Kubernetes/v1/dataStreams/scripts/resourcequotas.js`:
- Around line 1-30: Replace the duplicate parseCpuMillicores and parseMemoryMi
logic in plugins/Kubernetes/v1/dataStreams/scripts/resourcequotas.js (lines
1-30) and plugins/Kubernetes/v1/dataStreams/scripts/pvClaims.js (lines 1-18)
with complete Kubernetes Quantity parsing that accepts signed values, decimals,
and scientific notation and correctly handles n, u, m, k, and all binary and
decimal memory suffixes through E/Ei. Apply the same parser update to any other
Kubernetes data-stream scripts containing these helpers, then increment
plugins/Kubernetes/v1/metadata.json.

In `@plugins/Kubernetes/v1/defaultContent/Perspectives/node.dash.json`:
- Line 144: Update the tile titles in node.dash.json (line 144),
daemonset.dash.json (line 106), and statefulset.dash.json (line 106) to
capitalize “This”: use “Pods on This Node,” “Pods on This DaemonSet,” and “Pods
on This StatefulSet.”
- Around line 36-73: Update the metadata and tile overrides for every Mi-valued
field returned by parseMemoryMi to convert values to bytes and use the
binary-accurate "bytes" shape instead of "megabytes". Apply this consistently in
node.dash.json (lines 36-73), pod.dash.json (lines 36-55), and
persistentvolume.dash.json (lines 118-128), covering all three dashboards.

In `@plugins/Kubernetes/v1/docs/README.md`:
- Around line 64-66: Update the code fence immediately preceding the kubectl
create token command to specify the shell language as ```shell, leaving the
command and surrounding documentation unchanged.
- Line 1: Prepend the README content with a descriptive level-one Markdown
heading for the Kubernetes plugin, and keep the existing introductory paragraph
immediately below it unchanged.
- Line 118: Update the Pod row in the Kubernetes API documentation table to
describe the indexed population as a Kubernetes Pod regardless of phase,
replacing the inaccurate “A running pod” wording while preserving the existing
endpoint.
- Around line 132-133: Update the RBAC documentation in the README to
distinguish permission scopes: state that unscoped object and metrics streams
require cluster-wide list permissions, while Namespace Contents, namespaced Pods
by Parent, and Persistent Volume Claims use namespaced requests and require
access in every target namespace.
- Around line 62-68: Update the ServiceAccount token documentation around the
`kubectl create token` command to state that `--duration=8760h` is limited by
the API server’s effective token lifetime. Add concise rotation and
compromise-response guidance for both TokenRequest tokens and Secret-based
tokens, including deleting or replacing the Secret where applicable.
- Line 9: Update the setup instructions in the README to replace the
cluster-admin requirement with the specific RBAC prerequisites: the setup
identity needs get and create/patch access for the manifest objects, plus either
the granted permissions or escalate on clusterroles and bind on the
squaredup-reader ClusterRole. Keep the kubectl apply command unchanged.
- Around line 92-93: Update the README feature description to rename “Real
control-plane health” to “cluster and resource health,” preserving the existing
node, workload, and pod/container health details. Do not claim API-server,
scheduler, controller-manager, or etcd readiness unless documented readiness
signals are added.
- Line 85: Update the “Ignore certificate errors” entry in the configuration
table to warn that disabling TLS verification can enable man-in-the-middle
attacks and expose the Bearer Token on untrusted networks. Explicitly advise
against enabling it for internet-reachable clusters, and document the supported
trusted-CA alternative; if none exists, recommend a CA-signed server certificate
or relay agent mode.

In `@plugins/Kubernetes/v1/ui.json`:
- Around line 3-10: Add a validation.pattern to the host field in the Kubernetes
UI configuration that accepts only non-whitespace HTTPS URLs, such as
^https://[^\s]+$. Add or update validation coverage to confirm an http:// host
is rejected before any request is sent, while preserving required-field
validation.
- Around line 23-27: Update the Kubernetes plugin auth flow so bearer-token
requests are not sent when ignoreCertificateErrors is enabled. Use the
ignoreCertificateErrors setting from the UI config to gate any Authorization
header creation in the Kubernetes plugin’s request/metadata path, and ensure all
credential-bearing calls respect the same check. Keep the existing
self-signed-certificate UX, but prevent token transmission whenever TLS
validation is disabled.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: 86556307-a637-4f1e-92e9-8799f0dc2bc7

📥 Commits

Reviewing files that changed from the base of the PR and between 55b2cfc and 9629b74.

⛔ Files ignored due to path filters (1)
  • plugins/Kubernetes/v1/icon.svg is excluded by !**/*.svg
📒 Files selected for processing (64)
  • plugins/Kubernetes/v1/configValidation.json
  • plugins/Kubernetes/v1/correlationRules/relate-daemonset-to-pod.json
  • plugins/Kubernetes/v1/correlationRules/relate-deployment-to-replicaset.json
  • plugins/Kubernetes/v1/correlationRules/relate-ingress-to-service.json
  • plugins/Kubernetes/v1/correlationRules/relate-namespace-to-objects.json
  • plugins/Kubernetes/v1/correlationRules/relate-node-to-pod.json
  • plugins/Kubernetes/v1/correlationRules/relate-replicaset-to-pod.json
  • plugins/Kubernetes/v1/correlationRules/relate-service-to-pod.json
  • plugins/Kubernetes/v1/correlationRules/relate-statefulset-to-pod.json
  • plugins/Kubernetes/v1/custom_types.json
  • plugins/Kubernetes/v1/dataStreams/daemonsets.json
  • plugins/Kubernetes/v1/dataStreams/deployments.json
  • plugins/Kubernetes/v1/dataStreams/events.json
  • plugins/Kubernetes/v1/dataStreams/ingresses.json
  • plugins/Kubernetes/v1/dataStreams/limitranges.json
  • plugins/Kubernetes/v1/dataStreams/namespaceContents.json
  • plugins/Kubernetes/v1/dataStreams/namespaces.json
  • plugins/Kubernetes/v1/dataStreams/nodeMetrics.json
  • plugins/Kubernetes/v1/dataStreams/nodes.json
  • plugins/Kubernetes/v1/dataStreams/persistentvolumes.json
  • plugins/Kubernetes/v1/dataStreams/podMetrics.json
  • plugins/Kubernetes/v1/dataStreams/pods.json
  • plugins/Kubernetes/v1/dataStreams/podsByParent.json
  • plugins/Kubernetes/v1/dataStreams/pvClaims.json
  • plugins/Kubernetes/v1/dataStreams/replicasets.json
  • plugins/Kubernetes/v1/dataStreams/resourcequotas.json
  • plugins/Kubernetes/v1/dataStreams/scripts/daemonsets.js
  • plugins/Kubernetes/v1/dataStreams/scripts/deployments.js
  • plugins/Kubernetes/v1/dataStreams/scripts/events.js
  • plugins/Kubernetes/v1/dataStreams/scripts/ingresses.js
  • plugins/Kubernetes/v1/dataStreams/scripts/limitranges.js
  • plugins/Kubernetes/v1/dataStreams/scripts/namespaceContents.js
  • plugins/Kubernetes/v1/dataStreams/scripts/namespaces.js
  • plugins/Kubernetes/v1/dataStreams/scripts/nodeMetrics.js
  • plugins/Kubernetes/v1/dataStreams/scripts/nodes.js
  • plugins/Kubernetes/v1/dataStreams/scripts/persistentvolumes.js
  • plugins/Kubernetes/v1/dataStreams/scripts/podMetrics.js
  • plugins/Kubernetes/v1/dataStreams/scripts/pods.js
  • plugins/Kubernetes/v1/dataStreams/scripts/podsByParent.js
  • plugins/Kubernetes/v1/dataStreams/scripts/pvClaims.js
  • plugins/Kubernetes/v1/dataStreams/scripts/replicasets.js
  • plugins/Kubernetes/v1/dataStreams/scripts/resourcequotas.js
  • plugins/Kubernetes/v1/dataStreams/scripts/services.js
  • plugins/Kubernetes/v1/dataStreams/scripts/statefulsets.js
  • plugins/Kubernetes/v1/dataStreams/scripts/version.js
  • plugins/Kubernetes/v1/dataStreams/services.json
  • plugins/Kubernetes/v1/dataStreams/statefulsets.json
  • plugins/Kubernetes/v1/dataStreams/version.json
  • plugins/Kubernetes/v1/defaultContent/Perspectives/daemonset.dash.json
  • plugins/Kubernetes/v1/defaultContent/Perspectives/deployment.dash.json
  • plugins/Kubernetes/v1/defaultContent/Perspectives/ingress.dash.json
  • plugins/Kubernetes/v1/defaultContent/Perspectives/manifest.json
  • plugins/Kubernetes/v1/defaultContent/Perspectives/namespace.dash.json
  • plugins/Kubernetes/v1/defaultContent/Perspectives/node.dash.json
  • plugins/Kubernetes/v1/defaultContent/Perspectives/persistentvolume.dash.json
  • plugins/Kubernetes/v1/defaultContent/Perspectives/pod.dash.json
  • plugins/Kubernetes/v1/defaultContent/Perspectives/service.dash.json
  • plugins/Kubernetes/v1/defaultContent/Perspectives/statefulset.dash.json
  • plugins/Kubernetes/v1/defaultContent/manifest.json
  • plugins/Kubernetes/v1/defaultContent/scopes.json
  • plugins/Kubernetes/v1/docs/README.md
  • plugins/Kubernetes/v1/indexDefinitions/default.json
  • plugins/Kubernetes/v1/metadata.json
  • plugins/Kubernetes/v1/ui.json

Comment on lines +4 to +10
"displayName": "Authenticate",
"dataStream": {
"name": "version"
},
"required": true,
"error": "Could not connect to the Kubernetes API server. Check the API Server URL is reachable, the Bearer Token is valid, and enable 'Ignore certificate errors' if the cluster uses a self-signed certificate.",
"success": "Connected to the Kubernetes API server successfully."

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- candidate file ---'
cat -n plugins/Kubernetes/v1/configValidation.json

printf '%s\n' '--- Kubernetes plugin files ---'
git ls-files plugins/Kubernetes

printf '%s\n' '--- version stream and endpoint references ---'
rg -n -C 3 '"name": "version"|/version|configValidation|dataStream' plugins/Kubernetes/v1

printf '%s\n' '--- metadata files and versions ---'
for f in $(git ls-files 'plugins/Kubernetes/**/metadata.json'); do
  printf '%s\n' "--- $f"
  cat "$f"
done

Repository: squaredup/plugins

Length of output: 50373


🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- version stream ---'
cat -n plugins/Kubernetes/v1/dataStreams/version.json
cat -n plugins/Kubernetes/v1/dataStreams/scripts/version.js

printf '%s\n' '--- representative protected streams ---'
for f in plugins/Kubernetes/v1/dataStreams/namespaces.json plugins/Kubernetes/v1/dataStreams/pods.json plugins/Kubernetes/v1/dataStreams/nodes.json plugins/Kubernetes/v1/dataStreams/events.json; do
  printf '%s\n' "--- $f"
  cat -n "$f"
done

printf '%s\n' '--- authentication and RBAC documentation ---'
rg -n -C 5 'Role|ClusterRole|apiGroups|resources|verbs|ServiceAccount|Bearer|anonymous|/version|httpRequestUnscoped' \
  plugins/Kubernetes/v1/docs/README.md \
  plugins/Kubernetes/v1/dataStreams \
  plugins/Kubernetes/v1

printf '%s\n' '--- metadata ---'
cat -n plugins/Kubernetes/v1/metadata.json

printf '%s\n' '--- compact data-stream endpoint summary ---'
python3 - <<'PY'
import json
from pathlib import Path

for path in sorted(Path("plugins/Kubernetes/v1/dataStreams").glob("*.json")):
    obj = json.loads(path.read_text())
    config = obj.get("config", {})
    print(f"{path}: name={obj.get('name')!r} base={obj.get('baseDataSourceName')!r} method={config.get('httpMethod')!r} endpoint={config.get('endpointPath')!r}")
PY

Repository: squaredup/plugins

Length of output: 50375


🌐 Web query:

Kubernetes official documentation anonymous authentication default /version public-info-viewer RBAC non-resource URL

💡 Result:

In Kubernetes, anonymous authentication is enabled by default [1][2][3]. When a request is not rejected by other configured authentication methods, the API server treats it as an anonymous request, assigning it the username system:anonymous and the group system:unauthenticated [1][4][2]. The system:public-info-viewer ClusterRole is a default role that provides read-only access to non-sensitive cluster information, including the /version and /healthz endpoints [5][3][6]. This role is bound by default to the system:unauthenticated group (as well as the system:authenticated group) [5][3][7], which permits anonymous users to access these specific non-resource URLs [3][7]. To manage or restrict anonymous access, administrators have two primary methods: 1. Command-line flag: Start the kube-apiserver with --anonymous-auth=false to disable anonymous authentication entirely [1][2][3]. 2. AuthenticationConfiguration: For more granular control, the AuthenticationConfiguration resource (stable in Kubernetes v1.34) allows specifying an explicit allowlist of paths (e.g., /livez, /readyz, /healthz) that support anonymous requests [1][2]. If an AuthenticationConfiguration file is used, the --anonymous-auth flag must not be set [1][8]. Non-resource URLs, such as /version or /healthz, are handled distinctly from namespaced resources in RBAC [9]. Granting access to these requires defining rules that specify nonResourceURLs rather than standard resource types [9][10]. If an identity, including the anonymous user, lacks the necessary permissions for these non-resource paths, the request will be rejected with a forbidden error [9].

Citations:


🏁 Script executed:

#!/bin/bash
set -eu

python3 - <<'PY'
import json
from pathlib import Path

root = Path("plugins/Kubernetes/v1")
validation = json.loads((root / "configValidation.json").read_text())
version = json.loads((root / "dataStreams/version.json").read_text())
protected_names = ["namespaces", "pods", "nodes", "events"]
protected = {}
for name in protected_names:
    obj = json.loads((root / f"dataStreams/{name}.json").read_text())
    protected[name] = obj["config"]["endpointPath"]

readme = (root / "docs/README.md").read_text()
manifest = readme[readme.index("```yaml") + len("```yaml"):readme.index("```", readme.index("```yaml") + len("```yaml"))]

print("validation_stream:", validation["steps"][0]["dataStream"]["name"])
print("validation_required:", validation["steps"][0]["required"])
print("validation_success:", validation["steps"][0]["success"])
print("version_endpoint:", version["config"]["endpointPath"])
print("protected_endpoints:", protected)
print("rbac_has_non_resource_urls:", "nonResourceURLs:" in manifest)
print("rbac_declares_list_and_get:", 'verbs: ["list", "get"]' in manifest)
print("docs_validation_endpoint:", "/version" in readme)
assert validation["steps"][0]["dataStream"]["name"] == "version"
assert version["config"]["endpointPath"] == "/version"
assert all(path.startswith("/api/") for path in protected.values())
assert "nonResourceURLs:" not in manifest
assert 'verbs: ["list", "get"]' in manifest
PY

printf '%s\n' '--- changed paths and metadata version ---'
git diff --name-only
python3 - <<'PY'
import json
from pathlib import Path
metadata = json.loads(Path("plugins/Kubernetes/v1/metadata.json").read_text())
print("metadata_version:", metadata.get("version"))
PY

Repository: squaredup/plugins

Length of output: 609


Validate a protected Kubernetes resource.

/version is a non-resource endpoint that can succeed without get or list permissions. Configuration validation can therefore succeed before the first resource request fails. Validate a protected read-only resource endpoint or add a separate RBAC check.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/Kubernetes/v1/configValidation.json` around lines 4 - 10, Update the
Kubernetes config validation for the Authenticate data stream so it no longer
relies on the non-resource `/version` endpoint in the dataStream.name field. Use
a protected read-only resource path or add an explicit RBAC permission check in
the validation flow around the Authenticate configuration so success only means
the cluster can actually read a protected resource.

Source: MCP tools

Comment on lines +9 to +14
"conditions": [
{
"sourceProperty": "primaryBackendServiceName",
"operator": "equals",
"targetProperty": "name"
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Add namespace conditions to namespace-scoped relationships.

Both rules compare fields that can repeat across namespaces. This can create false edges in the service map.

  • plugins/Kubernetes/v1/correlationRules/relate-ingress-to-service.json#L9-L14: Add sourceProperty: "namespace" and targetProperty: "namespace" as a second condition.
  • plugins/Kubernetes/v1/correlationRules/relate-service-to-pod.json#L9-L14: Add sourceProperty: "namespace" and targetProperty: "namespace" as a second condition.
📍 Affects 2 files
  • plugins/Kubernetes/v1/correlationRules/relate-ingress-to-service.json#L9-L14 (this comment)
  • plugins/Kubernetes/v1/correlationRules/relate-service-to-pod.json#L9-L14
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/Kubernetes/v1/correlationRules/relate-ingress-to-service.json` around
lines 9 - 14, Update the conditions arrays in
plugins/Kubernetes/v1/correlationRules/relate-ingress-to-service.json (lines
9-14) and plugins/Kubernetes/v1/correlationRules/relate-service-to-pod.json
(lines 9-14) to add a second condition matching sourceProperty "namespace" to
targetProperty "namespace" in addition to the existing name-based condition.

Comment on lines +5 to +7
"tags": [
"Kubernetes"
],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Replace plugin-name tags with existing categories.

Kubernetes is the plugin name. It is not a reusable category.

  • plugins/Kubernetes/v1/dataStreams/daemonsets.json#L5-L7: replace Kubernetes with the applicable existing category.
  • plugins/Kubernetes/v1/dataStreams/deployments.json#L5-L7: replace Kubernetes with the applicable existing category.
  • plugins/Kubernetes/v1/dataStreams/events.json#L5-L7: replace Kubernetes with the applicable existing category.
  • plugins/Kubernetes/v1/dataStreams/ingresses.json#L5-L7: replace Kubernetes with the applicable existing category.
  • plugins/Kubernetes/v1/dataStreams/limitranges.json#L5-L7: replace Kubernetes with the applicable existing category.
  • plugins/Kubernetes/v1/dataStreams/namespaceContents.json#L5-L7: replace Kubernetes with the applicable existing category.
  • plugins/Kubernetes/v1/dataStreams/namespaces.json#L5-L7: replace Kubernetes with the applicable existing category.

As per coding guidelines, tags must reuse existing categories without using the plugin name.

📍 Affects 7 files
  • plugins/Kubernetes/v1/dataStreams/daemonsets.json#L5-L7 (this comment)
  • plugins/Kubernetes/v1/dataStreams/deployments.json#L5-L7
  • plugins/Kubernetes/v1/dataStreams/events.json#L5-L7
  • plugins/Kubernetes/v1/dataStreams/ingresses.json#L5-L7
  • plugins/Kubernetes/v1/dataStreams/limitranges.json#L5-L7
  • plugins/Kubernetes/v1/dataStreams/namespaceContents.json#L5-L7
  • plugins/Kubernetes/v1/dataStreams/namespaces.json#L5-L7
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/Kubernetes/v1/dataStreams/daemonsets.json` around lines 5 - 7,
Replace the plugin-name tag "Kubernetes" with the applicable existing reusable
category in the tags arrays for
plugins/Kubernetes/v1/dataStreams/daemonsets.json lines 5-7, deployments.json
lines 5-7, events.json lines 5-7, ingresses.json lines 5-7, limitranges.json
lines 5-7, namespaceContents.json lines 5-7, and namespaces.json lines 5-7;
preserve the existing tags structure and do not use the plugin name as a
category.

Source: Coding guidelines

Comment on lines +39 to +76
"name": "defaultCpuMillicores",
"displayName": "Default CPU Limit (m)",
"shape": "number"
},
{
"name": "defaultMemoryMi",
"displayName": "Default Memory Limit",
"shape": "megabytes"
},
{
"name": "defaultRequestCpuMillicores",
"displayName": "Default CPU Request (m)",
"shape": "number"
},
{
"name": "defaultRequestMemoryMi",
"displayName": "Default Memory Request",
"shape": "megabytes"
},
{
"name": "maxCpuMillicores",
"displayName": "Max CPU (m)",
"shape": "number"
},
{
"name": "maxMemoryMi",
"displayName": "Max Memory",
"shape": "megabytes"
},
{
"name": "minCpuMillicores",
"displayName": "Min CPU (m)",
"shape": "number"
},
{
"name": "minMemoryMi",
"displayName": "Min Memory",
"shape": "megabytes"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Use byte values and the bytes semantic shape for memory quantities.

These fields expose Mi-based values with megabytes shapes. This breaks the required byte-size contract and can produce inconsistent dashboard formatting.

  • plugins/Kubernetes/v1/dataStreams/limitranges.json#L39-L76: emit raw byte values, rename the ...Mi fields to byte-based names, and declare shape: "bytes".
  • plugins/Kubernetes/v1/dataStreams/namespaceContents.json#L254-L357: make the same contract change and update plugins/Kubernetes/v1/dataStreams/scripts/namespaceContents.js to emit bytes.

As per coding guidelines, return raw numeric values and use the bytes semantic shape for byte sizes.

📍 Affects 2 files
  • plugins/Kubernetes/v1/dataStreams/limitranges.json#L39-L76 (this comment)
  • plugins/Kubernetes/v1/dataStreams/namespaceContents.json#L254-L357
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/Kubernetes/v1/dataStreams/limitranges.json` around lines 39 - 76,
Update the limit-range fields defaultMemoryMi, defaultRequestMemoryMi,
maxMemoryMi, and minMemoryMi in
plugins/Kubernetes/v1/dataStreams/limitranges.json (lines 39-76) to byte-based
names, emit raw numeric byte values, and use shape "bytes". Apply the same field
renaming and bytes-shape contract in
plugins/Kubernetes/v1/dataStreams/namespaceContents.json (lines 254-357), and
update the namespaceContents script to emit byte values for those fields.

Source: Coding guidelines

"baseDataSourceName": "httpRequestScopedSingle",
"config": {
"httpMethod": "get",
"endpointPath": "{{ '/' + (detailType === 'ingresses' ? 'apis/networking.k8s.io/v1' : (detailType === 'deployments' || detailType === 'daemonsets' || detailType === 'statefulsets' || detailType === 'replicasets') ? 'apis/apps/v1' : 'api/v1') + '/namespaces/' + object.name + '/' + detailType }}",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use a map for resource-path selection.

The mustache expression duplicates detailType routing logic in one endpoint string. Use a map that assigns each supported detailType to its API-group path. This makes unsupported resource types explicit.

As per coding guidelines, prefer map transformations instead of mustache-style value expressions or complex script processing.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/Kubernetes/v1/dataStreams/namespaceContents.json` at line 11, Replace
the nested detailType ternary in endpointPath with a dedicated map that
explicitly associates each supported resource type with its API-group path,
including the core api/v1 fallback as appropriate. Update the endpoint
construction to look up the mapped path, making unsupported detailType values
explicit while preserving the existing namespace and resource suffixes.

Source: Coding guidelines

Comment on lines +92 to +93
- **Real control-plane health, no Prometheus required** — node health (readiness plus memory/disk/PID pressure and network availability), workload availability (deployments, daemon sets, stateful sets), and pod/container health (crash loops, image pull failures, OOM kills) read directly from the Kubernetes API's own status conditions.
- **Live CPU/memory usage** — current node and pod resource consumption via Kubernetes' standard Metrics API (`metrics-server`), plus each pod's configured requests/limits and each node's allocatable/total capacity (including ephemeral storage), for at-a-glance capacity headroom. This is a live snapshot, not a Prometheus-style history.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- README excerpt ---'
sed -n '1,150p' plugins/Kubernetes/v1/docs/README.md
printf '%s\n' '--- Kubernetes plugin files ---'
git ls-files plugins/Kubernetes/v1
printf '%s\n' '--- health-related symbols and API references ---'
rg -n -i 'control.?plane|api.?server|scheduler|controller.?manager|etcd|readiness|health|metrics|node|deployment|daemonset|statefulset|pod|container' plugins/Kubernetes/v1

Repository: squaredup/plugins

Length of output: 50375


🏁 Script executed:

#!/bin/bash
set -e
python3 - <<'PY'
import json
from pathlib import Path

root = Path("plugins/Kubernetes/v1")
print("--- JSON API paths and health-related fields ---")
for path in sorted(root.rglob("*.json")):
    try:
        text = path.read_text()
        data = json.loads(text)
    except Exception:
        continue
    if any(term in text.lower() for term in (
        "health", "condition", "readiness", "pressure",
        "api-server", "scheduler", "controller-manager", "etcd"
    )):
        print(f"\n{path}")
        for line_no, line in enumerate(text.splitlines(), 1):
            if any(term in line.lower() for term in (
                "health", "condition", "readiness", "pressure",
                "api-server", "scheduler", "controller-manager", "etcd"
            )):
                print(f"{line_no}: {line.strip()}")

print("\n--- JavaScript API calls and health-related fields ---")
for path in sorted(root.rglob("*.js")):
    text = path.read_text()
    relevant = [
        (n, line.strip()) for n, line in enumerate(text.splitlines(), 1)
        if any(term in line.lower() for term in (
            "fetch", "request", "/healthz", "/readyz", "/livez",
            "api-server", "scheduler", "controller-manager", "etcd",
            "condition", "health", "pressure"
        ))
    ]
    if relevant:
        print(f"\n{path}")
        for n, line in relevant:
            print(f"{n}: {line}")
PY
printf '%s\n' '--- data stream definitions for health-bearing streams ---'
for f in \
  plugins/Kubernetes/v1/dataStreams/nodes.json \
  plugins/Kubernetes/v1/dataStreams/deployments.json \
  plugins/Kubernetes/v1/dataStreams/daemonsets.json \
  plugins/Kubernetes/v1/dataStreams/statefulsets.json \
  plugins/Kubernetes/v1/dataStreams/pods.json \
  plugins/Kubernetes/v1/dataStreams/version.json
do
  echo "--- $f"
  cat -n "$f"
done

Repository: squaredup/plugins

Length of output: 24188


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- changed files ---'
git diff --name-only
printf '%s\n' '--- Kubernetes plugin metadata change ---'
git diff -- plugins/Kubernetes/v1/metadata.json
printf '%s\n' '--- README change summary ---'
git diff --stat -- plugins/Kubernetes/v1/docs/README.md

Repository: squaredup/plugins

Length of output: 249


Rename the control-plane health claim. The plugin reports node, workload, and pod/container health. Its /version request confirms API access but does not measure API server, scheduler, controller-manager, or etcd readiness. Rename this to “cluster and resource health,” or add documented control-plane readiness signals.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/Kubernetes/v1/docs/README.md` around lines 92 - 93, Update the README
feature description to rename “Real control-plane health” to “cluster and
resource health,” preserving the existing node, workload, and pod/container
health details. Do not claim API-server, scheduler, controller-manager, or etcd
readiness unless documented readiness signals are added.

| **ReplicaSet** | `GET /apis/apps/v1/replicasets` | A replica set (bridges deployments to the pods they own). |
| **DaemonSet** | `GET /apis/apps/v1/daemonsets` | A workload scheduled on every matching node. |
| **StatefulSet** | `GET /apis/apps/v1/statefulsets` | A workload with stable identity/storage per replica. |
| **Pod** | `GET /api/v1/pods` | A running pod. |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- candidate files ---'
git ls-files 'plugins/Kubernetes/v1/*' 'plugins/Kubernetes/v1/**/*' | sed -n '1,120p'
printf '%s\n' '--- README context ---'
sed -n '90,135p' plugins/Kubernetes/v1/docs/README.md
printf '%s\n' '--- Kubernetes plugin references ---'
rg -n -i 'pods?|status\.phase|Running|Succeeded|Failed|api/v1/pods' plugins/Kubernetes/v1
printf '%s\n' '--- metadata ---'
cat plugins/Kubernetes/v1/metadata.json

Repository: squaredup/plugins

Length of output: 34020


🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- Pod stream definition ---'
cat -n plugins/Kubernetes/v1/dataStreams/pods.json
printf '%s\n' '--- Pod transformation ---'
cat -n plugins/Kubernetes/v1/dataStreams/scripts/pods.js
printf '%s\n' '--- relevant diff summary ---'
git diff --stat -- plugins/Kubernetes/v1/docs/README.md plugins/Kubernetes/v1/metadata.json plugins/Kubernetes/v1/dataStreams/pods.json plugins/Kubernetes/v1/dataStreams/scripts/pods.js
printf '%s\n' '--- relevant diff ---'
git diff -- plugins/Kubernetes/v1/docs/README.md plugins/Kubernetes/v1/metadata.json plugins/Kubernetes/v1/dataStreams/pods.json plugins/Kubernetes/v1/dataStreams/scripts/pods.js
printf '%s\n' '--- read-only stream invariant probe ---'
python3 - <<'PY'
import json
from pathlib import Path

stream = json.loads(Path("plugins/Kubernetes/v1/dataStreams/pods.json").read_text())
script = Path("plugins/Kubernetes/v1/dataStreams/scripts/pods.js").read_text()

print("endpointPath:", stream.get("endpointPath"))
print("queryArgs:", stream.get("queryArgs"))
print("phase filter literals:", [
    phase for phase in ("Pending", "Running", "Succeeded", "Failed")
    if f'status.phase={phase}' in script or f'phase === "{phase}"' in script
])
print("phase field exported:", "phase:" in script)
print("has status.phase query:", "status.phase" in json.dumps(stream))
PY

Repository: squaredup/plugins

Length of output: 9091


Describe the indexed Pod population accurately.

The stream lists Pods from /api/v1/pods without a phase filter. Replace A running pod with A Kubernetes Pod, regardless of phase.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/Kubernetes/v1/docs/README.md` at line 118, Update the Pod row in the
Kubernetes API documentation table to describe the indexed population as a
Kubernetes Pod regardless of phase, replacing the inaccurate “A running pod”
wording while preserving the existing endpoint.

Comment on lines +132 to +133
- **Cluster-wide read RBAC required.** All imports are cluster-wide list calls (no per-namespace fan-out); a ServiceAccount restricted to specific namespaces won't work with this version.
- **No historical metrics.** Every data stream, including CPU/memory usage, is a current-state snapshot (`timeframes: false`) — there is no time-series history. Add a Prometheus-based plugin alongside this one if you need trends over time.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- README context ---'
sed -n '90,145p' plugins/Kubernetes/v1/docs/README.md
printf '%s\n' '--- plugin files ---'
git ls-files plugins/Kubernetes/v1 | sed -n '1,160p'
printf '%s\n' '--- Kubernetes source symbols and request paths ---'
rg -n --glob '!docs/README.md' 'timeframes|namespace|list|List|imports|streams|usage|ClusterRole|Role' plugins/Kubernetes/v1

Repository: squaredup/plugins

Length of output: 29560


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- plugin tree ---'
find plugins/Kubernetes/v1 -maxdepth 3 -type f -print | sort
printf '%s\n' '--- README relevant sections ---'
cat -n plugins/Kubernetes/v1/docs/README.md | sed -n '95,140p'
printf '%s\n' '--- source outlines where available ---'
for f in $(find plugins/Kubernetes/v1 -maxdepth 3 -type f \( -name '*.ts' -o -name '*.js' -o -name '*.json' \) -print); do
  echo "### $f"
  wc -l "$f"
done

Repository: squaredup/plugins

Length of output: 18119


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- README context ---'
cat -n plugins/Kubernetes/v1/docs/README.md | sed -n '95,140p'
printf '%s\n' '--- tracked files ---'
git ls-files plugins/Kubernetes/v1 | sort
printf '%s\n' '--- source references ---'
rg -n --glob '!docs/README.md' 'timeframes|namespace|list|List|imports|streams|usage|ClusterRole|Role' plugins/Kubernetes/v1

Repository: squaredup/plugins

Length of output: 28622


🏁 Script executed:

#!/bin/bash
set -e
cat -n plugins/Kubernetes/v1/docs/README.md | sed -n '95,140p'
rg -n --glob '!docs/README.md' 'timeframes|namespace|list|List|imports|streams|usage|ClusterRole|Role' plugins/Kubernetes/v1

Repository: squaredup/plugins

Length of output: 24918


🏁 Script executed:

#!/bin/bash
set -e
python3 - <<'PY'
import json
from pathlib import Path

root = Path("plugins/Kubernetes/v1/dataStreams")
for path in sorted(root.glob("*.json")):
    data = json.loads(path.read_text())
    endpoint = data.get("request", {}).get("endpointPath")
    print(f"{path.name}\t{endpoint!r}")
PY
printf '%s\n' '--- RBAC setup ---'
cat -n plugins/Kubernetes/v1/docs/README.md | sed -n '1,70p'

Repository: squaredup/plugins

Length of output: 4214


🏁 Script executed:

#!/bin/bash
set -e
python3 - <<'PY'
import json
from pathlib import Path

root = Path("plugins/Kubernetes/v1/dataStreams")
for path in sorted(root.glob("*.json")):
    data = json.loads(path.read_text())
    print(f"{path.name}\t{data.get('request', {}).get('endpointPath')!r}")
PY
cat -n plugins/Kubernetes/v1/docs/README.md | sed -n '1,70p'

Repository: squaredup/plugins

Length of output: 4195


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- endpoint definitions ---'
for f in plugins/Kubernetes/v1/dataStreams/*.json; do
  echo "### $f"
  sed -n '1,22p' "$f"
done

Repository: squaredup/plugins

Length of output: 12977


🏁 Script executed:

#!/bin/bash
set -e
for f in plugins/Kubernetes/v1/dataStreams/*.json; do
  echo "### $f"
  sed -n '1,22p' "$f"
done

Repository: squaredup/plugins

Length of output: 12948


Clarify the RBAC scope. State that unscoped object and metrics streams require cluster-wide list permissions. Namespace Contents, namespaced Pods by Parent, and Persistent Volume Claims use namespaced requests and require access in each target namespace.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/Kubernetes/v1/docs/README.md` around lines 132 - 133, Update the RBAC
documentation in the README to distinguish permission scopes: state that
unscoped object and metrics streams require cluster-wide list permissions, while
Namespace Contents, namespaced Pods by Parent, and Persistent Volume Claims use
namespaced requests and require access in every target namespace.

Comment on lines +3 to +10
"type": "url",
"name": "host",
"label": "API Server URL",
"help": "Full URL to your Kubernetes API server, including port. Example: https://192.168.1.100:6443",
"placeholder": "https://your-cluster-api-server:6443",
"validation": {
"required": true
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- plugin files ---'
git ls-files 'plugins/Kubernetes/v1/*' 'plugins/Kubernetes/*' | sort
printf '%s\n' '--- ui.json ---'
cat -n plugins/Kubernetes/v1/ui.json
printf '%s\n' '--- metadata.json relevant section ---'
sed -n '1,110p' plugins/Kubernetes/v1/metadata.json
printf '%s\n' '--- URL validation and Kubernetes host usage ---'
rg -n --glob '!node_modules' --glob '!dist' 'type.?[:=].?["'\'']url|validation.*https|baseUrl|ignoreCertificateErrors|Authorization|Bearer' .

Repository: squaredup/plugins

Length of output: 14860


🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- URL field examples and validation rules ---'
rg -n -C 8 '"type": "url"|"type":"url"|"validation"|"pattern"|"regex"|"protocol"' plugins --glob 'ui.json' --glob '*.json' | head -n 500
printf '%s\n' '--- repository schemas and documentation ---'
rg -n -i -C 5 'ui\.json|type.?url|URL field|https.*validation|validation.*url|ignoreCertificateErrors' . --glob '!node_modules' --glob '!dist' --glob '!build' | head -n 500
printf '%s\n' '--- comparable plugin configurations ---'
cat -n plugins/ProxmoxVE/v1/ui.json
cat -n plugins/ProxmoxVE/v1/metadata.json | sed -n '20,45p'
cat -n plugins/OpenSearch/v1/ui.json | sed -n '1,75p'
cat -n plugins/OpenSearch/v1/metadata.json | sed -n '20,40p'

Repository: squaredup/plugins

Length of output: 49486


🌐 Web query:

SquaredUp WebAPI plugin ui.json type url validation HTTPS scheme

💡 Result:

In the context of the SquaredUp WebAPI plugin and custom plugin development, URL validation and HTTPS enforcement are handled through specific mechanisms rather than a single field property in ui.json. 1. URL Scheme Validation: SquaredUp typically mandates HTTPS for secure communication with APIs [1][2]. When configuring Web API providers or tiles, the base URL is expected to be an HTTPS endpoint [1][2]. If you are developing a custom plugin, the ui.json file describes the configuration fields shown to the user [3], but standard URL scheme validation logic is usually enforced during the plugin's validation phase (using the SquaredUp CLI validate command) [3][4] or at runtime during provider configuration. 2. HTTPS and SSL Enforcement: The SquaredUp WebAPI plugin enforces secure connections [5]. If an endpoint uses a self-signed certificate or presents an invalid certificate, the system may return a "The remote certificate is invalid according to the validation procedure" error [5]. To resolve this for specific providers, you can toggle the "ignore invalid ssl" setting to ON within the provider's administration configuration in SquaredUp [5][6]. 3. Plugin Validation: If you are building a custom plugin, you should use the official SquaredUp CLI (squaredup validate) to test your configuration files, including ui.json and configValidation.json [3][7]. This process ensures that your plugin metadata and configuration schemas conform to the required standards before deployment [7][8][4]. For further details on constructing and validating your plugin configuration, refer to the official SquaredUp plugin developer resources on GitHub, which detail the expected structure of ui.json and the use of the validation tools [9][3].

Citations:


🏁 Script executed:

#!/bin/bash
set -eu
tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT
for url in \
  "https://raw.githubusercontent.com/squaredup/squaredup-plugin-public/main/README.md" \
  "https://raw.githubusercontent.com/squaredup/plugins/main/.github/workflows/pr-run.yaml" \
  "https://raw.githubusercontent.com/squaredup/plugins/main/.claude/skills/build-plugin/SKILL.md"
do
  file="$tmpdir/$(basename "$url")"
  curl -fsSL "$url" -o "$file" || true
  printf '\n--- %s ---\n' "$url"
  rg -n -i -C 4 'type.?url|https|scheme|protocol|validation|WebAPI|ignore.*ssl|certificate' "$file" || true
done

Repository: squaredup/plugins

Length of output: 14264


🏁 Script executed:

#!/bin/bash
set -eu
base="https://raw.githubusercontent.com/squaredup/plugins/main/.claude/skills/build-plugin/references"
for name in ui.md metadata.md common-patterns.md; do
  printf '\n--- %s ---\n' "$name"
  curl -fsSL "$base/$name" | rg -n -i -C 6 'url|https|scheme|protocol|pattern|validation|certificate|ignore' || true
done

Repository: squaredup/plugins

Length of output: 9978


Security Misconfiguration (CWE-319): Cleartext Transmission of Sensitive Information

Reachability: External

Reject non-HTTPS API server URLs.

host is copied to baseUrl, and metadata.json adds Authorization: Bearer {{token}} to every request. Add a validation.pattern such as ^https://[^\s]+$ and a test that rejects http:// before any request is sent.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/Kubernetes/v1/ui.json` around lines 3 - 10, Add a validation.pattern
to the host field in the Kubernetes UI configuration that accepts only
non-whitespace HTTPS URLs, such as ^https://[^\s]+$. Add or update validation
coverage to confirm an http:// host is rejected before any request is sent,
while preserving required-field validation.

Source: MCP tools

Comment on lines +23 to +27
"type": "checkbox",
"name": "ignoreCertificateErrors",
"label": "Ignore certificate errors",
"help": "Enable when connecting to a cluster with a self-signed API server certificate (e.g. a local kind/minikube cluster)."
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

# Map the Kubernetes plugin structure
find plugins/Kubernetes/v1 -type f | head -20

Repository: squaredup/plugins

Length of output: 1335


🏁 Script executed:

# Check the plugin metadata and structure
cat -n plugins/Kubernetes/v1/metadata.json

Repository: squaredup/plugins

Length of output: 2544


🏁 Script executed:

# Search for how ignoreCertificateErrors is used in the plugin code
rg "ignoreCertificateErrors" plugins/Kubernetes/v1/ -A 3 -B 3

Repository: squaredup/plugins

Length of output: 635


🏁 Script executed:

# Search for bearer token handling and WebAPI request construction
rg "bearer|token|Bearer" plugins/Kubernetes/v1/ -A 2 -B 2

Repository: squaredup/plugins

Length of output: 8300


🏁 Script executed:

# View the complete ui.json file
cat -n plugins/Kubernetes/v1/ui.json

Repository: squaredup/plugins

Length of output: 1297


🏁 Script executed:

# Check if there's any code or configuration that maps ui.json fields to WebAPI settings
rg "ignoreCertificateErrors|insecure|skipTLS|verifyTLS" plugins/Kubernetes/v1/ --type json -B 2 -A 2

Repository: squaredup/plugins

Length of output: 562


🏁 Script executed:

# Look at configValidation.json to see what happens on validation
cat -n plugins/Kubernetes/v1/configValidation.json

Repository: squaredup/plugins

Length of output: 743


🏁 Script executed:

# Search for any reference to ignoreCertificateErrors in all files, not just JSON
rg "ignoreCertificateErrors" plugins/Kubernetes/ --type-list

Repository: squaredup/plugins

Length of output: 6280


🏁 Script executed:

# Search in all Kubernetes plugin files for this setting
rg "ignoreCertificateErrors" plugins/Kubernetes/

Repository: squaredup/plugins

Length of output: 228


🏁 Script executed:

# Check if there's any mapping of ui.json fields to WebAPI config in scripts
find plugins/Kubernetes/v1 -type f \( -name "*.js" -o -name "*.ts" \) | head -20

Repository: squaredup/plugins

Length of output: 1222


🏁 Script executed:

# Look at WebAPI plugin documentation if available
rg "ignoreCertificateErrors|insecure|skipTLS" plugins/WebAPI/ -l | head -10

Repository: squaredup/plugins

Length of output: 258


🏁 Script executed:

# Search for references to WebAPI or base plugin configuration
rg "WebAPI|base.*plugin" plugins/Kubernetes/v1/ -A 2 -B 2

Repository: squaredup/plugins

Length of output: 1612


🏁 Script executed:

# Look for any scripts that might handle ignoreCertificateErrors or config transformation
rg "ignoreCertificateErrors|insecure|verify|certificate" plugins/Kubernetes/ -i

Repository: squaredup/plugins

Length of output: 1596


🏁 Script executed:

# Check the SquaredUp documentation URL mentioned in the error message
web_search
WebAPI plugin ignoreCertificateErrors bearer token security

Repository: squaredup/plugins

Length of output: 243


🌐 Web query:

SquaredUp WebAPI plugin ignoreCertificateErrors certificate validation

💡 Result:

In the SquaredUp Web API plugin, the option to bypass certificate validation is typically labeled as "ignore invalid ssl" or "ignore certificate errors" [1][2][3]. If you are encountering errors related to SSL/TLS trust (such as "The remote certificate is invalid" or "Could not establish trust relationship"), enabling this setting instructs the plugin to trust the connection despite certificate issues, such as those caused by self-signed certificates [1][2][4]. Configuration methods: 1. Graphical User Interface (GUI): Navigate to the Integrations section within your SquaredUp instance (often found under System > Integrations or System > Administration > Integrations) [2][4]. Select the specific Web API provider you are using, locate the toggle for "ignore invalid ssl," and set it to ON [2][3][4]. Save your changes [2][4]. 2. Configuration/Code: When defining providers programmatically (e.g., via Terraform or JSON configuration files), the field is commonly represented as "ignoreCertificateErrors" with a boolean value [5]. Setting this to true will disable certificate validation for that provider [5]. Always ensure that you are aware of the security implications of ignoring certificate errors, as it removes the verification that the server you are connecting to is trusted and genuine [1].

Citations:


🌐 Web query:

RFC 6750 bearer token TLS certificate validation requirements

💡 Result:

Under RFC 6750, clients are strictly required to validate the TLS certificate chain when making requests to protected resources [1][2]. This requirement is a mandatory security measure designed to protect against token disclosure and unauthorized access [1][3]. Specific requirements include: 1. Mandatory Validation: The client MUST validate the TLS certificate chain [1][2]. Failing to perform this validation can enable DNS hijacking and other man-in-the-middle attacks, potentially allowing an adversary to steal the bearer token and gain unauthorized access to protected resources [1][3][2]. 2. Certificate Revocation: The validation process must include checking the Certificate Revocation List (CRL) as defined in RFC 5280 [1][4]. 3. Server Identity: The client is required to verify the identity of the resource server, in accordance with the rules for HTTP over TLS [3]. 4. Transport Security: Clients must always use TLS (https) or equivalent transport security when using bearer tokens [1][2]. These requirements ensure that the communication channel is authenticated and secure, preventing the leakage of bearer tokens which serve as the primary security credential in this protocol [1][2].

Citations:


🌐 Web query:

WebAPI plugin SquaredUp configuration schema ignoreCertificateErrors

💡 Result:

In the SquaredUp Web API plugin, the configuration option to ignore certificate errors is labeled as "ignore invalid ssl" within the user interface [1][2][3][4]. When configuring a Web API provider, this appears as an on/off toggle switch used to permit connections when the target API uses self-signed certificates or has an invalid SSL/TLS certificate [1][2][5]. For users configuring the Web API via configuration files (such as when using Infrastructure as Code tools like Terraform), this property is referred to as "ignoreCertificateErrors" [6]. In a JSON-based configuration, it is defined as a boolean value: ignoreCertificateErrors = true (or false) [6] When encountering "An error occurred while sending the request" related to trust relationships for SSL/TLS, the recommended resolution is to navigate to System > Administration > Integrations, select the relevant Web API provider, and set "ignore invalid ssl" to ON [1][3].

Citations:


Security Misconfiguration (CWE-295): Improper Certificate Validation

Reachability: External

Bearer token is sent unconditionally when ignoreCertificateErrors is enabled, violating RFC 6750 requirements.

The Kubernetes plugin sends the bearer token in the Authorization header (defined in metadata.json) regardless of the ignoreCertificateErrors checkbox state. When a user enables this checkbox, the WebAPI base plugin disables TLS certificate validation. This combination allows a network attacker to intercept the connection, impersonate the API server, and capture the bearer token without detection. RFC 6750 explicitly requires TLS certificate chain validation before any bearer-token request; Section 2.1 states that clients MUST validate the certificate chain to prevent DNS hijacking and man-in-the-middle attacks that lead to token theft. The token grants cluster-wide read access.

Prevent token transmission when certificate validation is disabled. Options include:

  • Omit the bearer token from requests when ignoreCertificateErrors is true.
  • Support trusted CA certificate input as an alternative to disabling validation entirely.
  • If self-signed certificates must be supported, require an explicitly scoped, short-lived, or test-only token and document the risk prominently in the UI.
  • Verify all credential-bearing requests respect this setting.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/Kubernetes/v1/ui.json` around lines 23 - 27, Update the Kubernetes
plugin auth flow so bearer-token requests are not sent when
ignoreCertificateErrors is enabled. Use the ignoreCertificateErrors setting from
the UI config to gate any Authorization header creation in the Kubernetes
plugin’s request/metadata path, and ensure all credential-bearing calls respect
the same check. Keep the existing self-signed-certificate UX, but prevent token
transmission whenever TLS validation is disabled.

Source: MCP tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant