Merge pull request #121010 from Jefftree/decouple-openapi-v2v3-config

Decouple openapi v2v3 config

Kubernetes-commit: ac66f3d466caee27bcc0f66a04ceec9bf63750bd
This commit is contained in:
Kubernetes Publisher 2023-10-16 23:41:11 +02:00
commit 2a6d038562
5 changed files with 87 additions and 31 deletions

22
go.mod
View File

@ -41,13 +41,13 @@ require (
google.golang.org/protobuf v1.31.0 google.golang.org/protobuf v1.31.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1 gopkg.in/natefinch/lumberjack.v2 v2.2.1
gopkg.in/square/go-jose.v2 v2.6.0 gopkg.in/square/go-jose.v2 v2.6.0
k8s.io/api v0.0.0-20231016191944-7030ca672d51 k8s.io/api v0.0.0-20231016230927-b01b44926aa4
k8s.io/apimachinery v0.0.0-20231014214926-e0ab1cf45503 k8s.io/apimachinery v0.0.0-20231016230655-a1b8da8152f9
k8s.io/client-go v0.0.0-20231016231306-9f0ec66a5dd5 k8s.io/client-go v0.0.0-20231016231308-435ce6f2a8ef
k8s.io/component-base v0.0.0-20231012232716-1cde81dc58d7 k8s.io/component-base v0.0.0-20231016231942-6aa55648c840
k8s.io/klog/v2 v2.100.1 k8s.io/klog/v2 v2.100.1
k8s.io/kms v0.0.0-20231012233140-98eefd633e64 k8s.io/kms v0.0.0-20231016232213-86dc11279675
k8s.io/kube-openapi v0.0.0-20230918164632-68afd615200d k8s.io/kube-openapi v0.0.0-20231009201959-f62364c3c354
k8s.io/utils v0.0.0-20230726121419-3b25d923346b k8s.io/utils v0.0.0-20230726121419-3b25d923346b
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0 sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd
@ -126,9 +126,9 @@ require (
) )
replace ( replace (
k8s.io/api => k8s.io/api v0.0.0-20231016191944-7030ca672d51 k8s.io/api => k8s.io/api v0.0.0-20231016230927-b01b44926aa4
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20231014214926-e0ab1cf45503 k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20231016230655-a1b8da8152f9
k8s.io/client-go => k8s.io/client-go v0.0.0-20231016231306-9f0ec66a5dd5 k8s.io/client-go => k8s.io/client-go v0.0.0-20231016231308-435ce6f2a8ef
k8s.io/component-base => k8s.io/component-base v0.0.0-20231012232716-1cde81dc58d7 k8s.io/component-base => k8s.io/component-base v0.0.0-20231016231942-6aa55648c840
k8s.io/kms => k8s.io/kms v0.0.0-20231012233140-98eefd633e64 k8s.io/kms => k8s.io/kms v0.0.0-20231016232213-86dc11279675
) )

24
go.sum
View File

