mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Merge pull request #2367 from lavalamp/fix3
Yet more non-controversial fixes from #2277
This commit is contained in:
		
							
								
								
									
										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 {
 | 
			
		||||
			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 TestRESTCreate(t *testing.T) {
 | 
			
		||||
	_, rest := NewTestREST()
 | 
			
		||||
	eventA := &api.Event{
 | 
			
		||||
		ObjectMeta: api.ObjectMeta{Name: "foo"},
 | 
			
		||||
func testEvent(name string) *api.Event {
 | 
			
		||||
	return &api.Event{
 | 
			
		||||
		ObjectMeta: api.ObjectMeta{
 | 
			
		||||
			Name:      name,
 | 
			
		||||
			Namespace: "default",
 | 
			
		||||
		},
 | 
			
		||||
		InvolvedObject: api.ObjectReference{
 | 
			
		||||
			Namespace: "default",
 | 
			
		||||
		},
 | 
			
		||||
		Reason: "forTesting",
 | 
			
		||||
	}
 | 
			
		||||
	c, err := rest.Create(api.NewContext(), eventA)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatalf("Unexpected error %v", err)
 | 
			
		||||
}
 | 
			
		||||
	if !api.HasObjectMetaSystemFieldValues(&eventA.ObjectMeta) {
 | 
			
		||||
 | 
			
		||||
func TestRESTCreate(t *testing.T) {
 | 
			
		||||
	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,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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 := eventA, (<-c).Object; !reflect.DeepEqual(e, a) {
 | 
			
		||||
		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)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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,15 +202,15 @@ var aEvent string = `
 | 
			
		||||
{
 | 
			
		||||
  "kind": "Event",
 | 
			
		||||
  "apiVersion": "v1beta1",
 | 
			
		||||
  "namespace": "default",
 | 
			
		||||
  "id": "a",
 | 
			
		||||
  "involvedObject": {
 | 
			
		||||
    {
 | 
			
		||||
    "kind": "Minion",
 | 
			
		||||
    "name": "a",
 | 
			
		||||
    "namespace": "default",
 | 
			
		||||
    "apiVersion": "v1beta1",
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
`
 | 
			
		||||
 | 
			
		||||
var aBinding string = `
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user