mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 03:41:45 +00:00
fix up event client for namespaces
This commit is contained in:
parent
d153b98544
commit
3cf022786e
@ -33,7 +33,7 @@ type Interface interface {
|
|||||||
EndpointsNamespacer
|
EndpointsNamespacer
|
||||||
VersionInterface
|
VersionInterface
|
||||||
MinionsInterface
|
MinionsInterface
|
||||||
EventsInterface
|
EventNamespacer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) ReplicationControllers(namespace string) ReplicationControllerInterface {
|
func (c *Client) ReplicationControllers(namespace string) ReplicationControllerInterface {
|
||||||
@ -44,8 +44,8 @@ func (c *Client) Minions() MinionInterface {
|
|||||||
return newMinions(c)
|
return newMinions(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) Events() EventInterface {
|
func (c *Client) Events(namespace string) EventInterface {
|
||||||
return newEvents(c)
|
return newEvents(c, namespace)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) Endpoints(namespace string) EndpointsInterface {
|
func (c *Client) Endpoints(namespace string) EndpointsInterface {
|
||||||
|
@ -23,6 +23,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"path"
|
"path"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
"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)
|
requestBody := body(c.Request.Body, c.Request.RawBody)
|
||||||
actualQuery := c.handler.RequestReceived.URL.Query()
|
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
|
// We check the query manually, so blank it out so that FakeHandler.ValidateRequest
|
||||||
// won't check it.
|
// won't check it.
|
||||||
c.handler.RequestReceived.URL.RawQuery = ""
|
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 {
|
for key, values := range c.Request.Query {
|
||||||
validator, ok := c.QueryValidator[key]
|
validator, ok := c.QueryValidator[key]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
switch key {
|
||||||
|
case "labels", "fields":
|
||||||
|
validator = validateLabels
|
||||||
|
default:
|
||||||
validator = func(a, b string) bool { return a == b }
|
validator = func(a, b string) bool { return a == b }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
observed := actualQuery.Get(key)
|
observed := actualQuery.Get(key)
|
||||||
if !validator(values[0], observed) {
|
wanted := strings.Join(values, "")
|
||||||
t.Errorf("Unexpected query arg for key: %s. Expected %s, Received %s", key, values[0], observed)
|
if !validator(wanted, observed) {
|
||||||
|
t.Errorf("Unexpected query arg for key: %s. Expected %s, Received %s", key, wanted, observed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if c.Request.Header != "" {
|
if c.Request.Header != "" {
|
||||||
|
@ -17,14 +17,17 @@ limitations under the License.
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Events has methods to work with Event resources
|
// EventNamespacer can return an EventInterface for the given namespace.
|
||||||
type EventsInterface interface {
|
type EventNamespacer interface {
|
||||||
Events() EventInterface
|
Events(namespace string) EventInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
// EventInterface has methods to work with Event resources
|
// EventInterface has methods to work with Event resources
|
||||||
@ -33,32 +36,48 @@ type EventInterface interface {
|
|||||||
List(label, field labels.Selector) (*api.EventList, error)
|
List(label, field labels.Selector) (*api.EventList, error)
|
||||||
Get(id string) (*api.Event, error)
|
Get(id string) (*api.Event, error)
|
||||||
Watch(label, field labels.Selector, resourceVersion string) (watch.Interface, 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
|
// events implements Events interface
|
||||||
type events struct {
|
type events struct {
|
||||||
r *Client
|
client *Client
|
||||||
|
namespace string
|
||||||
}
|
}
|
||||||
|
|
||||||
// newEvents returns a events
|
// newEvents returns a new events object.
|
||||||
func newEvents(c *Client) *events {
|
func newEvents(c *Client, ns string) *events {
|
||||||
return &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.
|
// Create makes a new event. Returns the copy of the event the server returns,
|
||||||
func (c *events) Create(event *api.Event) (*api.Event, error) {
|
// 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{}
|
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
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// List returns a list of events matching the selectors.
|
// 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{}
|
result := &api.EventList{}
|
||||||
err := c.r.Get().
|
err := e.client.Get().
|
||||||
Path("events").
|
Path("events").
|
||||||
|
Namespace(e.namespace).
|
||||||
SelectorParam("labels", label).
|
SelectorParam("labels", label).
|
||||||
SelectorParam("fields", field).
|
SelectorParam("fields", field).
|
||||||
Do().
|
Do().
|
||||||
@ -67,19 +86,45 @@ func (c *events) List(label, field labels.Selector) (*api.EventList, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get returns the given event, or an 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{}
|
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
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Watch starts watching for events matching the given selectors.
|
// Watch starts watching for events matching the given selectors.
|
||||||
func (c *events) Watch(label, field labels.Selector, resourceVersion string) (watch.Interface, error) {
|
func (e *events) Watch(label, field labels.Selector, resourceVersion string) (watch.Interface, error) {
|
||||||
return c.r.Get().
|
return e.client.Get().
|
||||||
Path("watch").
|
Path("watch").
|
||||||
Path("events").
|
Path("events").
|
||||||
Param("resourceVersion", resourceVersion).
|
Param("resourceVersion", resourceVersion).
|
||||||
|
Namespace(e.namespace).
|
||||||
SelectorParam("labels", label).
|
SelectorParam("labels", label).
|
||||||
SelectorParam("fields", field).
|
SelectorParam("fields", field).
|
||||||
Watch()
|
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}
|
return &FakeMinions{Fake: c}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Fake) Events() EventInterface {
|
func (c *Fake) Events(namespace string) EventInterface {
|
||||||
return &FakeEvents{Fake: c}
|
return &FakeEvents{Fake: c}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ package client
|
|||||||
import (
|
import (
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
"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})
|
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "watch-events", Value: resourceVersion})
|
||||||
return c.Fake.Watch, c.Fake.Err
|
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
|
||||||
|
}
|
||||||
|
@ -56,7 +56,7 @@ func main() {
|
|||||||
glog.Fatalf("Invalid API configuration: %v", err)
|
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)
|
go http.ListenAndServe(net.JoinHostPort(address.String(), strconv.Itoa(*port)), nil)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user