@ -671,20 +671,20 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
k8s.io/api v0.0.0-20231016191944-7030ca672d51 h1:WvqKXHnDO2qbwHLxnlkcMZ1rl2mkMN6GYCCskzH+Hzc= k8s.io/api v0.0.0-20231016230927-b01b44926aa4 h1:YdPlQP6+WHLF9ava/tttQ4mWaGuk13V4R60AUTBVm9w=
k8s.io/api v0.0.0-20231016191944-7030ca672d51/go.mod h1:UkkjoUr+XAy0AYlIfbOMV4K0O3yGo3PF/2gnAbObmd8= k8s.io/api v0.0.0-20231016230927-b01b44926aa4/go.mod h1:a58jPYSjslcgbP59Ufe6gIkCWQbDxbdxxga22IoZEqw=
k8s.io/apimachinery v0.0.0-20231014214926-e0ab1cf45503 h1:rwpccECeeGhXjS0v6Rf0lfxxLWjZIzCnxrprCaodXKg= k8s.io/apimachinery v0.0.0-20231016230655-a1b8da8152f9 h1:P/hvmG2u3EJW3zSoSIPneQqJGEPFqXEmSbDJzueL9Rw=
k8s.io/apimachinery v0.0.0-20231014214926-e0ab1cf45503/go.mod h1:rmXxFscUaicYcLy9laCS6Y0pVztcz7vbFNT+u/IlhPI= k8s.io/apimachinery v0.0.0-20231016230655-a1b8da8152f9/go.mod h1:URVThVSROxf8S6kiqIS+KDdAJo7rhZTYXo5PE/BzBak=
k8s.io/client-go v0.0.0-20231016231306-9f0ec66a5dd5 h1:2BR+wSTUG3gXmQqdt0oAJl47UoEK7MtyrkKsh6rbyy0= k8s.io/client-go v0.0.0-20231016231308-435ce6f2a8ef h1:b3BXbpEPHopqKAckb5121hQMNhzQMxX4LK0TyvDQuOo=
k8s.io/client-go v0.0.0-20231016231306-9f0ec66a5dd5/go.mod h1:x+JuHGwffxO1wSaWqNuPP4m0HKzaQV9B59FsZdDax3Y= k8s.io/client-go v0.0.0-20231016231308-435ce6f2a8ef/go.mod h1:GdSjbu8MD3e4hCsr7Vf8ofin8o8QZttciq56kIp6Ap8=
k8s.io/component-base v0.0.0-20231012232716-1cde81dc58d7 h1:z5BLy+vNRLKJPg2Ru5ck3JSBjgoeEjDMBpnmhttKvlU= k8s.io/component-base v0.0.0-20231016231942-6aa55648c840 h1:rzN0kwUwgcpjh1y1MDWBmENMNkp1Jg46yU2YRVlb9Hw=
k8s.io/component-base v0.0.0-20231012232716-1cde81dc58d7/go.mod h1:/6+DLzsPDc5ULLterOV8+N53C33qwfijifn4nniD2oY= k8s.io/component-base v0.0.0-20231016231942-6aa55648c840/go.mod h1:D59zB3VEw03oDT4CqWcTKfmu0y+GK05ZpNC3n3ry5CU=
k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/kms v0.0.0-20231012233140-98eefd633e64 h1:HXICIT/38n82338C/kFJe6pMZI2O4WN7qZGMVj9/slM= k8s.io/kms v0.0.0-20231016232213-86dc11279675 h1:fy5mDU+0vDDbN3n8tozvJDu8YbFOlbxoJpDR+p1RzVc=
k8s.io/kms v0.0.0-20231012233140-98eefd633e64/go.mod h1:a3bQjdq1BkLOq2dl/W3R24RDNBVrdrgE9sdE3jSY2Qs= k8s.io/kms v0.0.0-20231016232213-86dc11279675/go.mod h1:Ue2hsNZ3E86NaIjPvxbDqzk5kZhWTk0XyyfFO476dn8=
k8s.io/kube-openapi v0.0.0-20230918164632-68afd615200d h1:/CFeJBjBrZvHX09rObS2+2iEEDevMWYc1v3aIYAjIYI= k8s.io/kube-openapi v0.0.0-20231009201959-f62364c3c354 h1:xoRyJBnZ7YYVJ/U/IT4ooD7ApFgcbEFvo0nlwHW/6S4=
k8s.io/kube-openapi v0.0.0-20230918164632-68afd615200d/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= k8s.io/kube-openapi v0.0.0-20231009201959-f62364c3c354/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA=
k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=

View File

