mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-11 00:52:55 +00:00
Improvements to kyaml fn framework
This commit creates a new version of the alpha configuration functions framework. Goals include: - Make it easy to build multi-version APIs with the framework (not previously facilitated at all). - Simplify the framework's APIs where redundant configuration options exist (leaving the most powerful, replacing others with helpers to maintain usability they provided). - Make the Framework's APIs more consistent (e.g. between the various template types, usage of kio.Filter, field names) - Decouple responsibilities (e.g. command creation, resource list processing, generation of templating functions). - Make the framework even more powerfully pluggable (e.g. any kio.Filter can be a selector, and the selector the framework provides is itself a filter built from reusable abstractions). - Improve documentation. - Make container patches merge fields (notably list fields like `env`) correctly.
This commit is contained in:
80
kyaml/fn/framework/template.go
Normal file
80
kyaml/fn/framework/template.go
Normal file
@@ -0,0 +1,80 @@
|
||||
// Copyright 2021 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package framework
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||
"sigs.k8s.io/kustomize/kyaml/kio"
|
||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||
)
|
||||
|
||||
// ResourceTemplate generates resources from templates.
|
||||
type ResourceTemplate struct {
|
||||
// Templates is a function that returns a list of templates to render into one or more resources.
|
||||
Templates TemplatesFunc
|
||||
|
||||
// TemplateData is the data to use when rendering the templates provided by the Templates field.
|
||||
TemplateData interface{}
|
||||
}
|
||||
|
||||
// DefaultTemplateData sets TemplateData to the provided default values if it has not already
|
||||
// been set.
|
||||
func (rt *ResourceTemplate) DefaultTemplateData(data interface{}) {
|
||||
if rt.TemplateData == nil {
|
||||
rt.TemplateData = data
|
||||
}
|
||||
}
|
||||
|
||||
// Render renders the Templates into resource nodes using TemplateData.
|
||||
func (rt *ResourceTemplate) Render() ([]*yaml.RNode, error) {
|
||||
var items []*yaml.RNode
|
||||
|
||||
if rt.Templates == nil {
|
||||
return items, nil
|
||||
}
|
||||
|
||||
templates, err := rt.Templates()
|
||||
if err != nil {
|
||||
return nil, errors.WrapPrefixf(err, "failed to retrieve ResourceTemplates")
|
||||
}
|
||||
|
||||
for i := range templates {
|
||||
newItems, err := rt.doTemplate(templates[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, newItems...)
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (rt *ResourceTemplate) doTemplate(t *template.Template) ([]*yaml.RNode, error) {
|
||||
// invoke the template
|
||||
var b bytes.Buffer
|
||||
err := t.Execute(&b, rt.TemplateData)
|
||||
if err != nil {
|
||||
return nil, errors.WrapPrefixf(err, "failed to render template %v", t.DefinedTemplates())
|
||||
}
|
||||
var items []*yaml.RNode
|
||||
|
||||
// split the resources so the error messaging is better
|
||||
for _, s := range strings.Split(b.String(), "\n---\n") {
|
||||
s = strings.TrimSpace(s)
|
||||
if s == "" {
|
||||
continue
|
||||
}
|
||||
newItems, err := (&kio.ByteReader{Reader: bytes.NewBufferString(s)}).Read()
|
||||
if err != nil {
|
||||
return nil, errors.WrapPrefixf(err,
|
||||
"failed to parse rendered template into a resource:\n%s\n", addLineNumbers(s))
|
||||
}
|
||||
|
||||
items = append(items, newItems...)
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
Reference in New Issue
Block a user