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/kubectl/pkg/util/templates"
|
||||||
|
|
||||||
"k8s.io/kops/cmd/kops/util"
|
"k8s.io/kops/cmd/kops/util"
|
||||||
|
kopsapi "k8s.io/kops/pkg/apis/kops"
|
||||||
"k8s.io/kops/pkg/try"
|
"k8s.io/kops/pkg/try"
|
||||||
"k8s.io/kops/pkg/util/templater"
|
"k8s.io/kops/pkg/util/templater"
|
||||||
"k8s.io/kops/upup/pkg/fi/utils"
|
"k8s.io/kops/upup/pkg/fi/utils"
|
||||||
|
|
@ -68,6 +69,7 @@ type toolboxTemplateOption struct {
|
||||||
templatePath []string
|
templatePath []string
|
||||||
values []string
|
values []string
|
||||||
stringValues []string
|
stringValues []string
|
||||||
|
channel string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCmdToolboxTemplate returns a new templating command
|
// 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().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.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().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.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().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")
|
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
|
// @step: render each of the templates, splitting on the documents
|
||||||
r := templater.NewTemplater()
|
r := templater.NewTemplater(channel)
|
||||||
var documents []string
|
var documents []string
|
||||||
for _, x := range templates {
|
for _, x := range templates {
|
||||||
content, err := ioutil.ReadFile(x)
|
content, err := ioutil.ReadFile(x)
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ kops toolbox template [flags]
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
```
|
```
|
||||||
|
--channel string Channel to use for the channel* functions
|
||||||
--config-value string Show the value of a specific configuration value
|
--config-value string Show the value of a specific configuration value
|
||||||
--fail-on-missing Fail on referencing unset variables in templates (default true)
|
--fail-on-missing Fail on referencing unset variables in templates (default true)
|
||||||
--format-yaml Attempt to format the generated yaml content before output
|
--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(
|
go_library(
|
||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
srcs = ["templater.go"],
|
srcs = [
|
||||||
|
"template_functions.go",
|
||||||
|
"templater.go",
|
||||||
|
],
|
||||||
importpath = "k8s.io/kops/pkg/util/templater",
|
importpath = "k8s.io/kops/pkg/util/templater",
|
||||||
visibility = ["//visibility:public"],
|
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(
|
go_test(
|
||||||
|
|
@ -15,6 +22,7 @@ go_test(
|
||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/diff:go_default_library",
|
"//pkg/diff:go_default_library",
|
||||||
|
"//tests/integration/channel/simple:go_default_library",
|
||||||
"//vendor/gopkg.in/yaml.v2: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"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"github.com/Masterminds/sprig/v3"
|
"k8s.io/kops/pkg/apis/kops"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -30,11 +30,15 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Templater is golang template renders
|
// Templater is golang template renders
|
||||||
type Templater struct{}
|
type Templater struct {
|
||||||
|
channel *kops.Channel
|
||||||
|
}
|
||||||
|
|
||||||
// NewTemplater returns a new renderer implementation
|
// NewTemplater returns a new renderer implementation
|
||||||
func NewTemplater() *Templater {
|
func NewTemplater(channel *kops.Channel) *Templater {
|
||||||
return &Templater{}
|
return &Templater{
|
||||||
|
channel: channel,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render is responsible for actually rendering the template
|
// 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
|
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
|
// indentContent is responsible for indenting the string content
|
||||||
func indentContent(indent int, content string) string {
|
func indentContent(indent int, content string) string {
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"k8s.io/kops/pkg/diff"
|
"k8s.io/kops/pkg/diff"
|
||||||
|
"k8s.io/kops/tests/integration/channel/simple"
|
||||||
|
|
||||||
yaml "gopkg.in/yaml.v2"
|
yaml "gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
@ -81,6 +82,17 @@ func TestRenderIndent(t *testing.T) {
|
||||||
makeRenderTests(t, cases)
|
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) {
|
func TestRenderSnippet(t *testing.T) {
|
||||||
cases := []renderTest{
|
cases := []renderTest{
|
||||||
{
|
{
|
||||||
|
|
@ -182,7 +194,11 @@ type renderTest struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeRenderTests(t *testing.T, tests []renderTest) {
|
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 {
|
for i, x := range tests {
|
||||||
render, err := r.Render(x.Template, x.Context, x.Snippets, !x.DisableMissing)
|
render, err := r.Render(x.Template, x.Context, x.Snippets, !x.DisableMissing)
|
||||||
if x.NotOK {
|
if x.NotOK {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue