Skip to content

Commit

Permalink
feat(cli): warning message if cli and operator not compatible
Browse files Browse the repository at this point in the history
* Compare client and operator version and send a warning message if major/minor differ
* Added a command annotation to apply comparison only to certain commands

Closes #1652
  • Loading branch information
squakez committed Jan 14, 2021
1 parent 89503f6 commit e177158
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 9 deletions.
3 changes: 3 additions & 0 deletions pkg/cmd/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ func newCmdDebug(rootCmdOptions *RootCmdOptions) (*cobra.Command, *debugCmdOptio
Args: options.validateArgs,
PreRunE: decode(&options),
RunE: options.run,
Annotations: map[string]string{
versionCompatibilityWarningCommandLabel: "true",
},
}

cmd.Flags().Bool("suspend", true, "Suspend the integration on startup, to let the debugger attach from the beginning")
Expand Down
3 changes: 3 additions & 0 deletions pkg/cmd/kit_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ func newKitCreateCmd(rootCmdOptions *RootCmdOptions) (*cobra.Command, *kitCreate
Args: options.validateArgs,
PreRunE: decode(&options),
RunE: options.run,
Annotations: map[string]string{
versionCompatibilityWarningCommandLabel: "true",
},
}

cmd.Flags().String("image", "", "Image used to create the kit")
Expand Down
50 changes: 42 additions & 8 deletions pkg/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,18 @@ package cmd

import (
"context"
"fmt"
"os"
"strings"

"github.com/Masterminds/semver"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/viper"

"github.com/apache/camel-k/pkg/client"
camelv1 "github.com/apache/camel-k/pkg/client/camel/clientset/versioned/typed/camel/v1"
"github.com/apache/camel-k/pkg/util/defaults"
)

const kamelCommandLongDescription = `Apache Camel K is a lightweight integration platform, born on Kubernetes, with serverless
Expand Down Expand Up @@ -167,24 +170,55 @@ func addHelpSubCommands(cmd *cobra.Command, options *RootCmdOptions) error {
}

func (command *RootCmdOptions) preRun(cmd *cobra.Command, _ []string) error {
if command.Namespace == "" && !isOfflineCommand(cmd) {
var current string
if !isOfflineCommand(cmd) {
client, err := command.GetCmdClient()
if err != nil {
return errors.Wrap(err, "cannot get command client")
}
current, err = client.GetCurrentNamespace(command.KubeConfig)
if err != nil {
return errors.Wrap(err, "cannot get current namespace")
if command.Namespace == "" {
current, err := client.GetCurrentNamespace(command.KubeConfig)
if err != nil {
return errors.Wrap(err, "cannot get current namespace")
}
err = cmd.Flag("namespace").Value.Set(current)
if err != nil {
return err
}
}
err = cmd.Flag("namespace").Value.Set(current)
if err != nil {
return err
if showCompatibilityWarning(cmd) {
checkAndShowCompatibilityWarning(command.Context, client, command.Namespace)
}
}

return nil
}

func checkAndShowCompatibilityWarning(ctx context.Context, cli client.Client, namespace string) {
operatorVersion, err := operatorVersion(ctx, cli, namespace)
if err != nil {
fmt.Printf("Some issue happened while looking for camel-k operator in namespace %s (error: %s)\n", namespace, err)
} else {
if !compatibleVersions(operatorVersion, defaults.Version) {
fmt.Printf("Warning: you're using Camel K %s client against a %s cluster operator\n", defaults.Version, operatorVersion)
}
}
}

func compatibleVersions(aVersion, bVersion string) bool {
v1, err := semver.NewVersion(aVersion)
if err != nil {
fmt.Printf("Could not parse %s (error: %s)\n", v1, err)
return false
}
v2, err := semver.NewVersion(bVersion)
if err != nil {
fmt.Printf("Could not parse %s (error: %s)\n", v2, err)
return false
}
// We consider compatible when major and minor are equals
return v1.Major() == v2.Major() && v1.Minor() == v2.Minor()
}

// GetCmdClient returns the client that can be used from command line tools
func (command *RootCmdOptions) GetCmdClient() (client.Client, error) {
// Get the pre-computed client
Expand Down
11 changes: 11 additions & 0 deletions pkg/cmd/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/apache/camel-k/pkg/util/test"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
)

func kamelTestPostAddCommandInit(t *testing.T, rootCmd *cobra.Command) {
Expand Down Expand Up @@ -130,3 +131,13 @@ func readViperConfigFromBytes(propertiesFile []byte, t *testing.T) {
t.Fatalf("Unexpected error: %v", unexpectedErr)
}
}

func TestCompatibleVersions(t *testing.T) {
assert.Equal(t, true, compatibleVersions("1.3.0", "1.3.0"))
assert.Equal(t, true, compatibleVersions("1.3.0", "1.3.1"))
assert.Equal(t, true, compatibleVersions("1.3.0", "1.3.0-SNAPSHOT"))
assert.Equal(t, false, compatibleVersions("1.3.0", "1.2.0"))
assert.Equal(t, false, compatibleVersions("1.3.0", "2.3.0"))
assert.Equal(t, false, compatibleVersions("1.3.0", "dsadsa"))
assert.Equal(t, false, compatibleVersions("dsadsa", "1.3.4"))
}
3 changes: 3 additions & 0 deletions pkg/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ func newCmdRun(rootCmdOptions *RootCmdOptions) (*cobra.Command, *runCmdOptions)
PreRunE: options.decode,
RunE: options.run,
PostRunE: options.postRun,
Annotations: map[string]string{
versionCompatibilityWarningCommandLabel: "true",
},
}

cmd.Flags().String("name", "", "The integration name")
Expand Down
7 changes: 6 additions & 1 deletion pkg/cmd/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ import (
)

const (
offlineCommandLabel = "camel.apache.org/cmd.offline"
offlineCommandLabel = "camel.apache.org/cmd.offline"
versionCompatibilityWarningCommandLabel = "camel.apache.org/cmd.versionCompatibilityWarning"
)

// DeleteIntegration --
Expand Down Expand Up @@ -201,6 +202,10 @@ func isOfflineCommand(cmd *cobra.Command) bool {
return cmd.Annotations[offlineCommandLabel] == "true"
}

func showCompatibilityWarning(cmd *cobra.Command) bool {
return cmd.Annotations[versionCompatibilityWarningCommandLabel] == "true"
}

func clone(dst interface{}, src interface{}) error {
if dst == nil {
return fmt.Errorf("dst cannot be nil")
Expand Down

0 comments on commit e177158

Please sign in to comment.