helm / helm

The Kubernetes Package Manager
https://helm.sh
Apache License 2.0
27.07k stars 7.12k forks source link

[Question] Can I reach files outside of chart folder with .Files.Glob #4026

Closed rhollins closed 6 years ago

rhollins commented 6 years ago

My current solution (Java Spring Boot) has this dir structure:


solution directory
├───charts
│   └───gs-spring-boot-docker
│       ├───charts
│       ├───resources
│       └───templates
└───src
    ├───main
    │   ├───java
    │   │   └───hello
    │   └───resources
    └───test
        └───java
            └───hello

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 }}

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ template "gs-spring-boot-docker.fullname" . }}
  labels:
    app: {{ template "gs-spring-boot-docker.name" . }}
    chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
    release: {{ .Release.Name }}    
data:
{{ (.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

technosophos commented 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.

rhollins commented 6 years ago

Thanks for confirmation.

ekhaydarov commented 4 years ago

Its 2020. Helm 3 doesnt care about tiller. Can we now reach files outside of chart folder with Files.Glob?

bacongobbler commented 4 years ago

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.

survivant commented 3 years ago

I filled an issue about getting the files from chart folder : https://github.com/helm/helm/issues/9420

VengefulAncient commented 3 years ago

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.

survivant commented 3 years ago

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.

VengefulAncient commented 3 years ago

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.

survivant commented 3 years ago

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 .

bacongobbler commented 3 years ago

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 😄).

survivant commented 3 years ago

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>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
vio-f commented 3 years ago

@survivant

8840 --- closed

8841 --- open and waiting to be merged

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

VengefulAncient commented 3 years ago

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.

ComradePashka commented 2 years ago

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.

trash-80 commented 2 years ago

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 }}
ikegentz commented 2 years ago

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

dee-kryvenko commented 1 year ago

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?

zfalen-deloitte commented 1 year ago

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

nkaijala-elisa commented 11 months ago

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?

vladmiller commented 9 months ago

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)
ArunKumarT1995 commented 5 months ago

@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 ?