mirror of https://github.com/kubernetes/kops.git
				
				
				
			Add template function for preferred version
This commit is contained in:
		
							parent
							
								
									2b0e84b432
								
							
						
					
					
						commit
						5fe948bb5c
					
				| 
						 | 
				
			
			@ -32,6 +32,7 @@ import (
 | 
			
		|||
	"k8s.io/kubectl/pkg/util/templates"
 | 
			
		||||
 | 
			
		||||
	"k8s.io/kops/cmd/kops/util"
 | 
			
		||||
	kopsapi "k8s.io/kops/pkg/apis/kops"
 | 
			
		||||
	"k8s.io/kops/pkg/try"
 | 
			
		||||
	"k8s.io/kops/pkg/util/templater"
 | 
			
		||||
	"k8s.io/kops/upup/pkg/fi/utils"
 | 
			
		||||
| 
						 | 
				
			
			@ -68,6 +69,7 @@ type toolboxTemplateOption struct {
 | 
			
		|||
	templatePath  []string
 | 
			
		||||
	values        []string
 | 
			
		||||
	stringValues  []string
 | 
			
		||||
	channel       string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewCmdToolboxTemplate returns a new templating command
 | 
			
		||||
| 
						 | 
				
			
			@ -96,6 +98,7 @@ func NewCmdToolboxTemplate(f *util.Factory, out io.Writer) *cobra.Command {
 | 
			
		|||
	cmd.Flags().StringArrayVar(&options.stringValues, "set-string", options.stringValues, "Set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
 | 
			
		||||
	cmd.Flags().StringSliceVar(&options.templatePath, "template", options.templatePath, "Path to template file or directory of templates to render")
 | 
			
		||||
	cmd.Flags().StringSliceVar(&options.snippetsPath, "snippets", options.snippetsPath, "Path to directory containing snippets used for templating")
 | 
			
		||||
	cmd.Flags().StringVar(&options.channel, "channel", options.channel, "Channel to use for the channel* functions")
 | 
			
		||||
	cmd.Flags().StringVar(&options.outputPath, "output", options.outputPath, "Path to output file, otherwise defaults to stdout")
 | 
			
		||||
	cmd.Flags().StringVar(&options.configValue, "config-value", "", "Show the value of a specific configuration value")
 | 
			
		||||
	cmd.Flags().BoolVar(&options.failOnMissing, "fail-on-missing", true, "Fail on referencing unset variables in templates")
 | 
			
		||||
| 
						 | 
				
			
			@ -158,8 +161,18 @@ func runToolBoxTemplate(f *util.Factory, out io.Writer, options *toolboxTemplate
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	channelLocation := ""
 | 
			
		||||
	if channelLocation == "" {
 | 
			
		||||
		channelLocation = kopsapi.DefaultChannel
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	channel, err := kopsapi.LoadChannel(channelLocation)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("error loading channel %q: %v", channelLocation, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// @step: render each of the templates, splitting on the documents
 | 
			
		||||
	r := templater.NewTemplater()
 | 
			
		||||
	r := templater.NewTemplater(channel)
 | 
			
		||||
	var documents []string
 | 
			
		||||
	for _, x := range templates {
 | 
			
		||||
		content, err := ioutil.ReadFile(x)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,6 +29,7 @@ kops toolbox template [flags]
 | 
			
		|||
### Options
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
      --channel string           Channel to use for the channel* functions
 | 
			
		||||
      --config-value string      Show the value of a specific configuration value
 | 
			
		||||
      --fail-on-missing          Fail on referencing unset variables in templates (default true)
 | 
			
		||||
      --format-yaml              Attempt to format the generated yaml content before output
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,10 +2,17 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
 | 
			
		|||
 | 
			
		||||
go_library(
 | 
			
		||||
    name = "go_default_library",
 | 
			
		||||
    srcs = ["templater.go"],
 | 
			
		||||
    srcs = [
 | 
			
		||||
        "template_functions.go",
 | 
			
		||||
        "templater.go",
 | 
			
		||||
    ],
 | 
			
		||||
    importpath = "k8s.io/kops/pkg/util/templater",
 | 
			
		||||
    visibility = ["//visibility:public"],
 | 
			
		||||
    deps = ["//vendor/github.com/Masterminds/sprig/v3:go_default_library"],
 | 
			
		||||
    deps = [
 | 
			
		||||
        "//:go_default_library",
 | 
			
		||||
        "//pkg/apis/kops:go_default_library",
 | 
			
		||||
        "//vendor/github.com/Masterminds/sprig/v3:go_default_library",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
go_test(
 | 
			
		||||
| 
						 | 
				
			
			@ -15,6 +22,7 @@ go_test(
 | 
			
		|||
    embed = [":go_default_library"],
 | 
			
		||||
    deps = [
 | 
			
		||||
        "//pkg/diff:go_default_library",
 | 
			
		||||
        "//tests/integration/channel/simple:go_default_library",
 | 
			
		||||
        "//vendor/gopkg.in/yaml.v2:go_default_library",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,48 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2020 The Kubernetes Authors.
 | 
			
		||||
 | 
			
		||||
Licensed 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 templater
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"text/template"
 | 
			
		||||
 | 
			
		||||
	"github.com/Masterminds/sprig/v3"
 | 
			
		||||
	"k8s.io/kops"
 | 
			
		||||
	kopsapi "k8s.io/kops/pkg/apis/kops"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// templateFuncsMap returns a map if the template functions for this template
 | 
			
		||||
func (r *Templater) templateFuncsMap(tm *template.Template) template.FuncMap {
 | 
			
		||||
	// grab the template functions from sprig which are pretty awesome
 | 
			
		||||
	funcs := sprig.TxtFuncMap()
 | 
			
		||||
 | 
			
		||||
	funcs["indent"] = indentContent
 | 
			
		||||
	// @step: as far as i can see there's no native way in sprig in include external snippets of code
 | 
			
		||||
	funcs["include"] = func(name string, context map[string]interface{}) string {
 | 
			
		||||
		content, err := includeSnippet(tm, name, context)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			panic(err.Error())
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return content
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	funcs["ChannelRecommendedKubernetesVersion"] = func() string {
 | 
			
		||||
		return kopsapi.RecommendedKubernetesVersion(r.channel, kops.Version).String()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return funcs
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -22,7 +22,7 @@ import (
 | 
			
		|||
	"strings"
 | 
			
		||||
	"text/template"
 | 
			
		||||
 | 
			
		||||
	"github.com/Masterminds/sprig/v3"
 | 
			
		||||
	"k8s.io/kops/pkg/apis/kops"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
| 
						 | 
				
			
			@ -30,11 +30,15 @@ const (
 | 
			
		|||
)
 | 
			
		||||
 | 
			
		||||
// Templater is golang template renders
 | 
			
		||||
type Templater struct{}
 | 
			
		||||
type Templater struct {
 | 
			
		||||
	channel *kops.Channel
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewTemplater returns a new renderer implementation
 | 
			
		||||
func NewTemplater() *Templater {
 | 
			
		||||
	return &Templater{}
 | 
			
		||||
func NewTemplater(channel *kops.Channel) *Templater {
 | 
			
		||||
	return &Templater{
 | 
			
		||||
		channel: channel,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Render is responsible for actually rendering the template
 | 
			
		||||
| 
						 | 
				
			
			@ -72,25 +76,6 @@ func (r *Templater) Render(content string, context map[string]interface{}, snipp
 | 
			
		|||
	return writer.String(), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// templateFuncsMap returns a map if the template functions for this template
 | 
			
		||||
func (r *Templater) templateFuncsMap(tm *template.Template) template.FuncMap {
 | 
			
		||||
	// grab the template functions from sprig which are pretty awesome
 | 
			
		||||
	funcs := sprig.TxtFuncMap()
 | 
			
		||||
 | 
			
		||||
	funcs["indent"] = indentContent
 | 
			
		||||
	// @step: as far as i can see there's no native way in sprig in include external snippets of code
 | 
			
		||||
	funcs["include"] = func(name string, context map[string]interface{}) string {
 | 
			
		||||
		content, err := includeSnippet(tm, name, context)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			panic(err.Error())
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return content
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return funcs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// indentContent is responsible for indenting the string content
 | 
			
		||||
func indentContent(indent int, content string) string {
 | 
			
		||||
	var b bytes.Buffer
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,6 +21,7 @@ import (
 | 
			
		|||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"k8s.io/kops/pkg/diff"
 | 
			
		||||
	"k8s.io/kops/tests/integration/channel/simple"
 | 
			
		||||
 | 
			
		||||
	yaml "gopkg.in/yaml.v2"
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -81,6 +82,17 @@ func TestRenderIndent(t *testing.T) {
 | 
			
		|||
	makeRenderTests(t, cases)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestRenderChannelFunctions(t *testing.T) {
 | 
			
		||||
	cases := []renderTest{
 | 
			
		||||
		{
 | 
			
		||||
			Context:  map[string]interface{}{},
 | 
			
		||||
			Template: `{{ ChannelRecommendedKubernetesVersion }}`,
 | 
			
		||||
			Expected: "1.5.2",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	makeRenderTests(t, cases)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestRenderSnippet(t *testing.T) {
 | 
			
		||||
	cases := []renderTest{
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -182,7 +194,11 @@ type renderTest struct {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func makeRenderTests(t *testing.T, tests []renderTest) {
 | 
			
		||||
	r := NewTemplater()
 | 
			
		||||
	channel, err := simple.NewMockChannel()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatalf("could not load channel: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	r := NewTemplater(channel)
 | 
			
		||||
	for i, x := range tests {
 | 
			
		||||
		render, err := r.Render(x.Template, x.Context, x.Snippets, !x.DisableMissing)
 | 
			
		||||
		if x.NotOK {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue