Enable basic auth for service query / scaling on provider

- this is a blocking issue for auth with Docker Swarm
fixes #879

Signed-off-by: Alex Ellis (VMware) <alexellis2@gmail.com>
This commit is contained in:
Alex Ellis (VMware) 2018-09-19 20:41:28 +01:00 committed by Alex Ellis
parent e7cfaa1b9b
commit 3598da2e51
5 changed files with 25 additions and 8 deletions

View File

@ -14,6 +14,7 @@ import (
"log" "log"
"github.com/openfaas/faas-provider/auth"
"github.com/openfaas/faas/gateway/requests" "github.com/openfaas/faas/gateway/requests"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -22,13 +23,15 @@ import (
type Exporter struct { type Exporter struct {
metricOptions MetricOptions metricOptions MetricOptions
services []requests.Function services []requests.Function
credentials *auth.BasicAuthCredentials
} }
// NewExporter creates a new exporter for the OpenFaaS gateway metrics // NewExporter creates a new exporter for the OpenFaaS gateway metrics
func NewExporter(options MetricOptions) *Exporter { func NewExporter(options MetricOptions, credentials *auth.BasicAuthCredentials) *Exporter {
return &Exporter{ return &Exporter{
metricOptions: options, metricOptions: options,
services: []requests.Function{}, services: []requests.Function{},
credentials: credentials,
} }
} }
@ -77,6 +80,9 @@ func (e *Exporter) StartServiceWatcher(endpointURL url.URL, metricsOptions Metri
case <-ticker.C: case <-ticker.C:
get, _ := http.NewRequest(http.MethodGet, endpointURL.String()+"system/functions", nil) get, _ := http.NewRequest(http.MethodGet, endpointURL.String()+"system/functions", nil)
if e.credentials != nil {
get.SetBasicAuth(e.credentials.User, e.credentials.Password)
}
services := []requests.Function{} services := []requests.Function{}
res, err := proxyClient.Do(get) res, err := proxyClient.Do(get)

View File

@ -33,7 +33,7 @@ func readGauge(g prometheus.Metric) metricResult {
func Test_Describe_DescribesThePrometheusMetrics(t *testing.T) { func Test_Describe_DescribesThePrometheusMetrics(t *testing.T) {
metricsOptions := BuildMetricsOptions() metricsOptions := BuildMetricsOptions()
exporter := NewExporter(metricsOptions) exporter := NewExporter(metricsOptions, nil)
ch := make(chan *prometheus.Desc) ch := make(chan *prometheus.Desc)
defer close(ch) defer close(ch)
@ -62,7 +62,7 @@ func Test_Describe_DescribesThePrometheusMetrics(t *testing.T) {
func Test_Collect_CollectsTheNumberOfReplicasOfAService(t *testing.T) { func Test_Collect_CollectsTheNumberOfReplicasOfAService(t *testing.T) {
metricsOptions := BuildMetricsOptions() metricsOptions := BuildMetricsOptions()
exporter := NewExporter(metricsOptions) exporter := NewExporter(metricsOptions, nil)
expectedService := requests.Function{ expectedService := requests.Function{
Name: "function_with_two_replica", Name: "function_with_two_replica",

View File

@ -7,7 +7,7 @@ import (
"net/http" "net/http"
) )
// PrometheusQuery a PrometheusQuery // PrometheusQuery represents parameters for querying Prometheus
type PrometheusQuery struct { type PrometheusQuery struct {
Port int Port int
Host string Host string

View File

@ -17,12 +17,13 @@ import (
"io/ioutil" "io/ioutil"
"github.com/openfaas/faas-provider/auth"
"github.com/openfaas/faas/gateway/handlers" "github.com/openfaas/faas/gateway/handlers"
"github.com/openfaas/faas/gateway/requests" "github.com/openfaas/faas/gateway/requests"
) )
// NewExternalServiceQuery proxies service queries to external plugin via HTTP // NewExternalServiceQuery proxies service queries to external plugin via HTTP
func NewExternalServiceQuery(externalURL url.URL) handlers.ServiceQuery { func NewExternalServiceQuery(externalURL url.URL, credentials *auth.BasicAuthCredentials) handlers.ServiceQuery {
proxyClient := http.Client{ proxyClient := http.Client{
Transport: &http.Transport{ Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment, Proxy: http.ProxyFromEnvironment,
@ -40,6 +41,7 @@ func NewExternalServiceQuery(externalURL url.URL) handlers.ServiceQuery {
return ExternalServiceQuery{ return ExternalServiceQuery{
URL: externalURL, URL: externalURL,
ProxyClient: proxyClient, ProxyClient: proxyClient,
Credentials: credentials,
} }
} }
@ -47,6 +49,7 @@ func NewExternalServiceQuery(externalURL url.URL) handlers.ServiceQuery {
type ExternalServiceQuery struct { type ExternalServiceQuery struct {
URL url.URL URL url.URL
ProxyClient http.Client ProxyClient http.Client
Credentials *auth.BasicAuthCredentials
} }
// ScaleServiceRequest request scaling of replica // ScaleServiceRequest request scaling of replica
@ -65,10 +68,13 @@ func (s ExternalServiceQuery) GetReplicas(serviceName string) (handlers.ServiceQ
req, _ := http.NewRequest(http.MethodGet, urlPath, nil) req, _ := http.NewRequest(http.MethodGet, urlPath, nil)
if s.Credentials != nil {
req.SetBasicAuth(s.Credentials.User, s.Credentials.Password)
}
res, err := s.ProxyClient.Do(req) res, err := s.ProxyClient.Do(req)
if err != nil { if err != nil {
log.Println(urlPath, err) log.Println(urlPath, err)
} else { } else {
@ -129,6 +135,11 @@ func (s ExternalServiceQuery) SetReplicas(serviceName string, count uint64) erro
urlPath := fmt.Sprintf("%ssystem/scale-function/%s", s.URL.String(), serviceName) urlPath := fmt.Sprintf("%ssystem/scale-function/%s", s.URL.String(), serviceName)
req, _ := http.NewRequest(http.MethodPost, urlPath, bytes.NewReader(requestBody)) req, _ := http.NewRequest(http.MethodPost, urlPath, bytes.NewReader(requestBody))
if s.Credentials != nil {
req.SetBasicAuth(s.Credentials.User, s.Credentials.Password)
}
defer req.Body.Close() defer req.Body.Close()
res, err := s.ProxyClient.Do(req) res, err := s.ProxyClient.Do(req)

View File

@ -53,7 +53,7 @@ func main() {
servicePollInterval := time.Second * 5 servicePollInterval := time.Second * 5
metricsOptions := metrics.BuildMetricsOptions() metricsOptions := metrics.BuildMetricsOptions()
exporter := metrics.NewExporter(metricsOptions) exporter := metrics.NewExporter(metricsOptions, credentials)
exporter.StartServiceWatcher(*config.FunctionsProviderURL, metricsOptions, "func", servicePollInterval) exporter.StartServiceWatcher(*config.FunctionsProviderURL, metricsOptions, "func", servicePollInterval)
metrics.RegisterExporter(exporter) metrics.RegisterExporter(exporter)
@ -89,7 +89,7 @@ func main() {
faasHandlers.QueryFunction = handlers.MakeForwardingProxyHandler(reverseProxy, forwardingNotifiers, urlResolver, nilURLTransformer) faasHandlers.QueryFunction = handlers.MakeForwardingProxyHandler(reverseProxy, forwardingNotifiers, urlResolver, nilURLTransformer)
faasHandlers.InfoHandler = handlers.MakeInfoHandler(handlers.MakeForwardingProxyHandler(reverseProxy, forwardingNotifiers, urlResolver, nilURLTransformer)) faasHandlers.InfoHandler = handlers.MakeInfoHandler(handlers.MakeForwardingProxyHandler(reverseProxy, forwardingNotifiers, urlResolver, nilURLTransformer))
alertHandler := plugin.NewExternalServiceQuery(*config.FunctionsProviderURL) alertHandler := plugin.NewExternalServiceQuery(*config.FunctionsProviderURL, credentials)
faasHandlers.Alert = handlers.MakeAlertHandler(alertHandler) faasHandlers.Alert = handlers.MakeAlertHandler(alertHandler)
if config.UseNATS() { if config.UseNATS() {