mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 20:24:09 +00:00
Fix bug: Specical GET should be transformed to WATCH
This commit is contained in:
parent
d9896a23bc
commit
5f98d8f798
@ -380,7 +380,7 @@ func RecordRequestAbort(req *http.Request, requestInfo *request.RequestInfo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
scope := CleanScope(requestInfo)
|
scope := CleanScope(requestInfo)
|
||||||
reportedVerb := cleanVerb(CanonicalVerb(strings.ToUpper(req.Method), scope), "", req)
|
reportedVerb := cleanVerb(CanonicalVerb(strings.ToUpper(req.Method), scope), getVerbIfWatch(req), req)
|
||||||
resource := requestInfo.Resource
|
resource := requestInfo.Resource
|
||||||
subresource := requestInfo.Subresource
|
subresource := requestInfo.Subresource
|
||||||
group := requestInfo.APIGroup
|
group := requestInfo.APIGroup
|
||||||
@ -403,7 +403,7 @@ func RecordRequestTermination(req *http.Request, requestInfo *request.RequestInf
|
|||||||
// InstrumentRouteFunc which is registered in installer.go with predefined
|
// InstrumentRouteFunc which is registered in installer.go with predefined
|
||||||
// list of verbs (different than those translated to RequestInfo).
|
// list of verbs (different than those translated to RequestInfo).
|
||||||
// However, we need to tweak it e.g. to differentiate GET from LIST.
|
// However, we need to tweak it e.g. to differentiate GET from LIST.
|
||||||
reportedVerb := cleanVerb(CanonicalVerb(strings.ToUpper(req.Method), scope), "", req)
|
reportedVerb := cleanVerb(CanonicalVerb(strings.ToUpper(req.Method), scope), getVerbIfWatch(req), req)
|
||||||
|
|
||||||
if requestInfo.IsResourceRequest {
|
if requestInfo.IsResourceRequest {
|
||||||
requestTerminationsTotal.WithContext(req.Context()).WithLabelValues(reportedVerb, requestInfo.APIGroup, requestInfo.APIVersion, requestInfo.Resource, requestInfo.Subresource, scope, component, codeToString(code)).Inc()
|
requestTerminationsTotal.WithContext(req.Context()).WithLabelValues(reportedVerb, requestInfo.APIGroup, requestInfo.APIVersion, requestInfo.Resource, requestInfo.Subresource, scope, component, codeToString(code)).Inc()
|
||||||
@ -425,7 +425,7 @@ func RecordLongRunning(req *http.Request, requestInfo *request.RequestInfo, comp
|
|||||||
// InstrumentRouteFunc which is registered in installer.go with predefined
|
// InstrumentRouteFunc which is registered in installer.go with predefined
|
||||||
// list of verbs (different than those translated to RequestInfo).
|
// list of verbs (different than those translated to RequestInfo).
|
||||||
// However, we need to tweak it e.g. to differentiate GET from LIST.
|
// However, we need to tweak it e.g. to differentiate GET from LIST.
|
||||||
reportedVerb := cleanVerb(CanonicalVerb(strings.ToUpper(req.Method), scope), "", req)
|
reportedVerb := cleanVerb(CanonicalVerb(strings.ToUpper(req.Method), scope), getVerbIfWatch(req), req)
|
||||||
|
|
||||||
if requestInfo.IsResourceRequest {
|
if requestInfo.IsResourceRequest {
|
||||||
e = longRunningRequestsGauge.WithContext(req.Context()).WithLabelValues(reportedVerb, requestInfo.APIGroup, requestInfo.APIVersion, requestInfo.Resource, requestInfo.Subresource, scope, component)
|
e = longRunningRequestsGauge.WithContext(req.Context()).WithLabelValues(reportedVerb, requestInfo.APIGroup, requestInfo.APIVersion, requestInfo.Resource, requestInfo.Subresource, scope, component)
|
||||||
@ -544,13 +544,8 @@ func CanonicalVerb(verb string, scope string) string {
|
|||||||
// LIST and APPLY from PATCH.
|
// LIST and APPLY from PATCH.
|
||||||
func CleanVerb(verb string, request *http.Request) string {
|
func CleanVerb(verb string, request *http.Request) string {
|
||||||
reportedVerb := verb
|
reportedVerb := verb
|
||||||
if verb == "LIST" {
|
if verb == "LIST" && checkIfWatch(request) {
|
||||||
// see apimachinery/pkg/runtime/conversion.go Convert_Slice_string_To_bool
|
reportedVerb = "WATCH"
|
||||||
if values := request.URL.Query()["watch"]; len(values) > 0 {
|
|
||||||
if value := strings.ToLower(values[0]); value != "0" && value != "false" {
|
|
||||||
reportedVerb = "WATCH"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// normalize the legacy WATCHLIST to WATCH to ensure users aren't surprised by metrics
|
// normalize the legacy WATCHLIST to WATCH to ensure users aren't surprised by metrics
|
||||||
if verb == "WATCHLIST" {
|
if verb == "WATCHLIST" {
|
||||||
@ -564,13 +559,15 @@ func CleanVerb(verb string, request *http.Request) string {
|
|||||||
|
|
||||||
// cleanVerb additionally ensures that unknown verbs don't clog up the metrics.
|
// cleanVerb additionally ensures that unknown verbs don't clog up the metrics.
|
||||||
func cleanVerb(verb, suggestedVerb string, request *http.Request) string {
|
func cleanVerb(verb, suggestedVerb string, request *http.Request) string {
|
||||||
reportedVerb := CleanVerb(verb, request)
|
|
||||||
// CanonicalVerb (being an input for this function) doesn't handle correctly the
|
// CanonicalVerb (being an input for this function) doesn't handle correctly the
|
||||||
// deprecated path pattern for watch of:
|
// deprecated path pattern for watch of:
|
||||||
// GET /api/{version}/watch/{resource}
|
// GET /api/{version}/watch/{resource}
|
||||||
// We correct it manually based on the pass verb from the installer.
|
// We correct it manually based on the pass verb from the installer.
|
||||||
|
var reportedVerb string
|
||||||
if suggestedVerb == "WATCH" || suggestedVerb == "WATCHLIST" {
|
if suggestedVerb == "WATCH" || suggestedVerb == "WATCHLIST" {
|
||||||
reportedVerb = "WATCH"
|
reportedVerb = "WATCH"
|
||||||
|
} else {
|
||||||
|
reportedVerb = CleanVerb(verb, request)
|
||||||
}
|
}
|
||||||
if validRequestMethods.Has(reportedVerb) {
|
if validRequestMethods.Has(reportedVerb) {
|
||||||
return reportedVerb
|
return reportedVerb
|
||||||
@ -578,6 +575,27 @@ func cleanVerb(verb, suggestedVerb string, request *http.Request) string {
|
|||||||
return OtherRequestMethod
|
return OtherRequestMethod
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//getVerbIfWatch additionally ensures that GET or List would be transformed to WATCH
|
||||||
|
func getVerbIfWatch(req *http.Request) string {
|
||||||
|
if strings.ToUpper(req.Method) == "GET" || strings.ToUpper(req.Method) == "LIST" {
|
||||||
|
if checkIfWatch(req) {
|
||||||
|
return "WATCH"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
//checkIfWatch check request is watch
|
||||||
|
func checkIfWatch(req *http.Request) bool {
|
||||||
|
// see apimachinery/pkg/runtime/conversion.go Convert_Slice_string_To_bool
|
||||||
|
if values := req.URL.Query()["watch"]; len(values) > 0 {
|
||||||
|
if value := strings.ToLower(values[0]); value != "0" && value != "false" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func cleanDryRun(u *url.URL) string {
|
func cleanDryRun(u *url.URL) string {
|
||||||
// avoid allocating when we don't see dryRun in the query
|
// avoid allocating when we don't see dryRun in the query
|
||||||
if !strings.Contains(u.RawQuery, "dryRun") {
|
if !strings.Contains(u.RawQuery, "dryRun") {
|
||||||
|
@ -65,6 +65,16 @@ func TestCleanVerb(t *testing.T) {
|
|||||||
},
|
},
|
||||||
expectedVerb: "LIST",
|
expectedVerb: "LIST",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
desc: "GET isn't be transformed to WATCH if we have the right query param on the request",
|
||||||
|
initialVerb: "GET",
|
||||||
|
request: &http.Request{
|
||||||
|
URL: &url.URL{
|
||||||
|
RawQuery: "watch=true",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedVerb: "GET",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
desc: "LIST is transformed to WATCH for the old pattern watch",
|
desc: "LIST is transformed to WATCH for the old pattern watch",
|
||||||
initialVerb: "LIST",
|
initialVerb: "LIST",
|
||||||
|
Loading…
Reference in New Issue
Block a user