Closed rhollins closed 6 years ago
There is no way to access files outside of a chart. This is by design, since Tiller is the thing that renders the template, and Tiller won't have access to your filesystem.
So currently you need to copy the files into the chart before deploying the chart.
Thanks for confirmation.
Its 2020. Helm 3 doesnt care about tiller. Can we now reach files outside of chart folder with Files.Glob
?
We're discussing a new feature to copy files into the chart before deploying with #3276, but @technosophos's argument still holds true: a chart should not be granted access to files it does not own. Introducing the concept of globbing files outside the chart's contents allows malicious chart authors to fetch files from another user's system and ship them elsewhere using an execution hook.
I filled an issue about getting the files from chart folder : https://github.com/helm/helm/issues/9420
This a dubious argument. A malicious chart author can also facilitate deployment of resources that could hijack one's entire cluster. Meanwhile, well-meaning users are locked out of a useful feature.
This a dubious argument. A malicious chart author can also facilitate deployment of resources that could hijack one's entire cluster. Meanwhile, well-meaning users are locked out of a useful feature.
I agree with that, but in the same time I user could still screwed up the cluster by overriding params. I think at this point the poweruser know what it's doing.
I don't want to create a custom chart only to override the default values in a chart. There are so many duplicate chart only to have a partial fix here and there.
I did create a PR on a community chart to fix a issue and it was closed before it was merge. At the end I had to duplicate the chart and apply the fix in my chart and publish it in github and now that chart is used by others too and we have 2 charts instead of one.
Thanks to this comment, I can now confirm this limitation can be bypassed entirely with simply creating a symbolic link inside the chart directory pointing to the required file. Hopefully this is helpful to anyone who wants to proceed with importing arbitrary files in their CI workflow.
If the maintainers have a security concern with this, I advise to simply exclude symlinks that lead outside the chart directory from chart packaging - that way those of us who want to have them in our infrastructure repositories can still have them or have the CI generate them, but the alleged malefactors are out of luck.
Interresting. Does that works on Windows too?
Le mer. 3 mars 2021 11 h 00, VengefulAncient notifications@github.com a écrit :
Thanks to this comment https://github.com/helm/helm/issues/3276#issuecomment-769229963, I can now confirm this limitation can be bypassed entirely with simply creating a symbolic link for the required file. Hopefully this is helpful to anyone who wants to proceed with importing arbitrary files in their CI workflow.
If the maintainers have a security concern with this, I advise to simply exclude symlinks that lead outside the chart from chart packaging - that way those of us who want to have them in our infrastructure repositories can still have them or have the CI generate them, but the alleged malefactors are out of luck.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/helm/helm/issues/4026#issuecomment-789821639, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABO3B76YETC2G3GZRY2AODTBZMJVANCNFSM4E7CIBHQ .
Interresting. Does that works on Windows too?
Windows 10 has symbolic link support, and not too long ago Go introduced support for symbolic links on Windows, so I don't see why not.
https://blogs.windows.com/windowsdeveloper/2016/12/02/symlinks-windows-10/
FYI, we're aware of these use cases and are discussing how to move forward in #3276. There are a number of pull requests open that are looking to implement this functionality - #8841 is the latest iteration.
If you have any further feedback, please feel free to comment in #3276, and provide any feedback you have when testing out #8841. We're trying to keep the topic condensed in one ticket. That way we can minimize the number of similar conversations occurring in parallel (case in point - this exact conversation 😄).
oh. thanks, I'll try that.
@bacongobbler little question. I'm looking at the merge : https://github.com/helm/helm/pull/8840 it talked about --include-file and --include-dir
I don't see it in the help output. Are they released ?
PS C:\windows\system32> helm version version.BuildInfo{Version:"v3.5.2", GitCommit:"167aac70832d3a384f65f9745335e9fb40169dc2", GitTreeState:"dirty", GoVersion:"go1.15.7"}
PS C:\windows\system32> helm install --help
This command installs a chart archive.
The install argument must be a chart reference, a path to a packaged chart,
a path to an unpacked chart directory or a URL.
To override values in a chart, use either the '--values' flag and pass in a file
or use the '--set' flag and pass configuration from the command line, to force
a string value use '--set-string'. In case a value is large and therefore
you want not to use neither '--values' nor '--set', use '--set-file' to read the
single large value from file.
$ helm install -f myvalues.yaml myredis ./redis
or
$ helm install --set name=prod myredis ./redis
or
$ helm install --set-string long_int=1234567890 myredis ./redis
or
$ helm install --set-file my_script=dothings.sh myredis ./redis
You can specify the '--values'/'-f' flag multiple times. The priority will be given to the
last (right-most) file specified. For example, if both myvalues.yaml and override.yaml
contained a key called 'Test', the value set in override.yaml would take precedence:
$ helm install -f myvalues.yaml -f override.yaml myredis ./redis
You can specify the '--set' flag multiple times. The priority will be given to the
last (right-most) set specified. For example, if both 'bar' and 'newbar' values are
set for a key called 'foo', the 'newbar' value would take precedence:
$ helm install --set foo=bar --set foo=newbar myredis ./redis
To check the generated manifests of a release without installing the chart,
the '--debug' and '--dry-run' flags can be combined.
If --verify is set, the chart MUST have a provenance file, and the provenance
file MUST pass all verification steps.
There are five different ways you can express the chart you want to install:
1. By chart reference: helm install mymaria example/mariadb
2. By path to a packaged chart: helm install mynginx ./nginx-1.2.3.tgz
3. By path to an unpacked chart directory: helm install mynginx ./nginx
4. By absolute URL: helm install mynginx https://example.com/charts/nginx-1.2.3.tgz
5. By chart reference and repo url: helm install --repo https://example.com/charts/ mynginx nginx
CHART REFERENCES
A chart reference is a convenient way of referencing a chart in a chart repository.
When you use a chart reference with a repo prefix ('example/mariadb'), Helm will look in the local
configuration for a chart repository named 'example', and will then look for a
chart in that repository whose name is 'mariadb'. It will install the latest stable version of that chart
until you specify '--devel' flag to also include development version (alpha, beta, and release candidate releases), or
supply a version number with the '--version' flag.
To see the list of chart repositories, use 'helm repo list'. To search for
charts in a repository, use 'helm search'.
Usage:
helm install [NAME] [CHART] [flags]
Flags:
--atomic if set, the installation process deletes the installation on failure. The --wait flag will be set automatically if --atomic is used
--ca-file string verify certificates of HTTPS-enabled servers using this CA bundle
--cert-file string identify HTTPS client using this SSL certificate file
--create-namespace create the release namespace if not present
--dependency-update run helm dependency update before installing the chart
--description string add a custom description
--devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored
--disable-openapi-validation if set, the installation process will not validate rendered templates against the Kubernetes OpenAPI Schema
--dry-run simulate an install
-g, --generate-name generate the name (and omit the NAME parameter)
-h, --help help for install
--insecure-skip-tls-verify skip tls certificate checks for the chart download
--key-file string identify HTTPS client using this SSL key file
--keyring string location of public keys used for verification (default "C:\\Users\\sd003526\\.gnupg\\pubring.gpg")
--name-template string specify template used to name the release
--no-hooks prevent hooks from running during install
-o, --output format prints the output in the specified format. Allowed values: table, json, yaml (default table)
--password string chart repository password where to locate the requested chart
--post-renderer postrenderer the path to an executable to be used for post rendering. If it exists in $PATH, the binary will be used, otherwise it will try to look for the executable at the given path (default exec)
--render-subchart-notes if set, render subchart notes along with the parent
--replace re-use the given name, only if that name is a deleted release which remains in the history. This is unsafe in production
--repo string chart repository url where to locate the requested chart
--set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
--set-file stringArray set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
--set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
--skip-crds if set, no CRDs will be installed. By default, CRDs are installed if not already present
--timeout duration time to wait for any individual Kubernetes operation (like Jobs for hooks) (default 5m0s)
--username string chart repository username where to locate the requested chart
-f, --values strings specify values in a YAML file or a URL (can specify multiple)
--verify verify the package before using it
--version string specify the exact chart version to use. If this is not specified, the latest version is used
--wait if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment, StatefulSet, or ReplicaSet are in a ready state before marking the release as successful. It will wait for as long as --timeout
--wait-for-jobs if set and --wait enabled, will wait until all Jobs have been completed before marking the release as successful. It will wait for as long as --timeout
Global Flags:
--debug enable verbose output
--kube-apiserver string the address and the port for the Kubernetes API server
--kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--kube-as-user string username to impersonate for the operation
--kube-ca-file string the certificate authority file for the Kubernetes API server connection
--kube-context string name of the kubeconfig context to use
--kube-token string bearer token used for authentication
--kubeconfig string path to the kubeconfig file
-n, --namespace string namespace scope for this request
--registry-config string path to the registry config file (default "C:\\Users\\sd003526\\AppData\\Roaming\\helm\\registry.json")
--repository-cache string path to the file containing cached repository indexes (default "C:\\Users\\sd003526\\AppData\\Local\\Temp\\helm\\repository")
--repository-config string path to the file containing repository names and URLs (default "C:\\Users\\sd003526\\AppData\\Roaming\\helm\\repositories.yaml")
PS C:\windows\system32>
@survivant
and for the record symlink idea is terrible in a production system as the symlink has to exist ahead of time (although this is less of an issue) and is fixed/bound to a immutable location.
At the very least it is a very inconvenient workaround.
Best would be to make the --include-dir
change in #8841
Of course the symlink is not a solution. It's a workaround, which happens to be perfectly suitable for us, since all we want is to let Helm pull in a file from the project's actual repository (one level above its Helm chart directory) to render some templates based on the contents of that file.
--include-dir
/--include-file
should obviously still go ahead to remove the need for such hacks, but personally I struggle to imagine a situation in which a CI can't create the required symlink right before deployment, or the symlink can't simply be saved in the chart's directory alongside templates and values. It's a workaround people can actually use, right now, without waiting for months it will probably take to discuss all sorts of theoretical issues the PR could cause, merge it, release it, and have it propagate to Helm plugins for popular CI systems (and that's assuming someone won't come up with a new excuse to not merge it - judging by this very thread, that's there the focus is, and not on adding requested functionality). An imperfect solution is better than none at all.
I wanted to get access to files like composer.json/package.json which is one level up from helm chart folder in the app file structure to exctact app version from it, but I end up with the idea that I am already using this version in pipelines and basically can populate it using pipeline scripts via helm values instead of making it from inside helm charts. It looks like workaround for initial issue, but as other said, it might be more proper way to keep helm charts clean and secure (isolated) but use other tools (CI/CD pipeline scripts) to pass any extra artifacts into it.
This worked for me (the base64 is for transport into the template as silly punctuation will cause a bad day) For Linux:
helm upgrade --install <chart-stuff> --set myFile=$(cat some-file/on/the-system | base64 -w 0 -)
temp.yaml contnents ...
data:
myFileName: |
{{ range (.Values.myFile | b64dec) | toStrings }}
{{ . | nindent 8 }}
{{ end }}
This worked for me (the base64 is for transport into the template as silly punctuation will cause a bad day) For Linux:
helm upgrade --install <chart-stuff> --set myFile=$(cat some-file/on/the-system | base64 -w 0 -)
temp.yaml contnents ...
data: myFileName: | {{ range (.Values.myFile | b64dec) | toStrings }} {{ . | nindent 8 }} {{ end }}
This worked like a charm, thank you! For anyone reading this, as @trash-80 mentioned, base64
is necessary for getting this to work. Even if your file is unencrypted (e.g. just a configmap or something) take care to still perform | base64 -w 0 -
on the cat
operation
I (somewhat) understand the argument against Helm trying to read an arbitrary file name by a full path, although I don't generally appreciate my tools trying to assume that I am dumb and trying to prevent me from shooting in my foot so hard that they stab me in the back in the process. This general trend of dummification of everything is sickening.
But what's wrong with Helm allowing to read a file in the current working directory? This is beyond my understanding. I just want to do something like:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "configmap-helm-chart.fullname" . }}
data:
{{- $files := .Files -}}
{{- range $keyName, $data := .Values.configMap }}
{{ $keyName }}: |-
{{- $data.content | nindent 4 }}
{{- end }}
And then be able to run this with (cd examples/basic && helm template ../.. -f ./values.yaml)
. A process reading files from the current working directory surely is not an unthinkable sin, is it?
10,000% agree with the above comment. Engineers should be responsible for vetting their tools. We at the very least need an install-time flag allowing access to cwd
or pwd
or a discrete /some/path
- this is immediately and obviously useful for applications where multiple files that should not be included in the chart itself need to be mounted via ConfigMap
into a Pod
's filesystem.
For instance - an email sending service reliant on Pug templates. The service is designed to read templates from /var/templates
and can be shipped super lightweight / flexibly without actually committing those templates into the source code. They can simply be mounted at runtime.
Right now, I have to build an entire Helm chart for each specific iteration of this imaginary service to inject custom Pug files. Or, alternatively, build separate docker images for every single possible variation where this service might be used.
In this example a simple feature / install-time flag could let me use one chart to mount whatever Pug templates you wanted. Hell, even Docker natively lets you mount local volumes into a container with --volume /my/local/dir:/var/someMountedDir
which is sort of .... the point of a container
I'm doing monorepo GitOps with Helm and ArgoCD among others, and would love to have the possibility to reach files outside the chart directory, without symlink hacks.
Maybe introduce an off-by-default setting as a compromise?
Still would have been amazing to get this feature in 2024.
--include-dir
seems like a great compromise, where developers can force certain folders to be included in helm, but it would take an extra step for an external attacker to convince a developer to run their tool.
Maybe you could even call it --unsafe-include-dir
and have a 10 second timeout where tool raises a pretty scary warning if you want to be extra safe.
For now I am doing the following workaround
helm install --namespace=local local-deployment ./local-deployment --set migrationsAsBase64Zip=$(zip -9 -q -r - "$(pwd)/../db/migrations" | base64)
@bacongobbler - As @survivant mentioned here, I too dont see --include-dir or --include-file options in helm upgrade commands. Can you help here ?
I'm looking at the merge : https://github.com/helm/helm/pull/8840 it talked about --include-file and --include-dir
I don't see it in the help output. Are they released ?
My current solution (Java Spring Boot) has this dir structure:
So my charts folder is inside: c:\solution directory\charts\gs-spring-boot-docker while the properties file which I'm trying to add to configmap is in: c:\solution directory\src\main\resources\application-dev.yml
I want to avoid copying application-dev.yml to c:\solution directory\charts\gs-spring-boot-docker and rather just reach this file where is seats currently.
My Configmap definition looks like this - but I cannot get this to go outside only when I create resources folder inside c:\solution directory\charts\gs-spring-boot-docker then it worked.
is there a way to do something like this with glob patterns to go up through parent dirs ? {{ (.Files.Glob "../../../resources/application-dev.yml").AsConfig | indent 2 }}
Output of
helm version
: Client: &version.Version{SemVer:"v2.9.0-rc1", GitCommit:"280863d2362345450125ce15c3db504471dde2cf", GitTreeState:"clean"} Server: &version.Version{SemVer:"v2.9.0-rc1", GitCommit:"280863d2362345450125ce15c3db504471dde2cf", GitTreeState:"clean"}Output of
kubectl version
: Server Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.2", GitCommit:"5fa2db2bd46ac79e5e00a4e6ed24191080aa463b", GitTreeState:"clean", BuildDate:"2018-01-18T09:42:01Z", GoVersion:"go1.9.2", Compiler:"gc", Platform:"linux/amd64"}Cloud Provider/Platform (AKS, GKE, Minikube etc.): AKS
OS: Windows