// Copyright 2021 The Kubernetes Authors. // SPDX-License-Identifier: Apache-2.0 package parser import ( "fmt" iofs "io/fs" "os" "path/filepath" "text/template" "sigs.k8s.io/kustomize/kyaml/fn/framework" ) const ( // TemplateExtension is the file extension this package requires template files to have TemplateExtension = ".template.yaml" ) // TemplateStrings returns a TemplateParser that will parse the templates from the given strings. // // This is a helper for use with framework.TemplateProcessor's template subfields. Example: // // processor := framework.TemplateProcessor{ // ResourceTemplates: []framework.ResourceTemplate{{ // Templates: parser.TemplateStrings(` // apiVersion: apps/v1 // kind: Deployment // metadata: // name: foo // namespace: default // annotations: // {{ .Key }}: {{ .Value }} // `) // }}, // } func TemplateStrings(data ...string) framework.TemplateParser { return framework.TemplateParserFunc(func() ([]*template.Template, error) { var templates []*template.Template for i := range data { t, err := template.New(fmt.Sprintf("inline%d", i)).Parse(data[i]) if err != nil { return nil, err } templates = append(templates, t) } return templates, nil }) } // TemplateFiles returns a TemplateParser that will parse the templates from the given files or directories. // Only immediate children of any given directories will be parsed. // All files must end in .template.yaml. // // This is a helper for use with framework.TemplateProcessor's template subfields. Example: // // processor := framework.TemplateProcessor{ // ResourceTemplates: []framework.ResourceTemplate{{ // Templates: parser.TemplateFiles("path/to/templates", "path/to/special.template.yaml") // }}, // } func TemplateFiles(paths ...string) TemplateParser { return TemplateParser{parser{paths: paths, extensions: []string{TemplateExtension}}} } // TemplateParser is a framework.TemplateParser that can parse files or directories containing Go templated YAML. type TemplateParser struct { parser } // Parse implements framework.TemplateParser func (l TemplateParser) Parse() ([]*template.Template, error) { if l.fs == nil { l.fs = os.DirFS(".") } var templates []*template.Template err := l.parse(func(content []byte, file string) error { t, err := template.New(filepath.Base(file)).Parse(string(content)) if err == nil { templates = append(templates, t) } return err }) if err != nil { return nil, err } return templates, nil } // FromFS allows you to replace the filesystem in which the parser will look up the given paths. // For example, you can use an embed.FS. func (l TemplateParser) FromFS(fs iofs.FS) TemplateParser { l.parser.fs = fs return l } // WithExtensions allows you to replace the extension the parser accept on the input files. func (l TemplateParser) WithExtensions(ext ...string) TemplateParser { l.parser.extensions = ext return l }