github.com/zsuzhengdu/helm@v3.0.0-beta.3+incompatible/pkg/engine/files.go (about)

     1  /*
     2  Copyright The Helm Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package engine
    18  
    19  import (
    20  	"encoding/base64"
    21  	"path"
    22  	"strings"
    23  
    24  	"github.com/gobwas/glob"
    25  
    26  	"helm.sh/helm/pkg/chart"
    27  )
    28  
    29  // files is a map of files in a chart that can be accessed from a template.
    30  type files map[string][]byte
    31  
    32  // NewFiles creates a new files from chart files.
    33  // Given an []*any.Any (the format for files in a chart.Chart), extract a map of files.
    34  func newFiles(from []*chart.File) files {
    35  	files := make(map[string][]byte)
    36  	for _, f := range from {
    37  		files[f.Name] = f.Data
    38  	}
    39  	return files
    40  }
    41  
    42  // GetBytes gets a file by path.
    43  //
    44  // The returned data is raw. In a template context, this is identical to calling
    45  // {{index .Files $path}}.
    46  //
    47  // This is intended to be accessed from within a template, so a missed key returns
    48  // an empty []byte.
    49  func (f files) GetBytes(name string) []byte {
    50  	if v, ok := f[name]; ok {
    51  		return v
    52  	}
    53  	return []byte{}
    54  }
    55  
    56  // Get returns a string representation of the given file.
    57  //
    58  // Fetch the contents of a file as a string. It is designed to be called in a
    59  // template.
    60  //
    61  //	{{.Files.Get "foo"}}
    62  func (f files) Get(name string) string {
    63  	return string(f.GetBytes(name))
    64  }
    65  
    66  // Glob takes a glob pattern and returns another files object only containing
    67  // matched  files.
    68  //
    69  // This is designed to be called from a template.
    70  //
    71  // {{ range $name, $content := .Files.Glob("foo/**") }}
    72  // {{ $name }}: |
    73  // {{ .Files.Get($name) | indent 4 }}{{ end }}
    74  func (f files) Glob(pattern string) files {
    75  	g, err := glob.Compile(pattern, '/')
    76  	if err != nil {
    77  		g, _ = glob.Compile("**")
    78  	}
    79  
    80  	nf := newFiles(nil)
    81  	for name, contents := range f {
    82  		if g.Match(name) {
    83  			nf[name] = contents
    84  		}
    85  	}
    86  
    87  	return nf
    88  }
    89  
    90  // AsConfig turns a Files group and flattens it to a YAML map suitable for
    91  // including in the 'data' section of a Kubernetes ConfigMap definition.
    92  // Duplicate keys will be overwritten, so be aware that your file names
    93  // (regardless of path) should be unique.
    94  //
    95  // This is designed to be called from a template, and will return empty string
    96  // (via toYAML function) if it cannot be serialized to YAML, or if the Files
    97  // object is nil.
    98  //
    99  // The output will not be indented, so you will want to pipe this to the
   100  // 'indent' template function.
   101  //
   102  //   data:
   103  // {{ .Files.Glob("config/**").AsConfig() | indent 4 }}
   104  func (f files) AsConfig() string {
   105  	if f == nil {
   106  		return ""
   107  	}
   108  
   109  	m := make(map[string]string)
   110  
   111  	// Explicitly convert to strings, and file names
   112  	for k, v := range f {
   113  		m[path.Base(k)] = string(v)
   114  	}
   115  
   116  	return toYAML(m)
   117  }
   118  
   119  // AsSecrets returns the base64-encoded value of a Files object suitable for
   120  // including in the 'data' section of a Kubernetes Secret definition.
   121  // Duplicate keys will be overwritten, so be aware that your file names
   122  // (regardless of path) should be unique.
   123  //
   124  // This is designed to be called from a template, and will return empty string
   125  // (via toYAML function) if it cannot be serialized to YAML, or if the Files
   126  // object is nil.
   127  //
   128  // The output will not be indented, so you will want to pipe this to the
   129  // 'indent' template function.
   130  //
   131  //   data:
   132  // {{ .Files.Glob("secrets/*").AsSecrets() }}
   133  func (f files) AsSecrets() string {
   134  	if f == nil {
   135  		return ""
   136  	}
   137  
   138  	m := make(map[string]string)
   139  
   140  	for k, v := range f {
   141  		m[path.Base(k)] = base64.StdEncoding.EncodeToString(v)
   142  	}
   143  
   144  	return toYAML(m)
   145  }
   146  
   147  // Lines returns each line of a named file (split by "\n") as a slice, so it can
   148  // be ranged over in your templates.
   149  //
   150  // This is designed to be called from a template.
   151  //
   152  // {{ range .Files.Lines "foo/bar.html" }}
   153  // {{ . }}{{ end }}
   154  func (f files) Lines(path string) []string {
   155  	if f == nil || f[path] == nil {
   156  		return []string{}
   157  	}
   158  
   159  	return strings.Split(string(f[path]), "\n")
   160  }