diff --git a/pkg/cmd/version/skew_warning.go b/pkg/cmd/version/skew_warning.go index 3b9d0101..2f3a2bf2 100644 --- a/pkg/cmd/version/skew_warning.go +++ b/pkg/cmd/version/skew_warning.go @@ -18,10 +18,10 @@ package version import ( "fmt" - "io" + "math" + "k8s.io/apimachinery/pkg/util/version" apimachineryversion "k8s.io/apimachinery/pkg/version" - "math" ) // supportedMinorVersionSkew is the maximum supported difference between the client and server minor versions. @@ -29,26 +29,26 @@ import ( // and server versions 1.18, 1.19, and 1.20 would be within the supported version skew for client version 1.19. const supportedMinorVersionSkew = 1 -// printVersionSkewWarning prints a warning message if the difference between the client and version is greater than +// getVersionSkewWarning returns a warning message if the difference between the client and version is greater than // the supported version skew. -func printVersionSkewWarning(w io.Writer, clientVersion, serverVersion apimachineryversion.Info) error { +func getVersionSkewWarning(clientVersion, serverVersion apimachineryversion.Info) (string, error) { parsedClientVersion, err := version.ParseSemantic(clientVersion.GitVersion) if err != nil { - return err + return "", fmt.Errorf("client version error: %w", err) } parsedServerVersion, err := version.ParseSemantic(serverVersion.GitVersion) if err != nil { - return err + return "", fmt.Errorf("server version error: %w", err) } majorVersionDifference := math.Abs(float64(parsedClientVersion.Major()) - float64(parsedServerVersion.Major())) minorVersionDifference := math.Abs(float64(parsedClientVersion.Minor()) - float64(parsedServerVersion.Minor())) if majorVersionDifference > 0 || minorVersionDifference > supportedMinorVersionSkew { - fmt.Fprintf(w, "WARNING: version difference between client (%d.%d) and server (%d.%d) exceeds the supported minor version skew of +/-%d\n", + warningMessage := fmt.Sprintf("version difference between client (%d.%d) and server (%d.%d) exceeds the supported minor version skew of +/-%d", parsedClientVersion.Major(), parsedClientVersion.Minor(), parsedServerVersion.Major(), parsedServerVersion.Minor(), supportedMinorVersionSkew) + return warningMessage, nil } - - return nil + return "", nil } diff --git a/pkg/cmd/version/skew_warning_test.go b/pkg/cmd/version/skew_warning_test.go index 778bdfc7..02ac19c6 100644 --- a/pkg/cmd/version/skew_warning_test.go +++ b/pkg/cmd/version/skew_warning_test.go @@ -17,14 +17,12 @@ limitations under the License. package version import ( - "bytes" - apimachineryversion "k8s.io/apimachinery/pkg/version" "testing" + + apimachineryversion "k8s.io/apimachinery/pkg/version" ) func TestPrintVersionSkewWarning(t *testing.T) { - output := &bytes.Buffer{} - testCases := []struct { name string clientVersion apimachineryversion.Info @@ -82,14 +80,15 @@ func TestPrintVersionSkewWarning(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - output.Reset() + warningMessage, err := getVersionSkewWarning(tc.clientVersion, tc.serverVersion) + if err != nil { + t.Errorf("error: %s", err) + } - printVersionSkewWarning(output, tc.clientVersion, tc.serverVersion) - - if tc.isWarningExpected && output.Len() == 0 { - t.Error("warning was expected, but not written to the output") - } else if !tc.isWarningExpected && output.Len() > 0 { - t.Errorf("warning was not expected, but was written to the output: %s", output.String()) + if tc.isWarningExpected && warningMessage == "" { + t.Error("warning was expected") + } else if !tc.isWarningExpected && warningMessage != "" { + t.Errorf("warning was not expected. but got %s", warningMessage) } }) } diff --git a/pkg/cmd/version/version.go b/pkg/cmd/version/version.go index 996fee8f..9617055c 100644 --- a/pkg/cmd/version/version.go +++ b/pkg/cmd/version/version.go @@ -53,8 +53,9 @@ var ( // Options is a struct to support version command type Options struct { - ClientOnly bool - Output string + ClientOnly bool + Output string + WarningsAsErrors bool args []string @@ -93,6 +94,9 @@ func NewCmdVersion(f cmdutil.Factory, ioStreams genericiooptions.IOStreams) *cob // Complete completes all the required options func (o *Options) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { var err error + + o.WarningsAsErrors = cmd.Flags().Lookup("warnings-as-errors").Value.String() == "true" + if o.ClientOnly { return nil } @@ -162,11 +166,17 @@ func (o *Options) Run() error { } if versionInfo.ServerVersion != nil { - if err := printVersionSkewWarning(o.ErrOut, *versionInfo.ClientVersion, *versionInfo.ServerVersion); err != nil { + warningMessage, err := getVersionSkewWarning(*versionInfo.ClientVersion, *versionInfo.ServerVersion) + if err != nil { return err } + if warningMessage != "" { + if o.WarningsAsErrors { + return errors.New(warningMessage) + } + fmt.Fprintf(o.ErrOut, "Warning: %s\n", warningMessage) //nolint:errcheck + } } - return serverErr } diff --git a/pkg/cmd/version/version_test.go b/pkg/cmd/version/version_test.go index 7bbd87fe..606a1af3 100644 --- a/pkg/cmd/version/version_test.go +++ b/pkg/cmd/version/version_test.go @@ -20,8 +20,6 @@ import ( "strings" "testing" - "github.com/spf13/cobra" - "k8s.io/cli-runtime/pkg/genericiooptions" cmdtesting "k8s.io/kubectl/pkg/cmd/testing" @@ -32,13 +30,18 @@ func TestNewCmdVersionClientVersion(t *testing.T) { defer tf.Cleanup() streams, _, buf, _ := genericiooptions.NewTestIOStreams() o := NewOptions(streams) - if err := o.Complete(tf, &cobra.Command{}, nil); err != nil { + + cmd := NewCmdVersion(tf, streams) + cmd.Flags().Bool("warnings-as-errors", false, "") + + if err := o.Complete(tf, cmd, nil); err != nil { t.Errorf("Unexpected error: %v", err) } if err := o.Validate(); err != nil { t.Errorf("Unexpected error: %v", err) } - if err := o.Complete(tf, &cobra.Command{}, []string{"extraParameter0"}); err != nil { + + if err := o.Complete(tf, cmd, []string{"extraParameter0"}); err != nil { t.Errorf("Unexpected error: %v", err) } if err := o.Validate(); !strings.Contains(err.Error(), "extra arguments") {