-
Notifications
You must be signed in to change notification settings - Fork 234
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for Options.HelmValuesOptions #146
base: main
Are you sure you want to change the base?
Conversation
@@ -80,10 +82,9 @@ func (l *lintContextImpl) renderHelmChart(dir string) (map[string]string, error) | |||
if err := chrt.Validate(); err != nil { | |||
return nil, err | |||
} | |||
valOpts := &values.Options{ValueFiles: []string{filepath.Join(dir, "values.yaml")}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code isn't necessary since the Helm parser already uses the default values.yaml
within the chart when it executes the render.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice.
58ffbd1
to
9ca1456
Compare
@@ -80,10 +82,9 @@ func (l *lintContextImpl) renderHelmChart(dir string) (map[string]string, error) | |||
if err := chrt.Validate(); err != nil { | |||
return nil, err | |||
} | |||
valOpts := &values.Options{ValueFiles: []string{filepath.Join(dir, "values.yaml")}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice.
pkg/lintcontext/create_contexts.go
Outdated
|
||
// HelmValuesOptions provide options for additional values.yamls that can be provided to Helm on loading a chart | ||
// These will be ignored for contexts that are not Helm-based | ||
HelmValuesOptions values.Options |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, one piece of complexity here is that CreateContexts
can potentially create multiple Helm contexts by crawling directories, whereas HelmValuesOptions
would be different for each Helm chart. What are your thoughts here? How are you using this function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah you are right. I was only using CreateContexts to create a single context, not multiple.
IMO, we should have lintContextImpl
continue to take in a single values.Options and update the exported lintcontext.Options
to have HelmValuesOptions []values.Options
.
Then, on CreateContexts
, we assert that len(filesOrDirs) == len(options.HelmValuesOptions)
or return an error.
Does this sound good to you? I can perform this change on rebasing this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is that CreateContexts
is recursive, so len(filesOrDirs) == len(options.HelmValuesOptions)
is not a sufficient condition. Plus, I prefer to avoid parallel arrays anyway.
Long term, in the context of someone running kube-linter lint
, I would like to move to a model where the user stores these options as code, along with their Helm chart, and KubeLinter reads them and users them. (See #49.) I also want users to be able to specify multiple values.Options
for a single Helm chart, too, because it would be useful for a user to lint their Helm chart against multiple different settings of values.
For library usage (which is the immediate use-case here), my suggestion is as follows: create a separate function that takes in one directory as input, which must contain a single Helm chart (if not, it returns an error), and then renders it. This function can take in a new Options
argument, which includes an array of HelmValuesOptions
, and also embeds the Options
you created in #144 in it (so that people can use that to pass customDecoders
). The function then returns a list of LintContexts
, one for each HelmValuesOption
passed in (or, if no HelmValuesOption
was passed in, it uses the default values.yaml and returns exactly one LintContext). We can avoid duplication by calling this function inside the isHelm
branch of CreateContexts
. This seems like it will be compatible with the changes we want to make down the road.
Does this make sense to you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is that CreateContexts is recursive, so len(filesOrDirs) == len(options.HelmValuesOptions) is not a sufficient condition. Plus, I prefer to avoid parallel arrays anyway.
I see your point. I didn't realize that CreateContexts was recursive till you just mentioned it 😅 but that makes sense.
For library usage (which is the immediate use-case here), my suggestion is as follows: create a separate function that takes in one directory as input, which must contain a single Helm chart (if not, it returns an error), and then renders it.
Sounds good to me! This was how I was using it anyways, so this would be perfect for my solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Long term, in the context of someone running kube-linter lint, I would like to move to a model where the user stores these options as code, along with their Helm chart, and KubeLinter reads them and users them. (See #49.) I also want users to be able to specify multiple values.Options for a single Helm chart, too, because it would be useful for a user to lint their Helm chart against multiple different settings of values.
This is incredibly similar to what I've been working on FYI. If you are interested in taking a peek behind the curtain, here is my code:
https://github.com/aiyengar2/charts-testing/tree/0dade8345626cd045fa9359e9018e20bebe0899a/testing
TLDR of the design:
- You define a testSuite, which replaces the Register code you use for registering templates / checks so that they can be dynamically provided by the user
- You then parse templates into the testSuite, where you also have the ability to set a custom scheme if you are using CRDs in your templates
- You then add a Test (e.g.
testBuilder
), specifying the templates it applies on (All|Include|Exclude
), subsets of resources you want to parse within those templates (On|OnFilter|OnMatcher
), and any function that satisfies the reflection-based requirements for a DoFunc - Finally, you call Run or RunWithContext (if you want to pass params to a DoFunc)
https://github.com/aiyengar2/charts-testing/tree/0dade8345626cd045fa9359e9018e20bebe0899a/tests/common contains some examples of DoFuncs that can be written using this framework (only involves writing a struct and then writing the function based on that struct)
https://github.com/aiyengar2/charts-testing/tree/0dade8345626cd045fa9359e9018e20bebe0899a/tests/template/tests contains example code that uses this framework. main_test.go
and example_*_test.go
might be interesting to you.
For repository-specific template configurations:
- While parsing in templates, I make sure that it's only a single Helm chart
- I add each Helm chart + values.yamls pair as a separate template here
w.r.t. the existing code in kube-linter, you could translate each template generically into a DoFunc based struct + function and convert all your built-in tests into Tests within a single testSuite.
I haven't quite figured out how to upstream it yet, but will do when I get a chance!
Also please don't hold me on the "public" facing API signatures just yet since it's not ready yet 😄 ... will need to move it into another repository before it's ready to be consumed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ooh this is pretty cool. Definitely looking forward to seeing where this ends up, and learning from it to figure out what makes sense for us to do in this repo (ie, to enable this functionality completely via options to the CLI).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Can you rebase on main
? I can merge after that.
Hi @aiyengar2, just wanted to check in on this. Will you be able to rebase and merge this one? |
c9c732c
to
e90231d
Compare
Allows users to provide options for creating lint context. Related Issue: stackrox#141 Signed-off-by: Arvind Iyengar <[email protected]>
e90231d
to
53e3415
Compare
Any chance for merging this PR? |
What's the status of this? |
This will allow consumers of this package to provide non-default Helm values.yamls to lint against.
Note:: First commit comes from #144, which will need to be merged in before this is merged. Alternatively, I can add this commit to that PR and drop this instead.
Related Issue: #145