-
Notifications
You must be signed in to change notification settings - Fork 320
/
version.go
121 lines (99 loc) · 3.05 KB
/
version.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Cilium
// Package version keeps track of the Kubernetes version the client is
// connected to
package version
import (
"fmt"
"github.com/cilium/cilium/pkg/lock"
"github.com/cilium/cilium/pkg/versioncheck"
semver "github.com/blang/semver/v4"
"k8s.io/client-go/kubernetes"
)
// ServerCapabilities is a list of server capabilities derived based on
// version, the Kubernetes discovery API, or probing of individual API
// endpoints.
type ServerCapabilities struct {
// MinimalVersionMet is true when the minimal version of Kubernetes
// required to run Cilium has been met
MinimalVersionMet bool
// APIExtensionsV1CRD is set to true when the K8s server supports
// apiextensions/v1 CRDs. TODO: Add link to docs
//
// This capability was introduced in K8s version 1.16, prior to which
// apiextensions/v1beta1 CRDs were used exclusively.
APIExtensionsV1CRD bool
}
type cachedVersion struct {
mutex lock.RWMutex
capabilities ServerCapabilities
version semver.Version
}
const (
// MinimalVersionConstraint is the minimal version that Cilium supports to
// run kubernetes.
MinimalVersionConstraint = "1.16.0"
)
var (
cached = cachedVersion{}
// Constraint to check support for apiextensions/v1 CRD types. Support for
// v1 CRDs was introduced in K8s version 1.16.
isGEThanAPIExtensionsV1CRD = versioncheck.MustCompile(">=1.16.0")
// isGEThanMinimalVersionConstraint is the minimal version required to run
// Cilium
isGEThanMinimalVersionConstraint = versioncheck.MustCompile(">=" + MinimalVersionConstraint)
)
// Version returns the version of the Kubernetes apiserver
func Version() semver.Version {
cached.mutex.RLock()
c := cached.version
cached.mutex.RUnlock()
return c
}
// Capabilities returns the capabilities of the Kubernetes apiserver
func Capabilities() ServerCapabilities {
cached.mutex.RLock()
c := cached.capabilities
cached.mutex.RUnlock()
return c
}
func updateVersion(version semver.Version) {
cached.mutex.Lock()
defer cached.mutex.Unlock()
cached.version = version
cached.capabilities.MinimalVersionMet = isGEThanMinimalVersionConstraint(version)
cached.capabilities.APIExtensionsV1CRD = isGEThanAPIExtensionsV1CRD(version)
}
// Force forces the use of a specific version
func Force(version string) error {
ver, err := versioncheck.Version(version)
if err != nil {
return err
}
updateVersion(ver)
return nil
}
func UpdateK8sServerVersion(client kubernetes.Interface) error {
var ver semver.Version
sv, err := client.Discovery().ServerVersion()
if err != nil {
return err
}
// Try GitVersion first. In case of error fallback to MajorMinor
if sv.GitVersion != "" {
// This is a string like "v1.9.0"
ver, err = versioncheck.Version(sv.GitVersion)
if err == nil {
updateVersion(ver)
return nil
}
}
if sv.Major != "" && sv.Minor != "" {
ver, err = versioncheck.Version(fmt.Sprintf("%s.%s", sv.Major, sv.Minor))
if err == nil {
updateVersion(ver)
return nil
}
}
return fmt.Errorf("cannot parse k8s server version from %+v: %s", sv, err)
}