Merge pull request #109031 from Jefftree/openapiv3beta
OpenAPI V3 Enable Beta Kubernetes-commit: 904c30562a9a34d26ff3e76db29d00daea2e0f60
This commit is contained in:
commit
ee1ac0ffde
18
go.mod
18
go.mod
|
|
@ -42,12 +42,12 @@ require (
|
|||
google.golang.org/grpc v1.40.0
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||
gopkg.in/square/go-jose.v2 v2.2.2
|
||||
k8s.io/api v0.0.0-20220330011019-6031be5d2a4d
|
||||
k8s.io/apimachinery v0.0.0-20220329130813-31e52c987dc1
|
||||
k8s.io/client-go v0.0.0-20220330011324-9cfda74c80a4
|
||||
k8s.io/component-base v0.0.0-20220330011832-6ef47acafa8e
|
||||
k8s.io/api v0.0.0-20220330051021-b754a94214be
|
||||
k8s.io/apimachinery v0.0.0-20220330050810-00f071187c12
|
||||
k8s.io/client-go v0.0.0-20220330051330-b1e85f6f0092
|
||||
k8s.io/component-base v0.0.0-20220330051900-ffc9c87ab39a
|
||||
k8s.io/klog/v2 v2.60.1
|
||||
k8s.io/kube-openapi v0.0.0-20220324211241-9f9c01d62a3a
|
||||
k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42
|
||||
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.30
|
||||
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2
|
||||
|
|
@ -56,8 +56,8 @@ require (
|
|||
)
|
||||
|
||||
replace (
|
||||
k8s.io/api => k8s.io/api v0.0.0-20220330011019-6031be5d2a4d
|
||||
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20220329130813-31e52c987dc1
|
||||
k8s.io/client-go => k8s.io/client-go v0.0.0-20220330011324-9cfda74c80a4
|
||||
k8s.io/component-base => k8s.io/component-base v0.0.0-20220330011832-6ef47acafa8e
|
||||
k8s.io/api => k8s.io/api v0.0.0-20220330051021-b754a94214be
|
||||
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20220330050810-00f071187c12
|
||||
k8s.io/client-go => k8s.io/client-go v0.0.0-20220330051330-b1e85f6f0092
|
||||
k8s.io/component-base => k8s.io/component-base v0.0.0-20220330051900-ffc9c87ab39a
|
||||
)
|
||||
|
|
|
|||
20
go.sum
20
go.sum
|
|
@ -954,21 +954,21 @@ 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-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=
|
||||
k8s.io/api v0.0.0-20220330011019-6031be5d2a4d h1:JITAFP7p1OtAeKzWnjkjjJxn6ctWoQvwwxabOyc8v7E=
|
||||
k8s.io/api v0.0.0-20220330011019-6031be5d2a4d/go.mod h1:DtY4NYpJTdEZbyZNYT6OchYvejyTwdm7DK07dMzPcII=
|
||||
k8s.io/apimachinery v0.0.0-20220329130813-31e52c987dc1 h1:ESix+UawmXFu9oem7ngnHSbufLCiIQrvn9TXHB1x/w4=
|
||||
k8s.io/apimachinery v0.0.0-20220329130813-31e52c987dc1/go.mod h1:WkN7hnr/sIpKTK8v3BZKqLkdqTMz00TBdMWqE0M0O7Q=
|
||||
k8s.io/client-go v0.0.0-20220330011324-9cfda74c80a4 h1:/DhMBD0xkS7DvAriCuffRTIsz1G4fI4NswWFfSNbLgQ=
|
||||
k8s.io/client-go v0.0.0-20220330011324-9cfda74c80a4/go.mod h1:YxULbpSLECQQvysnBfh02ucl8mDQnaxBbWzj/j4OpyI=
|
||||
k8s.io/component-base v0.0.0-20220330011832-6ef47acafa8e h1:LVTPrdPXjDa/QVeuJGpWfryOq7PJ4TEzICMomzm0hNE=
|
||||
k8s.io/component-base v0.0.0-20220330011832-6ef47acafa8e/go.mod h1:X2whuyKi0x6081clOWdbkh0RA29kBroU/3eEhlbWHBU=
|
||||
k8s.io/api v0.0.0-20220330051021-b754a94214be h1:UnXBdsSVy3e2Y6cyf9rVmzn0wPXyoUuGIZAM43vdTj0=
|
||||
k8s.io/api v0.0.0-20220330051021-b754a94214be/go.mod h1:gL+2VXubbVTH6gK18uLau2gxoDmu43bdiQmz5TTa3zw=
|
||||
k8s.io/apimachinery v0.0.0-20220330050810-00f071187c12 h1:+Cp1h0ojFtOluw7Bgiju2A/LqoWzeYyaB+sY/YSflwE=
|
||||
k8s.io/apimachinery v0.0.0-20220330050810-00f071187c12/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM=
|
||||
k8s.io/client-go v0.0.0-20220330051330-b1e85f6f0092 h1:juuWgiTcvrIkUVtF+C5CYsVA0YK7eNA6M/uD1J4WxNU=
|
||||
k8s.io/client-go v0.0.0-20220330051330-b1e85f6f0092/go.mod h1:891OlZJw6BK4fpxlZNVtaoFv0uIX9BfbxEsmMJBv1xM=
|
||||
k8s.io/component-base v0.0.0-20220330051900-ffc9c87ab39a h1:5GgsJwT9dZE4ta+/a+DDXa2FB0f7ZkmwqJbFE6CHZHo=
|
||||
k8s.io/component-base v0.0.0-20220330051900-ffc9c87ab39a/go.mod h1:LJBddfwf8ppsSrBEKyFor1D79VOnf+xhBp7/sE+XB/E=
|
||||
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||
k8s.io/klog/v2 v2.60.1 h1:VW25q3bZx9uE3vvdL6M8ezOX79vA2Aq1nEWLqNQclHc=
|
||||
k8s.io/klog/v2 v2.60.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
k8s.io/kube-openapi v0.0.0-20220324211241-9f9c01d62a3a h1:91uLlZzSWSkvb1xuJeHwRMTMLHRHXz7eXPNuKxXJb+0=
|
||||
k8s.io/kube-openapi v0.0.0-20220324211241-9f9c01d62a3a/go.mod h1:Z/45zLw8lUo4wdiUkI+v/ImEGAvu3WatcZl3lPMR4Rk=
|
||||
k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42 h1:Gii5eqf+GmIEwGNKQYQClCayuJCe2/4fZUvF7VG99sU=
|
||||
k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42/go.mod h1:Z/45zLw8lUo4wdiUkI+v/ImEGAvu3WatcZl3lPMR4Rk=
|
||||
k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19Vz2GdbOCyI4qqhc=
|
||||
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ const (
|
|||
// owner: @jefftree
|
||||
// kep: http://kep.k8s.io/2896
|
||||
// alpha: v1.23
|
||||
// beta: v1.24
|
||||
//
|
||||
// Enables kubernetes to publish OpenAPI v3
|
||||
OpenAPIV3 featuregate.Feature = "OpenAPIV3"
|
||||
|
|
@ -212,7 +213,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
|||
APIServerTracing: {Default: false, PreRelease: featuregate.Alpha},
|
||||
OpenAPIEnums: {Default: true, PreRelease: featuregate.Beta},
|
||||
CustomResourceValidationExpressions: {Default: false, PreRelease: featuregate.Alpha},
|
||||
OpenAPIV3: {Default: false, PreRelease: featuregate.Alpha},
|
||||
OpenAPIV3: {Default: true, PreRelease: featuregate.Beta},
|
||||
ServerSideFieldValidation: {Default: true, PreRelease: featuregate.Beta},
|
||||
CronJobTimeZone: {Default: false, PreRelease: featuregate.Alpha},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,6 +171,8 @@ type Config struct {
|
|||
Serializer runtime.NegotiatedSerializer
|
||||
// OpenAPIConfig will be used in generating OpenAPI spec. This is nil by default. Use DefaultOpenAPIConfig for "working" defaults.
|
||||
OpenAPIConfig *openapicommon.Config
|
||||
// OpenAPIV3Config will be used in generating OpenAPI V3 spec. This is nil by default. Use DefaultOpenAPIV3Config for "working" defaults.
|
||||
OpenAPIV3Config *openapicommon.Config
|
||||
// SkipOpenAPIInstallation avoids installing the OpenAPI handler if set to true.
|
||||
SkipOpenAPIInstallation bool
|
||||
|
||||
|
|
@ -382,6 +384,7 @@ func NewRecommendedConfig(codecs serializer.CodecFactory) *RecommendedConfig {
|
|||
}
|
||||
}
|
||||
|
||||
// DefaultOpenAPIConfig provides the default OpenAPIConfig used to build the OpenAPI V2 spec
|
||||
func DefaultOpenAPIConfig(getDefinitions openapicommon.GetOpenAPIDefinitions, defNamer *apiopenapi.DefinitionNamer) *openapicommon.Config {
|
||||
return &openapicommon.Config{
|
||||
ProtocolList: []string{"https"},
|
||||
|
|
@ -402,6 +405,17 @@ func DefaultOpenAPIConfig(getDefinitions openapicommon.GetOpenAPIDefinitions, de
|
|||
}
|
||||
}
|
||||
|
||||
// DefaultOpenAPIV3Config provides the default OpenAPIV3Config used to build the OpenAPI V3 spec
|
||||
func DefaultOpenAPIV3Config(getDefinitions openapicommon.GetOpenAPIDefinitions, defNamer *apiopenapi.DefinitionNamer) *openapicommon.Config {
|
||||
defaultConfig := DefaultOpenAPIConfig(getDefinitions, defNamer)
|
||||
defaultConfig.Definitions = getDefinitions(func(name string) spec.Ref {
|
||||
defName, _ := defaultConfig.GetDefinitionName(name)
|
||||
return spec.MustCreateRef("#/components/schemas/" + openapicommon.EscapeJsonPointer(defName))
|
||||
})
|
||||
|
||||
return defaultConfig
|
||||
}
|
||||
|
||||
func (c *AuthenticationInfo) ApplyClientCert(clientCA dynamiccertificates.CAContentProvider, servingInfo *SecureServingInfo) error {
|
||||
if servingInfo == nil {
|
||||
return nil
|
||||
|
|
@ -475,6 +489,45 @@ func (c *Config) AddPostStartHookOrDie(name string, hook PostStartHookFunc) {
|
|||
}
|
||||
}
|
||||
|
||||
func completeOpenAPI(config *openapicommon.Config, version *version.Info) {
|
||||
if config == nil {
|
||||
return
|
||||
}
|
||||
if config.SecurityDefinitions != nil {
|
||||
// Setup OpenAPI security: all APIs will have the same authentication for now.
|
||||
config.DefaultSecurity = []map[string][]string{}
|
||||
keys := []string{}
|
||||
for k := range *config.SecurityDefinitions {
|
||||
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]spec.Response{}
|
||||
}
|
||||
if _, exists := config.CommonResponses[http.StatusUnauthorized]; !exists {
|
||||
config.CommonResponses[http.StatusUnauthorized] = spec.Response{
|
||||
ResponseProps: spec.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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Complete fills in any fields not set that are required to have valid data and can be derived
|
||||
// from other fields. If you're going to `ApplyOptions`, do that first. It's mutating the receiver.
|
||||
func (c *Config) Complete(informers informers.SharedInformerFactory) CompletedConfig {
|
||||
|
|
@ -494,42 +547,9 @@ func (c *Config) Complete(informers informers.SharedInformerFactory) CompletedCo
|
|||
c.ExternalAddress = net.JoinHostPort(c.ExternalAddress, strconv.Itoa(port))
|
||||
}
|
||||
|
||||
if c.OpenAPIConfig != nil {
|
||||
if c.OpenAPIConfig.SecurityDefinitions != nil {
|
||||
// Setup OpenAPI security: all APIs will have the same authentication for now.
|
||||
c.OpenAPIConfig.DefaultSecurity = []map[string][]string{}
|
||||
keys := []string{}
|
||||
for k := range *c.OpenAPIConfig.SecurityDefinitions {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, k := range keys {
|
||||
c.OpenAPIConfig.DefaultSecurity = append(c.OpenAPIConfig.DefaultSecurity, map[string][]string{k: {}})
|
||||
}
|
||||
if c.OpenAPIConfig.CommonResponses == nil {
|
||||
c.OpenAPIConfig.CommonResponses = map[int]spec.Response{}
|
||||
}
|
||||
if _, exists := c.OpenAPIConfig.CommonResponses[http.StatusUnauthorized]; !exists {
|
||||
c.OpenAPIConfig.CommonResponses[http.StatusUnauthorized] = spec.Response{
|
||||
ResponseProps: spec.ResponseProps{
|
||||
Description: "Unauthorized",
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
completeOpenAPI(c.OpenAPIConfig, c.Version)
|
||||
completeOpenAPI(c.OpenAPIV3Config, c.Version)
|
||||
|
||||
// make sure we populate info, and info.version, if not manually set
|
||||
if c.OpenAPIConfig.Info == nil {
|
||||
c.OpenAPIConfig.Info = &spec.Info{}
|
||||
}
|
||||
if c.OpenAPIConfig.Info.Version == "" {
|
||||
if c.Version != nil {
|
||||
c.OpenAPIConfig.Info.Version = strings.Split(c.Version.String(), "-")[0]
|
||||
} else {
|
||||
c.OpenAPIConfig.Info.Version = "unversioned"
|
||||
}
|
||||
}
|
||||
}
|
||||
if c.DiscoveryAddresses == nil {
|
||||
c.DiscoveryAddresses = discovery.DefaultAddresses{DefaultAddress: c.ExternalAddress}
|
||||
}
|
||||
|
|
@ -606,6 +626,7 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G
|
|||
ExternalAddress: c.ExternalAddress,
|
||||
|
||||
openAPIConfig: c.OpenAPIConfig,
|
||||
openAPIV3Config: c.OpenAPIV3Config,
|
||||
skipOpenAPIInstallation: c.SkipOpenAPIInstallation,
|
||||
|
||||
postStartHooks: map[string]postStartHookEntry{},
|
||||
|
|
|
|||
|
|
@ -135,6 +135,9 @@ type GenericAPIServer struct {
|
|||
// Enable swagger and/or OpenAPI if these configs are non-nil.
|
||||
openAPIConfig *openapicommon.Config
|
||||
|
||||
// Enable swagger and/or OpenAPI V3 if these configs are non-nil.
|
||||
openAPIV3Config *openapicommon.Config
|
||||
|
||||
// SkipOpenAPIInstallation indicates not to install the OpenAPI handler
|
||||
// during PrepareRun.
|
||||
// Set this to true when the specific API Server has its own OpenAPI handler
|
||||
|
|
@ -351,9 +354,12 @@ func (s *GenericAPIServer) PrepareRun() preparedGenericAPIServer {
|
|||
s.OpenAPIVersionedService, s.StaticOpenAPISpec = routes.OpenAPI{
|
||||
Config: s.openAPIConfig,
|
||||
}.InstallV2(s.Handler.GoRestfulContainer, s.Handler.NonGoRestfulMux)
|
||||
}
|
||||
|
||||
if s.openAPIV3Config != nil && !s.skipOpenAPIInstallation {
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.OpenAPIV3) {
|
||||
s.OpenAPIV3VersionedService = routes.OpenAPI{
|
||||
Config: s.openAPIConfig,
|
||||
Config: s.openAPIV3Config,
|
||||
}.InstallV3(s.Handler.GoRestfulContainer, s.Handler.NonGoRestfulMux)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue