InstallScripts: pin teleport version using ServerVersion (#28149)

* InstallScripts: pin teleport version using ServerVersion

When Automatic Upgrades are enabled and the current installation is an
enterprise build, it will install teleport using:
- stable/cloud repo channel (yum, apt)
- pin the version to the one present at:
  https://updates.releases.teleport.dev/v1/stable/cloud/version

* improve comments
This commit is contained in:
Marco André Dinis
2023-06-23 15:45:36 +00:00
committed by GitHub
parent 2593843c6f
commit 48a113bb93
12 changed files with 393 additions and 108 deletions
+3 -8
View File
@@ -28,15 +28,10 @@ on_azure() {
PACKAGE_LIST="${PACKAGE_LIST} {{ .TeleportPackage }}-updater"
fi
# old versions of ubuntu require that keys get added by `apt-key add`, without
# adding the key apt shows a key signing error when installing teleport.
LEGACY_UBUNTU=false
if [ "$VERSION_CODENAME" = "xenial" ] || [ "$VERSION_CODENAME" = "trusty" ]; then
LEGACY_UBUNTU=true
fi
if [ "$ID" = "debian" ] || [ "$ID" = "ubuntu" ]; then
if [ "$LEGACY_UBUNTU" = true ]; then
# old versions of ubuntu require that keys get added by `apt-key add`, without
# adding the key apt shows a key signing error when installing teleport.
if [ "$VERSION_CODENAME" = "xenial" ] || [ "$VERSION_CODENAME" = "trusty" ]; then
curl -o /tmp/teleport-pubkey.asc https://apt.releases.teleport.dev/gpg
sudo apt-key add /tmp/teleport-pubkey.asc
echo "deb https://apt.releases.teleport.dev/ubuntu ${VERSION_CODENAME?} {{ .RepoChannel }}" | sudo tee /etc/apt/sources.list.d/teleport.list
+75
View File
@@ -0,0 +1,75 @@
/*
Copyright 2023 Gravitational, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package automaticupgrades
import (
"context"
"net/http"
"net/url"
"strings"
"github.com/gravitational/trace"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/lib/utils"
)
const (
// stableCloudVersionBaseURL is the base URL for the server that returns the current stable/cloud version.
stableCloudVersionBaseURL = "https://updates.releases.teleport.dev"
// stableCloudVersionPath is the URL path that returns the current stable/cloud version.
stableCloudVersionPath = "/v1/stable/cloud/version"
)
// Version returns the version that should be used for installing Teleport Services
// This is used when installing agents using scripts.
// Even when Teleport Auth/Proxy is using vX, the agents must always respect this version.
func Version(ctx context.Context, baseURL string) (string, error) {
if baseURL == "" {
baseURL = stableCloudVersionBaseURL
}
fullURL, err := url.JoinPath(baseURL, stableCloudVersionPath)
if err != nil {
return "", trace.Wrap(err)
}
req, err := http.NewRequestWithContext(ctx, http.MethodGet, fullURL, nil)
if err != nil {
return "", trace.Wrap(err)
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return "", trace.Wrap(err)
}
defer resp.Body.Close()
body, err := utils.ReadAtMost(resp.Body, teleport.MaxHTTPResponseSize)
if err != nil {
return "", trace.Wrap(err)
}
if resp.StatusCode != http.StatusOK {
return "", trace.BadParameter("invalid status code %d, body: %s", resp.StatusCode, string(body))
}
versionString := strings.TrimSpace(string(body))
return versionString, trace.Wrap(err)
}
+86
View File
@@ -0,0 +1,86 @@
/*
Copyright 2023 Gravitational, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package automaticupgrades
import (
"context"
"net/http"
"net/http/httptest"
"testing"
"github.com/gravitational/trace"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestVersion(t *testing.T) {
ctx := context.Background()
isBadParameterErr := func(tt require.TestingT, err error, i ...interface{}) {
require.True(tt, trace.IsBadParameter(err), "expected bad parameter, got %v", err)
}
for _, tt := range []struct {
name string
mockStatusCode int
mockResponseString string
errCheck require.ErrorAssertionFunc
expectedVersion string
}{
{
name: "real response",
mockStatusCode: http.StatusOK,
mockResponseString: "v13.1.1\n",
errCheck: require.NoError,
expectedVersion: "v13.1.1",
},
{
name: "invalid status code (500)",
mockStatusCode: http.StatusInternalServerError,
errCheck: isBadParameterErr,
},
{
name: "invalid status code (403)",
mockStatusCode: http.StatusForbidden,
errCheck: isBadParameterErr,
},
{
name: "valid but has spaces",
mockStatusCode: http.StatusOK,
mockResponseString: " v13.1.1 \n \r\n",
errCheck: require.NoError,
expectedVersion: "v13.1.1",
},
} {
t.Run(tt.name, func(t *testing.T) {
httpTestServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, r.URL.Path, "/v1/stable/cloud/version")
w.WriteHeader(tt.mockStatusCode)
w.Write([]byte(tt.mockResponseString))
}))
defer httpTestServer.Close()
v, err := Version(ctx, httpTestServer.URL)
tt.errCheck(t, err)
if err != nil {
return
}
require.Equal(t, v, tt.expectedVersion)
})
}
}
-6
View File
@@ -42,7 +42,6 @@ import (
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/api/constants"
apiutils "github.com/gravitational/teleport/api/utils"
"github.com/gravitational/teleport/lib/modules"
)
// WriteContextCloser provides close method with context
@@ -506,11 +505,6 @@ func ReadOrMakeHostUUID(dataDir string) (string, error) {
return id, nil
}
// PrintVersion prints human readable version
func PrintVersion() {
modules.GetModules().PrintVersion()
}
// StringSliceSubset returns true if b is a subset of a.
func StringSliceSubset(a []string, b []string) error {
aset := make(map[string]bool)
+6 -6
View File
@@ -1702,20 +1702,20 @@ func (h *Handler) installer(w http.ResponseWriter, r *http.Request, p httprouter
// By default, it uses the stable/v<majorVersion> channel.
repoChannel := fmt.Sprintf("stable/%s", version)
// For Teleport Cloud installations, use the `stable/cloud` channel.
if feats.Cloud {
// If the updater must be installed, then change the repo to stable/cloud
// It must also install the version specified in
// https://updates.releases.teleport.dev/v1/stable/cloud/version
installUpdater := automaticUpgrades(h.ClusterFeatures)
if installUpdater {
repoChannel = stableCloudChannelRepo
}
// TODO(marco): remove BuildType check when teleport-upgrade (oss) package is available in apt/yum repos.
automaticUpgrades := feats.AutomaticUpgrades && modules.GetModules().BuildType() == modules.BuildEnterprise
tmpl := installers.Template{
PublicProxyAddr: h.PublicProxyAddr(),
MajorVersion: version,
TeleportPackage: teleportPackage,
RepoChannel: repoChannel,
AutomaticUpgrades: strconv.FormatBool(automaticUpgrades),
AutomaticUpgrades: strconv.FormatBool(installUpdater),
}
err = instTmpl.Execute(w, tmpl)
return nil, trace.Wrap(err)
+145 -35
View File
@@ -2539,43 +2539,43 @@ func TestPingAutomaticUpgrades(t *testing.T) {
// TestInstallerRepoChannel ensures the returned installer script has the proper repo channel
func TestInstallerRepoChannel(t *testing.T) {
s := newWebSuiteWithConfig(t, webSuiteConfig{
authPreferenceSpec: &types.AuthPreferenceSpecV2{
Type: constants.Local,
SecondFactor: constants.SecondFactorOn,
Webauthn: &types.Webauthn{RPID: "localhost"},
},
})
t.Run("cloud with automatic upgrades", func(t *testing.T) {
modules.SetTestModules(t, &modules.TestModules{
TestFeatures: modules.Features{
Cloud: true,
AutomaticUpgrades: true,
},
})
wc := s.client(t)
t.Run("documented variables are injected", func(t *testing.T) {
// Variables documented here: https://goteleport.com/docs/server-access/guides/ec2-discovery/#step-67-optional-customize-the-default-installer-script
err := s.server.Auth().SetInstaller(s.ctx, types.MustNewInstallerV1("custom", `#!/usr/bin/env bash
s := newWebSuiteWithConfig(t, webSuiteConfig{
authPreferenceSpec: &types.AuthPreferenceSpecV2{
Type: constants.Local,
SecondFactor: constants.SecondFactorOn,
Webauthn: &types.Webauthn{RPID: "localhost"},
},
})
wc := s.client(t)
t.Run("documented variables are injected", func(t *testing.T) {
// Variables documented here: https://goteleport.com/docs/server-access/guides/ec2-discovery/#step-67-optional-customize-the-default-installer-script
err := s.server.Auth().SetInstaller(s.ctx, types.MustNewInstallerV1("custom", `#!/usr/bin/env bash
echo {{ .PublicProxyAddr }}
echo Teleport-{{ .MajorVersion }}
echo Repository Channel: {{ .RepoChannel }}
echo AutomaticUpgrades: {{ .AutomaticUpgrades }}
`))
require.NoError(t, err)
require.NoError(t, err)
re, err := wc.Get(s.ctx, wc.Endpoint("webapi", "scripts", "installer", "custom"), url.Values{})
require.NoError(t, err)
re, err := wc.Get(s.ctx, wc.Endpoint("webapi", "scripts", "installer", "custom"), url.Values{})
require.NoError(t, err)
responseString := string(re.Bytes())
responseString := string(re.Bytes())
// Variables must be injected
require.Contains(t, responseString, "echo Teleport-v")
require.Contains(t, responseString, "echo Repository Channel: stable/v")
require.NotContains(t, responseString, "echo Repository Channel: stable/cloud")
require.Contains(t, responseString, "echo AutomaticUpgrades: false")
})
t.Run("cloud with automatic upgrades", func(t *testing.T) {
modules.SetTestModules(t, &modules.TestModules{
TestBuildType: modules.BuildEnterprise,
TestFeatures: modules.Features{
Cloud: true,
AutomaticUpgrades: true,
},
// Variables must be injected
require.Contains(t, responseString, "echo Teleport-v")
require.NotContains(t, responseString, "echo Repository Channel: stable/v")
require.Contains(t, responseString, "echo Repository Channel: stable/cloud")
require.Contains(t, responseString, "echo AutomaticUpgrades: true")
})
t.Run("default-installer", func(t *testing.T) {
@@ -2595,6 +2595,7 @@ echo AutomaticUpgrades: {{ .AutomaticUpgrades }}
" fi",
)
})
t.Run("default-agentless-installer", func(t *testing.T) {
re, err := wc.Get(s.ctx, wc.Endpoint("webapi", "scripts", "installer", "default-agentless-installer"), url.Values{})
require.NoError(t, err)
@@ -2613,19 +2614,53 @@ echo AutomaticUpgrades: {{ .AutomaticUpgrades }}
)
})
})
t.Run("cloud without automatic upgrades", func(t *testing.T) {
modules.SetTestModules(t, &modules.TestModules{TestFeatures: modules.Features{
Cloud: true,
AutomaticUpgrades: false,
}})
t.Run("cloud without automatic upgrades", func(t *testing.T) {
modules.SetTestModules(t, &modules.TestModules{
TestFeatures: modules.Features{
Cloud: true,
AutomaticUpgrades: false,
},
})
s := newWebSuiteWithConfig(t, webSuiteConfig{
authPreferenceSpec: &types.AuthPreferenceSpecV2{
Type: constants.Local,
SecondFactor: constants.SecondFactorOn,
Webauthn: &types.Webauthn{RPID: "localhost"},
},
})
wc := s.client(t)
t.Run("documented variables are injected", func(t *testing.T) {
// Variables documented here: https://goteleport.com/docs/server-access/guides/ec2-discovery/#step-67-optional-customize-the-default-installer-script
err := s.server.Auth().SetInstaller(s.ctx, types.MustNewInstallerV1("custom", `#!/usr/bin/env bash
echo {{ .PublicProxyAddr }}
echo Teleport-{{ .MajorVersion }}
echo Repository Channel: {{ .RepoChannel }}
echo AutomaticUpgrades: {{ .AutomaticUpgrades }}
`))
require.NoError(t, err)
re, err := wc.Get(s.ctx, wc.Endpoint("webapi", "scripts", "installer", "custom"), url.Values{})
require.NoError(t, err)
responseString := string(re.Bytes())
// Variables must be injected
require.Contains(t, responseString, "echo Teleport-v")
require.Contains(t, responseString, "echo Repository Channel: stable/v")
require.NotContains(t, responseString, "echo Repository Channel: stable/cloud")
require.Contains(t, responseString, "echo AutomaticUpgrades: false")
})
t.Run("default-installer", func(t *testing.T) {
re, err := wc.Get(s.ctx, wc.Endpoint("webapi", "scripts", "installer", "default-installer"), url.Values{})
require.NoError(t, err)
responseString := string(re.Bytes())
require.Contains(t, responseString, "stable/cloud")
require.NotContains(t, responseString, "stable/cloud")
})
t.Run("default-agentless-installer", func(t *testing.T) {
re, err := wc.Get(s.ctx, wc.Endpoint("webapi", "scripts", "installer", "default-agentless-installer"), url.Values{})
@@ -2633,7 +2668,82 @@ echo AutomaticUpgrades: {{ .AutomaticUpgrades }}
responseString := string(re.Bytes())
require.Contains(t, responseString, "stable/cloud")
require.NotContains(t, responseString, "stable/cloud")
})
})
t.Run("oss or enterprise with automatic upgrades", func(t *testing.T) {
modules.SetTestModules(t, &modules.TestModules{
TestBuildType: modules.BuildOSS,
TestFeatures: modules.Features{
Cloud: false,
AutomaticUpgrades: true,
},
})
s := newWebSuiteWithConfig(t, webSuiteConfig{
authPreferenceSpec: &types.AuthPreferenceSpecV2{
Type: constants.Local,
SecondFactor: constants.SecondFactorOn,
Webauthn: &types.Webauthn{RPID: "localhost"},
},
})
wc := s.client(t)
t.Run("documented variables are injected", func(t *testing.T) {
// Variables documented here: https://goteleport.com/docs/server-access/guides/ec2-discovery/#step-67-optional-customize-the-default-installer-script
err := s.server.Auth().SetInstaller(s.ctx, types.MustNewInstallerV1("custom", `#!/usr/bin/env bash
echo {{ .PublicProxyAddr }}
echo Teleport-{{ .MajorVersion }}
echo Repository Channel: {{ .RepoChannel }}
echo AutomaticUpgrades: {{ .AutomaticUpgrades }}
`))
require.NoError(t, err)
re, err := wc.Get(s.ctx, wc.Endpoint("webapi", "scripts", "installer", "custom"), url.Values{})
require.NoError(t, err)
responseString := string(re.Bytes())
// Variables must be injected
require.Contains(t, responseString, "echo Teleport-v")
require.Contains(t, responseString, "echo Repository Channel: stable/v")
require.NotContains(t, responseString, "echo Repository Channel: stable/cloud")
require.Contains(t, responseString, "echo AutomaticUpgrades: false")
})
t.Run("default-installer", func(t *testing.T) {
re, err := wc.Get(s.ctx, wc.Endpoint("webapi", "scripts", "installer", "default-installer"), url.Values{})
require.NoError(t, err)
responseString := string(re.Bytes())
// The repo's channel to use is stable/cloud
require.NotContains(t, responseString, "stable/cloud")
require.Contains(t, responseString, "stable/v")
require.Contains(t, responseString, ""+
" PACKAGE_LIST=\"teleport jq\"\n"+
" # shellcheck disable=SC2050\n"+
" if [ \"false\" = \"true\" ]; then\n"+
" PACKAGE_LIST=\"${PACKAGE_LIST} teleport-updater\"\n"+
" fi",
)
})
t.Run("default-agentless-installer", func(t *testing.T) {
re, err := wc.Get(s.ctx, wc.Endpoint("webapi", "scripts", "installer", "default-agentless-installer"), url.Values{})
require.NoError(t, err)
responseString := string(re.Bytes())
// The repo's channel to use is stable/cloud
require.NotContains(t, responseString, "stable/cloud")
require.Contains(t, responseString, "stable/v")
require.Contains(t, responseString, ""+
" PACKAGE_LIST=\"jq teleport\"\n"+
" # shellcheck disable=SC2050\n"+
" if [[ \"false\" == \"true\" ]]; then\n"+
" PACKAGE_LIST=\"${PACKAGE_LIST} teleport-updater\"\n"+
" fi\n",
)
})
})
}
+37 -27
View File
@@ -40,6 +40,7 @@ import (
"github.com/gravitational/teleport/api/types"
apiutils "github.com/gravitational/teleport/api/utils"
"github.com/gravitational/teleport/lib/auth"
"github.com/gravitational/teleport/lib/automaticupgrades"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/httplib"
"github.com/gravitational/teleport/lib/modules"
@@ -71,20 +72,22 @@ type nodeJoinToken struct {
// scriptSettings is used to hold values which are passed into the function that
// generates the join script.
type scriptSettings struct {
token string
appInstallMode bool
appName string
appURI string
joinMethod string
databaseInstallMode bool
stableCloudChannelRepo bool
installUpdater bool
token string
appInstallMode bool
appName string
appURI string
joinMethod string
databaseInstallMode bool
installUpdater bool
// automaticUpgradesVersionBaseURL is the base URL for getting the version when using the cloud/stable channel.
// Optional.
automaticUpgradesVersionBaseURL string
}
// automaticUpgrades returns whether automaticUpgrades should be enabled.
func automaticUpgrades(features proto.Features) bool {
// TODO(marco): remove BuildType check when teleport-updater (oss) package is available in apt/yum repos.
return features.AutomaticUpgrades && modules.GetModules().BuildType() == modules.BuildEnterprise
return features.AutomaticUpgrades && features.Cloud
}
func (h *Handler) createTokenHandle(w http.ResponseWriter, r *http.Request, params httprouter.Params, ctx *SessionContext) (interface{}, error) {
@@ -210,11 +213,10 @@ func (h *Handler) getNodeJoinScriptHandle(w http.ResponseWriter, r *http.Request
scripts.SetScriptHeaders(w.Header())
settings := scriptSettings{
token: params.ByName("token"),
appInstallMode: false,
joinMethod: r.URL.Query().Get("method"),
stableCloudChannelRepo: h.ClusterFeatures.Cloud,
installUpdater: automaticUpgrades(h.ClusterFeatures),
token: params.ByName("token"),
appInstallMode: false,
joinMethod: r.URL.Query().Get("method"),
installUpdater: automaticUpgrades(h.ClusterFeatures),
}
script, err := getJoinScript(r.Context(), settings, h.GetProxyClient())
@@ -252,12 +254,11 @@ func (h *Handler) getAppJoinScriptHandle(w http.ResponseWriter, r *http.Request,
}
settings := scriptSettings{
token: params.ByName("token"),
appInstallMode: true,
appName: name,
appURI: uri,
stableCloudChannelRepo: h.ClusterFeatures.Cloud,
installUpdater: automaticUpgrades(h.ClusterFeatures),
token: params.ByName("token"),
appInstallMode: true,
appName: name,
appURI: uri,
installUpdater: automaticUpgrades(h.ClusterFeatures),
}
script, err := getJoinScript(r.Context(), settings, h.GetProxyClient())
@@ -280,10 +281,9 @@ func (h *Handler) getDatabaseJoinScriptHandle(w http.ResponseWriter, r *http.Req
scripts.SetScriptHeaders(w.Header())
settings := scriptSettings{
token: params.ByName("token"),
databaseInstallMode: true,
stableCloudChannelRepo: h.ClusterFeatures.Cloud,
installUpdater: automaticUpgrades(h.ClusterFeatures),
token: params.ByName("token"),
databaseInstallMode: true,
installUpdater: automaticUpgrades(h.ClusterFeatures),
}
script, err := getJoinScript(r.Context(), settings, h.GetProxyClient())
@@ -392,9 +392,19 @@ func getJoinScript(ctx context.Context, settings scriptSettings, m nodeAPIGetter
// By default, it will use `stable/v<majorVersion>`, eg stable/v12
repoChannel := ""
// For Teleport Cloud installations, use the `stable/cloud` channel.
if settings.stableCloudChannelRepo {
// The install script will install the updater (teleport-ent-updater) for Cloud customers enrolled in Automatic Upgrades.
// The repo channel used must be `stable/cloud` which has the available packages for the Cloud Customer's agents.
// It pins the teleport version to the one specified by https://updates.releases.teleport.dev/v1/stable/cloud/version
// This ensures the initial installed version is the same as the `teleport-ent-updater` would install.
if settings.installUpdater {
repoChannel = stableCloudChannelRepo
cloudStableVersion, err := automaticupgrades.Version(ctx, settings.automaticUpgradesVersionBaseURL)
if err != nil {
return "", trace.Wrap(err)
}
// cloudStableVersion has vX.Y.Z format, however the script expects the version to not include the `v`
version = strings.TrimPrefix(cloudStableVersion, "v")
}
// This section relies on Go's default zero values to make sure that the settings
+35 -22
View File
@@ -20,12 +20,16 @@ import (
"context"
"encoding/hex"
"fmt"
"net/http"
"net/http/httptest"
"regexp"
"testing"
"github.com/gravitational/trace"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/api/client/proto"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/api/utils"
@@ -873,7 +877,10 @@ func TestJoinScript(t *testing.T) {
mockGetProxyServers: func() ([]types.Server, error) {
return []types.Server{
&types.ServerV2{
Spec: types.ServerSpecV2{PublicAddrs: []string{"test-host:12345678"}},
Spec: types.ServerSpecV2{
PublicAddrs: []string{"test-host:12345678"},
Version: teleport.Version,
},
},
}, nil
},
@@ -926,10 +933,20 @@ func TestJoinScript(t *testing.T) {
})
t.Run("using repo", func(t *testing.T) {
t.Run("installUpdater set to true, list of packages must include updater package", func(t *testing.T) {
script, err := getJoinScript(context.Background(), scriptSettings{token: validToken, installUpdater: true}, m)
t.Run("installUpdater is true", func(t *testing.T) {
currentStableCloudVersion := "v99.1.1"
httpTestServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, r.URL.Path, "/v1/stable/cloud/version")
w.WriteHeader(http.StatusOK)
w.Write([]byte(currentStableCloudVersion))
}))
defer httpTestServer.Close()
script, err := getJoinScript(context.Background(), scriptSettings{token: validToken, installUpdater: true, automaticUpgradesVersionBaseURL: httpTestServer.URL}, m)
require.NoError(t, err)
// list of packages must include the updater
require.Contains(t, script, ""+
" PACKAGE_LIST=${TELEPORT_PACKAGE_PIN_VERSION}\n"+
" # (warning): This expression is constant. Did you forget the $ on a variable?\n"+
@@ -939,11 +956,14 @@ func TestJoinScript(t *testing.T) {
" PACKAGE_LIST+=\" ${TELEPORT_UPDATER_PIN_VERSION}\"\n"+
" fi\n",
)
// Repo channel is stable/cloud
require.Contains(t, script, "REPO_CHANNEL='stable/cloud'")
// TELEPORT_VERSION is the one provided by https://updates.releases.teleport.dev/v1/stable/cloud/version
require.Contains(t, script, "TELEPORT_VERSION='99.1.1'")
})
t.Run("installUpdater set to false, list of packages must not include updater package", func(t *testing.T) {
t.Run("installUpdater is false", func(t *testing.T) {
script, err := getJoinScript(context.Background(), scriptSettings{token: validToken, installUpdater: false}, m)
require.NoError(t, err)
require.Contains(t, script, ""+
" PACKAGE_LIST=${TELEPORT_PACKAGE_PIN_VERSION}\n"+
" # (warning): This expression is constant. Did you forget the $ on a variable?\n"+
@@ -953,26 +973,19 @@ func TestJoinScript(t *testing.T) {
" PACKAGE_LIST+=\" ${TELEPORT_UPDATER_PIN_VERSION}\"\n"+
" fi\n",
)
})
t.Run("using stable/cloud channel", func(t *testing.T) {
script, err := getJoinScript(context.Background(), scriptSettings{token: validToken, stableCloudChannelRepo: true}, m)
require.NoError(t, err)
require.Contains(t, script, "REPO_CHANNEL='stable/cloud'")
})
t.Run("not hard-coding a particular channel", func(t *testing.T) {
script, err := getJoinScript(context.Background(), scriptSettings{token: validToken, stableCloudChannelRepo: false}, m)
require.NoError(t, err)
// Default based on current version is used instead
require.Contains(t, script, "REPO_CHANNEL=''")
// Current version must be used
require.Contains(t, script, fmt.Sprintf("TELEPORT_VERSION='%s'", teleport.Version))
})
})
}
func TestAutomaticUpgrades(t *testing.T) {
t.Run("enterprise and automatic upgrades enabled", func(t *testing.T) {
t.Run("cloud and automatic upgrades enabled", func(t *testing.T) {
modules.SetTestModules(t, &modules.TestModules{
TestBuildType: modules.BuildEnterprise,
TestFeatures: modules.Features{
Cloud: true,
AutomaticUpgrades: true,
},
})
@@ -980,10 +993,10 @@ func TestAutomaticUpgrades(t *testing.T) {
got := automaticUpgrades(*modules.GetModules().Features().ToProto())
require.True(t, got)
})
t.Run("enterprise but automatic upgrades disabled", func(t *testing.T) {
t.Run("cloud but automatic upgrades disabled", func(t *testing.T) {
modules.SetTestModules(t, &modules.TestModules{
TestBuildType: modules.BuildEnterprise,
TestFeatures: modules.Features{
Cloud: true,
AutomaticUpgrades: false,
},
})
@@ -992,12 +1005,12 @@ func TestAutomaticUpgrades(t *testing.T) {
require.False(t, got)
})
// There's no `teleport-updater` (oss) package yet, so even if automatic upgrades are enabled it must return false.
t.Run("automatic upgrades enabled but build is OSS", func(t *testing.T) {
t.Run("automatic upgrades enabled but is not cloud", func(t *testing.T) {
modules.SetTestModules(t, &modules.TestModules{
TestBuildType: modules.BuildEnterprise,
TestFeatures: modules.Features{
AutomaticUpgrades: false,
Cloud: false,
AutomaticUpgrades: true,
},
})
+2 -1
View File
@@ -32,6 +32,7 @@ import (
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/modules"
"github.com/gravitational/teleport/lib/tbot"
"github.com/gravitational/teleport/lib/tbot/config"
"github.com/gravitational/teleport/lib/utils"
@@ -179,7 +180,7 @@ func Run(args []string, stdout io.Writer) error {
}
func onVersion() error {
utils.PrintVersion()
modules.GetModules().PrintVersion()
return nil
}
+2 -1
View File
@@ -39,6 +39,7 @@ import (
"github.com/gravitational/teleport/lib/client/identityfile"
"github.com/gravitational/teleport/lib/config"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/modules"
"github.com/gravitational/teleport/lib/service/servicecfg"
"github.com/gravitational/teleport/lib/utils"
"github.com/gravitational/teleport/tool/common"
@@ -176,7 +177,7 @@ func TryRun(commands []CLICommand, args []string) error {
// "version" command?
if selectedCmd == ver.FullCommand() {
utils.PrintVersion()
modules.GetModules().PrintVersion()
return nil
}
+1 -1
View File
@@ -501,7 +501,7 @@ func Run(options Options) (app *kingpin.Application, executedCommand string, con
// by the systemd unit upgrader).
fmt.Printf("%s\n", teleport.Version)
} else {
utils.PrintVersion()
modules.GetModules().PrintVersion()
}
case dbConfigureCreate.FullCommand():
err = onDumpDatabaseConfig(dbConfigCreateFlags)
+1 -1
View File
@@ -1461,7 +1461,7 @@ func onVersion(cf *CLIConf) error {
format := strings.ToLower(cf.Format)
switch format {
case teleport.Text, "":
utils.PrintVersion()
modules.GetModules().PrintVersion()
if proxyVersion != "" {
fmt.Printf("Proxy version: %s\n", proxyVersion)
fmt.Printf("Proxy: %s\n", proxyPublicAddr)