pkg/template/engine/files.go (64 lines of code) (raw):

// Licensed to Elasticsearch B.V. under one or more contributor // license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright // ownership. Elasticsearch B.V. licenses this file to you under // the Apache License, Version 2.0 (the "License"); you may // not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. package engine import ( "encoding/base64" "path" "strings" "github.com/gobwas/glob" "github.com/elastic/harp/pkg/template/files" ) // Files is a map of files that can be accessed from a template. type Files map[string][]byte // NewFiles returns an engine file collection from file loader. func NewFiles(from []*files.BufferedFile) Files { fileMap := make(map[string][]byte) for _, f := range from { fileMap[f.Name] = f.Data } return fileMap } // GetBytes gets a file by path. // // The returned data is raw. In a template context, this is identical to calling // {{index .Files $path}}. // // This is intended to be accessed from within a template, so a missed key returns // an empty []byte. func (f Files) GetBytes(name string) []byte { if v, ok := f[name]; ok { return v } return []byte{} } // Get returns a string representation of the given file. // // Fetch the contents of a file as a string. It is designed to be called in a // template. // // {{.Files.Get "foo"}} func (f Files) Get(name string) string { 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 := Files{} for name, contents := range f { if g.Match(name) { nf[name] = contents } } return nf } // AsConfig returns a Files group and flattens it to a YAML map suitable for // including in the 'data' section of a Kubernetes ConfigMap definition. // Duplicate keys will be overwritten, so be aware that your file names // (regardless of path) should be unique. // // The output will not be indented, so you will want to pipe this to the // 'indent' template function. // // data: // // {{ .Files.Glob("config/**").AsConfig() | toYaml | indent 4 }} func (f Files) AsConfig() map[string]string { if f == nil { return nil } m := make(map[string]string) // Explicitly convert to strings, and file names for k, v := range f { m[path.Base(k)] = string(v) } return m } // AsSecrets returns the base64-encoded value of a Files object suitable for // including in the 'data' section of a Kubernetes Secret definition. // Duplicate keys will be overwritten, so be aware that your file names // (regardless of path) should be unique. // // The output will not be indented, so you will want to pipe this to the // 'indent' template function. // // data: // // {{ .Files.Glob("secrets/*").AsSecrets() | toYaml }} func (f Files) AsSecrets() map[string]string { if f == nil { return nil } m := make(map[string]string) for k, v := range f { m[path.Base(k)] = base64.StdEncoding.EncodeToString(v) } return m } // Lines returns each line of a named file (split by "\n") as a slice, so it can // be ranged over in your templates. // // This is designed to be called from a template. // // {{ range .Files.Lines "foo/bar.html" }} // {{ . }}{{ end }} func (f Files) Lines(filePath string) []string { if f == nil || f[filePath] == nil { return []string{} } return strings.Split(string(f[filePath]), "\n") }