mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 04:33:26 +00:00
Merge pull request #2367 from lavalamp/fix3
Yet more non-controversial fixes from #2277
This commit is contained in:
commit
c25ef89b24
35
pkg/api/validation/events.go
Normal file
35
pkg/api/validation/events.go
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
Copyright 2014 Google Inc. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
errs "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
)
|
||||
|
||||
// ValidateEvent makes sure that the event makes sense.
|
||||
func ValidateEvent(event *api.Event) errs.ValidationErrorList {
|
||||
allErrs := errs.ValidationErrorList{}
|
||||
if event.Namespace != event.InvolvedObject.Namespace {
|
||||
allErrs = append(allErrs, errs.NewFieldInvalid("involvedObject.namespace", event.InvolvedObject.Namespace))
|
||||
}
|
||||
if !util.IsDNSSubdomain(event.Namespace) {
|
||||
allErrs = append(allErrs, errs.NewFieldInvalid("namespace", event.Namespace))
|
||||
}
|
||||
return allErrs
|
||||
}
|
60
pkg/api/validation/events_test.go
Normal file
60
pkg/api/validation/events_test.go
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
Copyright 2014 Google Inc. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
)
|
||||
|
||||
func TestValidateEvent(t *testing.T) {
|
||||
table := []struct {
|
||||
*api.Event
|
||||
valid bool
|
||||
}{
|
||||
{
|
||||
&api.Event{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "test1",
|
||||
Namespace: "foo",
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
Namespace: "bar",
|
||||
},
|
||||
},
|
||||
false,
|
||||
}, {
|
||||
&api.Event{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "test1",
|
||||
Namespace: "aoeu-_-aoeu",
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
Namespace: "aoeu-_-aoeu",
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, item := range table {
|
||||
if e, a := item.valid, len(ValidateEvent(item.Event)) == 0; e != a {
|
||||
t.Errorf("%v: expected %v, got %v", item.Event.Name, e, a)
|
||||
}
|
||||
}
|
||||
}
|
@ -33,7 +33,7 @@ type Interface interface {
|
||||
EndpointsNamespacer
|
||||
VersionInterface
|
||||
MinionsInterface
|
||||
EventsInterface
|
||||
EventNamespacer
|
||||
}
|
||||
|
||||
func (c *Client) ReplicationControllers(namespace string) ReplicationControllerInterface {
|
||||
@ -44,8 +44,8 @@ func (c *Client) Minions() MinionInterface {
|
||||
return newMinions(c)
|
||||
}
|
||||
|
||||
func (c *Client) Events() EventInterface {
|
||||
return newEvents(c)
|
||||
func (c *Client) Events(namespace string) EventInterface {
|
||||
return newEvents(c, namespace)
|
||||
}
|
||||
|
||||
func (c *Client) Endpoints(namespace string) EndpointsInterface {
|
||||
|
@ -23,6 +23,7 @@ import (
|
||||
"net/url"
|
||||
"path"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
@ -121,6 +122,7 @@ func (c *testClient) ValidateCommon(t *testing.T, err error) {
|
||||
|
||||
requestBody := body(c.Request.Body, c.Request.RawBody)
|
||||
actualQuery := c.handler.RequestReceived.URL.Query()
|
||||
t.Logf("got query: %v", actualQuery)
|
||||
// We check the query manually, so blank it out so that FakeHandler.ValidateRequest
|
||||
// won't check it.
|
||||
c.handler.RequestReceived.URL.RawQuery = ""
|
||||
@ -128,11 +130,17 @@ func (c *testClient) ValidateCommon(t *testing.T, err error) {
|
||||
for key, values := range c.Request.Query {
|
||||
validator, ok := c.QueryValidator[key]
|
||||
if !ok {
|
||||
validator = func(a, b string) bool { return a == b }
|
||||
switch key {
|
||||
case "labels", "fields":
|
||||
validator = validateLabels
|
||||
default:
|
||||
validator = func(a, b string) bool { return a == b }
|
||||
}
|
||||
}
|
||||
observed := actualQuery.Get(key)
|
||||
if !validator(values[0], observed) {
|
||||
t.Errorf("Unexpected query arg for key: %s. Expected %s, Received %s", key, values[0], observed)
|
||||
wanted := strings.Join(values, "")
|
||||
if !validator(wanted, observed) {
|
||||
t.Errorf("Unexpected query arg for key: %s. Expected %s, Received %s", key, wanted, observed)
|
||||
}
|
||||
}
|
||||
if c.Request.Header != "" {
|
||||
|
@ -17,14 +17,17 @@ limitations under the License.
|
||||
package client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// Events has methods to work with Event resources
|
||||
type EventsInterface interface {
|
||||
Events() EventInterface
|
||||
// EventNamespacer can return an EventInterface for the given namespace.
|
||||
type EventNamespacer interface {
|
||||
Events(namespace string) EventInterface
|
||||
}
|
||||
|
||||
// EventInterface has methods to work with Event resources
|
||||
@ -33,32 +36,48 @@ type EventInterface interface {
|
||||
List(label, field labels.Selector) (*api.EventList, error)
|
||||
Get(id string) (*api.Event, error)
|
||||
Watch(label, field labels.Selector, resourceVersion string) (watch.Interface, error)
|
||||
// Search finds events about the specified object
|
||||
Search(objOrRef runtime.Object) (*api.EventList, error)
|
||||
}
|
||||
|
||||
// events implements Events interface
|
||||
type events struct {
|
||||
r *Client
|
||||
client *Client
|
||||
namespace string
|
||||
}
|
||||
|
||||
// newEvents returns a events
|
||||
func newEvents(c *Client) *events {
|
||||
// newEvents returns a new events object.
|
||||
func newEvents(c *Client, ns string) *events {
|
||||
return &events{
|
||||
r: c,
|
||||
client: c,
|
||||
namespace: ns,
|
||||
}
|
||||
}
|
||||
|
||||
// Create makes a new event. Returns the copy of the event the server returns, or an error.
|
||||
func (c *events) Create(event *api.Event) (*api.Event, error) {
|
||||
// Create makes a new event. Returns the copy of the event the server returns,
|
||||
// or an error. The namespace to create the event within is deduced from the
|
||||
// event; it must either match this event client's namespace, or this event
|
||||
// client must have been created with the "" namespace.
|
||||
func (e *events) Create(event *api.Event) (*api.Event, error) {
|
||||
if e.namespace != "" && event.Namespace != e.namespace {
|
||||
return nil, fmt.Errorf("can't create an event with namespace '%v' in namespace '%v'", event.Namespace, e.namespace)
|
||||
}
|
||||
result := &api.Event{}
|
||||
err := c.r.Post().Path("events").Namespace(event.Namespace).Body(event).Do().Into(result)
|
||||
err := e.client.Post().
|
||||
Path("events").
|
||||
Namespace(event.Namespace).
|
||||
Body(event).
|
||||
Do().
|
||||
Into(result)
|
||||
return result, err
|
||||
}
|
||||
|
||||
// List returns a list of events matching the selectors.
|
||||
func (c *events) List(label, field labels.Selector) (*api.EventList, error) {
|
||||
func (e *events) List(label, field labels.Selector) (*api.EventList, error) {
|
||||
result := &api.EventList{}
|
||||
err := c.r.Get().
|
||||
err := e.client.Get().
|
||||
Path("events").
|
||||
Namespace(e.namespace).
|
||||
SelectorParam("labels", label).
|
||||
SelectorParam("fields", field).
|
||||
Do().
|
||||
@ -67,19 +86,45 @@ func (c *events) List(label, field labels.Selector) (*api.EventList, error) {
|
||||
}
|
||||
|
||||
// Get returns the given event, or an error.
|
||||
func (c *events) Get(id string) (*api.Event, error) {
|
||||
func (e *events) Get(id string) (*api.Event, error) {
|
||||
result := &api.Event{}
|
||||
err := c.r.Get().Path("events").Path(id).Do().Into(result)
|
||||
err := e.client.Get().
|
||||
Path("events").
|
||||
Path(id).
|
||||
Namespace(e.namespace).
|
||||
Do().
|
||||
Into(result)
|
||||
return result, err
|
||||
}
|
||||
|
||||
// Watch starts watching for events matching the given selectors.
|
||||
func (c *events) Watch(label, field labels.Selector, resourceVersion string) (watch.Interface, error) {
|
||||
return c.r.Get().
|
||||
func (e *events) Watch(label, field labels.Selector, resourceVersion string) (watch.Interface, error) {
|
||||
return e.client.Get().
|
||||
Path("watch").
|
||||
Path("events").
|
||||
Param("resourceVersion", resourceVersion).
|
||||
Namespace(e.namespace).
|
||||
SelectorParam("labels", label).
|
||||
SelectorParam("fields", field).
|
||||
Watch()
|
||||
}
|
||||
|
||||
// Search finds events about the specified object. The namespace of the
|
||||
// object must match this event's client namespace unless the event client
|
||||
// was made with the "" namespace.
|
||||
func (e *events) Search(objOrRef runtime.Object) (*api.EventList, error) {
|
||||
ref, err := api.GetReference(objOrRef)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// TODO: search by UID if it's set
|
||||
fields := labels.Set{
|
||||
"involvedObject.kind": ref.Kind,
|
||||
"involvedObject.namespace": ref.Namespace,
|
||||
"involvedObject.name": ref.Name,
|
||||
}.AsSelector()
|
||||
if e.namespace != "" && ref.Namespace != e.namespace {
|
||||
return nil, fmt.Errorf("won't be able to find any events of namespace '%v' in namespace '%v'", ref.Namespace, e.namespace)
|
||||
}
|
||||
return e.List(labels.Everything(), fields)
|
||||
}
|
||||
|
49
pkg/client/events_test.go
Normal file
49
pkg/client/events_test.go
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright 2014 Google Inc. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package client
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
|
||||
)
|
||||
|
||||
func TestEventSearch(t *testing.T) {
|
||||
c := &testClient{
|
||||
Request: testRequest{
|
||||
Method: "GET",
|
||||
Path: "/events",
|
||||
Query: url.Values{
|
||||
"fields": []string{"involvedObject.kind=Pod,involvedObject.name=foo,involvedObject.namespace=baz"},
|
||||
"labels": []string{},
|
||||
},
|
||||
},
|
||||
Response: Response{StatusCode: 200, Body: &api.EventList{}},
|
||||
}
|
||||
eventList, err := c.Setup().Events("").Search(
|
||||
&api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
SelfLink: testapi.SelfLink("pods", ""),
|
||||
},
|
||||
},
|
||||
)
|
||||
c.Validate(t, eventList, err)
|
||||
}
|
@ -49,7 +49,7 @@ func (c *Fake) Minions() MinionInterface {
|
||||
return &FakeMinions{Fake: c}
|
||||
}
|
||||
|
||||
func (c *Fake) Events() EventInterface {
|
||||
func (c *Fake) Events(namespace string) EventInterface {
|
||||
return &FakeEvents{Fake: c}
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ package client
|
||||
import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
@ -51,3 +52,9 @@ func (c *FakeEvents) Watch(label, field labels.Selector, resourceVersion string)
|
||||
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "watch-events", Value: resourceVersion})
|
||||
return c.Fake.Watch, c.Fake.Err
|
||||
}
|
||||
|
||||
// Search returns a list of events matching the specified object.
|
||||
func (c *FakeEvents) Search(objOrRef runtime.Object) (*api.EventList, error) {
|
||||
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "search-events"})
|
||||
return &c.Fake.EventsList, nil
|
||||
}
|
||||
|
@ -38,29 +38,13 @@ type Describer interface {
|
||||
func DescriberFor(kind string, c *client.Client) (Describer, bool) {
|
||||
switch kind {
|
||||
case "Pod":
|
||||
return &PodDescriber{
|
||||
PodClient: func(namespace string) (client.PodInterface, error) {
|
||||
return c.Pods(namespace), nil
|
||||
},
|
||||
ReplicationControllerClient: func(namespace string) (client.ReplicationControllerInterface, error) {
|
||||
return c.ReplicationControllers(namespace), nil
|
||||
},
|
||||
}, true
|
||||
return &PodDescriber{c}, true
|
||||
case "ReplicationController":
|
||||
return &ReplicationControllerDescriber{
|
||||
PodClient: func(namespace string) (client.PodInterface, error) {
|
||||
return c.Pods(namespace), nil
|
||||
},
|
||||
ReplicationControllerClient: func(namespace string) (client.ReplicationControllerInterface, error) {
|
||||
return c.ReplicationControllers(namespace), nil
|
||||
},
|
||||
}, true
|
||||
return &ReplicationControllerDescriber{c}, true
|
||||
case "Service":
|
||||
return &ServiceDescriber{
|
||||
ServiceClient: func(namespace string) (client.ServiceInterface, error) {
|
||||
return c.Services(namespace), nil
|
||||
},
|
||||
}, true
|
||||
return &ServiceDescriber{c}, true
|
||||
case "Minion", "Node":
|
||||
return &MinionDescriber{c}, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
@ -68,19 +52,12 @@ func DescriberFor(kind string, c *client.Client) (Describer, bool) {
|
||||
// PodDescriber generates information about a pod and the replication controllers that
|
||||
// create it.
|
||||
type PodDescriber struct {
|
||||
PodClient func(namespace string) (client.PodInterface, error)
|
||||
ReplicationControllerClient func(namespace string) (client.ReplicationControllerInterface, error)
|
||||
client.Interface
|
||||
}
|
||||
|
||||
func (d *PodDescriber) Describe(namespace, name string) (string, error) {
|
||||
rc, err := d.ReplicationControllerClient(namespace)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
pc, err := d.PodClient(namespace)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
rc := d.ReplicationControllers(namespace)
|
||||
pc := d.Pods(namespace)
|
||||
|
||||
pod, err := pc.Get(name)
|
||||
if err != nil {
|
||||
@ -107,19 +84,12 @@ func (d *PodDescriber) Describe(namespace, name string) (string, error) {
|
||||
// ReplicationControllerDescriber generates information about a replication controller
|
||||
// and the pods it has created.
|
||||
type ReplicationControllerDescriber struct {
|
||||
ReplicationControllerClient func(namespace string) (client.ReplicationControllerInterface, error)
|
||||
PodClient func(namespace string) (client.PodInterface, error)
|
||||
client.Interface
|
||||
}
|
||||
|
||||
func (d *ReplicationControllerDescriber) Describe(namespace, name string) (string, error) {
|
||||
rc, err := d.ReplicationControllerClient(namespace)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
pc, err := d.PodClient(namespace)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
rc := d.ReplicationControllers(namespace)
|
||||
pc := d.Pods(namespace)
|
||||
|
||||
controller, err := rc.Get(name)
|
||||
if err != nil {
|
||||
@ -144,14 +114,11 @@ func (d *ReplicationControllerDescriber) Describe(namespace, name string) (strin
|
||||
|
||||
// ServiceDescriber generates information about a service.
|
||||
type ServiceDescriber struct {
|
||||
ServiceClient func(namespace string) (client.ServiceInterface, error)
|
||||
client.Interface
|
||||
}
|
||||
|
||||
func (d *ServiceDescriber) Describe(namespace, name string) (string, error) {
|
||||
c, err := d.ServiceClient(namespace)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
c := d.Services(namespace)
|
||||
|
||||
service, err := c.Get(name)
|
||||
if err != nil {
|
||||
@ -169,14 +136,11 @@ func (d *ServiceDescriber) Describe(namespace, name string) (string, error) {
|
||||
|
||||
// MinionDescriber generates information about a minion.
|
||||
type MinionDescriber struct {
|
||||
MinionClient func() (client.MinionInterface, error)
|
||||
client.Interface
|
||||
}
|
||||
|
||||
func (d *MinionDescriber) Describe(namespace, name string) (string, error) {
|
||||
mc, err := d.MinionClient()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
mc := d.Minions()
|
||||
minion, err := mc.Get(name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
@ -27,37 +27,13 @@ type describeClient struct {
|
||||
T *testing.T
|
||||
Namespace string
|
||||
Err error
|
||||
Fake *client.Fake
|
||||
}
|
||||
|
||||
func (c *describeClient) Pod(namespace string) (client.PodInterface, error) {
|
||||
if namespace != c.Namespace {
|
||||
c.T.Errorf("unexpected namespace arg: %s", namespace)
|
||||
}
|
||||
return c.Fake.Pods(namespace), c.Err
|
||||
}
|
||||
|
||||
func (c *describeClient) ReplicationController(namespace string) (client.ReplicationControllerInterface, error) {
|
||||
if namespace != c.Namespace {
|
||||
c.T.Errorf("unexpected namespace arg: %s", namespace)
|
||||
}
|
||||
return c.Fake.ReplicationControllers(namespace), c.Err
|
||||
}
|
||||
|
||||
func (c *describeClient) Service(namespace string) (client.ServiceInterface, error) {
|
||||
if namespace != c.Namespace {
|
||||
c.T.Errorf("unexpected namespace arg: %s", namespace)
|
||||
}
|
||||
return c.Fake.Services(namespace), c.Err
|
||||
*client.Fake
|
||||
}
|
||||
|
||||
func TestDescribePod(t *testing.T) {
|
||||
fake := &client.Fake{}
|
||||
c := &describeClient{T: t, Namespace: "foo", Fake: fake}
|
||||
d := PodDescriber{
|
||||
PodClient: c.Pod,
|
||||
ReplicationControllerClient: c.ReplicationController,
|
||||
}
|
||||
d := PodDescriber{c}
|
||||
out, err := d.Describe("foo", "bar")
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
@ -70,9 +46,7 @@ func TestDescribePod(t *testing.T) {
|
||||
func TestDescribeService(t *testing.T) {
|
||||
fake := &client.Fake{}
|
||||
c := &describeClient{T: t, Namespace: "foo", Fake: fake}
|
||||
d := ServiceDescriber{
|
||||
ServiceClient: c.Service,
|
||||
}
|
||||
d := ServiceDescriber{c}
|
||||
out, err := d.Describe("foo", "bar")
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
|
@ -20,6 +20,8 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
|
||||
@ -45,7 +47,14 @@ func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid object type")
|
||||
}
|
||||
|
||||
if api.Namespace(ctx) != "" {
|
||||
if !api.ValidNamespace(ctx, &event.ObjectMeta) {
|
||||
return nil, errors.NewConflict("event", event.Namespace, fmt.Errorf("event.namespace does not match the provided context"))
|
||||
}
|
||||
}
|
||||
if errs := validation.ValidateEvent(event); len(errs) > 0 {
|
||||
return nil, errors.NewInvalid("event", event.Name, errs)
|
||||
}
|
||||
api.FillObjectMetaSystemFields(ctx, &event.ObjectMeta)
|
||||
|
||||
return apiserver.MakeAsync(func() (runtime.Object, error) {
|
||||
|
@ -38,38 +38,74 @@ func NewTestREST() (testRegistry, *REST) {
|
||||
return reg, NewREST(reg)
|
||||
}
|
||||
|
||||
func testEvent(name string) *api.Event {
|
||||
return &api.Event{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: "default",
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
Namespace: "default",
|
||||
},
|
||||
Reason: "forTesting",
|
||||
}
|
||||
}
|
||||
|
||||
func TestRESTCreate(t *testing.T) {
|
||||
_, rest := NewTestREST()
|
||||
eventA := &api.Event{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Reason: "forTesting",
|
||||
table := []struct {
|
||||
ctx api.Context
|
||||
event *api.Event
|
||||
valid bool
|
||||
}{
|
||||
{
|
||||
ctx: api.NewDefaultContext(),
|
||||
event: testEvent("foo"),
|
||||
valid: true,
|
||||
}, {
|
||||
ctx: api.NewContext(),
|
||||
event: testEvent("bar"),
|
||||
valid: true,
|
||||
}, {
|
||||
ctx: api.WithNamespace(api.NewContext(), "nondefault"),
|
||||
event: testEvent("bazzzz"),
|
||||
valid: false,
|
||||
},
|
||||
}
|
||||
c, err := rest.Create(api.NewContext(), eventA)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error %v", err)
|
||||
|
||||
for _, item := range table {
|
||||
_, rest := NewTestREST()
|
||||
c, err := rest.Create(item.ctx, item.event)
|
||||
if !item.valid {
|
||||
if err == nil {
|
||||
ctxNS := api.Namespace(item.ctx)
|
||||
t.Errorf("unexpected non-error for %v (%v, %v)", item.event.Name, ctxNS, item.event.Namespace)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("%v: Unexpected error %v", item.event.Name, err)
|
||||
continue
|
||||
}
|
||||
if !api.HasObjectMetaSystemFieldValues(&item.event.ObjectMeta) {
|
||||
t.Errorf("storage did not populate object meta field values")
|
||||
}
|
||||
if e, a := item.event, (<-c).Object; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("diff: %s", util.ObjectDiff(e, a))
|
||||
}
|
||||
// Ensure we implement the interface
|
||||
_ = apiserver.ResourceWatcher(rest)
|
||||
}
|
||||
if !api.HasObjectMetaSystemFieldValues(&eventA.ObjectMeta) {
|
||||
t.Errorf("storage did not populate object meta field values")
|
||||
}
|
||||
if e, a := eventA, (<-c).Object; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("diff: %s", util.ObjectDiff(e, a))
|
||||
}
|
||||
// Ensure we implement the interface
|
||||
_ = apiserver.ResourceWatcher(rest)
|
||||
}
|
||||
|
||||
func TestRESTDelete(t *testing.T) {
|
||||
_, rest := NewTestREST()
|
||||
eventA := &api.Event{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Reason: "forTesting",
|
||||
}
|
||||
c, err := rest.Create(api.NewContext(), eventA)
|
||||
eventA := testEvent("foo")
|
||||
c, err := rest.Create(api.NewDefaultContext(), eventA)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error %v", err)
|
||||
}
|
||||
<-c
|
||||
c, err = rest.Delete(api.NewContext(), eventA.Name)
|
||||
c, err = rest.Delete(api.NewDefaultContext(), eventA.Name)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error %v", err)
|
||||
}
|
||||
@ -80,16 +116,13 @@ func TestRESTDelete(t *testing.T) {
|
||||
|
||||
func TestRESTGet(t *testing.T) {
|
||||
_, rest := NewTestREST()
|
||||
eventA := &api.Event{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Reason: "forTesting",
|
||||
}
|
||||
c, err := rest.Create(api.NewContext(), eventA)
|
||||
eventA := testEvent("foo")
|
||||
c, err := rest.Create(api.NewDefaultContext(), eventA)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error %v", err)
|
||||
}
|
||||
<-c
|
||||
got, err := rest.Get(api.NewContext(), eventA.Name)
|
||||
got, err := rest.Get(api.NewDefaultContext(), eventA.Name)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error %v", err)
|
||||
}
|
||||
@ -140,16 +173,13 @@ func TestRESTgetAttrs(t *testing.T) {
|
||||
|
||||
func TestRESTUpdate(t *testing.T) {
|
||||
_, rest := NewTestREST()
|
||||
eventA := &api.Event{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Reason: "forTesting",
|
||||
}
|
||||
c, err := rest.Create(api.NewContext(), eventA)
|
||||
eventA := testEvent("foo")
|
||||
c, err := rest.Create(api.NewDefaultContext(), eventA)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error %v", err)
|
||||
}
|
||||
<-c
|
||||
_, err = rest.Update(api.NewContext(), eventA)
|
||||
_, err = rest.Update(api.NewDefaultContext(), eventA)
|
||||
if err == nil {
|
||||
t.Errorf("unexpected non-error")
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ func main() {
|
||||
glog.Fatalf("Invalid API configuration: %v", err)
|
||||
}
|
||||
|
||||
record.StartRecording(kubeClient.Events(), "scheduler")
|
||||
record.StartRecording(kubeClient.Events(""), "scheduler")
|
||||
|
||||
go http.ListenAndServe(net.JoinHostPort(address.String(), strconv.Itoa(*port)), nil)
|
||||
|
||||
|
@ -202,13 +202,13 @@ var aEvent string = `
|
||||
{
|
||||
"kind": "Event",
|
||||
"apiVersion": "v1beta1",
|
||||
"namespace": "default",
|
||||
"id": "a",
|
||||
"involvedObject": {
|
||||
{
|
||||
"kind": "Minion",
|
||||
"name": "a",
|
||||
"apiVersion": "v1beta1",
|
||||
}
|
||||
"kind": "Minion",
|
||||
"name": "a",
|
||||
"namespace": "default",
|
||||
"apiVersion": "v1beta1",
|
||||
}
|
||||
}
|
||||
`
|
||||
|
Loading…
Reference in New Issue
Block a user