Merge pull request #1617 from andrewstuart/files-subdir

feat(helm): Add Files.Glob method to permit file organization
pull/1621/head
Matt Butcher 8 years ago committed by GitHub
commit 2dacb92a1e

@ -9,6 +9,8 @@ Helm provides access to files through the `.Files` object. Before we get going w
- Files in `templates/` cannot be accessed. - Files in `templates/` cannot be accessed.
- Charts to not preserve UNIX mode information, so file-level permissions will have no impact on the availability of a file when it comes to the `.Files` object. - Charts to not preserve UNIX mode information, so file-level permissions will have no impact on the availability of a file when it comes to the `.Files` object.
## Basic example
With those caveats behind, let's write a template that reads three files into our ConfigMap. To get started, we will add three files to the chart, putting all three directly inside of the `mychart/` directory. With those caveats behind, let's write a template that reads three files into our ConfigMap. To get started, we will add three files to the chart, putting all three directly inside of the `mychart/` directory.
`config1.toml`: `config1.toml`:
@ -65,6 +67,42 @@ data:
message = Goodbye from config 3 message = Goodbye from config 3
``` ```
## Glob patterns
As your chart grows, you may find you have a greater need to organize your
files more, and so we provide a `Files.Glob(pattern string)` method to assist
in extracting certain files with all the flexibility of [glob patterns](//godoc.org/github.com/gobwas/glob).
For example, imagine the directory structure:
```
foo/:
foo.txt foo.yaml
bar/:
bar.go bar.conf baz.yaml
```
You have multiple options with Globs:
```yaml
{{ range $path := .Files.Glob "**.yaml" }}
{{ $path }}: |
{{ .Files.Get $path }}
{{ end }}
```
Or
```yaml
{{ range $path, $bytes := .Files.Glob "foo/*" }}
{{ $path }}: '{{ b64enc $bytes }}'
{{ end }}
```
## Secrets
When working with a Secret resource, you can import a file and have the template base-64 encode it for you: When working with a Secret resource, you can import a file and have the template base-64 encode it for you:
```yaml ```yaml

14
glide.lock generated

@ -1,5 +1,5 @@
hash: 89695daf5f2de706b79fdd8e8b095f9514f418c0fbcf80d7fdca4c208d114d19 hash: 707ac6d1785d0029397f2f9a3b0bc45f7d8ce819f14f6c246967b0a404627a2c
updated: 2016-11-29T14:56:31.55726541-07:00 updated: 2016-12-01T09:07:51.289370422-07:00
imports: imports:
- name: cloud.google.com/go - name: cloud.google.com/go
version: 3b1ae45394a234c385be014e9a488f2bb6eef821 version: 3b1ae45394a234c385be014e9a488f2bb6eef821
@ -103,6 +103,16 @@ imports:
version: 465937c80b3c07a7c7ad20cc934898646a91c1de version: 465937c80b3c07a7c7ad20cc934898646a91c1de
- name: github.com/ghodss/yaml - name: github.com/ghodss/yaml
version: 73d445a93680fa1a78ae23a5839bad48f32ba1ee version: 73d445a93680fa1a78ae23a5839bad48f32ba1ee
- name: github.com/gobwas/glob
version: 0354991b92587e2742549d3036f3b5bae5ab03f2
subpackages:
- compiler
- match
- syntax
- syntax/ast
- syntax/lexer
- util/runes
- util/strings
- name: github.com/gogo/protobuf - name: github.com/gogo/protobuf
version: e18d7aa8f8c624c915db340349aad4c49b10d173 version: e18d7aa8f8c624c915db340349aad4c49b10d173
subpackages: subpackages:

@ -49,3 +49,5 @@ import:
- package: golang.org/x/crypto - package: golang.org/x/crypto
subpackages: subpackages:
- openpgp - openpgp
- package: github.com/gobwas/glob
version: ^0.2.1

@ -16,6 +16,7 @@ limitations under the License.
package chartutil package chartutil
import ( import (
"github.com/gobwas/glob"
"github.com/golang/protobuf/ptypes/any" "github.com/golang/protobuf/ptypes/any"
) )
@ -26,8 +27,10 @@ type Files map[string][]byte
// Given an []*any.Any (the format for files in a chart.Chart), extract a map of files. // Given an []*any.Any (the format for files in a chart.Chart), extract a map of files.
func NewFiles(from []*any.Any) Files { func NewFiles(from []*any.Any) Files {
files := map[string][]byte{} files := map[string][]byte{}
for _, f := range from { if from != nil {
files[f.TypeUrl] = f.Value for _, f := range from {
files[f.TypeUrl] = f.Value
}
} }
return files return files
} }
@ -56,3 +59,27 @@ func (f Files) GetBytes(name string) []byte {
func (f Files) Get(name string) string { func (f Files) Get(name string) string {
return string(f.GetBytes(name)) return string(f.GetBytes(name))
} }
// Glob takes a glob pattern and returns another files object only containing
// matched files.
//
// This is designed to be called from a template.
//
// {{ range $name, $content := .Files.Glob("foo/**") }}
// {{ $name }}: |
// {{ .Files.Get($name) | indent 4 }}{{ end }}
func (f Files) Glob(pattern string) Files {
g, err := glob.Compile(pattern, '/')
if err != nil {
g, _ = glob.Compile("**")
}
nf := NewFiles(nil)
for name, contents := range f {
if g.Match(name) {
nf[name] = contents
}
}
return nf
}

@ -21,23 +21,25 @@ import (
"github.com/golang/protobuf/ptypes/any" "github.com/golang/protobuf/ptypes/any"
) )
func TestNewFiles(t *testing.T) { var cases = []struct {
path, data string
cases := []struct { }{
path, data string {"ship/captain.txt", "The Captain"},
}{ {"ship/stowaway.txt", "Legatt"},
{"ship/captain.txt", "The Captain"}, {"story/name.txt", "The Secret Sharer"},
{"ship/stowaway.txt", "Legatt"}, {"story/author.txt", "Joseph Conrad"},
{"story/name.txt", "The Secret Sharer"}, }
{"story/author.txt", "Joseph Conrad"},
}
func getTestFiles() []*any.Any {
a := []*any.Any{} a := []*any.Any{}
for _, c := range cases { for _, c := range cases {
a = append(a, &any.Any{TypeUrl: c.path, Value: []byte(c.data)}) a = append(a, &any.Any{TypeUrl: c.path, Value: []byte(c.data)})
} }
return a
}
files := NewFiles(a) func TestNewFiles(t *testing.T) {
files := NewFiles(getTestFiles())
if len(files) != len(cases) { if len(files) != len(cases) {
t.Errorf("Expected len() = %d, got %d", len(cases), len(files)) t.Errorf("Expected len() = %d, got %d", len(cases), len(files))
} }
@ -51,3 +53,18 @@ func TestNewFiles(t *testing.T) {
} }
} }
} }
func TestFileGlob(t *testing.T) {
f := NewFiles(getTestFiles())
matched := f.Glob("story/**")
if len(matched) != 2 {
t.Errorf("Expected two files in glob story/**, got %d", len(matched))
}
m, expect := matched.Get("story/author.txt"), "Joseph Conrad"
if m != expect {
t.Errorf("Wrong globbed file content. Expected %s, got %s", expect, m)
}
}

Loading…
Cancel
Save