mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-02-20 01:28:45 +01:00
feat: add OTEL instrumentation for authentication and handlers (#25296)
Signed-off-by: Mike Cutsail <mcutsail15@apple.com> Signed-off-by: Alexandre Gaudreault <alexandre_gaudreault@intuit.com> Co-authored-by: Alexandre Gaudreault <alexandre_gaudreault@intuit.com>
This commit is contained in:
@@ -44,8 +44,11 @@ import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/soheilhy/cmux"
|
||||
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
"go.opentelemetry.io/otel"
|
||||
otel_codes "go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/propagation"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/credentials"
|
||||
@@ -166,6 +169,9 @@ var (
|
||||
enableGRPCTimeHistogram = true
|
||||
)
|
||||
|
||||
// OpenTelemetry tracer for this package
|
||||
var tracer trace.Tracer
|
||||
|
||||
func init() {
|
||||
maxConcurrentLoginRequestsCount = env.ParseNumFromEnv(maxConcurrentLoginRequestsCountEnv, maxConcurrentLoginRequestsCount, 0, math.MaxInt32)
|
||||
replicasCount = env.ParseNumFromEnv(replicasCountEnv, replicasCount, 0, math.MaxInt32)
|
||||
@@ -173,6 +179,7 @@ func init() {
|
||||
maxConcurrentLoginRequestsCount = maxConcurrentLoginRequestsCount / replicasCount
|
||||
}
|
||||
enableGRPCTimeHistogram = env.ParseBoolFromEnv(common.EnvEnableGRPCTimeHistogramEnv, false)
|
||||
tracer = otel.Tracer("github.com/argoproj/argo-cd/v3/server")
|
||||
}
|
||||
|
||||
// ArgoCDServer is the API server for Argo CD
|
||||
@@ -1164,8 +1171,8 @@ func (server *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWeb
|
||||
Handler: &handlerSwitcher{
|
||||
handler: mux,
|
||||
urlToHandler: map[string]http.Handler{
|
||||
"/api/badge": badge.NewHandler(server.AppClientset, server.settingsMgr, server.Namespace, server.ApplicationNamespaces),
|
||||
common.LogoutEndpoint: logout.NewHandler(server.settingsMgr, server.sessionMgr, server.RootPath, server.BaseHRef),
|
||||
"/api/badge": otelhttp.NewHandler(badge.NewHandler(server.AppClientset, server.settingsMgr, server.Namespace, server.ApplicationNamespaces), "server.ArgoCDServer/badge"),
|
||||
common.LogoutEndpoint: otelhttp.NewHandler(logout.NewHandler(server.settingsMgr, server.sessionMgr, server.RootPath, server.BaseHRef), "server.ArgoCDServer/logout"),
|
||||
},
|
||||
contentTypeToHandler: map[string]http.Handler{
|
||||
"application/grpc-web+proto": grpcWebHandler,
|
||||
@@ -1293,7 +1300,7 @@ func registerExtensions(mux *http.ServeMux, a *ArgoCDServer, metricsReg HTTPMetr
|
||||
extHandler := http.HandlerFunc(a.extensionManager.CallExtension())
|
||||
authMiddleware := a.sessionMgr.AuthMiddlewareFunc(a.DisableAuth, a.settings.IsSSOConfigured(), a.ssoClientApp)
|
||||
// auth middleware ensures that requests to all extensions are authenticated first
|
||||
mux.Handle(extension.URLPrefix+"/", authMiddleware(extHandler))
|
||||
mux.Handle(extension.URLPrefix+"/", otelhttp.NewHandler(authMiddleware(extHandler), "server.ArgoCDServer/extensions"))
|
||||
|
||||
a.extensionManager.AddMetricsRegistry(metricsReg)
|
||||
|
||||
@@ -1351,9 +1358,10 @@ func (server *ArgoCDServer) registerDexHandlers(mux *http.ServeMux) {
|
||||
return
|
||||
}
|
||||
// Run dex OpenID Connect Identity Provider behind a reverse proxy (served at /api/dex)
|
||||
mux.HandleFunc(common.DexAPIEndpoint+"/", dexutil.NewDexHTTPReverseProxy(server.DexServerAddr, server.BaseHRef, server.DexTLSConfig))
|
||||
mux.HandleFunc(common.LoginEndpoint, server.ssoClientApp.HandleLogin)
|
||||
mux.HandleFunc(common.CallbackEndpoint, server.ssoClientApp.HandleCallback)
|
||||
mux.Handle(common.DexAPIEndpoint+"/", otelhttp.NewHandler(http.HandlerFunc(dexutil.NewDexHTTPReverseProxy(server.DexServerAddr, server.BaseHRef, server.DexTLSConfig)), "server.dex/Proxy"))
|
||||
|
||||
mux.Handle(common.LoginEndpoint, otelhttp.NewHandler(http.HandlerFunc(server.ssoClientApp.HandleLogin), "server.ClientApp/HandleLogin"))
|
||||
mux.Handle(common.CallbackEndpoint, otelhttp.NewHandler(http.HandlerFunc(server.ssoClientApp.HandleCallback), "server.ClientApp/HandleCallback"))
|
||||
}
|
||||
|
||||
// newRedirectServer returns an HTTP server which does a 307 redirect to the HTTPS server
|
||||
@@ -1510,6 +1518,9 @@ func replaceBaseHRef(data string, replaceWith string) string {
|
||||
|
||||
// Authenticate checks for the presence of a valid token when accessing server-side resources.
|
||||
func (server *ArgoCDServer) Authenticate(ctx context.Context) (context.Context, error) {
|
||||
var span trace.Span
|
||||
ctx, span = tracer.Start(ctx, "server.ArgoCDServer.Authenticate")
|
||||
defer span.End()
|
||||
if server.DisableAuth {
|
||||
return ctx, nil
|
||||
}
|
||||
@@ -1549,18 +1560,24 @@ func (server *ArgoCDServer) Authenticate(ctx context.Context) (context.Context,
|
||||
|
||||
// getClaims extracts, validates and refreshes a JWT token from an incoming request context.
|
||||
func (server *ArgoCDServer) getClaims(ctx context.Context) (jwt.Claims, string, error) {
|
||||
var span trace.Span
|
||||
ctx, span = tracer.Start(ctx, "server.ArgoCDServer.getClaims")
|
||||
defer span.End()
|
||||
md, ok := metadata.FromIncomingContext(ctx)
|
||||
if !ok {
|
||||
span.SetStatus(otel_codes.Error, ErrNoSession.Error())
|
||||
return nil, "", ErrNoSession
|
||||
}
|
||||
tokenString := getToken(md)
|
||||
if tokenString == "" {
|
||||
span.SetStatus(otel_codes.Error, ErrNoSession.Error())
|
||||
return nil, "", ErrNoSession
|
||||
}
|
||||
// A valid argocd-issued token is automatically refreshed here prior to expiration.
|
||||
// OIDC tokens will be verified but will not be refreshed here.
|
||||
claims, newToken, err := server.sessionMgr.VerifyToken(ctx, tokenString)
|
||||
if err != nil {
|
||||
span.SetStatus(otel_codes.Error, err.Error())
|
||||
return claims, "", status.Errorf(codes.Unauthenticated, "invalid session: %v", err)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user