Skip to content
This repository was archived by the owner on Mar 24, 2023. It is now read-only.

Commit 63c14e7

Browse files
authored
Merge pull request #91 from dexhorthy/dex/ch9821/hidden-default-when
Fix for rendering fields with `when`
2 parents d52d20c + 2a7f22c commit 63c14e7

13 files changed

+307
-21
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ state.json
66
.idea
77
.vscode
88
installer/
9+
.ship/

pkg/lifecycle/render/config/api.go

+26-3
Original file line numberDiff line numberDiff line change
@@ -181,18 +181,23 @@ func (r *APIConfigRenderer) ResolveConfig(
181181
liveValues map[string]interface{},
182182
) ([]libyaml.ConfigGroup, error) {
183183
resolvedConfig := make([]libyaml.ConfigGroup, 0, 0)
184+
configCopy, err := r.deepCopyConfig(release.Spec.Config.V1)
185+
if err != nil {
186+
return resolvedConfig, errors.Wrap(err, "deep copy config")
187+
}
188+
189+
updatedValues, err := resolveConfigValuesMap(liveValues, configCopy, r.Logger, r.Viper)
184190

185-
updatedValues, err := resolveConfigValuesMap(liveValues, release.Spec.Config.V1, r.Logger, r.Viper)
186191
if err != nil {
187-
return resolvedConfig, errors.Wrap(err, "resolve config values map")
192+
return resolvedConfig, errors.Wrap(err, "resolve configCopy values map")
188193
}
189194

190195
builder, err := r.newBuilder(ctx, release, updatedValues)
191196
if err != nil {
192197
return resolvedConfig, errors.Wrap(err, "initialize tpl builder")
193198
}
194199

195-
for _, configGroup := range release.Spec.Config.V1 {
200+
for _, configGroup := range configCopy {
196201
resolvedItems := make([]*libyaml.ConfigItem, 0, 0)
197202
for _, configItem := range configGroup.Items {
198203

@@ -416,3 +421,21 @@ func (r *APIConfigRenderer) resolveConfigChildItem(ctx context.Context, builder
416421
// TODO
417422
return configChildItem, nil
418423
}
424+
func (r *APIConfigRenderer) deepCopyConfig(groups []libyaml.ConfigGroup) ([]libyaml.ConfigGroup, error) {
425+
var buf bytes.Buffer
426+
enc := json.NewEncoder(&buf)
427+
dec := json.NewDecoder(&buf)
428+
err := enc.Encode(groups)
429+
if err != nil {
430+
return nil, errors.Wrapf(err, "encode group")
431+
}
432+
433+
level.Debug(r.Logger).Log("event", "deepCopyConfig.encode", "encoded", buf.String())
434+
435+
var groupsCopy []libyaml.ConfigGroup
436+
err = dec.Decode(&groupsCopy)
437+
if err != nil {
438+
return nil, errors.Wrapf(err, "decode group")
439+
}
440+
return groupsCopy, nil
441+
}

pkg/lifecycle/render/config/api_test.go

+21-8
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ type apiTestcase struct {
2525
Name string
2626
Error bool
2727
Config []libyaml.ConfigGroup
28-
ViperConfig map[string]interface{} `yaml:"viper_config"`
29-
Responses responsesJson `yaml:"responses"`
30-
LiveValues map[string]interface{} `yaml:"input"`
31-
State map[string]interface{} `yaml:"state"`
28+
ViperConfig map[string]interface{} `yaml:"viper_config"`
29+
Responses responsesJson `yaml:"responses"`
30+
LiveValues []map[string]interface{} `yaml:"input"`
31+
State map[string]interface{} `yaml:"state"`
3232
}
3333

3434
type responsesJson struct {
@@ -93,12 +93,24 @@ func TestAPIResolver(t *testing.T) {
9393

9494
func() {
9595
if test.LiveValues == nil {
96-
test.LiveValues = make(map[string]interface{})
96+
test.LiveValues = make([]map[string]interface{}, 0)
9797
}
9898
if test.State == nil {
9999
test.State = make(map[string]interface{})
100100
}
101-
resolvedConfig, err := resolver.ResolveConfig(ctx, release, test.State, test.LiveValues)
101+
102+
var resolvedConfig []libyaml.ConfigGroup
103+
var err error
104+
105+
if len(test.LiveValues) == 0 {
106+
resolvedConfig, err = resolver.ResolveConfig(ctx, release, test.State, make(map[string]interface{}))
107+
} else {
108+
// simulate multiple inputs
109+
for _, liveValues := range test.LiveValues {
110+
resolvedConfig, err = resolver.ResolveConfig(ctx, release, test.State, liveValues)
111+
}
112+
}
113+
102114
if test.Error {
103115
req.True(err != nil, "Expected this api call to return an error")
104116
} else {
@@ -128,6 +140,7 @@ func TestResolveConfigValuesMap(t *testing.T) {
128140
{
129141
dependencies: map[string][]string{
130142
"alpha": {},
143+
131144
"bravo": {"alpha"},
132145
},
133146
input: map[string]interface{}{"alpha": "abc"},
@@ -206,10 +219,10 @@ func areSameJSON(t *testing.T, s1, s2 []byte) bool {
206219
var o2 interface{}
207220

208221
err := json.Unmarshal(s1, &o1)
209-
assert.NoError(t, err)
222+
require.NoError(t, err, string(s1))
210223

211224
err = json.Unmarshal(s2, &o2)
212-
assert.NoError(t, err)
225+
require.NoError(t, err, string(s2))
213226

214227
return reflect.DeepEqual(o1, o2)
215228
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
- name: checkbox with when on item -- hidden false
2+
input:
3+
- { airgap_install: "1" }
4+
config:
5+
- name: cluster_info
6+
title: Kubernetes cluster info
7+
items:
8+
- name: airgap_install
9+
title: Airgap cluster
10+
type: bool
11+
value: '1'
12+
- name: docker_registry_address
13+
title: Docker registry address
14+
type: text
15+
when: '{{repl ConfigOptionEquals "airgap_install" "1" }}'
16+
responses:
17+
json: |
18+
19+
[
20+
{
21+
"description": "",
22+
"filters": null,
23+
"items": [
24+
{
25+
"affix": "",
26+
"data_cmd": null,
27+
"default": "",
28+
"default_cmd": null,
29+
"filters": null,
30+
"help_text": "",
31+
"hidden": false,
32+
"is_excluded_from_support": false,
33+
"items": null,
34+
"multi_value": null,
35+
"multiple": false,
36+
"name": "airgap_install",
37+
"props": null,
38+
"readonly": false,
39+
"recommended": false,
40+
"required": false,
41+
"test_proc": null,
42+
"title": "Airgap cluster",
43+
"type": "bool",
44+
"value": "1",
45+
"value_cmd": null,
46+
"when": ""
47+
},
48+
{
49+
"affix": "",
50+
"data_cmd": null,
51+
"default": "",
52+
"default_cmd": null,
53+
"filters": null,
54+
"help_text": "",
55+
"hidden": false,
56+
"is_excluded_from_support": false,
57+
"items": null,
58+
"multi_value": null,
59+
"multiple": false,
60+
"name": "docker_registry_address",
61+
"props": null,
62+
"readonly": false,
63+
"recommended": false,
64+
"required": false,
65+
"test_proc": null,
66+
"title": "Docker registry address",
67+
"type": "text",
68+
"value": "",
69+
"value_cmd": null,
70+
"when": "true"
71+
}
72+
],
73+
"name": "cluster_info",
74+
"test_proc": null,
75+
"title": "Kubernetes cluster info",
76+
"when": ""
77+
}
78+
]
79+
80+
81+
- name: checkbox with when on item -- hidden should be true
82+
input:
83+
- { airgap_install: "0" }
84+
config:
85+
- name: cluster_info
86+
title: Kubernetes cluster info
87+
items:
88+
- name: airgap_install
89+
title: Airgap cluster
90+
type: bool
91+
default: '1'
92+
- name: docker_registry_address
93+
title: Docker registry address
94+
type: text
95+
when: '{{repl ConfigOptionEquals "airgap_install" "1" }}'
96+
responses:
97+
json: |
98+
99+
[
100+
{
101+
"description": "",
102+
"filters": null,
103+
"items": [
104+
{
105+
"affix": "",
106+
"data_cmd": null,
107+
"default": "1",
108+
"default_cmd": null,
109+
"filters": null,
110+
"help_text": "",
111+
"hidden": false,
112+
"is_excluded_from_support": false,
113+
"items": null,
114+
"multi_value": null,
115+
"multiple": false,
116+
"name": "airgap_install",
117+
"props": null,
118+
"readonly": false,
119+
"recommended": false,
120+
"required": false,
121+
"test_proc": null,
122+
"title": "Airgap cluster",
123+
"type": "bool",
124+
"value": "0",
125+
"value_cmd": null,
126+
"when": ""
127+
},
128+
{
129+
"affix": "",
130+
"data_cmd": null,
131+
"default": "",
132+
"default_cmd": null,
133+
"filters": null,
134+
"help_text": "",
135+
"hidden": true,
136+
"is_excluded_from_support": false,
137+
"items": null,
138+
"multi_value": null,
139+
"multiple": false,
140+
"name": "docker_registry_address",
141+
"props": null,
142+
"readonly": false,
143+
"recommended": false,
144+
"required": false,
145+
"test_proc": null,
146+
"title": "Docker registry address",
147+
"type": "text",
148+
"value": "",
149+
"value_cmd": null,
150+
"when": "false"
151+
}
152+
],
153+
"name": "cluster_info",
154+
"test_proc": null,
155+
"title": "Kubernetes cluster info",
156+
"when": ""
157+
}
158+
]
159+
160+
# this is wild -- ensures we do a deep copy of the config group, and re-render `when` on every POST /config/live call
161+
- name: checkbox with when on item -- hidden should be true after toggling
162+
input:
163+
- { airgap_install: "1" }
164+
- { airgap_install: "0" }
165+
config:
166+
- name: cluster_info
167+
title: Kubernetes cluster info
168+
items:
169+
- name: airgap_install
170+
title: Airgap cluster
171+
type: bool
172+
default: '1'
173+
- name: docker_registry_address
174+
title: Docker registry address
175+
type: text
176+
when: '{{repl ConfigOptionEquals "airgap_install" "1" }}'
177+
responses:
178+
json: |
179+
180+
[
181+
{
182+
"description": "",
183+
"filters": null,
184+
"items": [
185+
{
186+
"affix": "",
187+
"data_cmd": null,
188+
"default": "1",
189+
"default_cmd": null,
190+
"filters": null,
191+
"help_text": "",
192+
"hidden": false,
193+
"is_excluded_from_support": false,
194+
"items": null,
195+
"multi_value": null,
196+
"multiple": false,
197+
"name": "airgap_install",
198+
"props": null,
199+
"readonly": false,
200+
"recommended": false,
201+
"required": false,
202+
"test_proc": null,
203+
"title": "Airgap cluster",
204+
"type": "bool",
205+
"value": "0",
206+
"value_cmd": null,
207+
"when": ""
208+
},
209+
{
210+
"affix": "",
211+
"data_cmd": null,
212+
"default": "",
213+
"default_cmd": null,
214+
"filters": null,
215+
"help_text": "",
216+
"hidden": true,
217+
"is_excluded_from_support": false,
218+
"items": null,
219+
"multi_value": null,
220+
"multiple": false,
221+
"name": "docker_registry_address",
222+
"props": null,
223+
"readonly": false,
224+
"recommended": false,
225+
"required": false,
226+
"test_proc": null,
227+
"title": "Docker registry address",
228+
"type": "text",
229+
"value": "",
230+
"value_cmd": null,
231+
"when": "false"
232+
}
233+
],
234+
"name": "cluster_info",
235+
"test_proc": null,
236+
"title": "Kubernetes cluster info",
237+
"when": ""
238+
}
239+
]

pkg/lifecycle/render/config/test-cases/api/data-references.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
##Alpha is a file, represented by a base64 encoded blob. Bravo references this and should receive the decoded value
22
- name: Referencing file contents
3-
input: {alpha: "dGVzdGluZ3Rlc3RpbmcxMjM="}
3+
input:
4+
- {alpha: "dGVzdGluZ3Rlc3RpbmcxMjM="}
45
config:
56
- name: alpha_group
67
description: Alpha Group

pkg/lifecycle/render/config/test-cases/api/defaults.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
- name: options with defaults and options with values
2-
input: {}
2+
input:
3+
- {}
34
config:
45
- name: group_one
56
items:

pkg/lifecycle/render/config/test-cases/api/failing/hidden-group.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
## now visible
44

55
- name: a when that defaults to false with select_one
6-
input: {}
6+
input:
7+
- {}
78
config:
89
- name: external_service_enable
910
title: Enable Some External Service

pkg/lifecycle/render/config/test-cases/api/failing/hidden-password.yaml

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
- name: more than one group, hidden password
2-
input: {}
2+
input:
3+
- {}
34
config:
45
- name: alpha_group
56
description: Alpha Group

pkg/lifecycle/render/config/test-cases/api/failing/simple-hidden-password.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
- name: one group, hidden password
2-
input: {}
2+
input:
3+
- {}
34
config:
45
- name: alpha_group
56
description: Alpha Group

0 commit comments

Comments
 (0)