Skip to content

Commit

Permalink
Minimum client version support (#224)
Browse files Browse the repository at this point in the history
  • Loading branch information
majst01 authored Dec 4, 2023
1 parent 1f86825 commit c23c462
Show file tree
Hide file tree
Showing 7 changed files with 301 additions and 586 deletions.
7 changes: 7 additions & 0 deletions cmd/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"strings"
"time"

"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
"github.com/metal-stack/metal-go/api/models"
"github.com/metal-stack/metal-lib/auth"
"github.com/metal-stack/metalctl/pkg/api"
Expand Down Expand Up @@ -143,3 +145,8 @@ func portOpen(ip string, port string, timeout time.Duration) bool {
}
return false
}

func clientNoAuth() runtime.ClientAuthInfoWriterFunc {
noAuth := func(_ runtime.ClientRequest, _ strfmt.Registry) error { return nil }
return runtime.ClientAuthInfoWriterFunc(noAuth)
}
43 changes: 42 additions & 1 deletion cmd/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ import (
"os"
"strings"

"github.com/Masterminds/semver/v3"
"github.com/metal-stack/metal-go/api/client/version"
"github.com/metal-stack/metal-lib/auth"
"github.com/metal-stack/metalctl/pkg/api"
"github.com/metal-stack/v"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
Expand Down Expand Up @@ -62,7 +65,45 @@ func newLoginCmd(c *config) *cobra.Command {

fmt.Fprintln(c.out)

return auth.OIDCFlow(config)
err := auth.OIDCFlow(config)
if err != nil {
return err
}

resp, err := c.client.Version().Info(version.NewInfoParams(), clientNoAuth())
if err != nil {
return err
}
if resp.Payload != nil && resp.Payload.MinClientVersion != nil {
minVersion := *resp.Payload.MinClientVersion
parsedMinVersion, err := semver.NewVersion(minVersion)
if err != nil {
return fmt.Errorf("required metalctl minimum version:%q is not semver parsable:%w", minVersion, err)
}

// This is a developer build
if !strings.HasPrefix(v.Version, "v") {
return nil
}

thisVersion, err := semver.NewVersion(v.Version)
if err != nil {
return fmt.Errorf("metalctl version:%q is not semver parsable:%w", v.Version, err)
}

if thisVersion.LessThan(parsedMinVersion) {
return fmt.Errorf("your metalctl version:%s is smaller than the required minimum version:%s, please run `metalctl update do` to get this version", thisVersion, minVersion)
}

if !thisVersion.Equal(parsedMinVersion) {
fmt.Fprintln(c.out)
fmt.Fprintf(c.out, "WARNING: Your metalctl version %q might not compatible with the metal-api (supported version is %q). Please run `metalctl update do` to update to the supported version.", thisVersion, minVersion)
fmt.Fprintln(c.out)
}
}

return nil

},
}
loginCmd.Flags().Bool("print-only", false, "If true, the token is printed to stdout")
Expand Down
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ metalctl machine list -o template --template "{{ .id }}:{{ .size.id }}"
rootCmd.AddCommand(newWhoamiCmd(c))
rootCmd.AddCommand(newContextCmd(c))
rootCmd.AddCommand(newVPNCmd(c))
rootCmd.AddCommand(newUpdateCmd())
rootCmd.AddCommand(newUpdateCmd(c))

return rootCmd
}
Expand Down
43 changes: 40 additions & 3 deletions cmd/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ package cmd

import (
"github.com/spf13/cobra"
"github.com/spf13/viper"

"github.com/metal-stack/metal-go/api/client/version"
"github.com/metal-stack/metal-lib/pkg/pointer"
"github.com/metal-stack/updater"
)

func newUpdateCmd() *cobra.Command {
func newUpdateCmd(c *config) *cobra.Command {
updateCmd := &cobra.Command{
Use: "update",
Short: "update the program",
Expand All @@ -15,7 +18,11 @@ func newUpdateCmd() *cobra.Command {
Use: "check",
Short: "check for update of the program",
RunE: func(cmd *cobra.Command, args []string) error {
u, err := updater.New("metal-stack", binaryName, binaryName)
desired, err := getMinimumClientVersion(c)
if err != nil {
return err
}
u, err := updater.New("metal-stack", binaryName, binaryName, desired)
if err != nil {
return err
}
Expand All @@ -26,14 +33,44 @@ func newUpdateCmd() *cobra.Command {
Use: "do",
Short: "do the update of the program",
RunE: func(cmd *cobra.Command, args []string) error {
u, err := updater.New("metal-stack", binaryName, binaryName)
var desired *string

if !viper.IsSet("version") {
var err error
desired, err = getMinimumClientVersion(c)
if err != nil {
return err
}
}

if viper.IsSet("version") && viper.GetString("version") != "latest" {
desired = pointer.Pointer(viper.GetString("version"))
}

u, err := updater.New("metal-stack", binaryName, binaryName, desired)
if err != nil {
return err
}

return u.Do()
},
}

updateCmd.Flags().StringP("version", "v", "", `the version to update to, by default updates to the supported version, use "latest" to update to latest version`)

updateCmd.AddCommand(updateCheckCmd)
updateCmd.AddCommand(updateDoCmd)

return updateCmd
}

func getMinimumClientVersion(c *config) (*string, error) {
resp, err := c.client.Version().Info(version.NewInfoParams(), clientNoAuth())
if err != nil {
return nil, err
}
if resp.Payload != nil && resp.Payload.MinClientVersion != nil {
return resp.Payload.MinClientVersion, nil
}
return nil, nil
}
3 changes: 2 additions & 1 deletion docs/metalctl_update.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ update the program
### Options

```
-h, --help help for update
-h, --help help for update
-v, --version string the version to update to
```

### Options inherited from parent commands
Expand Down
Loading

0 comments on commit c23c462

Please sign in to comment.