diff --git a/kubernetes-model-generator/openapi/generator/pkg/openapi/openapi-gen-processors.go b/kubernetes-model-generator/openapi/generator/pkg/openapi/openapi-gen-processors.go index c391152c21..f13a488f77 100644 --- a/kubernetes-model-generator/openapi/generator/pkg/openapi/openapi-gen-processors.go +++ b/kubernetes-model-generator/openapi/generator/pkg/openapi/openapi-gen-processors.go @@ -77,6 +77,12 @@ func addOrAppend(commentLines []string, prefix, value string) []string { } return commentLines } +func publicInterfaceName(name string) string { + if unicode.IsUpper(rune(name[0])) { + return name + } + return string(unicode.ToUpper(rune(name[0]))) + name[1:] +} // func processProtobufOneof // To generate interfaces and extending classes for oneof fields @@ -84,19 +90,9 @@ func addOrAppend(commentLines []string, prefix, value string) []string { // // For processing we'll add +k8s:openapi-gen=x-kubernetes tags that will be later processed by kube-openapi and added to the OpenAPI json spec func processProtobufOneof(_ *generator.Context, pkg *types.Package, t *types.Type, m *types.Member, memberIndex int) { - publicInterfaceName := func(name string) string { - if unicode.IsUpper(rune(name[0])) { - return name - } - return string(unicode.ToUpper(rune(name[0]))) + name[1:] - } // Interfaces protobufOneOf := reflect.StructTag(m.Tags).Get("protobuf_oneof") if protobufOneOf != "" { - // kube-openapi doesn't handle interfaces, so we need to change the interface to a struct - m.Type.Kind = types.Struct - // Ensure it's exported - t.Members[memberIndex].Type.Name.Name = publicInterfaceName(m.Type.Name.Name) //// Add comment tag to the referenced type and mark it as an interface t.Members[memberIndex].Type.CommentLines = append(m.Type.CommentLines, "+k8s:openapi-gen=x-kubernetes-fabric8-type:interface") // Add comment tag to the current type to mark it as it has fields that are interfaces (useful for the OpenAPI Java generator) @@ -119,6 +115,28 @@ func processProtobufOneof(_ *generator.Context, pkg *types.Package, t *types.Typ } } +// processProtobufPackageOneOf function to process the protobuf package and change the interfaces to structs +// kube-openapi doesn't handle interfaces, so we need to change the interface to a struct +func processProtobufPackageOneOf(_ *generator.Context, pkg *types.Package) { + for _, t := range pkg.Types { + if t.Kind != types.Interface { + continue + } + openApiGen := gengo.ExtractCommentTags("+", t.CommentLines)["k8s:openapi-gen"] + if len(openApiGen) > 0 { + for _, openApiGenValue := range openApiGen { + if openApiGenValue == "x-kubernetes-fabric8-type:interface" { + // Change to Struct so that it's processed by kube-openapi + t.Kind = types.Struct + // Ensure it's public so that it can be exported + t.Name.Name = publicInterfaceName(t.Name.Name) + break + } + } + } + } +} + // processProtobufTags function to process the protobuf field tags and fix json tags that might have mismatched names for serialization // This happens for most of the istio APIs func processProtobufTags(_ *generator.Context, _ *types.Package, t *types.Type, m *types.Member, memberIndex int) { @@ -126,6 +144,7 @@ func processProtobufTags(_ *generator.Context, _ *types.Package, t *types.Type, protobufTag := tags.Get("protobuf") jsonTag := tags.Get("json") if protobufTag != "" && strings.Contains(protobufTag, "json=") { + // TODO, consider also name= (sometimes this is included instad of json=) name := strings.Split(protobufTag, "json=")[1] name = strings.Split(name, ",")[0] var updatedJsonTag string diff --git a/kubernetes-model-generator/openapi/generator/pkg/openapi/openapi-gen.go b/kubernetes-model-generator/openapi/generator/pkg/openapi/openapi-gen.go index 84786cbb06..acaec7e6f0 100644 --- a/kubernetes-model-generator/openapi/generator/pkg/openapi/openapi-gen.go +++ b/kubernetes-model-generator/openapi/generator/pkg/openapi/openapi-gen.go @@ -32,12 +32,15 @@ type GoGenerator struct { openapiargs.Args Patterns []string inputPkgs map[string]bool - processors []func(context *generator.Context, pkg *types.Package, t *types.Type, member *types.Member, memberIndex int) + // memberProcessors are functions that are applied to each member of a type + memberProcessors []func(context *generator.Context, pkg *types.Package, t *types.Type, member *types.Member, memberIndex int) + // packageProcessors are functions that are applied to each package once all type members have been processed for that package + packageProcessors []func(context *generator.Context, pkg *types.Package) } func (g *GoGenerator) Generate() error { g.ReportFilename = g.OutputFile + ".report.txt" - g.processors = []func(context *generator.Context, pkg *types.Package, t *types.Type, member *types.Member, memberIndex int){ + g.memberProcessors = []func(context *generator.Context, pkg *types.Package, t *types.Type, member *types.Member, memberIndex int){ processMapKeyTypes, processOmitPrivateFields, processPatchComments, @@ -45,6 +48,9 @@ func (g *GoGenerator) Generate() error { processProtobufTags, processSwaggerIgnore, } + g.packageProcessors = []func(context *generator.Context, pkg *types.Package){ + processProtobufPackageOneOf, + } return gengo.Execute( generators.NameSystems(), generators.DefaultNameSystem(), @@ -89,11 +95,14 @@ func (g *GoGenerator) processUniverse(context *generator.Context) { for _, pkg := range context.Universe { for _, t := range pkg.Types { for memberIndex, member := range t.Members { - for _, processor := range g.processors { - processor(context, pkg, t, &member, memberIndex) + for _, memeberProcessor := range g.memberProcessors { + memeberProcessor(context, pkg, t, &member, memberIndex) } } } + for _, packageProcessor := range g.packageProcessors { + packageProcessor(context, pkg) + } } // Non-deterministic bug-fix diff --git a/kubernetes-model-generator/openapi/maven-plugin/pom.xml b/kubernetes-model-generator/openapi/maven-plugin/pom.xml index c2cc627f04..17e9a8c750 100644 --- a/kubernetes-model-generator/openapi/maven-plugin/pom.xml +++ b/kubernetes-model-generator/openapi/maven-plugin/pom.xml @@ -67,16 +67,6 @@ swagger-parser 2.1.23 - - org.junit.jupiter - junit-jupiter-engine - test - - - org.junit.jupiter - junit-jupiter-params - test -