@@ -2,34 +2,93 @@ package kubernetes
2
2
3
3
import (
4
4
"context"
5
+ "encoding/json"
5
6
"fmt"
7
+ "strings"
6
8
9
+ "github.com/Masterminds/semver/v3"
7
10
"github.com/cdr/coder-doctor/internal/api"
11
+ "k8s.io/apimachinery/pkg/version"
8
12
)
9
13
10
- func CheckVersion (ctx context.Context , opts api.CheckOptions ) api.CheckResults {
11
- // coderVersion := opts.CoderVersion
14
+ type CoderVersionRequirement struct {
15
+ CoderVersion * semver.Version
16
+ KubernetesVersionMin * semver.Version
17
+ KubernetesVersionMax * semver.Version
18
+ }
19
+
20
+ var versionRequirements = []CoderVersionRequirement {
21
+ {
22
+ CoderVersion : semver .MustParse ("1.21" ),
23
+ KubernetesVersionMin : semver .MustParse ("1.19" ),
24
+ KubernetesVersionMax : semver .MustParse ("1.22" ),
25
+ }, {
26
+ CoderVersion : semver .MustParse ("1.20" ),
27
+ KubernetesVersionMin : semver .MustParse ("1.19" ),
28
+ KubernetesVersionMax : semver .MustParse ("1.21" ),
29
+ },
30
+ }
31
+
32
+ func CheckVersion (ctx context.Context , opts api.CheckOptions ) * api.CheckResult {
33
+ const checkName = "kubernetes-version"
34
+
35
+ coderVersion := opts .CoderVersion
12
36
client := opts .Kubernetes
13
37
14
- versionInfo , err := client .Discovery ().ServerVersion ()
38
+ var versionInfo version.Info
39
+
40
+ // This uses the RESTClient rather than Discovery().ServerVersion()
41
+ // because the latter does not accept a context.
42
+ body , err := client .Discovery ().RESTClient ().Get ().AbsPath ("/version" ).Do (ctx ).Raw ()
43
+ if err != nil {
44
+ return api .ErrorResult (checkName , "failed to get version from server" , err )
45
+ }
46
+
47
+ err = json .Unmarshal (body , & versionInfo )
15
48
if err != nil {
16
- return api.CheckResults {
17
- api.CheckResult {
18
- Name : "kubernetes-version" ,
19
- State : api .StateFailed ,
20
- Summary : "failed to get Kubernetes version from server" ,
21
- Details : map [string ]interface {}{
22
- "error" : err ,
23
- },
24
- },
49
+ return api .ErrorResult (checkName , "failed to parse server version" , err )
50
+ }
51
+
52
+ var v CoderVersionRequirement
53
+ for _ , v = range versionRequirements {
54
+ if ! v .CoderVersion .LessThan (coderVersion ) {
55
+ break
25
56
}
26
57
}
27
58
28
- return api.CheckResults {
29
- api.CheckResult {
30
- Name : "kubernetes-version" ,
31
- State : api .StateInfo ,
32
- Summary : fmt .Sprintf ("kubernetes version: %s" , versionInfo ),
59
+ kubernetesVersion , err := semver .NewVersion (strings .TrimLeft (versionInfo .GitVersion , "v" ))
60
+ if err != nil {
61
+ fmt .Printf ("error parsing version: %v\n " , err )
62
+ }
63
+
64
+ result := & api.CheckResult {
65
+ Name : checkName ,
66
+ Details : map [string ]interface {}{
67
+ "platform" : versionInfo .Platform ,
68
+ "major" : versionInfo .Major ,
69
+ "minor" : versionInfo .Minor ,
70
+ "git-version" : versionInfo .GitVersion ,
71
+ "git-commit" : versionInfo .GitCommit ,
72
+ "git-tree-state" : versionInfo .GitTreeState ,
73
+ "build-date" : versionInfo .BuildDate ,
74
+ "go-version" : versionInfo .GoVersion ,
75
+ "compiler" : versionInfo .Compiler ,
33
76
},
34
77
}
78
+
79
+ if kubernetesVersion .LessThan (v .KubernetesVersionMin ) || kubernetesVersion .GreaterThan (v .KubernetesVersionMax ) {
80
+ result .State = api .StateFailed
81
+ result .Summary = fmt .Sprintf ("Coder %s supports Kubernetes %s to %s and was not tested with %s" ,
82
+ v .CoderVersion , v .KubernetesVersionMin , v .KubernetesVersionMax , kubernetesVersion )
83
+ } else {
84
+ result .State = api .StatePassed
85
+ result .Summary = fmt .Sprintf ("Coder %s supports Kubernetes %s to %s (server version %s)" ,
86
+ v .CoderVersion , v .KubernetesVersionMin , v .KubernetesVersionMax , kubernetesVersion )
87
+ }
88
+
89
+ // fmt.Printf("server version: %v\n", kubernetesVersion)
90
+ // fmt.Printf("min version: %v\n", v.KubernetesVersionMin)
91
+ // fmt.Printf("max version: %v\n", v.KubernetesVersionMax)
92
+
93
+ return result
35
94
}
0 commit comments