diff --git a/go.mod b/go.mod index eabf6593..aa76ea65 100644 --- a/go.mod +++ b/go.mod @@ -24,6 +24,7 @@ require ( k8s.io/gengo v0.0.0-20240826214909-a7b603a56eb7 k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70 k8s.io/kube-aggregator v0.31.1 + k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 sigs.k8s.io/cli-utils v0.37.2 ) @@ -40,9 +41,9 @@ require ( github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.22.4 // indirect + github.com/go-openapi/swag v0.23.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/cel-go v0.20.1 // indirect @@ -82,7 +83,7 @@ require ( golang.org/x/oauth2 v0.21.0 // indirect golang.org/x/sys v0.23.0 // indirect golang.org/x/term v0.23.0 // indirect - golang.org/x/time v0.3.0 // indirect + golang.org/x/time v0.5.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect google.golang.org/grpc v1.65.0 // indirect @@ -95,7 +96,6 @@ require ( k8s.io/component-base v0.31.1 // indirect k8s.io/klog v1.0.0 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect diff --git a/go.sum b/go.sum index cc6b9c35..1625316a 100644 --- a/go.sum +++ b/go.sum @@ -37,13 +37,14 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= -github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -212,8 +213,8 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= diff --git a/pkg/controller-gen/args/args.go b/pkg/controller-gen/args/args.go index 67c3f858..fbccfefc 100644 --- a/pkg/controller-gen/args/args.go +++ b/pkg/controller-gen/args/args.go @@ -47,6 +47,10 @@ type Group struct { GenerateListers bool // Generate informers GenerateInformers bool + // Generate openapi + GenerateOpenAPI bool + // OpenAPI extra dependencies + OpenAPIDependencies []string // The package name of the API types PackageName string } diff --git a/pkg/controller-gen/generators/client_generator.go b/pkg/controller-gen/generators/client_generator.go index ee74dae0..9c48d898 100644 --- a/pkg/controller-gen/generators/client_generator.go +++ b/pkg/controller-gen/generators/client_generator.go @@ -92,12 +92,17 @@ func (cg *ClientGenerator) typesGroupVersionDocPackage(name *types.Name, gv sche } }) + openAPIDirective := "" + if customArgs.Options.Groups[gv.Group].GenerateOpenAPI { + openAPIDirective = fmt.Sprintf("\n// +k8s:openapi-gen=true") + } + p.HeaderComment = []byte(fmt.Sprintf(` %s - +%s // +k8s:deepcopy-gen=package // +groupName=%s -`, string(customArgs.BoilerplateContent), gv.Group)) +`, string(customArgs.BoilerplateContent), openAPIDirective, gv.Group)) return p } diff --git a/pkg/controller-gen/main.go b/pkg/controller-gen/main.go index 4b61289a..820d0969 100644 --- a/pkg/controller-gen/main.go +++ b/pkg/controller-gen/main.go @@ -26,6 +26,8 @@ import ( lsargs "k8s.io/code-generator/cmd/lister-gen/args" ls "k8s.io/code-generator/cmd/lister-gen/generators" dp "k8s.io/gengo/examples/deepcopy-gen/generators" + oaargs "k8s.io/kube-openapi/cmd/openapi-gen/args" + oa "k8s.io/kube-openapi/pkg/generators" ) func Run(opts cgargs.Options) { @@ -75,6 +77,7 @@ func Run(opts cgargs.Options) { listerGroups := map[string]bool{} informerGroups := map[string]bool{} deepCopygroups := map[string]bool{} + openAPIGroups := map[string]bool{} for groupName, group := range customArgs.Options.Groups { if group.GenerateTypes { deepCopygroups[groupName] = true @@ -88,9 +91,12 @@ func Run(opts cgargs.Options) { if group.GenerateInformers { informerGroups[groupName] = true } + if group.GenerateOpenAPI { + openAPIGroups[groupName] = true + } } - if len(deepCopygroups) == 0 && len(groups) == 0 && len(listerGroups) == 0 && len(informerGroups) == 0 { + if len(deepCopygroups) == 0 && len(groups) == 0 && len(listerGroups) == 0 && len(informerGroups) == 0 && len(openAPIGroups) == 0 { if err := copyGoPathToModules(customArgs); err != nil { logrus.Fatalf("go modules copy failed: %v", err) } @@ -117,6 +123,10 @@ func Run(opts cgargs.Options) { logrus.Fatalf("informers failed: %v", err) } + if err := generateOpenAPI(openAPIGroups, customArgs); err != nil { + logrus.Fatalf("openapi failed: %v", err) + } + if err := copyGoPathToModules(customArgs); err != nil { logrus.Fatalf("go modules copy failed: %v", err) } @@ -265,6 +275,55 @@ func generateClientset(groups map[string]bool, customArgs *cgargs.CustomArgs) er ) } +func generateOpenAPI(groups map[string]bool, customArgs *cgargs.CustomArgs) error { + if len(groups) == 0 { + return nil + } + + openAPIArgs := oaargs.New() + openAPIArgs.OutputDir = filepath.Join(customArgs.OutputBase, customArgs.Options.OutputPackage, "openapi") + openAPIArgs.OutputFile = "zz_generated_openapi.go" + openAPIArgs.OutputPkg = customArgs.Options.OutputPackage + "/openapi" + openAPIArgs.GoHeaderFile = customArgs.Options.Boilerplate + + if err := openAPIArgs.Validate(); err != nil { + return err + } + + inputDirsMap := map[string]bool{} + inputDirs := []string{} + for gv, names := range customArgs.TypesByGroup { + if !groups[gv.Group] { + continue + } + + if _, found := inputDirsMap[names[0].Package]; !found { + inputDirsMap[names[0].Package] = true + inputDirs = append(inputDirs, names[0].Package) + } + + group := customArgs.Options.Groups[gv.Group] + for _, dep := range group.OpenAPIDependencies { + if _, found := inputDirsMap[dep]; !found { + inputDirsMap[dep] = true + inputDirs = append(inputDirs, dep) + } + } + } + + getTargets := func(context *generator.Context) []generator.Target { + return oa.GetTargets(context, openAPIArgs) + } + + return gengo.Execute( + oa.NameSystems(), + oa.DefaultNameSystem(), + getTargets, + gengo.StdBuildTag, + inputDirs, + ) +} + func setGenClient( groups map[string]bool, typesByGroup map[schema.GroupVersion][]*types.Name,