From 99ff52d063aa8575c8f6a256a97b8fc7376c3343 Mon Sep 17 00:00:00 2001 From: Xabier Larrakoetxea Date: Sun, 7 Oct 2018 18:17:39 +0200 Subject: [PATCH] Add prometheus client factory and sli retrieval interface Signed-off-by: Xabier Larrakoetxea --- go.mod | 2 +- go.sum | 4 +-- pkg/service/client/kubernetes/factory.go | 2 +- pkg/service/client/prometheus/factory.go | 43 ++++++++++++++++++++++++ pkg/service/client/prometheus/fake.go | 34 +++++++++++++++++++ pkg/service/sli/sli.go | 41 ++++++++++++++++++++++ 6 files changed, 122 insertions(+), 4 deletions(-) create mode 100644 pkg/service/client/prometheus/factory.go create mode 100644 pkg/service/client/prometheus/fake.go create mode 100644 pkg/service/sli/sli.go diff --git a/go.mod b/go.mod index fcd3d03..6d9e439 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/onsi/gomega v1.4.2 // indirect github.com/opentracing/opentracing-go v1.0.2 // indirect github.com/pborman/uuid v1.2.0 // indirect - github.com/prometheus/client_golang v0.8.0 // indirect + github.com/prometheus/client_golang v0.9.0-pre1.0.20181001174001-0a8115f42e03 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 // indirect github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e // indirect github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d // indirect diff --git a/go.sum b/go.sum index 0246e21..dc6c2c7 100644 --- a/go.sum +++ b/go.sum @@ -50,8 +50,8 @@ github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v0.8.0 h1:1921Yw9Gc3iSc4VQh3PIoOqgPCZS7G/4xQNVUp8Mda8= -github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.0-pre1.0.20181001174001-0a8115f42e03 h1:hqNopISksxji/N5zEy1xMN7TrnSyVG/LymiwnkXi6/Q= +github.com/prometheus/client_golang v0.9.0-pre1.0.20181001174001-0a8115f42e03/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e h1:n/3MEhJQjQxrOUCzh1Y3Re6aJUUWRp2M9+Oc3eVn/54= diff --git a/pkg/service/client/kubernetes/factory.go b/pkg/service/client/kubernetes/factory.go index 3c1fdc4..63e1705 100644 --- a/pkg/service/client/kubernetes/factory.go +++ b/pkg/service/client/kubernetes/factory.go @@ -26,7 +26,7 @@ type factory struct { aexcli apiextensionscli.Interface } -// New returns a new kubernetes client factory. +// NewFactory returns a new kubernetes client factory. func NewFactory(config *rest.Config) ClientFactory { return &factory{ restCfg: config, diff --git a/pkg/service/client/prometheus/factory.go b/pkg/service/client/prometheus/factory.go new file mode 100644 index 0000000..5d16873 --- /dev/null +++ b/pkg/service/client/prometheus/factory.go @@ -0,0 +1,43 @@ +package prometheus + +import ( + "sync" + + "github.com/prometheus/client_golang/api" + promv1 "github.com/prometheus/client_golang/api/prometheus/v1" +) + +// ClientFactory knows how to get prometheus API clients. +type ClientFactory interface { + // GetV1APIClient returns a new prometheus v1 API client. + // address is the address of the prometheus. + GetV1APIClient(address string) (promv1.API, error) +} + +type factory struct { + clis map[string]api.Client + climu sync.Mutex +} + +// NewFactory returns a new client factory. +func NewFactory() ClientFactory { + return &factory{ + clis: map[string]api.Client{}, + } +} + +// GetV1APIClient satisfies ClientFactory interface. +func (f *factory) GetV1APIClient(address string) (promv1.API, error) { + f.climu.Lock() + f.climu.Unlock() + + cli, ok := f.clis[address] + if !ok { + cli, err := api.NewClient(api.Config{Address: address}) + if err != nil { + return nil, err + } + f.clis[address] = cli + } + return promv1.NewAPI(cli), nil +} diff --git a/pkg/service/client/prometheus/fake.go b/pkg/service/client/prometheus/fake.go new file mode 100644 index 0000000..a64ce71 --- /dev/null +++ b/pkg/service/client/prometheus/fake.go @@ -0,0 +1,34 @@ +package prometheus + +import ( + "context" + "net/http" + "net/url" + + promv1 "github.com/prometheus/client_golang/api/prometheus/v1" +) + +type fakeFactory struct { +} + +// NewFakeFactory returns a new fake factory. +func NewFakeFactory() ClientFactory { + return &fakeFactory{} +} + +// GetV1APIClient satisfies ClientFactory interface. +func (f *fakeFactory) GetV1APIClient(_ string) (promv1.API, error) { + cli := &fakeClient{} + return promv1.NewAPI(cli), nil +} + +// fakeClient is a faked http client. +// TODO +type fakeClient struct{} + +func (c *fakeClient) URL(ep string, args map[string]string) *url.URL { return nil } +func (c *fakeClient) Do(ctx context.Context, req *http.Request) (*http.Response, []byte, error) { + b := []byte{} + resp := &http.Response{} + return resp, b, nil +} diff --git a/pkg/service/sli/sli.go b/pkg/service/sli/sli.go new file mode 100644 index 0000000..14fa059 --- /dev/null +++ b/pkg/service/sli/sli.go @@ -0,0 +1,41 @@ +package sli + +import ( + "errors" + + measurev1alpha1 "github.com/slok/service-level-operator/pkg/apis/measure/v1alpha1" + "github.com/slok/service-level-operator/pkg/log" + promcli "github.com/slok/service-level-operator/pkg/service/client/prometheus" +) + +// Result is the result of getting a SLI from a backend. +type Result struct { + TotalQ float64 + ErrorQ float64 +} + +// Service knows how to get . +type Service interface { + // GetSLI returns the result of a ServiceLevel SLI + GetSLI(*measurev1alpha1.ServiceLevel) (Result, error) +} + +// Prometheus knows how to get SLIs from a prometheus backend. +type prometheus struct { + cliFactory promcli.ClientFactory + logger log.Logger +} + +// NewPrometheus returns a new prometheus SLI service. +func NewPrometheus(promCliFactory promcli.ClientFactory, logger log.Logger) Service { + return &prometheus{ + cliFactory: promCliFactory, + logger: logger, + } +} + +// GetSLI satisfies Service interface.. +func (p *prometheus) GetSLI(sl *measurev1alpha1.ServiceLevel) (Result, error) { + // TODO + return Result{}, errors.New("not implemented") +}