1
1
package config
2
2
3
3
import (
4
+ "errors"
4
5
"fmt"
5
6
7
+ "github.com/replicatedhq/embedded-cluster/api/types"
6
8
kotsv1beta1 "github.com/replicatedhq/kotskinds/apis/kots/v1beta1"
7
9
"github.com/replicatedhq/kotskinds/multitype"
8
10
"github.com/tiendc/go-deepcopy"
9
11
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10
12
)
11
13
14
+ var (
15
+ ErrConfigItemRequired = errors .New ("item is required" )
16
+ ErrConfigValueNotFound = errors .New ("value not found" )
17
+ )
18
+
12
19
func (m * appConfigManager ) GetConfig (config kotsv1beta1.Config ) (kotsv1beta1.Config , error ) {
13
20
return filterAppConfig (config )
14
21
}
@@ -17,6 +24,42 @@ func (m *appConfigManager) GetConfigValues() (map[string]string, error) {
17
24
return m .appConfigStore .GetConfigValues ()
18
25
}
19
26
27
+ func (m * appConfigManager ) ValidateConfigValues (config kotsv1beta1.Config , configValues map [string ]string ) error {
28
+ var ve * types.APIError
29
+
30
+ configItems := make (map [string ]kotsv1beta1.ConfigItem )
31
+ configChildItems := make (map [string ]kotsv1beta1.ConfigChildItem )
32
+
33
+ // first check required items
34
+ for _ , group := range config .Spec .Groups {
35
+ for _ , item := range group .Items {
36
+ configItems [item .Name ] = item
37
+
38
+ configValue := getConfigValueFromItem (item , configValues )
39
+ if isRequiredItem (item ) && isUnsetItem (configValue ) {
40
+ ve = types .AppendFieldError (ve , item .Name , ErrConfigItemRequired )
41
+ }
42
+
43
+ for _ , childItem := range item .Items {
44
+ configChildItems [childItem .Name ] = childItem
45
+ }
46
+ }
47
+ }
48
+
49
+ // then check if all the config values are present
50
+ for name := range configValues {
51
+ if _ , ok := configItems [name ]; ok {
52
+ continue
53
+ }
54
+ if _ , ok := configChildItems [name ]; ok {
55
+ continue
56
+ }
57
+ ve = types .AppendFieldError (ve , name , ErrConfigValueNotFound )
58
+ }
59
+
60
+ return ve .ErrorOrNil ()
61
+ }
62
+
20
63
func (m * appConfigManager ) SetConfigValues (config kotsv1beta1.Config , configValues map [string ]string ) error {
21
64
filteredValues := make (map [string ]string )
22
65
@@ -42,14 +85,18 @@ func (m *appConfigManager) SetConfigValues(config kotsv1beta1.Config, configValu
42
85
}
43
86
44
87
func (m * appConfigManager ) GetKotsadmConfigValues (config kotsv1beta1.Config ) (kotsv1beta1.ConfigValues , error ) {
45
- filteredConfig , err := m .GetConfig ( config )
88
+ storedValues , err := m .GetConfigValues ( )
46
89
if err != nil {
47
- return kotsv1beta1.ConfigValues {}, fmt .Errorf ("get config: %w" , err )
90
+ return kotsv1beta1.ConfigValues {}, fmt .Errorf ("get config values : %w" , err )
48
91
}
49
92
50
- storedValues , err := m .GetConfigValues ()
93
+ return m .getKotsadmConfigValues (config , storedValues )
94
+ }
95
+
96
+ func (m * appConfigManager ) getKotsadmConfigValues (config kotsv1beta1.Config , configValues map [string ]string ) (kotsv1beta1.ConfigValues , error ) {
97
+ filteredConfig , err := m .GetConfig (config )
51
98
if err != nil {
52
- return kotsv1beta1.ConfigValues {}, fmt .Errorf ("get config values : %w" , err )
99
+ return kotsv1beta1.ConfigValues {}, fmt .Errorf ("get config: %w" , err )
53
100
}
54
101
55
102
kotsadmConfigValues := kotsv1beta1.ConfigValues {
@@ -68,33 +115,43 @@ func (m *appConfigManager) GetKotsadmConfigValues(config kotsv1beta1.Config) (ko
68
115
// add values from the filtered config
69
116
for _ , group := range filteredConfig .Spec .Groups {
70
117
for _ , item := range group .Items {
71
- configValue := kotsv1beta1.ConfigValue {
72
- Value : item .Value .String (),
73
- Default : item .Default .String (),
74
- }
75
- // override values from the config values store
76
- if value , ok := storedValues [item .Name ]; ok {
77
- configValue .Value = value
78
- }
79
- kotsadmConfigValues .Spec .Values [item .Name ] = configValue
118
+ kotsadmConfigValues .Spec .Values [item .Name ] = getConfigValueFromItem (item , configValues )
80
119
81
- for _ , subItem := range item .Items {
82
- subConfigValue := kotsv1beta1.ConfigValue {
83
- Value : subItem .Value .String (),
84
- Default : subItem .Default .String (),
85
- }
86
- // override values from the config values store
87
- if value , ok := storedValues [subItem .Name ]; ok {
88
- subConfigValue .Value = value
89
- }
90
- kotsadmConfigValues .Spec .Values [subItem .Name ] = subConfigValue
120
+ for _ , childItem := range item .Items {
121
+ kotsadmConfigValues .Spec .Values [childItem .Name ] = getConfigValueFromChildItem (childItem , configValues )
91
122
}
92
123
}
93
124
}
94
125
95
126
return kotsadmConfigValues , nil
96
127
}
97
128
129
+ func getConfigValueFromItem (item kotsv1beta1.ConfigItem , configValues map [string ]string ) kotsv1beta1.ConfigValue {
130
+ configValue := kotsv1beta1.ConfigValue {
131
+ Value : item .Value .String (),
132
+ Default : item .Default .String (),
133
+ }
134
+ // override values from the config values store
135
+ value , ok := configValues [item .Name ]
136
+ if ok {
137
+ configValue .Value = value
138
+ }
139
+ return configValue
140
+ }
141
+
142
+ func getConfigValueFromChildItem (item kotsv1beta1.ConfigChildItem , configValues map [string ]string ) kotsv1beta1.ConfigValue {
143
+ configValue := kotsv1beta1.ConfigValue {
144
+ Value : item .Value .String (),
145
+ Default : item .Default .String (),
146
+ }
147
+ // override values from the config values store
148
+ value , ok := configValues [item .Name ]
149
+ if ok {
150
+ configValue .Value = value
151
+ }
152
+ return configValue
153
+ }
154
+
98
155
// filterAppConfig filters out disabled groups and items based on their 'when' condition
99
156
func filterAppConfig (config kotsv1beta1.Config ) (kotsv1beta1.Config , error ) {
100
157
// deepcopy the config to avoid mutating the original config
@@ -129,3 +186,19 @@ func filterAppConfig(config kotsv1beta1.Config) (kotsv1beta1.Config, error) {
129
186
func isItemEnabled (when multitype.QuotedBool ) bool {
130
187
return when != "false"
131
188
}
189
+
190
+ func isRequiredItem (item kotsv1beta1.ConfigItem ) bool {
191
+ if ! item .Required {
192
+ return false
193
+ }
194
+ // TODO: should an item really not be required if it's hidden?
195
+ if item .Hidden || item .When == "false" {
196
+ return false
197
+ }
198
+ return true
199
+ }
200
+
201
+ func isUnsetItem (configValue kotsv1beta1.ConfigValue ) bool {
202
+ // TODO: repeatable items
203
+ return configValue .Value == "" && configValue .Default == ""
204
+ }
0 commit comments