Files
teleport/lib/utils/ver.go
T
Edoardo Spadolini 91741f1abf Tweak api/version.go generation (#54257)
* Delete audit stream version check for v13

* Remove string parsing for bpf min kernel version

* Remove string parsing for min etcd version

* Remove version string parsing for route not found

* Remove string parsing for min mariadb version

* Remove string parsing for min mongodb custom data version

* Remove string parsing for min openat2 kernel version

* Use consts in api/version.go

* Generate api/version.go with a go command

* Avoid using a global variable SemVersion

* Keep but deprecate SemVersion in api

* fix-license
2025-04-24 12:58:05 +00:00

155 lines
4.5 KiB
Go

/*
* Teleport
* Copyright (C) 2023 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 <http://www.gnu.org/licenses/>.
*/
package utils
import (
"fmt"
"github.com/coreos/go-semver/semver"
"github.com/gravitational/trace"
)
// MeetsMinVersion returns true if gotVer is empty or at least minVer.
func MeetsMinVersion(gotVer, minVer string) bool {
if gotVer == "" {
return true // Ignore empty versions.
}
err := CheckMinVersion(gotVer, minVer)
// Non BadParameter errors are semver parsing errors.
return !trace.IsBadParameter(err)
}
// MeetsMaxVersion returns true if gotVer is empty or at most maxVer.
func MeetsMaxVersion(gotVer, maxVer string) bool {
if gotVer == "" {
return true // Ignore empty versions.
}
err := CheckMaxVersion(gotVer, maxVer)
// Non BadParameter errors are semver parsing errors.
return !trace.IsBadParameter(err)
}
// CheckMinVersion compares a version with a minimum version supported.
func CheckMinVersion(currentVersion, minVersion string) error {
currentSemver, minSemver, err := versionStringsToSemver(currentVersion, minVersion)
if err != nil {
return trace.Wrap(err)
}
if currentSemver.LessThan(*minSemver) {
return trace.BadParameter("incompatible versions: %v < %v", currentVersion, minVersion)
}
return nil
}
// CheckMaxVersion compares a version with a maximum version supported.
func CheckMaxVersion(currentVersion, maxVersion string) error {
currentSemver, maxSemver, err := versionStringsToSemver(currentVersion, maxVersion)
if err != nil {
return trace.Wrap(err)
}
if maxSemver.LessThan(*currentSemver) {
return trace.BadParameter("incompatible versions: %v > %v", currentVersion, maxVersion)
}
return nil
}
// VersionBeforeAlpha appends "-aa" to the version so that it comes before <version>-alpha.
// This ban be used to make version checks work during development.
func VersionBeforeAlpha(version string) string {
return version + "-aa"
}
// VersionWithoutPreRelease removes the prerelease suffix. Useful when showing
// teleport.MinClientSemVer(), which by default comes with the -aa prerelease.
func VersionWithoutPreRelease(version string) (string, error) {
semver, err := versionStringToSemver(version)
if err != nil {
return "", trace.Wrap(err)
}
semver.PreRelease = ""
return semver.String(), nil
}
// MinVerWithoutPreRelease compares semver strings, but skips prerelease. This allows to compare
// two versions and ignore dev,alpha,beta, etc. strings.
func MinVerWithoutPreRelease(currentVersion, minVersion string) (bool, error) {
currentSemver, minSemver, err := versionStringsToSemver(currentVersion, minVersion)
if err != nil {
return false, trace.Wrap(err)
}
// Erase pre-release string, so only version is compared.
currentSemver.PreRelease = ""
minSemver.PreRelease = ""
return !currentSemver.LessThan(*minSemver), nil
}
// MajorSemver returns the major version as a semver string.
// Ex: 13.4.3 -> 13.0.0
func MajorSemver(version string) (string, error) {
ver, err := semver.NewVersion(version)
if err != nil {
return "", trace.Wrap(err)
}
return fmt.Sprintf("%d.0.0", ver.Major), nil
}
// MajorSemverWithWildcards returns the major version as a semver string.
// Ex: 13.4.3 -> 13.x.x
func MajorSemverWithWildcards(version string) (string, error) {
ver, err := semver.NewVersion(version)
if err != nil {
return "", trace.Wrap(err)
}
return fmt.Sprintf("%d.x.x", ver.Major), nil
}
func versionStringsToSemver(ver1, ver2 string) (*semver.Version, *semver.Version, error) {
v1Semver, err := versionStringToSemver(ver1)
if err != nil {
return nil, nil, trace.Wrap(err)
}
v2Semver, err := versionStringToSemver(ver2)
if err != nil {
return nil, nil, trace.Wrap(err)
}
return v1Semver, v2Semver, nil
}
func versionStringToSemver(ver string) (*semver.Version, error) {
semver, err := semver.NewVersion(ver)
if err != nil {
return nil, trace.Wrap(err, "unsupported version format, need semver format: %q, e.g 1.0.0", semver)
}
return semver, nil
}