@ -78,6 +78,7 @@ import (
"k8s.io/component-base/tracing" "k8s.io/component-base/tracing"
"k8s.io/klog/v2" "k8s.io/klog/v2"
openapicommon "k8s.io/kube-openapi/pkg/common" openapicommon "k8s.io/kube-openapi/pkg/common"
"k8s.io/kube-openapi/pkg/spec3"
"k8s.io/kube-openapi/pkg/validation/spec" "k8s.io/kube-openapi/pkg/validation/spec"
"k8s.io/utils/clock" "k8s.io/utils/clock"
utilsnet "k8s.io/utils/net" utilsnet "k8s.io/utils/net"
@ -194,7 +195,7 @@ type Config struct {
// OpenAPIConfig will be used in generating OpenAPI spec. This is nil by default. Use DefaultOpenAPIConfig for "working" defaults. // OpenAPIConfig will be used in generating OpenAPI spec. This is nil by default. Use DefaultOpenAPIConfig for "working" defaults.
OpenAPIConfig *openapicommon.Config OpenAPIConfig *openapicommon.Config
// OpenAPIV3Config will be used in generating OpenAPI V3 spec. This is nil by default. Use DefaultOpenAPIV3Config for "working" defaults. // OpenAPIV3Config will be used in generating OpenAPI V3 spec. This is nil by default. Use DefaultOpenAPIV3Config for "working" defaults.
OpenAPIV3Config *openapicommon.Config OpenAPIV3Config *openapicommon.OpenAPIV3Config
// SkipOpenAPIInstallation avoids installing the OpenAPI handler if set to true. // SkipOpenAPIInstallation avoids installing the OpenAPI handler if set to true.
SkipOpenAPIInstallation bool SkipOpenAPIInstallation bool
@ -482,8 +483,23 @@ func DefaultOpenAPIConfig(getDefinitions openapicommon.GetOpenAPIDefinitions, de
} }
// DefaultOpenAPIV3Config provides the default OpenAPIV3Config used to build the OpenAPI V3 spec // DefaultOpenAPIV3Config provides the default OpenAPIV3Config used to build the OpenAPI V3 spec
func DefaultOpenAPIV3Config(getDefinitions openapicommon.GetOpenAPIDefinitions, defNamer *apiopenapi.DefinitionNamer) *openapicommon.Config { func DefaultOpenAPIV3Config(getDefinitions openapicommon.GetOpenAPIDefinitions, defNamer *apiopenapi.DefinitionNamer) *openapicommon.OpenAPIV3Config {
defaultConfig := DefaultOpenAPIConfig(getDefinitions, defNamer) defaultConfig := &openapicommon.OpenAPIV3Config{
IgnorePrefixes: []string{},
Info: &spec.Info{
InfoProps: spec.InfoProps{
Title: "Generic API Server",
},
},
DefaultResponse: &spec3.Response{
ResponseProps: spec3.ResponseProps{
Description: "Default Response.",
},
},
GetOperationIDAndTags: apiopenapi.GetOperationIDAndTags,
GetDefinitionName: defNamer.GetDefinitionName,
GetDefinitions: getDefinitions,
}
defaultConfig.Definitions = getDefinitions(func(name string) spec.Ref { defaultConfig.Definitions = getDefinitions(func(name string) spec.Ref {
defName, _ := defaultConfig.GetDefinitionName(name) defName, _ := defaultConfig.GetDefinitionName(name)
return spec.MustCreateRef("#/components/schemas/" + openapicommon.EscapeJsonPointer(defName)) return spec.MustCreateRef("#/components/schemas/" + openapicommon.EscapeJsonPointer(defName))
@ -608,6 +624,45 @@ func completeOpenAPI(config *openapicommon.Config, version *version.Info) {
} }
} }
func completeOpenAPIV3(config *openapicommon.OpenAPIV3Config, version *version.Info) {
if config == nil {
return
}
if config.SecuritySchemes != nil {
// Setup OpenAPI security: all APIs will have the same authentication for now.
config.DefaultSecurity = []map[string][]string{}
keys := []string{}
for k := range config.SecuritySchemes {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
config.DefaultSecurity = append(config.DefaultSecurity, map[string][]string{k: {}})
}
if config.CommonResponses == nil {
config.CommonResponses = map[int]*spec3.Response{}
}
if _, exists := config.CommonResponses[http.StatusUnauthorized]; !exists {
config.CommonResponses[http.StatusUnauthorized] = &spec3.Response{
ResponseProps: spec3.ResponseProps{
Description: "Unauthorized",
},
}
}
}
// make sure we populate info, and info.version, if not manually set
if config.Info == nil {
config.Info = &spec.Info{}
}
if config.Info.Version == "" {
if version != nil {
config.Info.Version = strings.Split(version.String(), "-")[0]
} else {
config.Info.Version = "unversioned"
}
}
}
// DrainedNotify returns a lifecycle signal of genericapiserver already drained while shutting down. // DrainedNotify returns a lifecycle signal of genericapiserver already drained while shutting down.
func (c *Config) DrainedNotify() <-chan struct{} { func (c *Config) DrainedNotify() <-chan struct{} {
return c.lifecycleSignals.InFlightRequestsDrained.Signaled() return c.lifecycleSignals.InFlightRequestsDrained.Signaled()
@ -633,7 +688,7 @@ func (c *Config) Complete(informers informers.SharedInformerFactory) CompletedCo
} }
completeOpenAPI(c.OpenAPIConfig, c.Version) completeOpenAPI(c.OpenAPIConfig, c.Version)
completeOpenAPI(c.OpenAPIV3Config, c.Version) completeOpenAPIV3(c.OpenAPIV3Config, c.Version)
if c.DiscoveryAddresses == nil { if c.DiscoveryAddresses == nil {
c.DiscoveryAddresses = discovery.DefaultAddresses{DefaultAddress: c.ExternalAddress} c.DiscoveryAddresses = discovery.DefaultAddresses{DefaultAddress: c.ExternalAddress}

View File

@ -158,7 +158,7 @@ type GenericAPIServer struct {
openAPIConfig *openapicommon.Config openAPIConfig *openapicommon.Config
// Enable swagger and/or OpenAPI V3 if these configs are non-nil. // Enable swagger and/or OpenAPI V3 if these configs are non-nil.
openAPIV3Config *openapicommon.Config openAPIV3Config *openapicommon.OpenAPIV3Config
// SkipOpenAPIInstallation indicates not to install the OpenAPI handler // SkipOpenAPIInstallation indicates not to install the OpenAPI handler
// during PrepareRun. // during PrepareRun.
@ -432,7 +432,7 @@ func (s *GenericAPIServer) PrepareRun() preparedGenericAPIServer {
if s.openAPIV3Config != nil && !s.skipOpenAPIInstallation { if s.openAPIV3Config != nil && !s.skipOpenAPIInstallation {
if utilfeature.DefaultFeatureGate.Enabled(features.OpenAPIV3) { if utilfeature.DefaultFeatureGate.Enabled(features.OpenAPIV3) {
s.OpenAPIV3VersionedService = routes.OpenAPI{ s.OpenAPIV3VersionedService = routes.OpenAPI{
Config: s.openAPIV3Config, V3Config: s.openAPIV3Config,
}.InstallV3(s.Handler.GoRestfulContainer, s.Handler.NonGoRestfulMux) }.InstallV3(s.Handler.GoRestfulContainer, s.Handler.NonGoRestfulMux)
} }
} }

View File

@ -32,7 +32,8 @@ import (
// OpenAPI installs spec endpoints for each web service. // OpenAPI installs spec endpoints for each web service.
type OpenAPI struct { type OpenAPI struct {
Config *common.Config Config *common.Config
V3Config *common.OpenAPIV3Config
} }
// Install adds the SwaggerUI webservice to the given mux. // Install adds the SwaggerUI webservice to the given mux.
@ -65,7 +66,7 @@ func (oa OpenAPI) InstallV3(c *restful.Container, mux *mux.PathRecorderMux) *han
} }
for gv, ws := range grouped { for gv, ws := range grouped {
spec, err := builder3.BuildOpenAPISpecFromRoutes(restfuladapter.AdaptWebServices(ws), oa.Config) spec, err := builder3.BuildOpenAPISpecFromRoutes(restfuladapter.AdaptWebServices(ws), oa.V3Config)
if err != nil { if err != nil {
klog.Errorf("Failed to build OpenAPI v3 for group %s, %q", gv, err) klog.Errorf("Failed to build OpenAPI v3 for group %s, %q", gv, err)