Merge pull request #114998 from alexzielenski/apiserver/smd/ssa-conditionals

Fix SSA being silently disabled by lack of OpenAPI config
This commit is contained in:
Kubernetes Prow Robot 2023-05-01 16:34:11 -07:00 committed by GitHub
commit 2588ae9a04
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 3016 additions and 147 deletions

View File

@ -1,3 +1,40 @@
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,ConversionRequest,Objects
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,ConversionResponse,ConvertedObjects
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,CustomResourceDefinitionNames,Categories
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,CustomResourceDefinitionNames,ShortNames
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,CustomResourceDefinitionSpec,Versions
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,CustomResourceDefinitionStatus,StoredVersions
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,CustomResourceDefinitionVersion,AdditionalPrinterColumns
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSON,Raw
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaProps,AllOf
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaProps,AnyOf
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaProps,Enum
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaProps,OneOf
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaProps,Required
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaProps,XListMapKeys
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaPropsOrArray,JSONSchemas
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaPropsOrStringArray,Property
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,WebhookClientConfig,CABundle
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,WebhookConversion,ConversionReviewVersions
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,ConversionRequest,Objects
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,ConversionResponse,ConvertedObjects
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,CustomResourceConversion,ConversionReviewVersions
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,CustomResourceDefinitionNames,Categories
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,CustomResourceDefinitionNames,ShortNames
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,CustomResourceDefinitionSpec,AdditionalPrinterColumns
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,CustomResourceDefinitionSpec,Versions
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,CustomResourceDefinitionStatus,StoredVersions
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,CustomResourceDefinitionVersion,AdditionalPrinterColumns
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSON,Raw
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaProps,AllOf
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaProps,AnyOf
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaProps,Enum
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaProps,OneOf
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaProps,Required
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaProps,XListMapKeys
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaPropsOrArray,JSONSchemas
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaPropsOrStringArray,Property
API rule violation: list_type_missing,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,WebhookClientConfig,CABundle
API rule violation: list_type_missing,k8s.io/apimachinery/pkg/apis/meta/v1,APIGroup,ServerAddressByClientCIDRs API rule violation: list_type_missing,k8s.io/apimachinery/pkg/apis/meta/v1,APIGroup,ServerAddressByClientCIDRs
API rule violation: list_type_missing,k8s.io/apimachinery/pkg/apis/meta/v1,APIGroup,Versions API rule violation: list_type_missing,k8s.io/apimachinery/pkg/apis/meta/v1,APIGroup,Versions
API rule violation: list_type_missing,k8s.io/apimachinery/pkg/apis/meta/v1,APIGroupList,Groups API rule violation: list_type_missing,k8s.io/apimachinery/pkg/apis/meta/v1,APIGroupList,Groups
@ -25,6 +62,37 @@ API rule violation: list_type_missing,k8s.io/apimachinery/pkg/apis/meta/v1,Table
API rule violation: list_type_missing,k8s.io/apimachinery/pkg/apis/meta/v1,UpdateOptions,DryRun API rule violation: list_type_missing,k8s.io/apimachinery/pkg/apis/meta/v1,UpdateOptions,DryRun
API rule violation: list_type_missing,k8s.io/apimachinery/pkg/runtime,RawExtension,Raw API rule violation: list_type_missing,k8s.io/apimachinery/pkg/runtime,RawExtension,Raw
API rule violation: list_type_missing,k8s.io/apimachinery/pkg/runtime,Unknown,Raw API rule violation: list_type_missing,k8s.io/apimachinery/pkg/runtime,Unknown,Raw
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaProps,Ref
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaProps,Schema
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaProps,XEmbeddedResource
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaProps,XIntOrString
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaProps,XListMapKeys
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaProps,XListType
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaProps,XMapType
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaProps,XPreserveUnknownFields
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaProps,XValidations
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaPropsOrArray,JSONSchemas
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaPropsOrArray,Schema
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaPropsOrBool,Allows
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaPropsOrBool,Schema
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaPropsOrStringArray,Property
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaPropsOrStringArray,Schema
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,CustomResourceColumnDefinition,JSONPath
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaProps,Ref
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaProps,Schema
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaProps,XEmbeddedResource
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaProps,XIntOrString
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaProps,XListMapKeys
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaProps,XListType
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaProps,XMapType
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaProps,XPreserveUnknownFields
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaProps,XValidations
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaPropsOrArray,JSONSchemas
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaPropsOrArray,Schema
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaPropsOrBool,Allows
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaPropsOrBool,Schema
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaPropsOrStringArray,Property
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1,JSONSchemaPropsOrStringArray,Schema
API rule violation: names_match,k8s.io/apimachinery/pkg/apis/meta/v1,APIResourceList,APIResources API rule violation: names_match,k8s.io/apimachinery/pkg/apis/meta/v1,APIResourceList,APIResources
API rule violation: names_match,k8s.io/apimachinery/pkg/apis/meta/v1,Duration,Duration API rule violation: names_match,k8s.io/apimachinery/pkg/apis/meta/v1,Duration,Duration
API rule violation: names_match,k8s.io/apimachinery/pkg/apis/meta/v1,InternalEvent,Object API rule violation: names_match,k8s.io/apimachinery/pkg/apis/meta/v1,InternalEvent,Object

