Kubernetes - #107
Conversation
🧩 Plugin PR Summary📦 Modified Plugins
📋 Results
🔍 Validation Details✅
|
📝 WalkthroughWalkthroughAdds a complete Kubernetes plugin with API authentication, resource data streams, normalized metrics and health data, object relationships, indexed resources, dashboards, scopes, and setup documentation. ChangesKubernetes plugin foundation
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
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
Comment |
There was a problem hiding this comment.
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
⛔ Files ignored due to path filters (1)
plugins/Kubernetes/v1/icon.svgis excluded by!**/*.svg
📒 Files selected for processing (64)
plugins/Kubernetes/v1/configValidation.jsonplugins/Kubernetes/v1/correlationRules/relate-daemonset-to-pod.jsonplugins/Kubernetes/v1/correlationRules/relate-deployment-to-replicaset.jsonplugins/Kubernetes/v1/correlationRules/relate-ingress-to-service.jsonplugins/Kubernetes/v1/correlationRules/relate-namespace-to-objects.jsonplugins/Kubernetes/v1/correlationRules/relate-node-to-pod.jsonplugins/Kubernetes/v1/correlationRules/relate-replicaset-to-pod.jsonplugins/Kubernetes/v1/correlationRules/relate-service-to-pod.jsonplugins/Kubernetes/v1/correlationRules/relate-statefulset-to-pod.jsonplugins/Kubernetes/v1/custom_types.jsonplugins/Kubernetes/v1/dataStreams/daemonsets.jsonplugins/Kubernetes/v1/dataStreams/deployments.jsonplugins/Kubernetes/v1/dataStreams/events.jsonplugins/Kubernetes/v1/dataStreams/ingresses.jsonplugins/Kubernetes/v1/dataStreams/limitranges.jsonplugins/Kubernetes/v1/dataStreams/namespaceContents.jsonplugins/Kubernetes/v1/dataStreams/namespaces.jsonplugins/Kubernetes/v1/dataStreams/nodeMetrics.jsonplugins/Kubernetes/v1/dataStreams/nodes.jsonplugins/Kubernetes/v1/dataStreams/persistentvolumes.jsonplugins/Kubernetes/v1/dataStreams/podMetrics.jsonplugins/Kubernetes/v1/dataStreams/pods.jsonplugins/Kubernetes/v1/dataStreams/podsByParent.jsonplugins/Kubernetes/v1/dataStreams/pvClaims.jsonplugins/Kubernetes/v1/dataStreams/replicasets.jsonplugins/Kubernetes/v1/dataStreams/resourcequotas.jsonplugins/Kubernetes/v1/dataStreams/scripts/daemonsets.jsplugins/Kubernetes/v1/dataStreams/scripts/deployments.jsplugins/Kubernetes/v1/dataStreams/scripts/events.jsplugins/Kubernetes/v1/dataStreams/scripts/ingresses.jsplugins/Kubernetes/v1/dataStreams/scripts/limitranges.jsplugins/Kubernetes/v1/dataStreams/scripts/namespaceContents.jsplugins/Kubernetes/v1/dataStreams/scripts/namespaces.jsplugins/Kubernetes/v1/dataStreams/scripts/nodeMetrics.jsplugins/Kubernetes/v1/dataStreams/scripts/nodes.jsplugins/Kubernetes/v1/dataStreams/scripts/persistentvolumes.jsplugins/Kubernetes/v1/dataStreams/scripts/podMetrics.jsplugins/Kubernetes/v1/dataStreams/scripts/pods.jsplugins/Kubernetes/v1/dataStreams/scripts/podsByParent.jsplugins/Kubernetes/v1/dataStreams/scripts/pvClaims.jsplugins/Kubernetes/v1/dataStreams/scripts/replicasets.jsplugins/Kubernetes/v1/dataStreams/scripts/resourcequotas.jsplugins/Kubernetes/v1/dataStreams/scripts/services.jsplugins/Kubernetes/v1/dataStreams/scripts/statefulsets.jsplugins/Kubernetes/v1/dataStreams/scripts/version.jsplugins/Kubernetes/v1/dataStreams/services.jsonplugins/Kubernetes/v1/dataStreams/statefulsets.jsonplugins/Kubernetes/v1/dataStreams/version.jsonplugins/Kubernetes/v1/defaultContent/Perspectives/daemonset.dash.jsonplugins/Kubernetes/v1/defaultContent/Perspectives/deployment.dash.jsonplugins/Kubernetes/v1/defaultContent/Perspectives/ingress.dash.jsonplugins/Kubernetes/v1/defaultContent/Perspectives/manifest.jsonplugins/Kubernetes/v1/defaultContent/Perspectives/namespace.dash.jsonplugins/Kubernetes/v1/defaultContent/Perspectives/node.dash.jsonplugins/Kubernetes/v1/defaultContent/Perspectives/persistentvolume.dash.jsonplugins/Kubernetes/v1/defaultContent/Perspectives/pod.dash.jsonplugins/Kubernetes/v1/defaultContent/Perspectives/service.dash.jsonplugins/Kubernetes/v1/defaultContent/Perspectives/statefulset.dash.jsonplugins/Kubernetes/v1/defaultContent/manifest.jsonplugins/Kubernetes/v1/defaultContent/scopes.jsonplugins/Kubernetes/v1/docs/README.mdplugins/Kubernetes/v1/indexDefinitions/default.jsonplugins/Kubernetes/v1/metadata.jsonplugins/Kubernetes/v1/ui.json
| "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." |
There was a problem hiding this comment.
🎯 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"
doneRepository: 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}")
PYRepository: 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:
- 1: https://kubernetes.io/docs/reference/access-authn-authz/authentication/
- 2: https://k8s-security.guru/kubernetes-security/best-practices/cluster-setup-and-hardening/api-server-security/anonymous-api-access/
- 3: https://raesene.github.io/blog/2023/03/18/lets-talk-about-anonymous-access-to-Kubernetes/
- 4: https://kubernetes.io/docs/reference/access-authn-authz/kubelet-authn-authz/
- 5: https://kubernetes.io/docs/reference/access-authn-authz/rbac/
- 6: https://docs.cloud.google.com/kubernetes-engine/docs/how-to/role-based-access-control
- 7: https://stackoverflow.com/questions/62070263/kubernetes-systemdiscovery-role-mechanism
- 8: https://kubernetes.ltd/docs/reference/access-authn-authz/authentication/
- 9: https://codemia.io/knowledge-hub/path/forbidden_user_cannot_get_path__not_anonymous_user
- 10: https://kubernetes.io/docs/reference/kubernetes-api/definitions/non-resource-attributes-v1-authorization/
🏁 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"))
PYRepository: 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
| "conditions": [ | ||
| { | ||
| "sourceProperty": "primaryBackendServiceName", | ||
| "operator": "equals", | ||
| "targetProperty": "name" | ||
| } |
There was a problem hiding this comment.
🗄️ 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: AddsourceProperty: "namespace"andtargetProperty: "namespace"as a second condition.plugins/Kubernetes/v1/correlationRules/relate-service-to-pod.json#L9-L14: AddsourceProperty: "namespace"andtargetProperty: "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.
| "tags": [ | ||
| "Kubernetes" | ||
| ], |
There was a problem hiding this comment.
📐 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: replaceKuberneteswith the applicable existing category.plugins/Kubernetes/v1/dataStreams/deployments.json#L5-L7: replaceKuberneteswith the applicable existing category.plugins/Kubernetes/v1/dataStreams/events.json#L5-L7: replaceKuberneteswith the applicable existing category.plugins/Kubernetes/v1/dataStreams/ingresses.json#L5-L7: replaceKuberneteswith the applicable existing category.plugins/Kubernetes/v1/dataStreams/limitranges.json#L5-L7: replaceKuberneteswith the applicable existing category.plugins/Kubernetes/v1/dataStreams/namespaceContents.json#L5-L7: replaceKuberneteswith the applicable existing category.plugins/Kubernetes/v1/dataStreams/namespaces.json#L5-L7: replaceKuberneteswith 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-L7plugins/Kubernetes/v1/dataStreams/events.json#L5-L7plugins/Kubernetes/v1/dataStreams/ingresses.json#L5-L7plugins/Kubernetes/v1/dataStreams/limitranges.json#L5-L7plugins/Kubernetes/v1/dataStreams/namespaceContents.json#L5-L7plugins/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
| "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" |
There was a problem hiding this comment.
🗄️ 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...Mifields to byte-based names, and declareshape: "bytes".plugins/Kubernetes/v1/dataStreams/namespaceContents.json#L254-L357: make the same contract change and updateplugins/Kubernetes/v1/dataStreams/scripts/namespaceContents.jsto 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 }}", |
There was a problem hiding this comment.
📐 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
| - **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. |
There was a problem hiding this comment.
🎯 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/v1Repository: 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"
doneRepository: 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.mdRepository: 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. | |
There was a problem hiding this comment.
🎯 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.jsonRepository: 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))
PYRepository: 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.
| - **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. |
There was a problem hiding this comment.
🎯 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/v1Repository: 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"
doneRepository: 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/v1Repository: 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/v1Repository: 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"
doneRepository: 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"
doneRepository: 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.
| "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 | ||
| } |
There was a problem hiding this comment.
🔒 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:
- 1: https://docs.squaredup.com/data-sources/web-api-plugin/data-stream-parameters
- 2: https://docs.squaredup.com/dashboard-tutorials/using-the-web-api-plugin/how-to-configure-a-web-api-tile
- 3: https://github.com/squaredup/squaredup-plugin-public
- 4: https://github.com/squaredup/plugins/blob/ae90aac86862aa2ddf885b4b09ababd97ffe93d4/.github/workflows/pr-run.yaml
- 5: https://scomsupport.squaredup.com/troubleshooting/dashboards/web-api-an-error-occurred-while-sending-the-request
- 6: https://scomsupport.squaredup.com/dashboarding/integrations/-web-api-provider
- 7: build-plugin: deploy-early, test-as-you-build flow #72
- 8: Add Notion plugin #74
- 9: https://github.com/squaredup/plugins/blob/main/.claude/skills/build-plugin/SKILL.md
🏁 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
doneRepository: 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
doneRepository: 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
| "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)." | ||
| } |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
# Map the Kubernetes plugin structure
find plugins/Kubernetes/v1 -type f | head -20Repository: squaredup/plugins
Length of output: 1335
🏁 Script executed:
# Check the plugin metadata and structure
cat -n plugins/Kubernetes/v1/metadata.jsonRepository: 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 3Repository: 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 2Repository: squaredup/plugins
Length of output: 8300
🏁 Script executed:
# View the complete ui.json file
cat -n plugins/Kubernetes/v1/ui.jsonRepository: 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 2Repository: squaredup/plugins
Length of output: 562
🏁 Script executed:
# Look at configValidation.json to see what happens on validation
cat -n plugins/Kubernetes/v1/configValidation.jsonRepository: 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-listRepository: 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 -20Repository: squaredup/plugins
Length of output: 1222
🏁 Script executed:
# Look at WebAPI plugin documentation if available
rg "ignoreCertificateErrors|insecure|skipTLS" plugins/WebAPI/ -l | head -10Repository: 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 2Repository: 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/ -iRepository: 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 securityRepository: 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:
- 1: https://docs.squaredup.com/data-sources/web-api-plugin
- 2: https://communitysupport.squaredup.com/troubleshooting/dashboards/web-api-an-error-occurred-while-sending-the-request
- 3: https://scomsupport.squaredup.com/dashboarding/integrations/-web-api-provider
- 4: https://scomsupport.squaredup.com/troubleshooting/dashboards
- 5: https://community.squaredup.com/t/terraform-data-source-config-json-examples/2441
🌐 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:
- 1: https://www.rfc-editor.org/rfc/rfc6750.html
- 2: https://www.ietf.org/rfc/rfc6750
- 3: https://www.rfc-editor.org/rfc/rfc6750.txt
- 4: https://datatracker.ietf.org/doc/html/rfc6750.html
🌐 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:
- 1: https://scomsupport.squaredup.com/troubleshooting/dashboards/web-api-an-error-occurred-while-sending-the-request
- 2: https://azuresupport.squaredup.com/dashboarding/integrations/-web-api-provider
- 3: https://communitysupport.squaredup.com/troubleshooting/dashboards/web-api-an-error-occurred-while-sending-the-request
- 4: https://scomsupport.squaredup.com/dashboarding/integrations/-web-api-provider
- 5: https://communitysupport.squaredup.com/dashboarding/integrations/-web-api-provider
- 6: https://community.squaredup.com/t/terraform-data-source-config-json-examples/2441
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
ignoreCertificateErrorsis 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
🔌 Plugin overview
🖼️ Plugin screenshots
Plugin configuration
Default dashboards
🧪 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.
metrics-server(with--kubelet-insecure-tlsfor the local cluster's self-signed kubelet certs) and verified live CPU/memory usage tiles on Node and Pod perspectivesobjectsUI filter, reducing the stream count while keeping the same dashboard behaviormetrics-serverin the cluster (standard lightweight Kubernetes Metrics API, not Prometheus) — usage tiles show no data without it, rest of the plugin unaffectedapp/app.kubernetes.io/name/k8s-app), not full subset matching📚 Checklist
Summary by CodeRabbit
New Features
Documentation