Skip to content

Commit

Permalink
Merge pull request #11 from caas-team/feat/metrics
Browse files Browse the repository at this point in the history
Feat/metrics
  • Loading branch information
y-eight authored Apr 1, 2023
2 parents 2e20db0 + ade140d commit 6a2ce12
Show file tree
Hide file tree
Showing 15 changed files with 389 additions and 36 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
.vscode
tmp
**/*moq.go
5 changes: 5 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,8 @@ stages:
include:
- project: caas/cicd_templates
file: ci_general.yml

test_go:
stage: test
before_script:
- go install github.com/matryer/moq@latest
2 changes: 1 addition & 1 deletion CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
# For more details, read the following article on GitHub: https://help.github.com/articles/about-codeowners/.

# These are the default owners for the whole content of this repository. The default owners are automatically added as reviewers when you open a pull request, unless different owners are specified in the file.
* @y-eight
* @y-eight @puffitos @eumel8
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,12 @@ Use the offered CLI options or use environment variables with a 'MESH' prefix e.
- Server: needs Server Cert & Server Key
- use: `ca-cert`, `server-cert`, `server-key` flags

### `/metrics` support

Canary data will be exposed at `/metrics`. Authorization is required.
Use the token passed to the canary by flag `--token` for authorization (if you did not set the token yourself, it will be generated and exposed to stdout).
Currently the `node_count` and histogram metrics (`rtt` buckets) from the requested pod are available.

## Support and Feedback

The following channels are available for discussions, feedback, and support requests:
Expand Down
25 changes: 19 additions & 6 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ import (
connect "github.com/bufbuild/connect-go"
grpc_zap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/telekom/canary-bot/data"
h "github.com/telekom/canary-bot/helper"
"github.com/telekom/canary-bot/metric"
"github.com/telekom/canary-bot/proto/api/third_party"
apiv1 "github.com/telekom/canary-bot/proto/api/v1"
"github.com/telekom/canary-bot/proto/api/v1/apiv1connect"
Expand All @@ -53,11 +55,12 @@ import (
"google.golang.org/protobuf/encoding/protojson"
)

func StartApi(data data.Database, config *Configuration, log *zap.SugaredLogger) error {
func StartApi(data data.Database, metrics metric.Metrics, config *Configuration, log *zap.SugaredLogger) error {
a := &Api{
data: data,
config: config,
log: log,
data: data,
metrics: metrics,
config: config,
log: log,
}

if config.DebugGrpc {
Expand All @@ -73,7 +76,6 @@ func StartApi(data data.Database, config *Configuration, log *zap.SugaredLogger)
config.ServerCert,
config.ServerKey,
)

if err != nil {
log.Warnw("Cannot load TLS server credentials - using insecure connection for incoming requests")
log.Debugw("Cannot load TLS credentials", "error", err.Error())
Expand All @@ -84,7 +86,6 @@ func StartApi(data data.Database, config *Configuration, log *zap.SugaredLogger)
var tlsClientCredentials credentials.TransportCredentials
if tlsCredentials != nil {
tlsClientCredentials, err = h.LoadClientTLSCredentials(config.CaCertPath, config.CaCert)

}

if err != nil {
Expand Down Expand Up @@ -133,6 +134,18 @@ func StartApi(data data.Database, config *Configuration, log *zap.SugaredLogger)

mux.Handle(apiv1connect.NewApiServiceHandler(a, interceptors))
mux.Handle("/api/v1/", gwmux)
mux.Handle("/metrics",
a.NewAuthHandler(
metrics.Handler(a.data,
promhttp.HandlerFor(
metrics.GetRegistry(),
promhttp.HandlerOpts{
EnableOpenMetrics: true,
},
),
),
),
)
server := &http.Server{
Addr: addr,
Handler: h2c.NewHandler(mux, &http2.Server{}),
Expand Down
44 changes: 39 additions & 5 deletions api/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,32 +24,66 @@ package api
import (
"context"
"errors"
"net/http"
"strings"

connect "github.com/bufbuild/connect-go"
)

// http auth handler
func (a *Api) NewAuthHandler(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
splitToken := strings.Split(r.Header.Get("Authorization"), "Bearer")
// check if token is set
if len(splitToken) != 2 {
a.log.Warnw("Request", "host", r.Header.Get("X-Forwarded-Host"), "auth", "failed", "reason", "no bearer token")
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}

// get token
authToken := strings.TrimSpace(splitToken[1])

// check if token is correct
for _, t := range a.config.Tokens {
if authToken == t {
a.log.Infow("Request", "host", r.Header.Get("X-Forwarded-Host"), "auth", "succeded")
h.ServeHTTP(w, r)
return
}
}
a.log.Warnw("Request", "host", r.Header.Get("X-Forwarded-Host"), "auth", "failed", "reason", "invalid token")
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
})
}

// grpc auth interceptor
func (a *Api) NewAuthInterceptor() connect.UnaryInterceptorFunc {
interceptor := func(next connect.UnaryFunc) connect.UnaryFunc {
return connect.UnaryFunc(
func(ctx context.Context, req connect.AnyRequest) (connect.AnyResponse, error) {
authToken := req.Header().Get("Authorization")
splitToken := strings.Split(req.Header().Get("Authorization"), "Bearer")
// check if token is set
if authToken == "" {
a.log.Warnw("Request", "host", req.Header().Get("X-Forwarded-Host"), "auth", "failed")
if len(splitToken) != 2 {
a.log.Warnw("Request", "host", req.Header().Get("X-Forwarded-Host"), "auth", "failed", "reason", "no bearer token")
return nil, connect.NewError(
connect.CodeUnauthenticated,
errors.New("no token provided"),
)
}

// get token
authToken := strings.TrimSpace(splitToken[1])

// check if token is correct
for _, t := range a.config.Tokens {
if authToken[7:] == t {
if authToken == t {
a.log.Infow("Request", "host", req.Header().Get("X-Forwarded-Host"), "auth", "succeded")
return next(ctx, req)
}
}
a.log.Warnw("Request", "host", req.Header().Get("X-Forwarded-Host"), "auth", "failed")
a.log.Warnw("Request", "host", req.Header().Get("X-Forwarded-Host"), "auth", "failed", "reason", "invalid token")
return nil, connect.NewError(
connect.CodeUnauthenticated,
errors.New("auth failed"),
Expand Down
8 changes: 5 additions & 3 deletions api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"time"

"github.com/telekom/canary-bot/data"
"github.com/telekom/canary-bot/metric"

apiv1 "github.com/telekom/canary-bot/proto/api/v1"

Expand All @@ -35,9 +36,10 @@ import (

// Api implements the protobuf interface
type Api struct {
data data.Database
config *Configuration
log *zap.SugaredLogger
data data.Database
metrics metric.Metrics
config *Configuration
log *zap.SugaredLogger
}

type Configuration struct {
Expand Down
7 changes: 7 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,18 @@ require (
)

require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.0.7 // indirect
github.com/prometheus/client_model v0.3.0 // indirect
github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect
github.com/spf13/afero v1.9.5 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
Expand All @@ -37,6 +43,7 @@ require (
github.com/hashicorp/go-memdb v1.3.4
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/prometheus/client_golang v1.14.0
github.com/spf13/cobra v1.6.1
github.com/spf13/pflag v1.0.5
golang.org/x/net v0.8.0
Expand Down
Loading

0 comments on commit 6a2ce12

Please sign in to comment.