From a528fe4f942af8fc03973ac3925ee2649387fb32 Mon Sep 17 00:00:00 2001 From: Olivier Lemasle Date: Mon, 2 Jan 2023 17:21:55 +0100 Subject: [PATCH] Fix panic for some invalid custom metric requests This refactors the handling of metrics related to namespaces, by moving the logic from the storage part to the handler. This allows the handler to perform validation of the request. --- pkg/apiserver/endpoints/handlers/get.go | 23 ++++++++++++++++++++++ pkg/registry/custom_metrics/reststorage.go | 9 --------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/pkg/apiserver/endpoints/handlers/get.go b/pkg/apiserver/endpoints/handlers/get.go index 0f4ad95b..1ce71623 100644 --- a/pkg/apiserver/endpoints/handlers/get.go +++ b/pkg/apiserver/endpoints/handlers/get.go @@ -41,6 +41,29 @@ func ListResourceWithOptions(r cm_rest.ListerWithOptions, scope handlers.Request // For performance tracking purposes. trace := utiltrace.New("List " + req.URL.Path) + requestInfo, ok := request.RequestInfoFrom(req.Context()) + if !ok { + err := errors.NewBadRequest("missing requestInfo") + writeError(&scope, err, w, req) + return + } + + // handle metrics describing namespaces + if requestInfo.Namespace != "" && requestInfo.Resource == "metrics" { + requestInfo.Subresource = requestInfo.Name + requestInfo.Name = requestInfo.Namespace + requestInfo.Resource = "namespaces" + requestInfo.Namespace = "" + requestInfo.Parts = append([]string{"namespaces", requestInfo.Name}, requestInfo.Parts[1:]...) + } + + // handle invalid requests, e.g. /namespaces/name/foo + if len(requestInfo.Parts) < 3 { + err := errors.NewBadRequest("invalid request path") + writeError(&scope, err, w, req) + return + } + namespace, err := scope.Namer.Namespace(req) if err != nil { writeError(&scope, err, w, req) diff --git a/pkg/registry/custom_metrics/reststorage.go b/pkg/registry/custom_metrics/reststorage.go index 79b27a23..1b703eef 100644 --- a/pkg/registry/custom_metrics/reststorage.go +++ b/pkg/registry/custom_metrics/reststorage.go @@ -112,15 +112,6 @@ func (r *REST) List(ctx context.Context, options *metainternalversion.ListOption groupResource := schema.ParseGroupResource(resourceRaw) - // handle metrics describing namespaces - if namespace != "" && resourceRaw == "metrics" { - // namespace-describing metrics have a path of /namespaces/$NS/metrics/$metric, - groupResource = schema.GroupResource{Resource: "namespaces"} - metricName = name - name = namespace - namespace = "" - } - var res *custom_metrics.MetricValueList var err error