mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-01-06 07:57:35 +00:00
Move pkg/api.{Context,RequestContextMapper} into pkg/genericapiserver/api/request
This commit is contained in:
@@ -11,7 +11,6 @@ load(
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"context.go",
|
||||
"conversion.go",
|
||||
"defaults.go",
|
||||
"doc.go",
|
||||
@@ -22,7 +21,6 @@ go_library(
|
||||
"meta.go",
|
||||
"ref.go",
|
||||
"register.go",
|
||||
"requestcontext.go",
|
||||
"resource_helpers.go",
|
||||
"types.go",
|
||||
"zz_generated.deepcopy.go",
|
||||
@@ -32,9 +30,9 @@ go_library(
|
||||
"//pkg/api/meta:go_default_library",
|
||||
"//pkg/api/resource:go_default_library",
|
||||
"//pkg/apis/meta/v1:go_default_library",
|
||||
"//pkg/auth/user:go_default_library",
|
||||
"//pkg/conversion:go_default_library",
|
||||
"//pkg/fields:go_default_library",
|
||||
"//pkg/genericapiserver/api/request:go_default_library",
|
||||
"//pkg/labels:go_default_library",
|
||||
"//pkg/runtime:go_default_library",
|
||||
"//pkg/runtime/schema:go_default_library",
|
||||
@@ -48,8 +46,6 @@ go_library(
|
||||
"//pkg/util/uuid:go_default_library",
|
||||
"//pkg/util/validation/field:go_default_library",
|
||||
"//vendor:github.com/davecgh/go-spew/spew",
|
||||
"//vendor:github.com/golang/glog",
|
||||
"//vendor:golang.org/x/net/context",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -75,7 +71,6 @@ go_test(
|
||||
go_test(
|
||||
name = "go_default_xtest",
|
||||
srcs = [
|
||||
"context_test.go",
|
||||
"conversion_test.go",
|
||||
"copy_test.go",
|
||||
"deep_copy_test.go",
|
||||
@@ -96,8 +91,8 @@ go_test(
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
"//pkg/apis/extensions/v1beta1:go_default_library",
|
||||
"//pkg/apis/meta/v1:go_default_library",
|
||||
"//pkg/auth/user:go_default_library",
|
||||
"//pkg/conversion:go_default_library",
|
||||
"//pkg/genericapiserver/api/request:go_default_library",
|
||||
"//pkg/runtime:go_default_library",
|
||||
"//pkg/runtime/schema:go_default_library",
|
||||
"//pkg/runtime/serializer/protobuf:go_default_library",
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
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 api
|
||||
|
||||
import (
|
||||
stderrs "errors"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
"k8s.io/kubernetes/pkg/auth/user"
|
||||
"k8s.io/kubernetes/pkg/types"
|
||||
)
|
||||
|
||||
// Context carries values across API boundaries.
|
||||
// This context matches the context.Context interface
|
||||
// (https://blog.golang.org/context), for the purposes
|
||||
// of passing the api.Context through to the storage tier.
|
||||
// TODO: Determine the extent that this abstraction+interface
|
||||
// is used by the api, and whether we can remove.
|
||||
type Context interface {
|
||||
// Value returns the value associated with key or nil if none.
|
||||
Value(key interface{}) interface{}
|
||||
|
||||
// Deadline returns the time when this Context will be canceled, if any.
|
||||
Deadline() (deadline time.Time, ok bool)
|
||||
|
||||
// Done returns a channel that is closed when this Context is canceled
|
||||
// or times out.
|
||||
Done() <-chan struct{}
|
||||
|
||||
// Err indicates why this context was canceled, after the Done channel
|
||||
// is closed.
|
||||
Err() error
|
||||
}
|
||||
|
||||
// The key type is unexported to prevent collisions
|
||||
type key int
|
||||
|
||||
const (
|
||||
// namespaceKey is the context key for the request namespace.
|
||||
namespaceKey key = iota
|
||||
|
||||
// userKey is the context key for the request user.
|
||||
userKey
|
||||
|
||||
// uidKey is the context key for the uid to assign to an object on create.
|
||||
uidKey
|
||||
|
||||
// userAgentKey is the context key for the request user agent.
|
||||
userAgentKey
|
||||
)
|
||||
|
||||
// NewContext instantiates a base context object for request flows.
|
||||
func NewContext() Context {
|
||||
return context.TODO()
|
||||
}
|
||||
|
||||
// NewDefaultContext instantiates a base context object for request flows in the default namespace
|
||||
func NewDefaultContext() Context {
|
||||
return WithNamespace(NewContext(), NamespaceDefault)
|
||||
}
|
||||
|
||||
// WithValue returns a copy of parent in which the value associated with key is val.
|
||||
func WithValue(parent Context, key interface{}, val interface{}) Context {
|
||||
internalCtx, ok := parent.(context.Context)
|
||||
if !ok {
|
||||
panic(stderrs.New("Invalid context type"))
|
||||
}
|
||||
return context.WithValue(internalCtx, key, val)
|
||||
}
|
||||
|
||||
// WithNamespace returns a copy of parent in which the namespace value is set
|
||||
func WithNamespace(parent Context, namespace string) Context {
|
||||
return WithValue(parent, namespaceKey, namespace)
|
||||
}
|
||||
|
||||
// NamespaceFrom returns the value of the namespace key on the ctx
|
||||
func NamespaceFrom(ctx Context) (string, bool) {
|
||||
namespace, ok := ctx.Value(namespaceKey).(string)
|
||||
return namespace, ok
|
||||
}
|
||||
|
||||
// NamespaceValue returns the value of the namespace key on the ctx, or the empty string if none
|
||||
func NamespaceValue(ctx Context) string {
|
||||
namespace, _ := NamespaceFrom(ctx)
|
||||
return namespace
|
||||
}
|
||||
|
||||
// ValidNamespace returns false if the namespace on the context differs from the resource. If the resource has no namespace, it is set to the value in the context.
|
||||
func ValidNamespace(ctx Context, resource *ObjectMeta) bool {
|
||||
ns, ok := NamespaceFrom(ctx)
|
||||
if len(resource.Namespace) == 0 {
|
||||
resource.Namespace = ns
|
||||
}
|
||||
return ns == resource.Namespace && ok
|
||||
}
|
||||
|
||||
// WithNamespaceDefaultIfNone returns a context whose namespace is the default if and only if the parent context has no namespace value
|
||||
func WithNamespaceDefaultIfNone(parent Context) Context {
|
||||
namespace, ok := NamespaceFrom(parent)
|
||||
if !ok || len(namespace) == 0 {
|
||||
return WithNamespace(parent, NamespaceDefault)
|
||||
}
|
||||
return parent
|
||||
}
|
||||
|
||||
// WithUser returns a copy of parent in which the user value is set
|
||||
func WithUser(parent Context, user user.Info) Context {
|
||||
return WithValue(parent, userKey, user)
|
||||
}
|
||||
|
||||
// UserFrom returns the value of the user key on the ctx
|
||||
func UserFrom(ctx Context) (user.Info, bool) {
|
||||
user, ok := ctx.Value(userKey).(user.Info)
|
||||
return user, ok
|
||||
}
|
||||
|
||||
// WithUID returns a copy of parent in which the uid value is set
|
||||
func WithUID(parent Context, uid types.UID) Context {
|
||||
return WithValue(parent, uidKey, uid)
|
||||
}
|
||||
|
||||
// UIDFrom returns the value of the uid key on the ctx
|
||||
func UIDFrom(ctx Context) (types.UID, bool) {
|
||||
uid, ok := ctx.Value(uidKey).(types.UID)
|
||||
return uid, ok
|
||||
}
|
||||
|
||||
// WithUserAgent returns a copy of parent in which the user value is set
|
||||
func WithUserAgent(parent Context, userAgent string) Context {
|
||||
return WithValue(parent, userAgentKey, userAgent)
|
||||
}
|
||||
|
||||
// UserAgentFrom returns the value of the userAgent key on the ctx
|
||||
func UserAgentFrom(ctx Context) (string, bool) {
|
||||
userAgent, ok := ctx.Value(userAgentKey).(string)
|
||||
return userAgent, ok
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
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 api_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/auth/user"
|
||||
"k8s.io/kubernetes/pkg/types"
|
||||
)
|
||||
|
||||
// TestNamespaceContext validates that a namespace can be get/set on a context object
|
||||
func TestNamespaceContext(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
result, ok := api.NamespaceFrom(ctx)
|
||||
if !ok {
|
||||
t.Fatalf("Error getting namespace")
|
||||
}
|
||||
if api.NamespaceDefault != result {
|
||||
t.Fatalf("Expected: %s, Actual: %s", api.NamespaceDefault, result)
|
||||
}
|
||||
|
||||
ctx = api.NewContext()
|
||||
result, ok = api.NamespaceFrom(ctx)
|
||||
if ok {
|
||||
t.Fatalf("Should not be ok because there is no namespace on the context")
|
||||
}
|
||||
}
|
||||
|
||||
// TestValidNamespace validates that namespace rules are enforced on a resource prior to create or update
|
||||
func TestValidNamespace(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
namespace, _ := api.NamespaceFrom(ctx)
|
||||
resource := api.ReplicationController{}
|
||||
if !api.ValidNamespace(ctx, &resource.ObjectMeta) {
|
||||
t.Fatalf("expected success")
|
||||
}
|
||||
if namespace != resource.Namespace {
|
||||
t.Fatalf("expected resource to have the default namespace assigned during validation")
|
||||
}
|
||||
resource = api.ReplicationController{ObjectMeta: api.ObjectMeta{Namespace: "other"}}
|
||||
if api.ValidNamespace(ctx, &resource.ObjectMeta) {
|
||||
t.Fatalf("Expected error that resource and context errors do not match because resource has different namespace")
|
||||
}
|
||||
ctx = api.NewContext()
|
||||
if api.ValidNamespace(ctx, &resource.ObjectMeta) {
|
||||
t.Fatalf("Expected error that resource and context errors do not match since context has no namespace")
|
||||
}
|
||||
|
||||
ctx = api.NewContext()
|
||||
ns := api.NamespaceValue(ctx)
|
||||
if ns != "" {
|
||||
t.Fatalf("Expected the empty string")
|
||||
}
|
||||
}
|
||||
|
||||
//TestUserContext validates that a userinfo can be get/set on a context object
|
||||
func TestUserContext(t *testing.T) {
|
||||
ctx := api.NewContext()
|
||||
_, ok := api.UserFrom(ctx)
|
||||
if ok {
|
||||
t.Fatalf("Should not be ok because there is no user.Info on the context")
|
||||
}
|
||||
ctx = api.WithUser(
|
||||
ctx,
|
||||
&user.DefaultInfo{
|
||||
Name: "bob",
|
||||
UID: "123",
|
||||
Groups: []string{"group1"},
|
||||
Extra: map[string][]string{"foo": {"bar"}},
|
||||
},
|
||||
)
|
||||
|
||||
result, ok := api.UserFrom(ctx)
|
||||
if !ok {
|
||||
t.Fatalf("Error getting user info")
|
||||
}
|
||||
|
||||
expectedName := "bob"
|
||||
if result.GetName() != expectedName {
|
||||
t.Fatalf("Get user name error, Expected: %s, Actual: %s", expectedName, result.GetName())
|
||||
}
|
||||
|
||||
expectedUID := "123"
|
||||
if result.GetUID() != expectedUID {
|
||||
t.Fatalf("Get UID error, Expected: %s, Actual: %s", expectedUID, result.GetName())
|
||||
}
|
||||
|
||||
expectedGroup := "group1"
|
||||
actualGroup := result.GetGroups()
|
||||
if len(actualGroup) != 1 {
|
||||
t.Fatalf("Get user group number error, Expected: 1, Actual: %d", len(actualGroup))
|
||||
} else if actualGroup[0] != expectedGroup {
|
||||
t.Fatalf("Get user group error, Expected: %s, Actual: %s", expectedGroup, actualGroup[0])
|
||||
}
|
||||
|
||||
expectedExtraKey := "foo"
|
||||
expectedExtraValue := "bar"
|
||||
actualExtra := result.GetExtra()
|
||||
if len(actualExtra[expectedExtraKey]) != 1 {
|
||||
t.Fatalf("Get user extra map number error, Expected: 1, Actual: %d", len(actualExtra[expectedExtraKey]))
|
||||
} else if actualExtra[expectedExtraKey][0] != expectedExtraValue {
|
||||
t.Fatalf("Get user extra map value error, Expected: %s, Actual: %s", expectedExtraValue, actualExtra[expectedExtraKey])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//TestUIDContext validates that a UID can be get/set on a context object
|
||||
func TestUIDContext(t *testing.T) {
|
||||
ctx := api.NewContext()
|
||||
_, ok := api.UIDFrom(ctx)
|
||||
if ok {
|
||||
t.Fatalf("Should not be ok because there is no UID on the context")
|
||||
}
|
||||
ctx = api.WithUID(
|
||||
ctx,
|
||||
types.UID("testUID"),
|
||||
)
|
||||
_, ok = api.UIDFrom(ctx)
|
||||
if !ok {
|
||||
t.Fatalf("Error getting UID")
|
||||
}
|
||||
}
|
||||
|
||||
//TestUserAgentContext validates that a useragent can be get/set on a context object
|
||||
func TestUserAgentContext(t *testing.T) {
|
||||
ctx := api.NewContext()
|
||||
_, ok := api.UserAgentFrom(ctx)
|
||||
if ok {
|
||||
t.Fatalf("Should not be ok because there is no UserAgent on the context")
|
||||
}
|
||||
|
||||
ctx = api.WithUserAgent(
|
||||
ctx,
|
||||
"TestUserAgent",
|
||||
)
|
||||
result, ok := api.UserAgentFrom(ctx)
|
||||
if !ok {
|
||||
t.Fatalf("Error getting UserAgent")
|
||||
}
|
||||
expectedResult := "TestUserAgent"
|
||||
if result != expectedResult {
|
||||
t.Fatalf("Get user agent error, Expected: %s, Actual: %s", expectedResult, result)
|
||||
}
|
||||
}
|
||||
@@ -20,17 +20,18 @@ import (
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
metav1 "k8s.io/kubernetes/pkg/apis/meta/v1"
|
||||
"k8s.io/kubernetes/pkg/conversion"
|
||||
genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/types"
|
||||
"k8s.io/kubernetes/pkg/util/uuid"
|
||||
)
|
||||
|
||||
// FillObjectMetaSystemFields populates fields that are managed by the system on ObjectMeta.
|
||||
func FillObjectMetaSystemFields(ctx Context, meta *ObjectMeta) {
|
||||
func FillObjectMetaSystemFields(ctx genericapirequest.Context, meta *ObjectMeta) {
|
||||
meta.CreationTimestamp = metav1.Now()
|
||||
// allows admission controllers to assign a UID earlier in the request processing
|
||||
// to support tracking resources pending creation.
|
||||
uid, found := UIDFrom(ctx)
|
||||
uid, found := genericapirequest.UIDFrom(ctx)
|
||||
if !found {
|
||||
uid = uuid.NewUUID()
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/apimachinery/registered"
|
||||
metav1 "k8s.io/kubernetes/pkg/apis/meta/v1"
|
||||
genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/runtime/schema"
|
||||
"k8s.io/kubernetes/pkg/util/uuid"
|
||||
@@ -35,7 +36,7 @@ var _ meta.Object = &api.ObjectMeta{}
|
||||
|
||||
// TestFillObjectMetaSystemFields validates that system populated fields are set on an object
|
||||
func TestFillObjectMetaSystemFields(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
ctx := genericapirequest.NewDefaultContext()
|
||||
resource := api.ObjectMeta{}
|
||||
api.FillObjectMetaSystemFields(ctx, &resource)
|
||||
if resource.CreationTimestamp.Time.IsZero() {
|
||||
@@ -45,7 +46,7 @@ func TestFillObjectMetaSystemFields(t *testing.T) {
|
||||
}
|
||||
// verify we can inject a UID
|
||||
uid := uuid.NewUUID()
|
||||
ctx = api.WithUID(ctx, uid)
|
||||
ctx = genericapirequest.WithUID(ctx, uid)
|
||||
resource = api.ObjectMeta{}
|
||||
api.FillObjectMetaSystemFields(ctx, &resource)
|
||||
if resource.UID != uid {
|
||||
@@ -55,7 +56,7 @@ func TestFillObjectMetaSystemFields(t *testing.T) {
|
||||
|
||||
// TestHasObjectMetaSystemFieldValues validates that true is returned if and only if all fields are populated
|
||||
func TestHasObjectMetaSystemFieldValues(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
ctx := genericapirequest.NewDefaultContext()
|
||||
resource := api.ObjectMeta{}
|
||||
if api.HasObjectMetaSystemFieldValues(&resource) {
|
||||
t.Errorf("the resource does not have all fields yet populated, but incorrectly reports it does")
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
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 api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
// RequestContextMapper keeps track of the context associated with a particular request
|
||||
type RequestContextMapper interface {
|
||||
// Get returns the context associated with the given request (if any), and true if the request has an associated context, and false if it does not.
|
||||
Get(req *http.Request) (Context, bool)
|
||||
// Update maps the request to the given context. If no context was previously associated with the request, an error is returned.
|
||||
// Update should only be called with a descendant context of the previously associated context.
|
||||
// Updating to an unrelated context may return an error in the future.
|
||||
// The context associated with a request should only be updated by a limited set of callers.
|
||||
// Valid examples include the authentication layer, or an audit/tracing layer.
|
||||
Update(req *http.Request, context Context) error
|
||||
}
|
||||
|
||||
type requestContextMap struct {
|
||||
contexts map[*http.Request]Context
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
// NewRequestContextMapper returns a new RequestContextMapper.
|
||||
// The returned mapper must be added as a request filter using NewRequestContextFilter.
|
||||
func NewRequestContextMapper() RequestContextMapper {
|
||||
return &requestContextMap{
|
||||
contexts: make(map[*http.Request]Context),
|
||||
}
|
||||
}
|
||||
|
||||
// Get returns the context associated with the given request (if any), and true if the request has an associated context, and false if it does not.
|
||||
// Get will only return a valid context when called from inside the filter chain set up by NewRequestContextFilter()
|
||||
func (c *requestContextMap) Get(req *http.Request) (Context, bool) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
context, ok := c.contexts[req]
|
||||
return context, ok
|
||||
}
|
||||
|
||||
// Update maps the request to the given context.
|
||||
// If no context was previously associated with the request, an error is returned and the context is ignored.
|
||||
func (c *requestContextMap) Update(req *http.Request, context Context) error {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
if _, ok := c.contexts[req]; !ok {
|
||||
return errors.New("No context associated")
|
||||
}
|
||||
// TODO: ensure the new context is a descendant of the existing one
|
||||
c.contexts[req] = context
|
||||
return nil
|
||||
}
|
||||
|
||||
// init maps the request to the given context and returns true if there was no context associated with the request already.
|
||||
// if a context was already associated with the request, it ignores the given context and returns false.
|
||||
// init is intentionally unexported to ensure that all init calls are paired with a remove after a request is handled
|
||||
func (c *requestContextMap) init(req *http.Request, context Context) bool {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
if _, exists := c.contexts[req]; exists {
|
||||
return false
|
||||
}
|
||||
c.contexts[req] = context
|
||||
return true
|
||||
}
|
||||
|
||||
// remove is intentionally unexported to ensure that the context is not removed until a request is handled
|
||||
func (c *requestContextMap) remove(req *http.Request) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
delete(c.contexts, req)
|
||||
}
|
||||
|
||||
// WithRequestContext ensures there is a Context object associated with the request before calling the passed handler.
|
||||
// After the passed handler runs, the context is cleaned up.
|
||||
func WithRequestContext(handler http.Handler, mapper RequestContextMapper) http.Handler {
|
||||
rcMap, ok := mapper.(*requestContextMap)
|
||||
if !ok {
|
||||
glog.Fatal("Unknown RequestContextMapper implementation.")
|
||||
}
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
if rcMap.init(req, NewContext()) {
|
||||
// If we were the ones to successfully initialize, pair with a remove
|
||||
defer rcMap.remove(req)
|
||||
}
|
||||
handler.ServeHTTP(w, req)
|
||||
})
|
||||
}
|
||||
|
||||
// IsEmpty returns true if there are no contexts registered, or an error if it could not be determined. Intended for use by tests.
|
||||
func IsEmpty(requestsToContexts RequestContextMapper) (bool, error) {
|
||||
if requestsToContexts, ok := requestsToContexts.(*requestContextMap); ok {
|
||||
return len(requestsToContexts.contexts) == 0, nil
|
||||
}
|
||||
return true, errors.New("Unknown RequestContextMapper implementation")
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
|
||||
"k8s.io/kubernetes/pkg/api/resource"
|
||||
metav1 "k8s.io/kubernetes/pkg/apis/meta/v1"
|
||||
genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request"
|
||||
)
|
||||
|
||||
// Returns string version of ResourceName.
|
||||
@@ -227,3 +228,13 @@ func PodRequestsAndLimits(pod *Pod) (reqs map[ResourceName]resource.Quantity, li
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ValidNamespace returns false if the namespace on the context differs from the resource. If the resource has no namespace, it is set to the value in the context.
|
||||
// TODO(sttts): move into pkg/genericapiserver/api
|
||||
func ValidNamespace(ctx genericapirequest.Context, resource *ObjectMeta) bool {
|
||||
ns, ok := genericapirequest.NamespaceFrom(ctx)
|
||||
if len(resource.Namespace) == 0 {
|
||||
resource.Namespace = ns
|
||||
}
|
||||
return ns == resource.Namespace && ok
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ go_library(
|
||||
"//pkg/api/validation:go_default_library",
|
||||
"//pkg/api/validation/path:go_default_library",
|
||||
"//pkg/apis/meta/v1:go_default_library",
|
||||
"//pkg/genericapiserver/api/request:go_default_library",
|
||||
"//pkg/runtime:go_default_library",
|
||||
"//pkg/runtime/schema:go_default_library",
|
||||
"//pkg/util/validation/field:go_default_library",
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/api/errors"
|
||||
"k8s.io/kubernetes/pkg/api/validation"
|
||||
path "k8s.io/kubernetes/pkg/api/validation/path"
|
||||
genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/runtime/schema"
|
||||
"k8s.io/kubernetes/pkg/util/validation/field"
|
||||
@@ -41,10 +42,10 @@ type RESTCreateStrategy interface {
|
||||
// the object. For example: remove fields that are not to be persisted,
|
||||
// sort order-insensitive list fields, etc. This should not remove fields
|
||||
// whose presence would be considered a validation error.
|
||||
PrepareForCreate(ctx api.Context, obj runtime.Object)
|
||||
PrepareForCreate(ctx genericapirequest.Context, obj runtime.Object)
|
||||
// Validate is invoked after default fields in the object have been filled in before
|
||||
// the object is persisted. This method should not mutate the object.
|
||||
Validate(ctx api.Context, obj runtime.Object) field.ErrorList
|
||||
Validate(ctx genericapirequest.Context, obj runtime.Object) field.ErrorList
|
||||
// Canonicalize is invoked after validation has succeeded but before the
|
||||
// object has been persisted. This method may mutate the object.
|
||||
Canonicalize(obj runtime.Object)
|
||||
@@ -53,7 +54,7 @@ type RESTCreateStrategy interface {
|
||||
// BeforeCreate ensures that common operations for all resources are performed on creation. It only returns
|
||||
// errors that can be converted to api.Status. It invokes PrepareForCreate, then GenerateName, then Validate.
|
||||
// It returns nil if the object should be created.
|
||||
func BeforeCreate(strategy RESTCreateStrategy, ctx api.Context, obj runtime.Object) error {
|
||||
func BeforeCreate(strategy RESTCreateStrategy, ctx genericapirequest.Context, obj runtime.Object) error {
|
||||
objectMeta, kind, kerr := objectMetaAndKind(strategy, obj)
|
||||
if kerr != nil {
|
||||
return kerr
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/errors"
|
||||
metav1 "k8s.io/kubernetes/pkg/apis/meta/v1"
|
||||
genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/runtime/schema"
|
||||
)
|
||||
@@ -52,7 +53,7 @@ type GarbageCollectionDeleteStrategy interface {
|
||||
type RESTGracefulDeleteStrategy interface {
|
||||
// CheckGracefulDelete should return true if the object can be gracefully deleted and set
|
||||
// any default values on the DeleteOptions.
|
||||
CheckGracefulDelete(ctx api.Context, obj runtime.Object, options *api.DeleteOptions) bool
|
||||
CheckGracefulDelete(ctx genericapirequest.Context, obj runtime.Object, options *api.DeleteOptions) bool
|
||||
}
|
||||
|
||||
// BeforeDelete tests whether the object can be gracefully deleted. If graceful is set the object
|
||||
@@ -61,7 +62,7 @@ type RESTGracefulDeleteStrategy interface {
|
||||
// condition cannot be checked or the gracePeriodSeconds is invalid. The options argument may be updated with
|
||||
// default values if graceful is true. Second place where we set deletionTimestamp is pkg/registry/generic/registry/store.go
|
||||
// this function is responsible for setting deletionTimestamp during gracefulDeletion, other one for cascading deletions.
|
||||
func BeforeDelete(strategy RESTDeleteStrategy, ctx api.Context, obj runtime.Object, options *api.DeleteOptions) (graceful, gracefulPending bool, err error) {
|
||||
func BeforeDelete(strategy RESTDeleteStrategy, ctx genericapirequest.Context, obj runtime.Object, options *api.DeleteOptions) (graceful, gracefulPending bool, err error) {
|
||||
objectMeta, gvk, kerr := objectMetaAndKind(strategy, obj)
|
||||
if kerr != nil {
|
||||
return false, false, kerr
|
||||
|
||||
@@ -17,7 +17,7 @@ limitations under the License.
|
||||
package rest
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
@@ -25,5 +25,5 @@ import (
|
||||
type RESTExportStrategy interface {
|
||||
// Export strips fields that can not be set by the user. If 'exact' is false
|
||||
// fields specific to the cluster are also stripped
|
||||
Export(ctx api.Context, obj runtime.Object, exact bool) error
|
||||
Export(ctx genericapirequest.Context, obj runtime.Object, exact bool) error
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
metav1 "k8s.io/kubernetes/pkg/apis/meta/v1"
|
||||
genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/runtime/schema"
|
||||
"k8s.io/kubernetes/pkg/watch"
|
||||
@@ -70,7 +71,7 @@ type Lister interface {
|
||||
// This object must be a pointer type for use with Codec.DecodeInto([]byte, runtime.Object)
|
||||
NewList() runtime.Object
|
||||
// List selects resources in the storage which match to the selector. 'options' can be nil.
|
||||
List(ctx api.Context, options *api.ListOptions) (runtime.Object, error)
|
||||
List(ctx genericapirequest.Context, options *api.ListOptions) (runtime.Object, error)
|
||||
}
|
||||
|
||||
// Exporter is an object that knows how to strip a RESTful resource for export
|
||||
@@ -78,7 +79,7 @@ type Exporter interface {
|
||||
// Export an object. Fields that are not user specified (e.g. Status, ObjectMeta.ResourceVersion) are stripped out
|
||||
// Returns the stripped object. If 'exact' is true, fields that are specific to the cluster (e.g. namespace) are
|
||||
// retained, otherwise they are stripped also.
|
||||
Export(ctx api.Context, name string, opts metav1.ExportOptions) (runtime.Object, error)
|
||||
Export(ctx genericapirequest.Context, name string, opts metav1.ExportOptions) (runtime.Object, error)
|
||||
}
|
||||
|
||||
// Getter is an object that can retrieve a named RESTful resource.
|
||||
@@ -86,7 +87,7 @@ type Getter interface {
|
||||
// Get finds a resource in the storage by name and returns it.
|
||||
// Although it can return an arbitrary error value, IsNotFound(err) is true for the
|
||||
// returned error value err when the specified resource is not found.
|
||||
Get(ctx api.Context, name string, options *metav1.GetOptions) (runtime.Object, error)
|
||||
Get(ctx genericapirequest.Context, name string, options *metav1.GetOptions) (runtime.Object, error)
|
||||
}
|
||||
|
||||
// GetterWithOptions is an object that retrieve a named RESTful resource and takes
|
||||
@@ -99,7 +100,7 @@ type GetterWithOptions interface {
|
||||
// The options object passed to it is of the same type returned by the NewGetOptions
|
||||
// method.
|
||||
// TODO: Pass metav1.GetOptions.
|
||||
Get(ctx api.Context, name string, options runtime.Object) (runtime.Object, error)
|
||||
Get(ctx genericapirequest.Context, name string, options runtime.Object) (runtime.Object, error)
|
||||
|
||||
// NewGetOptions returns an empty options object that will be used to pass
|
||||
// options to the Get method. It may return a bool and a string, if true, the
|
||||
@@ -117,7 +118,7 @@ type Deleter interface {
|
||||
// returned error value err when the specified resource is not found.
|
||||
// Delete *may* return the object that was deleted, or a status object indicating additional
|
||||
// information about deletion.
|
||||
Delete(ctx api.Context, name string) (runtime.Object, error)
|
||||
Delete(ctx genericapirequest.Context, name string) (runtime.Object, error)
|
||||
}
|
||||
|
||||
// GracefulDeleter knows how to pass deletion options to allow delayed deletion of a
|
||||
@@ -130,7 +131,7 @@ type GracefulDeleter interface {
|
||||
// returned error value err when the specified resource is not found.
|
||||
// Delete *may* return the object that was deleted, or a status object indicating additional
|
||||
// information about deletion.
|
||||
Delete(ctx api.Context, name string, options *api.DeleteOptions) (runtime.Object, error)
|
||||
Delete(ctx genericapirequest.Context, name string, options *api.DeleteOptions) (runtime.Object, error)
|
||||
}
|
||||
|
||||
// GracefulDeleteAdapter adapts the Deleter interface to GracefulDeleter
|
||||
@@ -139,7 +140,7 @@ type GracefulDeleteAdapter struct {
|
||||
}
|
||||
|
||||
// Delete implements RESTGracefulDeleter in terms of Deleter
|
||||
func (w GracefulDeleteAdapter) Delete(ctx api.Context, name string, options *api.DeleteOptions) (runtime.Object, error) {
|
||||
func (w GracefulDeleteAdapter) Delete(ctx genericapirequest.Context, name string, options *api.DeleteOptions) (runtime.Object, error) {
|
||||
return w.Deleter.Delete(ctx, name)
|
||||
}
|
||||
|
||||
@@ -151,7 +152,7 @@ type CollectionDeleter interface {
|
||||
// them or return an invalid request error.
|
||||
// DeleteCollection may not be atomic - i.e. it may delete some objects and still
|
||||
// return an error after it. On success, returns a list of deleted objects.
|
||||
DeleteCollection(ctx api.Context, options *api.DeleteOptions, listOptions *api.ListOptions) (runtime.Object, error)
|
||||
DeleteCollection(ctx genericapirequest.Context, options *api.DeleteOptions, listOptions *api.ListOptions) (runtime.Object, error)
|
||||
}
|
||||
|
||||
// Creater is an object that can create an instance of a RESTful object.
|
||||
@@ -161,7 +162,7 @@ type Creater interface {
|
||||
New() runtime.Object
|
||||
|
||||
// Create creates a new version of a resource.
|
||||
Create(ctx api.Context, obj runtime.Object) (runtime.Object, error)
|
||||
Create(ctx genericapirequest.Context, obj runtime.Object) (runtime.Object, error)
|
||||
}
|
||||
|
||||
// NamedCreater is an object that can create an instance of a RESTful object using a name parameter.
|
||||
@@ -173,7 +174,7 @@ type NamedCreater interface {
|
||||
// Create creates a new version of a resource. It expects a name parameter from the path.
|
||||
// This is needed for create operations on subresources which include the name of the parent
|
||||
// resource in the path.
|
||||
Create(ctx api.Context, name string, obj runtime.Object) (runtime.Object, error)
|
||||
Create(ctx genericapirequest.Context, name string, obj runtime.Object) (runtime.Object, error)
|
||||
}
|
||||
|
||||
// UpdatedObjectInfo provides information about an updated object to an Updater.
|
||||
@@ -186,7 +187,7 @@ type UpdatedObjectInfo interface {
|
||||
|
||||
// UpdatedObject returns the updated object, given a context and old object.
|
||||
// The only time an empty oldObj should be passed in is if a "create on update" is occurring (there is no oldObj).
|
||||
UpdatedObject(ctx api.Context, oldObj runtime.Object) (newObj runtime.Object, err error)
|
||||
UpdatedObject(ctx genericapirequest.Context, oldObj runtime.Object) (newObj runtime.Object, err error)
|
||||
}
|
||||
|
||||
// Updater is an object that can update an instance of a RESTful object.
|
||||
@@ -198,14 +199,14 @@ type Updater interface {
|
||||
// Update finds a resource in the storage and updates it. Some implementations
|
||||
// may allow updates creates the object - they should set the created boolean
|
||||
// to true.
|
||||
Update(ctx api.Context, name string, objInfo UpdatedObjectInfo) (runtime.Object, bool, error)
|
||||
Update(ctx genericapirequest.Context, name string, objInfo UpdatedObjectInfo) (runtime.Object, bool, error)
|
||||
}
|
||||
|
||||
// CreaterUpdater is a storage object that must support both create and update.
|
||||
// Go prevents embedded interfaces that implement the same method.
|
||||
type CreaterUpdater interface {
|
||||
Creater
|
||||
Update(ctx api.Context, name string, objInfo UpdatedObjectInfo) (runtime.Object, bool, error)
|
||||
Update(ctx genericapirequest.Context, name string, objInfo UpdatedObjectInfo) (runtime.Object, bool, error)
|
||||
}
|
||||
|
||||
// CreaterUpdater must satisfy the Updater interface.
|
||||
@@ -224,7 +225,7 @@ type Watcher interface {
|
||||
// are supported; an error should be returned if 'field' tries to select on a field that
|
||||
// isn't supported. 'resourceVersion' allows for continuing/starting a watch at a
|
||||
// particular version.
|
||||
Watch(ctx api.Context, options *api.ListOptions) (watch.Interface, error)
|
||||
Watch(ctx genericapirequest.Context, options *api.ListOptions) (watch.Interface, error)
|
||||
}
|
||||
|
||||
// StandardStorage is an interface covering the common verbs. Provided for testing whether a
|
||||
@@ -241,7 +242,7 @@ type StandardStorage interface {
|
||||
// Redirector know how to return a remote resource's location.
|
||||
type Redirector interface {
|
||||
// ResourceLocation should return the remote location of the given resource, and an optional transport to use to request it, or an error.
|
||||
ResourceLocation(ctx api.Context, id string) (remoteLocation *url.URL, transport http.RoundTripper, err error)
|
||||
ResourceLocation(ctx genericapirequest.Context, id string) (remoteLocation *url.URL, transport http.RoundTripper, err error)
|
||||
}
|
||||
|
||||
// Responder abstracts the normal response behavior for a REST method and is passed to callers that
|
||||
@@ -261,7 +262,7 @@ type Connecter interface {
|
||||
// code and body, so the ServeHTTP method should exit after invoking the responder. The Handler will
|
||||
// be used for a single API request and then discarded. The Responder is guaranteed to write to the
|
||||
// same http.ResponseWriter passed to ServeHTTP.
|
||||
Connect(ctx api.Context, id string, options runtime.Object, r Responder) (http.Handler, error)
|
||||
Connect(ctx genericapirequest.Context, id string, options runtime.Object, r Responder) (http.Handler, error)
|
||||
|
||||
// NewConnectOptions returns an empty options object that will be used to pass
|
||||
// options to the Connect method. If nil, then a nil options object is passed to
|
||||
|
||||
@@ -19,6 +19,7 @@ go_library(
|
||||
"//pkg/apis/meta/v1:go_default_library",
|
||||
"//pkg/conversion:go_default_library",
|
||||
"//pkg/fields:go_default_library",
|
||||
"//pkg/genericapiserver/api/request:go_default_library",
|
||||
"//pkg/labels:go_default_library",
|
||||
"//pkg/runtime:go_default_library",
|
||||
"//pkg/types:go_default_library",
|
||||
|
||||
@@ -30,6 +30,7 @@ import (
|
||||
metav1 "k8s.io/kubernetes/pkg/apis/meta/v1"
|
||||
"k8s.io/kubernetes/pkg/conversion"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/types"
|
||||
@@ -96,11 +97,11 @@ func (t *Tester) TestNamespace() string {
|
||||
|
||||
// TestContext returns a namespaced context that will be used when making storage calls.
|
||||
// Namespace is determined by TestNamespace()
|
||||
func (t *Tester) TestContext() api.Context {
|
||||
func (t *Tester) TestContext() genericapirequest.Context {
|
||||
if t.clusterScope {
|
||||
return api.NewContext()
|
||||
return genericapirequest.NewContext()
|
||||
}
|
||||
return api.WithNamespace(api.NewContext(), t.TestNamespace())
|
||||
return genericapirequest.WithNamespace(genericapirequest.NewContext(), t.TestNamespace())
|
||||
}
|
||||
|
||||
func (t *Tester) getObjectMetaOrFail(obj runtime.Object) *api.ObjectMeta {
|
||||
@@ -117,7 +118,7 @@ func (t *Tester) setObjectMeta(obj runtime.Object, name string) {
|
||||
if t.clusterScope {
|
||||
meta.Namespace = api.NamespaceNone
|
||||
} else {
|
||||
meta.Namespace = api.NamespaceValue(t.TestContext())
|
||||
meta.Namespace = genericapirequest.NamespaceValue(t.TestContext())
|
||||
}
|
||||
meta.GenerateName = ""
|
||||
meta.Generation = 1
|
||||
@@ -133,11 +134,11 @@ func copyOrDie(obj runtime.Object) runtime.Object {
|
||||
|
||||
type AssignFunc func([]runtime.Object) []runtime.Object
|
||||
type EmitFunc func(runtime.Object, string) error
|
||||
type GetFunc func(api.Context, runtime.Object) (runtime.Object, error)
|
||||
type GetFunc func(genericapirequest.Context, runtime.Object) (runtime.Object, error)
|
||||
type InitWatchFunc func()
|
||||
type InjectErrFunc func(err error)
|
||||
type IsErrorFunc func(err error) bool
|
||||
type CreateFunc func(api.Context, runtime.Object) error
|
||||
type CreateFunc func(genericapirequest.Context, runtime.Object) error
|
||||
type SetRVFunc func(uint64)
|
||||
type UpdateFunc func(runtime.Object) runtime.Object
|
||||
|
||||
@@ -223,7 +224,7 @@ func (t *Tester) TestWatch(
|
||||
// =============================================================================
|
||||
// Creation tests.
|
||||
|
||||
func (t *Tester) delete(ctx api.Context, obj runtime.Object) error {
|
||||
func (t *Tester) delete(ctx genericapirequest.Context, obj runtime.Object) error {
|
||||
objectMeta, err := api.ObjectMetaFor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -332,7 +333,7 @@ func (t *Tester) testCreateHasMetadata(valid runtime.Object) {
|
||||
|
||||
func (t *Tester) testCreateIgnoresContextNamespace(valid runtime.Object) {
|
||||
// Ignore non-empty namespace in context
|
||||
ctx := api.WithNamespace(api.NewContext(), "not-default2")
|
||||
ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), "not-default2")
|
||||
|
||||
// Ideally, we'd get an error back here, but at least verify the namespace wasn't persisted
|
||||
created, err := t.storage.(rest.Creater).Create(ctx, copyOrDie(valid))
|
||||
@@ -351,7 +352,7 @@ func (t *Tester) testCreateIgnoresMismatchedNamespace(valid runtime.Object) {
|
||||
|
||||
// Ignore non-empty namespace in object meta
|
||||
objectMeta.Namespace = "not-default"
|
||||
ctx := api.WithNamespace(api.NewContext(), "not-default2")
|
||||
ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), "not-default2")
|
||||
|
||||
// Ideally, we'd get an error back here, but at least verify the namespace wasn't persisted
|
||||
created, err := t.storage.(rest.Creater).Create(ctx, copyOrDie(valid))
|
||||
@@ -580,7 +581,7 @@ func (t *Tester) testUpdateRetrievesOldObject(obj runtime.Object, createFn Creat
|
||||
// Make sure a custom transform is called, and sees the expected updatedObject and oldObject
|
||||
// This tests the mechanism used to pass the old and new object to admission
|
||||
calledUpdatedObject := 0
|
||||
noopTransform := func(_ api.Context, updatedObject runtime.Object, oldObject runtime.Object) (runtime.Object, error) {
|
||||
noopTransform := func(_ genericapirequest.Context, updatedObject runtime.Object, oldObject runtime.Object) (runtime.Object, error) {
|
||||
if !reflect.DeepEqual(storedFoo, oldObject) {
|
||||
t.Errorf("Expected\n\t%#v\ngot\n\t%#v", storedFoo, oldObject)
|
||||
}
|
||||
@@ -622,7 +623,7 @@ func (t *Tester) testUpdatePropagatesUpdatedObjectError(obj runtime.Object, crea
|
||||
|
||||
// Make sure our transform is called, and sees the expected updatedObject and oldObject
|
||||
propagateErr := fmt.Errorf("custom updated object error for %v", foo)
|
||||
noopTransform := func(_ api.Context, updatedObject runtime.Object, oldObject runtime.Object) (runtime.Object, error) {
|
||||
noopTransform := func(_ genericapirequest.Context, updatedObject runtime.Object, oldObject runtime.Object) (runtime.Object, error) {
|
||||
return nil, propagateErr
|
||||
}
|
||||
|
||||
@@ -1029,15 +1030,15 @@ func (t *Tester) testGetDifferentNamespace(obj runtime.Object) {
|
||||
objMeta := t.getObjectMetaOrFail(obj)
|
||||
objMeta.Name = t.namer(5)
|
||||
|
||||
ctx1 := api.WithNamespace(api.NewContext(), "bar3")
|
||||
objMeta.Namespace = api.NamespaceValue(ctx1)
|
||||
ctx1 := genericapirequest.WithNamespace(genericapirequest.NewContext(), "bar3")
|
||||
objMeta.Namespace = genericapirequest.NamespaceValue(ctx1)
|
||||
_, err := t.storage.(rest.Creater).Create(ctx1, obj)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
ctx2 := api.WithNamespace(api.NewContext(), "bar4")
|
||||
objMeta.Namespace = api.NamespaceValue(ctx2)
|
||||
ctx2 := genericapirequest.WithNamespace(genericapirequest.NewContext(), "bar4")
|
||||
objMeta.Namespace = genericapirequest.NamespaceValue(ctx2)
|
||||
_, err = t.storage.(rest.Creater).Create(ctx2, obj)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
@@ -1051,8 +1052,8 @@ func (t *Tester) testGetDifferentNamespace(obj runtime.Object) {
|
||||
if got1Meta.Name != objMeta.Name {
|
||||
t.Errorf("unexpected name of object: %#v, expected: %s", got1, objMeta.Name)
|
||||
}
|
||||
if got1Meta.Namespace != api.NamespaceValue(ctx1) {
|
||||
t.Errorf("unexpected namespace of object: %#v, expected: %s", got1, api.NamespaceValue(ctx1))
|
||||
if got1Meta.Namespace != genericapirequest.NamespaceValue(ctx1) {
|
||||
t.Errorf("unexpected namespace of object: %#v, expected: %s", got1, genericapirequest.NamespaceValue(ctx1))
|
||||
}
|
||||
|
||||
got2, err := t.storage.(rest.Getter).Get(ctx2, objMeta.Name, &metav1.GetOptions{})
|
||||
@@ -1063,8 +1064,8 @@ func (t *Tester) testGetDifferentNamespace(obj runtime.Object) {
|
||||
if got2Meta.Name != objMeta.Name {
|
||||
t.Errorf("unexpected name of object: %#v, expected: %s", got2, objMeta.Name)
|
||||
}
|
||||
if got2Meta.Namespace != api.NamespaceValue(ctx2) {
|
||||
t.Errorf("unexpected namespace of object: %#v, expected: %s", got2, api.NamespaceValue(ctx2))
|
||||
if got2Meta.Namespace != genericapirequest.NamespaceValue(ctx2) {
|
||||
t.Errorf("unexpected namespace of object: %#v, expected: %s", got2, genericapirequest.NamespaceValue(ctx2))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1090,11 +1091,11 @@ func (t *Tester) testGetFound(obj runtime.Object) {
|
||||
}
|
||||
|
||||
func (t *Tester) testGetMimatchedNamespace(obj runtime.Object) {
|
||||
ctx1 := api.WithNamespace(api.NewContext(), "bar1")
|
||||
ctx2 := api.WithNamespace(api.NewContext(), "bar2")
|
||||
ctx1 := genericapirequest.WithNamespace(genericapirequest.NewContext(), "bar1")
|
||||
ctx2 := genericapirequest.WithNamespace(genericapirequest.NewContext(), "bar2")
|
||||
objMeta := t.getObjectMetaOrFail(obj)
|
||||
objMeta.Name = t.namer(4)
|
||||
objMeta.Namespace = api.NamespaceValue(ctx1)
|
||||
objMeta.Namespace = genericapirequest.NamespaceValue(ctx1)
|
||||
_, err := t.storage.(rest.Creater).Create(ctx1, obj)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
@@ -1181,7 +1182,7 @@ func (t *Tester) testListMatchLabels(obj runtime.Object, assignFn AssignFunc) {
|
||||
foo4 := copyOrDie(obj)
|
||||
foo4Meta := t.getObjectMetaOrFail(foo4)
|
||||
foo4Meta.Name = "foo4"
|
||||
foo4Meta.Namespace = api.NamespaceValue(ctx)
|
||||
foo4Meta.Namespace = genericapirequest.NamespaceValue(ctx)
|
||||
foo4Meta.Labels = testLabels
|
||||
|
||||
objs := ([]runtime.Object{foo3, foo4})
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/api/errors"
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/api/validation"
|
||||
genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/util/validation/field"
|
||||
)
|
||||
@@ -41,11 +42,11 @@ type RESTUpdateStrategy interface {
|
||||
// the object. For example: remove fields that are not to be persisted,
|
||||
// sort order-insensitive list fields, etc. This should not remove fields
|
||||
// whose presence would be considered a validation error.
|
||||
PrepareForUpdate(ctx api.Context, obj, old runtime.Object)
|
||||
PrepareForUpdate(ctx genericapirequest.Context, obj, old runtime.Object)
|
||||
// ValidateUpdate is invoked after default fields in the object have been
|
||||
// filled in before the object is persisted. This method should not mutate
|
||||
// the object.
|
||||
ValidateUpdate(ctx api.Context, obj, old runtime.Object) field.ErrorList
|
||||
ValidateUpdate(ctx genericapirequest.Context, obj, old runtime.Object) field.ErrorList
|
||||
// Canonicalize is invoked after validation has succeeded but before the
|
||||
// object has been persisted. This method may mutate the object.
|
||||
Canonicalize(obj runtime.Object)
|
||||
@@ -74,7 +75,7 @@ func validateCommonFields(obj, old runtime.Object) (field.ErrorList, error) {
|
||||
// BeforeUpdate ensures that common operations for all resources are performed on update. It only returns
|
||||
// errors that can be converted to api.Status. It will invoke update validation with the provided existing
|
||||
// and updated objects.
|
||||
func BeforeUpdate(strategy RESTUpdateStrategy, ctx api.Context, obj, old runtime.Object) error {
|
||||
func BeforeUpdate(strategy RESTUpdateStrategy, ctx genericapirequest.Context, obj, old runtime.Object) error {
|
||||
objectMeta, kind, kerr := objectMetaAndKind(strategy, obj)
|
||||
if kerr != nil {
|
||||
return kerr
|
||||
@@ -115,7 +116,7 @@ func BeforeUpdate(strategy RESTUpdateStrategy, ctx api.Context, obj, old runtime
|
||||
}
|
||||
|
||||
// TransformFunc is a function to transform and return newObj
|
||||
type TransformFunc func(ctx api.Context, newObj runtime.Object, oldObj runtime.Object) (transformedNewObj runtime.Object, err error)
|
||||
type TransformFunc func(ctx genericapirequest.Context, newObj runtime.Object, oldObj runtime.Object) (transformedNewObj runtime.Object, err error)
|
||||
|
||||
// defaultUpdatedObjectInfo implements UpdatedObjectInfo
|
||||
type defaultUpdatedObjectInfo struct {
|
||||
@@ -157,7 +158,7 @@ func (i *defaultUpdatedObjectInfo) Preconditions() *api.Preconditions {
|
||||
|
||||
// UpdatedObject satisfies the UpdatedObjectInfo interface.
|
||||
// It returns a copy of the held obj, passed through any configured transformers.
|
||||
func (i *defaultUpdatedObjectInfo) UpdatedObject(ctx api.Context, oldObj runtime.Object) (runtime.Object, error) {
|
||||
func (i *defaultUpdatedObjectInfo) UpdatedObject(ctx genericapirequest.Context, oldObj runtime.Object) (runtime.Object, error) {
|
||||
var err error
|
||||
// Start with the configured object
|
||||
newObj := i.obj
|
||||
@@ -207,7 +208,7 @@ func (i *wrappedUpdatedObjectInfo) Preconditions() *api.Preconditions {
|
||||
|
||||
// UpdatedObject satisfies the UpdatedObjectInfo interface.
|
||||
// It delegates to the wrapped objInfo and passes the result through any configured transformers.
|
||||
func (i *wrappedUpdatedObjectInfo) UpdatedObject(ctx api.Context, oldObj runtime.Object) (runtime.Object, error) {
|
||||
func (i *wrappedUpdatedObjectInfo) UpdatedObject(ctx genericapirequest.Context, oldObj runtime.Object) (runtime.Object, error) {
|
||||
newObj, err := i.objInfo.UpdatedObject(ctx, oldObj)
|
||||
if err != nil {
|
||||
return newObj, err
|
||||
|
||||
Reference in New Issue
Block a user