Skip to content
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

feat(helm): add ability for --dry-run to do lookup functions #9426

Merged
merged 14 commits into from
Jul 20, 2023

Conversation

tapaskapadia
Copy link
Contributor

When a helm command is run with the --dry-run flag, it will try to connect to the cluster
to be able to render lookup functions.
Closes #8137

Signed-off-by: Tapas Kapadia tapaskapadia10@gmail.com

What this PR does / why we need it: It is hard to debug the lookup function and currently there is not a good way to test it with any flags. #8137 Stated that the --dry-run was fair game to try to implement this logic as long as the helm template logic stays the same.

Special notes for your reviewer: This is my first PR for the Helm; please let me know if I need to add or change anything.

If applicable:

  • this PR contains documentation
  • this PR contains unit tests
  • this PR has been tested for backwards compatibility

@helm-bot helm-bot added the size/S Denotes a PR that changes 10-29 lines, ignoring generated files. label Feb 28, 2021
@tapaskapadia
Copy link
Contributor Author

tapaskapadia commented Feb 28, 2021

FYI, I believe this test is not testing what it states in the current master branch. I think it will pass regardless of the DryRun field being sent to "true" or "false". https://github.com/helm/helm/blob/master/pkg/action/install_test.go#L245

I have attached a document of a sample of the basic tests I ran. I did not see any good way to positively test a successful lookup without using a live cluster.

basicTests.txt

@DanielHabenicht
Copy link

Any updates on this? I would support if something is missing.

@iTaybb
Copy link

iTaybb commented May 9, 2021

I'm also looking forward for this, and wish to help if any help is needed.

@rickardp
Copy link

@tapaskapadia Can you fix the merge conflicts? Or if you let me, I'm happy to do so. I can help out with testing if needed.

