get k8s version through k8sclient
This commit is contained in:
4
Gopkg.lock
generated
4
Gopkg.lock
generated
@@ -742,11 +742,12 @@
|
|||||||
version = "v7.0.0"
|
version = "v7.0.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:1de91645e73441071e6df50478003c60881687cf9849ba0585a61035a6d2a2af"
|
digest = "1:2bdbea32607f4effd9e91dadd90baab1ecf224839b613bcaa8f50db5a5f133f5"
|
||||||
name = "k8s.io/kubernetes"
|
name = "k8s.io/kubernetes"
|
||||||
packages = [
|
packages = [
|
||||||
"pkg/apis/core",
|
"pkg/apis/core",
|
||||||
"pkg/util/slice",
|
"pkg/util/slice",
|
||||||
|
"pkg/util/version",
|
||||||
]
|
]
|
||||||
pruneopts = "UT"
|
pruneopts = "UT"
|
||||||
revision = "5ca598b4ba5abb89bb773071ce452e33fb66339d"
|
revision = "5ca598b4ba5abb89bb773071ce452e33fb66339d"
|
||||||
@@ -800,6 +801,7 @@
|
|||||||
"k8s.io/client-go/tools/remotecommand",
|
"k8s.io/client-go/tools/remotecommand",
|
||||||
"k8s.io/kubernetes/pkg/apis/core",
|
"k8s.io/kubernetes/pkg/apis/core",
|
||||||
"k8s.io/kubernetes/pkg/util/slice",
|
"k8s.io/kubernetes/pkg/util/slice",
|
||||||
|
"k8s.io/kubernetes/pkg/util/version",
|
||||||
]
|
]
|
||||||
solver-name = "gps-cdcl"
|
solver-name = "gps-cdcl"
|
||||||
solver-version = 1
|
solver-version = 1
|
||||||
|
|||||||
@@ -36,8 +36,7 @@ import (
|
|||||||
|
|
||||||
"k8s.io/kubernetes/pkg/apis/core"
|
"k8s.io/kubernetes/pkg/apis/core"
|
||||||
|
|
||||||
"strconv"
|
utilversion "k8s.io/kubernetes/pkg/util/version"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"kubesphere.io/kubesphere/pkg/client"
|
"kubesphere.io/kubesphere/pkg/client"
|
||||||
"kubesphere.io/kubesphere/pkg/constants"
|
"kubesphere.io/kubesphere/pkg/constants"
|
||||||
@@ -232,21 +231,14 @@ func (ctl *NamespaceCtl) createRoleAndRuntime(item v1.Namespace) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ctl *NamespaceCtl) createCephSecretAfterNewNs(item v1.Namespace) {
|
func (ctl *NamespaceCtl) createCephSecretAfterNewNs(item v1.Namespace) {
|
||||||
// Kubernetes version must <= 1.10
|
// Kubernetes version must < 1.11.0
|
||||||
openInfo, err := ctl.K8sClient.OpenAPISchema()
|
verInfo, err := ctl.K8sClient.ServerVersion()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Error("consult openAPI error: ", err)
|
glog.Error("consult k8s server error: ", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if openInfo == nil {
|
if !utilversion.MustParseSemantic(verInfo.String()).LessThan(utilversion.MustParseSemantic("v1.11.0")) {
|
||||||
glog.Error("cannot find openAPI info")
|
glog.Infof("disable Ceph secret controller due to k8s version %s >= v1.11.0", verInfo.String())
|
||||||
return
|
|
||||||
}
|
|
||||||
ver := strings.Split(openInfo.GetInfo().GetVersion(), ".")
|
|
||||||
midVer, _ := strconv.Atoi(ver[1])
|
|
||||||
if !(ver[0] == "v1" && midVer < 11) {
|
|
||||||
glog.Infof("disable Ceph secret controller due to Kubernetes version %s mismatch",
|
|
||||||
openInfo.GetInfo().GetVersion())
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"strconv"
|
utilversion "k8s.io/kubernetes/pkg/util/version"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
coreV1 "k8s.io/api/core/v1"
|
coreV1 "k8s.io/api/core/v1"
|
||||||
@@ -95,21 +94,14 @@ func (ctl *StorageClassCtl) total() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ctl *StorageClassCtl) createCephSecretAfterNewSc(item v1.StorageClass) {
|
func (ctl *StorageClassCtl) createCephSecretAfterNewSc(item v1.StorageClass) {
|
||||||
// Kubernetes version must <= 1.10
|
// Kubernetes version must < 1.11.0
|
||||||
openInfo, err := ctl.K8sClient.OpenAPISchema()
|
verInfo, err := ctl.K8sClient.ServerVersion()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Error("consult openAPI error: ", err)
|
glog.Error("consult k8s server error: ", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if openInfo == nil {
|
if !utilversion.MustParseSemantic(verInfo.String()).LessThan(utilversion.MustParseSemantic("v1.11.0")) {
|
||||||
glog.Error("cannot find openAPI info")
|
glog.Infof("disable Ceph secret controller due to k8s version %s >= v1.11.0", verInfo.String())
|
||||||
return
|
|
||||||
}
|
|
||||||
ver := strings.Split(openInfo.GetInfo().GetVersion(), ".")
|
|
||||||
midVer, _ := strconv.Atoi(ver[1])
|
|
||||||
if !(ver[0] == "v1" && midVer < 11) {
|
|
||||||
glog.Infof("disable Ceph secret controller due to Kubernetes version %s mismatch",
|
|
||||||
openInfo.GetInfo().GetVersion())
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
35
vendor/k8s.io/kubernetes/pkg/util/version/BUILD
generated
vendored
Normal file
35
vendor/k8s.io/kubernetes/pkg/util/version/BUILD
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
load(
|
||||||
|
"@io_bazel_rules_go//go:def.bzl",
|
||||||
|
"go_library",
|
||||||
|
"go_test",
|
||||||
|
)
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = [
|
||||||
|
"doc.go",
|
||||||
|
"version.go",
|
||||||
|
],
|
||||||
|
importpath = "k8s.io/kubernetes/pkg/util/version",
|
||||||
|
)
|
||||||
|
|
||||||
|
go_test(
|
||||||
|
name = "go_default_test",
|
||||||
|
srcs = ["version_test.go"],
|
||||||
|
embed = [":go_default_library"],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "package-srcs",
|
||||||
|
srcs = glob(["**"]),
|
||||||
|
tags = ["automanaged"],
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "all-srcs",
|
||||||
|
srcs = [":package-srcs"],
|
||||||
|
tags = ["automanaged"],
|
||||||
|
)
|
||||||
18
vendor/k8s.io/kubernetes/pkg/util/version/doc.go
generated
vendored
Normal file
18
vendor/k8s.io/kubernetes/pkg/util/version/doc.go
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2016 The Kubernetes Authors.
|
||||||
|
|
||||||
|
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 version provides utilities for version number comparisons
|
||||||
|
package version // import "k8s.io/kubernetes/pkg/util/version"
|
||||||
285
vendor/k8s.io/kubernetes/pkg/util/version/version.go
generated
vendored
Normal file
285
vendor/k8s.io/kubernetes/pkg/util/version/version.go
generated
vendored
Normal file
@@ -0,0 +1,285 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2016 The Kubernetes Authors.
|
||||||
|
|
||||||
|
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 version
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Version is an opqaue representation of a version number
|
||||||
|
type Version struct {
|
||||||
|
components []uint
|
||||||
|
semver bool
|
||||||
|
preRelease string
|
||||||
|
buildMetadata string
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
// versionMatchRE splits a version string into numeric and "extra" parts
|
||||||
|
versionMatchRE = regexp.MustCompile(`^\s*v?([0-9]+(?:\.[0-9]+)*)(.*)*$`)
|
||||||
|
// extraMatchRE splits the "extra" part of versionMatchRE into semver pre-release and build metadata; it does not validate the "no leading zeroes" constraint for pre-release
|
||||||
|
extraMatchRE = regexp.MustCompile(`^(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?\s*$`)
|
||||||
|
)
|
||||||
|
|
||||||
|
func parse(str string, semver bool) (*Version, error) {
|
||||||
|
parts := versionMatchRE.FindStringSubmatch(str)
|
||||||
|
if parts == nil {
|
||||||
|
return nil, fmt.Errorf("could not parse %q as version", str)
|
||||||
|
}
|
||||||
|
numbers, extra := parts[1], parts[2]
|
||||||
|
|
||||||
|
components := strings.Split(numbers, ".")
|
||||||
|
if (semver && len(components) != 3) || (!semver && len(components) < 2) {
|
||||||
|
return nil, fmt.Errorf("illegal version string %q", str)
|
||||||
|
}
|
||||||
|
|
||||||
|
v := &Version{
|
||||||
|
components: make([]uint, len(components)),
|
||||||
|
semver: semver,
|
||||||
|
}
|
||||||
|
for i, comp := range components {
|
||||||
|
if (i == 0 || semver) && strings.HasPrefix(comp, "0") && comp != "0" {
|
||||||
|
return nil, fmt.Errorf("illegal zero-prefixed version component %q in %q", comp, str)
|
||||||
|
}
|
||||||
|
num, err := strconv.ParseUint(comp, 10, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("illegal non-numeric version component %q in %q: %v", comp, str, err)
|
||||||
|
}
|
||||||
|
v.components[i] = uint(num)
|
||||||
|
}
|
||||||
|
|
||||||
|
if semver && extra != "" {
|
||||||
|
extraParts := extraMatchRE.FindStringSubmatch(extra)
|
||||||
|
if extraParts == nil {
|
||||||
|
return nil, fmt.Errorf("could not parse pre-release/metadata (%s) in version %q", extra, str)
|
||||||
|
}
|
||||||
|
v.preRelease, v.buildMetadata = extraParts[1], extraParts[2]
|
||||||
|
|
||||||
|
for _, comp := range strings.Split(v.preRelease, ".") {
|
||||||
|
if _, err := strconv.ParseUint(comp, 10, 0); err == nil {
|
||||||
|
if strings.HasPrefix(comp, "0") && comp != "0" {
|
||||||
|
return nil, fmt.Errorf("illegal zero-prefixed version component %q in %q", comp, str)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseGeneric parses a "generic" version string. The version string must consist of two
|
||||||
|
// or more dot-separated numeric fields (the first of which can't have leading zeroes),
|
||||||
|
// followed by arbitrary uninterpreted data (which need not be separated from the final
|
||||||
|
// numeric field by punctuation). For convenience, leading and trailing whitespace is
|
||||||
|
// ignored, and the version can be preceded by the letter "v". See also ParseSemantic.
|
||||||
|
func ParseGeneric(str string) (*Version, error) {
|
||||||
|
return parse(str, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MustParseGeneric is like ParseGeneric except that it panics on error
|
||||||
|
func MustParseGeneric(str string) *Version {
|
||||||
|
v, err := ParseGeneric(str)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseSemantic parses a version string that exactly obeys the syntax and semantics of
|
||||||
|
// the "Semantic Versioning" specification (http://semver.org/) (although it ignores
|
||||||
|
// leading and trailing whitespace, and allows the version to be preceded by "v"). For
|
||||||
|
// version strings that are not guaranteed to obey the Semantic Versioning syntax, use
|
||||||
|
// ParseGeneric.
|
||||||
|
func ParseSemantic(str string) (*Version, error) {
|
||||||
|
return parse(str, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MustParseSemantic is like ParseSemantic except that it panics on error
|
||||||
|
func MustParseSemantic(str string) *Version {
|
||||||
|
v, err := ParseSemantic(str)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Major returns the major release number
|
||||||
|
func (v *Version) Major() uint {
|
||||||
|
return v.components[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Minor returns the minor release number
|
||||||
|
func (v *Version) Minor() uint {
|
||||||
|
return v.components[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Patch returns the patch release number if v is a Semantic Version, or 0
|
||||||
|
func (v *Version) Patch() uint {
|
||||||
|
if len(v.components) < 3 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return v.components[2]
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildMetadata returns the build metadata, if v is a Semantic Version, or ""
|
||||||
|
func (v *Version) BuildMetadata() string {
|
||||||
|
return v.buildMetadata
|
||||||
|
}
|
||||||
|
|
||||||
|
// PreRelease returns the prerelease metadata, if v is a Semantic Version, or ""
|
||||||
|
func (v *Version) PreRelease() string {
|
||||||
|
return v.preRelease
|
||||||
|
}
|
||||||
|
|
||||||
|
// Components returns the version number components
|
||||||
|
func (v *Version) Components() []uint {
|
||||||
|
return v.components
|
||||||
|
}
|
||||||
|
|
||||||
|
// String converts a Version back to a string; note that for versions parsed with
|
||||||
|
// ParseGeneric, this will not include the trailing uninterpreted portion of the version
|
||||||
|
// number.
|
||||||
|
func (v *Version) String() string {
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
|
||||||
|
for i, comp := range v.components {
|
||||||
|
if i > 0 {
|
||||||
|
buffer.WriteString(".")
|
||||||
|
}
|
||||||
|
buffer.WriteString(fmt.Sprintf("%d", comp))
|
||||||
|
}
|
||||||
|
if v.preRelease != "" {
|
||||||
|
buffer.WriteString("-")
|
||||||
|
buffer.WriteString(v.preRelease)
|
||||||
|
}
|
||||||
|
if v.buildMetadata != "" {
|
||||||
|
buffer.WriteString("+")
|
||||||
|
buffer.WriteString(v.buildMetadata)
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// compareInternal returns -1 if v is less than other, 1 if it is greater than other, or 0
|
||||||
|
// if they are equal
|
||||||
|
func (v *Version) compareInternal(other *Version) int {
|
||||||
|
|
||||||
|
vLen := len(v.components)
|
||||||
|
oLen := len(other.components)
|
||||||
|
for i := 0; i < vLen && i < oLen; i++ {
|
||||||
|
switch {
|
||||||
|
case other.components[i] < v.components[i]:
|
||||||
|
return 1
|
||||||
|
case other.components[i] > v.components[i]:
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If components are common but one has more items and they are not zeros, it is bigger
|
||||||
|
switch {
|
||||||
|
case oLen < vLen && !onlyZeros(v.components[oLen:]):
|
||||||
|
return 1
|
||||||
|
case oLen > vLen && !onlyZeros(other.components[vLen:]):
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
if !v.semver || !other.semver {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case v.preRelease == "" && other.preRelease != "":
|
||||||
|
return 1
|
||||||
|
case v.preRelease != "" && other.preRelease == "":
|
||||||
|
return -1
|
||||||
|
case v.preRelease == other.preRelease: // includes case where both are ""
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
vPR := strings.Split(v.preRelease, ".")
|
||||||
|
oPR := strings.Split(other.preRelease, ".")
|
||||||
|
for i := 0; i < len(vPR) && i < len(oPR); i++ {
|
||||||
|
vNum, err := strconv.ParseUint(vPR[i], 10, 0)
|
||||||
|
if err == nil {
|
||||||
|
oNum, err := strconv.ParseUint(oPR[i], 10, 0)
|
||||||
|
if err == nil {
|
||||||
|
switch {
|
||||||
|
case oNum < vNum:
|
||||||
|
return 1
|
||||||
|
case oNum > vNum:
|
||||||
|
return -1
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if oPR[i] < vPR[i] {
|
||||||
|
return 1
|
||||||
|
} else if oPR[i] > vPR[i] {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case len(oPR) < len(vPR):
|
||||||
|
return 1
|
||||||
|
case len(oPR) > len(vPR):
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns false if array contain any non-zero element
|
||||||
|
func onlyZeros(array []uint) bool {
|
||||||
|
for _, num := range array {
|
||||||
|
if num != 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// AtLeast tests if a version is at least equal to a given minimum version. If both
|
||||||
|
// Versions are Semantic Versions, this will use the Semantic Version comparison
|
||||||
|
// algorithm. Otherwise, it will compare only the numeric components, with non-present
|
||||||
|
// components being considered "0" (ie, "1.4" is equal to "1.4.0").
|
||||||
|
func (v *Version) AtLeast(min *Version) bool {
|
||||||
|
return v.compareInternal(min) != -1
|
||||||
|
}
|
||||||
|
|
||||||
|
// LessThan tests if a version is less than a given version. (It is exactly the opposite
|
||||||
|
// of AtLeast, for situations where asking "is v too old?" makes more sense than asking
|
||||||
|
// "is v new enough?".)
|
||||||
|
func (v *Version) LessThan(other *Version) bool {
|
||||||
|
return v.compareInternal(other) == -1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare compares v against a version string (which will be parsed as either Semantic
|
||||||
|
// or non-Semantic depending on v). On success it returns -1 if v is less than other, 1 if
|
||||||
|
// it is greater than other, or 0 if they are equal.
|
||||||
|
func (v *Version) Compare(other string) (int, error) {
|
||||||
|
ov, err := parse(other, v.semver)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return v.compareInternal(ov), nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user