mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-06 02:34:03 +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:
commit
2014ce2313
@ -724,6 +724,12 @@ func (c *RecommendedConfig) Complete() CompletedConfig {
|
|||||||
return c.Config.Complete(c.SharedInformerFactory)
|
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.
|
// 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.
|
// name is used to differentiate for logging. The handler chain in particular can be difficult as it starts delegating.
|
||||||
// delegationTarget may not be nil.
|
// delegationTarget may not be nil.
|
||||||
@ -731,6 +737,18 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G
|
|||||||
if c.Serializer == nil {
|
if c.Serializer == nil {
|
||||||
return nil, fmt.Errorf("Genericapiserver.New() called with config.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 {
|
if c.LoopbackClientConfig == nil {
|
||||||
return nil, fmt.Errorf("Genericapiserver.New() called with config.LoopbackClientConfig == nil")
|
return nil, fmt.Errorf("Genericapiserver.New() called with config.LoopbackClientConfig == nil")
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/json"
|
"k8s.io/apimachinery/pkg/util/json"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
@ -362,3 +363,21 @@ func (b *testBackend) ProcessEvents(events ...*auditinternal.Event) bool {
|
|||||||
b.events = append(b.events, events...)
|
b.events = append(b.events, events...)
|
||||||
return true
|
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"
|
"github.com/spf13/pflag"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
@ -87,6 +88,12 @@ func NewEtcdOptions(backendConfig *storagebackend.Config) *EtcdOptions {
|
|||||||
return options
|
return options
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var storageMediaTypes = sets.New(
|
||||||
|
runtime.ContentTypeJSON,
|
||||||
|
runtime.ContentTypeYAML,
|
||||||
|
runtime.ContentTypeProtobuf,
|
||||||
|
)
|
||||||
|
|
||||||
func (s *EtcdOptions) Validate() []error {
|
func (s *EtcdOptions) Validate() []error {
|
||||||
if s == nil {
|
if s == nil {
|
||||||
return 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"))
|
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
|
return allErrors
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,6 +160,40 @@ func TestEtcdOptionsValidate(t *testing.T) {
|
|||||||
EtcdServersOverrides: []string{"/events#http://127.0.0.1:4002"},
|
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 {
|
for _, testcase := range testCases {
|
||||||
|
Loading…
Reference in New Issue
Block a user