// wishes and do not connect to the cluster.
if !dryRun && c.RESTClientGetter != nil {
// A `helm template` should not talk to the remote cluster. However, commands
// with `--dry-run` should be able to try to connect to the cluster.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is much more in line with user expectations, IMHO. Specifically, the sentence saying "when the user says to dry run, respect the user's wishes and do not connect to the cluster" is not in any way implied by naming convention or any best practices. Typically, dry run an operations means "do not mutate" not "do not read". Are there any documentation to update as well?

Copy link
Contributor Author

@tapaskapadia tapaskapadia Aug 24, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call on updating the documentation: https://helm.sh/docs/chart_template_guide/functions_and_pipelines/#using-the-lookup-function
This page does reference that helm install --dry-run is not supposed to contact the cluster.
If this is approved this page will also need to be changed: https://github.com/helm/helm-www/blob/2875cecd9b1b8b6290e9fee595e288807f033eb5/content/ko/docs/chart_template_guide/functions_and_pipelines.md (for all the languages)

@tapaskapadia
Copy link
Contributor Author

tapaskapadia commented Aug 24, 2021

@tapaskapadia Can you fix the merge conflicts? Or if you let me, I'm happy to do so. I can help out with testing if needed.

I'll rebase it to fix the merge conflicts. I may need a little help getting started if unit test cases are required as when I initially took at a stab at this it was not clear to me how to simulate having a real connection.

@mumoshu
Copy link
Contributor

mumoshu commented Jan 9, 2022

FWIW, helm-diff needs this, and I prefer this over changing helm template to have cluster access.

databus23/helm-diff#263

@joejulian
Copy link
Contributor

I would prefer we not do this in this fashion, but instead do what kubectl does with --dry-run=<server|client>. I think an interim change to just default to --dry-run=client if --dry-run is specified without qualification could be sufficient to keep it from being considered a breaking change, then go ahead and open up the flood gates on server connections with --dry-run=server.

Unfortunately, dry-run already broke the client-only contract. I'd still be against changing the comments to make it seem ok to do that further, especially if we're going to want to walk that back in helm 4.

@beekhof
Copy link

beekhof commented Jan 21, 2022

I found myself nodding furiously to this comment from @rickardp

Specifically, the sentence saying "when the user says to dry run, respect the user's wishes and do not connect to the cluster" is not in any way implied by naming convention or any best practices. Typically, dry run an operations means "do not mutate" not "do not read".

That this topic is raised over and over again is surely a sign that dry-run must imply a client-only contract is not what everyone wants, because it makes Helm less useful for some of us, and our lives harder.

@joejulian 's --dry-run=<server|client> suggestion seems pretty reasonable compromise.

  • Are there key folks that remain to be convinced before such an approach could be merged?
  • Is someone already working on it, or are we waiting for volunteers? (I'd be happy to do so).

@ksa-real
Copy link

ksa-real commented Feb 28, 2022

+1 on that one. I had to re-implement deployment scripts to do necessary lookups outside of helm upgrade --dry-run and then supply retrieved values via a temp file. My use of dry-run is to do a preflight check and helm diff with the already deployed release. At the moment not having lookup in -dry-mode generates too much noise and makes this mode too hard to use (without my enhancements).

@BrandonArp
Copy link

What is needed to get this merged? It looks like it has support from the community and, personally, I would really like to see it.

@v-sag
Copy link

v-sag commented Jun 7, 2022

Please support this.

@QuentinN42
Copy link

Any updates about the needed work to merge it ?
I have some time to pass some commits :)

@alexzhc
Copy link

alexzhc commented Sep 2, 2022

ugently needed 👍🏻

@jgreat
Copy link

jgreat commented Sep 2, 2022

Can I ask a question here? Would this feature be more likely to be approved and merged if it wasn't tied to the --dry-run flag?

I can't speak for everyone, but what I'm looking for is the ability to do a full test run with connections to the remote cluster so lookups work. These cluster connections would run under the user's approved/provisioned security context, so there doesn't seem to be a security problem or potential to expose something that the user doesn't already have access to via kubectl.

@QuentinN42
Copy link

QuentinN42 commented Sep 6, 2022

Looking at the k8s docs of the dry-run :

The request is still processed as typical request: the fields are defaulted, the object is validated, it goes through the validation admission chain, and through the mutating admission chain, and then the final object is returned to the user as it normally would, without being persisted.

So kubectl notion of dry-run is "I do all the stuff as normal, but at the last moment I do not apply changes".

I think helm upgrade with a --dry-run must do the same, lookups are executed, connection to the cluster is tested, and objects are validated through the k8s API.

If you want to NOT connect to the cluster, why not using helm template ?

@joejulian
Copy link
Contributor

joejulian commented Sep 19, 2022

Looking at kubectl help:

    --dry-run='none':
	Must be "none", "server", or "client". If client strategy, only print the object that
	would be sent, without sending it. If server strategy, submit server-side request without
	persisting the resource.

If you don't specify, it suggests "client" which has always been the default:

W0919 10:06:16.181516 1786127 helpers.go:639] --dry-run is deprecated and can be replaced with --dry-run=client.

I'm suggesting helm would do the same.

@codablock
Copy link

+1 for this as I'm using the template functionality of Helm to integrate Helm into kluctl. I'm however not calling Helm binaries but instead use Helm as a go dependency and configure an install action so that it uses DryRun=true.

I'd like to ask that whatever the final solution will be to allow lookup+dryRun, that this is also possible when Helm is used as a library and not only when it is used as a binary.

codablock added a commit to kluctl/kluctl that referenced this pull request Sep 26, 2022
This is a preparation to allow lookup in Helm charts. It will however not
work before helm/helm#9426 or a comparable
solution is merged.
@mikeshng
Copy link
Contributor

+1 on this PR or any other PRs that can enhance the dry-run capability to perform lookup.

@QuentinN42
Copy link

@rickardp what is needed to merge this ?
@tapaskapadia are you still working on this ?

If needed I can help by creating a new MR with all this changes on the last version of helm:main.

@gjenkins8
Copy link
Member

I second @joejulian said about --dry-run='none'|'client'|'server'. The PR here (as it stands) is a change in behavior.

