mirror of
https://github.com/kubernetes-sigs/prometheus-adapter.git
synced 2026-04-06 09:47:54 +00:00
vendored changes
This commit is contained in:
parent
d091fff18b
commit
128f9a29f5
522 changed files with 29974 additions and 25705 deletions
48
vendor/github.com/kubernetes-incubator/custom-metrics-apiserver/pkg/apiserver/cmapis.go
generated
vendored
48
vendor/github.com/kubernetes-incubator/custom-metrics-apiserver/pkg/apiserver/cmapis.go
generated
vendored
|
|
@ -32,31 +32,35 @@ import (
|
|||
)
|
||||
|
||||
func (s *CustomMetricsAdapterServer) InstallCustomMetricsAPI() error {
|
||||
groupInfo := genericapiserver.NewDefaultAPIGroupInfo(custom_metrics.GroupName, Scheme, metav1.ParameterCodec, Codecs)
|
||||
groupInfo := genericapiserver.NewDefaultAPIGroupInfo(custom_metrics.GroupName, Scheme, runtime.NewParameterCodec(Scheme), Codecs)
|
||||
container := s.GenericAPIServer.Handler.GoRestfulContainer
|
||||
|
||||
mainGroupVer := groupInfo.PrioritizedVersions[0]
|
||||
preferredVersionForDiscovery := metav1.GroupVersionForDiscovery{
|
||||
GroupVersion: mainGroupVer.String(),
|
||||
Version: mainGroupVer.Version,
|
||||
}
|
||||
groupVersion := metav1.GroupVersionForDiscovery{
|
||||
GroupVersion: mainGroupVer.String(),
|
||||
Version: mainGroupVer.Version,
|
||||
}
|
||||
apiGroup := metav1.APIGroup{
|
||||
Name: mainGroupVer.Group,
|
||||
Versions: []metav1.GroupVersionForDiscovery{groupVersion},
|
||||
PreferredVersion: preferredVersionForDiscovery,
|
||||
}
|
||||
// Register custom metrics REST handler for all supported API versions.
|
||||
for versionIndex, mainGroupVer := range groupInfo.PrioritizedVersions {
|
||||
preferredVersionForDiscovery := metav1.GroupVersionForDiscovery{
|
||||
GroupVersion: mainGroupVer.String(),
|
||||
Version: mainGroupVer.Version,
|
||||
}
|
||||
groupVersion := metav1.GroupVersionForDiscovery{
|
||||
GroupVersion: mainGroupVer.String(),
|
||||
Version: mainGroupVer.Version,
|
||||
}
|
||||
apiGroup := metav1.APIGroup{
|
||||
Name: mainGroupVer.Group,
|
||||
Versions: []metav1.GroupVersionForDiscovery{groupVersion},
|
||||
PreferredVersion: preferredVersionForDiscovery,
|
||||
}
|
||||
|
||||
cmAPI := s.cmAPI(&groupInfo, mainGroupVer)
|
||||
if err := cmAPI.InstallREST(s.GenericAPIServer.Handler.GoRestfulContainer); err != nil {
|
||||
return err
|
||||
cmAPI := s.cmAPI(&groupInfo, mainGroupVer)
|
||||
if err := cmAPI.InstallREST(container); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if versionIndex == 0 {
|
||||
s.GenericAPIServer.DiscoveryGroupManager.AddGroup(apiGroup)
|
||||
container.Add(discovery.NewAPIGroupHandler(s.GenericAPIServer.Serializer, apiGroup).WebService())
|
||||
}
|
||||
}
|
||||
|
||||
s.GenericAPIServer.DiscoveryGroupManager.AddGroup(apiGroup)
|
||||
s.GenericAPIServer.Handler.GoRestfulContainer.Add(discovery.NewAPIGroupHandler(s.GenericAPIServer.Serializer, apiGroup).WebService())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
175
vendor/github.com/kubernetes-incubator/custom-metrics-apiserver/pkg/apiserver/endpoints/handlers/get.go
generated
vendored
Normal file
175
vendor/github.com/kubernetes-incubator/custom-metrics-apiserver/pkg/apiserver/endpoints/handlers/get.go
generated
vendored
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
Copyright 2017 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 handlers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apiserver/pkg/endpoints/handlers"
|
||||
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
|
||||
"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters"
|
||||
"k8s.io/apiserver/pkg/endpoints/request"
|
||||
utiltrace "k8s.io/utils/trace"
|
||||
|
||||
cm_rest "github.com/kubernetes-incubator/custom-metrics-apiserver/pkg/apiserver/registry/rest"
|
||||
)
|
||||
|
||||
func ListResourceWithOptions(r cm_rest.ListerWithOptions, scope handlers.RequestScope) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, req *http.Request) {
|
||||
// For performance tracking purposes.
|
||||
trace := utiltrace.New("List " + req.URL.Path)
|
||||
|
||||
namespace, err := scope.Namer.Namespace(req)
|
||||
if err != nil {
|
||||
writeError(&scope, err, w, req)
|
||||
return
|
||||
}
|
||||
|
||||
// Watches for single objects are routed to this function.
|
||||
// Treat a name parameter the same as a field selector entry.
|
||||
hasName := true
|
||||
_, name, err := scope.Namer.Name(req)
|
||||
if err != nil {
|
||||
hasName = false
|
||||
}
|
||||
|
||||
ctx := req.Context()
|
||||
ctx = request.WithNamespace(ctx, namespace)
|
||||
|
||||
opts := metainternalversion.ListOptions{}
|
||||
if err := metainternalversion.ParameterCodec.DecodeParameters(req.URL.Query(), scope.MetaGroupVersion, &opts); err != nil {
|
||||
err = errors.NewBadRequest(err.Error())
|
||||
writeError(&scope, err, w, req)
|
||||
return
|
||||
}
|
||||
|
||||
// transform fields
|
||||
// TODO: DecodeParametersInto should do this.
|
||||
if opts.FieldSelector != nil {
|
||||
fn := func(label, value string) (newLabel, newValue string, err error) {
|
||||
return scope.Convertor.ConvertFieldLabel(scope.Kind, label, value)
|
||||
}
|
||||
if opts.FieldSelector, err = opts.FieldSelector.Transform(fn); err != nil {
|
||||
// TODO: allow bad request to set field causes based on query parameters
|
||||
err = errors.NewBadRequest(err.Error())
|
||||
writeError(&scope, err, w, req)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if hasName {
|
||||
// metadata.name is the canonical internal name.
|
||||
// SelectionPredicate will notice that this is a request for
|
||||
// a single object and optimize the storage query accordingly.
|
||||
nameSelector := fields.OneTermEqualSelector("metadata.name", name)
|
||||
|
||||
// Note that fieldSelector setting explicitly the "metadata.name"
|
||||
// will result in reaching this branch (as the value of that field
|
||||
// is propagated to requestInfo as the name parameter.
|
||||
// That said, the allowed field selectors in this branch are:
|
||||
// nil, fields.Everything and field selector matching metadata.name
|
||||
// for our name.
|
||||
if opts.FieldSelector != nil && !opts.FieldSelector.Empty() {
|
||||
selectedName, ok := opts.FieldSelector.RequiresExactMatch("metadata.name")
|
||||
if !ok || name != selectedName {
|
||||
writeError(&scope, errors.NewBadRequest("fieldSelector metadata.name doesn't match requested name"), w, req)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
opts.FieldSelector = nameSelector
|
||||
}
|
||||
}
|
||||
|
||||
// Log only long List requests (ignore Watch).
|
||||
defer trace.LogIfLong(500 * time.Millisecond)
|
||||
trace.Step("About to List from storage")
|
||||
extraOpts, hasSubpath, subpathKey := r.NewListOptions()
|
||||
if err := getRequestOptions(req, scope, extraOpts, hasSubpath, subpathKey, false); err != nil {
|
||||
err = errors.NewBadRequest(err.Error())
|
||||
writeError(&scope, err, w, req)
|
||||
return
|
||||
}
|
||||
result, err := r.List(ctx, &opts, extraOpts)
|
||||
if err != nil {
|
||||
writeError(&scope, err, w, req)
|
||||
return
|
||||
}
|
||||
trace.Step("Listing from storage done")
|
||||
numberOfItems, err := setListSelfLink(result, ctx, req, scope.Namer)
|
||||
if err != nil {
|
||||
writeError(&scope, err, w, req)
|
||||
return
|
||||
}
|
||||
trace.Step("Self-linking done")
|
||||
// Ensure empty lists return a non-nil items slice
|
||||
if numberOfItems == 0 && meta.IsListType(result) {
|
||||
if err := meta.SetList(result, []runtime.Object{}); err != nil {
|
||||
writeError(&scope, err, w, req)
|
||||
return
|
||||
}
|
||||
}
|
||||
responsewriters.WriteObjectNegotiated(scope.Serializer, negotiation.DefaultEndpointRestrictions, scope.Kind.GroupVersion(), w, req, http.StatusOK, result)
|
||||
trace.Step(fmt.Sprintf("Writing http response done (%d items)", numberOfItems))
|
||||
}
|
||||
}
|
||||
|
||||
// getRequestOptions parses out options and can include path information. The path information shouldn't include the subresource.
|
||||
func getRequestOptions(req *http.Request, scope handlers.RequestScope, into runtime.Object, hasSubpath bool, subpathKey string, isSubresource bool) error {
|
||||
if into == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
query := req.URL.Query()
|
||||
if hasSubpath {
|
||||
newQuery := make(url.Values)
|
||||
for k, v := range query {
|
||||
newQuery[k] = v
|
||||
}
|
||||
|
||||
ctx := req.Context()
|
||||
requestInfo, _ := request.RequestInfoFrom(ctx)
|
||||
startingIndex := 2
|
||||
if isSubresource {
|
||||
startingIndex = 3
|
||||
}
|
||||
|
||||
p := strings.Join(requestInfo.Parts[startingIndex:], "/")
|
||||
|
||||
// ensure non-empty subpaths correctly reflect a leading slash
|
||||
if len(p) > 0 && !strings.HasPrefix(p, "/") {
|
||||
p = "/" + p
|
||||
}
|
||||
|
||||
// ensure subpaths correctly reflect the presence of a trailing slash on the original request
|
||||
if strings.HasSuffix(requestInfo.Path, "/") && !strings.HasSuffix(p, "/") {
|
||||
p += "/"
|
||||
}
|
||||
|
||||
newQuery[subpathKey] = []string{p}
|
||||
query = newQuery
|
||||
}
|
||||
return scope.ParameterCodec.DecodeParameters(query, scope.Kind.GroupVersion(), into)
|
||||
}
|
||||
73
vendor/github.com/kubernetes-incubator/custom-metrics-apiserver/pkg/apiserver/endpoints/handlers/rest.go
generated
vendored
Normal file
73
vendor/github.com/kubernetes-incubator/custom-metrics-apiserver/pkg/apiserver/endpoints/handlers/rest.go
generated
vendored
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
Copyright 2017 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 handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apiserver/pkg/endpoints/handlers"
|
||||
"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters"
|
||||
"k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
func writeError(scope *handlers.RequestScope, err error, w http.ResponseWriter, req *http.Request) {
|
||||
responsewriters.ErrorNegotiated(err, scope.Serializer, scope.Kind.GroupVersion(), w, req)
|
||||
}
|
||||
|
||||
// setSelfLink sets the self link of an object (or the child items in a list) to the base URL of the request
|
||||
// plus the path and query generated by the provided linkFunc
|
||||
func setSelfLink(obj runtime.Object, requestInfo *request.RequestInfo, namer handlers.ScopeNamer) error {
|
||||
// TODO: SelfLink generation should return a full URL?
|
||||
uri, err := namer.GenerateLink(requestInfo, obj)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return namer.SetSelfLink(obj, uri)
|
||||
}
|
||||
|
||||
// setListSelfLink sets the self link of a list to the base URL, then sets the self links
|
||||
// on all child objects returned. Returns the number of items in the list.
|
||||
func setListSelfLink(obj runtime.Object, ctx context.Context, req *http.Request, namer handlers.ScopeNamer) (int, error) {
|
||||
if !meta.IsListType(obj) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
uri, err := namer.GenerateListLink(req)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if err := namer.SetSelfLink(obj, uri); err != nil {
|
||||
klog.V(4).Infof("Unable to set self link on object: %v", err)
|
||||
}
|
||||
requestInfo, ok := request.RequestInfoFrom(ctx)
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("missing requestInfo")
|
||||
}
|
||||
|
||||
count := 0
|
||||
err = meta.EachListItem(obj, func(obj runtime.Object) error {
|
||||
count++
|
||||
return setSelfLink(obj, requestInfo, namer)
|
||||
})
|
||||
return count, err
|
||||
}
|
||||
|
|
@ -24,9 +24,9 @@ import (
|
|||
"k8s.io/apiserver/pkg/endpoints/handlers"
|
||||
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
|
||||
"k8s.io/apiserver/pkg/endpoints/metrics"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
"github.com/kubernetes-incubator/custom-metrics-apiserver/pkg/apiserver/registry/rest"
|
||||
)
|
||||
|
||||
type CMHandlers struct{}
|
||||
|
|
@ -47,7 +47,7 @@ func (ch *CMHandlers) registerResourceHandlers(a *MetricsAPIInstaller, ws *restf
|
|||
|
||||
kind := fqKindToRegister.Kind
|
||||
|
||||
lister := a.group.DynamicStorage.(rest.Lister)
|
||||
lister := a.group.DynamicStorage.(rest.ListerWithOptions)
|
||||
list := lister.NewList()
|
||||
listGVKs, _, err := a.group.Typer.ObjectKinds(list)
|
||||
if err != nil {
|
||||
|
|
@ -64,6 +64,20 @@ func (ch *CMHandlers) registerResourceHandlers(a *MetricsAPIInstaller, ws *restf
|
|||
return err
|
||||
}
|
||||
|
||||
listOptions, _, _ := lister.NewListOptions()
|
||||
listOptionsInternalKinds, _, err := a.group.Typer.ObjectKinds(listOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
listOptionsInternalKind := listOptionsInternalKinds[0]
|
||||
versionedListExtraOptions, err := a.group.Creater.New(a.group.GroupVersion.WithKind(listOptionsInternalKind.Kind))
|
||||
if err != nil {
|
||||
versionedListExtraOptions, err = a.group.Creater.New(optionsExternalVersion.WithKind(listOptionsInternalKind.Kind))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
nameParam := ws.PathParameter("name", "name of the described resource").DataType("string")
|
||||
resourceParam := ws.PathParameter("resource", "the name of the resource").DataType("string")
|
||||
subresourceParam := ws.PathParameter("subresource", "the name of the subresource").DataType("string")
|
||||
|
|
@ -135,7 +149,7 @@ func (ch *CMHandlers) registerResourceHandlers(a *MetricsAPIInstaller, ws *restf
|
|||
reqScope.Subresource,
|
||||
"cluster",
|
||||
"custom-metrics",
|
||||
restfulListResource(lister, nil, reqScope, false, a.minRequestTimeout),
|
||||
restfulListResourceWithOptions(lister, reqScope),
|
||||
)
|
||||
|
||||
// install the root-scoped route
|
||||
|
|
@ -149,6 +163,9 @@ func (ch *CMHandlers) registerResourceHandlers(a *MetricsAPIInstaller, ws *restf
|
|||
if err := addObjectParams(ws, rootScopedRoute, versionedListOptions); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := addObjectParams(ws, rootScopedRoute, versionedListExtraOptions); err != nil {
|
||||
return err
|
||||
}
|
||||
addParams(rootScopedRoute, rootScopedParams)
|
||||
ws.Route(rootScopedRoute)
|
||||
|
||||
|
|
@ -168,7 +185,7 @@ func (ch *CMHandlers) registerResourceHandlers(a *MetricsAPIInstaller, ws *restf
|
|||
reqScope.Subresource,
|
||||
"resource",
|
||||
"custom-metrics",
|
||||
restfulListResource(lister, nil, reqScope, false, a.minRequestTimeout),
|
||||
restfulListResourceWithOptions(lister, reqScope),
|
||||
)
|
||||
|
||||
namespacedRoute := ws.GET(namespacedPath).To(namespacedHandler).
|
||||
|
|
@ -181,6 +198,9 @@ func (ch *CMHandlers) registerResourceHandlers(a *MetricsAPIInstaller, ws *restf
|
|||
if err := addObjectParams(ws, namespacedRoute, versionedListOptions); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := addObjectParams(ws, namespacedRoute, versionedListExtraOptions); err != nil {
|
||||
return err
|
||||
}
|
||||
addParams(namespacedRoute, namespacedParams)
|
||||
ws.Route(namespacedRoute)
|
||||
|
||||
|
|
@ -201,7 +221,7 @@ func (ch *CMHandlers) registerResourceHandlers(a *MetricsAPIInstaller, ws *restf
|
|||
reqScope.Subresource,
|
||||
"resource",
|
||||
"custom-metrics",
|
||||
restfulListResource(lister, nil, reqScope, false, a.minRequestTimeout),
|
||||
restfulListResourceWithOptions(lister, reqScope),
|
||||
)
|
||||
|
||||
namespaceSpecificRoute := ws.GET(namespaceSpecificPath).To(namespaceSpecificHandler).
|
||||
|
|
@ -214,6 +234,9 @@ func (ch *CMHandlers) registerResourceHandlers(a *MetricsAPIInstaller, ws *restf
|
|||
if err := addObjectParams(ws, namespaceSpecificRoute, versionedListOptions); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := addObjectParams(ws, namespaceSpecificRoute, versionedListExtraOptions); err != nil {
|
||||
return err
|
||||
}
|
||||
addParams(namespaceSpecificRoute, namespaceSpecificParams)
|
||||
ws.Route(namespaceSpecificRoute)
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ import (
|
|||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
cm_handlers "github.com/kubernetes-incubator/custom-metrics-apiserver/pkg/apiserver/endpoints/handlers"
|
||||
cm_rest "github.com/kubernetes-incubator/custom-metrics-apiserver/pkg/apiserver/registry/rest"
|
||||
)
|
||||
|
||||
// NB: the contents of this file should mostly be a subset of the functionality
|
||||
|
|
@ -283,6 +285,12 @@ func (n MetricsNaming) GenerateLink(requestInfo *request.RequestInfo, obj runtim
|
|||
|
||||
func restfulListResource(r rest.Lister, rw rest.Watcher, scope handlers.RequestScope, forceWatch bool, minRequestTimeout time.Duration) restful.RouteFunction {
|
||||
return func(req *restful.Request, res *restful.Response) {
|
||||
handlers.ListResource(r, rw, scope, forceWatch, minRequestTimeout)(res.ResponseWriter, req.Request)
|
||||
handlers.ListResource(r, rw, &scope, forceWatch, minRequestTimeout)(res.ResponseWriter, req.Request)
|
||||
}
|
||||
}
|
||||
|
||||
func restfulListResourceWithOptions(r cm_rest.ListerWithOptions, scope handlers.RequestScope) restful.RouteFunction {
|
||||
return func(req *restful.Request, res *restful.Response) {
|
||||
cm_handlers.ListResourceWithOptions(r, scope)(res.ResponseWriter, req.Request)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
45
vendor/github.com/kubernetes-incubator/custom-metrics-apiserver/pkg/apiserver/registry/rest/rest.go
generated
vendored
Normal file
45
vendor/github.com/kubernetes-incubator/custom-metrics-apiserver/pkg/apiserver/registry/rest/rest.go
generated
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
Copyright 2017 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 rest
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// ListerWithOptions is an object that can retrieve resources that match the provided field
|
||||
// and label criteria and takes additional options on the list request.
|
||||
type ListerWithOptions interface {
|
||||
// NewList returns an empty object that can be used with the List call.
|
||||
// This object must be a pointer type for use with Codec.DecodeInto([]byte, runtime.Object)
|
||||
NewList() runtime.Object
|
||||
|
||||
// List selects resources in the storage which match to the selector. 'options' can be nil.
|
||||
// The extraOptions object passed to it is of the same type returned by the NewListOptions
|
||||
// method.
|
||||
List(ctx context.Context, options *metainternalversion.ListOptions, extraOptions runtime.Object) (runtime.Object, error)
|
||||
|
||||
// NewListOptions returns an empty options object that will be used to pass extra options
|
||||
// to the List method. It may return a bool and a string, if true, the
|
||||
// value of the request path below the list will be included as the named
|
||||
// string in the serialization of the runtime object. E.g., returning "path"
|
||||
// will convert the trailing request scheme value to "path" in the map[string][]string
|
||||
// passed to the converter.
|
||||
NewListOptions() (runtime.Object, bool, string)
|
||||
}
|
||||
12
vendor/github.com/kubernetes-incubator/custom-metrics-apiserver/pkg/provider/errors.go
generated
vendored
12
vendor/github.com/kubernetes-incubator/custom-metrics-apiserver/pkg/provider/errors.go
generated
vendored
|
|
@ -23,6 +23,7 @@ import (
|
|||
apierr "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
|
|
@ -47,3 +48,14 @@ func NewMetricNotFoundForError(resource schema.GroupResource, metricName string,
|
|||
Message: fmt.Sprintf("the server could not find the metric %s for %s %s", metricName, resource.String(), resourceName),
|
||||
}}
|
||||
}
|
||||
|
||||
// NewMetricNotFoundForError returns a StatusError indicating the given metric could not be found for
|
||||
// the given named object. It is similar to NewNotFound, but more specialized
|
||||
func NewMetricNotFoundForSelectorError(resource schema.GroupResource, metricName string, resourceName string, selector labels.Selector) *apierr.StatusError {
|
||||
return &apierr.StatusError{metav1.Status{
|
||||
Status: metav1.StatusFailure,
|
||||
Code: int32(http.StatusNotFound),
|
||||
Reason: metav1.StatusReasonNotFound,
|
||||
Message: fmt.Sprintf("the server could not find the metric %s for %s %s with selector %s", metricName, resource.String(), resourceName, selector.String()),
|
||||
}}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,11 +84,11 @@ func (i CustomMetricInfo) Normalized(mapper apimeta.RESTMapper) (normalizedInfo
|
|||
type CustomMetricsProvider interface {
|
||||
// GetMetricByName fetches a particular metric for a particular object.
|
||||
// The namespace will be empty if the metric is root-scoped.
|
||||
GetMetricByName(name types.NamespacedName, info CustomMetricInfo) (*custom_metrics.MetricValue, error)
|
||||
GetMetricByName(name types.NamespacedName, info CustomMetricInfo, metricSelector labels.Selector) (*custom_metrics.MetricValue, error)
|
||||
|
||||
// GetMetricBySelector fetches a particular metric for a set of objects matching
|
||||
// the given label selector. The namespace will be empty if the metric is root-scoped.
|
||||
GetMetricBySelector(namespace string, selector labels.Selector, info CustomMetricInfo) (*custom_metrics.MetricValueList, error)
|
||||
GetMetricBySelector(namespace string, selector labels.Selector, info CustomMetricInfo, metricSelector labels.Selector) (*custom_metrics.MetricValueList, error)
|
||||
|
||||
// ListAllMetrics provides a list of all available metrics at
|
||||
// the current time. Note that this is not allowed to return
|
||||
|
|
@ -98,7 +98,7 @@ type CustomMetricsProvider interface {
|
|||
}
|
||||
|
||||
// ExternalMetricsProvider is a source of external metrics.
|
||||
// Metric is normally idendified by a name and a set of labels/tags. It is up to a specific
|
||||
// Metric is normally identified by a name and a set of labels/tags. It is up to a specific
|
||||
// implementation how to translate metricSelector to a filter for metric values.
|
||||
// Namespace can be used by the implemetation for metric identification, access control or ignored.
|
||||
type ExternalMetricsProvider interface {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,9 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
cm_rest "github.com/kubernetes-incubator/custom-metrics-apiserver/pkg/apiserver/registry/rest"
|
||||
"github.com/kubernetes-incubator/custom-metrics-apiserver/pkg/provider"
|
||||
|
||||
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
|
@ -37,7 +39,7 @@ type REST struct {
|
|||
}
|
||||
|
||||
var _ rest.Storage = &REST{}
|
||||
var _ rest.Lister = &REST{}
|
||||
var _ cm_rest.ListerWithOptions = &REST{}
|
||||
|
||||
func NewREST(cmProvider provider.CustomMetricsProvider) *REST {
|
||||
return &REST{
|
||||
|
|
@ -51,19 +53,37 @@ func (r *REST) New() runtime.Object {
|
|||
return &custom_metrics.MetricValue{}
|
||||
}
|
||||
|
||||
// Implement Lister
|
||||
// Implement ListerWithOptions
|
||||
|
||||
func (r *REST) NewList() runtime.Object {
|
||||
return &custom_metrics.MetricValueList{}
|
||||
}
|
||||
|
||||
func (r *REST) List(ctx context.Context, options *metainternalversion.ListOptions) (runtime.Object, error) {
|
||||
func (r *REST) NewListOptions() (runtime.Object, bool, string) {
|
||||
return &custom_metrics.MetricListOptions{}, true, "metricName"
|
||||
}
|
||||
|
||||
func (r *REST) List(ctx context.Context, options *metainternalversion.ListOptions, metricOpts runtime.Object) (runtime.Object, error) {
|
||||
metricOptions, ok := metricOpts.(*custom_metrics.MetricListOptions)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid options object: %#v", options)
|
||||
}
|
||||
|
||||
// populate the label selector, defaulting to all
|
||||
selector := labels.Everything()
|
||||
if options != nil && options.LabelSelector != nil {
|
||||
selector = options.LabelSelector
|
||||
}
|
||||
|
||||
metricLabelSelector := labels.Everything()
|
||||
if metricOptions != nil && len(metricOptions.MetricLabelSelector) > 0 {
|
||||
sel, err := labels.Parse(metricOptions.MetricLabelSelector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
metricLabelSelector = sel
|
||||
}
|
||||
|
||||
// grab the name, if present, from the field selector list options
|
||||
// (this is how the list handler logic injects it)
|
||||
// (otherwise we'd have to write a custom list handler)
|
||||
|
|
@ -97,18 +117,18 @@ func (r *REST) List(ctx context.Context, options *metainternalversion.ListOption
|
|||
|
||||
// handle namespaced and root metrics
|
||||
if name == "*" {
|
||||
return r.handleWildcardOp(namespace, groupResource, selector, metricName)
|
||||
return r.handleWildcardOp(namespace, groupResource, selector, metricName, metricLabelSelector)
|
||||
} else {
|
||||
return r.handleIndividualOp(namespace, groupResource, name, metricName)
|
||||
return r.handleIndividualOp(namespace, groupResource, name, metricName, metricLabelSelector)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *REST) handleIndividualOp(namespace string, groupResource schema.GroupResource, name string, metricName string) (*custom_metrics.MetricValueList, error) {
|
||||
func (r *REST) handleIndividualOp(namespace string, groupResource schema.GroupResource, name string, metricName string, metricLabelSelector labels.Selector) (*custom_metrics.MetricValueList, error) {
|
||||
singleRes, err := r.cmProvider.GetMetricByName(types.NamespacedName{Namespace: namespace, Name: name}, provider.CustomMetricInfo{
|
||||
GroupResource: groupResource,
|
||||
Metric: metricName,
|
||||
Namespaced: namespace != "",
|
||||
})
|
||||
}, metricLabelSelector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -118,10 +138,10 @@ func (r *REST) handleIndividualOp(namespace string, groupResource schema.GroupRe
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (r *REST) handleWildcardOp(namespace string, groupResource schema.GroupResource, selector labels.Selector, metricName string) (*custom_metrics.MetricValueList, error) {
|
||||
func (r *REST) handleWildcardOp(namespace string, groupResource schema.GroupResource, selector labels.Selector, metricName string, metricLabelSelector labels.Selector) (*custom_metrics.MetricValueList, error) {
|
||||
return r.cmProvider.GetMetricBySelector(namespace, selector, provider.CustomMetricInfo{
|
||||
GroupResource: groupResource,
|
||||
Metric: metricName,
|
||||
Namespaced: namespace != "",
|
||||
})
|
||||
}, metricLabelSelector)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue