mirror of
https://github.com/kubernetes-sigs/prometheus-adapter.git
synced 2026-04-06 17:57:51 +00:00
Stubbing out metric converters.
This commit is contained in:
parent
b3d99534a8
commit
a69a5cbbcc
5 changed files with 213 additions and 30 deletions
|
|
@ -1,29 +1,14 @@
|
|||
/*
|
||||
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 provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
pmodel "github.com/prometheus/common/model"
|
||||
|
||||
conv "github.com/directxman12/k8s-prometheus-adapter/pkg/custom-provider/metric-converter"
|
||||
"github.com/kubernetes-incubator/custom-metrics-apiserver/pkg/provider"
|
||||
|
||||
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/dynamic"
|
||||
|
|
@ -32,16 +17,22 @@ import (
|
|||
prom "github.com/directxman12/k8s-prometheus-adapter/pkg/client"
|
||||
)
|
||||
|
||||
//TODO: Make sure everything has the proper licensing disclosure at the top.
|
||||
//TODO: I'd like to move these files into another directory, but the compiler was giving me
|
||||
//some static around unexported types. I'm going to leave things as-is for now, but it
|
||||
//might be worthwhile to, once the shared components are discovered, move some things around.
|
||||
|
||||
//TODO: Some of these members may not be necessary.
|
||||
//Some of them are definitely duplicated between the
|
||||
//external and custom providers. They should probably share
|
||||
//the same instances of these objects (especially the SeriesRegistry)
|
||||
//to cut down on unnecessary chatter/bookkeeping.
|
||||
type externalPrometheusProvider struct {
|
||||
mapper apimeta.RESTMapper
|
||||
kubeClient dynamic.Interface
|
||||
promClient prom.Client
|
||||
queryBuilder ExternalMetricQueryBuilder
|
||||
mapper apimeta.RESTMapper
|
||||
kubeClient dynamic.Interface
|
||||
promClient prom.Client
|
||||
queryBuilder ExternalMetricQueryBuilder
|
||||
metricConverter conv.MetricConverter
|
||||
|
||||
SeriesRegistry
|
||||
}
|
||||
|
|
@ -52,7 +43,8 @@ type externalPrometheusProvider struct {
|
|||
//Just glancing at start.go looks like it would be much more straightforward
|
||||
//to do one of those two things instead of trying to run the two providers
|
||||
//independently.
|
||||
func NewExternalPrometheusProvider(mapper apimeta.RESTMapper, kubeClient dynamic.Interface, promClient prom.Client, namers []MetricNamer, updateInterval time.Duration, queryBuilder ExternalMetricQueryBuilder) (provider.ExternalMetricsProvider, Runnable) {
|
||||
|
||||
func NewExternalPrometheusProvider(mapper apimeta.RESTMapper, kubeClient dynamic.Interface, promClient prom.Client, namers []MetricNamer, updateInterval time.Duration, queryBuilder ExternalMetricQueryBuilder, metricConverter conv.MetricConverter) (provider.ExternalMetricsProvider, Runnable) {
|
||||
lister := &cachingMetricsLister{
|
||||
updateInterval: updateInterval,
|
||||
promClient: promClient,
|
||||
|
|
@ -64,9 +56,10 @@ func NewExternalPrometheusProvider(mapper apimeta.RESTMapper, kubeClient dynamic
|
|||
}
|
||||
|
||||
return &externalPrometheusProvider{
|
||||
mapper: mapper,
|
||||
kubeClient: kubeClient,
|
||||
promClient: promClient,
|
||||
mapper: mapper,
|
||||
kubeClient: kubeClient,
|
||||
promClient: promClient,
|
||||
metricConverter: metricConverter,
|
||||
|
||||
SeriesRegistry: lister,
|
||||
}, lister
|
||||
|
|
@ -79,12 +72,13 @@ func (p *externalPrometheusProvider) GetExternalMetric(namespace string, metricN
|
|||
//TODO: I don't yet know what a context is, but apparently I should use a real one.
|
||||
queryResults, err := p.promClient.Query(context.TODO(), pmodel.Now(), selector)
|
||||
|
||||
//TODO: Only here to stop compiler issues in this incomplete code.
|
||||
fmt.Printf("%s, %s", queryResults, err)
|
||||
if err != nil {
|
||||
//TODO: Is this how folks normally deal w/ errors? Just propagate them upwards?
|
||||
//I should go look at what the customProvider does.
|
||||
return nil, err
|
||||
}
|
||||
|
||||
//TODO: Check for errors. See what the custromPrometheusProvider does for errors.
|
||||
//TODO: Adapt the results in queryResults to the appropriate return type.
|
||||
return nil, nil
|
||||
return p.metricConverter.Convert(queryResults)
|
||||
}
|
||||
|
||||
func (p *externalPrometheusProvider) ListAllExternalMetrics() []provider.ExternalMetricInfo {
|
||||
|
|
|
|||
37
pkg/custom-provider/metric-converter/matrix_converter.go
Normal file
37
pkg/custom-provider/metric-converter/matrix_converter.go
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
package provider
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
prom "github.com/directxman12/k8s-prometheus-adapter/pkg/client"
|
||||
"github.com/prometheus/common/model"
|
||||
"k8s.io/metrics/pkg/apis/external_metrics"
|
||||
)
|
||||
|
||||
type matrixConverter struct {
|
||||
}
|
||||
|
||||
//NewMatrixConverter creates a MatrixConverter capable of converting
|
||||
//matrix Prometheus query results into external metric types.
|
||||
func NewMatrixConverter() MetricConverter {
|
||||
return &matrixConverter{}
|
||||
}
|
||||
|
||||
func (c *matrixConverter) Convert(queryResult prom.QueryResult) (*external_metrics.ExternalMetricValueList, error) {
|
||||
if queryResult.Type != model.ValMatrix {
|
||||
return nil, errors.New("matrixConverter can only convert scalar query results")
|
||||
}
|
||||
|
||||
toConvert := queryResult.Matrix
|
||||
|
||||
if toConvert == nil {
|
||||
return nil, errors.New("the provided input did not contain matrix query results")
|
||||
}
|
||||
|
||||
return c.convert(toConvert)
|
||||
}
|
||||
|
||||
func (c *matrixConverter) convert(result *model.Matrix) (*external_metrics.ExternalMetricValueList, error) {
|
||||
//TODO: Implementation.
|
||||
return nil, nil
|
||||
}
|
||||
47
pkg/custom-provider/metric-converter/metric_converter.go
Normal file
47
pkg/custom-provider/metric-converter/metric_converter.go
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
package provider
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
prom "github.com/directxman12/k8s-prometheus-adapter/pkg/client"
|
||||
"github.com/prometheus/common/model"
|
||||
"k8s.io/metrics/pkg/apis/external_metrics"
|
||||
)
|
||||
|
||||
//MetricConverter provides a unified interface for converting the results of
|
||||
//Prometheus queries into external metric types.
|
||||
type MetricConverter interface {
|
||||
Convert(queryResult prom.QueryResult) (*external_metrics.ExternalMetricValueList, error)
|
||||
}
|
||||
|
||||
type metricConverter struct {
|
||||
scalarConverter MetricConverter
|
||||
vectorConverter MetricConverter
|
||||
matrixConverter MetricConverter
|
||||
}
|
||||
|
||||
//NewMetricConverter creates a MetricCoverter, capable of converting any of the three metric types
|
||||
//returned by the Prometheus client into external metrics types.
|
||||
func NewMetricConverter(scalar MetricConverter, vector MetricConverter, matrix MetricConverter) MetricConverter {
|
||||
return &metricConverter{
|
||||
scalarConverter: scalar,
|
||||
vectorConverter: vector,
|
||||
matrixConverter: matrix,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *metricConverter) Convert(queryResult prom.QueryResult) (*external_metrics.ExternalMetricValueList, error) {
|
||||
if queryResult.Type == model.ValScalar {
|
||||
return c.scalarConverter.Convert(queryResult)
|
||||
}
|
||||
|
||||
if queryResult.Type == model.ValVector {
|
||||
return c.vectorConverter.Convert(queryResult)
|
||||
}
|
||||
|
||||
if queryResult.Type == model.ValMatrix {
|
||||
return c.matrixConverter.Convert(queryResult)
|
||||
}
|
||||
|
||||
return nil, errors.New("encountered an unexpected query result type")
|
||||
}
|
||||
68
pkg/custom-provider/metric-converter/scalar_converter.go
Normal file
68
pkg/custom-provider/metric-converter/scalar_converter.go
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
package provider
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
prom "github.com/directxman12/k8s-prometheus-adapter/pkg/client"
|
||||
"github.com/prometheus/common/model"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/metrics/pkg/apis/external_metrics"
|
||||
)
|
||||
|
||||
type scalarConverter struct {
|
||||
}
|
||||
|
||||
//NewScalarConverter creates a ScalarConverter capable of converting
|
||||
//scalar Prometheus query results into external metric types.
|
||||
func NewScalarConverter() MetricConverter {
|
||||
return &scalarConverter{}
|
||||
}
|
||||
|
||||
func (c *scalarConverter) Convert(queryResult prom.QueryResult) (*external_metrics.ExternalMetricValueList, error) {
|
||||
if queryResult.Type != model.ValScalar {
|
||||
return nil, errors.New("scalarConverter can only convert scalar query results")
|
||||
}
|
||||
|
||||
toConvert := queryResult.Scalar
|
||||
|
||||
if toConvert == nil {
|
||||
return nil, errors.New("the provided input did not contain scalar query results")
|
||||
}
|
||||
|
||||
return c.convert(toConvert)
|
||||
}
|
||||
|
||||
func (c *scalarConverter) convert(input *model.Scalar) (*external_metrics.ExternalMetricValueList, error) {
|
||||
tempWindow := int64(0)
|
||||
result := external_metrics.ExternalMetricValueList{
|
||||
//TODO: Where should all of these values come from?
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "?",
|
||||
APIVersion: "?",
|
||||
},
|
||||
ListMeta: metav1.ListMeta{
|
||||
SelfLink: "?",
|
||||
ResourceVersion: "?",
|
||||
Continue: "?",
|
||||
},
|
||||
Items: []external_metrics.ExternalMetricValue{
|
||||
external_metrics.ExternalMetricValue{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "?",
|
||||
APIVersion: "?",
|
||||
},
|
||||
//TODO: Carry forward the metric name so we can set it here.
|
||||
MetricName: "?",
|
||||
Timestamp: metav1.Time{
|
||||
input.Timestamp.Time(),
|
||||
},
|
||||
//TODO: Carry forward some information about our configuration so we can provide it here.
|
||||
WindowSeconds: &tempWindow,
|
||||
//TODO: Jump through the necessary hoops to convert our number into the proper type.
|
||||
Value: resource.Quantity{},
|
||||
},
|
||||
},
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
37
pkg/custom-provider/metric-converter/vector_converter.go
Normal file
37
pkg/custom-provider/metric-converter/vector_converter.go
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
package provider
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
prom "github.com/directxman12/k8s-prometheus-adapter/pkg/client"
|
||||
"github.com/prometheus/common/model"
|
||||
"k8s.io/metrics/pkg/apis/external_metrics"
|
||||
)
|
||||
|
||||
type vectorConverter struct {
|
||||
}
|
||||
|
||||
//NewVectorConverter creates a VectorConverter capable of converting
|
||||
//vector Prometheus query results into external metric types.
|
||||
func NewVectorConverter() MetricConverter {
|
||||
return &vectorConverter{}
|
||||
}
|
||||
|
||||
func (c *vectorConverter) Convert(queryResult prom.QueryResult) (*external_metrics.ExternalMetricValueList, error) {
|
||||
if queryResult.Type != model.ValVector {
|
||||
return nil, errors.New("vectorConverter can only convert scalar query results")
|
||||
}
|
||||
|
||||
toConvert := queryResult.Vector
|
||||
|
||||
if toConvert == nil {
|
||||
return nil, errors.New("the provided input did not contain vector query results")
|
||||
}
|
||||
|
||||
return c.convert(toConvert)
|
||||
}
|
||||
|
||||
func (c *vectorConverter) convert(result *model.Vector) (*external_metrics.ExternalMetricValueList, error) {
|
||||
//TODO: Implementation.
|
||||
return nil, nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue