diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go index db9b43b2694..a06070c5724 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go @@ -113,13 +113,13 @@ type crdInfo struct { storages map[string]customresource.CustomResourceStorage // Request scope per version - requestScopes map[string]handlers.RequestScope + requestScopes map[string]*handlers.RequestScope // Scale scope per version - scaleRequestScopes map[string]handlers.RequestScope + scaleRequestScopes map[string]*handlers.RequestScope // Status scope per version - statusRequestScopes map[string]handlers.RequestScope + statusRequestScopes map[string]*handlers.RequestScope // storageVersion is the CRD version used when storing the object in etcd. storageVersion string @@ -444,10 +444,10 @@ func (r *crdHandler) getOrCreateServingInfoFor(crd *apiextensions.CustomResource } // Scope/Storages per version. - requestScopes := map[string]handlers.RequestScope{} + requestScopes := map[string]*handlers.RequestScope{} storages := map[string]customresource.CustomResourceStorage{} - statusScopes := map[string]handlers.RequestScope{} - scaleScopes := map[string]handlers.RequestScope{} + statusScopes := map[string]*handlers.RequestScope{} + scaleScopes := map[string]*handlers.RequestScope{} for _, v := range crd.Spec.Versions { safeConverter, unsafeConverter, err := r.converterFactory.NewConverter(crd) @@ -548,7 +548,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(crd *apiextensions.CustomResource clusterScoped := crd.Spec.Scope == apiextensions.ClusterScoped - requestScopes[v.Name] = handlers.RequestScope{ + requestScopes[v.Name] = &handlers.RequestScope{ Namer: handlers.ContextBasedNaming{ SelfLinker: meta.NewAccessor(), ClusterScoped: clusterScoped, @@ -576,19 +576,19 @@ func (r *crdHandler) getOrCreateServingInfoFor(crd *apiextensions.CustomResource Authorizer: r.authorizer, } if utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) { - reqScope := requestScopes[v.Name] + reqScope := *requestScopes[v.Name] reqScope.FieldManager = fieldmanager.NewCRDFieldManager( reqScope.Convertor, reqScope.Defaulter, reqScope.Kind.GroupVersion(), reqScope.HubGroupVersion, ) - requestScopes[v.Name] = reqScope + requestScopes[v.Name] = &reqScope } // override scaleSpec subresource values // shallow copy - scaleScope := requestScopes[v.Name] + scaleScope := *requestScopes[v.Name] scaleConverter := scale.NewScaleConverter() scaleScope.Subresource = "scale" scaleScope.Serializer = serializer.NewCodecFactory(scaleConverter.Scheme()) @@ -599,11 +599,11 @@ func (r *crdHandler) getOrCreateServingInfoFor(crd *apiextensions.CustomResource SelfLinkPathPrefix: selfLinkPrefix, SelfLinkPathSuffix: "/scale", } - scaleScopes[v.Name] = scaleScope + scaleScopes[v.Name] = &scaleScope // override status subresource values // shallow copy - statusScope := requestScopes[v.Name] + statusScope := *requestScopes[v.Name] statusScope.Subresource = "status" statusScope.Namer = handlers.ContextBasedNaming{ SelfLinker: meta.NewAccessor(), @@ -611,7 +611,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(crd *apiextensions.CustomResource SelfLinkPathPrefix: selfLinkPrefix, SelfLinkPathSuffix: "/status", } - statusScopes[v.Name] = statusScope + statusScopes[v.Name] = &statusScope } ret := &crdInfo{ diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/create.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/create.go index 80e781fb887..40c53efae33 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/create.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/create.go @@ -43,7 +43,7 @@ import ( utiltrace "k8s.io/utils/trace" ) -func createHandler(r rest.NamedCreater, scope RequestScope, admit admission.Interface, includeName bool) http.HandlerFunc { +func createHandler(r rest.NamedCreater, scope *RequestScope, admit admission.Interface, includeName bool) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { // For performance tracking purposes. trace := utiltrace.New("Create " + req.URL.Path) @@ -73,7 +73,7 @@ func createHandler(r rest.NamedCreater, scope RequestScope, admit admission.Inte ctx := req.Context() ctx = request.WithNamespace(ctx, namespace) - outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, &scope) + outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, scope) if err != nil { scope.err(err, w, req) return @@ -130,7 +130,7 @@ func createHandler(r rest.NamedCreater, scope RequestScope, admit admission.Inte userInfo, _ := request.UserFrom(ctx) admissionAttributes := admission.NewAttributesRecord(obj, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Create, dryrun.IsDryRun(options.DryRun), userInfo) if mutatingAdmission, ok := admit.(admission.MutationInterface); ok && mutatingAdmission.Handles(admission.Create) { - err = mutatingAdmission.Admit(admissionAttributes, &scope) + err = mutatingAdmission.Admit(admissionAttributes, scope) if err != nil { scope.err(err, w, req) return @@ -157,7 +157,7 @@ func createHandler(r rest.NamedCreater, scope RequestScope, admit admission.Inte ctx, name, obj, - rest.AdmissionToValidateObjectFunc(admit, admissionAttributes, &scope), + rest.AdmissionToValidateObjectFunc(admit, admissionAttributes, scope), options, ) }) @@ -173,18 +173,17 @@ func createHandler(r rest.NamedCreater, scope RequestScope, admit admission.Inte status.Code = int32(code) } - scope.Trace = trace - transformResponseObject(ctx, scope, req, w, code, outputMediaType, result) + transformResponseObject(ctx, scope, trace, req, w, code, outputMediaType, result) } } // CreateNamedResource returns a function that will handle a resource creation with name. -func CreateNamedResource(r rest.NamedCreater, scope RequestScope, admission admission.Interface) http.HandlerFunc { +func CreateNamedResource(r rest.NamedCreater, scope *RequestScope, admission admission.Interface) http.HandlerFunc { return createHandler(r, scope, admission, true) } // CreateResource returns a function that will handle a resource creation. -func CreateResource(r rest.Creater, scope RequestScope, admission admission.Interface) http.HandlerFunc { +func CreateResource(r rest.Creater, scope *RequestScope, admission admission.Interface) http.HandlerFunc { return createHandler(&namedCreaterAdapter{r}, scope, admission, false) } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/delete.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/delete.go index a37c7f8d525..8f1d1d21793 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/delete.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/delete.go @@ -40,7 +40,7 @@ import ( // DeleteResource returns a function that will handle a resource deletion // TODO admission here becomes solely validating admission -func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope RequestScope, admit admission.Interface) http.HandlerFunc { +func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope *RequestScope, admit admission.Interface) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { // For performance tracking purposes. trace := utiltrace.New("Delete " + req.URL.Path) @@ -64,7 +64,7 @@ func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope RequestSco ae := request.AuditEventFrom(ctx) admit = admission.WithAudit(admit, ae) - outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, &scope) + outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, scope) if err != nil { scope.err(err, w, req) return @@ -119,13 +119,13 @@ func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope RequestSco userInfo, _ := request.UserFrom(ctx) attrs := admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Delete, dryrun.IsDryRun(options.DryRun), userInfo) if mutatingAdmission, ok := admit.(admission.MutationInterface); ok { - if err := mutatingAdmission.Admit(attrs, &scope); err != nil { + if err := mutatingAdmission.Admit(attrs, scope); err != nil { scope.err(err, w, req) return } } if validatingAdmission, ok := admit.(admission.ValidationInterface); ok { - if err := validatingAdmission.Validate(attrs, &scope); err != nil { + if err := validatingAdmission.Validate(attrs, scope); err != nil { scope.err(err, w, req) return } @@ -168,13 +168,12 @@ func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope RequestSco } } - scope.Trace = trace - transformResponseObject(ctx, scope, req, w, status, outputMediaType, result) + transformResponseObject(ctx, scope, trace, req, w, status, outputMediaType, result) } } // DeleteCollection returns a function that will handle a collection deletion -func DeleteCollection(r rest.CollectionDeleter, checkBody bool, scope RequestScope, admit admission.Interface) http.HandlerFunc { +func DeleteCollection(r rest.CollectionDeleter, checkBody bool, scope *RequestScope, admit admission.Interface) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { trace := utiltrace.New("Delete " + req.URL.Path) defer trace.LogIfLong(500 * time.Millisecond) @@ -197,7 +196,7 @@ func DeleteCollection(r rest.CollectionDeleter, checkBody bool, scope RequestSco ctx = request.WithNamespace(ctx, namespace) ae := request.AuditEventFrom(ctx) - outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, &scope) + outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, scope) if err != nil { scope.err(err, w, req) return @@ -269,7 +268,7 @@ func DeleteCollection(r rest.CollectionDeleter, checkBody bool, scope RequestSco userInfo, _ := request.UserFrom(ctx) attrs := admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, "", scope.Resource, scope.Subresource, admission.Delete, dryrun.IsDryRun(options.DryRun), userInfo) if mutatingAdmission, ok := admit.(admission.MutationInterface); ok { - err = mutatingAdmission.Admit(attrs, &scope) + err = mutatingAdmission.Admit(attrs, scope) if err != nil { scope.err(err, w, req) return @@ -277,7 +276,7 @@ func DeleteCollection(r rest.CollectionDeleter, checkBody bool, scope RequestSco } if validatingAdmission, ok := admit.(admission.ValidationInterface); ok { - err = validatingAdmission.Validate(attrs, &scope) + err = validatingAdmission.Validate(attrs, scope) if err != nil { scope.err(err, w, req) return @@ -305,7 +304,6 @@ func DeleteCollection(r rest.CollectionDeleter, checkBody bool, scope RequestSco } } - scope.Trace = trace - transformResponseObject(ctx, scope, req, w, http.StatusOK, outputMediaType, result) + transformResponseObject(ctx, scope, trace, req, w, http.StatusOK, outputMediaType, result) } } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/get.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/get.go index efb839657b7..d6757730bc4 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/get.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/get.go @@ -46,7 +46,7 @@ type getterFunc func(ctx context.Context, name string, req *http.Request, trace // getResourceHandler is an HTTP handler function for get requests. It delegates to the // passed-in getterFunc to perform the actual get. -func getResourceHandler(scope RequestScope, getter getterFunc) http.HandlerFunc { +func getResourceHandler(scope *RequestScope, getter getterFunc) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { trace := utiltrace.New("Get " + req.URL.Path) defer trace.LogIfLong(500 * time.Millisecond) @@ -59,7 +59,7 @@ func getResourceHandler(scope RequestScope, getter getterFunc) http.HandlerFunc ctx := req.Context() ctx = request.WithNamespace(ctx, namespace) - outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, &scope) + outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, scope) if err != nil { scope.err(err, w, req) return @@ -72,14 +72,13 @@ func getResourceHandler(scope RequestScope, getter getterFunc) http.HandlerFunc } trace.Step("About to write a response") - scope.Trace = trace - transformResponseObject(ctx, scope, req, w, http.StatusOK, outputMediaType, result) + transformResponseObject(ctx, scope, trace, req, w, http.StatusOK, outputMediaType, result) trace.Step("Transformed response object") } } // GetResource returns a function that handles retrieving a single resource from a rest.Storage object. -func GetResource(r rest.Getter, e rest.Exporter, scope RequestScope) http.HandlerFunc { +func GetResource(r rest.Getter, e rest.Exporter, scope *RequestScope) http.HandlerFunc { return getResourceHandler(scope, func(ctx context.Context, name string, req *http.Request, trace *utiltrace.Trace) (runtime.Object, error) { // check for export @@ -109,7 +108,7 @@ func GetResource(r rest.Getter, e rest.Exporter, scope RequestScope) http.Handle } // GetResourceWithOptions returns a function that handles retrieving a single resource from a rest.Storage object. -func GetResourceWithOptions(r rest.GetterWithOptions, scope RequestScope, isSubresource bool) http.HandlerFunc { +func GetResourceWithOptions(r rest.GetterWithOptions, scope *RequestScope, isSubresource bool) http.HandlerFunc { return getResourceHandler(scope, func(ctx context.Context, name string, req *http.Request, trace *utiltrace.Trace) (runtime.Object, error) { opts, subpath, subpathKey := r.NewGetOptions() @@ -126,7 +125,7 @@ func GetResourceWithOptions(r rest.GetterWithOptions, scope RequestScope, isSubr } // getRequestOptions parses out options and can include path information. The path information shouldn't include the subresource. -func getRequestOptions(req *http.Request, scope RequestScope, into runtime.Object, subpath bool, subpathKey string, isSubresource bool) error { +func getRequestOptions(req *http.Request, scope *RequestScope, into runtime.Object, subpath bool, subpathKey string, isSubresource bool) error { if into == nil { return nil } @@ -163,7 +162,7 @@ func getRequestOptions(req *http.Request, scope RequestScope, into runtime.Objec return scope.ParameterCodec.DecodeParameters(query, scope.Kind.GroupVersion(), into) } -func ListResource(r rest.Lister, rw rest.Watcher, scope RequestScope, forceWatch bool, minRequestTimeout time.Duration) http.HandlerFunc { +func ListResource(r rest.Lister, rw rest.Watcher, scope *RequestScope, forceWatch bool, minRequestTimeout time.Duration) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { // For performance tracking purposes. trace := utiltrace.New("List " + req.URL.Path) @@ -185,7 +184,7 @@ func ListResource(r rest.Lister, rw rest.Watcher, scope RequestScope, forceWatch ctx := req.Context() ctx = request.WithNamespace(ctx, namespace) - outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, &scope) + outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, scope) if err != nil { scope.err(err, w, req) return @@ -272,8 +271,7 @@ func ListResource(r rest.Lister, rw rest.Watcher, scope RequestScope, forceWatch } trace.Step("Listing from storage done") - scope.Trace = trace - transformResponseObject(ctx, scope, req, w, http.StatusOK, outputMediaType, result) + transformResponseObject(ctx, scope, trace, req, w, http.StatusOK, outputMediaType, result) trace.Step(fmt.Sprintf("Writing http response done (%d items)", meta.LenList(result))) } } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/patch.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/patch.go index bc06b7acf5c..23644bd3409 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/patch.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/patch.go @@ -55,7 +55,7 @@ const ( ) // PatchResource returns a function that will handle a resource patch. -func PatchResource(r rest.Patcher, scope RequestScope, admit admission.Interface, patchTypes []string) http.HandlerFunc { +func PatchResource(r rest.Patcher, scope *RequestScope, admit admission.Interface, patchTypes []string) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { // For performance tracking purposes. trace := utiltrace.New("Patch " + req.URL.Path) @@ -95,7 +95,7 @@ func PatchResource(r rest.Patcher, scope RequestScope, admit admission.Interface ctx := req.Context() ctx = request.WithNamespace(ctx, namespace) - outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, &scope) + outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, scope) if err != nil { scope.err(err, w, req) return @@ -191,12 +191,12 @@ func PatchResource(r rest.Patcher, scope RequestScope, admit admission.Interface subresource: scope.Subresource, dryRun: dryrun.IsDryRun(options.DryRun), - objectInterfaces: &scope, + objectInterfaces: scope, hubGroupVersion: scope.HubGroupVersion, - createValidation: withAuthorization(rest.AdmissionToValidateObjectFunc(admit, staticCreateAttributes, &scope), scope.Authorizer, createAuthorizerAttributes), - updateValidation: rest.AdmissionToValidateObjectUpdateFunc(admit, staticUpdateAttributes, &scope), + createValidation: withAuthorization(rest.AdmissionToValidateObjectFunc(admit, staticCreateAttributes, scope), scope.Authorizer, createAuthorizerAttributes), + updateValidation: rest.AdmissionToValidateObjectUpdateFunc(admit, staticUpdateAttributes, scope), admissionCheck: mutatingAdmission, codec: codec, @@ -235,8 +235,7 @@ func PatchResource(r rest.Patcher, scope RequestScope, admit admission.Interface if wasCreated { status = http.StatusCreated } - scope.Trace = trace - transformResponseObject(ctx, scope, req, w, status, outputMediaType, result) + transformResponseObject(ctx, scope, trace, req, w, status, outputMediaType, result) } } @@ -517,7 +516,7 @@ func (p *patcher) applyAdmission(ctx context.Context, patchedObject runtime.Obje } // patchResource divides PatchResource for easier unit testing -func (p *patcher) patchResource(ctx context.Context, scope RequestScope) (runtime.Object, bool, error) { +func (p *patcher) patchResource(ctx context.Context, scope *RequestScope) (runtime.Object, bool, error) { p.namespace = request.NamespaceValue(ctx) switch p.patchType { case types.JSONPatchType, types.MergePatchType: diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/response.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/response.go index c9e0d23ff63..0c00fbd39d0 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/response.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/response.go @@ -31,12 +31,13 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apiserver/pkg/endpoints/handlers/negotiation" "k8s.io/apiserver/pkg/endpoints/handlers/responsewriters" + utiltrace "k8s.io/utils/trace" ) // transformObject takes the object as returned by storage and ensures it is in // the client's desired form, as well as ensuring any API level fields like self-link // are properly set. -func transformObject(ctx context.Context, obj runtime.Object, opts interface{}, mediaType negotiation.MediaTypeOptions, scope RequestScope, req *http.Request) (runtime.Object, error) { +func transformObject(ctx context.Context, obj runtime.Object, opts interface{}, mediaType negotiation.MediaTypeOptions, scope *RequestScope, req *http.Request) (runtime.Object, error) { if _, ok := obj.(*metav1.Status); ok { return obj, nil } @@ -104,7 +105,7 @@ func targetEncodingForTransform(scope *RequestScope, mediaType negotiation.Media // transformResponseObject takes an object loaded from storage and performs any necessary transformations. // Will write the complete response object. -func transformResponseObject(ctx context.Context, scope RequestScope, req *http.Request, w http.ResponseWriter, statusCode int, mediaType negotiation.MediaTypeOptions, result runtime.Object) { +func transformResponseObject(ctx context.Context, scope *RequestScope, trace *utiltrace.Trace, req *http.Request, w http.ResponseWriter, statusCode int, mediaType negotiation.MediaTypeOptions, result runtime.Object) { options, err := optionsForTransform(mediaType, req) if err != nil { scope.err(err, w, req) @@ -115,8 +116,8 @@ func transformResponseObject(ctx context.Context, scope RequestScope, req *http. scope.err(err, w, req) return } - kind, serializer, _ := targetEncodingForTransform(&scope, mediaType, req) - responsewriters.WriteObjectNegotiated(serializer, &scope, kind.GroupVersion(), w, req, statusCode, obj) + kind, serializer, _ := targetEncodingForTransform(scope, mediaType, req) + responsewriters.WriteObjectNegotiated(serializer, scope, kind.GroupVersion(), w, req, statusCode, obj) } // errNotAcceptable indicates Accept negotiation has failed @@ -141,7 +142,7 @@ func (e errNotAcceptable) Status() metav1.Status { } } -func asV1Beta1Table(ctx context.Context, result runtime.Object, opts *metav1beta1.TableOptions, scope RequestScope) (runtime.Object, error) { +func asV1Beta1Table(ctx context.Context, result runtime.Object, opts *metav1beta1.TableOptions, scope *RequestScope) (runtime.Object, error) { table, err := scope.TableConvertor.ConvertToTable(ctx, result, opts) if err != nil { return nil, err diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest.go index c184ce5f99c..3728a3b771d 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest.go @@ -42,7 +42,6 @@ import ( "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/registry/rest" "k8s.io/klog" - utiltrace "k8s.io/utils/trace" ) // RequestScope encapsulates common fields across all RESTful handler methods. @@ -58,7 +57,6 @@ type RequestScope struct { Typer runtime.ObjectTyper UnsafeConvertor runtime.ObjectConvertor Authorizer authorizer.Authorizer - Trace *utiltrace.Trace TableConvertor rest.TableConvertor FieldManager *fieldmanager.FieldManager @@ -113,7 +111,7 @@ func (r *RequestScope) GetObjectDefaulter() runtime.ObjectDefaulter { return r.D func (r *RequestScope) GetObjectConvertor() runtime.ObjectConvertor { return r.Convertor } // ConnectResource returns a function that handles a connect request on a rest.Storage object. -func ConnectResource(connecter rest.Connecter, scope RequestScope, admit admission.Interface, restPath string, isSubresource bool) http.HandlerFunc { +func ConnectResource(connecter rest.Connecter, scope *RequestScope, admit admission.Interface, restPath string, isSubresource bool) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { if isDryRun(req.URL) { scope.err(errors.NewBadRequest("dryRun is not supported"), w, req) @@ -140,14 +138,14 @@ func ConnectResource(connecter rest.Connecter, scope RequestScope, admit admissi userInfo, _ := request.UserFrom(ctx) // TODO: remove the mutating admission here as soon as we have ported all plugin that handle CONNECT if mutatingAdmission, ok := admit.(admission.MutationInterface); ok { - err = mutatingAdmission.Admit(admission.NewAttributesRecord(opts, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Connect, false, userInfo), &scope) + err = mutatingAdmission.Admit(admission.NewAttributesRecord(opts, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Connect, false, userInfo), scope) if err != nil { scope.err(err, w, req) return } } if validatingAdmission, ok := admit.(admission.ValidationInterface); ok { - err = validatingAdmission.Validate(admission.NewAttributesRecord(opts, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Connect, false, userInfo), &scope) + err = validatingAdmission.Validate(admission.NewAttributesRecord(opts, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Connect, false, userInfo), scope) if err != nil { scope.err(err, w, req) return @@ -168,13 +166,13 @@ func ConnectResource(connecter rest.Connecter, scope RequestScope, admit admissi // responder implements rest.Responder for assisting a connector in writing objects or errors. type responder struct { - scope RequestScope + scope *RequestScope req *http.Request w http.ResponseWriter } func (r *responder) Object(statusCode int, obj runtime.Object) { - responsewriters.WriteObjectNegotiated(r.scope.Serializer, &r.scope, r.scope.Kind.GroupVersion(), r.w, r.req, statusCode, obj) + responsewriters.WriteObjectNegotiated(r.scope.Serializer, r.scope, r.scope.Kind.GroupVersion(), r.w, r.req, statusCode, obj) } func (r *responder) Error(err error) { diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest_test.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest_test.go index 9ebd06786e4..1003de9d6f3 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest_test.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest_test.go @@ -462,7 +462,7 @@ func (tc *patchTestCase) Run(t *testing.T) { trace: utiltrace.New("Patch" + name), } - resultObj, _, err := p.patchResource(ctx, RequestScope{}) + resultObj, _, err := p.patchResource(ctx, &RequestScope{}) if len(tc.expectedError) != 0 { if err == nil || err.Error() != tc.expectedError { t.Errorf("%s: expected error %v, but got %v", tc.name, tc.expectedError, err) diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/update.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/update.go index 569fcb9dfa3..4117c0e1683 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/update.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/update.go @@ -42,7 +42,7 @@ import ( ) // UpdateResource returns a function that will handle a resource update -func UpdateResource(r rest.Updater, scope RequestScope, admit admission.Interface) http.HandlerFunc { +func UpdateResource(r rest.Updater, scope *RequestScope, admit admission.Interface) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { // For performance tracking purposes. trace := utiltrace.New("Update " + req.URL.Path) @@ -64,7 +64,7 @@ func UpdateResource(r rest.Updater, scope RequestScope, admit admission.Interfac ctx := req.Context() ctx = request.WithNamespace(ctx, namespace) - outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, &scope) + outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, scope) if err != nil { scope.err(err, w, req) return @@ -138,11 +138,11 @@ func UpdateResource(r rest.Updater, scope RequestScope, admit admission.Interfac return nil, fmt.Errorf("unexpected error when extracting UID from oldObj: %v", err.Error()) } else if !isNotZeroObject { if mutatingAdmission.Handles(admission.Create) { - return newObj, mutatingAdmission.Admit(admission.NewAttributesRecord(newObj, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Create, dryrun.IsDryRun(options.DryRun), userInfo), &scope) + return newObj, mutatingAdmission.Admit(admission.NewAttributesRecord(newObj, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Create, dryrun.IsDryRun(options.DryRun), userInfo), scope) } } else { if mutatingAdmission.Handles(admission.Update) { - return newObj, mutatingAdmission.Admit(admission.NewAttributesRecord(newObj, oldObj, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Update, dryrun.IsDryRun(options.DryRun), userInfo), &scope) + return newObj, mutatingAdmission.Admit(admission.NewAttributesRecord(newObj, oldObj, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Update, dryrun.IsDryRun(options.DryRun), userInfo), scope) } } return newObj, nil @@ -172,11 +172,11 @@ func UpdateResource(r rest.Updater, scope RequestScope, admit admission.Interfac rest.DefaultUpdatedObjectInfo(obj, transformers...), withAuthorization(rest.AdmissionToValidateObjectFunc( admit, - admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Create, dryrun.IsDryRun(options.DryRun), userInfo), &scope), + admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Create, dryrun.IsDryRun(options.DryRun), userInfo), scope), scope.Authorizer, createAuthorizerAttributes), rest.AdmissionToValidateObjectUpdateFunc( admit, - admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Update, dryrun.IsDryRun(options.DryRun), userInfo), &scope), + admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Update, dryrun.IsDryRun(options.DryRun), userInfo), scope), false, options, ) @@ -194,8 +194,7 @@ func UpdateResource(r rest.Updater, scope RequestScope, admit admission.Interfac status = http.StatusCreated } - scope.Trace = trace - transformResponseObject(ctx, scope, req, w, status, outputMediaType, result) + transformResponseObject(ctx, scope, trace, req, w, status, outputMediaType, result) } } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/watch.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/watch.go index 301423d8480..e7fa738162f 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/watch.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/watch.go @@ -63,7 +63,7 @@ func (w *realTimeoutFactory) TimeoutCh() (<-chan time.Time, func() bool) { // serveWatch will serve a watch response. // TODO: the functionality in this method and in WatchServer.Serve is not cleanly decoupled. -func serveWatch(watcher watch.Interface, scope RequestScope, mediaTypeOptions negotiation.MediaTypeOptions, req *http.Request, w http.ResponseWriter, timeout time.Duration) { +func serveWatch(watcher watch.Interface, scope *RequestScope, mediaTypeOptions negotiation.MediaTypeOptions, req *http.Request, w http.ResponseWriter, timeout time.Duration) { options, err := optionsForTransform(mediaTypeOptions, req) if err != nil { scope.err(err, w, req) @@ -71,7 +71,7 @@ func serveWatch(watcher watch.Interface, scope RequestScope, mediaTypeOptions ne } // negotiate for the stream serializer from the scope's serializer - serializer, err := negotiation.NegotiateOutputMediaTypeStream(req, scope.Serializer, &scope) + serializer, err := negotiation.NegotiateOutputMediaTypeStream(req, scope.Serializer, scope) if err != nil { scope.err(err, w, req) return @@ -92,7 +92,7 @@ func serveWatch(watcher watch.Interface, scope RequestScope, mediaTypeOptions ne // locate the appropriate embedded encoder based on the transform var embeddedEncoder runtime.Encoder - contentKind, contentSerializer, transform := targetEncodingForTransform(&scope, mediaTypeOptions, req) + contentKind, contentSerializer, transform := targetEncodingForTransform(scope, mediaTypeOptions, req) if transform { var embedded runtime.Serializer for _, supported := range contentSerializer.SupportedMediaTypes() { @@ -145,7 +145,7 @@ func serveWatch(watcher watch.Interface, scope RequestScope, mediaTypeOptions ne // WatchServer serves a watch.Interface over a websocket or vanilla HTTP. type WatchServer struct { Watching watch.Interface - Scope RequestScope + Scope *RequestScope // true if websocket messages should use text framing (as opposed to binary framing) UseTextFraming bool diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go b/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go index 21cd3c87733..a5d3282e56a 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go @@ -1076,60 +1076,60 @@ func isVowel(c rune) bool { func restfulListResource(r rest.Lister, rw rest.Watcher, scope handlers.RequestScope, forceWatch bool, minRequestTimeout time.Duration) restful.RouteFunction { return func(req *restful.Request, res *restful.Response) { - handlers.ListResource(r, rw, scope, forceWatch, minRequestTimeout)(res.ResponseWriter, req.Request) + handlers.ListResource(r, rw, &scope, forceWatch, minRequestTimeout)(res.ResponseWriter, req.Request) } } func restfulCreateNamedResource(r rest.NamedCreater, scope handlers.RequestScope, admit admission.Interface) restful.RouteFunction { return func(req *restful.Request, res *restful.Response) { - handlers.CreateNamedResource(r, scope, admit)(res.ResponseWriter, req.Request) + handlers.CreateNamedResource(r, &scope, admit)(res.ResponseWriter, req.Request) } } func restfulCreateResource(r rest.Creater, scope handlers.RequestScope, admit admission.Interface) restful.RouteFunction { return func(req *restful.Request, res *restful.Response) { - handlers.CreateResource(r, scope, admit)(res.ResponseWriter, req.Request) + handlers.CreateResource(r, &scope, admit)(res.ResponseWriter, req.Request) } } func restfulDeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope handlers.RequestScope, admit admission.Interface) restful.RouteFunction { return func(req *restful.Request, res *restful.Response) { - handlers.DeleteResource(r, allowsOptions, scope, admit)(res.ResponseWriter, req.Request) + handlers.DeleteResource(r, allowsOptions, &scope, admit)(res.ResponseWriter, req.Request) } } func restfulDeleteCollection(r rest.CollectionDeleter, checkBody bool, scope handlers.RequestScope, admit admission.Interface) restful.RouteFunction { return func(req *restful.Request, res *restful.Response) { - handlers.DeleteCollection(r, checkBody, scope, admit)(res.ResponseWriter, req.Request) + handlers.DeleteCollection(r, checkBody, &scope, admit)(res.ResponseWriter, req.Request) } } func restfulUpdateResource(r rest.Updater, scope handlers.RequestScope, admit admission.Interface) restful.RouteFunction { return func(req *restful.Request, res *restful.Response) { - handlers.UpdateResource(r, scope, admit)(res.ResponseWriter, req.Request) + handlers.UpdateResource(r, &scope, admit)(res.ResponseWriter, req.Request) } } func restfulPatchResource(r rest.Patcher, scope handlers.RequestScope, admit admission.Interface, supportedTypes []string) restful.RouteFunction { return func(req *restful.Request, res *restful.Response) { - handlers.PatchResource(r, scope, admit, supportedTypes)(res.ResponseWriter, req.Request) + handlers.PatchResource(r, &scope, admit, supportedTypes)(res.ResponseWriter, req.Request) } } func restfulGetResource(r rest.Getter, e rest.Exporter, scope handlers.RequestScope) restful.RouteFunction { return func(req *restful.Request, res *restful.Response) { - handlers.GetResource(r, e, scope)(res.ResponseWriter, req.Request) + handlers.GetResource(r, e, &scope)(res.ResponseWriter, req.Request) } } func restfulGetResourceWithOptions(r rest.GetterWithOptions, scope handlers.RequestScope, isSubresource bool) restful.RouteFunction { return func(req *restful.Request, res *restful.Response) { - handlers.GetResourceWithOptions(r, scope, isSubresource)(res.ResponseWriter, req.Request) + handlers.GetResourceWithOptions(r, &scope, isSubresource)(res.ResponseWriter, req.Request) } } func restfulConnectResource(connecter rest.Connecter, scope handlers.RequestScope, admit admission.Interface, restPath string, isSubresource bool) restful.RouteFunction { return func(req *restful.Request, res *restful.Response) { - handlers.ConnectResource(connecter, scope, admit, restPath, isSubresource)(res.ResponseWriter, req.Request) + handlers.ConnectResource(connecter, &scope, admit, restPath, isSubresource)(res.ResponseWriter, req.Request) } } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/watch_test.go b/staging/src/k8s.io/apiserver/pkg/endpoints/watch_test.go index 24acbf717f9..63b2967d550 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/watch_test.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/watch_test.go @@ -579,6 +579,7 @@ func TestWatchHTTPErrors(t *testing.T) { // Setup a new watchserver watchServer := &handlers.WatchServer{ + Scope: &handlers.RequestScope{}, Watching: watcher, MediaType: "testcase/json", @@ -639,6 +640,7 @@ func TestWatchHTTPDynamicClientErrors(t *testing.T) { // Setup a new watchserver watchServer := &handlers.WatchServer{ + Scope: &handlers.RequestScope{}, Watching: watcher, MediaType: "testcase/json", @@ -701,6 +703,7 @@ func TestWatchHTTPTimeout(t *testing.T) { // Setup a new watchserver watchServer := &handlers.WatchServer{ + Scope: &handlers.RequestScope{}, Watching: watcher, MediaType: "testcase/json",