A touch more work on GetExternalMetric.

Also added some comments for anyone reviewing this to help explain what I'm thinking.
This commit is contained in:
Tony Compton 2018-06-27 22:11:28 -04:00
parent 3727f99343
commit 5533ff7580
2 changed files with 22 additions and 25 deletions

View file

@ -17,9 +17,12 @@ limitations under the License.
package provider
import (
"context"
"fmt"
"time"
pmodel "github.com/prometheus/common/model"
"github.com/kubernetes-incubator/custom-metrics-apiserver/pkg/provider"
apimeta "k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/labels"
@ -29,6 +32,11 @@ import (
prom "github.com/directxman12/k8s-prometheus-adapter/pkg/client"
)
//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
@ -38,6 +46,12 @@ type externalPrometheusProvider struct {
SeriesRegistry
}
//TODO: It probably makes more sense to, once this is functional and complete, roll the
//customPrometheusProvider and externalPrometheusProvider up into a single type
//that implements both interfaces or provide a thin wrapper that composes them.
//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) {
lister := &cachingMetricsLister{
updateInterval: updateInterval,
@ -59,21 +73,17 @@ func NewExternalPrometheusProvider(mapper apimeta.RESTMapper, kubeClient dynamic
}
func (p *externalPrometheusProvider) GetExternalMetric(namespace string, metricName string, metricSelector labels.Selector) (*external_metrics.ExternalMetricValueList, error) {
//TODO: Steps
//1. Generate a Prometheus Query.
// Something like my_metric{namespace="namespace" some_label="some_value"}
//2. Send that query to Prometheus.
//3. Adapt the results.
//The query generation for external metrics is much more straightforward
//than for custom metrics because no renaming is applied.
//So we'll just start with some simple string operations and see how far that gets us.
//Then I'll circle back and figure out how much code reuse I can get out of the original implementation.
query := p.queryBuilder.BuildPrometheusQuery(namespace, metricName, metricSelector)
selector := prom.Selector(query)
//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(query)
fmt.Printf("%s, %s", queryResults, err)
//TODO: Construct a real result.
//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
}