zegl / kube-score

Kubernetes object analysis with recommendations for improved reliability and security. kube-score actively prevents downtime and bugs in your Kubernetes YAML and Charts. Static code analysis for Kubernetes.
https://kube-score.com
MIT License
2.8k stars 179 forks source link

Use kube-score as library #419

Open prskr opened 2 years ago

prskr commented 2 years ago

First of all: kube-score is an awesome project! Thanks for all your efforts!

I would like to use kube-score more in a library/'framework' way as part of an internal project to provide best practice reports to our Kubernetes teams.

Therefore some additional features would come in handy:

  1. the current Score function only takes a configuration struct. To be able to use kube-score as library it would be nice to be able to pass the *checks.Checks as parameter to be able to add custom checks that only apply to our environment.
  2. rather a mid/long-range feature: support for arbitrary CRDs would allow us/everyone to add custom checks for CRDs like Cilium, Prometheus, Velero,... or even their own. To support this I think an architecture change how the data is collected and passed to the checks could be necessary but it would probably also make it easier to extend kube-score in the future.

I'd have a rough idea how to achieve all this but I figured it would be better to first ask you what you think, is this something you'd be interested in? Shall I just create a PR(s) and we discuss further details directly in these?

zegl commented 2 years ago

Hey @baez90, thanks for your nice words!

Yes! I definitely think that it makes sense to improve the API to make kube-score easier to use by other projects. ​

I think that I've seen kube-score used as a library a few times actually, or at least wrapped in one way or another. I'll do some searching to see if I can find the project again, to see how they used it / what it was used for. It might be good input for the API design.

I have no clear ideas yet for what the API could look like, but it sounds like you do. 😄

Let's collaborate on the API either here in the issue or in PRs if that's easier for you.

Totally agree on the point of extensibility for custom CRDs or custom checks for built in objects too, but I agree that it’s more of a long term thing. We can start improving the API for embedding first.

prskr commented 2 years ago

I think I sense some enthusiasm here and I'm very glad to hear that! :smile:

The only think I had to change was this which allows me to pass new checks defined out of tree already.

Apart from that I'm actually already done with the integration and I'm already generating reports based on your impressive rule set :blush:

The biggest...problem I encountered was that I had to re-implement all your interfaces like Podspecer,... because I'm using our Kubernetes clusters as source-of-truth and therefore it didn't really make sense to use your parser because from what I saw in the code I would have had to marshal all objects to pass them as Configuration.AllFiles to your parser again :sweat_smile: I decided to typedef the Kubernetes types to new types and implemented the required interfaces for these types along with a custom implementation of your AllTypes interface.

And that is actually where I 'feel' the hardest limitation...I was wondering why not e.g. using the controller-runtime's fake client to store all either parsed or retrieved objects and pass this fake client (probably as Reader) to all checks? Of course extra effort would be necessary to track file positions of certain objects but at least it would be very flexible and it would be possible to register custom schemes e.g. to support CRDs.

Spontaneous idea for keeping the file relations:

type FileSourcedPod struct {
   *corev1.Pod
   ks.FileLocationer
}

That way you could still use a *FileSourcedPod as a client.Object but you also could get the original file location for later printing and for live pods there is just no file location?

I'm thinking about how to...open up the API a bit already for quite some time but I'm not yet sure what might be the best approach...for instance with this approach there's no easy way to migrate the meta checks. But probably an exception for this very special kind of checks wouldn't be that hard?

Any ideas? What do you think about the fake client approach?