Skip to content

Commit

Permalink
Require at least Teleport v15 for tsh (#32776)
Browse files Browse the repository at this point in the history
* Warn if the Teleport version is too low for tsh

* Allow v15 development versions
  • Loading branch information
codingllama authored Sep 29, 2023
1 parent 33cfd9d commit 6797d3d
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 3 deletions.
18 changes: 15 additions & 3 deletions lib/client/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -4155,9 +4155,9 @@ func (tc *TeleportClient) Ping(ctx context.Context) (*webclient.PingResponse, er
return nil, trace.Wrap(err)
}

// If version checking was requested and the server advertises a minimum version.
if tc.CheckVersions && pr.MinClientVersion != "" {
if err := utils.CheckVersion(teleport.Version, pr.MinClientVersion); err != nil && trace.IsBadParameter(err) {
// Verify server->client and client->server compatibility.
if tc.CheckVersions {
if !utils.MeetsVersion(teleport.Version, pr.MinClientVersion) {
fmt.Fprintf(tc.Stderr, `
WARNING
Detected potentially incompatible client and server versions.
Expand All @@ -4166,6 +4166,18 @@ func (tc *TeleportClient) Ping(ctx context.Context) (*webclient.PingResponse, er
Future versions of tsh will fail when incompatible versions are detected.
`, pr.MinClientVersion, teleport.Version, pr.MinClientVersion)
}

// Recent `tsh mfa` changes require at least Teleport v15.
const minServerVersion = "15.0.0-aa" // "-aa" matches all development versions
if !utils.MeetsVersion(pr.ServerVersion, minServerVersion) {
fmt.Fprintf(tc.Stderr, `
WARNING
Detected incompatible client and server versions.
Minimum server version supported by tsh is %v but your server is using %v.
Please use a tsh version that matches your server.
You may use the --skip-version-check flag to bypass this check.
`, minServerVersion, pr.ServerVersion)
}
}

// Update tc with proxy and auth settings specified in Ping response.
Expand Down
2 changes: 2 additions & 0 deletions lib/utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ func TestVersions(t *testing.T) {
for _, testCase := range successTestCases {
t.Run(testCase.info, func(t *testing.T) {
require.NoError(t, CheckVersion(testCase.client, testCase.minClient))
assert.True(t, MeetsVersion(testCase.client, testCase.minClient), "MeetsVersion expected to succeed")
})
}

Expand All @@ -159,6 +160,7 @@ func TestVersions(t *testing.T) {
for _, testCase := range failTestCases {
t.Run(testCase.info, func(t *testing.T) {
fixtures.AssertBadParameter(t, CheckVersion(testCase.client, testCase.minClient))
assert.False(t, MeetsVersion(testCase.client, testCase.minClient), "MeetsVersion expected to fail")
})
}
}
Expand Down
12 changes: 12 additions & 0 deletions lib/utils/ver.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@ import (
"github.com/gravitational/trace"
)

// MeetsVersion returns true if gotVer is empty or at least minVer.
func MeetsVersion(gotVer, minVer string) bool {
if gotVer == "" {
return true // Ignore empty versions.
}

err := CheckVersion(gotVer, minVer)

// Non BadParameter errors are semver parsing errors.
return !trace.IsBadParameter(err)
}

// CheckVersion compares a version with a minimum version supported.
func CheckVersion(currentVersion, minVersion string) error {
currentSemver, minSemver, err := versionStringToSemver(currentVersion, minVersion)
Expand Down
15 changes: 15 additions & 0 deletions lib/utils/ver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,21 @@ package utils

import "testing"

func TestMeetsVersion_emptyOrInvalid(t *testing.T) {
// See TestVersions for more comprehensive tests.

if !MeetsVersion("", "v1.2.3") {
t.Error("MeetsVersion with an empty gotVer should always succeed")
}

if !MeetsVersion("banana", "v1.2.3") {
t.Error("MeetsVersion with an invalid version should always succeed")
}
if !MeetsVersion("v1.2.3", "banana") {
t.Error("MeetsVersion with an invalid version should always succeed")
}
}

func TestMinVerWithoutPreRelease(t *testing.T) {
t.Parallel()

Expand Down

0 comments on commit 6797d3d

Please sign in to comment.