diff --git a/examples/instrumentation/go-synthetic/Dockerfile b/examples/instrumentation/go-synthetic/Dockerfile index 38d9d004b5..b8ad47915d 100644 --- a/examples/instrumentation/go-synthetic/Dockerfile +++ b/examples/instrumentation/go-synthetic/Dockerfile @@ -4,7 +4,7 @@ COPY . ./ FROM buildbase as appbase -RUN CGO_ENABLED=0 go build -o go-synthetic ./examples/instrumentation/go-synthetic/main.go +RUN CGO_ENABLED=0 go build -o go-synthetic ./examples/instrumentation/go-synthetic FROM gcr.io/distroless/static-debian11:latest COPY --from=appbase /app/go-synthetic /bin/go-synthetic diff --git a/examples/instrumentation/go-synthetic/README.md b/examples/instrumentation/go-synthetic/README.md index a765e01604..edc7bb086f 100644 --- a/examples/instrumentation/go-synthetic/README.md +++ b/examples/instrumentation/go-synthetic/README.md @@ -9,6 +9,31 @@ types (including exotic OpenMetrics types and Native Histograms). It's used for testing and validation purposes, but also can be used to demo and debug Prometheus monitoring infrastructure. +## Running Locally + +You can run this application locally via: + +```bash +go run ./examples/instrumentation/go-synthetic/ +``` + +Then, you can access the [`/metrics`](http://localhost:8080/metrics) endpoint. For example, via `curl`: + +```bash +curl localhost:8080/metrics +``` + +### Authorization + +The example application can be protected with various authorization methods: + +#### BasicAuth + +```bash +go run ./examples/instrumentation/go-synthetic/ --basic-auth-username=admin --basic-auth-password=pw +curl localhost:8080/metrics -u "admin:pw" +``` + ## Running on Kubernetes If running managed-collection on a Kubernetes cluster, the `go-synthetic` can be diff --git a/examples/instrumentation/go-synthetic/auth.go b/examples/instrumentation/go-synthetic/auth.go new file mode 100644 index 0000000000..97c8c7381a --- /dev/null +++ b/examples/instrumentation/go-synthetic/auth.go @@ -0,0 +1,39 @@ +package main + +import ( + "flag" + "net/http" +) + +type basicAuthConfig struct { + username string + password string +} + +func newBasicAuthConfigFromFlags() *basicAuthConfig { + c := &basicAuthConfig{} + flag.StringVar(&c.username, "basic-auth-username", "", "BasicAuth username") + flag.StringVar(&c.password, "basic-auth-password", "", "BasicAuth password") + return c +} + +func (c *basicAuthConfig) isEnabled() bool { + return c.username != "" || c.password != "" +} + +func (c *basicAuthConfig) handle(handler http.Handler) http.Handler { + if !c.isEnabled() { + return handler + } + + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + username, password, ok := r.BasicAuth() + if ok && username == c.username && password == c.password { + handler.ServeHTTP(w, r) + return + } + + w.Header().Set("WWW-Authenticate", `Basic realm="restricted", charset="UTF-8"`) + http.Error(w, "Unauthorized", http.StatusUnauthorized) + }) +} diff --git a/examples/instrumentation/go-synthetic/main.go b/examples/instrumentation/go-synthetic/main.go index 8b247521a9..b8434604bd 100644 --- a/examples/instrumentation/go-synthetic/main.go +++ b/examples/instrumentation/go-synthetic/main.go @@ -172,6 +172,7 @@ var ( ) func main() { + basicAuthConfig := newBasicAuthConfigFromFlags() flag.Parse() metrics := prometheus.NewRegistry() @@ -217,8 +218,16 @@ func main() { ) } { - server := &http.Server{Addr: *addr} - http.Handle("/metrics", promhttp.HandlerFor(metrics, promhttp.HandlerOpts{Registry: metrics, EnableOpenMetrics: true})) + mux := http.NewServeMux() + mux.Handle("/metrics", basicAuthConfig.handle(promhttp.HandlerFor(metrics, promhttp.HandlerOpts{ + Registry: metrics, + EnableOpenMetrics: true, + }))) + + server := &http.Server{ + Addr: *addr, + Handler: mux, + } g.Add(func() error { return server.ListenAndServe() @@ -251,7 +260,7 @@ func main() { ) } if err := g.Run(); err != nil { - log.Println("Exit with error", err) + log.Println("Exit with error:", err) os.Exit(1) } }