controller-tools
controller-tools copied to clipboard
Flattening a schema drops the validation marker type overrides.
I'm using the tools from the crd package to generate an OpenAPI Schema and noticed the following behaviour:
- The Type of a field
Xis set through the validation marker+kubebuilder:validation:Type=string(for example, forcing ametav1.Timeto be a string instead of an object) - The
Parsercorrectly discovers the type override andparser.Schemata[myTypeIdent]says the fieldXis a string - But
parser.FlattenedSchemata[myTypeIdent]says the fieldXis an object
I'm not sure this behaviour is intended.
Here is a toy example reproducing the issue, the mis-typed field is LastTransitionTime. I would expect its type to be string in both the regular and the flattened schemas.
main.go
package main
import (
"fmt"
"sigs.k8s.io/controller-tools/pkg/crd"
crdmarkers "sigs.k8s.io/controller-tools/pkg/crd/markers"
"sigs.k8s.io/controller-tools/pkg/loader"
"sigs.k8s.io/controller-tools/pkg/markers"
)
func main() {
registry := &markers.Registry{}
crdmarkers.Register(registry)
parser := crd.Parser{
Collector: &markers.Collector{Registry: registry},
Checker: &loader.TypeChecker{},
}
pkgs, err := loader.LoadRoots("./...")
if err != nil {
fmt.Printf("parser error: %s", err)
}
var statusType crd.TypeIdent
pkg := pkgs[1]
parser.NeedPackage(pkg)
statusType = crd.TypeIdent{
Package: pkg,
Name: "UserStatus",
}
parser.NeedFlattenedSchemaFor(statusType)
fmt.Printf("Schemata %v \n", parser.Schemata[statusType])
fmt.Printf("Flattened Schemata %v \n", parser.FlattenedSchemata[statusType])
}
v2/user_types.go
package v2
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/scheme"
)
var (
GroupVersion = schema.GroupVersion{Group: "myGroup", Version: "v2"}
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
AddToScheme = SchemeBuilder.AddToScheme
)
func init() {
SchemeBuilder.Register(&User{}, &UserList{})
}
type UserStatus struct {
// +required
// +kubebuilder:validation:Required
// +kubebuilder:validation:Type=string
// +kubebuilder:validation:Format=date-time
LastTransitionTime metav1.Time `json:"lastTransitionTime" protobuf:"bytes,4,opt,name=lastTransitionTime"`
}
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
type User struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Status UserStatus `json:"status,omitempty"`
}
The workaround is using known type overrides.