-
Notifications
You must be signed in to change notification settings - Fork 149
/
check.go
120 lines (93 loc) · 3.01 KB
/
check.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
package check
import (
"context"
"errors"
"fmt"
"strings"
"github.com/Masterminds/semver/v3"
"github.com/weaveworks/weave-gitops/pkg/flux"
"github.com/weaveworks/weave-gitops/pkg/kube"
)
var ErrKubernetesNotFound = errors.New("no kubernetes version found")
const (
FluxCompatibleMessage = "Current flux version is compatible"
FluxNotCompatibleMessage = "Current flux version is not compatible"
)
// Pre runs pre-install checks
func Pre(ctx context.Context, kubeClient kube.Kube, fluxClient flux.Flux, expectedFluxVersion string) (string, error) {
output := ""
k8sOutput, err := runKubernetesCheck(fluxClient)
if err != nil {
return "", err
}
output += k8sOutput + "\n"
currentFluxVersion, err := getCurrentFluxVersion(ctx, kubeClient)
if err != nil {
if errors.Is(err, kube.ErrNamespaceNotFound) {
output += "✔ Flux is not installed"
return output, nil
}
return "", fmt.Errorf("failed getting installed flux version: %w", err)
}
fluxOutput, err := validateFluxVersion(currentFluxVersion, expectedFluxVersion)
if err != nil {
return "", err
}
output += fluxOutput
return output, nil
}
func runKubernetesCheck(fluxClient flux.Flux) (string, error) {
output, err := fluxClient.PreCheck()
if err != nil {
return "", fmt.Errorf("failed running flux pre check %w", err)
}
lines := strings.Split(output, "\n")
for _, line := range lines {
if strings.Contains(line, "Kubernetes") {
return line, nil
}
}
return "", ErrKubernetesNotFound
}
func getCurrentFluxVersion(ctx context.Context, kubeClient kube.Kube) (string, error) {
namespace, err := kubeClient.FetchNamespaceWithLabel(ctx, flux.PartOfLabelKey, flux.PartOfLabelValue)
if err != nil {
return "", err
}
labels := namespace.GetLabels()
return labels[flux.VersionLabelKey], nil
}
func validateFluxVersion(actualFluxVersion string, expectedFluxVersion string) (string, error) {
actualParsedFluxVersion, err := parseVersion(actualFluxVersion)
if err != nil {
return "", err
}
expectedParsedFluxVersion, err := parseVersion(expectedFluxVersion)
if err != nil {
return "", err
}
fluxOutput := ""
expectedMajor := expectedParsedFluxVersion.Major()
expectedMinor := expectedParsedFluxVersion.Minor()
constraintFormat := fmt.Sprintf("~%d.%d.x", expectedMajor, expectedMinor)
constraint, err := semver.NewConstraint(constraintFormat)
if err != nil {
return "", fmt.Errorf("failed creating semver constraint: %w", err)
}
check := constraint.Check(actualParsedFluxVersion)
if check {
fluxOutput += fmt.Sprintf("✔ Flux %s ~=%s\n", actualParsedFluxVersion, expectedParsedFluxVersion)
fluxOutput += FluxCompatibleMessage
} else {
fluxOutput += fmt.Sprintf("✗ Flux %s !=%s\n", actualParsedFluxVersion, constraintFormat)
fluxOutput += FluxNotCompatibleMessage
}
return fluxOutput, nil
}
func parseVersion(version string) (*semver.Version, error) {
versionLessV := strings.TrimPrefix(version, "v")
if _, err := semver.StrictNewVersion(versionLessV); err != nil {
return nil, err
}
return semver.NewVersion(version)
}