Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile.cbm
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,7 @@ PIPELINE_SRCS = \
src/pipeline/pass_compile_commands.c \
src/pipeline/pass_infrascan.c \
src/pipeline/pass_k8s.c \
src/pipeline/helm_template.c \
src/pipeline/pass_operator.c \
src/pipeline/pass_shell.c \
src/pipeline/pass_terraform.c \
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ The install script placed beside the binary is **reported, not deleted**: uninst
- `INFRA_MAPS`: a Kubernetes Service to each workload whose pod labels carry every `key: value` of the Service's selector, within one namespace
- `CONNECTS_TO`: a Kubernetes workload or compose service to the Service its containers' environment addresses (`PRODUCT_CATALOG_SERVICE_ADDR: productcatalogservice:3550`, a URL's host, `<svc>.<ns>.svc...`, a bare name on an `*_ADDR` / `*_HOST` / `*_URL` / ... key; compose: the project's `.env` interpolated): a Kubernetes Service of the same bundle and namespace, or a compose service of the same file. The edge keeps `via: env`, `key` and `container`, never the value
- `USAGE` with `ref: image`: a Kubernetes workload (any pod template: containers, initContainers, CronJobs, custom resources) or a docker compose service to the `Image` it runs
- Helm templates are rendered for their images: with the chart's values (the `Chart` `DEPLOYS` them, `default_of`: the values keys read) and with each release's (a Flux HelmRelease, a kustomize `helmCharts` entry, a Terraform `helm_release`: `override_of`). An image the render cannot know is left out, never guessed: after a change of values it does not run exactly, a `tpl` or include it cannot look into, a release value it cannot read, or a work budget it runs past. Known limit: each template file renders on its own, while Helm renders a chart's files with one shared `.Values` (a subchart's is its parent's `.Values.<alias>`), so a chart that changes `.Values` in one file and reads it in another can still show a wrong image
- `DEPLOYS`: what puts manifests, kustomizations or charts on a cluster, to what it puts there: a Flux Kustomization or Argo Application to the kustomizations / manifests / chart of its path, a Flux HelmRelease to its chart (`spec.chart` or `chartRef` → OCIRepository), a shell command or Make recipe (`kubectl apply -f/-k`, `kustomize build | kubectl apply`, `helm install/upgrade/template`), a Go installer loading a chart with the Helm SDK, a Terraform `helm_release`, a Terraform `kubernetes_*` resource the object it declares (a `Resource` like a manifest's, `ecosystem: terraform`, when its name is a literal), a kustomization inflating a chart (`helmCharts`; its values file an `IMPORTS`). A chart outside the repository is an external `Chart`, keyed by its publisher when its repository URL is stated (`__chart__<repository>/<name>`, the same node in every project, the URL in `repository`), else one per project and name; the edge says `via` (`flux`, `argo`, `helmrelease`, `kubectl`, `kustomize`, `helm`, `helm-sdk`, `terraform`, `helmcharts`, ...)
- `DEPENDS_ON`: a Helm chart to the charts it declares (the local chart for a resolvable `file://` repository, otherwise an external `Chart`; the edge keeps `repository`), and a `go.mod` / `requirements.txt` file to an external `Package`; a Dockerfile to the `Image`s it builds on (`via: from`, `copy-from`); an `Image` to the Dockerfile it is built from (`via: build`; `tool`: `skaffold`, `compose`, `docker-build` for `docker` / `podman` / `nerdctl` / `buildah` build commands in scripts, Make and CI); a compose service to the services its `depends_on` / `links` name
- `CONFIGURES`: code reading an environment variable to the shared `EnvVar` of that name (`strategy: env_access`); a Kubernetes container, compose service or Dockerfile (`ENV` of the image) setting one to that container's own `EnvVar` (`strategy: env_set`, with `source`: `value`, `configMapKeyRef`, `secretKeyRef`, `fieldRef`, ..., `compose`, `dockerfile`; values are never stored); and that container's `EnvVar` to the code reading the name inside the files its image is built from (`strategy: env_read`, with `dockerfile`): the image's files are the sources its Dockerfile's `COPY` / `ADD` put into it, less the context's `.dockerignore`
Expand Down
6 changes: 5 additions & 1 deletion internal/cbm/cbm.h
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,9 @@ typedef struct {
* from the URL `name`; a HelmRelease whose chartRef names it deploys the
* chart there.
* CBM_K8S_FACT_IMAGE: object def_index runs its container `container`
* (NULL: unnamed) from image `name` (a literal reference); via "container".
* (NULL: unnamed) from image `name` (a literal reference, or a Helm
* template's placeholder `<...>`, which names none); via "container";
* `line` the image's line, start_line / end_line the container's.
* CBM_K8S_FACT_ENV: object def_index sets environment variable `name` in
* its container `container` (NULL: unnamed) at `line`; via = where the
* value comes from ("value", or the valueFrom kind) -- never the value.
Expand Down Expand Up @@ -758,6 +760,8 @@ typedef struct {
const char *url; /* DEPLOY (kustomize): the chart repository */
const char *release; /* DEPLOY (kustomize): the release name */
int line;
int start_line; /* IMAGE: the container mapping's first line */
int end_line; /* IMAGE: its last line */
} CBMK8sFact;

typedef struct {
Expand Down
10 changes: 8 additions & 2 deletions internal/cbm/extract_k8s.c
Original file line number Diff line number Diff line change
Expand Up @@ -1487,12 +1487,18 @@ static void k8s_container(k8s_walk_t *w, const char *path, TSNode container) {
const char *cname = k8s_text(w, container, "name");
cname = cname && cname[0] && !strstr(cname, "{{") ? cname : NULL;
const char *image = k8s_text(w, container, "image");
if (k8s_image_literal(image)) {
/* a Helm template's image is its skeleton placeholder: pass_k8s.c renders it */
if (k8s_image_literal(image) || (image && strchr(image, '<'))) {
TSNode iv = k8s_child(w, container, "image");
CBMK8sFact f = {.fact = CBM_K8S_FACT_IMAGE,
.def_index = w->def_index,
.name = image,
.container = cname,
.via = "container"};
.via = "container",
.line =
ts_node_is_null(iv) ? 0 : (int)ts_node_start_point(iv).row + SKIP_ONE,
.start_line = (int)ts_node_start_point(container).row + SKIP_ONE,
.end_line = (int)ts_node_end_point(container).row + SKIP_ONE};
cbm_k8sfact_push(&w->ctx->result->k8s_facts, w->ctx->arena, f);
}
k8s_iter_t env = k8s_iter(k8s_child(w, container, "env"));
Expand Down
Loading
Loading