diff --git a/utils/meta.go b/utils/meta.go index e21fcecb3082dddd8c3271e46c90e98ee1faac0f..9548969b2c3e36769012ebbb44da8ec651509f25 100644 --- a/utils/meta.go +++ b/utils/meta.go @@ -6,6 +6,7 @@ import ( "strconv" "strings" + "github.com/blang/semver" log "github.com/sirupsen/logrus" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -21,6 +22,38 @@ type ServerVersion struct { // ParseVersion parses version.Info into a ServerVersion struct func ParseVersion(v *version.Info) (ret ServerVersion, err error) { + // + // Note: It is not advisable to use the Major / Minor version pair returned + // by The ServerVersion as it may be empty. We will use the GitVersion as + // it appears to always be populated, and is the return value provided by + // client-go's v.String(). + // + // As a safety precaution, we will still default to the Major / Minor version, + // if the GitVersion fails. + // + + versionString := v.String() + if len(versionString) >= 1 { + // trim off "v" infront of version since it is invalid semver syntax. + versionString = versionString[1:] + } + + version, err := semver.Make(versionString) + if err != nil { + ret, err = parseFromMajorMinor(v) + if err != nil { + err = fmt.Errorf("Server version '%s' does not conform to semver format", versionString) + } + return + } + + ret.Major = int(version.Major) + ret.Minor = int(version.Minor) + + return +} + +func parseFromMajorMinor(v *version.Info) (ret ServerVersion, err error) { re := regexp.MustCompile("[0-9]+") major := re.FindAllString(v.Major, 1) @@ -44,6 +77,7 @@ func ParseVersion(v *version.Info) (ret ServerVersion, err error) { if err != nil { return } + return } diff --git a/utils/meta_test.go b/utils/meta_test.go index ea9f30bbf396d46315d3817d0f51da8506645a24..ac570c5ef104f83d24bca33f293554201ac40ce6 100644 --- a/utils/meta_test.go +++ b/utils/meta_test.go @@ -17,6 +17,20 @@ func TestParseVersion(t *testing.T) { expected ServerVersion error bool }{ + { + input: version.Info{GitVersion: "v1.7.0"}, + expected: ServerVersion{Major: 1, Minor: 7}, + }, + { + input: version.Info{GitVersion: "v1.7.11-gke.1"}, + expected: ServerVersion{Major: 1, Minor: 7}, + }, + // Bad GitVersion case + { + input: version.Info{Major: "1", Minor: "6", GitVersion: "invalid"}, + expected: ServerVersion{Major: 1, Minor: 6}, + }, + // GitVersion does not exist cases { input: version.Info{Major: "1", Minor: "6"}, expected: ServerVersion{Major: 1, Minor: 6},