...

Source file src/helm.sh/helm/v3/pkg/engine/files.go

Documentation: helm.sh/helm/v3/pkg/engine

     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/v3/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 []*chart.File (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  //
   104  // {{ .Files.Glob("config/**").AsConfig() | indent 4 }}
   105  func (f files) AsConfig() string {
   106  	if f == nil {
   107  		return ""
   108  	}
   109  
   110  	m := make(map[string]string)
   111  
   112  	// Explicitly convert to strings, and file names
   113  	for k, v := range f {
   114  		m[path.Base(k)] = string(v)
   115  	}
   116  
   117  	return toYAML(m)
   118  }
   119  
   120  // AsSecrets returns the base64-encoded value of a Files object suitable for
   121  // including in the 'data' section of a Kubernetes Secret definition.
   122  // Duplicate keys will be overwritten, so be aware that your file names
   123  // (regardless of path) should be unique.
   124  //
   125  // This is designed to be called from a template, and will return empty string
   126  // (via toYAML function) if it cannot be serialized to YAML, or if the Files
   127  // object is nil.
   128  //
   129  // The output will not be indented, so you will want to pipe this to the
   130  // 'indent' template function.
   131  //
   132  //	data:
   133  //
   134  // {{ .Files.Glob("secrets/*").AsSecrets() | indent 4 }}
   135  func (f files) AsSecrets() string {
   136  	if f == nil {
   137  		return ""
   138  	}
   139  
   140  	m := make(map[string]string)
   141  
   142  	for k, v := range f {
   143  		m[path.Base(k)] = base64.StdEncoding.EncodeToString(v)
   144  	}
   145  
   146  	return toYAML(m)
   147  }
   148  
   149  // Lines returns each line of a named file (split by "\n") as a slice, so it can
   150  // be ranged over in your templates.
   151  //
   152  // This is designed to be called from a template.
   153  //
   154  // {{ range .Files.Lines "foo/bar.html" }}
   155  // {{ . }}{{ end }}
   156  func (f files) Lines(path string) []string {
   157  	if f == nil || f[path] == nil {
   158  		return []string{}
   159  	}
   160  	s := string(f[path])
   161  	if s[len(s)-1] == '\n' {
   162  		s = s[:len(s)-1]
   163  	}
   164  	return strings.Split(s, "\n")
   165  }
   166  

View as plain text