kube-score icon indicating copy to clipboard operation
kube-score copied to clipboard

Recursively traverse a directory containing Kubernetes YAML files

Open jawnsy opened this issue 3 years ago • 6 comments

Currently, kube-score emits an error if passing a directory name ti the score function:

[coder@jawnsy-m enterprise-helm]$ kube-score score build
Failed to score files: read build: is a directory[coder@jawnsy-m enterprise-helm]$ 

(Sidenote: this also seems to be missing a trailing newline)

By contrast, kube-linter recursively traverses the directory and lints everything, emitting the filenames and errors for each, which is extremely convenient in a CI pipeline:

coder@jawnsy-m enterprise-helm]$ kube-linter lint build
build/kind/coder/templates/cemanager.yaml: (object: coder-jawnsy-m/cemanager apps/v1, Kind=Deployment) container "cemanager" does not have a read-only root file system (check: no-read-only-root-fs, remediation: Set readOnlyRootFilesystem to true in your container's securityContext.)

build/kind/coder/templates/dashboard.yaml: (object: coder-jawnsy-m/dashboard apps/v1, Kind=Deployment) container "dashboard" does not have a read-only root file system (check: no-read-only-root-fs, remediation: Set readOnlyRootFilesystem to true in your container's securityContext.)

build/kind/coder/templates/dashboard.yaml: (object: coder-jawnsy-m/dashboard apps/v1, Kind=Deployment) container "dashboard" has cpu request 0 (check: unset-cpu-requirements, remediation: Set your container's CPU requests and limits depending on its requirements. See https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limits for more details.)

build/kind/coder/templates/envproxy.yaml: (object: coder-jawnsy-m/envproxy apps/v1, Kind=Deployment) container "envproxy" does not have a read-only root file system (check: no-read-only-root-fs, remediation: Set readOnlyRootFilesystem to true in your container's securityContext.)

build/kind/coder/templates/envproxy.yaml: (object: coder-jawnsy-m/envproxy apps/v1, Kind=Deployment) container "envproxy" has cpu request 0 (check: unset-cpu-requirements, remediation: Set your container's CPU requests and limits depending on its requirements. See https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limits for more details.)

I'd love to contribute a feature like this to kube-score, but will need some guidance on how to do so :smile:

jawnsy avatar Mar 08 '21 03:03 jawnsy

Hey,

you can utilise your shells filename expansion features and achieve this with kube-score score build/*. Generally I don't think that kube-score should incorporate features that other tools can do, so I'm a bit torn about this.

On the other hand, I'd be happy to accept a PR to fix the newline bug: https://github.com/zegl/kube-score/blob/ac55fb01452f9302941a5383ca7354ab711fb32c/cmd/kube-score/main.go#L37

zegl avatar Mar 08 '21 08:03 zegl

I can certainly appreciate the desire to lean on shell features (Unix philosophy and all that) and keep the code as simple as possible. Yet, I also think there's value to making the small UX improvement.

A limitation of using helm template and piping into kube-score or even using the shell globbing is that (a) they're slightly more work; and (b) they do not show affected filenames. Users can certainly write a small script or rely on xargs to do this, but if the long-term maintenance costs aren't significant, then I think first-class support would be better

I'll open a PR to fix the newline issue, thanks for the pointer!

jawnsy avatar Mar 08 '21 16:03 jawnsy

and (b) they do not show affected filenames

They do! In the default output format kube-score doesn't display the file paths (the json and serif formats do), but the support for tracking the filenames is there, even if the data comes from templated helm.

Here's some examples from the testdata:

$ helm template score/testdata/helm/app1 | kube-score score - --output-format json | jq '.[].file_name'
"app1/templates/deployment.yaml"
"app1/templates/deployment.yaml"
$ kube-score score score/testdata/ingress-* --output-format json | jq '.[].file_name'
"/Users/gustav/src/kube-score/score/testdata/ingress-v1-invalid-backend.yaml"
"/Users/gustav/src/kube-score/score/testdata/ingress-targets-service.yaml"
"/Users/gustav/src/kube-score/score/testdata/ingress-networkingv1-targets-service.yaml"
"/Users/gustav/src/kube-score/score/testdata/ingress-networkingv1beta1-targets-service.yaml"
"/Users/gustav/src/kube-score/score/testdata/ingress-targets-service.yaml"

Users can certainly write a small script or rely on xargs to do this, but if the long-term maintenance costs aren't significant, then I think first-class support would be better

This might very well be true, but it's still hard to get right. Should symlinks be followed? Should non .yaml or .yml files automatically be ignored? Etc.

zegl avatar Mar 08 '21 17:03 zegl

But how would that work with nested folders? When I generate templates with helmfile these end up in nested file structures.

Morriz avatar May 13 '21 13:05 Morriz

@Morriz - I managed to use the following for nested folders: $ kube-score score $(find <path> -type f -print)

@zegl - I really like this tool, but agree that it would be much easier if kube-score supported this functionality natively. Also note that the default docker image is build on scratch and doesn't include a shell, so I needed to use the helm3 variant unfortunately.

day1118 avatar Oct 18 '21 02:10 day1118

When I pass all the files to kube-score using find then finding where the object is located is difficult in human output format (working with helm charts that have complex dependent charts). And it is a human who reads it, so making it json format is not desired. When I print the file name and then run kube-score file-by-file then I would get a bunch of errors about missing "network policies" etc (obviously).

I think it would be helpful to print the file name when kube-score was executed with more than 1 file as the input. As demonstrated earlier, the program already has the information when using "json" output. Perhaps this should be a separate issue? Since this issue is about recursive path traversing and it can easely be solved with find or xargs example.

I have created a fork that does something like this, I am not sure if it is PR worthy though since I did not write tests for it but the current tests do still pass: https://github.com/martivo/kube-score/commit/913eee636e6f0d04bae932493eb642875b1e61d8

The best part of it is that it also works when passing a "helm template ." through stdin.

martivo avatar Jul 20 '23 07:07 martivo