diff --git a/docs/operations/cluster_template.md b/docs/operations/cluster_template.md index 1328a7fd93..bfc302c8cb 100644 --- a/docs/operations/cluster_template.md +++ b/docs/operations/cluster_template.md @@ -121,6 +121,18 @@ spec: ### Template Functions +#### Kops specific functions + +##### ChannelRecommendedKopsKubernetesVersion + +This function returns the kubernetes version recommended for the running kops version. + +##### ChannelRecommendedKopsUpgradeVersion + +This function returns the kubernetes upgrade recommendation given that you run ``. Typically this is the latest minor version supported by the given channel. + +#### Sprig functions + The entire set of https://github.com/Masterminds/sprig functions are available within the templates for you. Note if you want to use the 'defaults' functions switch off the verification check on the command line by `--fail-on-missing=false`; ```YAML diff --git a/docs/releases/1.20-NOTES.md b/docs/releases/1.20-NOTES.md index 93acdfb863..e00eb36db7 100644 --- a/docs/releases/1.20-NOTES.md +++ b/docs/releases/1.20-NOTES.md @@ -4,6 +4,8 @@ # Significant changes +* Added [template funtions](https://kops.sigs.k8s.io/operations/cluster_template/#template-functions) for kubernetes version based on channel data. + # Breaking changes * Support for Kubernetes 1.11 and 1.12 has been removed. @@ -14,6 +16,8 @@ # Required Actions +* If you are running `kops toolbox template` in an airgapped environment, you have to set `--channel` to point to a local channel file. + # Deprecations * Support for Kubernetes versions 1.13 and 1.14 are deprecated and will be removed in kOps 1.21. diff --git a/pkg/util/templater/BUILD.bazel b/pkg/util/templater/BUILD.bazel index dd36b2331e..39b1d0951b 100644 --- a/pkg/util/templater/BUILD.bazel +++ b/pkg/util/templater/BUILD.bazel @@ -11,6 +11,7 @@ go_library( deps = [ "//:go_default_library", "//pkg/apis/kops:go_default_library", + "//pkg/apis/kops/util:go_default_library", "//vendor/github.com/Masterminds/sprig/v3:go_default_library", ], ) diff --git a/pkg/util/templater/template_functions.go b/pkg/util/templater/template_functions.go index 79a3a759ce..bac7fac431 100644 --- a/pkg/util/templater/template_functions.go +++ b/pkg/util/templater/template_functions.go @@ -22,6 +22,7 @@ import ( "github.com/Masterminds/sprig/v3" "k8s.io/kops" kopsapi "k8s.io/kops/pkg/apis/kops" + "k8s.io/kops/pkg/apis/kops/util" ) // templateFuncsMap returns a map if the template functions for this template @@ -40,8 +41,25 @@ func (r *Templater) templateFuncsMap(tm *template.Template) template.FuncMap { return content } - funcs["ChannelRecommendedKubernetesVersion"] = func() string { + funcs["ChannelRecommendedKubernetesUpgradeVersion"] = func(version string) string { + + parsed, err := util.ParseKubernetesVersion(version) + if err != nil { + panic(err.Error()) + } + + versionInfo := kopsapi.FindKubernetesVersionSpec(r.channel.Spec.KubernetesVersions, *parsed) + recommended, err := versionInfo.FindRecommendedUpgrade(*parsed) + if err != nil { + panic(err.Error()) + } + return recommended.String() + + } + + funcs["ChannelRecommendedKopsKubernetesVersion"] = func() string { return kopsapi.RecommendedKubernetesVersion(r.channel, kops.Version).String() + } return funcs diff --git a/pkg/util/templater/templater_test.go b/pkg/util/templater/templater_test.go index 46d3f863c5..584cbed7ea 100644 --- a/pkg/util/templater/templater_test.go +++ b/pkg/util/templater/templater_test.go @@ -18,6 +18,7 @@ package templater import ( "io/ioutil" + "os" "testing" "k8s.io/kops/pkg/diff" @@ -86,9 +87,14 @@ func TestRenderChannelFunctions(t *testing.T) { cases := []renderTest{ { Context: map[string]interface{}{}, - Template: `{{ ChannelRecommendedKubernetesVersion }}`, + Template: `{{ ChannelRecommendedKopsKubernetesVersion }}`, Expected: "1.5.2", }, + { + Context: map[string]interface{}{}, + Template: `{{ ChannelRecommendedKubernetesUpgradeVersion "1.4.2" }}`, + Expected: "1.4.8", + }, } makeRenderTests(t, cases) } @@ -194,9 +200,13 @@ type renderTest struct { } func makeRenderTests(t *testing.T, tests []renderTest) { - channel, err := simple.NewMockChannel() + + sourcePath := "../../../tests/integration/channel/simple/channel.yaml" + s, _ := os.Getwd() + + channel, err := simple.NewMockChannel(sourcePath) if err != nil { - t.Fatalf("could not load channel: %v", err) + t.Fatalf("could not load channel: %v, %s", err, s) } r := NewTemplater(channel) for i, x := range tests { diff --git a/tests/integration/channel/integration_test.go b/tests/integration/channel/integration_test.go index 866087b7c1..436d972616 100644 --- a/tests/integration/channel/integration_test.go +++ b/tests/integration/channel/integration_test.go @@ -28,8 +28,9 @@ import ( // TestKopsUpgrades tests the version logic for kops versions func TestKopsUpgrades(t *testing.T) { + sourcePath := "simple/channel.yaml" - channel, err := simple.NewMockChannel() + channel, err := simple.NewMockChannel(sourcePath) if err != nil { t.Fatalf("failed to create channel: %v", err) } diff --git a/tests/integration/channel/simple/mock_channel.go b/tests/integration/channel/simple/mock_channel.go index 749722d400..26218d45e3 100644 --- a/tests/integration/channel/simple/mock_channel.go +++ b/tests/integration/channel/simple/mock_channel.go @@ -23,8 +23,7 @@ import ( "k8s.io/kops/pkg/apis/kops" ) -func NewMockChannel() (*kops.Channel, error) { - sourcePath := "simple/channel.yaml" +func NewMockChannel(sourcePath string) (*kops.Channel, error) { sourceBytes, err := ioutil.ReadFile(sourcePath) if err != nil { return nil, fmt.Errorf("unexpected error reading sourcePath %q: %v", sourcePath, err)