mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 05:57:25 +00:00
Make RequestScope be a pointer consistently for better memory use
RequestScope is a large struct and causes stack growth when we pass it by value into multiple stack levels. Avoid the allocations for this read only struct by passing a pointer.
This commit is contained in:
parent
1514bb2141
commit
8fede0b18a
@ -113,13 +113,13 @@ type crdInfo struct {
|
|||||||
storages map[string]customresource.CustomResourceStorage
|
storages map[string]customresource.CustomResourceStorage
|
||||||
|
|
||||||
// Request scope per version
|
// Request scope per version
|
||||||
requestScopes map[string]handlers.RequestScope
|
requestScopes map[string]*handlers.RequestScope
|
||||||
|
|
||||||
// Scale scope per version
|
// Scale scope per version
|
||||||
scaleRequestScopes map[string]handlers.RequestScope
|
scaleRequestScopes map[string]*handlers.RequestScope
|
||||||
|
|
||||||
// Status scope per version
|
// 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 is the CRD version used when storing the object in etcd.
|
||||||
storageVersion string
|
storageVersion string
|
||||||
@ -444,10 +444,10 @@ func (r *crdHandler) getOrCreateServingInfoFor(crd *apiextensions.CustomResource
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Scope/Storages per version.
|
// Scope/Storages per version.
|
||||||
requestScopes := map[string]handlers.RequestScope{}
|
requestScopes := map[string]*handlers.RequestScope{}
|
||||||
storages := map[string]customresource.CustomResourceStorage{}
|
storages := map[string]customresource.CustomResourceStorage{}
|
||||||
statusScopes := map[string]handlers.RequestScope{}
|
statusScopes := map[string]*handlers.RequestScope{}
|
||||||
scaleScopes := map[string]handlers.RequestScope{}
|
scaleScopes := map[string]*handlers.RequestScope{}
|
||||||
|
|
||||||
for _, v := range crd.Spec.Versions {
|
for _, v := range crd.Spec.Versions {
|
||||||
safeConverter, unsafeConverter, err := r.converterFactory.NewConverter(crd)
|
safeConverter, unsafeConverter, err := r.converterFactory.NewConverter(crd)
|
||||||
@ -548,7 +548,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(crd *apiextensions.CustomResource
|
|||||||
|
|
||||||
clusterScoped := crd.Spec.Scope == apiextensions.ClusterScoped
|
clusterScoped := crd.Spec.Scope == apiextensions.ClusterScoped
|
||||||
|
|
||||||
requestScopes[v.Name] = handlers.RequestScope{
|
requestScopes[v.Name] = &handlers.RequestScope{
|
||||||
Namer: handlers.ContextBasedNaming{
|
Namer: handlers.ContextBasedNaming{
|
||||||
SelfLinker: meta.NewAccessor(),
|
SelfLinker: meta.NewAccessor(),
|
||||||
ClusterScoped: clusterScoped,
|
ClusterScoped: clusterScoped,
|
||||||
@ -576,19 +576,19 @@ func (r *crdHandler) getOrCreateServingInfoFor(crd *apiextensions.CustomResource
|
|||||||
Authorizer: r.authorizer,
|
Authorizer: r.authorizer,
|
||||||
}
|
}
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) {
|
if utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) {
|
||||||
reqScope := requestScopes[v.Name]
|
reqScope := *requestScopes[v.Name]
|
||||||
reqScope.FieldManager = fieldmanager.NewCRDFieldManager(
|
reqScope.FieldManager = fieldmanager.NewCRDFieldManager(
|
||||||
reqScope.Convertor,
|
reqScope.Convertor,
|
||||||
reqScope.Defaulter,
|
reqScope.Defaulter,
|
||||||
reqScope.Kind.GroupVersion(),
|
reqScope.Kind.GroupVersion(),
|
||||||
reqScope.HubGroupVersion,
|
reqScope.HubGroupVersion,
|
||||||
)
|
)
|
||||||
requestScopes[v.Name] = reqScope
|
requestScopes[v.Name] = &reqScope
|
||||||
}
|
}
|
||||||
|
|
||||||
// override scaleSpec subresource values
|
// override scaleSpec subresource values
|
||||||
// shallow copy
|
// shallow copy
|
||||||
scaleScope := requestScopes[v.Name]
|
scaleScope := *requestScopes[v.Name]
|
||||||
scaleConverter := scale.NewScaleConverter()
|
scaleConverter := scale.NewScaleConverter()
|
||||||
scaleScope.Subresource = "scale"
|
scaleScope.Subresource = "scale"
|
||||||
scaleScope.Serializer = serializer.NewCodecFactory(scaleConverter.Scheme())
|
scaleScope.Serializer = serializer.NewCodecFactory(scaleConverter.Scheme())
|
||||||
@ -599,11 +599,11 @@ func (r *crdHandler) getOrCreateServingInfoFor(crd *apiextensions.CustomResource
|
|||||||
SelfLinkPathPrefix: selfLinkPrefix,
|
SelfLinkPathPrefix: selfLinkPrefix,
|
||||||
SelfLinkPathSuffix: "/scale",
|
SelfLinkPathSuffix: "/scale",
|
||||||
}
|
}
|
||||||
scaleScopes[v.Name] = scaleScope
|
scaleScopes[v.Name] = &scaleScope
|
||||||
|
|
||||||
// override status subresource values
|
// override status subresource values
|
||||||
// shallow copy
|
// shallow copy
|
||||||
statusScope := requestScopes[v.Name]
|
statusScope := *requestScopes[v.Name]
|
||||||
statusScope.Subresource = "status"
|
statusScope.Subresource = "status"
|
||||||
statusScope.Namer = handlers.ContextBasedNaming{
|
statusScope.Namer = handlers.ContextBasedNaming{
|
||||||
SelfLinker: meta.NewAccessor(),
|
SelfLinker: meta.NewAccessor(),
|
||||||
@ -611,7 +611,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(crd *apiextensions.CustomResource
|
|||||||
SelfLinkPathPrefix: selfLinkPrefix,
|
SelfLinkPathPrefix: selfLinkPrefix,
|
||||||
SelfLinkPathSuffix: "/status",
|
SelfLinkPathSuffix: "/status",
|
||||||
}
|
}
|
||||||
statusScopes[v.Name] = statusScope
|
statusScopes[v.Name] = &statusScope
|
||||||
}
|
}
|
||||||
|
|
||||||
ret := &crdInfo{
|
ret := &crdInfo{
|
||||||
|
@ -43,7 +43,7 @@ import (
|
|||||||
utiltrace "k8s.io/utils/trace"
|
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) {
|
return func(w http.ResponseWriter, req *http.Request) {
|
||||||
// For performance tracking purposes.
|
// For performance tracking purposes.
|
||||||
trace := utiltrace.New("Create " + req.URL.Path)
|
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 := req.Context()
|
||||||
ctx = request.WithNamespace(ctx, namespace)
|
ctx = request.WithNamespace(ctx, namespace)
|
||||||
outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, &scope)
|
outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, scope)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
scope.err(err, w, req)
|
scope.err(err, w, req)
|
||||||
return
|
return
|
||||||
@ -130,7 +130,7 @@ func createHandler(r rest.NamedCreater, scope RequestScope, admit admission.Inte
|
|||||||
userInfo, _ := request.UserFrom(ctx)
|
userInfo, _ := request.UserFrom(ctx)
|
||||||
admissionAttributes := admission.NewAttributesRecord(obj, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Create, dryrun.IsDryRun(options.DryRun), userInfo)
|
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) {
|
if mutatingAdmission, ok := admit.(admission.MutationInterface); ok && mutatingAdmission.Handles(admission.Create) {
|
||||||
err = mutatingAdmission.Admit(admissionAttributes, &scope)
|
err = mutatingAdmission.Admit(admissionAttributes, scope)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
scope.err(err, w, req)
|
scope.err(err, w, req)
|
||||||
return
|
return
|
||||||
@ -157,7 +157,7 @@ func createHandler(r rest.NamedCreater, scope RequestScope, admit admission.Inte
|
|||||||
ctx,
|
ctx,
|
||||||
name,
|
name,
|
||||||
obj,
|
obj,
|
||||||
rest.AdmissionToValidateObjectFunc(admit, admissionAttributes, &scope),
|
rest.AdmissionToValidateObjectFunc(admit, admissionAttributes, scope),
|
||||||
options,
|
options,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@ -173,18 +173,17 @@ func createHandler(r rest.NamedCreater, scope RequestScope, admit admission.Inte
|
|||||||
status.Code = int32(code)
|
status.Code = int32(code)
|
||||||
}
|
}
|
||||||
|
|
||||||
scope.Trace = trace
|
transformResponseObject(ctx, scope, trace, req, w, code, outputMediaType, result)
|
||||||
transformResponseObject(ctx, scope, req, w, code, outputMediaType, result)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateNamedResource returns a function that will handle a resource creation with name.
|
// 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)
|
return createHandler(r, scope, admission, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateResource returns a function that will handle a resource creation.
|
// 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)
|
return createHandler(&namedCreaterAdapter{r}, scope, admission, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ import (
|
|||||||
|
|
||||||
// DeleteResource returns a function that will handle a resource deletion
|
// DeleteResource returns a function that will handle a resource deletion
|
||||||
// TODO admission here becomes solely validating admission
|
// 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) {
|
return func(w http.ResponseWriter, req *http.Request) {
|
||||||
// For performance tracking purposes.
|
// For performance tracking purposes.
|
||||||
trace := utiltrace.New("Delete " + req.URL.Path)
|
trace := utiltrace.New("Delete " + req.URL.Path)
|
||||||
@ -64,7 +64,7 @@ func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope RequestSco
|
|||||||
ae := request.AuditEventFrom(ctx)
|
ae := request.AuditEventFrom(ctx)
|
||||||
admit = admission.WithAudit(admit, ae)
|
admit = admission.WithAudit(admit, ae)
|
||||||
|
|
||||||
outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, &scope)
|
outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, scope)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
scope.err(err, w, req)
|
scope.err(err, w, req)
|
||||||
return
|
return
|
||||||
@ -119,13 +119,13 @@ func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope RequestSco
|
|||||||
userInfo, _ := request.UserFrom(ctx)
|
userInfo, _ := request.UserFrom(ctx)
|
||||||
attrs := admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Delete, dryrun.IsDryRun(options.DryRun), userInfo)
|
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 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)
|
scope.err(err, w, req)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if validatingAdmission, ok := admit.(admission.ValidationInterface); ok {
|
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)
|
scope.err(err, w, req)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -168,13 +168,12 @@ func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope RequestSco
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scope.Trace = trace
|
transformResponseObject(ctx, scope, trace, req, w, status, outputMediaType, result)
|
||||||
transformResponseObject(ctx, scope, req, w, status, outputMediaType, result)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteCollection returns a function that will handle a collection deletion
|
// 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) {
|
return func(w http.ResponseWriter, req *http.Request) {
|
||||||
trace := utiltrace.New("Delete " + req.URL.Path)
|
trace := utiltrace.New("Delete " + req.URL.Path)
|
||||||
defer trace.LogIfLong(500 * time.Millisecond)
|
defer trace.LogIfLong(500 * time.Millisecond)
|
||||||
@ -197,7 +196,7 @@ func DeleteCollection(r rest.CollectionDeleter, checkBody bool, scope RequestSco
|
|||||||
ctx = request.WithNamespace(ctx, namespace)
|
ctx = request.WithNamespace(ctx, namespace)
|
||||||
ae := request.AuditEventFrom(ctx)
|
ae := request.AuditEventFrom(ctx)
|
||||||
|
|
||||||
outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, &scope)
|
outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, scope)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
scope.err(err, w, req)
|
scope.err(err, w, req)
|
||||||
return
|
return
|
||||||
@ -269,7 +268,7 @@ func DeleteCollection(r rest.CollectionDeleter, checkBody bool, scope RequestSco
|
|||||||
userInfo, _ := request.UserFrom(ctx)
|
userInfo, _ := request.UserFrom(ctx)
|
||||||
attrs := admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, "", scope.Resource, scope.Subresource, admission.Delete, dryrun.IsDryRun(options.DryRun), userInfo)
|
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 {
|
if mutatingAdmission, ok := admit.(admission.MutationInterface); ok {
|
||||||
err = mutatingAdmission.Admit(attrs, &scope)
|
err = mutatingAdmission.Admit(attrs, scope)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
scope.err(err, w, req)
|
scope.err(err, w, req)
|
||||||
return
|
return
|
||||||
@ -277,7 +276,7 @@ func DeleteCollection(r rest.CollectionDeleter, checkBody bool, scope RequestSco
|
|||||||
}
|
}
|
||||||
|
|
||||||
if validatingAdmission, ok := admit.(admission.ValidationInterface); ok {
|
if validatingAdmission, ok := admit.(admission.ValidationInterface); ok {
|
||||||
err = validatingAdmission.Validate(attrs, &scope)
|
err = validatingAdmission.Validate(attrs, scope)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
scope.err(err, w, req)
|
scope.err(err, w, req)
|
||||||
return
|
return
|
||||||
@ -305,7 +304,6 @@ func DeleteCollection(r rest.CollectionDeleter, checkBody bool, scope RequestSco
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scope.Trace = trace
|
transformResponseObject(ctx, scope, trace, req, w, http.StatusOK, outputMediaType, result)
|
||||||
transformResponseObject(ctx, scope, req, w, http.StatusOK, outputMediaType, result)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
// getResourceHandler is an HTTP handler function for get requests. It delegates to the
|
||||||
// passed-in getterFunc to perform the actual get.
|
// 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) {
|
return func(w http.ResponseWriter, req *http.Request) {
|
||||||
trace := utiltrace.New("Get " + req.URL.Path)
|
trace := utiltrace.New("Get " + req.URL.Path)
|
||||||
defer trace.LogIfLong(500 * time.Millisecond)
|
defer trace.LogIfLong(500 * time.Millisecond)
|
||||||
@ -59,7 +59,7 @@ func getResourceHandler(scope RequestScope, getter getterFunc) http.HandlerFunc
|
|||||||
ctx := req.Context()
|
ctx := req.Context()
|
||||||
ctx = request.WithNamespace(ctx, namespace)
|
ctx = request.WithNamespace(ctx, namespace)
|
||||||
|
|
||||||
outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, &scope)
|
outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, scope)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
scope.err(err, w, req)
|
scope.err(err, w, req)
|
||||||
return
|
return
|
||||||
@ -72,14 +72,13 @@ func getResourceHandler(scope RequestScope, getter getterFunc) http.HandlerFunc
|
|||||||
}
|
}
|
||||||
|
|
||||||
trace.Step("About to write a response")
|
trace.Step("About to write a response")
|
||||||
scope.Trace = trace
|
transformResponseObject(ctx, scope, trace, req, w, http.StatusOK, outputMediaType, result)
|
||||||
transformResponseObject(ctx, scope, req, w, http.StatusOK, outputMediaType, result)
|
|
||||||
trace.Step("Transformed response object")
|
trace.Step("Transformed response object")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetResource returns a function that handles retrieving a single resource from a rest.Storage 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,
|
return getResourceHandler(scope,
|
||||||
func(ctx context.Context, name string, req *http.Request, trace *utiltrace.Trace) (runtime.Object, error) {
|
func(ctx context.Context, name string, req *http.Request, trace *utiltrace.Trace) (runtime.Object, error) {
|
||||||
// check for export
|
// 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.
|
// 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,
|
return getResourceHandler(scope,
|
||||||
func(ctx context.Context, name string, req *http.Request, trace *utiltrace.Trace) (runtime.Object, error) {
|
func(ctx context.Context, name string, req *http.Request, trace *utiltrace.Trace) (runtime.Object, error) {
|
||||||
opts, subpath, subpathKey := r.NewGetOptions()
|
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.
|
// 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 {
|
if into == nil {
|
||||||
return 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)
|
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) {
|
return func(w http.ResponseWriter, req *http.Request) {
|
||||||
// For performance tracking purposes.
|
// For performance tracking purposes.
|
||||||
trace := utiltrace.New("List " + req.URL.Path)
|
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 := req.Context()
|
||||||
ctx = request.WithNamespace(ctx, namespace)
|
ctx = request.WithNamespace(ctx, namespace)
|
||||||
|
|
||||||
outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, &scope)
|
outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, scope)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
scope.err(err, w, req)
|
scope.err(err, w, req)
|
||||||
return
|
return
|
||||||
@ -272,8 +271,7 @@ func ListResource(r rest.Lister, rw rest.Watcher, scope RequestScope, forceWatch
|
|||||||
}
|
}
|
||||||
trace.Step("Listing from storage done")
|
trace.Step("Listing from storage done")
|
||||||
|
|
||||||
scope.Trace = trace
|
transformResponseObject(ctx, scope, trace, req, w, http.StatusOK, outputMediaType, result)
|
||||||
transformResponseObject(ctx, scope, req, w, http.StatusOK, outputMediaType, result)
|
|
||||||
trace.Step(fmt.Sprintf("Writing http response done (%d items)", meta.LenList(result)))
|
trace.Step(fmt.Sprintf("Writing http response done (%d items)", meta.LenList(result)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// PatchResource returns a function that will handle a resource patch.
|
// 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) {
|
return func(w http.ResponseWriter, req *http.Request) {
|
||||||
// For performance tracking purposes.
|
// For performance tracking purposes.
|
||||||
trace := utiltrace.New("Patch " + req.URL.Path)
|
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 := req.Context()
|
||||||
ctx = request.WithNamespace(ctx, namespace)
|
ctx = request.WithNamespace(ctx, namespace)
|
||||||
|
|
||||||
outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, &scope)
|
outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, scope)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
scope.err(err, w, req)
|
scope.err(err, w, req)
|
||||||
return
|
return
|
||||||
@ -191,12 +191,12 @@ func PatchResource(r rest.Patcher, scope RequestScope, admit admission.Interface
|
|||||||
subresource: scope.Subresource,
|
subresource: scope.Subresource,
|
||||||
dryRun: dryrun.IsDryRun(options.DryRun),
|
dryRun: dryrun.IsDryRun(options.DryRun),
|
||||||
|
|
||||||
objectInterfaces: &scope,
|
objectInterfaces: scope,
|
||||||
|
|
||||||
hubGroupVersion: scope.HubGroupVersion,
|
hubGroupVersion: scope.HubGroupVersion,
|
||||||
|
|
||||||
createValidation: withAuthorization(rest.AdmissionToValidateObjectFunc(admit, staticCreateAttributes, &scope), scope.Authorizer, createAuthorizerAttributes),
|
createValidation: withAuthorization(rest.AdmissionToValidateObjectFunc(admit, staticCreateAttributes, scope), scope.Authorizer, createAuthorizerAttributes),
|
||||||
updateValidation: rest.AdmissionToValidateObjectUpdateFunc(admit, staticUpdateAttributes, &scope),
|
updateValidation: rest.AdmissionToValidateObjectUpdateFunc(admit, staticUpdateAttributes, scope),
|
||||||
admissionCheck: mutatingAdmission,
|
admissionCheck: mutatingAdmission,
|
||||||
|
|
||||||
codec: codec,
|
codec: codec,
|
||||||
@ -235,8 +235,7 @@ func PatchResource(r rest.Patcher, scope RequestScope, admit admission.Interface
|
|||||||
if wasCreated {
|
if wasCreated {
|
||||||
status = http.StatusCreated
|
status = http.StatusCreated
|
||||||
}
|
}
|
||||||
scope.Trace = trace
|
transformResponseObject(ctx, scope, trace, req, w, status, outputMediaType, result)
|
||||||
transformResponseObject(ctx, scope, 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
|
// 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)
|
p.namespace = request.NamespaceValue(ctx)
|
||||||
switch p.patchType {
|
switch p.patchType {
|
||||||
case types.JSONPatchType, types.MergePatchType:
|
case types.JSONPatchType, types.MergePatchType:
|
||||||
|
@ -31,12 +31,13 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
|
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
|
||||||
"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters"
|
"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
|
// 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
|
// the client's desired form, as well as ensuring any API level fields like self-link
|
||||||
// are properly set.
|
// 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 {
|
if _, ok := obj.(*metav1.Status); ok {
|
||||||
return obj, nil
|
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.
|
// transformResponseObject takes an object loaded from storage and performs any necessary transformations.
|
||||||
// Will write the complete response object.
|
// 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)
|
options, err := optionsForTransform(mediaType, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
scope.err(err, w, req)
|
scope.err(err, w, req)
|
||||||
@ -115,8 +116,8 @@ func transformResponseObject(ctx context.Context, scope RequestScope, req *http.
|
|||||||
scope.err(err, w, req)
|
scope.err(err, w, req)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
kind, serializer, _ := targetEncodingForTransform(&scope, mediaType, req)
|
kind, serializer, _ := targetEncodingForTransform(scope, mediaType, req)
|
||||||
responsewriters.WriteObjectNegotiated(serializer, &scope, kind.GroupVersion(), w, req, statusCode, obj)
|
responsewriters.WriteObjectNegotiated(serializer, scope, kind.GroupVersion(), w, req, statusCode, obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
// errNotAcceptable indicates Accept negotiation has failed
|
// 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)
|
table, err := scope.TableConvertor.ConvertToTable(ctx, result, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -42,7 +42,6 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/endpoints/request"
|
"k8s.io/apiserver/pkg/endpoints/request"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
"k8s.io/klog"
|
"k8s.io/klog"
|
||||||
utiltrace "k8s.io/utils/trace"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// RequestScope encapsulates common fields across all RESTful handler methods.
|
// RequestScope encapsulates common fields across all RESTful handler methods.
|
||||||
@ -58,7 +57,6 @@ type RequestScope struct {
|
|||||||
Typer runtime.ObjectTyper
|
Typer runtime.ObjectTyper
|
||||||
UnsafeConvertor runtime.ObjectConvertor
|
UnsafeConvertor runtime.ObjectConvertor
|
||||||
Authorizer authorizer.Authorizer
|
Authorizer authorizer.Authorizer
|
||||||
Trace *utiltrace.Trace
|
|
||||||
|
|
||||||
TableConvertor rest.TableConvertor
|
TableConvertor rest.TableConvertor
|
||||||
FieldManager *fieldmanager.FieldManager
|
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 }
|
func (r *RequestScope) GetObjectConvertor() runtime.ObjectConvertor { return r.Convertor }
|
||||||
|
|
||||||
// ConnectResource returns a function that handles a connect request on a rest.Storage object.
|
// 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) {
|
return func(w http.ResponseWriter, req *http.Request) {
|
||||||
if isDryRun(req.URL) {
|
if isDryRun(req.URL) {
|
||||||
scope.err(errors.NewBadRequest("dryRun is not supported"), w, req)
|
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)
|
userInfo, _ := request.UserFrom(ctx)
|
||||||
// TODO: remove the mutating admission here as soon as we have ported all plugin that handle CONNECT
|
// TODO: remove the mutating admission here as soon as we have ported all plugin that handle CONNECT
|
||||||
if mutatingAdmission, ok := admit.(admission.MutationInterface); ok {
|
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 {
|
if err != nil {
|
||||||
scope.err(err, w, req)
|
scope.err(err, w, req)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if validatingAdmission, ok := admit.(admission.ValidationInterface); ok {
|
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 {
|
if err != nil {
|
||||||
scope.err(err, w, req)
|
scope.err(err, w, req)
|
||||||
return
|
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.
|
// responder implements rest.Responder for assisting a connector in writing objects or errors.
|
||||||
type responder struct {
|
type responder struct {
|
||||||
scope RequestScope
|
scope *RequestScope
|
||||||
req *http.Request
|
req *http.Request
|
||||||
w http.ResponseWriter
|
w http.ResponseWriter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *responder) Object(statusCode int, obj runtime.Object) {
|
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) {
|
func (r *responder) Error(err error) {
|
||||||
|
@ -462,7 +462,7 @@ func (tc *patchTestCase) Run(t *testing.T) {
|
|||||||
trace: utiltrace.New("Patch" + name),
|
trace: utiltrace.New("Patch" + name),
|
||||||
}
|
}
|
||||||
|
|
||||||
resultObj, _, err := p.patchResource(ctx, RequestScope{})
|
resultObj, _, err := p.patchResource(ctx, &RequestScope{})
|
||||||
if len(tc.expectedError) != 0 {
|
if len(tc.expectedError) != 0 {
|
||||||
if err == nil || err.Error() != tc.expectedError {
|
if err == nil || err.Error() != tc.expectedError {
|
||||||
t.Errorf("%s: expected error %v, but got %v", tc.name, tc.expectedError, err)
|
t.Errorf("%s: expected error %v, but got %v", tc.name, tc.expectedError, err)
|
||||||
|
@ -42,7 +42,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// UpdateResource returns a function that will handle a resource update
|
// 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) {
|
return func(w http.ResponseWriter, req *http.Request) {
|
||||||
// For performance tracking purposes.
|
// For performance tracking purposes.
|
||||||
trace := utiltrace.New("Update " + req.URL.Path)
|
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 := req.Context()
|
||||||
ctx = request.WithNamespace(ctx, namespace)
|
ctx = request.WithNamespace(ctx, namespace)
|
||||||
|
|
||||||
outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, &scope)
|
outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, scope)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
scope.err(err, w, req)
|
scope.err(err, w, req)
|
||||||
return
|
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())
|
return nil, fmt.Errorf("unexpected error when extracting UID from oldObj: %v", err.Error())
|
||||||
} else if !isNotZeroObject {
|
} else if !isNotZeroObject {
|
||||||
if mutatingAdmission.Handles(admission.Create) {
|
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 {
|
} else {
|
||||||
if mutatingAdmission.Handles(admission.Update) {
|
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
|
return newObj, nil
|
||||||
@ -172,11 +172,11 @@ func UpdateResource(r rest.Updater, scope RequestScope, admit admission.Interfac
|
|||||||
rest.DefaultUpdatedObjectInfo(obj, transformers...),
|
rest.DefaultUpdatedObjectInfo(obj, transformers...),
|
||||||
withAuthorization(rest.AdmissionToValidateObjectFunc(
|
withAuthorization(rest.AdmissionToValidateObjectFunc(
|
||||||
admit,
|
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),
|
scope.Authorizer, createAuthorizerAttributes),
|
||||||
rest.AdmissionToValidateObjectUpdateFunc(
|
rest.AdmissionToValidateObjectUpdateFunc(
|
||||||
admit,
|
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,
|
false,
|
||||||
options,
|
options,
|
||||||
)
|
)
|
||||||
@ -194,8 +194,7 @@ func UpdateResource(r rest.Updater, scope RequestScope, admit admission.Interfac
|
|||||||
status = http.StatusCreated
|
status = http.StatusCreated
|
||||||
}
|
}
|
||||||
|
|
||||||
scope.Trace = trace
|
transformResponseObject(ctx, scope, trace, req, w, status, outputMediaType, result)
|
||||||
transformResponseObject(ctx, scope, req, w, status, outputMediaType, result)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ func (w *realTimeoutFactory) TimeoutCh() (<-chan time.Time, func() bool) {
|
|||||||
|
|
||||||
// serveWatch will serve a watch response.
|
// serveWatch will serve a watch response.
|
||||||
// TODO: the functionality in this method and in WatchServer.Serve is not cleanly decoupled.
|
// 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)
|
options, err := optionsForTransform(mediaTypeOptions, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
scope.err(err, w, req)
|
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
|
// 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 {
|
if err != nil {
|
||||||
scope.err(err, w, req)
|
scope.err(err, w, req)
|
||||||
return
|
return
|
||||||
@ -92,7 +92,7 @@ func serveWatch(watcher watch.Interface, scope RequestScope, mediaTypeOptions ne
|
|||||||
|
|
||||||
// locate the appropriate embedded encoder based on the transform
|
// locate the appropriate embedded encoder based on the transform
|
||||||
var embeddedEncoder runtime.Encoder
|
var embeddedEncoder runtime.Encoder
|
||||||
contentKind, contentSerializer, transform := targetEncodingForTransform(&scope, mediaTypeOptions, req)
|
contentKind, contentSerializer, transform := targetEncodingForTransform(scope, mediaTypeOptions, req)
|
||||||
if transform {
|
if transform {
|
||||||
var embedded runtime.Serializer
|
var embedded runtime.Serializer
|
||||||
for _, supported := range contentSerializer.SupportedMediaTypes() {
|
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.
|
// WatchServer serves a watch.Interface over a websocket or vanilla HTTP.
|
||||||
type WatchServer struct {
|
type WatchServer struct {
|
||||||
Watching watch.Interface
|
Watching watch.Interface
|
||||||
Scope RequestScope
|
Scope *RequestScope
|
||||||
|
|
||||||
// true if websocket messages should use text framing (as opposed to binary framing)
|
// true if websocket messages should use text framing (as opposed to binary framing)
|
||||||
UseTextFraming bool
|
UseTextFraming bool
|
||||||
|
@ -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 {
|
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) {
|
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 {
|
func restfulCreateNamedResource(r rest.NamedCreater, scope handlers.RequestScope, admit admission.Interface) restful.RouteFunction {
|
||||||
return func(req *restful.Request, res *restful.Response) {
|
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 {
|
func restfulCreateResource(r rest.Creater, scope handlers.RequestScope, admit admission.Interface) restful.RouteFunction {
|
||||||
return func(req *restful.Request, res *restful.Response) {
|
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 {
|
func restfulDeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope handlers.RequestScope, admit admission.Interface) restful.RouteFunction {
|
||||||
return func(req *restful.Request, res *restful.Response) {
|
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 {
|
func restfulDeleteCollection(r rest.CollectionDeleter, checkBody bool, scope handlers.RequestScope, admit admission.Interface) restful.RouteFunction {
|
||||||
return func(req *restful.Request, res *restful.Response) {
|
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 {
|
func restfulUpdateResource(r rest.Updater, scope handlers.RequestScope, admit admission.Interface) restful.RouteFunction {
|
||||||
return func(req *restful.Request, res *restful.Response) {
|
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 {
|
func restfulPatchResource(r rest.Patcher, scope handlers.RequestScope, admit admission.Interface, supportedTypes []string) restful.RouteFunction {
|
||||||
return func(req *restful.Request, res *restful.Response) {
|
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 {
|
func restfulGetResource(r rest.Getter, e rest.Exporter, scope handlers.RequestScope) restful.RouteFunction {
|
||||||
return func(req *restful.Request, res *restful.Response) {
|
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 {
|
func restfulGetResourceWithOptions(r rest.GetterWithOptions, scope handlers.RequestScope, isSubresource bool) restful.RouteFunction {
|
||||||
return func(req *restful.Request, res *restful.Response) {
|
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 {
|
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) {
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -579,6 +579,7 @@ func TestWatchHTTPErrors(t *testing.T) {
|
|||||||
|
|
||||||
// Setup a new watchserver
|
// Setup a new watchserver
|
||||||
watchServer := &handlers.WatchServer{
|
watchServer := &handlers.WatchServer{
|
||||||
|
Scope: &handlers.RequestScope{},
|
||||||
Watching: watcher,
|
Watching: watcher,
|
||||||
|
|
||||||
MediaType: "testcase/json",
|
MediaType: "testcase/json",
|
||||||
@ -639,6 +640,7 @@ func TestWatchHTTPDynamicClientErrors(t *testing.T) {
|
|||||||
|
|
||||||
// Setup a new watchserver
|
// Setup a new watchserver
|
||||||
watchServer := &handlers.WatchServer{
|
watchServer := &handlers.WatchServer{
|
||||||
|
Scope: &handlers.RequestScope{},
|
||||||
Watching: watcher,
|
Watching: watcher,
|
||||||
|
|
||||||
MediaType: "testcase/json",
|
MediaType: "testcase/json",
|
||||||
@ -701,6 +703,7 @@ func TestWatchHTTPTimeout(t *testing.T) {
|
|||||||
|
|
||||||
// Setup a new watchserver
|
// Setup a new watchserver
|
||||||
watchServer := &handlers.WatchServer{
|
watchServer := &handlers.WatchServer{
|
||||||
|
Scope: &handlers.RequestScope{},
|
||||||
Watching: watcher,
|
Watching: watcher,
|
||||||
|
|
||||||
MediaType: "testcase/json",
|
MediaType: "testcase/json",
|
||||||
|
Loading…
Reference in New Issue
Block a user