kubernetes / kubernetes/kube-openapi
openapi-gen ignores +listType/+listMapKey markers on named slice types (type Foo []Bar), emitting atomic lists
- Dominant language
- Go
- Stars
- 356
- Forks
- 249
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 3
Description
`+listType=map` / `+listMapKey` placed on a named slice type declaration (`type Foo []Bar`) is honored by controller-gen (CRD gets
`x-kubernetes-list-type: map`) but dropped by openapi-gen — so the apply/structured-merge-diff schema produced by applyconfiguration-gen comes out `atomic`. When the identical marker is placed on the struct field, all three generators agree.
```go
// +listType=map
// +listMapKey=key
type SelectorsA []Selector // marker on the type
type Spec struct {
SelectorsFromType SelectorsA `json:"selectorsFromType,omitempty"`
// +listType=map
// +listMapKey=key
SelectorsOnField []Selector `json:"selectorsOnField,omitempty"` // marker on the FIELD
}
```
Full CRD is here https://github.com/npinaeva/openapi-bug/blob/main/api/v1/types.go
CRD is generated correctly https://github.com/npinaeva/openapi-bug/blob/main/crds/example.io_examples.yaml
```yaml
selectorsFromType:
...
x-kubernetes-list-map-keys: [key]
x-kubernetes-list-type: map
selectorsOnField:
...
x-kubernetes-list-map-keys: [key]
x-kubernetes-list-type: map
```
But `openapi-gen` dropped the type marker
https://github.com/npinaeva/openapi-bug/blob/main/api/v1/openapi/zz_generated.openapi.go
```go
Properties: map[string]spec.Schema{
"selectorsFromType": {
SchemaProps: spec.SchemaProps{
Description: "Variant A: field references a named slice type whose *type* carries the markers.",
Type: []string{"array"},
Items: &spec.SchemaOrArray{
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
Ref: ref(v1.Selector{}.OpenAPIModelName()),
},
},
},
},
},
"selectorsOnField": {
VendorExtensible: spec.VendorExtensible{
Extensions: spec.Extensions{
"x-kubernetes-list-map-keys": []interface{}{
"key",
},
"x-kubernetes-list-type": "map",
},
},
SchemaProps: spec.SchemaProps{
Description: "Variant B: same element type, but markers on the FIELD.",
Type: []string{"array"},
Items: &spec.SchemaOrArray{
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
Ref: ref(v1.Selector{}.OpenAPIModelName()),
},
},
},
},
},
},
```
Looks like https://github.com/kubernetes/kube-openapi/blob/d427ff9ee9ad05f5da435abbb7c5929cb713ac56/pkg/generators/openapi.go#L756 ignores aliases
Contributor guide
Research direction
Start in pkg/generators/openapi.go around line 756, then compare the named-slice and field-marker examples in api/v1/types.go with the generated api/v1/openapi/zz_generated.openapi.go. Reproduce the generation and verify that the named type retains x-kubernetes-list-type and x-kubernetes-list-map-keys instead of producing an atomic list.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- api
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100