mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-05-02 22:34:56 -04:00
cli: add --kubernetes
flag (#1226)
The flag can be used to specify a Kubernetes version in format MAJOR.MINOR and let the CLI extend the value with the patch version.
This commit is contained in:
parent
477d667360
commit
da7a870f54
3 changed files with 105 additions and 13 deletions
|
@ -8,14 +8,18 @@ package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
"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/config"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/file"
|
"github.com/edgelesssys/constellation/v2/internal/file"
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/versions"
|
||||||
"github.com/siderolabs/talos/pkg/machinery/config/encoder"
|
"github.com/siderolabs/talos/pkg/machinery/config/encoder"
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"golang.org/x/mod/semver"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newConfigGenerateCmd() *cobra.Command {
|
func newConfigGenerateCmd() *cobra.Command {
|
||||||
|
@ -31,12 +35,14 @@ func newConfigGenerateCmd() *cobra.Command {
|
||||||
RunE: runConfigGenerate,
|
RunE: runConfigGenerate,
|
||||||
}
|
}
|
||||||
cmd.Flags().StringP("file", "f", constants.ConfigFilename, "path to output file, or '-' for stdout")
|
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
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
type generateFlags struct {
|
type generateFlags struct {
|
||||||
file string
|
file string
|
||||||
|
k8sVersion string
|
||||||
}
|
}
|
||||||
|
|
||||||
type configGenerateCmd struct {
|
type configGenerateCmd struct {
|
||||||
|
@ -64,6 +70,11 @@ func (cg *configGenerateCmd) configGenerate(cmd *cobra.Command, fileHandler file
|
||||||
cg.log.Debugf("Parsed flags as %v", flags)
|
cg.log.Debugf("Parsed flags as %v", flags)
|
||||||
cg.log.Debugf("Using cloud provider %s", provider.String())
|
cg.log.Debugf("Using cloud provider %s", provider.String())
|
||||||
conf := createConfig(provider)
|
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 == "-" {
|
if flags.file == "-" {
|
||||||
content, err := encoder.NewEncoder(conf).Encode()
|
content, err := encoder.NewEncoder(conf).Encode()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -101,13 +112,36 @@ func createConfig(provider cloudprovider.Provider) *config.Config {
|
||||||
return conf
|
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) {
|
func parseGenerateFlags(cmd *cobra.Command) (generateFlags, error) {
|
||||||
file, err := cmd.Flags().GetString("file")
|
file, err := cmd.Flags().GetString("file")
|
||||||
if err != nil {
|
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{
|
return generateFlags{
|
||||||
file: file,
|
file: file,
|
||||||
|
k8sVersion: prefixedVersion,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,12 +15,54 @@ import (
|
||||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/file"
|
"github.com/edgelesssys/constellation/v2/internal/file"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/versions"
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"golang.org/x/mod/semver"
|
||||||
"gopkg.in/yaml.v3"
|
"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) {
|
func TestConfigGenerateDefault(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
require := require.New(t)
|
require := require.New(t)
|
||||||
|
|
|
@ -327,19 +327,35 @@ func (c *Config) validateK8sVersion(fl validator.FieldLevel) bool {
|
||||||
if !semver.IsValid(configVersion) {
|
if !semver.IsValid(configVersion) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
var extendedVersion string
|
|
||||||
switch semver.MajorMinor(configVersion) {
|
extendedVersion := K8sVersionFromMajorMinor(semver.MajorMinor(configVersion))
|
||||||
case semver.MajorMinor(string(versions.V1_24)):
|
if extendedVersion == "" {
|
||||||
extendedVersion = string(versions.V1_24)
|
|
||||||
case semver.MajorMinor(string(versions.V1_25)):
|
|
||||||
extendedVersion = string(versions.V1_25)
|
|
||||||
case semver.MajorMinor(string(versions.V1_26)):
|
|
||||||
extendedVersion = string(versions.V1_26)
|
|
||||||
default:
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
valid := versions.IsSupportedK8sVersion(extendedVersion)
|
||||||
|
if !valid {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
c.KubernetesVersion = extendedVersion
|
c.KubernetesVersion = extendedVersion
|
||||||
return versions.IsSupportedK8sVersion(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)):
|
||||||
|
return string(versions.V1_24)
|
||||||
|
case semver.MajorMinor(string(versions.V1_25)):
|
||||||
|
return string(versions.V1_25)
|
||||||
|
case semver.MajorMinor(string(versions.V1_26)):
|
||||||
|
return string(versions.V1_26)
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerVersionCompatibilityError(ut ut.Translator) error {
|
func registerVersionCompatibilityError(ut ut.Translator) error {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue