feat(kubernetes): add Kubernetes workload tree representation - #72
Merged
Conversation
Add an explicit Kubernetes provider to the resource tree, mirroring the provider -> service -> resource shape used by the cloud providers: - provider: kubernetes - service: Kubernetes API group (apps, batch) - resource: workload kind (Deployment, StatefulSet, DaemonSet, ReplicaSet, Job, CronJob) Workloads share a single workload.Workload type (annotations + per- container sizing); kinds with extra cost-relevant fields embed it and add their own (replicas; completions/parallelism; schedule). Labels are stored on the base resource's Tags. CPU/memory are stored in millicores and bytes — the exact base units a Kubernetes quantity reduces to. The reflective proto serializer now flattens anonymous embedded structs into the parent's attributes, so embedding a shared base produces the same flat wire message as declaring the fields inline. Also adds the PROVIDER_KUBERNETES mapping (proto v1.150.0).
liamg
approved these changes
Jun 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds an explicit Kubernetes workload representation to the resource tree — the first step of the Kubernetes workload parser work. There is no Kubernetes grouping in the tree today; this defines the tree shape every later step (parser plugin, provider plugin) depends on.
It mirrors the existing
provider -> service -> resourceshape:kubernetesapps,batch)deployment,statefulset,daemonset,replicaset,job,cronjob)Each workload carries per-container sizing (CPU in millicores, memory in bytes — the exact base units a Kubernetes quantity reduces to, so there's no GiB-vs-GB ambiguity), annotations, and labels (stored on the base resource's
Tags). Kinds with extra cost-relevant fields embed a sharedworkload.Workloadand add their own (replicas;completions/parallelism;schedule).Also adds the
PROVIDER_KUBERNETESenum mapping (protov1.150.0).We deliberately do not know the full set of fields yet. The exact metadata and sizing fields needed to compute costs will only become clear as we build the parser and provider plugins against real manifests/charts. We're merging this now to unblock that development — it gives both plugins a concrete tree to build against, and discovering the unknowns is the point. Expect follow-up changes to the workload fields.
Flattening of anonymous embedded structs
To let kinds compose (
Deploymentembedsworkload.Workloadand addsReplicas;CronJobembedsJobembedsWorkload), the reflective proto serializer (convert.go) now flattens anonymous embedded structs into the parent's attributes on both the read and write sides.resource.Resourcekeeps its existing dedicated handling; everything else embedded is inlined — which is simply Go's own embedding semantics applied to serialization.Why this is forward- and backward-compatible: the embedded struct's fields are written into the same flat raw proto fields as if they'd been declared inline — there is no nesting introduced by the embedding. So the embedding is purely a Go-side organisational choice with no wire-format footprint. You could later promote the embedded
Workloadinto a flat list of individual fields on each kind (or the reverse), and the message sent over the wire would be byte-for-byte identical. The Go composition can be refactored freely without breaking any consumer already decoding the proto.Testing
pkg/tree/kubernetes_test.go— round-trips a Deployment, DaemonSet and CronJob throughToProto/FromProto, asserting base fields, embedded-base fields and kind-specific fields all survive at one flat level (including the multi-levelCronJob -> Job -> Workload).gofmt/go vetclean.