Not every project needs a grand plan. These three came out of specific problems I ran into — some in my homelab, some during my day job as a Platform Architect — and each one just solves that problem and stops. A lot of AI assistance went into all three, they’re shipped as-is with no roadmap for continuous development, and I’m fully open to contributions if someone finds them useful and wants to take them further. I’ll keep contributing myself whenever I have time or hit a need for a new feature.

node-providerid

node-providerid is a Go CLI that reads or changes a Kubernetes Node’s spec.providerID directly through the etcd v3 API, targeting embedded etcd on a k3s server by default.

providerID links a Node object to its machine in the cloud provider, and Kubernetes treats it as immutable once set — the API server rejects any attempt to change a non-empty value, and it can’t be cleared through kubectl edit or kubectl patch. In practice it still ends up wrong sometimes: a Node registered before the cloud provider was configured, a migration between providers, or a bad --provider-id baked in at first boot. The usual fix is to drain, delete and re-register the Node. When that isn’t practical, the only place left to correct the value is the datastore itself — which is exactly what this tool does, as narrowly as possible: it patches only the providerID field, guards the write with an etcd compare-and-swap on the Node’s revision, and writes a per-key backup first.

Worth saying plainly: set writes directly to your cluster’s backing store and bypasses every Kubernetes safety layer — schema validation, admission control, authorization, the lot. get is read-only and safe; set is a deliberate, last-resort operation, and the README says so at length before you get anywhere near running it.

burrow

burrow exposes a TCP service running outside a Kubernetes cluster to workloads running inside it, without opening inbound firewall ports or configuring static routes.

The client runs wherever the service actually lives — laptop, edge node, private server — and dials outbound to a WebSocket endpoint on a server component running inside the cluster. Because the client always initiates the connection, it works through NAT, firewalls and most corporate networks. Traffic from pods reaches the local service through that persistent tunnel; the server can optionally manage a Kubernetes Service object per connected client, so pods reach tunnelled services by a stable DNS name rather than tracking ports by hand. It’s the kind of thing that’s handy for reaching a homelab machine from an in-cluster job, or bridging a service that will never itself run in Kubernetes.

alertmanager-label-enricher

alertmanager-label-enricher is an inline proxy that sits between Prometheus and Alertmanager and enriches alert labels from external lookups — Kubernetes objects, HTTP endpoints, or a static file — before forwarding alerts on.

Prometheus’s own alert_relabel_configs already covers static and conditional label rewriting, but nothing for a lookup against something external — for example, adding a team label read off the Kubernetes object for the alert’s namespace, or off a CMDB via HTTP. Because enrichment happens before Alertmanager sees the alert, the new labels participate fully in routing, grouping, inhibition and silences, exactly like any label Prometheus set itself.

Rules run in declared order, all matching rules apply, and later rules see labels earlier ones added. Overwriting or dropping an existing label changes the alert’s fingerprint in Alertmanager — which can invalidate existing silences — so both require an explicit opt-in, while annotations (no fingerprint risk) don’t. alertname gets extra protection since it’s Alertmanager’s primary identifying label. A rule can be marked required, failing the whole batch closed so Prometheus retries if its lookup fails; everything else fails open rather than block delivery.


None of these three are trying to be a platform or a product — they each fix one specific thing that was in my way. If one of them is in your way too, they’re on GitHub and I’ll happily look at a PR.