diff --git a/pkg/endpoints/handlers/namer.go b/pkg/endpoints/handlers/namer.go index 019e37e25..88c0dc44c 100644 --- a/pkg/endpoints/handlers/namer.go +++ b/pkg/endpoints/handlers/namer.go @@ -45,7 +45,7 @@ type ScopeNamer interface { SetSelfLink(obj runtime.Object, url string) error // GenerateLink creates an encoded URI for a given runtime object that represents the canonical path // and query. - GenerateLink(req *http.Request, obj runtime.Object) (uri string, err error) + GenerateLink(ctx request.Context, obj runtime.Object) (uri string, err error) // GenerateListLink creates an encoded URI for a list that represents the canonical path and query. GenerateListLink(req *http.Request) (uri string, err error) } @@ -90,8 +90,8 @@ func (n ContextBasedNaming) Name(req *http.Request) (namespace, name string, err return ns, requestInfo.Name, nil } -func (n ContextBasedNaming) GenerateLink(req *http.Request, obj runtime.Object) (uri string, err error) { - requestInfo, ok := request.RequestInfoFrom(n.GetContext(req)) +func (n ContextBasedNaming) GenerateLink(ctx request.Context, obj runtime.Object) (uri string, err error) { + requestInfo, ok := request.RequestInfoFrom(ctx) if !ok { return "", fmt.Errorf("missing requestInfo") } diff --git a/pkg/endpoints/handlers/rest.go b/pkg/endpoints/handlers/rest.go index da466c2fc..3535769fb 100644 --- a/pkg/endpoints/handlers/rest.go +++ b/pkg/endpoints/handlers/rest.go @@ -102,7 +102,7 @@ func getResourceHandler(scope RequestScope, getter getterFunc) http.HandlerFunc scope.err(err, w, req) return } - if err := setSelfLink(result, req, scope.Namer); err != nil { + if err := setSelfLink(result, ctx, scope.Namer); err != nil { scope.err(err, w, req) return } @@ -325,7 +325,7 @@ func ListResource(r rest.Lister, rw rest.Watcher, scope RequestScope, forceWatch return } trace.Step("Listing from storage done") - numberOfItems, err := setListSelfLink(result, req, scope.Namer) + numberOfItems, err := setListSelfLink(result, ctx, req, scope.Namer) if err != nil { scope.err(err, w, req) return @@ -423,7 +423,7 @@ func createHandler(r rest.NamedCreater, scope RequestScope, typer runtime.Object } trace.Step("Object stored in database") - if err := setSelfLink(result, req, scope.Namer); err != nil { + if err := setSelfLink(result, ctx, scope.Namer); err != nil { scope.err(err, w, req) return } @@ -516,7 +516,7 @@ func PatchResource(r rest.Patcher, scope RequestScope, admit admission.Interface return } - if err := setSelfLink(result, req, scope.Namer); err != nil { + if err := setSelfLink(result, ctx, scope.Namer); err != nil { scope.err(err, w, req) return } @@ -833,7 +833,7 @@ func UpdateResource(r rest.Updater, scope RequestScope, typer runtime.ObjectType } trace.Step("Object stored in database") - if err := setSelfLink(result, req, scope.Namer); err != nil { + if err := setSelfLink(result, ctx, scope.Namer); err != nil { scope.err(err, w, req) return } @@ -947,7 +947,7 @@ func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope RequestSco } else { // when a non-status response is returned, set the self link if _, ok := result.(*metav1.Status); !ok { - if err := setSelfLink(result, req, scope.Namer); err != nil { + if err := setSelfLink(result, ctx, scope.Namer); err != nil { scope.err(err, w, req) return } @@ -1049,7 +1049,7 @@ func DeleteCollection(r rest.CollectionDeleter, checkBody bool, scope RequestSco } else { // when a non-status response is returned, set the self link if _, ok := result.(*metav1.Status); !ok { - if _, err := setListSelfLink(result, req, scope.Namer); err != nil { + if _, err := setListSelfLink(result, ctx, req, scope.Namer); err != nil { scope.err(err, w, req) return } @@ -1117,9 +1117,9 @@ func transformDecodeError(typer runtime.ObjectTyper, baseErr error, into runtime // setSelfLink sets the self link of an object (or the child items in a list) to the base URL of the request // plus the path and query generated by the provided linkFunc -func setSelfLink(obj runtime.Object, req *http.Request, namer ScopeNamer) error { +func setSelfLink(obj runtime.Object, ctx request.Context, namer ScopeNamer) error { // TODO: SelfLink generation should return a full URL? - uri, err := namer.GenerateLink(req, obj) + uri, err := namer.GenerateLink(ctx, obj) if err != nil { return nil } @@ -1164,7 +1164,7 @@ func checkName(obj runtime.Object, name, namespace string, namer ScopeNamer) err // setListSelfLink sets the self link of a list to the base URL, then sets the self links // on all child objects returned. Returns the number of items in the list. -func setListSelfLink(obj runtime.Object, req *http.Request, namer ScopeNamer) (int, error) { +func setListSelfLink(obj runtime.Object, ctx request.Context, req *http.Request, namer ScopeNamer) (int, error) { if !meta.IsListType(obj) { return 0, nil } @@ -1180,7 +1180,7 @@ func setListSelfLink(obj runtime.Object, req *http.Request, namer ScopeNamer) (i count := 0 err = meta.EachListItem(obj, func(obj runtime.Object) error { count++ - return setSelfLink(obj, req, namer) + return setSelfLink(obj, ctx, namer) }) return count, err } diff --git a/pkg/endpoints/handlers/rest_test.go b/pkg/endpoints/handlers/rest_test.go index 3d6aad640..2c6c9eb09 100644 --- a/pkg/endpoints/handlers/rest_test.go +++ b/pkg/endpoints/handlers/rest_test.go @@ -160,11 +160,11 @@ func (p *testNamer) SetSelfLink(obj runtime.Object, url string) error { } // GenerateLink creates a path and query for a given runtime object that represents the canonical path. -func (p *testNamer) GenerateLink(req *http.Request, obj runtime.Object) (uri string, err error) { +func (p *testNamer) GenerateLink(ctx request.Context, obj runtime.Object) (uri string, err error) { return "", errors.New("not implemented") } -// GenerateLink creates a path and query for a list that represents the canonical path. +// GenerateListLink creates a path and query for a list that represents the canonical path. func (p *testNamer) GenerateListLink(req *http.Request) (uri string, err error) { return "", errors.New("not implemented") } diff --git a/pkg/endpoints/handlers/watch.go b/pkg/endpoints/handlers/watch.go index 077169a9a..2a8d81e19 100755 --- a/pkg/endpoints/handlers/watch.go +++ b/pkg/endpoints/handlers/watch.go @@ -30,6 +30,7 @@ import ( utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/watch" "k8s.io/apiserver/pkg/endpoints/handlers/negotiation" + "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/server/httplog" "k8s.io/apiserver/pkg/util/wsstream" @@ -88,6 +89,14 @@ func serveWatch(watcher watch.Interface, scope RequestScope, req *http.Request, mediaType += ";stream=watch" } + namespace, _, err := scope.Namer.Name(req) + if err != nil { + scope.err(fmt.Errorf("unexpected error from Namer.Name: %v", err), w, req) + return + } + ctx := scope.ContextFunc(req) + ctx = request.WithNamespace(ctx, namespace) + server := &WatchServer{ Watching: watcher, Scope: scope, @@ -98,7 +107,7 @@ func serveWatch(watcher watch.Interface, scope RequestScope, req *http.Request, Encoder: encoder, EmbeddedEncoder: embeddedEncoder, Fixup: func(obj runtime.Object) { - if err := setSelfLink(obj, req, scope.Namer); err != nil { + if err := setSelfLink(obj, ctx, scope.Namer); err != nil { utilruntime.HandleError(fmt.Errorf("failed to set link for object %v: %v", reflect.TypeOf(obj), err)) } },