Currently helm install --dry-run=true does not contact the cluster, and to the point of the security advisory/model (GHSA-q8q8-93cv-v6h8), I think would be a breaking change for some users (ie. they could suddenly get secrets printed and logged in a CI system; see e.g. #7275)

I put a proposal on the main issue (rather than this implementation PR here

@sandipchitale
Copy link

sandipchitale commented Dec 30, 2022

What about Capabilities.APIVersions and Capabilities.KubeVersion? Will this also work once lookup will work when correct flag is passed?

@mattfarina mattfarina requested a review from joejulian July 6, 2023 16:37
@crenshaw-dev
Copy link

@mattfarina is your review stale / should be dismissed?

Comment on lines +145 to +147
if client.DryRunOption == "" {
client.DryRunOption = "none"
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is unreachable code. With NoOptDefVal being set you shouldn't run into a value of "" here.

@dudicoco
Copy link

@tapaskapadia thank you for this important contribution!

@pwillis-eiq
Copy link

pwillis-eiq commented Jul 25, 2023

Thank you @tapaskapadia, @rickardp, @joejulian, @QuentinN42, @mattfarina, and everyone else who helped push this through!

This feature change took 2 years, 4 months and 20 days to merge! But it was finally completed - by a bunch of strangers on the internet, all working together, with no monetary incentive, contractual agreement, or under any hierarchical organization chart. Because of all this, a bunch of other strangers will now benefit - whether it's supporting a business, helping customers, just getting their day jobs done, or working on the tools they care about. Open Source lifts all boats ❤️ ⛵ ❤️

MichaelMorrisEst added a commit to Nordix/helm-diff that referenced this pull request Jul 25, 2023
Helm PR helm/helm#9426 enables support for executing lookups during dry run. This PR is to make use of this new support in helm-diff.
Backwards compatibility for older versions of helm is maintained by checking the helm version before setting the flag

Addresses issue: databus23#449

Signed-off-by: MichaelMorris <michael.morris@est.tech>
mumoshu pushed a commit to databus23/helm-diff that referenced this pull request Aug 21, 2023
Helm PR helm/helm#9426 enables support for executing lookups during dry run. This PR is to make use of this new support in helm-diff.
Backwards compatibility for older versions of helm is maintained by checking the helm version before setting the flag

Addresses issue: #449

Signed-off-by: MichaelMorris <michael.morris@est.tech>
yxxhero pushed a commit to helm/helm-www that referenced this pull request Dec 14, 2023
Change lookup's description to reflect change on helm/helm#9426

Signed-off-by: Kerry Gougeon <kerrygougeon@gmail.com>
gjenkins8 pushed a commit to gjenkins8/helm-www that referenced this pull request Jan 19, 2024
Change lookup's description to reflect change on helm/helm#9426

Signed-off-by: Kerry Gougeon <kerrygougeon@gmail.com>
EronWright added a commit to pulumi/pulumi-kubernetes that referenced this pull request Jun 4, 2024
<!--Thanks for your contribution. See [CONTRIBUTING](CONTRIBUTING.md)
    for Pulumi's contribution guidelines.

    Help us merge your changes more quickly by adding more details such
    as labels, milestones, and reviewers.-->

### Proposed changes

<!--Give us a brief description of what you've done and what it solves.
-->

This PR fixes a problem with how Chart v4 uses the Helm library. The
design goal is to allow for connectivity during template rendering, to
support the lookup function (see helm/helm#9426)
and to provide an accurate [Capabilities
object](https://helm.sh/docs/chart_template_guide/builtin_objects/).
Unfortunately we were slightly too aggressive and caused some of Helm's
"non-template" code to execute.

This fix works by turning off the `helm template --validation` flag, so
that the internal `ClientOnly` flag is true thus avoiding [this block of
code](https://github.com/helm/helm/blob/6f32a8f9d338bacc3c6a1c0c3610012b01edb3d1/pkg/action/install.go#L345-L350)
that causes the unexpected error. A side-effect of `ClientOnly` being
true is that the capabilities aren't automatically set, and so we set
them using the provider's kube client (akin to using `--kube-version`).

Detailed changes:
- (chart.go) use ClientOnly mode, set KubeVersion and APIVersions
- (tool.go) remove redundant KubeVersion and ExtraAPIs 
- (testdata/reference) add a version check
- (chart_test.go) unit tests for `.Capabilities`
- integration test to install cert-manager

### Related issues (optional)

<!--Refer to related PRs or issues: #1234, or 'Fixes #1234' or 'Closes
#1234'.
Or link to full URLs to issues or pull requests in other GitHub
repositories. -->
Closes #3045
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
size/M Denotes a PR that changes 30-99 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unable to debug "lookup" function, as its disabled with helm template