mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 19:01:49 +00:00
Hide OpeAPI details behind the NewTypeConverter
The fact that we're building the OpenAPI using the proto.Models is an implementation detail that we shouldn't have to expose. Since we're going to change the way this is transformed, let's first hide it behind the common NewTypeConverter so that the next change is transparent. This will also enable other clean-ups like hiding the gvkParser which shouldn't be exposed and prevent some refactoring.
This commit is contained in:
parent
88c952d256
commit
a7ab6b86db
@ -71,13 +71,11 @@ import (
|
||||
apirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/apiserver/pkg/registry/generic"
|
||||
genericfilters "k8s.io/apiserver/pkg/server/filters"
|
||||
utilopenapi "k8s.io/apiserver/pkg/util/openapi"
|
||||
"k8s.io/apiserver/pkg/warning"
|
||||
"k8s.io/client-go/scale"
|
||||
"k8s.io/client-go/scale/scheme/autoscalingv1"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/kube-openapi/pkg/util/proto"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
"k8s.io/kube-openapi/pkg/validation/strfmt"
|
||||
"k8s.io/kube-openapi/pkg/validation/validate"
|
||||
@ -1371,7 +1369,7 @@ func hasServedCRDVersion(spec *apiextensionsv1.CustomResourceDefinitionSpec, ver
|
||||
// buildOpenAPIModelsForApply constructs openapi models from any validation schemas specified in the custom resource,
|
||||
// and merges it with the models defined in the static OpenAPI spec.
|
||||
// Returns nil models ifthe static spec is nil, or an error is encountered.
|
||||
func buildOpenAPIModelsForApply(staticOpenAPISpec *spec.Swagger, crd *apiextensionsv1.CustomResourceDefinition) (proto.Models, error) {
|
||||
func buildOpenAPIModelsForApply(staticOpenAPISpec *spec.Swagger, crd *apiextensionsv1.CustomResourceDefinition) (*spec.Swagger, error) {
|
||||
if staticOpenAPISpec == nil {
|
||||
return nil, nil
|
||||
}
|
||||
@ -1391,9 +1389,5 @@ func buildOpenAPIModelsForApply(staticOpenAPISpec *spec.Swagger, crd *apiextensi
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
models, err := utilopenapi.ToProtoModels(mergedOpenAPI)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return models, nil
|
||||
return mergedOpenAPI, nil
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ import (
|
||||
"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
"k8s.io/apiserver/pkg/storageversion"
|
||||
openapiproto "k8s.io/kube-openapi/pkg/util/proto"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
)
|
||||
|
||||
// ConvertabilityChecker indicates what versions a GroupKind is available in.
|
||||
@ -96,7 +96,7 @@ type APIGroupVersion struct {
|
||||
MinRequestTimeout time.Duration
|
||||
|
||||
// OpenAPIModels exposes the OpenAPI models to each individual handler.
|
||||
OpenAPIModels openapiproto.Models
|
||||
OpenAPIModels *spec.Swagger
|
||||
|
||||
// The limit on the request body size that would be accepted and decoded in a write request.
|
||||
// 0 means no limit.
|
||||
|
@ -17,8 +17,10 @@ limitations under the License.
|
||||
package fieldmanagertest
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
@ -28,39 +30,34 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager"
|
||||
"k8s.io/kube-openapi/pkg/util/proto"
|
||||
prototesting "k8s.io/kube-openapi/pkg/util/proto/testing"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
|
||||
"sigs.k8s.io/structured-merge-diff/v4/merge"
|
||||
"sigs.k8s.io/structured-merge-diff/v4/typed"
|
||||
)
|
||||
|
||||
var kubernetesSwaggerSchema = prototesting.Fake{
|
||||
Path: filepath.Join(
|
||||
var builtinConverter = func() fieldmanager.TypeConverter {
|
||||
data, err := ioutil.ReadFile(filepath.Join(
|
||||
strings.Repeat(".."+string(filepath.Separator), 8),
|
||||
"api", "openapi-spec", "swagger.json"),
|
||||
}
|
||||
|
||||
// NewBuiltinTypeConverter creates a TypeConverter with all the built-in
|
||||
// types defined, given the committed kubernetes swagger.json.
|
||||
func NewBuiltinTypeConverter() fieldmanager.TypeConverter {
|
||||
tc, err := fieldmanager.NewTypeConverter(newFakeOpenAPIModels(), false)
|
||||
"api", "openapi-spec", "swagger.json"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
spec := spec.Swagger{}
|
||||
if err := json.Unmarshal(data, &spec); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
tc, err := fieldmanager.NewTypeConverter(&spec, false)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("Failed to build TypeConverter: %v", err))
|
||||
}
|
||||
return tc
|
||||
}
|
||||
}()
|
||||
|
||||
func newFakeOpenAPIModels() proto.Models {
|
||||
d, err := kubernetesSwaggerSchema.OpenAPISchema()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
m, err := proto.NewOpenAPIData(d)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return m
|
||||
// NewBuiltinTypeConverter creates a TypeConverter with all the built-in
|
||||
// types defined, given the committed kubernetes swagger.json.
|
||||
func NewBuiltinTypeConverter() fieldmanager.TypeConverter {
|
||||
return builtinConverter
|
||||
}
|
||||
|
||||
type fakeObjectConvertor struct {
|
||||
|
@ -23,7 +23,8 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/managedfields"
|
||||
"k8s.io/kube-openapi/pkg/util/proto"
|
||||
utilopenapi "k8s.io/apiserver/pkg/util/openapi"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
"sigs.k8s.io/structured-merge-diff/v4/typed"
|
||||
"sigs.k8s.io/structured-merge-diff/v4/value"
|
||||
)
|
||||
@ -70,10 +71,14 @@ type typeConverter struct {
|
||||
|
||||
var _ TypeConverter = &typeConverter{}
|
||||
|
||||
// NewTypeConverter builds a TypeConverter from a proto.Models. This
|
||||
// NewTypeConverter builds a TypeConverter from a spec.Swagger. This
|
||||
// will automatically find the proper version of the object, and the
|
||||
// corresponding schema information.
|
||||
func NewTypeConverter(models proto.Models, preserveUnknownFields bool) (TypeConverter, error) {
|
||||
func NewTypeConverter(openapiSpec *spec.Swagger, preserveUnknownFields bool) (TypeConverter, error) {
|
||||
models, err := utilopenapi.ToProtoModels(openapiSpec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
parser, err := managedfields.NewGVKParser(models, preserveUnknownFields)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -17,7 +17,9 @@ limitations under the License.
|
||||
package fieldmanager_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
@ -27,25 +29,23 @@ import (
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager"
|
||||
"k8s.io/kube-openapi/pkg/util/proto"
|
||||
prototesting "k8s.io/kube-openapi/pkg/util/proto/testing"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
)
|
||||
|
||||
var testSchema = prototesting.Fake{
|
||||
Path: filepath.Join("testdata", "swagger.json"),
|
||||
}
|
||||
var testSchema = func() *spec.Swagger {
|
||||
data, err := ioutil.ReadFile(filepath.Join("testdata", "swagger.json"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
spec := spec.Swagger{}
|
||||
if err := json.Unmarshal(data, &spec); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &spec
|
||||
}()
|
||||
|
||||
func TestTypeConverter(t *testing.T) {
|
||||
d, err := testSchema.OpenAPISchema()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to parse OpenAPI schema: %v", err)
|
||||
}
|
||||
m, err := proto.NewOpenAPIData(d)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to build OpenAPI models: %v", err)
|
||||
}
|
||||
|
||||
tc, err := fieldmanager.NewTypeConverter(m, false)
|
||||
tc, err := fieldmanager.NewTypeConverter(testSchema, false)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to build TypeConverter: %v", err)
|
||||
}
|
||||
@ -177,16 +177,7 @@ spec:
|
||||
b.Fatalf("Failed to parse yaml object: %v", err)
|
||||
}
|
||||
|
||||
d, err := testSchema.OpenAPISchema()
|
||||
if err != nil {
|
||||
b.Fatalf("Failed to parse OpenAPI schema: %v", err)
|
||||
}
|
||||
m, err := proto.NewOpenAPIData(d)
|
||||
if err != nil {
|
||||
b.Fatalf("Failed to build OpenAPI models: %v", err)
|
||||
}
|
||||
|
||||
tc, err := fieldmanager.NewTypeConverter(m, false)
|
||||
tc, err := fieldmanager.NewTypeConverter(testSchema, false)
|
||||
if err != nil {
|
||||
b.Fatalf("Failed to build TypeConverter: %v", err)
|
||||
}
|
||||
|
@ -17,7 +17,9 @@ limitations under the License.
|
||||
package fieldmanager
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
@ -25,26 +27,25 @@ import (
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/kube-openapi/pkg/util/proto"
|
||||
prototesting "k8s.io/kube-openapi/pkg/util/proto/testing"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
|
||||
)
|
||||
|
||||
var testSchema = prototesting.Fake{
|
||||
Path: filepath.Join("testdata", "swagger.json"),
|
||||
}
|
||||
var testSchema = func() *spec.Swagger {
|
||||
data, err := ioutil.ReadFile(filepath.Join("testdata", "swagger.json"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
spec := spec.Swagger{}
|
||||
if err := json.Unmarshal(data, &spec); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &spec
|
||||
}()
|
||||
|
||||
// TestVersionConverter tests the version converter
|
||||
func TestVersionConverter(t *testing.T) {
|
||||
d, err := testSchema.OpenAPISchema()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to parse OpenAPI schema: %v", err)
|
||||
}
|
||||
m, err := proto.NewOpenAPIData(d)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to build OpenAPI models: %v", err)
|
||||
}
|
||||
tc, err := NewTypeConverter(m, false)
|
||||
tc, err := NewTypeConverter(testSchema, false)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to build TypeConverter: %v", err)
|
||||
}
|
||||
|
@ -49,7 +49,6 @@ import (
|
||||
"k8s.io/apiserver/pkg/server/routes"
|
||||
"k8s.io/apiserver/pkg/storageversion"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
utilopenapi "k8s.io/apiserver/pkg/util/openapi"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/klog/v2"
|
||||
openapibuilder2 "k8s.io/kube-openapi/pkg/builder"
|
||||
@ -57,7 +56,6 @@ import (
|
||||
"k8s.io/kube-openapi/pkg/handler"
|
||||
"k8s.io/kube-openapi/pkg/handler3"
|
||||
openapiutil "k8s.io/kube-openapi/pkg/util"
|
||||
openapiproto "k8s.io/kube-openapi/pkg/util/proto"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
"k8s.io/utils/clock"
|
||||
)
|
||||
@ -666,7 +664,7 @@ func (s preparedGenericAPIServer) NonBlockingRun(stopCh <-chan struct{}, shutdow
|
||||
}
|
||||
|
||||
// installAPIResources is a private method for installing the REST storage backing each api groupversionresource
|
||||
func (s *GenericAPIServer) installAPIResources(apiPrefix string, apiGroupInfo *APIGroupInfo, openAPIModels openapiproto.Models) error {
|
||||
func (s *GenericAPIServer) installAPIResources(apiPrefix string, apiGroupInfo *APIGroupInfo, openAPIModels *spec.Swagger) error {
|
||||
var resourceInfos []*storageversion.ResourceInfo
|
||||
for _, groupVersion := range apiGroupInfo.PrioritizedVersions {
|
||||
if len(apiGroupInfo.VersionedResourcesStorageMap[groupVersion.Version]) == 0 {
|
||||
@ -881,7 +879,7 @@ func NewDefaultAPIGroupInfo(group string, scheme *runtime.Scheme, parameterCodec
|
||||
}
|
||||
|
||||
// getOpenAPIModels is a private method for getting the OpenAPI models
|
||||
func (s *GenericAPIServer) getOpenAPIModels(apiPrefix string, apiGroupInfos ...*APIGroupInfo) (openapiproto.Models, error) {
|
||||
func (s *GenericAPIServer) getOpenAPIModels(apiPrefix string, apiGroupInfos ...*APIGroupInfo) (*spec.Swagger, error) {
|
||||
if s.openAPIConfig == nil {
|
||||
return nil, nil
|
||||
}
|
||||
@ -903,7 +901,7 @@ func (s *GenericAPIServer) getOpenAPIModels(apiPrefix string, apiGroupInfos ...*
|
||||
for _, apiGroupInfo := range apiGroupInfos {
|
||||
apiGroupInfo.StaticOpenAPISpec = openAPISpec
|
||||
}
|
||||
return utilopenapi.ToProtoModels(openAPISpec)
|
||||
return openAPISpec, nil
|
||||
}
|
||||
|
||||
// getResourceNamesForGroup is a private method for getting the canonical names for each resource to build in an api group
|
||||
|
Loading…
Reference in New Issue
Block a user