Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cli: add --kubernetes flag to config generate #1226

Merged
merged 1 commit into from
Feb 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 37 additions & 3 deletions cli/internal/cmd/configgenerate.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,18 @@ package cmd

import (
"fmt"
"strings"

"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/compatibility"
"github.com/edgelesssys/constellation/v2/internal/config"
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/file"
"github.com/edgelesssys/constellation/v2/internal/versions"
"github.com/siderolabs/talos/pkg/machinery/config/encoder"
"github.com/spf13/afero"
"github.com/spf13/cobra"
"golang.org/x/mod/semver"
)

func newConfigGenerateCmd() *cobra.Command {
Expand All @@ -31,12 +35,14 @@ func newConfigGenerateCmd() *cobra.Command {
RunE: runConfigGenerate,
}
cmd.Flags().StringP("file", "f", constants.ConfigFilename, "path to output file, or '-' for stdout")
cmd.Flags().StringP("kubernetes", "k", semver.MajorMinor(config.Default().KubernetesVersion), "Kubernetes version to use in format MAJOR.MINOR")

return cmd
}

type generateFlags struct {
file string
file string
k8sVersion string
}

type configGenerateCmd struct {
Expand Down Expand Up @@ -64,6 +70,11 @@ func (cg *configGenerateCmd) configGenerate(cmd *cobra.Command, fileHandler file
cg.log.Debugf("Parsed flags as %v", flags)
cg.log.Debugf("Using cloud provider %s", provider.String())
conf := createConfig(provider)
extendedVersion := config.K8sVersionFromMajorMinor(flags.k8sVersion)
if extendedVersion == "" {
return fmt.Errorf("kubernetes (%s) does not specify a valid Kubernetes version. Supported versions: %s", strings.TrimPrefix(flags.k8sVersion, "v"), supportedVersions())
}
conf.KubernetesVersion = extendedVersion
if flags.file == "-" {
content, err := encoder.NewEncoder(conf).Encode()
if err != nil {
Expand Down Expand Up @@ -101,13 +112,36 @@ func createConfig(provider cloudprovider.Provider) *config.Config {
return conf
}

// supportedVersions prints the supported version without v prefix and without patch version.
// Should only be used when accepting Kubernetes versions from --kubernetes.
func supportedVersions() string {
builder := strings.Builder{}
for i, version := range versions.SupportedK8sVersions() {
if i > 0 {
builder.WriteString(" ")
}
builder.WriteString(strings.TrimPrefix(semver.MajorMinor(version), "v"))
}
return builder.String()
}

func parseGenerateFlags(cmd *cobra.Command) (generateFlags, error) {
file, err := cmd.Flags().GetString("file")
if err != nil {
return generateFlags{}, fmt.Errorf("parsing config generate flags: %w", err)
return generateFlags{}, fmt.Errorf("parsing file flag: %w", err)
}
k8sVersion, err := cmd.Flags().GetString("kubernetes")
if err != nil {
return generateFlags{}, fmt.Errorf("parsing kuberentes flag: %w", err)
}
prefixedVersion := compatibility.EnsurePrefixV(k8sVersion)
if !semver.IsValid(prefixedVersion) {
return generateFlags{}, fmt.Errorf("kubernetes flag does not specify a valid semantic version: %s", k8sVersion)
}

return generateFlags{
file: file,
file: file,
k8sVersion: prefixedVersion,
}, nil
}

Expand Down
42 changes: 42 additions & 0 deletions cli/internal/cmd/configgenerate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,54 @@ import (
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/file"
"github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/versions"
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/mod/semver"
"gopkg.in/yaml.v3"
)

func TestConfigGenerateKubernetesVersion(t *testing.T) {
testCases := map[string]struct {
version string
wantErr bool
}{
"success": {
version: semver.MajorMinor(string(versions.Default)),
},
"no semver": {
version: "asdf",
wantErr: true,
},
"not supported": {
version: "1111",
wantErr: true,
},
}

for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
assert := assert.New(t)
require := require.New(t)

fileHandler := file.NewHandler(afero.NewMemMapFs())
cmd := newConfigGenerateCmd()
err := cmd.Flags().Set("kubernetes", tc.version)
require.NoError(err)

cg := &configGenerateCmd{log: logger.NewTest(t)}
err = cg.configGenerate(cmd, fileHandler, cloudprovider.Unknown)

if tc.wantErr {
assert.Error(err)
return
}
assert.NoError(err)
})
}
}

func TestConfigGenerateDefault(t *testing.T) {
assert := assert.New(t)
require := require.New(t)
Expand Down
32 changes: 24 additions & 8 deletions internal/config/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,19 +319,35 @@ func (c *Config) validateK8sVersion(fl validator.FieldLevel) bool {
if !semver.IsValid(configVersion) {
return false
}
var extendedVersion string
switch semver.MajorMinor(configVersion) {

extendedVersion := K8sVersionFromMajorMinor(semver.MajorMinor(configVersion))
if extendedVersion == "" {
return false
}

valid := versions.IsSupportedK8sVersion(extendedVersion)
if !valid {
return false
}

c.KubernetesVersion = extendedVersion
return true
}

// K8sVersionFromMajorMinor takes a semver in format MAJOR.MINOR
// and returns the version in format MAJOR.MINOR.PATCH with the
// supported patch version as PATCH.
func K8sVersionFromMajorMinor(version string) string {
switch version {
case semver.MajorMinor(string(versions.V1_24)):
extendedVersion = string(versions.V1_24)
return string(versions.V1_24)
case semver.MajorMinor(string(versions.V1_25)):
extendedVersion = string(versions.V1_25)
return string(versions.V1_25)
case semver.MajorMinor(string(versions.V1_26)):
extendedVersion = string(versions.V1_26)
return string(versions.V1_26)
default:
return false
return ""
}
c.KubernetesVersion = extendedVersion
return versions.IsSupportedK8sVersion(extendedVersion)
}

func registerVersionCompatibilityError(ut ut.Translator) error {
Expand Down