diff --git a/Makefile b/Makefile index ac37739d8bb..1b9d1477588 100644 --- a/Makefile +++ b/Makefile @@ -269,7 +269,7 @@ ifeq ("$(REPRODUCIBLE)","yes") TAR_FLAGS = --sort=name --owner=root:0 --group=root:0 --mtime='UTC 2015-03-02' --format=gnu endif -VERSRC = version.go gitref.go api/version.go +VERSRC = gitref.go api/version.go KUBECONFIG ?= TEST_KUBE ?= @@ -1312,7 +1312,6 @@ ADDLICENSE_COMMON_ARGS := -c 'Gravitational, Inc.' \ -ignore 'lib/srv/desktop/rdp/rdpclient/target/**' \ -ignore 'lib/web/build/**' \ -ignore 'target/**' \ - -ignore 'version.go' \ -ignore 'web/packages/design/src/assets/icomoon/style.css' \ -ignore 'web/packages/shared/libs/ironrdp/**' \ -ignore 'lib/limiter/internal/ratelimit/**' \ @@ -1349,7 +1348,7 @@ update-version: version test-helm-update-snapshots version: $(VERSRC) # This rule triggers re-generation of version files specified if Makefile changes. -$(VERSRC): Makefile +$(VERSRC): Makefile version.mk VERSION=$(VERSION) $(MAKE) -f version.mk setver # Pushes GITTAG and api/GITTAG to GitHub. diff --git a/api/constants/constants.go b/api/constants/constants.go index 652b0a0d11d..449b621804a 100644 --- a/api/constants/constants.go +++ b/api/constants/constants.go @@ -34,10 +34,6 @@ const ( // since we register "teleport.cluster.local" as a DNS in Certificates. APIDomain = "teleport.cluster.local" - // EnhancedRecordingMinKernel is the minimum kernel version for the enhanced - // recording feature. - EnhancedRecordingMinKernel = "5.8.0" - // EnhancedRecordingCommand is a role option that implies command events are // captured. EnhancedRecordingCommand = "command" diff --git a/api/semversion.go b/api/semversion.go new file mode 100644 index 00000000000..cf3fbd24ac5 --- /dev/null +++ b/api/semversion.go @@ -0,0 +1,35 @@ +// Copyright 2025 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 api + +import "github.com/coreos/go-semver/semver" + +// SemVer returns the version of Teleport in use as a [semver.Version]. +func SemVer() *semver.Version { + return &semver.Version{ + Major: VersionMajor, + Minor: VersionMinor, + Patch: VersionPatch, + PreRelease: VersionPreRelease, + Metadata: VersionMetadata, + } +} + +// SemVersion contains the same value you'd get by calling [SemVer]. +// +// Deprecated: call [SemVer] instead. +var SemVersion = SemVer() + +// TODO(espadolini) DELETE IN v19 diff --git a/api/semversion_test.go b/api/semversion_test.go new file mode 100644 index 00000000000..2e280016c1a --- /dev/null +++ b/api/semversion_test.go @@ -0,0 +1,40 @@ +// Copyright 2025 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 api + +import ( + "testing" + + "github.com/coreos/go-semver/semver" + "github.com/stretchr/testify/require" +) + +// this is a static assertion that the shape of semver.Version hasn't changed +// under our nose, since we can't inspect unexported fields in our equality +// check and we'd potentially miss out on a discrepancy between +// semver.New(Version) and our manually assembled semver.Version +var _ semver.Version = struct { + Major int64 + Minor int64 + Patch int64 + PreRelease semver.PreRelease + Metadata string +}{} + +func TestSemVersion(t *testing.T) { + v, err := semver.NewVersion(Version) + require.NoError(t, err) + require.Equal(t, SemVer(), v) +} diff --git a/api/types/trust.go b/api/types/trust.go index 7cdbc09dda6..6811b22bb35 100644 --- a/api/types/trust.go +++ b/api/types/trust.go @@ -86,7 +86,7 @@ var CertAuthTypes = []CertAuthType{HostCA, // major version, so that we can avoid erroring out when a potentially older // remote server doesn't know about them. func (c CertAuthType) NewlyAdded() bool { - return c.addedInMajorVer() >= api.SemVersion.Major + return c.addedInMajorVer() >= api.VersionMajor } // addedInVer return the major version in which given CA was added. diff --git a/api/version.go b/api/version.go index 78532e11f4e..9ad60b95cb8 100644 --- a/api/version.go +++ b/api/version.go @@ -1,8 +1,11 @@ // Code generated by "make version". DO NOT EDIT. -package api -import "github.com/coreos/go-semver/semver" +package api const Version = "18.0.0-dev" -var SemVersion = semver.New(Version) +const VersionMajor = 18 +const VersionMinor = 0 +const VersionPatch = 0 +const VersionPreRelease = "dev" +const VersionMetadata = "" diff --git a/build.assets/tooling/cmd/apiversion/main.go b/build.assets/tooling/cmd/apiversion/main.go new file mode 100644 index 00000000000..c34f203afca --- /dev/null +++ b/build.assets/tooling/cmd/apiversion/main.go @@ -0,0 +1,47 @@ +// Teleport +// Copyright (C) 2025 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package main + +import ( + "os" + "text/template" + + "github.com/coreos/go-semver/semver" +) + +var outTemplate = template.Must(template.New("apiversion").Parse( + `// Code generated by "make version". DO NOT EDIT. + +package api + +const Version = "{{.}}" + +const VersionMajor = {{.Major}} +const VersionMinor = {{.Minor}} +const VersionPatch = {{.Patch}} +const VersionPreRelease = "{{.PreRelease}}" +const VersionMetadata = "{{.Metadata}}" +`)) + +func main() { + v := semver.New(os.Args[1]) + if os.Args[1] != v.String() { + panic("impossible semver parse") + } + + outTemplate.Execute(os.Stdout, v) +} diff --git a/build.assets/tooling/go.mod b/build.assets/tooling/go.mod index 377b61e72af..f8f8d924632 100644 --- a/build.assets/tooling/go.mod +++ b/build.assets/tooling/go.mod @@ -7,6 +7,7 @@ require ( github.com/alecthomas/kingpin/v2 v2.4.0 // replaced github.com/awalterschulze/goderive v0.5.1 github.com/bmatcuk/doublestar/v4 v4.8.1 + github.com/coreos/go-semver v0.3.1 github.com/gogo/protobuf v1.3.2 github.com/google/go-github/v41 v41.0.0 github.com/gravitational/trace v1.5.1 @@ -48,6 +49,7 @@ require ( golang.org/x/net v0.38.0 // indirect golang.org/x/text v0.23.0 // indirect golang.org/x/tools v0.26.0 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 k8s.io/apimachinery v0.32.3 // indirect @@ -58,6 +60,4 @@ require ( sigs.k8s.io/yaml v1.4.0 // indirect ) -require gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect - replace github.com/alecthomas/kingpin/v2 => github.com/gravitational/kingpin/v2 v2.1.11-0.20230515143221-4ec6b70ecd33 diff --git a/build.assets/tooling/go.sum b/build.assets/tooling/go.sum index aa4a2b3d936..ac8d9401227 100644 --- a/build.assets/tooling/go.sum +++ b/build.assets/tooling/go.sum @@ -14,6 +14,8 @@ github.com/awalterschulze/goderive v0.5.1 h1:H2XNRDw0Ordwj/pgLAVqQgDC1LQWP7L99of github.com/awalterschulze/goderive v0.5.1/go.mod h1:DLlff0SRVo846CBrp8nXuXJ4mdWA92ai5CYTr+LV/II= github.com/bmatcuk/doublestar/v4 v4.8.1 h1:54Bopc5c2cAvhLRAzqOGCYHYyhcDHsFF4wWIR5wKP38= github.com/bmatcuk/doublestar/v4 v4.8.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= +github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= +github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= diff --git a/constants.go b/constants.go index 8295c46963e..a7e99c3b6ae 100644 --- a/constants.go +++ b/constants.go @@ -427,9 +427,6 @@ const ( // DebugLevel is a debug logging level name DebugLevel = "debug" - // MinimumEtcdVersion is the minimum version of etcd supported by Teleport - MinimumEtcdVersion = "3.3.0" - // EnvVarAllowNoSecondFactor is used to allow disabling second factor auth // todo(tross): DELETE WHEN ABLE TO EnvVarAllowNoSecondFactor = "TELEPORT_ALLOW_NO_SECOND_FACTOR" diff --git a/integrations/kube-agent-updater/cmd/teleport-kube-agent-updater/main.go b/integrations/kube-agent-updater/cmd/teleport-kube-agent-updater/main.go index 3ffe2072a4e..aef3c90d309 100644 --- a/integrations/kube-agent-updater/cmd/teleport-kube-agent-updater/main.go +++ b/integrations/kube-agent-updater/cmd/teleport-kube-agent-updater/main.go @@ -251,7 +251,7 @@ func main() { case insecureNoVerify: ctrl.Log.Info("INSECURE: Image validation disabled") imageValidators = append(imageValidators, img.NewInsecureValidator("insecure always verified", kc)) - case kubeversionupdater.SemVersion != nil && kubeversionupdater.SemVersion.PreRelease != "": + case kubeversionupdater.Version().PreRelease != "": ctrl.Log.Info("This is a pre-release updater version, the key used to sign dev and pre-release builds of Teleport will be trusted.") validator, err := img.NewCosignSingleKeyValidator(teleportStageOCIPubKey, "staging cosign signature validator", kc) if err != nil { @@ -314,7 +314,7 @@ func main() { os.Exit(1) } - ctrl.Log.Info("starting the updater", "version", kubeversionupdater.Version) + ctrl.Log.Info("starting the updater", "version", kubeversionupdater.Version().String()) if err := mgr.Start(ctx); err != nil { ctrl.Log.Error(err, "failed to start manager, exiting") diff --git a/integrations/kube-agent-updater/version.go b/integrations/kube-agent-updater/version.go index e0801dfc1a2..5cc85b00d24 100644 --- a/integrations/kube-agent-updater/version.go +++ b/integrations/kube-agent-updater/version.go @@ -18,8 +18,12 @@ package kubeversionupdater -import "github.com/gravitational/teleport/api" +import ( + "github.com/coreos/go-semver/semver" -const Version = api.Version + "github.com/gravitational/teleport/api" +) -var SemVersion = api.SemVersion +func Version() *semver.Version { + return api.SemVer() +} diff --git a/lib/auth/grpcserver.go b/lib/auth/grpcserver.go index 7455b9d4e0b..0cc733a5e09 100644 --- a/lib/auth/grpcserver.go +++ b/lib/auth/grpcserver.go @@ -443,18 +443,6 @@ func (g *GRPCServer) CreateAuditStream(stream authpb.AuthService_CreateAuditStre var errors []error errors = append(errors, eventStream.RecordEvent(stream.Context(), preparedEvent)) - // v13 clients expect this request to also emit the event, so emit here - // just for them. - switch event.GetType() { - // Don't emit really verbose events. - case events.ResizeEvent, events.SessionDiskEvent, events.SessionPrintEvent, events.AppSessionRequestEvent, "": - default: - clientVersion, versionExists := metadata.ClientVersionFromContext(stream.Context()) - if versionExists && semver.New(clientVersion).Major <= 13 { - errors = append(errors, auth.EmitAuditEvent(stream.Context(), event)) - } - } - err = trace.NewAggregate(errors...) if err != nil { switch { diff --git a/lib/auth/helpers.go b/lib/auth/helpers.go index b1bebaeed92..e3745d33dd5 100644 --- a/lib/auth/helpers.go +++ b/lib/auth/helpers.go @@ -1232,7 +1232,7 @@ func NewFakeTeleportVersion() *FakeTeleportVersion { // GetTeleportVersion returns current Teleport version. func (s FakeTeleportVersion) GetTeleportVersion(_ context.Context) (*semver.Version, error) { - return teleport.SemVersion, nil + return teleport.SemVer(), nil } // WriteTeleportVersion stub function for writing. diff --git a/lib/auth/init.go b/lib/auth/init.go index 05e3136bea0..6b8f6fbbfe4 100644 --- a/lib/auth/init.go +++ b/lib/auth/init.go @@ -412,7 +412,7 @@ func initCluster(ctx context.Context, cfg InitConfig, asrv *Server) error { if err != nil { return trace.Wrap(err) } - if err := validateAndUpdateTeleportVersion(ctx, cfg.VersionStorage, teleport.SemVersion); err != nil { + if err := validateAndUpdateTeleportVersion(ctx, cfg.VersionStorage, teleport.SemVer()); err != nil { return trace.Wrap(err) } diff --git a/lib/auth/init_test.go b/lib/auth/init_test.go index dc112d15490..c6f265dd5ca 100644 --- a/lib/auth/init_test.go +++ b/lib/auth/init_test.go @@ -45,6 +45,7 @@ import ( kyaml "k8s.io/apimachinery/pkg/util/yaml" "github.com/gravitational/teleport" + "github.com/gravitational/teleport/api" "github.com/gravitational/teleport/api/constants" dbobjectimportrulev1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobjectimportrule/v1" healthcheckconfigv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/healthcheckconfig/v1" @@ -2171,33 +2172,33 @@ func TestTeleportProcessAuthVersionUpgradeCheck(t *testing.T) { }, { name: "old-version-upgrade", - initialVersion: fmt.Sprintf("%d.0.0", teleport.SemVersion.Major-1), + initialVersion: fmt.Sprintf("%d.0.0", api.VersionMajor-1), expectedVersion: teleport.Version, expectError: false, }, { name: "major-upgrade-fail", - initialVersion: fmt.Sprintf("%d.0.0", teleport.SemVersion.Major-2), - expectedVersion: fmt.Sprintf("%d.0.0", teleport.SemVersion.Major-2), + initialVersion: fmt.Sprintf("%d.0.0", api.VersionMajor-2), + expectedVersion: fmt.Sprintf("%d.0.0", api.VersionMajor-2), expectError: true, }, { name: "major-upgrade-with-dev-skip-check", - initialVersion: fmt.Sprintf("%d.0.0", teleport.SemVersion.Major-2), - expectedVersion: fmt.Sprintf("%d.0.0", teleport.SemVersion.Major-2), + initialVersion: fmt.Sprintf("%d.0.0", api.VersionMajor-2), + expectedVersion: fmt.Sprintf("%d.0.0", api.VersionMajor-2), expectError: false, skipCheck: true, }, { name: "major-downgrade-fail", - initialVersion: fmt.Sprintf("%d.0.0", teleport.SemVersion.Major+2), - expectedVersion: fmt.Sprintf("%d.0.0", teleport.SemVersion.Major+2), + initialVersion: fmt.Sprintf("%d.0.0", api.VersionMajor+2), + expectedVersion: fmt.Sprintf("%d.0.0", api.VersionMajor+2), expectError: true, }, { name: "major-downgrade-with-dev-skip-check", - initialVersion: fmt.Sprintf("%d.0.0", teleport.SemVersion.Major+2), - expectedVersion: fmt.Sprintf("%d.0.0", teleport.SemVersion.Major+2), + initialVersion: fmt.Sprintf("%d.0.0", api.VersionMajor+2), + expectedVersion: fmt.Sprintf("%d.0.0", api.VersionMajor+2), expectError: false, skipCheck: true, }, diff --git a/lib/auth/join_iam.go b/lib/auth/join_iam.go index 9ecfedd07be..0f0bddbb289 100644 --- a/lib/auth/join_iam.go +++ b/lib/auth/join_iam.go @@ -329,7 +329,7 @@ type iamRegisterConfig struct { func defaultIAMRegisterConfig(fips bool) *iamRegisterConfig { return &iamRegisterConfig{ - authVersion: teleport.SemVersion, + authVersion: teleport.SemVer(), fips: fips, } } diff --git a/lib/auth/middleware.go b/lib/auth/middleware.go index f35d38e2c61..6a2f4dc0ad2 100644 --- a/lib/auth/middleware.go +++ b/lib/auth/middleware.go @@ -173,7 +173,7 @@ func NewTLSServer(ctx context.Context, cfg TLSServerConfig) (*TLSServer, error) return nil, trace.Wrap(err) } - oldestSupportedVersion := &teleport.MinClientSemVersion + oldestSupportedVersion := teleport.MinClientSemVer() if os.Getenv("TELEPORT_UNSTABLE_ALLOW_OLD_CLIENTS") == "yes" { oldestSupportedVersion = nil } diff --git a/lib/auth/middleware_test.go b/lib/auth/middleware_test.go index 603654e38e3..c2ae62b183f 100644 --- a/lib/auth/middleware_test.go +++ b/lib/auth/middleware_test.go @@ -43,6 +43,7 @@ import ( "google.golang.org/grpc/metadata" "github.com/gravitational/teleport" + "github.com/gravitational/teleport/api" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/lib/authz" "github.com/gravitational/teleport/lib/services" @@ -698,38 +699,38 @@ func TestValidateClientVersion(t *testing.T) { }, { name: "rejection enabled and client version not specified", - middleware: &Middleware{OldestSupportedVersion: &teleport.MinClientSemVersion}, + middleware: &Middleware{OldestSupportedVersion: teleport.MinClientSemVer()}, errAssertion: func(t *testing.T, err error) { require.NoError(t, err) }, }, { name: "client rejected", - middleware: &Middleware{OldestSupportedVersion: &teleport.MinClientSemVersion}, - clientVersion: semver.Version{Major: teleport.SemVersion.Major - 2}.String(), + middleware: &Middleware{OldestSupportedVersion: teleport.MinClientSemVer()}, + clientVersion: semver.Version{Major: api.VersionMajor - 2}.String(), errAssertion: func(t *testing.T, err error) { require.True(t, trace.IsAccessDenied(err), "got %T, expected access denied error", err) }, }, { name: "valid client v-1", - middleware: &Middleware{OldestSupportedVersion: &teleport.MinClientSemVersion}, - clientVersion: semver.Version{Major: teleport.SemVersion.Major - 1}.String(), + middleware: &Middleware{OldestSupportedVersion: teleport.MinClientSemVer()}, + clientVersion: semver.Version{Major: api.VersionMajor - 1}.String(), errAssertion: func(t *testing.T, err error) { require.NoError(t, err) }, }, { name: "valid client v-0", - middleware: &Middleware{OldestSupportedVersion: &teleport.MinClientSemVersion}, - clientVersion: semver.Version{Major: teleport.SemVersion.Major}.String(), + middleware: &Middleware{OldestSupportedVersion: teleport.MinClientSemVer()}, + clientVersion: semver.Version{Major: api.VersionMajor}.String(), errAssertion: func(t *testing.T, err error) { require.NoError(t, err) }, }, { name: "invalid client version", - middleware: &Middleware{OldestSupportedVersion: &teleport.MinClientSemVersion}, + middleware: &Middleware{OldestSupportedVersion: teleport.MinClientSemVer()}, clientVersion: "abc123", errAssertion: func(t *testing.T, err error) { require.True(t, trace.IsAccessDenied(err), "got %T, expected access denied error", err) @@ -737,16 +738,16 @@ func TestValidateClientVersion(t *testing.T) { }, { name: "pre-release client allowed", - middleware: &Middleware{OldestSupportedVersion: &teleport.MinClientSemVersion}, - clientVersion: semver.Version{Major: teleport.SemVersion.Major - 1, PreRelease: "dev.abcd.123"}.String(), + middleware: &Middleware{OldestSupportedVersion: teleport.MinClientSemVer()}, + clientVersion: semver.Version{Major: api.VersionMajor - 1, PreRelease: "dev.abcd.123"}.String(), errAssertion: func(t *testing.T, err error) { require.NoError(t, err) }, }, { name: "pre-release client rejected", - middleware: &Middleware{OldestSupportedVersion: &teleport.MinClientSemVersion}, - clientVersion: semver.Version{Major: teleport.SemVersion.Major - 2, PreRelease: "dev.abcd.123"}.String(), + middleware: &Middleware{OldestSupportedVersion: teleport.MinClientSemVer()}, + clientVersion: semver.Version{Major: api.VersionMajor - 2, PreRelease: "dev.abcd.123"}.String(), errAssertion: func(t *testing.T, err error) { require.True(t, trace.IsAccessDenied(err), "got %T, expected access denied error", err) }, @@ -768,7 +769,7 @@ func TestValidateClientVersion(t *testing.T) { func TestRejectedClientClusterAlertContents(t *testing.T) { var alerts []types.ClusterAlert mw := Middleware{ - OldestSupportedVersion: &teleport.MinClientSemVersion, + OldestSupportedVersion: teleport.MinClientSemVer(), AlertCreator: func(ctx context.Context, a types.ClusterAlert) error { alerts = append(alerts, a) return nil @@ -781,7 +782,7 @@ func TestRejectedClientClusterAlertContents(t *testing.T) { Patch: mw.OldestSupportedVersion.Patch, }.String() - version := semver.Version{Major: teleport.SemVersion.Major - 5}.String() + version := semver.Version{Major: api.VersionMajor - 5}.String() tests := []struct { name string @@ -850,7 +851,7 @@ func TestRejectedClientClusterAlertContents(t *testing.T) { func TestRejectedClientClusterAlert(t *testing.T) { var alerts []types.ClusterAlert mw := Middleware{ - OldestSupportedVersion: &teleport.MinClientSemVersion, + OldestSupportedVersion: teleport.MinClientSemVer(), AlertCreator: func(ctx context.Context, a types.ClusterAlert) error { alerts = append(alerts, a) return nil @@ -859,7 +860,7 @@ func TestRejectedClientClusterAlert(t *testing.T) { // Validate an unsupported client, which should trigger an alert ctx := metadata.NewIncomingContext(context.Background(), metadata.New(map[string]string{ - "version": semver.Version{Major: teleport.SemVersion.Major - 20}.String(), + "version": semver.Version{Major: api.VersionMajor - 20}.String(), })) err := mw.ValidateClientVersion(ctx, IdentityInfo{Conn: &fakeConn{}, IdentityGetter: TestBuiltin(types.RoleNode).I}) assert.Error(t, err) @@ -890,7 +891,7 @@ func TestRejectedClientClusterAlert(t *testing.T) { // Create a new context with the user-agent set to a client tool. This should alter the // text in the alert to indicate the connection was from a client tool and not an agent. ctx = metadata.NewIncomingContext(context.Background(), metadata.New(map[string]string{ - "version": semver.Version{Major: teleport.SemVersion.Major - 20}.String(), + "version": semver.Version{Major: api.VersionMajor - 20}.String(), "user-agent": tool + "/" + teleport.Version, })) diff --git a/lib/auth/tls_test.go b/lib/auth/tls_test.go index e1a2972603e..b5ee57d7f8a 100644 --- a/lib/auth/tls_test.go +++ b/lib/auth/tls_test.go @@ -111,7 +111,7 @@ func TestRejectedClients(t *testing.T) { defer clt.Close() t.Run("reject old version", func(t *testing.T) { - version := teleport.MinClientSemVersion + version := teleport.MinClientSemVer() version.Major-- ctx := context.WithValue(context.Background(), metadata.DisableInterceptors{}, struct{}{}) ctx = metadata.AddMetadataToContext(ctx, map[string]string{ @@ -123,7 +123,7 @@ func TestRejectedClients(t *testing.T) { }) t.Run("allow valid versions", func(t *testing.T) { - version := teleport.MinClientSemVersion + version := teleport.MinClientSemVer() version.Major-- for i := 0; i < 5; i++ { version.Major++ diff --git a/lib/automaticupgrades/channel.go b/lib/automaticupgrades/channel.go index f90ea648ecb..94cf6fb009d 100644 --- a/lib/automaticupgrades/channel.go +++ b/lib/automaticupgrades/channel.go @@ -27,7 +27,7 @@ import ( "github.com/coreos/go-semver/semver" "github.com/gravitational/trace" - "github.com/gravitational/teleport" + "github.com/gravitational/teleport/api" "github.com/gravitational/teleport/lib/automaticupgrades/maintenance" "github.com/gravitational/teleport/lib/automaticupgrades/version" ) @@ -121,10 +121,7 @@ type Channel struct { versionGetter version.Getter // criticalTrigger gets the criticality of the channel. It is populated by CheckAndSetDefaults. criticalTrigger maintenance.Trigger - // teleportMajor stores the current teleport major for comparison. - // This field is initialized during CheckAndSetDefaults. - teleportMajor int64 - // mutex protects versionGetter, criticalTrigger, and teleportMajor + // mutex protects versionGetter and criticalTrigger mutex sync.Mutex } @@ -155,8 +152,6 @@ func (c *Channel) CheckAndSetDefaults() error { return trace.BadParameter("either ForwardURL or StaticVersion must be set") } - c.teleportMajor = teleport.SemVersion.Major - return nil } @@ -177,11 +172,8 @@ func (c *Channel) GetVersion(ctx context.Context) (*semver.Version, error) { // The target version is officially incompatible with our version, // we prefer returning our version rather than having a broken client - if targetVersion.Major > c.teleportMajor { - targetVersion, err = version.EnsureSemver(teleport.Version) - if err != nil { - return nil, trace.Wrap(err, "ensuring current teleport version is semver-compatible") - } + if targetVersion.Major > api.VersionMajor { + targetVersion = api.SemVer() } return targetVersion, nil @@ -204,7 +196,7 @@ var newDefaultChannel = sync.OnceValues[*Channel, error]( } } else { channel = &Channel{ - StaticVersion: teleport.Version, + StaticVersion: api.Version, } } if err := channel.CheckAndSetDefaults(); err != nil { diff --git a/lib/automaticupgrades/channel_test.go b/lib/automaticupgrades/channel_test.go index 94c4eed1d3b..7171445e4f1 100644 --- a/lib/automaticupgrades/channel_test.go +++ b/lib/automaticupgrades/channel_test.go @@ -230,7 +230,7 @@ func Test_Channel_GetVersion(t *testing.T) { { name: "version too high", targetVersion: "v99.1.1", - expectedVersion: teleport.SemVersion, + expectedVersion: teleport.SemVer(), assertErr: require.NoError, }, { diff --git a/lib/backend/etcdbk/etcd.go b/lib/backend/etcdbk/etcd.go index 799dc2631aa..ac095bf8a42 100644 --- a/lib/backend/etcdbk/etcd.go +++ b/lib/backend/etcdbk/etcd.go @@ -340,10 +340,10 @@ func (b *EtcdBackend) checkVersion(ctx context.Context) error { return trace.BadParameter("failed to parse etcd version %q: %v", status.Version, err) } - min := semver.New(teleport.MinimumEtcdVersion) - if ver.LessThan(*min) { + minEtcdVersion := semver.Version{Major: 3, Minor: 3, Patch: 0} + if ver.LessThan(minEtcdVersion) { return trace.BadParameter("unsupported version of etcd %v for node %v, must be %v or greater", - status.Version, n, teleport.MinimumEtcdVersion) + status.Version, n, minEtcdVersion) } return nil diff --git a/lib/bpf/common.go b/lib/bpf/common.go index 0ebd72a2c31..5730f8bb0f3 100644 --- a/lib/bpf/common.go +++ b/lib/bpf/common.go @@ -26,7 +26,6 @@ import ( "github.com/coreos/go-semver/semver" "github.com/gravitational/trace" - "github.com/gravitational/teleport/api/constants" apievents "github.com/gravitational/teleport/api/types/events" "github.com/gravitational/teleport/lib/utils" ) @@ -110,13 +109,13 @@ func (s *NOP) Enabled() bool { // IsHostCompatible checks that BPF programs can run on this host. func IsHostCompatible() error { - minKernel := semver.New(constants.EnhancedRecordingMinKernel) version, err := utils.KernelVersion() if err != nil { return trace.Wrap(err) } - if version.LessThan(*minKernel) { - return trace.BadParameter("incompatible kernel found, minimum supported kernel is %v", minKernel) + minKernelVersion := semver.Version{Major: 5, Minor: 8, Patch: 0} + if version.LessThan(minKernelVersion) { + return trace.BadParameter("incompatible kernel found, minimum supported kernel is %v", minKernelVersion) } if err = utils.HasBTF(); err != nil { diff --git a/lib/client/api_test.go b/lib/client/api_test.go index 248f6979049..5ee75196ea9 100644 --- a/lib/client/api_test.go +++ b/lib/client/api_test.go @@ -1563,7 +1563,7 @@ Future versions of tsh will fail when incompatible versions are detected. minClientVersion, err := semver.NewVersion(test.serverVersion) require.NoError(t, err) minClientVersion.Major = minClientVersion.Major - 1 - // Mirror what happens with teleport.MinClientSemVersion. + // Mirror what happens with teleport.MinClientSemVer. minClientVersion.PreRelease = "aa" warning, err := getClientIncompatibilityWarning(Versions{ MinClient: minClientVersion.String(), diff --git a/lib/cloud/aws/aws.go b/lib/cloud/aws/aws.go index 208ad5b1dc7..9e8f7931b21 100644 --- a/lib/cloud/aws/aws.go +++ b/lib/cloud/aws/aws.go @@ -133,8 +133,7 @@ func IsRDSInstanceSupported(instance *rdstypes.DBInstance) bool { // Min supported MariaDB version that supports IAM is 10.6 // https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html - minIAMSupportedVer := semver.New("10.6.0") - return !ver.LessThan(*minIAMSupportedVer) + return !ver.LessThan(semver.Version{Major: 10, Minor: 6, Patch: 0}) } // IsRDSClusterSupported checks whether the Aurora cluster is supported. diff --git a/lib/httplib/httplib.go b/lib/httplib/httplib.go index c345e3b2e85..a969fd93c2d 100644 --- a/lib/httplib/httplib.go +++ b/lib/httplib/httplib.go @@ -34,13 +34,13 @@ import ( "strconv" "strings" - "github.com/coreos/go-semver/semver" "github.com/gravitational/roundtrip" "github.com/gravitational/trace" "github.com/julienschmidt/httprouter" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" "github.com/gravitational/teleport" + "github.com/gravitational/teleport/api" "github.com/gravitational/teleport/api/observability/tracing" tracehttp "github.com/gravitational/teleport/api/observability/tracing/http" "github.com/gravitational/teleport/lib/utils" @@ -232,27 +232,20 @@ type ProxyVersion struct { // RouteNotFoundResponse writes a JSON error reply containing // a not found error, a Version object, and a not found HTTP status code. -func RouteNotFoundResponse(ctx context.Context, w http.ResponseWriter, proxyVersion string) { +func RouteNotFoundResponse(ctx context.Context, w http.ResponseWriter) { SetDefaultSecurityHeaders(w.Header()) errObj := &trace.TraceErr{ Err: trace.NotFound("path not found"), - } - - ver, err := semver.NewVersion(proxyVersion) - if err != nil { - slog.DebugContext(ctx, "Error parsing Teleport proxy semver version", "err", err) - } else { - verObj := ProxyVersion{ - Major: ver.Major, - Minor: ver.Minor, - Patch: ver.Patch, - String: proxyVersion, - PreRelease: string(ver.PreRelease), - } - fields := make(map[string]interface{}) - fields["proxyVersion"] = verObj - errObj.Fields = fields + Fields: map[string]any{ + "proxyVersion": ProxyVersion{ + Major: api.VersionMajor, + Minor: api.VersionMinor, + Patch: api.VersionPatch, + String: api.Version, + PreRelease: api.VersionPreRelease, + }, + }, } roundtrip.ReplyJSON(w, http.StatusNotFound, errObj) diff --git a/lib/integrations/awsoidc/deployservice_test.go b/lib/integrations/awsoidc/deployservice_test.go index 1211b82696d..24e7b2b8b37 100644 --- a/lib/integrations/awsoidc/deployservice_test.go +++ b/lib/integrations/awsoidc/deployservice_test.go @@ -238,7 +238,7 @@ func TestUpsertTask(t *testing.T) { }, } - semVer := *teleport.SemVersion + semVer := teleport.SemVer() semVer.PreRelease = "" taskDefinition, err := upsertTask(ctx, mockClient, upsertTaskRequest{TeleportVersionTag: semVer.String()}) require.NoError(t, err) diff --git a/lib/integrations/awsoidc/deployservice_update_test.go b/lib/integrations/awsoidc/deployservice_update_test.go index 88910688903..27a11621e29 100644 --- a/lib/integrations/awsoidc/deployservice_update_test.go +++ b/lib/integrations/awsoidc/deployservice_update_test.go @@ -162,7 +162,7 @@ func TestUpdateDeployServices(t *testing.T) { clusterName := "my-cluster" integrationName := "my-integration" ownershipTags := tags.DefaultResourceCreationTags(clusterName, integrationName) - semVer := *teleport.SemVersion + semVer := teleport.SemVer() semVer.PreRelease = "" teleportVersion := semVer.String() log := utils.NewSlogLoggerForTests().With("test", t.Name()) diff --git a/lib/service/service.go b/lib/service/service.go index e707e6a399d..76452562f54 100644 --- a/lib/service/service.go +++ b/lib/service/service.go @@ -1571,7 +1571,7 @@ func (process *TeleportProcess) detectUpgrader() (kind, externalName string, ver // If this is a teleport-update managed installation, the version // managed by the timer will always match the installed version of teleport. kind = types.UpgraderKindTeleportUpdate - version = teleport.SemVersion + version = teleport.SemVer() } // Instances deployed using the AWS OIDC integration are automatically updated diff --git a/lib/service/service_test.go b/lib/service/service_test.go index 0c8dc093537..b7bd9663856 100644 --- a/lib/service/service_test.go +++ b/lib/service/service_test.go @@ -50,6 +50,7 @@ import ( "google.golang.org/grpc/credentials/insecure" "github.com/gravitational/teleport" + "github.com/gravitational/teleport/api" "github.com/gravitational/teleport/api/breaker" autoupdatepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1" "github.com/gravitational/teleport/api/types" @@ -1038,7 +1039,7 @@ func TestTeleportProcessAuthVersionCheck(t *testing.T) { // Set the Node's major version to be greater than the Auth Service's, // which should make the version check fail. - currentVersion := semver.Version{Major: teleport.SemVersion.Major + 1} + currentVersion := semver.Version{Major: api.VersionMajor + 1} nodeCfg.Testing.TeleportVersion = currentVersion.String() t.Run("with version check", func(t *testing.T) { diff --git a/lib/srv/db/mongodb/autousers.go b/lib/srv/db/mongodb/autousers.go index 506cf98678f..95f00c2661e 100644 --- a/lib/srv/db/mongodb/autousers.go +++ b/lib/srv/db/mongodb/autousers.go @@ -223,7 +223,7 @@ func (e *Engine) isShowCustomDataSupported(ctx context.Context, client adminClie e.Log.DebugContext(e.Context, "Failed to get server version. Assuming showCustomData is supported.", "error", err) return false } - return serverVersion.Compare(*semver.New("5.2.0")) >= 0 + return serverVersion.Compare(semver.Version{Major: 5, Minor: 2, Patch: 0}) >= 0 } func (e *Engine) getUser(ctx context.Context, sessionCtx *common.Session, client adminClient) (*user, bool, error) { diff --git a/lib/tbot/botfs/fs_linux.go b/lib/tbot/botfs/fs_linux.go index 3512ac1b813..f5d01c3927c 100644 --- a/lib/tbot/botfs/fs_linux.go +++ b/lib/tbot/botfs/fs_linux.go @@ -41,10 +41,6 @@ import ( "github.com/gravitational/teleport/lib/utils" ) -// Openat2MinKernel is the kernel release that adds support for the openat2() -// syscall. -const Openat2MinKernel = "5.6.0" - // mostACLRead is a permission mode granting readonly access to a file. const modeACLRead fs.FileMode = 04 @@ -672,7 +668,6 @@ func HasACLSupport() bool { // We've encountered this being incorrect in environments where access to the // kernel is hampered e.g. seccomp/apparmor/container runtimes. func HasSecureWriteSupport() bool { - minKernel := semver.New(Openat2MinKernel) version, err := utils.KernelVersion() if err != nil { log.InfoContext( @@ -682,7 +677,8 @@ func HasSecureWriteSupport() bool { ) return false } - if version.LessThan(*minKernel) { + // kernel release that added support for the openat2() syscall + if version.LessThan(semver.Version{Major: 5, Minor: 6, Patch: 0}) { return false } diff --git a/lib/utils/teleportassets/teleportassets.go b/lib/utils/teleportassets/teleportassets.go index 995f0356762..d5fb430a49b 100644 --- a/lib/utils/teleportassets/teleportassets.go +++ b/lib/utils/teleportassets/teleportassets.go @@ -39,7 +39,7 @@ const ( // CDNBaseURL returns the URL of the CDN that can be used to download Teleport // binary assets. func CDNBaseURL() string { - return cdnBaseURL(*teleport.SemVersion) + return cdnBaseURL(*teleport.SemVer()) } // cdnBaseURL returns the base URL of the CDN that can be used to download @@ -56,7 +56,7 @@ func cdnBaseURL(version semver.Version) string { // the pre-release CDN while Teleport pre-release builds can download both form // the production and pre-release CDN. func CDNBaseURLForVersion(artifactVersion *semver.Version) string { - return cdnBaseURLForVersion(artifactVersion, teleport.SemVersion) + return cdnBaseURLForVersion(artifactVersion, teleport.SemVer()) } func cdnBaseURLForVersion(artifactVersion, teleportVersion *semver.Version) string { diff --git a/lib/utils/ver.go b/lib/utils/ver.go index 8113d987945..9e9c9d2701c 100644 --- a/lib/utils/ver.go +++ b/lib/utils/ver.go @@ -84,7 +84,7 @@ func VersionBeforeAlpha(version string) string { } // VersionWithoutPreRelease removes the prerelease suffix. Useful when showing -// teleport.MinClientSemVersion, which by default comes with the -aa prerelease. +// teleport.MinClientSemVer(), which by default comes with the -aa prerelease. func VersionWithoutPreRelease(version string) (string, error) { semver, err := versionStringToSemver(version) if err != nil { diff --git a/lib/web/apiserver.go b/lib/web/apiserver.go index 434177382cc..ec294a938f6 100644 --- a/lib/web/apiserver.go +++ b/lib/web/apiserver.go @@ -642,7 +642,7 @@ func NewHandler(cfg Config, opts ...HandlerOption) (*APIHandler, error) { return } } - httplib.RouteNotFoundResponse(r.Context(), w, teleport.Version) + httplib.RouteNotFoundResponse(r.Context(), w) return } @@ -694,7 +694,7 @@ func NewHandler(cfg Config, opts ...HandlerOption) (*APIHandler, error) { h.logger.ErrorContext(r.Context(), "Failed to execute index page template", "error", err) } } else { - httplib.RouteNotFoundResponse(r.Context(), w, teleport.Version) + httplib.RouteNotFoundResponse(r.Context(), w) return } }) @@ -1624,7 +1624,7 @@ func (h *Handler) ping(w http.ResponseWriter, r *http.Request, p httprouter.Para Auth: authSettings, Proxy: *proxyConfig, ServerVersion: teleport.Version, - MinClientVersion: teleport.MinClientVersion, + MinClientVersion: teleport.MinClientSemVer().String(), ClusterName: h.auth.clusterName, AutomaticUpgrades: pr.ServerFeatures.GetAutomaticUpgrades(), AutoUpdate: h.automaticUpdateSettings184(r.Context(), group, "" /* updater UUID */), @@ -1656,7 +1656,7 @@ func (h *Handler) find(w http.ResponseWriter, r *http.Request, p httprouter.Para Proxy: *proxyConfig, Auth: webclient.AuthenticationSettings{SignatureAlgorithmSuite: authPref.GetSignatureAlgorithmSuite()}, ServerVersion: teleport.Version, - MinClientVersion: teleport.MinClientVersion, + MinClientVersion: teleport.MinClientSemVer().String(), ClusterName: h.auth.clusterName, Edition: modules.GetModules().BuildType(), FIPS: modules.IsBoringBinary(), @@ -1691,7 +1691,7 @@ func (h *Handler) pingWithConnector(w http.ResponseWriter, r *http.Request, p ht response := &webclient.PingResponse{ Proxy: *proxyConfig, ServerVersion: teleport.Version, - MinClientVersion: teleport.MinClientVersion, + MinClientVersion: teleport.MinClientSemVer().String(), ClusterName: h.auth.clusterName, } @@ -2248,7 +2248,7 @@ func (h *Handler) installer(w http.ResponseWriter, r *http.Request, p httprouter targetVersion, err := h.autoUpdateAgentVersion(r.Context(), group, agentUUD) if err != nil { h.logger.WarnContext(r.Context(), "Error retrieving the target version", "error", err) - targetVersion = teleport.SemVersion + targetVersion = teleport.SemVer() } instTmpl, err := template.New("").Parse(installer.GetScript()) diff --git a/lib/web/autoupdate_rfd184.go b/lib/web/autoupdate_rfd184.go index 26ead1704eb..d8d275f4b25 100644 --- a/lib/web/autoupdate_rfd184.go +++ b/lib/web/autoupdate_rfd184.go @@ -52,7 +52,7 @@ func (h *Handler) automaticUpdateSettings184(ctx context.Context, group, updater if err != nil { h.logger.ErrorContext(ctx, "failed to resolve AgentVersion", "error", err) // Defaulting to current version - agentVersion = teleport.SemVersion + agentVersion = teleport.SemVer() } // If the source of truth is RFD 109 configuration (channels + CMC) we must emulate the // RFD109 agent maintenance window behavior by looking up the CMC and checking if @@ -67,7 +67,7 @@ func (h *Handler) automaticUpdateSettings184(ctx context.Context, group, updater toolsVersion, err := getToolsVersion(autoUpdateVersion) if err != nil { h.logger.ErrorContext(ctx, "failed to get tools version", "error", err) - toolsVersion = teleport.SemVersion + toolsVersion = teleport.SemVer() } return webclient.AutoUpdateSettings{ @@ -94,7 +94,7 @@ func getToolsVersion(v *autoupdatepb.AutoUpdateVersion) (*semver.Version, error) // If we can't get the AU version or tools AU version is not specified, we default to the current proxy version. // This ensures we always advertise a version compatible with the cluster. if v.GetSpec().GetTools() == nil { - return teleport.SemVersion, nil + return teleport.SemVer(), nil } return version.EnsureSemver(v.GetSpec().GetTools().GetTargetVersion()) } diff --git a/lib/web/scripts.go b/lib/web/scripts.go index 79f809185b0..dfe33184f28 100644 --- a/lib/web/scripts.go +++ b/lib/web/scripts.go @@ -89,7 +89,7 @@ func (h *Handler) installScriptOptions(ctx context.Context) (scripts.InstallScri version, err := h.autoUpdateAgentVersion(ctx, defaultGroup, defaultUpdater) if err != nil { h.logger.WarnContext(ctx, "Failed to get intended agent version", "error", err) - version = teleport.SemVersion + version = teleport.SemVer() } // if there's a rollout, we do new autoupdates @@ -134,7 +134,6 @@ func (h *Handler) installScriptOptions(ctx context.Context) (scripts.InstallScri TeleportFlavor: teleportFlavor, FIPS: modules.IsBoringBinary(), }, nil - } // EnvVarCDNBaseURL is the environment variable that allows users to override the Teleport base CDN url used in the installation script. diff --git a/version.go b/version.go index bf112efbd6e..d24f2df8c7b 100644 --- a/version.go +++ b/version.go @@ -24,20 +24,21 @@ import ( "github.com/gravitational/teleport/api" ) +// Version is the version of Teleport in use. const Version = api.Version -var ( - // SemVersion is the Version represented as a [semver.Version]. - SemVersion = api.SemVersion - // MinClientVersion is the minimum client version required by the server. - // Per https://github.com/gravitational/teleport/blob/master/rfd/0012-teleport-versioning.md, - // only one major version backwards is supported for clients. - MinClientVersion = MinClientSemVersion.String() - // MinClientSemVersion is the MinClientVersion represented as a [semver.Version]. The - // [semver.Version.PreRelease] is set to "aa" so that the minimum client version comes before - // -alpha so that alpha, beta, rc, and dev builds are permitted. - MinClientSemVersion = semver.Version{Major: SemVersion.Major - 1, PreRelease: "aa"} -) +// SemVer returns the version of Teleport in use as a [semver.Version]. +func SemVer() *semver.Version { + return api.SemVer() +} + +// MinClientSemVer returns the minimum client version required by the server. +// The [semver.Version.PreRelease] is set to "aa" so that the minimum client +// version comes before -alpha so that alpha, beta, rc, and dev builds +// are permitted. +func MinClientSemVer() *semver.Version { + return &semver.Version{Major: api.VersionMajor - 1, PreRelease: "aa"} +} // Gitref is set to the output of "git describe" during the build process. var Gitref string diff --git a/version.mk b/version.mk index 5cd50fa0fc7..c37997842db 100644 --- a/version.mk +++ b/version.mk @@ -1,23 +1,16 @@ GITREF=$(shell git describe --long --tags) -# $(API_VERSION_GO) will be written to api/version.go -API_VERSION_GO="// Code generated by \"make version\". DO NOT EDIT.\n\ -package api\n\n\ -import \"github.com/coreos/go-semver/semver\"\n\n\ -const Version = \"$(VERSION)\"\n\n\ -var SemVersion = semver.New(Version)\n\n" - # $(GITREF_GO) will be written to gitref.go -GITREF_GO="// Code generated by \"make version\". DO NOT EDIT.\n\ +GITREF_GO="// Code generated by \"make version\". DO NOT EDIT.\n\n\ package teleport\n\n\ func init() { Gitref = \"$(GITREF)\" }\n" # -# setver updates version.go and gitref.go with VERSION and GITREF vars +# setver updates api/version.go and gitref.go with VERSION and GITREF vars # -.PHONY:setver +.PHONY: setver setver: validate-semver helm-version tsh-version - @printf $(API_VERSION_GO) | gofmt > ./api/version.go + GOWORK=off CGO_ENABLED=0 go -C build.assets/tooling run ./cmd/apiversion "$(VERSION)" > api/version.go @printf $(GITREF_GO) | gofmt > gitref.go # helm-version automatically updates the versions of Helm charts to match the version set in the Makefile,