Refactor to remove duplicate code from boilerplate

This commit switches to using the boilerplate versions of
a couple different utilities, including the metric info normalization
and the common error types.
This commit is contained in:
Solly Ross 2017-08-02 15:48:12 -04:00
parent 8e5cb77e7f
commit 58a9769eaa
2 changed files with 8 additions and 49 deletions

View file

@ -127,7 +127,7 @@ func (r *basicSeriesRegistry) QueryForMetric(metricInfo provider.MetricInfo, nam
return 0, "", "", false return 0, "", "", false
} }
metricInfo, singularResource, err := r.namer.normalizeInfo(metricInfo) metricInfo, singularResource, err := metricInfo.Normalized(r.namer.mapper)
if err != nil { if err != nil {
glog.Errorf("unable to normalize group resource while producing a query: %v", err) glog.Errorf("unable to normalize group resource while producing a query: %v", err)
return 0, "", "", false return 0, "", "", false
@ -167,7 +167,7 @@ func (r *basicSeriesRegistry) MatchValuesToNames(metricInfo provider.MetricInfo,
r.mu.RLock() r.mu.RLock()
defer r.mu.RUnlock() defer r.mu.RUnlock()
metricInfo, singularResource, err := r.namer.normalizeInfo(metricInfo) metricInfo, singularResource, err := metricInfo.Normalized(r.namer.mapper)
if err != nil { if err != nil {
glog.Errorf("unable to normalize group resource while matching values to names: %v", err) glog.Errorf("unable to normalize group resource while matching values to names: %v", err)
return nil, false return nil, false
@ -212,24 +212,6 @@ type seriesSpec struct {
kind SeriesType kind SeriesType
} }
// normalizeInfo takes in some metricInfo an "normalizes" it to ensure a common GroupResource form.
func (r *metricNamer) normalizeInfo(metricInfo provider.MetricInfo) (provider.MetricInfo, string, error) {
// NB: we need to "normalize" the metricInfo's GroupResource so we have a consistent pluralization, etc
// TODO: move this to the boilerplate
normalizedGroupRes, err := r.mapper.ResourceFor(metricInfo.GroupResource.WithVersion(""))
if err != nil {
return provider.MetricInfo{}, "", err
}
metricInfo.GroupResource = normalizedGroupRes.GroupResource()
singularResource, err := r.mapper.ResourceSingularizer(metricInfo.GroupResource.Resource)
if err != nil {
return provider.MetricInfo{}, "", err
}
return metricInfo, singularResource, nil
}
// processContainerSeries performs special work to extract metric definitions // processContainerSeries performs special work to extract metric definitions
// from cAdvisor-sourced container metrics, which don't particularly follow any useful conventions consistently. // from cAdvisor-sourced container metrics, which don't particularly follow any useful conventions consistently.
func (n *metricNamer) processContainerSeries(series prom.Series, infos map[provider.MetricInfo]seriesInfo) { func (n *metricNamer) processContainerSeries(series prom.Series, infos map[provider.MetricInfo]seriesInfo) {
@ -323,7 +305,7 @@ func (n *metricNamer) processRootScopedSeries(series prom.Series, infos map[prov
// going through each label, checking to see if it corresponds to a known resource. For instance, // going through each label, checking to see if it corresponds to a known resource. For instance,
// a series `ingress_http_hits_total{pod="foo",service="bar",ingress="baz",namespace="ns"}` // a series `ingress_http_hits_total{pod="foo",service="bar",ingress="baz",namespace="ns"}`
// would return three GroupResources: "pods", "services", and "ingresses". // would return three GroupResources: "pods", "services", and "ingresses".
// Returned MetricInfo is equilavent to the "normalized" info produced by normalizeInfo. // Returned MetricInfo is equilavent to the "normalized" info produced by metricInfo.Normalized.
func (n *metricNamer) groupResourcesFromSeries(series prom.Series) ([]schema.GroupResource, error) { func (n *metricNamer) groupResourcesFromSeries(series prom.Series) ([]schema.GroupResource, error) {
var res []schema.GroupResource var res []schema.GroupResource
for label := range series.Labels { for label := range series.Labels {

View file

@ -20,7 +20,6 @@ import (
"context" "context"
"fmt" "fmt"
"github.com/golang/glog" "github.com/golang/glog"
"net/http"
"time" "time"
"github.com/kubernetes-incubator/custom-metrics-apiserver/pkg/provider" "github.com/kubernetes-incubator/custom-metrics-apiserver/pkg/provider"
@ -43,28 +42,6 @@ import (
prom "github.com/directxman12/k8s-prometheus-adapter/pkg/client" prom "github.com/directxman12/k8s-prometheus-adapter/pkg/client"
) )
// newMetricNotFoundError returns a StatusError indicating the given metric could not be found.
// It is similar to NewNotFound, but more specialized
func newMetricNotFoundError(resource schema.GroupResource, metricName string) *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", metricName, resource.String()),
}}
}
// 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 newMetricNotFoundForError(resource schema.GroupResource, metricName string, resourceName string) *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", metricName, resource.String(), resourceName),
}}
}
type prometheusProvider struct { type prometheusProvider struct {
mapper apimeta.RESTMapper mapper apimeta.RESTMapper
kubeClient dynamic.ClientPool kubeClient dynamic.ClientPool
@ -128,7 +105,7 @@ func (p *prometheusProvider) metricsFor(valueSet pmodel.Vector, info provider.Me
values, found := p.MatchValuesToNames(info, valueSet) values, found := p.MatchValuesToNames(info, valueSet)
if !found { if !found {
return nil, newMetricNotFoundError(info.GroupResource, info.Metric) return nil, provider.NewMetricNotFoundError(info.GroupResource, info.Metric)
} }
res := []custom_metrics.MetricValue{} res := []custom_metrics.MetricValue{}
@ -158,7 +135,7 @@ func (p *prometheusProvider) metricsFor(valueSet pmodel.Vector, info provider.Me
func (p *prometheusProvider) buildQuery(info provider.MetricInfo, namespace string, names ...string) (pmodel.Vector, error) { func (p *prometheusProvider) buildQuery(info provider.MetricInfo, namespace string, names ...string) (pmodel.Vector, error) {
kind, baseQuery, groupBy, found := p.QueryForMetric(info, namespace, names...) kind, baseQuery, groupBy, found := p.QueryForMetric(info, namespace, names...)
if !found { if !found {
return nil, newMetricNotFoundError(info.GroupResource, info.Metric) return nil, provider.NewMetricNotFoundError(info.GroupResource, info.Metric)
} }
fullQuery := baseQuery fullQuery := baseQuery
@ -200,12 +177,12 @@ func (p *prometheusProvider) getSingle(info provider.MetricInfo, namespace, name
} }
if len(queryResults) < 1 { if len(queryResults) < 1 {
return nil, newMetricNotFoundForError(info.GroupResource, info.Metric, name) return nil, provider.NewMetricNotFoundForError(info.GroupResource, info.Metric, name)
} }
namedValues, found := p.MatchValuesToNames(info, queryResults) namedValues, found := p.MatchValuesToNames(info, queryResults)
if !found { if !found {
return nil, newMetricNotFoundError(info.GroupResource, info.Metric) return nil, provider.NewMetricNotFoundError(info.GroupResource, info.Metric)
} }
if len(namedValues) > 1 { if len(namedValues) > 1 {
@ -215,7 +192,7 @@ func (p *prometheusProvider) getSingle(info provider.MetricInfo, namespace, name
resultValue, nameFound := namedValues[name] resultValue, nameFound := namedValues[name]
if !nameFound { if !nameFound {
glog.Errorf("None of the results returned by when fetching metric %s for %q matched the resource name", info.String(), name) glog.Errorf("None of the results returned by when fetching metric %s for %q matched the resource name", info.String(), name)
return nil, newMetricNotFoundForError(info.GroupResource, info.Metric, name) return nil, provider.NewMetricNotFoundForError(info.GroupResource, info.Metric, name)
} }
return p.metricFor(resultValue, info.GroupResource, "", name, info.Metric) return p.metricFor(resultValue, info.GroupResource, "", name, info.Metric)