Skip to content

Commit d5ff91d

Browse files
mamachanko100mik
authored andcommitted
Treat null value as any type when generating schema from Helm chart
fixes #1630 Signed-off-by: Max Brauer <[email protected]>
1 parent ad99570 commit d5ff91d

File tree

3 files changed

+93
-7
lines changed

3 files changed

+93
-7
lines changed

cli/pkg/kctrl/cmd/package/release/schemagenerator/helm_openapi_schema_gen.go

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const (
2626
itemsKey = "items"
2727
propertiesKey = "properties"
2828
defaultKey = "default"
29+
nullableKey = "nullable"
2930
)
3031

3132
var keyOrder = map[string]int{
@@ -35,6 +36,7 @@ var keyOrder = map[string]int{
3536
itemsKey: 4,
3637
propertiesKey: 5,
3738
defaultKey: 6,
39+
nullableKey: 7,
3840
}
3941

4042
const (
@@ -211,6 +213,11 @@ func (h HelmValuesSchemaGen) calculateProperties(key *yaml3.Node, value *yaml3.N
211213
if err != nil {
212214
return nil, err
213215
}
216+
if value.Tag == nullTag {
217+
// We cannot infer a key's type from a null value and must assume "any".
218+
apiKeys = append(apiKeys, newAnyType())
219+
break
220+
}
214221
apiKeys = append(apiKeys, &MapItem{Key: typeKey, Value: h.openAPIType(value.Tag, value.Value)})
215222
apiKeys = append(apiKeys, &MapItem{Key: defaultKey, Value: defaultVal})
216223
if value.Tag == floatTag {
@@ -266,7 +273,6 @@ func (h HelmValuesSchemaGen) openAPIType(tag, value string) string {
266273
}
267274
}
268275
return "string"
269-
270276
}
271277

272278
func (h HelmValuesSchemaGen) getDefaultValue(tag, value string) (interface{}, error) {
@@ -281,3 +287,29 @@ func (h HelmValuesSchemaGen) getDefaultValue(tag, value string) (interface{}, er
281287
return value, nil
282288
}
283289
}
290+
291+
func newAnyType() *MapItem {
292+
nullable := func(t string) map[string]interface{} {
293+
n := map[string]interface{}{
294+
typeKey: t,
295+
defaultKey: nil,
296+
nullableKey: true,
297+
}
298+
if t == "array" {
299+
n["items"] = map[string]string{}
300+
}
301+
return n
302+
}
303+
return &MapItem{
304+
Key: "oneOf",
305+
Value: []map[string]interface{}{
306+
nullable("integer"),
307+
nullable("number"),
308+
nullable("boolean"),
309+
nullable("string"),
310+
nullable("object"),
311+
nullable("array"),
312+
},
313+
}
314+
}
315+

cli/pkg/kctrl/cmd/package/release/schemagenerator/helm_openapi_schema_gen_test.go

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ arrKeyEmpty: []
6969
type: string
7070
type: array
7171
type: object
72-
`},
72+
`,
73+
},
7374
{
7475
name: "object with different values",
7576
input: `
@@ -123,7 +124,8 @@ objExample: {}
123124
description: Object example
124125
type: object
125126
type: object
126-
`},
127+
`,
128+
},
127129
{
128130
name: "nested complex object",
129131
input: `
@@ -176,7 +178,8 @@ containers:
176178
type: string
177179
type: object
178180
type: object
179-
`},
181+
`,
182+
},
180183
{
181184
name: "Alias Node",
182185
input: `
@@ -223,7 +226,40 @@ aliasEx:
223226
type: object
224227
type: array
225228
type: object
226-
`},
229+
`,
230+
},
231+
{
232+
name: "unknown type",
233+
input: `
234+
# a field without a type
235+
anything: null
236+
`,
237+
want: `properties:
238+
anything:
239+
description: a field without a type
240+
oneOf:
241+
- default: null
242+
nullable: true
243+
type: integer
244+
- default: null
245+
nullable: true
246+
type: number
247+
- default: null
248+
nullable: true
249+
type: boolean
250+
- default: null
251+
nullable: true
252+
type: string
253+
- default: null
254+
nullable: true
255+
type: object
256+
- default: null
257+
items: {}
258+
nullable: true
259+
type: array
260+
type: object
261+
`,
262+
},
227263
}
228264

229265
for _, test := range tests {

cli/test/e2e/package_authoring_e2e_test.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,8 +336,26 @@ spec:
336336
default: quay.io/mongodb
337337
type: string
338338
imagePullSecrets:
339-
default: ""
340-
type: string
339+
oneOf:
340+
- default: null
341+
nullable: true
342+
type: integer
343+
- default: null
344+
nullable: true
345+
type: number
346+
- default: null
347+
nullable: true
348+
type: boolean
349+
- default: null
350+
nullable: true
351+
type: string
352+
- default: null
353+
nullable: true
354+
type: object
355+
- default: null
356+
items: {}
357+
nullable: true
358+
type: array
341359
initAppDb:
342360
default: quay.io/mongodb
343361
type: string

0 commit comments

Comments
 (0)