mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Merge pull request #121325 from benluddy/check-apiserver-serializers
KEP-4222: Restrict supported media types for new apiservers.
This commit is contained in:
		@@ -724,6 +724,12 @@ func (c *RecommendedConfig) Complete() CompletedConfig {
 | 
			
		||||
	return c.Config.Complete(c.SharedInformerFactory)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var allowedMediaTypes = []string{
 | 
			
		||||
	runtime.ContentTypeJSON,
 | 
			
		||||
	runtime.ContentTypeYAML,
 | 
			
		||||
	runtime.ContentTypeProtobuf,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// New creates a new server which logically combines the handling chain with the passed server.
 | 
			
		||||
// name is used to differentiate for logging. The handler chain in particular can be difficult as it starts delegating.
 | 
			
		||||
// delegationTarget may not be nil.
 | 
			
		||||
@@ -731,6 +737,18 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G
 | 
			
		||||
	if c.Serializer == nil {
 | 
			
		||||
		return nil, fmt.Errorf("Genericapiserver.New() called with config.Serializer == nil")
 | 
			
		||||
	}
 | 
			
		||||
	for _, info := range c.Serializer.SupportedMediaTypes() {
 | 
			
		||||
		var ok bool
 | 
			
		||||
		for _, mt := range allowedMediaTypes {
 | 
			
		||||
			if info.MediaType == mt {
 | 
			
		||||
				ok = true
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if !ok {
 | 
			
		||||
			return nil, fmt.Errorf("refusing to create new apiserver %q with support for media type %q (allowed media types are: %s)", name, info.MediaType, strings.Join(allowedMediaTypes, ", "))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if c.LoopbackClientConfig == nil {
 | 
			
		||||
		return nil, fmt.Errorf("Genericapiserver.New() called with config.LoopbackClientConfig == nil")
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,7 @@ import (
 | 
			
		||||
	"testing"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/util/json"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/util/sets"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/util/wait"
 | 
			
		||||
@@ -362,3 +363,21 @@ func (b *testBackend) ProcessEvents(events ...*auditinternal.Event) bool {
 | 
			
		||||
	b.events = append(b.events, events...)
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestNewErrorForbiddenSerializer(t *testing.T) {
 | 
			
		||||
	config := CompletedConfig{
 | 
			
		||||
		&completedConfig{
 | 
			
		||||
			Config: &Config{
 | 
			
		||||
				Serializer: runtime.NewSimpleNegotiatedSerializer(runtime.SerializerInfo{
 | 
			
		||||
					MediaType: "application/cbor",
 | 
			
		||||
				}),
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	_, err := config.New("test", NewEmptyDelegate())
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		t.Error("successfully created a new server configured with cbor support")
 | 
			
		||||
	} else if err.Error() != `refusing to create new apiserver "test" with support for media type "application/cbor" (allowed media types are: application/json, application/yaml, application/vnd.kubernetes.protobuf)` {
 | 
			
		||||
		t.Errorf("unexpected error: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,7 @@ import (
 | 
			
		||||
 | 
			
		||||
	"github.com/spf13/pflag"
 | 
			
		||||
 | 
			
		||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/runtime/schema"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/util/sets"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/util/wait"
 | 
			
		||||
@@ -87,6 +88,12 @@ func NewEtcdOptions(backendConfig *storagebackend.Config) *EtcdOptions {
 | 
			
		||||
	return options
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var storageMediaTypes = sets.New(
 | 
			
		||||
	runtime.ContentTypeJSON,
 | 
			
		||||
	runtime.ContentTypeYAML,
 | 
			
		||||
	runtime.ContentTypeProtobuf,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (s *EtcdOptions) Validate() []error {
 | 
			
		||||
	if s == nil {
 | 
			
		||||
		return nil
 | 
			
		||||
@@ -120,6 +127,10 @@ func (s *EtcdOptions) Validate() []error {
 | 
			
		||||
		allErrors = append(allErrors, fmt.Errorf("--encryption-provider-config-automatic-reload must be set with --encryption-provider-config"))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if s.DefaultStorageMediaType != "" && !storageMediaTypes.Has(s.DefaultStorageMediaType) {
 | 
			
		||||
		allErrors = append(allErrors, fmt.Errorf("--storage-media-type %q invalid, allowed values: %s", s.DefaultStorageMediaType, strings.Join(sets.List(storageMediaTypes), ", ")))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return allErrors
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -160,6 +160,40 @@ func TestEtcdOptionsValidate(t *testing.T) {
 | 
			
		||||
				EtcdServersOverrides:    []string{"/events#http://127.0.0.1:4002"},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "empty storage-media-type",
 | 
			
		||||
			testOptions: &EtcdOptions{
 | 
			
		||||
				StorageConfig: storagebackend.Config{
 | 
			
		||||
					Transport: storagebackend.TransportConfig{
 | 
			
		||||
						ServerList: []string{"http://127.0.0.1"},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
				DefaultStorageMediaType: "",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "recognized storage-media-type",
 | 
			
		||||
			testOptions: &EtcdOptions{
 | 
			
		||||
				StorageConfig: storagebackend.Config{
 | 
			
		||||
					Transport: storagebackend.TransportConfig{
 | 
			
		||||
						ServerList: []string{"http://127.0.0.1"},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
				DefaultStorageMediaType: "application/json",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "unrecognized storage-media-type",
 | 
			
		||||
			testOptions: &EtcdOptions{
 | 
			
		||||
				StorageConfig: storagebackend.Config{
 | 
			
		||||
					Transport: storagebackend.TransportConfig{
 | 
			
		||||
						ServerList: []string{"http://127.0.0.1"},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
				DefaultStorageMediaType: "foo/bar",
 | 
			
		||||
			},
 | 
			
		||||
			expectErr: `--storage-media-type "foo/bar" invalid, allowed values: application/json, application/vnd.kubernetes.protobuf, application/yaml`,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, testcase := range testCases {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user