View File

@ -378,9 +378,10 @@ func buildGenericConfig(
} }
// wrap the definitions to revert any changes from disabled features // wrap the definitions to revert any changes from disabled features
getOpenAPIDefinitions := openapi.GetOpenAPIDefinitionsWithoutDisabledFeatures(generatedopenapi.GetOpenAPIDefinitions) getOpenAPIDefinitions := openapi.GetOpenAPIDefinitionsWithoutDisabledFeatures(generatedopenapi.GetOpenAPIDefinitions)
genericConfig.OpenAPIConfig = genericapiserver.DefaultOpenAPIConfig(getOpenAPIDefinitions, openapinamer.NewDefinitionNamer(legacyscheme.Scheme, extensionsapiserver.Scheme, aggregatorscheme.Scheme)) namer := openapinamer.NewDefinitionNamer(legacyscheme.Scheme, extensionsapiserver.Scheme, aggregatorscheme.Scheme)
genericConfig.OpenAPIConfig = genericapiserver.DefaultOpenAPIConfig(getOpenAPIDefinitions, namer)
genericConfig.OpenAPIConfig.Info.Title = "Kubernetes" genericConfig.OpenAPIConfig.Info.Title = "Kubernetes"
genericConfig.OpenAPIV3Config = genericapiserver.DefaultOpenAPIV3Config(getOpenAPIDefinitions, openapinamer.NewDefinitionNamer(legacyscheme.Scheme, extensionsapiserver.Scheme, aggregatorscheme.Scheme)) genericConfig.OpenAPIV3Config = genericapiserver.DefaultOpenAPIV3Config(getOpenAPIDefinitions, namer)
genericConfig.OpenAPIV3Config.Info.Title = "Kubernetes" genericConfig.OpenAPIV3Config.Info.Title = "Kubernetes"
genericConfig.LongRunningFunc = filters.BasicLongRunningRequestCheck( genericConfig.LongRunningFunc = filters.BasicLongRunningRequestCheck(

View File

@ -603,7 +603,7 @@ function codegen::openapi() {
local APIEXTENSIONS_tag_files=() local APIEXTENSIONS_tag_files=()
kube::util::read-array APIEXTENSIONS_tag_files < <( kube::util::read-array APIEXTENSIONS_tag_files < <(
k8s_tag_files_matching \ k8s_tag_files_matching \
vendor/k8s.io/apiextensions \ vendor/k8s.io/apiextensions-apiserver \
vendor/k8s.io/api/autoscaling/v1 \ vendor/k8s.io/api/autoscaling/v1 \
"${apimachinery_dirs[@]}" "${apimachinery_dirs[@]}"
) )

View File

@ -37,26 +37,31 @@ import (
nodev1beta1 "k8s.io/api/node/v1beta1" nodev1beta1 "k8s.io/api/node/v1beta1"
policyapiv1beta1 "k8s.io/api/policy/v1beta1" policyapiv1beta1 "k8s.io/api/policy/v1beta1"
storageapiv1beta1 "k8s.io/api/storage/v1beta1" storageapiv1beta1 "k8s.io/api/storage/v1beta1"
extensionsapiserver "k8s.io/apiextensions-apiserver/pkg/apiserver"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
utilnet "k8s.io/apimachinery/pkg/util/net" utilnet "k8s.io/apimachinery/pkg/util/net"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/version" "k8s.io/apimachinery/pkg/version"
"k8s.io/apiserver/pkg/authorization/authorizerfactory" "k8s.io/apiserver/pkg/authorization/authorizerfactory"
openapinamer "k8s.io/apiserver/pkg/endpoints/openapi"
genericapiserver "k8s.io/apiserver/pkg/server" genericapiserver "k8s.io/apiserver/pkg/server"
"k8s.io/apiserver/pkg/server/options" "k8s.io/apiserver/pkg/server/options"
"k8s.io/apiserver/pkg/server/resourceconfig" "k8s.io/apiserver/pkg/server/resourceconfig"
serverstorage "k8s.io/apiserver/pkg/server/storage" serverstorage "k8s.io/apiserver/pkg/server/storage"
etcd3testing "k8s.io/apiserver/pkg/storage/etcd3/testing" etcd3testing "k8s.io/apiserver/pkg/storage/etcd3/testing"
"k8s.io/apiserver/pkg/util/openapi"
"k8s.io/client-go/discovery" "k8s.io/client-go/discovery"
"k8s.io/client-go/informers" "k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest" restclient "k8s.io/client-go/rest"
kubeversion "k8s.io/component-base/version" kubeversion "k8s.io/component-base/version"
aggregatorscheme "k8s.io/kube-aggregator/pkg/apiserver/scheme"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
flowcontrolv1beta2 "k8s.io/kubernetes/pkg/apis/flowcontrol/v1beta2" flowcontrolv1beta2 "k8s.io/kubernetes/pkg/apis/flowcontrol/v1beta2"
"k8s.io/kubernetes/pkg/controlplane/reconcilers" "k8s.io/kubernetes/pkg/controlplane/reconcilers"
"k8s.io/kubernetes/pkg/controlplane/storageversionhashdata" "k8s.io/kubernetes/pkg/controlplane/storageversionhashdata"
generatedopenapi "k8s.io/kubernetes/pkg/generated/openapi"
"k8s.io/kubernetes/pkg/kubeapiserver" "k8s.io/kubernetes/pkg/kubeapiserver"
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client" kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
certificatesrest "k8s.io/kubernetes/pkg/registry/certificates/rest" certificatesrest "k8s.io/kubernetes/pkg/registry/certificates/rest"
@ -113,6 +118,10 @@ func setUp(t *testing.T) (*etcd3testing.EtcdTestServer, Config, *assert.Assertio
// set fake SecureServingInfo because the listener port is needed for the kubernetes service // set fake SecureServingInfo because the listener port is needed for the kubernetes service
config.GenericConfig.SecureServing = &genericapiserver.SecureServingInfo{Listener: fakeLocalhost443Listener{}} config.GenericConfig.SecureServing = &genericapiserver.SecureServingInfo{Listener: fakeLocalhost443Listener{}}
getOpenAPIDefinitions := openapi.GetOpenAPIDefinitionsWithoutDisabledFeatures(generatedopenapi.GetOpenAPIDefinitions)
namer := openapinamer.NewDefinitionNamer(legacyscheme.Scheme, extensionsapiserver.Scheme, aggregatorscheme.Scheme)
config.GenericConfig.OpenAPIV3Config = genericapiserver.DefaultOpenAPIV3Config(getOpenAPIDefinitions, namer)
clientset, err := kubernetes.NewForConfig(config.GenericConfig.LoopbackClientConfig) clientset, err := kubernetes.NewForConfig(config.GenericConfig.LoopbackClientConfig)
if err != nil { if err != nil {
t.Fatalf("unable to create client set due to %v", err) t.Fatalf("unable to create client set due to %v", err)

View File

@ -29,13 +29,17 @@ import (
v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
"k8s.io/apiextensions-apiserver/pkg/apiserver" "k8s.io/apiextensions-apiserver/pkg/apiserver"
generatedopenapi "k8s.io/apiextensions-apiserver/pkg/generated/openapi"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
utilerrors "k8s.io/apimachinery/pkg/util/errors" utilerrors "k8s.io/apimachinery/pkg/util/errors"
openapinamer "k8s.io/apiserver/pkg/endpoints/openapi"
genericregistry "k8s.io/apiserver/pkg/registry/generic" genericregistry "k8s.io/apiserver/pkg/registry/generic"
genericapiserver "k8s.io/apiserver/pkg/server" genericapiserver "k8s.io/apiserver/pkg/server"
genericoptions "k8s.io/apiserver/pkg/server/options" genericoptions "k8s.io/apiserver/pkg/server/options"
"k8s.io/apiserver/pkg/util/openapi"
"k8s.io/apiserver/pkg/util/proxy" "k8s.io/apiserver/pkg/util/proxy"
"k8s.io/apiserver/pkg/util/webhook" "k8s.io/apiserver/pkg/util/webhook"
scheme "k8s.io/client-go/kubernetes/scheme"
corev1 "k8s.io/client-go/listers/core/v1" corev1 "k8s.io/client-go/listers/core/v1"
netutils "k8s.io/utils/net" netutils "k8s.io/utils/net"
) )
@ -111,6 +115,8 @@ func (o CustomResourceDefinitionsServerOptions) Config() (*apiserver.Config, err
if err != nil { if err != nil {
return nil, err return nil, err
} }
serverConfig.OpenAPIV3Config = genericapiserver.DefaultOpenAPIV3Config(openapi.GetOpenAPIDefinitionsWithoutDisabledFeatures(generatedopenapi.GetOpenAPIDefinitions), openapinamer.NewDefinitionNamer(apiserver.Scheme, scheme.Scheme))
config := &apiserver.Config{ config := &apiserver.Config{
GenericConfig: serverConfig, GenericConfig: serverConfig,
ExtraConfig: apiserver.ExtraConfig{ ExtraConfig: apiserver.ExtraConfig{

View File

@ -40,6 +40,7 @@ import (
"k8s.io/apiserver/pkg/endpoints" "k8s.io/apiserver/pkg/endpoints"
"k8s.io/apiserver/pkg/endpoints/openapi" "k8s.io/apiserver/pkg/endpoints/openapi"
utilopenapi "k8s.io/apiserver/pkg/util/openapi" utilopenapi "k8s.io/apiserver/pkg/util/openapi"
"k8s.io/client-go/kubernetes/scheme"
openapibuilder "k8s.io/kube-openapi/pkg/builder" openapibuilder "k8s.io/kube-openapi/pkg/builder"
"k8s.io/kube-openapi/pkg/builder3" "k8s.io/kube-openapi/pkg/builder3"
"k8s.io/kube-openapi/pkg/common" "k8s.io/kube-openapi/pkg/common"
@ -468,7 +469,7 @@ func withDescription(s spec.Schema, desc string) spec.Schema {
} }
func generateBuildDefinitionsFunc() { func generateBuildDefinitionsFunc() {
namer = openapi.NewDefinitionNamer(runtime.NewScheme()) namer = openapi.NewDefinitionNamer(scheme.Scheme)
definitionsV3 = utilopenapi.GetOpenAPIDefinitionsWithoutDisabledFeatures(generatedopenapi.GetOpenAPIDefinitions)(func(name string) spec.Ref { definitionsV3 = utilopenapi.GetOpenAPIDefinitionsWithoutDisabledFeatures(generatedopenapi.GetOpenAPIDefinitions)(func(name string) spec.Ref {
defName, _ := namer.GetDefinitionName(name) defName, _ := namer.GetDefinitionName(name)
prefix := v3DefinitionPrefix prefix := v3DefinitionPrefix

View File

@ -41,6 +41,9 @@ var _ Manager = &structuredMergeManager{}
// NewStructuredMergeManager creates a new Manager that merges apply requests // NewStructuredMergeManager creates a new Manager that merges apply requests
// and update managed fields for other types of requests. // and update managed fields for other types of requests.
func NewStructuredMergeManager(typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, gv schema.GroupVersion, hub schema.GroupVersion, resetFields map[fieldpath.APIVersion]*fieldpath.Set) (Manager, error) { func NewStructuredMergeManager(typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, gv schema.GroupVersion, hub schema.GroupVersion, resetFields map[fieldpath.APIVersion]*fieldpath.Set) (Manager, error) {
if typeConverter == nil {
return nil, fmt.Errorf("typeconverter must not be nil")
}
return &structuredMergeManager{ return &structuredMergeManager{
typeConverter: typeConverter, typeConverter: typeConverter,
objectConverter: objectConverter, objectConverter: objectConverter,

View File

@ -56,6 +56,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apimachinery/pkg/runtime/serializer/streaming" "k8s.io/apimachinery/pkg/runtime/serializer/streaming"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/managedfields"
"k8s.io/apimachinery/pkg/util/net" "k8s.io/apimachinery/pkg/util/net"
utilruntime "k8s.io/apimachinery/pkg/util/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
@ -231,6 +232,7 @@ func handleInternal(storage map[string]rest.Storage, admissionControl admission.
Creater: scheme, Creater: scheme,
Convertor: scheme, Convertor: scheme,
TypeConverter: managedfields.NewDeducedTypeConverter(),
UnsafeConvertor: runtime.UnsafeObjectConvertor(scheme), UnsafeConvertor: runtime.UnsafeObjectConvertor(scheme),
Defaulter: scheme, Defaulter: scheme,
Typer: scheme, Typer: scheme,
@ -3339,6 +3341,7 @@ func TestParentResourceIsRequired(t *testing.T) {
Creater: scheme, Creater: scheme,
Convertor: scheme, Convertor: scheme,
UnsafeConvertor: runtime.UnsafeObjectConvertor(scheme), UnsafeConvertor: runtime.UnsafeObjectConvertor(scheme),
TypeConverter: managedfields.NewDeducedTypeConverter(),
Defaulter: scheme, Defaulter: scheme,
Typer: scheme, Typer: scheme,
Namer: namer, Namer: namer,
@ -3532,6 +3535,8 @@ func TestNamedCreaterWithGenerateName(t *testing.T) {
t.Errorf("unexpected error: %v %#v", err, response) t.Errorf("unexpected error: %v %#v", err, response)
} }
// Avoid comparing managed fields in expected result
itemOut.ManagedFields = nil
itemOut.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{}) itemOut.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{})
simple.Name = populateName simple.Name = populateName
simple.Namespace = "default" // populated by create handler to match request URL simple.Namespace = "default" // populated by create handler to match request URL
@ -3612,6 +3617,8 @@ func TestCreate(t *testing.T) {
t.Errorf("unexpected error: %v %#v", err, response) t.Errorf("unexpected error: %v %#v", err, response)
} }
// Avoid comparing managed fields in expected result
itemOut.ManagedFields = nil
itemOut.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{}) itemOut.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{})
simple.Namespace = "default" // populated by create handler to match request URL simple.Namespace = "default" // populated by create handler to match request URL
if !reflect.DeepEqual(&itemOut, simple) { if !reflect.DeepEqual(&itemOut, simple) {
@ -3674,6 +3681,8 @@ func TestCreateYAML(t *testing.T) {
t.Fatalf("unexpected error: %v %#v", err, response) t.Fatalf("unexpected error: %v %#v", err, response)
} }
// Avoid comparing managed fields in expected result
itemOut.ManagedFields = nil
itemOut.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{}) itemOut.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{})
simple.Namespace = "default" // populated by create handler to match request URL simple.Namespace = "default" // populated by create handler to match request URL
if !reflect.DeepEqual(&itemOut, simple) { if !reflect.DeepEqual(&itemOut, simple) {
@ -3726,6 +3735,8 @@ func TestCreateInNamespace(t *testing.T) {
t.Fatalf("unexpected error: %v\n%s", err, data) t.Fatalf("unexpected error: %v\n%s", err, data)
} }
// Avoid comparing managed fields in expected result
itemOut.ManagedFields = nil
itemOut.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{}) itemOut.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{})
simple.Namespace = "other" // populated by create handler to match request URL simple.Namespace = "other" // populated by create handler to match request URL
if !reflect.DeepEqual(&itemOut, simple) { if !reflect.DeepEqual(&itemOut, simple) {
@ -4324,6 +4335,7 @@ func TestXGSubresource(t *testing.T) {
Creater: scheme, Creater: scheme,
Convertor: scheme, Convertor: scheme,
TypeConverter: managedfields.NewDeducedTypeConverter(),
UnsafeConvertor: runtime.UnsafeObjectConvertor(scheme), UnsafeConvertor: runtime.UnsafeObjectConvertor(scheme),
Defaulter: scheme, Defaulter: scheme,
Typer: scheme, Typer: scheme,

View File

@ -191,14 +191,13 @@ func createHandler(r rest.NamedCreater, scope *RequestScope, admit admission.Int
// Dedup owner references before updating managed fields // Dedup owner references before updating managed fields
dedupOwnerReferencesAndAddWarning(obj, req.Context(), false) dedupOwnerReferencesAndAddWarning(obj, req.Context(), false)
result, err := finisher.FinishRequest(ctx, func() (runtime.Object, error) { result, err := finisher.FinishRequest(ctx, func() (runtime.Object, error) {
if scope.FieldManager != nil {
liveObj, err := scope.Creater.New(scope.Kind) liveObj, err := scope.Creater.New(scope.Kind)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to create new object (Create for %v): %v", scope.Kind, err) return nil, fmt.Errorf("failed to create new object (Create for %v): %v", scope.Kind, err)
} }
obj = scope.FieldManager.UpdateNoErrors(liveObj, obj, managerOrUserAgent(options.FieldManager, req.UserAgent())) obj = scope.FieldManager.UpdateNoErrors(liveObj, obj, managerOrUserAgent(options.FieldManager, req.UserAgent()))
admit = fieldmanager.NewManagedFieldsValidatingAdmissionController(admit) admit = fieldmanager.NewManagedFieldsValidatingAdmissionController(admit)
}
if mutatingAdmission, ok := admit.(admission.MutationInterface); ok && mutatingAdmission.Handles(admission.Create) { if mutatingAdmission, ok := admit.(admission.MutationInterface); ok && mutatingAdmission.Handles(admission.Create) {
if err := mutatingAdmission.Admit(ctx, admissionAttributes, scope); err != nil { if err := mutatingAdmission.Admit(ctx, admissionAttributes, scope); err != nil {
return nil, err return nil, err

View File

@ -177,9 +177,8 @@ func PatchResource(r rest.Patcher, scope *RequestScope, admit admission.Interfac
userInfo, userInfo,
) )
if scope.FieldManager != nil {
admit = fieldmanager.NewManagedFieldsValidatingAdmissionController(admit) admit = fieldmanager.NewManagedFieldsValidatingAdmissionController(admit)
}
mutatingAdmission, _ := admit.(admission.MutationInterface) mutatingAdmission, _ := admit.(admission.MutationInterface)
createAuthorizerAttributes := authorizer.AttributesRecord{ createAuthorizerAttributes := authorizer.AttributesRecord{
User: userInfo, User: userInfo,
@ -345,9 +344,12 @@ func (p *jsonPatcher) applyPatchToCurrentObject(requestContext context.Context,
} }
} }
if p.fieldManager != nil { if p.options == nil {
objToUpdate = p.fieldManager.UpdateNoErrors(currentObject, objToUpdate, managerOrUserAgent(p.options.FieldManager, p.userAgent)) // Provide a more informative error for the crash that would
// happen on the next line
panic("PatchOptions required but not provided")
} }
objToUpdate = p.fieldManager.UpdateNoErrors(currentObject, objToUpdate, managerOrUserAgent(p.options.FieldManager, p.userAgent))
return objToUpdate, nil return objToUpdate, nil
} }
@ -441,9 +443,7 @@ func (p *smpPatcher) applyPatchToCurrentObject(requestContext context.Context, c
return nil, err return nil, err
} }
if p.fieldManager != nil {
newObj = p.fieldManager.UpdateNoErrors(currentObject, newObj, managerOrUserAgent(p.options.FieldManager, p.userAgent)) newObj = p.fieldManager.UpdateNoErrors(currentObject, newObj, managerOrUserAgent(p.options.FieldManager, p.userAgent))
}
return newObj, nil return newObj, nil
} }

View File

@ -40,6 +40,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/json" "k8s.io/apimachinery/pkg/util/json"
"k8s.io/apimachinery/pkg/util/managedfields"
utilruntime "k8s.io/apimachinery/pkg/util/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/strategicpatch" "k8s.io/apimachinery/pkg/util/strategicpatch"
"k8s.io/apimachinery/pkg/util/yaml" "k8s.io/apimachinery/pkg/util/yaml"
@ -451,6 +452,13 @@ func (tc *patchTestCase) Run(t *testing.T) {
schemaReferenceObj := &examplev1.Pod{} schemaReferenceObj := &examplev1.Pod{}
hubVersion := example.SchemeGroupVersion hubVersion := example.SchemeGroupVersion
fieldmanager, err := managedfields.NewDefaultFieldManager(
managedfields.NewDeducedTypeConverter(),
convertor, defaulter, creater, kind, hubVersion, "", nil)
if err != nil {
t.Fatalf("failed to create field manager: %v", err)
}
for _, patchType := range []types.PatchType{types.JSONPatchType, types.MergePatchType, types.StrategicMergePatchType} { for _, patchType := range []types.PatchType{types.JSONPatchType, types.MergePatchType, types.StrategicMergePatchType} {
// This needs to be reset on each iteration. // This needs to be reset on each iteration.
testPatcher := &testPatcher{ testPatcher := &testPatcher{
@ -536,10 +544,15 @@ func (tc *patchTestCase) Run(t *testing.T) {
name: name, name: name,
patchType: patchType, patchType: patchType,
patchBytes: patch, patchBytes: patch,
options: &metav1.PatchOptions{
FieldManager: "test-manager",
},
} }
ctx, cancel := context.WithTimeout(ctx, time.Second) ctx, cancel := context.WithTimeout(ctx, time.Second)
resultObj, _, err := p.patchResource(ctx, &RequestScope{}) resultObj, _, err := p.patchResource(ctx, &RequestScope{
FieldManager: fieldmanager,
})
cancel() cancel()
if len(tc.expectedError) != 0 { if len(tc.expectedError) != 0 {

View File

@ -156,7 +156,6 @@ func UpdateResource(r rest.Updater, scope *RequestScope, admit admission.Interfa
// allows skipping managedFields update if the resulting object is too big // allows skipping managedFields update if the resulting object is too big
shouldUpdateManagedFields := true shouldUpdateManagedFields := true
if scope.FieldManager != nil {
admit = fieldmanager.NewManagedFieldsValidatingAdmissionController(admit) admit = fieldmanager.NewManagedFieldsValidatingAdmissionController(admit)
transformers = append(transformers, func(_ context.Context, newObj, liveObj runtime.Object) (runtime.Object, error) { transformers = append(transformers, func(_ context.Context, newObj, liveObj runtime.Object) (runtime.Object, error) {
if shouldUpdateManagedFields { if shouldUpdateManagedFields {
@ -164,7 +163,6 @@ func UpdateResource(r rest.Updater, scope *RequestScope, admit admission.Interfa
} }
return newObj, nil return newObj, nil
}) })
}
if mutatingAdmission, ok := admit.(admission.MutationInterface); ok { if mutatingAdmission, ok := admit.(admission.MutationInterface); ok {
transformers = append(transformers, func(ctx context.Context, newObj, oldObj runtime.Object) (runtime.Object, error) { transformers = append(transformers, func(ctx context.Context, newObj, oldObj runtime.Object) (runtime.Object, error) {
@ -228,7 +226,7 @@ func UpdateResource(r rest.Updater, scope *RequestScope, admit admission.Interfa
result, err := requestFunc() result, err := requestFunc()
// If the object wasn't committed to storage because it's serialized size was too large, // If the object wasn't committed to storage because it's serialized size was too large,
// it is safe to remove managedFields (which can be large) and try again. // it is safe to remove managedFields (which can be large) and try again.
if isTooLargeError(err) && scope.FieldManager != nil { if isTooLargeError(err) {
if accessor, accessorErr := meta.Accessor(obj); accessorErr == nil { if accessor, accessorErr := meta.Accessor(obj); accessorErr == nil {
accessor.SetManagedFields(nil) accessor.SetManagedFields(nil)
shouldUpdateManagedFields = false shouldUpdateManagedFields = false

View File

@ -674,10 +674,6 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
reqScope.MetaGroupVersion = *a.group.MetaGroupVersion reqScope.MetaGroupVersion = *a.group.MetaGroupVersion
} }
// Use TypeConverter's nil-ness as a proxy for whether SSA/OpenAPI is enabled
// This should be removed in the future and made unconditional
// https://github.com/kubernetes/kubernetes/pull/114998
if a.group.TypeConverter != nil {
var resetFields map[fieldpath.APIVersion]*fieldpath.Set var resetFields map[fieldpath.APIVersion]*fieldpath.Set
if resetFieldsStrategy, isResetFieldsStrategy := storage.(rest.ResetFieldsStrategy); isResetFieldsStrategy { if resetFieldsStrategy, isResetFieldsStrategy := storage.(rest.ResetFieldsStrategy); isResetFieldsStrategy {
resetFields = resetFieldsStrategy.GetResetFields() resetFields = resetFieldsStrategy.GetResetFields()
@ -696,7 +692,6 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("failed to create field manager: %v", err) return nil, nil, fmt.Errorf("failed to create field manager: %v", err)
} }
}
for _, action := range actions { for _, action := range actions {
producedObject := storageMeta.ProducesObject(action.Verb) producedObject := storageMeta.ProducesObject(action.Verb)

View File

@ -18,6 +18,7 @@ package server
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"net/http" "net/http"
gpath "path" gpath "path"
@ -736,16 +737,7 @@ func (s preparedGenericAPIServer) NonBlockingRun(stopCh <-chan struct{}, shutdow
} }
// installAPIResources is a private method for installing the REST storage backing each api groupversionresource // installAPIResources is a private method for installing the REST storage backing each api groupversionresource
func (s *GenericAPIServer) installAPIResources(apiPrefix string, apiGroupInfo *APIGroupInfo, openAPIModels map[string]*spec.Schema) error { func (s *GenericAPIServer) installAPIResources(apiPrefix string, apiGroupInfo *APIGroupInfo, typeConverter managedfields.TypeConverter) error {
var typeConverter managedfields.TypeConverter
if len(openAPIModels) > 0 {
var err error
typeConverter, err = managedfields.NewTypeConverter(openAPIModels, false)
if err != nil {
return err
}
}
var resourceInfos []*storageversion.ResourceInfo var resourceInfos []*storageversion.ResourceInfo
for _, groupVersion := range apiGroupInfo.PrioritizedVersions { for _, groupVersion := range apiGroupInfo.PrioritizedVersions {
if len(apiGroupInfo.VersionedResourcesStorageMap[groupVersion.Version]) == 0 { if len(apiGroupInfo.VersionedResourcesStorageMap[groupVersion.Version]) == 0 {
@ -953,13 +945,13 @@ func NewDefaultAPIGroupInfo(group string, scheme *runtime.Scheme, parameterCodec
} }
// getOpenAPIModels is a private method for getting the OpenAPI models // getOpenAPIModels is a private method for getting the OpenAPI models
func (s *GenericAPIServer) getOpenAPIModels(apiPrefix string, apiGroupInfos ...*APIGroupInfo) (map[string]*spec.Schema, error) { func (s *GenericAPIServer) getOpenAPIModels(apiPrefix string, apiGroupInfos ...*APIGroupInfo) (managedfields.TypeConverter, error) {
if s.openAPIV3Config == nil { if s.openAPIV3Config == nil {
//!TODO: A future work should add a requirement that // SSA is GA and requires OpenAPI config to be set
// OpenAPIV3 config is required. May require some refactoring of tests. // to create models.
return nil, nil return nil, errors.New("OpenAPIV3 config must not be nil")
} }
pathsToIgnore := openapiutil.NewTrie(s.openAPIConfig.IgnorePrefixes) pathsToIgnore := openapiutil.NewTrie(s.openAPIV3Config.IgnorePrefixes)
resourceNames := make([]string, 0) resourceNames := make([]string, 0)
for _, apiGroupInfo := range apiGroupInfos { for _, apiGroupInfo := range apiGroupInfos {
groupResources, err := getResourceNamesForGroup(apiPrefix, apiGroupInfo, pathsToIgnore) groupResources, err := getResourceNamesForGroup(apiPrefix, apiGroupInfo, pathsToIgnore)
@ -977,7 +969,13 @@ func (s *GenericAPIServer) getOpenAPIModels(apiPrefix string, apiGroupInfos ...*
for _, apiGroupInfo := range apiGroupInfos { for _, apiGroupInfo := range apiGroupInfos {
apiGroupInfo.StaticOpenAPISpec = openAPISpec apiGroupInfo.StaticOpenAPISpec = openAPISpec
} }
return openAPISpec, nil
typeConverter, err := managedfields.NewTypeConverter(openAPISpec, false)
if err != nil {
return nil, err
}
return typeConverter, nil
} }
// getResourceNamesForGroup is a private method for getting the canonical names for each resource to build in an api group // getResourceNamesForGroup is a private method for getting the canonical names for each resource to build in an api group

View File

@ -139,6 +139,8 @@ func setUp(t *testing.T) (Config, *assert.Assertions) {
config.OpenAPIConfig = DefaultOpenAPIConfig(testGetOpenAPIDefinitions, openapinamer.NewDefinitionNamer(runtime.NewScheme())) config.OpenAPIConfig = DefaultOpenAPIConfig(testGetOpenAPIDefinitions, openapinamer.NewDefinitionNamer(runtime.NewScheme()))
config.OpenAPIConfig.Info.Version = "unversioned" config.OpenAPIConfig.Info.Version = "unversioned"
config.OpenAPIV3Config = DefaultOpenAPIV3Config(testGetOpenAPIDefinitions, openapinamer.NewDefinitionNamer(runtime.NewScheme()))
config.OpenAPIV3Config.Info.Version = "unversioned"
sharedInformers := informers.NewSharedInformerFactory(clientset, config.LoopbackClientConfig.Timeout) sharedInformers := informers.NewSharedInformerFactory(clientset, config.LoopbackClientConfig.Timeout)
config.Complete(sharedInformers) config.Complete(sharedInformers)