diff --git a/pkg/registry/core/pod/storage/storage.go b/pkg/registry/core/pod/storage/storage.go index 4947cf3d10d..3f07af35c32 100644 --- a/pkg/registry/core/pod/storage/storage.go +++ b/pkg/registry/core/pod/storage/storage.go @@ -148,11 +148,18 @@ func (r *BindingREST) New() runtime.Object { return &api.Binding{} } -var _ = rest.Creater(&BindingREST{}) +var _ = rest.NamedCreater(&BindingREST{}) // Create ensures a pod is bound to a specific host. -func (r *BindingREST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (out runtime.Object, err error) { - binding := obj.(*api.Binding) +func (r *BindingREST) Create(ctx context.Context, name string, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (out runtime.Object, err error) { + binding, ok := obj.(*api.Binding) + if !ok { + return nil, errors.NewBadRequest(fmt.Sprintf("not a Binding object: %#v", obj)) + } + + if name != binding.Name { + return nil, errors.NewBadRequest("name in URL does not match name in Binding object") + } // TODO: move me to a binding strategy if errs := validation.ValidatePodBinding(binding); len(errs) != 0 { diff --git a/pkg/registry/core/pod/storage/storage_test.go b/pkg/registry/core/pod/storage/storage_test.go index d8c8e324f7c..545e6362cb9 100644 --- a/pkg/registry/core/pod/storage/storage_test.go +++ b/pkg/registry/core/pod/storage/storage_test.go @@ -587,7 +587,7 @@ func TestEtcdCreate(t *testing.T) { } // Suddenly, a wild scheduler appears: - _, err = bindingStorage.Create(ctx, &api.Binding{ + _, err = bindingStorage.Create(ctx, "foo", &api.Binding{ ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "foo"}, Target: api.ObjectReference{Name: "machine"}, }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) @@ -613,7 +613,7 @@ func TestEtcdCreateBindingNoPod(t *testing.T) { // - Create (apiserver) // - Schedule (scheduler) // - Delete (apiserver) - _, err := bindingStorage.Create(ctx, &api.Binding{ + _, err := bindingStorage.Create(ctx, "foo", &api.Binding{ ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "foo"}, Target: api.ObjectReference{Name: "machine"}, }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) @@ -657,7 +657,7 @@ func TestEtcdCreateWithContainersNotFound(t *testing.T) { } // Suddenly, a wild scheduler appears: - _, err = bindingStorage.Create(ctx, &api.Binding{ + _, err = bindingStorage.Create(ctx, "foo", &api.Binding{ ObjectMeta: metav1.ObjectMeta{ Namespace: metav1.NamespaceDefault, Name: "foo", @@ -700,12 +700,12 @@ func TestEtcdCreateWithConflict(t *testing.T) { }, Target: api.ObjectReference{Name: "machine"}, } - _, err = bindingStorage.Create(ctx, &binding, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + _, err = bindingStorage.Create(ctx, binding.Name, &binding, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("unexpected error: %v", err) } - _, err = bindingStorage.Create(ctx, &binding, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + _, err = bindingStorage.Create(ctx, binding.Name, &binding, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err == nil || !errors.IsConflict(err) { t.Fatalf("expected resource conflict error, not: %v", err) } @@ -722,7 +722,7 @@ func TestEtcdCreateWithExistingContainers(t *testing.T) { } // Suddenly, a wild scheduler appears: - _, err = bindingStorage.Create(ctx, &api.Binding{ + _, err = bindingStorage.Create(ctx, "foo", &api.Binding{ ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "foo"}, Target: api.ObjectReference{Name: "machine"}, }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) @@ -740,8 +740,9 @@ func TestEtcdCreateBinding(t *testing.T) { ctx := genericapirequest.NewDefaultContext() testCases := map[string]struct { - binding api.Binding - errOK func(error) bool + binding api.Binding + badNameInURL bool + errOK func(error) bool }{ "noName": { binding: api.Binding{ @@ -750,6 +751,14 @@ func TestEtcdCreateBinding(t *testing.T) { }, errOK: func(err error) bool { return err != nil }, }, + "badNameInURL": { + binding: api.Binding{ + ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "foo"}, + Target: api.ObjectReference{}, + }, + badNameInURL: true, + errOK: func(err error) bool { return err != nil }, + }, "badKind": { binding: api.Binding{ ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "foo"}, @@ -778,7 +787,11 @@ func TestEtcdCreateBinding(t *testing.T) { if _, err := storage.Create(ctx, validNewPod(), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}); err != nil { t.Fatalf("%s: unexpected error: %v", k, err) } - if _, err := bindingStorage.Create(ctx, &test.binding, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}); !test.errOK(err) { + name := test.binding.Name + if test.badNameInURL { + name += "badNameInURL" + } + if _, err := bindingStorage.Create(ctx, name, &test.binding, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}); !test.errOK(err) { t.Errorf("%s: unexpected error: %v", k, err) } else if err == nil { // If bind succeeded, verify Host field in pod's Spec.