-
Notifications
You must be signed in to change notification settings - Fork 0
/
dogu.go
142 lines (116 loc) · 3.8 KB
/
dogu.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package validation
import (
"fmt"
"strings"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
"github.com/cloudogu/cesapp-lib/core"
"github.com/cloudogu/cesapp-lib/remote"
"github.com/cloudogu/k8s-ces-setup/app/context"
)
type doguValidator struct {
secret corev1.Secret
Registry remote.Registry
}
// NewDoguValidator creates a new validator for the dogu region of the setup configuration.
func NewDoguValidator(registry remote.Registry) *doguValidator {
return &doguValidator{Registry: registry}
}
// ValidateDogus check whether the configured dogu has no invalid or unmet dependencies.
func (dv *doguValidator) ValidateDogus(dogus context.Dogus) error {
doguList, err := dv.parseDoguStrToDoguList(dogus.Install)
if err != nil {
return err
}
isDeafultDoguValid := false
for _, dogu := range dogus.Install {
if strings.Contains(dogu, dogus.DefaultDogu) {
isDeafultDoguValid = true
}
}
if !isDeafultDoguValid {
return fmt.Errorf("invalid value for default dogu [%s]", dogus.DefaultDogu)
}
for _, installDogu := range doguList {
err = dv.validateDoguDependencies(doguList, installDogu.GetDependenciesOfType("dogu"))
if err != nil {
return fmt.Errorf("failed to validate dependencies for dogu %s: %w", installDogu.Name, err)
}
}
return nil
}
func (dv *doguValidator) parseDoguStrToDoguList(dogus []string) ([]*core.Dogu, error) {
var doguList = make([]*core.Dogu, len(dogus))
for i, doguStr := range dogus {
dogu, err := dv.getDoguFromVersionStr(doguStr)
if err != nil {
return nil, err
}
doguList[i] = dogu
}
return doguList, nil
}
func (dv *doguValidator) validateDoguDependencies(dogus []*core.Dogu, dependencies []core.Dependency) error {
for _, dependency := range dependencies {
depName := dependency.Name
if depName == "nginx" || depName == "registrator" {
continue
}
dependentDogu, err := dv.getDoguFromSelection(dogus, depName)
if err != nil {
return fmt.Errorf("dogu dependency %s ist not selected", depName)
}
if dependency.Version == "" {
continue
}
allows, err := isDependencyVersionAllowed(dependentDogu, dependency)
if err != nil {
return err
}
if !allows {
return errors.Errorf("%s parsed Version does not fulfill version requirement of %s dogu %s", dependentDogu.Version, dependency.Version, dependency.Name)
}
}
return nil
}
func isDependencyVersionAllowed(dependentDogu *core.Dogu, dependency core.Dependency) (bool, error) {
doguVersion, err := core.ParseVersion(dependentDogu.Version)
if err != nil {
return false, errors.Wrapf(err, "failed to parse version of dependency %s", dependency.Name)
}
comparator, err := core.ParseVersionComparator(dependency.Version)
if err != nil {
return false, errors.Wrapf(err, "failed to parse ParseVersionComparator of version %s for doguDependency %s", dependency.Version, dependency.Name)
}
allows, err := comparator.Allows(doguVersion)
if err != nil {
return false, errors.Wrapf(err, "An error occurred when comparing the versions")
}
return allows, nil
}
func (dv *doguValidator) getDoguFromSelection(dogus []*core.Dogu, doguName string) (*core.Dogu, error) {
for _, installDogu := range dogus {
if installDogu.GetSimpleName() == doguName {
return installDogu, nil
}
}
return nil, fmt.Errorf("dogu not found")
}
func (dv *doguValidator) getDoguFromVersionStr(doguStr string) (*core.Dogu, error) {
namespacedName, version, found := strings.Cut(doguStr, ":")
var dogu *core.Dogu
var err error
if found {
v, vErr := core.ParseVersion(version)
if vErr != nil {
return nil, fmt.Errorf("failed to parse dogu version %s: %w", version, err)
}
dogu, err = dv.Registry.GetVersion(namespacedName, v.Raw)
} else {
dogu, err = dv.Registry.Get(namespacedName)
}
if err != nil {
return nil, fmt.Errorf("failed to get dogu %s: %w", doguStr, err)
}
return dogu, nil
}