mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 10:51:29 +00:00
Merge pull request #88936 from jpbetz/http-trace
Add nested tracing and endpoint filter tracing to apiserver
This commit is contained in:
commit
240a72b5c0
@ -23,6 +23,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
|
"//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
||||||
|
@ -30,6 +30,7 @@ import (
|
|||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
corelisters "k8s.io/client-go/listers/core/v1"
|
corelisters "k8s.io/client-go/listers/core/v1"
|
||||||
extenderv1 "k8s.io/kube-scheduler/extender/v1"
|
extenderv1 "k8s.io/kube-scheduler/extender/v1"
|
||||||
@ -136,7 +137,7 @@ func (g *genericScheduler) snapshot() error {
|
|||||||
// If it succeeds, it will return the name of the node.
|
// If it succeeds, it will return the name of the node.
|
||||||
// If it fails, it will return a FitError error with reasons.
|
// If it fails, it will return a FitError error with reasons.
|
||||||
func (g *genericScheduler) Schedule(ctx context.Context, prof *profile.Profile, state *framework.CycleState, pod *v1.Pod) (result ScheduleResult, err error) {
|
func (g *genericScheduler) Schedule(ctx context.Context, prof *profile.Profile, state *framework.CycleState, pod *v1.Pod) (result ScheduleResult, err error) {
|
||||||
trace := utiltrace.New("Scheduling", utiltrace.Field{Key: "namespace", Value: pod.Namespace}, utiltrace.Field{Key: "name", Value: pod.Name})
|
ctx, trace := genericapirequest.WithTrace(ctx, "Scheduling", utiltrace.Field{Key: "namespace", Value: pod.Namespace}, utiltrace.Field{Key: "name", Value: pod.Name})
|
||||||
defer trace.LogIfLong(100 * time.Millisecond)
|
defer trace.LogIfLong(100 * time.Millisecond)
|
||||||
|
|
||||||
if err := podPassesBasicChecks(pod, g.pvcLister); err != nil {
|
if err := podPassesBasicChecks(pod, g.pvcLister); err != nil {
|
||||||
|
@ -24,6 +24,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library",
|
"//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
||||||
|
@ -34,6 +34,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/apimachinery/pkg/util/uuid"
|
"k8s.io/apimachinery/pkg/util/uuid"
|
||||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
|
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||||
"k8s.io/apiserver/pkg/util/webhook"
|
"k8s.io/apiserver/pkg/util/webhook"
|
||||||
"k8s.io/client-go/rest"
|
"k8s.io/client-go/rest"
|
||||||
utiltrace "k8s.io/utils/trace"
|
utiltrace "k8s.io/utils/trace"
|
||||||
@ -259,7 +260,7 @@ func (c *webhookConverter) Convert(in runtime.Object, toGV schema.GroupVersion)
|
|||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
trace := utiltrace.New("Call conversion webhook",
|
ctx, trace := genericapirequest.WithTrace(context.TODO(), "Call conversion webhook",
|
||||||
utiltrace.Field{"custom-resource-definition", c.name},
|
utiltrace.Field{"custom-resource-definition", c.name},
|
||||||
utiltrace.Field{"desired-api-version", desiredAPIVersion},
|
utiltrace.Field{"desired-api-version", desiredAPIVersion},
|
||||||
utiltrace.Field{"object-count", objCount},
|
utiltrace.Field{"object-count", objCount},
|
||||||
@ -269,8 +270,6 @@ func (c *webhookConverter) Convert(in runtime.Object, toGV schema.GroupVersion)
|
|||||||
// the conversion request on the apiserver side (~4ms per object).
|
// the conversion request on the apiserver side (~4ms per object).
|
||||||
defer trace.LogIfLong(time.Duration(50+8*objCount) * time.Millisecond)
|
defer trace.LogIfLong(time.Duration(50+8*objCount) * time.Millisecond)
|
||||||
|
|
||||||
// TODO: Figure out if adding one second timeout make sense here.
|
|
||||||
ctx := context.TODO()
|
|
||||||
r := c.restClient.Post().Body(request).Do(ctx)
|
r := c.restClient.Post().Body(request).Do(ctx)
|
||||||
if err := r.Into(response); err != nil {
|
if err := r.Into(response); err != nil {
|
||||||
// TODO: Return a webhook specific error to be able to convert it to meta.Status
|
// TODO: Return a webhook specific error to be able to convert it to meta.Status
|
||||||
|
@ -29,6 +29,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/generic:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/generic:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/request:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/request:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/apis/audit:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/apis/audit:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/warning:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/warning:go_default_library",
|
||||||
"//vendor/github.com/evanphx/json-patch:go_default_library",
|
"//vendor/github.com/evanphx/json-patch:go_default_library",
|
||||||
|
@ -42,6 +42,7 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/admission/plugin/webhook/generic"
|
"k8s.io/apiserver/pkg/admission/plugin/webhook/generic"
|
||||||
webhookrequest "k8s.io/apiserver/pkg/admission/plugin/webhook/request"
|
webhookrequest "k8s.io/apiserver/pkg/admission/plugin/webhook/request"
|
||||||
auditinternal "k8s.io/apiserver/pkg/apis/audit"
|
auditinternal "k8s.io/apiserver/pkg/apis/audit"
|
||||||
|
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||||
webhookutil "k8s.io/apiserver/pkg/util/webhook"
|
webhookutil "k8s.io/apiserver/pkg/util/webhook"
|
||||||
"k8s.io/apiserver/pkg/warning"
|
"k8s.io/apiserver/pkg/warning"
|
||||||
utiltrace "k8s.io/utils/trace"
|
utiltrace "k8s.io/utils/trace"
|
||||||
@ -221,7 +222,7 @@ func (a *mutatingDispatcher) callAttrMutatingHook(ctx context.Context, h *admiss
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return false, &webhookutil.ErrCallingWebhook{WebhookName: h.Name, Reason: err}
|
return false, &webhookutil.ErrCallingWebhook{WebhookName: h.Name, Reason: err}
|
||||||
}
|
}
|
||||||
trace := utiltrace.New("Call mutating webhook",
|
ctx, trace := genericapirequest.WithTrace(ctx, "Call mutating webhook",
|
||||||
utiltrace.Field{"configuration", configurationName},
|
utiltrace.Field{"configuration", configurationName},
|
||||||
utiltrace.Field{"webhook", h.Name},
|
utiltrace.Field{"webhook", h.Name},
|
||||||
utiltrace.Field{"resource", attr.GetResource()},
|
utiltrace.Field{"resource", attr.GetResource()},
|
||||||
|
@ -22,6 +22,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/errors:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/errors:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/generic:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/generic:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/request:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/request:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/warning:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/warning:go_default_library",
|
||||||
"//vendor/k8s.io/klog/v2:go_default_library",
|
"//vendor/k8s.io/klog/v2:go_default_library",
|
||||||
|
@ -32,6 +32,7 @@ import (
|
|||||||
webhookerrors "k8s.io/apiserver/pkg/admission/plugin/webhook/errors"
|
webhookerrors "k8s.io/apiserver/pkg/admission/plugin/webhook/errors"
|
||||||
"k8s.io/apiserver/pkg/admission/plugin/webhook/generic"
|
"k8s.io/apiserver/pkg/admission/plugin/webhook/generic"
|
||||||
webhookrequest "k8s.io/apiserver/pkg/admission/plugin/webhook/request"
|
webhookrequest "k8s.io/apiserver/pkg/admission/plugin/webhook/request"
|
||||||
|
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||||
webhookutil "k8s.io/apiserver/pkg/util/webhook"
|
webhookutil "k8s.io/apiserver/pkg/util/webhook"
|
||||||
"k8s.io/apiserver/pkg/warning"
|
"k8s.io/apiserver/pkg/warning"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
@ -181,7 +182,7 @@ func (d *validatingDispatcher) callHook(ctx context.Context, h *v1.ValidatingWeb
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return &webhookutil.ErrCallingWebhook{WebhookName: h.Name, Reason: err}
|
return &webhookutil.ErrCallingWebhook{WebhookName: h.Name, Reason: err}
|
||||||
}
|
}
|
||||||
trace := utiltrace.New("Call validating webhook",
|
ctx, trace := genericapirequest.WithTrace(ctx, "Call validating webhook",
|
||||||
utiltrace.Field{"configuration", invocation.Webhook.GetConfigurationName()},
|
utiltrace.Field{"configuration", invocation.Webhook.GetConfigurationName()},
|
||||||
utiltrace.Field{"webhook", h.Name},
|
utiltrace.Field{"webhook", h.Name},
|
||||||
utiltrace.Field{"resource", attr.GetResource()},
|
utiltrace.Field{"resource", attr.GetResource()},
|
||||||
|
@ -112,6 +112,7 @@ filegroup(
|
|||||||
"//staging/src/k8s.io/apiserver/pkg/endpoints/discovery:all-srcs",
|
"//staging/src/k8s.io/apiserver/pkg/endpoints/discovery:all-srcs",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/endpoints/filters:all-srcs",
|
"//staging/src/k8s.io/apiserver/pkg/endpoints/filters:all-srcs",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/endpoints/handlers:all-srcs",
|
"//staging/src/k8s.io/apiserver/pkg/endpoints/handlers:all-srcs",
|
||||||
|
"//staging/src/k8s.io/apiserver/pkg/endpoints/internal:all-srcs",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/endpoints/metrics:all-srcs",
|
"//staging/src/k8s.io/apiserver/pkg/endpoints/metrics:all-srcs",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/endpoints/openapi:all-srcs",
|
"//staging/src/k8s.io/apiserver/pkg/endpoints/openapi:all-srcs",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/endpoints/request:all-srcs",
|
"//staging/src/k8s.io/apiserver/pkg/endpoints/request:all-srcs",
|
||||||
|
@ -55,6 +55,7 @@ go_library(
|
|||||||
"impersonation.go",
|
"impersonation.go",
|
||||||
"metrics.go",
|
"metrics.go",
|
||||||
"requestinfo.go",
|
"requestinfo.go",
|
||||||
|
"trace.go",
|
||||||
"warning.go",
|
"warning.go",
|
||||||
],
|
],
|
||||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/endpoints/filters",
|
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/endpoints/filters",
|
||||||
@ -76,12 +77,14 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/endpoints/handlers/responsewriters:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/endpoints/handlers/responsewriters:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiserver/pkg/endpoints/internal:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/server/httplog:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/server/httplog:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/warning:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/warning:go_default_library",
|
||||||
"//staging/src/k8s.io/component-base/metrics:go_default_library",
|
"//staging/src/k8s.io/component-base/metrics:go_default_library",
|
||||||
"//staging/src/k8s.io/component-base/metrics/legacyregistry:go_default_library",
|
"//staging/src/k8s.io/component-base/metrics/legacyregistry:go_default_library",
|
||||||
"//vendor/k8s.io/klog/v2:go_default_library",
|
"//vendor/k8s.io/klog/v2:go_default_library",
|
||||||
|
"//vendor/k8s.io/utils/trace:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -47,6 +47,7 @@ func WithAuthentication(handler http.Handler, auth authenticator.Request, failed
|
|||||||
req = req.WithContext(authenticator.WithAudiences(req.Context(), apiAuds))
|
req = req.WithContext(authenticator.WithAudiences(req.Context(), apiAuds))
|
||||||
}
|
}
|
||||||
resp, ok, err := auth.AuthenticateRequest(req)
|
resp, ok, err := auth.AuthenticateRequest(req)
|
||||||
|
traceFilterStep(req.Context(), "Authenticate check done")
|
||||||
defer recordAuthMetrics(resp, ok, err, apiAuds, authenticationStart)
|
defer recordAuthMetrics(resp, ok, err, apiAuds, authenticationStart)
|
||||||
if err != nil || !ok {
|
if err != nil || !ok {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -57,6 +57,7 @@ func WithAuthorization(handler http.Handler, a authorizer.Authorizer, s runtime.
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
authorized, reason, err := a.Authorize(ctx, attributes)
|
authorized, reason, err := a.Authorize(ctx, attributes)
|
||||||
|
traceFilterStep(ctx, "Authorize check done")
|
||||||
// an authorizer like RBAC could encounter evaluation errors and still allow the request, so authorizer decision is checked before error here.
|
// an authorizer like RBAC could encounter evaluation errors and still allow the request, so authorizer decision is checked before error here.
|
||||||
if authorized == authorizer.DecisionAllow {
|
if authorized == authorizer.DecisionAllow {
|
||||||
audit.LogAnnotation(ae, decisionAnnotationKey, decisionAllow)
|
audit.LogAnnotation(ae, decisionAnnotationKey, decisionAllow)
|
||||||
|
@ -110,6 +110,7 @@ func WithImpersonation(handler http.Handler, a authorizer.Authorizer, s runtime.
|
|||||||
}
|
}
|
||||||
|
|
||||||
decision, reason, err := a.Authorize(ctx, actingAsAttributes)
|
decision, reason, err := a.Authorize(ctx, actingAsAttributes)
|
||||||
|
traceFilterStep(ctx, "Impersonation authorize check done")
|
||||||
if err != nil || decision != authorizer.DecisionAllow {
|
if err != nil || decision != authorizer.DecisionAllow {
|
||||||
klog.V(4).Infof("Forbidden: %#v, Reason: %s, Error: %v", req.RequestURI, reason, err)
|
klog.V(4).Infof("Forbidden: %#v, Reason: %s, Error: %v", req.RequestURI, reason, err)
|
||||||
responsewriters.Forbidden(ctx, actingAsAttributes, w, req, reason, s)
|
responsewriters.Forbidden(ctx, actingAsAttributes, w, req, reason, s)
|
||||||
@ -144,7 +145,6 @@ func WithImpersonation(handler http.Handler, a authorizer.Authorizer, s runtime.
|
|||||||
req.Header.Del(headerName)
|
req.Header.Del(headerName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handler.ServeHTTP(w, req)
|
handler.ServeHTTP(w, req)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
69
staging/src/k8s.io/apiserver/pkg/endpoints/filters/trace.go
Normal file
69
staging/src/k8s.io/apiserver/pkg/endpoints/filters/trace.go
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2020 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package filters
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
utiltrace "k8s.io/utils/trace"
|
||||||
|
|
||||||
|
"k8s.io/apiserver/pkg/endpoints/internal"
|
||||||
|
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||||
|
)
|
||||||
|
|
||||||
|
// WithTrace decorates a http.Handler with tracing for all the non-long running
|
||||||
|
// requests coming to the server.
|
||||||
|
func WithTrace(handler http.Handler, longRunningCheck genericapirequest.LongRunningRequestCheck) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||||
|
ri, ok := genericapirequest.RequestInfoFrom(req.Context())
|
||||||
|
isLongRunning := false
|
||||||
|
if longRunningCheck != nil {
|
||||||
|
if ok && longRunningCheck(req, ri) {
|
||||||
|
isLongRunning = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if isLongRunning {
|
||||||
|
handler.ServeHTTP(w, req)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx, trace := genericapirequest.WithTrace(req.Context(), "HTTP Request",
|
||||||
|
utiltrace.Field{Key: "method", Value: req.Method},
|
||||||
|
utiltrace.Field{Key: "url", Value: req.URL.Path},
|
||||||
|
utiltrace.Field{Key: "verb", Value: ri.Verb},
|
||||||
|
utiltrace.Field{Key: "name", Value: ri.Name},
|
||||||
|
utiltrace.Field{Key: "resource", Value: ri.Resource},
|
||||||
|
utiltrace.Field{Key: "subresource", Value: ri.Subresource},
|
||||||
|
utiltrace.Field{Key: "namespace", Value: ri.Namespace},
|
||||||
|
utiltrace.Field{Key: "api-group", Value: ri.APIGroup},
|
||||||
|
utiltrace.Field{Key: "api-version", Value: ri.APIVersion},
|
||||||
|
utiltrace.Field{Key: "user-agent", Value: &internal.LazyTruncatedUserAgent{req}},
|
||||||
|
utiltrace.Field{Key: "client", Value: &internal.LazyClientIP{req}})
|
||||||
|
req = req.Clone(ctx)
|
||||||
|
// Set trace as root trace in context for nested tracing
|
||||||
|
defer trace.LogIfLong(30 * time.Second)
|
||||||
|
handler.ServeHTTP(w, req)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func traceFilterStep(ctx context.Context, msg string, field ...utiltrace.Field) {
|
||||||
|
if trace, ok := genericapirequest.TraceFrom(ctx); ok {
|
||||||
|
trace.Step(msg, field...)
|
||||||
|
}
|
||||||
|
}
|
@ -10,7 +10,6 @@ go_test(
|
|||||||
name = "go_default_test",
|
name = "go_default_test",
|
||||||
srcs = [
|
srcs = [
|
||||||
"create_test.go",
|
"create_test.go",
|
||||||
"helpers_test.go",
|
|
||||||
"namer_test.go",
|
"namer_test.go",
|
||||||
"response_test.go",
|
"response_test.go",
|
||||||
"rest_test.go",
|
"rest_test.go",
|
||||||
@ -42,7 +41,6 @@ go_test(
|
|||||||
"//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library",
|
"//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library",
|
||||||
"//vendor/github.com/evanphx/json-patch:go_default_library",
|
"//vendor/github.com/evanphx/json-patch:go_default_library",
|
||||||
"//vendor/github.com/google/gofuzz:go_default_library",
|
"//vendor/github.com/google/gofuzz:go_default_library",
|
||||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
|
||||||
"//vendor/k8s.io/utils/trace:go_default_library",
|
"//vendor/k8s.io/utils/trace:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@ -54,7 +52,6 @@ go_library(
|
|||||||
"delete.go",
|
"delete.go",
|
||||||
"doc.go",
|
"doc.go",
|
||||||
"get.go",
|
"get.go",
|
||||||
"helpers.go",
|
|
||||||
"namer.go",
|
"namer.go",
|
||||||
"patch.go",
|
"patch.go",
|
||||||
"response.go",
|
"response.go",
|
||||||
@ -82,7 +79,6 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/json:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/json:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/mergepatch:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/mergepatch:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/strategicpatch:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/strategicpatch:go_default_library",
|
||||||
@ -94,6 +90,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/endpoints/handlers/negotiation:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/endpoints/handlers/negotiation:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/endpoints/handlers/responsewriters:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/endpoints/handlers/responsewriters:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiserver/pkg/endpoints/internal:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/endpoints/metrics:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/endpoints/metrics:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/features:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/features:go_default_library",
|
||||||
|
@ -33,9 +33,11 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/validation"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/validation"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
|
||||||
"k8s.io/apiserver/pkg/admission"
|
"k8s.io/apiserver/pkg/admission"
|
||||||
"k8s.io/apiserver/pkg/audit"
|
"k8s.io/apiserver/pkg/audit"
|
||||||
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
|
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
|
||||||
|
"k8s.io/apiserver/pkg/endpoints/internal"
|
||||||
"k8s.io/apiserver/pkg/endpoints/request"
|
"k8s.io/apiserver/pkg/endpoints/request"
|
||||||
"k8s.io/apiserver/pkg/features"
|
"k8s.io/apiserver/pkg/features"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
@ -47,7 +49,7 @@ import (
|
|||||||
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", utiltrace.Field{Key: "url", Value: req.URL.Path}, utiltrace.Field{Key: "user-agent", Value: &lazyTruncatedUserAgent{req}}, utiltrace.Field{Key: "client", Value: &lazyClientIP{req}})
|
req, trace := requestWithTrace(req, "Create", utiltrace.Field{Key: "url", Value: req.URL.Path}, utiltrace.Field{Key: "user-agent", Value: &internal.LazyTruncatedUserAgent{req}}, utiltrace.Field{Key: "client", Value: &internal.LazyClientIP{req}})
|
||||||
defer trace.LogIfLong(500 * time.Millisecond)
|
defer trace.LogIfLong(500 * time.Millisecond)
|
||||||
|
|
||||||
if isDryRun(req.URL) && !utilfeature.DefaultFeatureGate.Enabled(features.DryRun) {
|
if isDryRun(req.URL) && !utilfeature.DefaultFeatureGate.Enabled(features.DryRun) {
|
||||||
|
@ -30,9 +30,11 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/validation"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/validation"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
|
||||||
"k8s.io/apiserver/pkg/admission"
|
"k8s.io/apiserver/pkg/admission"
|
||||||
"k8s.io/apiserver/pkg/audit"
|
"k8s.io/apiserver/pkg/audit"
|
||||||
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
|
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
|
||||||
|
"k8s.io/apiserver/pkg/endpoints/internal"
|
||||||
"k8s.io/apiserver/pkg/endpoints/request"
|
"k8s.io/apiserver/pkg/endpoints/request"
|
||||||
"k8s.io/apiserver/pkg/features"
|
"k8s.io/apiserver/pkg/features"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
@ -46,7 +48,7 @@ import (
|
|||||||
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", utiltrace.Field{Key: "url", Value: req.URL.Path}, utiltrace.Field{Key: "user-agent", Value: &lazyTruncatedUserAgent{req}}, utiltrace.Field{Key: "client", Value: &lazyClientIP{req}})
|
req, trace := requestWithTrace(req, "Delete", utiltrace.Field{Key: "url", Value: req.URL.Path}, utiltrace.Field{Key: "user-agent", Value: &internal.LazyTruncatedUserAgent{req}}, utiltrace.Field{Key: "client", Value: &internal.LazyClientIP{req}})
|
||||||
defer trace.LogIfLong(500 * time.Millisecond)
|
defer trace.LogIfLong(500 * time.Millisecond)
|
||||||
|
|
||||||
if isDryRun(req.URL) && !utilfeature.DefaultFeatureGate.Enabled(features.DryRun) {
|
if isDryRun(req.URL) && !utilfeature.DefaultFeatureGate.Enabled(features.DryRun) {
|
||||||
@ -164,7 +166,7 @@ func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope *RequestSc
|
|||||||
// 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", utiltrace.Field{"url", req.URL.Path})
|
req, trace := requestWithTrace(req, "Delete", utiltrace.Field{"url", req.URL.Path})
|
||||||
defer trace.LogIfLong(500 * time.Millisecond)
|
defer trace.LogIfLong(500 * time.Millisecond)
|
||||||
|
|
||||||
if isDryRun(req.URL) && !utilfeature.DefaultFeatureGate.Enabled(features.DryRun) {
|
if isDryRun(req.URL) && !utilfeature.DefaultFeatureGate.Enabled(features.DryRun) {
|
||||||
|
@ -36,7 +36,9 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/fields"
|
"k8s.io/apimachinery/pkg/fields"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
|
||||||
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
|
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
|
||||||
|
"k8s.io/apiserver/pkg/endpoints/internal"
|
||||||
"k8s.io/apiserver/pkg/endpoints/metrics"
|
"k8s.io/apiserver/pkg/endpoints/metrics"
|
||||||
"k8s.io/apiserver/pkg/endpoints/request"
|
"k8s.io/apiserver/pkg/endpoints/request"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
@ -51,7 +53,7 @@ type getterFunc func(ctx context.Context, name string, req *http.Request, trace
|
|||||||
// 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", utiltrace.Field{Key: "url", Value: req.URL.Path}, utiltrace.Field{Key: "user-agent", Value: &lazyTruncatedUserAgent{req}}, utiltrace.Field{Key: "client", Value: &lazyClientIP{req}})
|
req, trace := requestWithTrace(req, "Get", utiltrace.Field{Key: "url", Value: req.URL.Path}, utiltrace.Field{Key: "user-agent", Value: &internal.LazyTruncatedUserAgent{req}}, utiltrace.Field{Key: "client", Value: &internal.LazyClientIP{req}})
|
||||||
defer trace.LogIfLong(500 * time.Millisecond)
|
defer trace.LogIfLong(500 * time.Millisecond)
|
||||||
|
|
||||||
namespace, name, err := scope.Namer.Name(req)
|
namespace, name, err := scope.Namer.Name(req)
|
||||||
@ -168,7 +170,7 @@ func getRequestOptions(req *http.Request, scope *RequestScope, into runtime.Obje
|
|||||||
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", utiltrace.Field{Key: "url", Value: req.URL.Path}, utiltrace.Field{Key: "user-agent", Value: &lazyTruncatedUserAgent{req}}, utiltrace.Field{Key: "client", Value: &lazyClientIP{req}})
|
req, trace := requestWithTrace(req, "List", utiltrace.Field{Key: "url", Value: req.URL.Path}, utiltrace.Field{Key: "user-agent", Value: &internal.LazyTruncatedUserAgent{req}}, utiltrace.Field{Key: "client", Value: &internal.LazyClientIP{req}})
|
||||||
|
|
||||||
namespace, err := scope.Namer.Namespace(req)
|
namespace, err := scope.Namer.Namespace(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -38,18 +38,20 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
|
"sigs.k8s.io/yaml"
|
||||||
|
|
||||||
"k8s.io/apiserver/pkg/admission"
|
"k8s.io/apiserver/pkg/admission"
|
||||||
"k8s.io/apiserver/pkg/audit"
|
"k8s.io/apiserver/pkg/audit"
|
||||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||||
"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager"
|
"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager"
|
||||||
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
|
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
|
||||||
|
"k8s.io/apiserver/pkg/endpoints/internal"
|
||||||
"k8s.io/apiserver/pkg/endpoints/request"
|
"k8s.io/apiserver/pkg/endpoints/request"
|
||||||
"k8s.io/apiserver/pkg/features"
|
"k8s.io/apiserver/pkg/features"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
"k8s.io/apiserver/pkg/util/dryrun"
|
"k8s.io/apiserver/pkg/util/dryrun"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
utiltrace "k8s.io/utils/trace"
|
utiltrace "k8s.io/utils/trace"
|
||||||
"sigs.k8s.io/yaml"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -61,7 +63,7 @@ const (
|
|||||||
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", utiltrace.Field{Key: "url", Value: req.URL.Path}, utiltrace.Field{Key: "user-agent", Value: &lazyTruncatedUserAgent{req}}, utiltrace.Field{Key: "client", Value: &lazyClientIP{req}})
|
req, trace := requestWithTrace(req, "Patch", utiltrace.Field{Key: "url", Value: req.URL.Path}, utiltrace.Field{Key: "user-agent", Value: &internal.LazyTruncatedUserAgent{req}}, utiltrace.Field{Key: "client", Value: &internal.LazyClientIP{req}})
|
||||||
defer trace.LogIfLong(500 * time.Millisecond)
|
defer trace.LogIfLong(500 * time.Millisecond)
|
||||||
|
|
||||||
if isDryRun(req.URL) && !utilfeature.DefaultFeatureGate.Enabled(features.DryRun) {
|
if isDryRun(req.URL) && !utilfeature.DefaultFeatureGate.Enabled(features.DryRun) {
|
||||||
|
@ -47,6 +47,7 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
|
utiltrace "k8s.io/utils/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RequestScope encapsulates common fields across all RESTful handler methods.
|
// RequestScope encapsulates common fields across all RESTful handler methods.
|
||||||
@ -445,3 +446,10 @@ func isTooLargeError(err error) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// requestWithTrace returns a new trace using the provided msg and fields, nested within any trace already in the
|
||||||
|
//context of the provided req. Also returns a request with the new trace in the context.
|
||||||
|
func requestWithTrace(req *http.Request, msg string, fields ...utiltrace.Field) (*http.Request, *utiltrace.Trace) {
|
||||||
|
ctx, trace := request.WithTrace(req.Context(), msg, fields...)
|
||||||
|
return req.Clone(ctx), trace
|
||||||
|
}
|
||||||
|
@ -30,10 +30,12 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/validation"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/validation"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
|
||||||
"k8s.io/apiserver/pkg/admission"
|
"k8s.io/apiserver/pkg/admission"
|
||||||
"k8s.io/apiserver/pkg/audit"
|
"k8s.io/apiserver/pkg/audit"
|
||||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||||
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
|
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
|
||||||
|
"k8s.io/apiserver/pkg/endpoints/internal"
|
||||||
"k8s.io/apiserver/pkg/endpoints/request"
|
"k8s.io/apiserver/pkg/endpoints/request"
|
||||||
"k8s.io/apiserver/pkg/features"
|
"k8s.io/apiserver/pkg/features"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
@ -46,7 +48,7 @@ import (
|
|||||||
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", utiltrace.Field{Key: "url", Value: req.URL.Path}, utiltrace.Field{Key: "user-agent", Value: &lazyTruncatedUserAgent{req}}, utiltrace.Field{Key: "client", Value: &lazyClientIP{req}})
|
req, trace := requestWithTrace(req, "Update", utiltrace.Field{Key: "url", Value: req.URL.Path}, utiltrace.Field{Key: "user-agent", Value: &internal.LazyTruncatedUserAgent{req}}, utiltrace.Field{Key: "client", Value: &internal.LazyClientIP{req}})
|
||||||
defer trace.LogIfLong(500 * time.Millisecond)
|
defer trace.LogIfLong(500 * time.Millisecond)
|
||||||
|
|
||||||
if isDryRun(req.URL) && !utilfeature.DefaultFeatureGate.Enabled(features.DryRun) {
|
if isDryRun(req.URL) && !utilfeature.DefaultFeatureGate.Enabled(features.DryRun) {
|
||||||
|
31
staging/src/k8s.io/apiserver/pkg/endpoints/internal/BUILD
Normal file
31
staging/src/k8s.io/apiserver/pkg/endpoints/internal/BUILD
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = ["helpers.go"],
|
||||||
|
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/endpoints/internal",
|
||||||
|
importpath = "k8s.io/apiserver/pkg/endpoints/internal",
|
||||||
|
visibility = ["//staging/src/k8s.io/apiserver/pkg/endpoints:__subpackages__"],
|
||||||
|
deps = ["//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library"],
|
||||||
|
)
|
||||||
|
|
||||||
|
go_test(
|
||||||
|
name = "go_default_test",
|
||||||
|
srcs = ["helpers_test.go"],
|
||||||
|
embed = [":go_default_library"],
|
||||||
|
deps = ["//vendor/github.com/stretchr/testify/assert:go_default_library"],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "package-srcs",
|
||||||
|
srcs = glob(["**"]),
|
||||||
|
tags = ["automanaged"],
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "all-srcs",
|
||||||
|
srcs = [":package-srcs"],
|
||||||
|
tags = ["automanaged"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package handlers
|
package internal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -27,16 +27,16 @@ const (
|
|||||||
userAgentTruncateSuffix = "...TRUNCATED"
|
userAgentTruncateSuffix = "...TRUNCATED"
|
||||||
)
|
)
|
||||||
|
|
||||||
// lazyTruncatedUserAgent implements String() string and it will
|
// LazyTruncatedUserAgent implements String() string and it will
|
||||||
// return user-agent which may be truncated.
|
// return user-agent which may be truncated.
|
||||||
type lazyTruncatedUserAgent struct {
|
type LazyTruncatedUserAgent struct {
|
||||||
req *http.Request
|
Req *http.Request
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lazy *lazyTruncatedUserAgent) String() string {
|
func (lazy *LazyTruncatedUserAgent) String() string {
|
||||||
ua := "unknown"
|
ua := "unknown"
|
||||||
if lazy.req != nil {
|
if lazy.Req != nil {
|
||||||
ua = utilnet.GetHTTPClient(lazy.req)
|
ua = utilnet.GetHTTPClient(lazy.Req)
|
||||||
if len(ua) > maxUserAgentLength {
|
if len(ua) > maxUserAgentLength {
|
||||||
ua = ua[:maxUserAgentLength] + userAgentTruncateSuffix
|
ua = ua[:maxUserAgentLength] + userAgentTruncateSuffix
|
||||||
}
|
}
|
||||||
@ -46,13 +46,13 @@ func (lazy *lazyTruncatedUserAgent) String() string {
|
|||||||
|
|
||||||
// LazyClientIP implements String() string and it will
|
// LazyClientIP implements String() string and it will
|
||||||
// calls GetClientIP() lazily only when required.
|
// calls GetClientIP() lazily only when required.
|
||||||
type lazyClientIP struct {
|
type LazyClientIP struct {
|
||||||
req *http.Request
|
Req *http.Request
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lazy *lazyClientIP) String() string {
|
func (lazy *LazyClientIP) String() string {
|
||||||
if lazy.req != nil {
|
if lazy.Req != nil {
|
||||||
if ip := utilnet.GetClientIP(lazy.req); ip != nil {
|
if ip := utilnet.GetClientIP(lazy.Req); ip != nil {
|
||||||
return ip.String()
|
return ip.String()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -14,13 +14,14 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package handlers
|
package internal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestLazyTruncatedUserAgent(t *testing.T) {
|
func TestLazyTruncatedUserAgent(t *testing.T) {
|
||||||
@ -29,7 +30,7 @@ func TestLazyTruncatedUserAgent(t *testing.T) {
|
|||||||
|
|
||||||
ua := "short-agent"
|
ua := "short-agent"
|
||||||
req.Header.Set("User-Agent", ua)
|
req.Header.Set("User-Agent", ua)
|
||||||
uaNotTruncated := &lazyTruncatedUserAgent{req}
|
uaNotTruncated := &LazyTruncatedUserAgent{req}
|
||||||
assert.Equal(t, ua, fmt.Sprintf("%v", uaNotTruncated))
|
assert.Equal(t, ua, fmt.Sprintf("%v", uaNotTruncated))
|
||||||
|
|
||||||
ua = ""
|
ua = ""
|
||||||
@ -37,10 +38,10 @@ func TestLazyTruncatedUserAgent(t *testing.T) {
|
|||||||
ua = ua + "a"
|
ua = ua + "a"
|
||||||
}
|
}
|
||||||
req.Header.Set("User-Agent", ua)
|
req.Header.Set("User-Agent", ua)
|
||||||
uaTruncated := &lazyTruncatedUserAgent{req}
|
uaTruncated := &LazyTruncatedUserAgent{req}
|
||||||
assert.NotEqual(t, ua, fmt.Sprintf("%v", uaTruncated))
|
assert.NotEqual(t, ua, fmt.Sprintf("%v", uaTruncated))
|
||||||
|
|
||||||
usUnknown := &lazyTruncatedUserAgent{}
|
usUnknown := &LazyTruncatedUserAgent{}
|
||||||
assert.Equal(t, "unknown", fmt.Sprintf("%v", usUnknown))
|
assert.Equal(t, "unknown", fmt.Sprintf("%v", usUnknown))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,9 +52,9 @@ func TestLazyClientIP(t *testing.T) {
|
|||||||
ip := "127.0.0.1"
|
ip := "127.0.0.1"
|
||||||
req.Header.Set("X-Forwarded-For", ip)
|
req.Header.Set("X-Forwarded-For", ip)
|
||||||
|
|
||||||
clientIPWithReq := &lazyClientIP{req}
|
clientIPWithReq := &LazyClientIP{req}
|
||||||
assert.Equal(t, ip, fmt.Sprintf("%v", clientIPWithReq))
|
assert.Equal(t, ip, fmt.Sprintf("%v", clientIPWithReq))
|
||||||
|
|
||||||
clientIPWithoutReq := &lazyClientIP{}
|
clientIPWithoutReq := &LazyClientIP{}
|
||||||
assert.Equal(t, "unknown", fmt.Sprintf("%v", clientIPWithoutReq))
|
assert.Equal(t, "unknown", fmt.Sprintf("%v", clientIPWithoutReq))
|
||||||
}
|
}
|
@ -38,6 +38,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apiserver/pkg/apis/audit:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/apis/audit:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||||
"//vendor/k8s.io/klog/v2:go_default_library",
|
"//vendor/k8s.io/klog/v2:go_default_library",
|
||||||
|
"//vendor/k8s.io/utils/trace:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apiserver/pkg/apis/audit"
|
"k8s.io/apiserver/pkg/apis/audit"
|
||||||
"k8s.io/apiserver/pkg/authentication/user"
|
"k8s.io/apiserver/pkg/authentication/user"
|
||||||
|
utiltrace "k8s.io/utils/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The key type is unexported to prevent collisions
|
// The key type is unexported to prevent collisions
|
||||||
@ -39,6 +40,9 @@ const (
|
|||||||
|
|
||||||
// audiencesKey is the context key for request audiences.
|
// audiencesKey is the context key for request audiences.
|
||||||
audiencesKey
|
audiencesKey
|
||||||
|
|
||||||
|
// traceKey is the context key for nested tracing.
|
||||||
|
traceKey
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewContext instantiates a base context object for request flows.
|
// NewContext instantiates a base context object for request flows.
|
||||||
@ -94,3 +98,17 @@ func AuditEventFrom(ctx context.Context) *audit.Event {
|
|||||||
ev, _ := ctx.Value(auditKey).(*audit.Event)
|
ev, _ := ctx.Value(auditKey).(*audit.Event)
|
||||||
return ev
|
return ev
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TraceFrom returns the value of the trace key on the ctx
|
||||||
|
func TraceFrom(ctx context.Context) (*utiltrace.Trace, bool) {
|
||||||
|
trace, ok := ctx.Value(traceKey).(*utiltrace.Trace)
|
||||||
|
return trace, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithTrace returns a new trace using the provided msg and fields, nested within any trace already in the
|
||||||
|
// provided context. Also returns a context containing the new trace
|
||||||
|
func WithTrace(ctx context.Context, msg string, fields ...utiltrace.Field) (context.Context, *utiltrace.Trace) {
|
||||||
|
parent, _ := TraceFrom(ctx) // ignore ok since Nest can be called with a nil receiver to create root traces
|
||||||
|
trace := parent.Nest(msg, fields...)
|
||||||
|
return context.WithValue(ctx, traceKey, trace), trace
|
||||||
|
}
|
||||||
|
@ -682,6 +682,7 @@ func DefaultBuildHandlerChain(apiHandler http.Handler, c *Config) http.Handler {
|
|||||||
handler = genericfilters.WithCORS(handler, c.CorsAllowedOriginList, nil, nil, nil, "true")
|
handler = genericfilters.WithCORS(handler, c.CorsAllowedOriginList, nil, nil, nil, "true")
|
||||||
handler = genericfilters.WithTimeoutForNonLongRunningRequests(handler, c.LongRunningFunc, c.RequestTimeout)
|
handler = genericfilters.WithTimeoutForNonLongRunningRequests(handler, c.LongRunningFunc, c.RequestTimeout)
|
||||||
handler = genericfilters.WithWaitGroup(handler, c.LongRunningFunc, c.HandlerChainWaitGroup)
|
handler = genericfilters.WithWaitGroup(handler, c.LongRunningFunc, c.HandlerChainWaitGroup)
|
||||||
|
handler = genericapifilters.WithTrace(handler, c.LongRunningFunc)
|
||||||
handler = genericapifilters.WithRequestInfo(handler, c.RequestInfoResolver)
|
handler = genericapifilters.WithRequestInfo(handler, c.RequestInfoResolver)
|
||||||
if c.SecureServing != nil && !c.SecureServing.DisableHTTP2 && c.GoawayChance > 0 {
|
if c.SecureServing != nil && !c.SecureServing.DisableHTTP2 && c.GoawayChance > 0 {
|
||||||
handler = genericfilters.WithProbabilisticGoaway(handler, c.GoawayChance)
|
handler = genericfilters.WithProbabilisticGoaway(handler, c.GoawayChance)
|
||||||
|
@ -27,6 +27,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/features:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/features:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/storage:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/storage:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||||
|
@ -35,6 +35,7 @@ import (
|
|||||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
"k8s.io/apimachinery/pkg/watch"
|
"k8s.io/apimachinery/pkg/watch"
|
||||||
|
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||||
"k8s.io/apiserver/pkg/features"
|
"k8s.io/apiserver/pkg/features"
|
||||||
"k8s.io/apiserver/pkg/storage"
|
"k8s.io/apiserver/pkg/storage"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
@ -604,7 +605,7 @@ func (c *Cacher) GetToList(ctx context.Context, key string, opts storage.ListOpt
|
|||||||
return c.storage.GetToList(ctx, key, opts, listObj)
|
return c.storage.GetToList(ctx, key, opts, listObj)
|
||||||
}
|
}
|
||||||
|
|
||||||
trace := utiltrace.New("cacher list", utiltrace.Field{"type", c.objectType.String()})
|
ctx, trace := genericapirequest.WithTrace(ctx, "cacher list", utiltrace.Field{"type", c.objectType.String()})
|
||||||
defer trace.LogIfLong(500 * time.Millisecond)
|
defer trace.LogIfLong(500 * time.Millisecond)
|
||||||
|
|
||||||
c.ready.wait()
|
c.ready.wait()
|
||||||
@ -678,7 +679,7 @@ func (c *Cacher) List(ctx context.Context, key string, opts storage.ListOptions,
|
|||||||
return c.storage.List(ctx, key, opts, listObj)
|
return c.storage.List(ctx, key, opts, listObj)
|
||||||
}
|
}
|
||||||
|
|
||||||
trace := utiltrace.New("cacher list", utiltrace.Field{"type", c.objectType.String()})
|
ctx, trace := genericapirequest.WithTrace(ctx, "cacher list", utiltrace.Field{"type", c.objectType.String()})
|
||||||
defer trace.LogIfLong(500 * time.Millisecond)
|
defer trace.LogIfLong(500 * time.Millisecond)
|
||||||
|
|
||||||
c.ready.wait()
|
c.ready.wait()
|
||||||
|
@ -75,6 +75,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/features:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/features:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/storage:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/storage:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/storage/etcd3/metrics:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/storage/etcd3/metrics:go_default_library",
|
||||||
|
@ -38,6 +38,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/conversion"
|
"k8s.io/apimachinery/pkg/conversion"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/watch"
|
"k8s.io/apimachinery/pkg/watch"
|
||||||
|
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||||
"k8s.io/apiserver/pkg/features"
|
"k8s.io/apiserver/pkg/features"
|
||||||
"k8s.io/apiserver/pkg/storage"
|
"k8s.io/apiserver/pkg/storage"
|
||||||
"k8s.io/apiserver/pkg/storage/etcd3/metrics"
|
"k8s.io/apiserver/pkg/storage/etcd3/metrics"
|
||||||
@ -239,7 +240,7 @@ func (s *store) conditionalDelete(ctx context.Context, key string, out runtime.O
|
|||||||
func (s *store) GuaranteedUpdate(
|
func (s *store) GuaranteedUpdate(
|
||||||
ctx context.Context, key string, out runtime.Object, ignoreNotFound bool,
|
ctx context.Context, key string, out runtime.Object, ignoreNotFound bool,
|
||||||
preconditions *storage.Preconditions, tryUpdate storage.UpdateFunc, suggestion ...runtime.Object) error {
|
preconditions *storage.Preconditions, tryUpdate storage.UpdateFunc, suggestion ...runtime.Object) error {
|
||||||
trace := utiltrace.New("GuaranteedUpdate etcd3", utiltrace.Field{"type", getTypeName(out)})
|
ctx, trace := genericapirequest.WithTrace(ctx, "GuaranteedUpdate etcd3", utiltrace.Field{"type", getTypeName(out)})
|
||||||
defer trace.LogIfLong(500 * time.Millisecond)
|
defer trace.LogIfLong(500 * time.Millisecond)
|
||||||
|
|
||||||
v, err := conversion.EnforcePtr(out)
|
v, err := conversion.EnforcePtr(out)
|
||||||
@ -382,7 +383,7 @@ func (s *store) GetToList(ctx context.Context, key string, listOpts storage.List
|
|||||||
resourceVersion := listOpts.ResourceVersion
|
resourceVersion := listOpts.ResourceVersion
|
||||||
match := listOpts.ResourceVersionMatch
|
match := listOpts.ResourceVersionMatch
|
||||||
pred := listOpts.Predicate
|
pred := listOpts.Predicate
|
||||||
trace := utiltrace.New("GetToList etcd3",
|
ctx, trace := genericapirequest.WithTrace(ctx, "GetToList etcd3",
|
||||||
utiltrace.Field{"key", key},
|
utiltrace.Field{"key", key},
|
||||||
utiltrace.Field{"resourceVersion", resourceVersion},
|
utiltrace.Field{"resourceVersion", resourceVersion},
|
||||||
utiltrace.Field{"resourceVersionMatch", match},
|
utiltrace.Field{"resourceVersionMatch", match},
|
||||||
@ -526,7 +527,7 @@ func (s *store) List(ctx context.Context, key string, opts storage.ListOptions,
|
|||||||
resourceVersion := opts.ResourceVersion
|
resourceVersion := opts.ResourceVersion
|
||||||
match := opts.ResourceVersionMatch
|
match := opts.ResourceVersionMatch
|
||||||
pred := opts.Predicate
|
pred := opts.Predicate
|
||||||
trace := utiltrace.New("List etcd3",
|
ctx, trace := genericapirequest.WithTrace(ctx, "List etcd3",
|
||||||
utiltrace.Field{"key", key},
|
utiltrace.Field{"key", key},
|
||||||
utiltrace.Field{"resourceVersion", resourceVersion},
|
utiltrace.Field{"resourceVersion", resourceVersion},
|
||||||
utiltrace.Field{"resourceVersionMatch", match},
|
utiltrace.Field{"resourceVersionMatch", match},
|
||||||
|
1
vendor/modules.txt
vendored
1
vendor/modules.txt
vendored
@ -1329,6 +1329,7 @@ k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager
|
|||||||
k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal
|
k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal
|
||||||
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
|
||||||
|
k8s.io/apiserver/pkg/endpoints/internal
|
||||||
k8s.io/apiserver/pkg/endpoints/metrics
|
k8s.io/apiserver/pkg/endpoints/metrics
|
||||||
k8s.io/apiserver/pkg/endpoints/openapi
|
k8s.io/apiserver/pkg/endpoints/openapi
|
||||||
k8s.io/apiserver/pkg/endpoints/request
|
k8s.io/apiserver/pkg/endpoints/request
|
||||||
|
Loading…
Reference in New Issue
Block a user