authnz: Fix panic in the authenticator and rename metric (#97150)
* Fix: panic * suggestion
This commit is contained in:
@@ -107,42 +107,49 @@ func FallbackUsed(ctx context.Context) bool {
|
|||||||
func (f *AuthenticatorWithFallback) Authenticate(ctx context.Context) (context.Context, error) {
|
func (f *AuthenticatorWithFallback) Authenticate(ctx context.Context) (context.Context, error) {
|
||||||
ctx, span := f.tracer.Start(ctx, "grpcutils.AuthenticatorWithFallback.Authenticate")
|
ctx, span := f.tracer.Start(ctx, "grpcutils.AuthenticatorWithFallback.Authenticate")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
span.SetAttributes(attribute.Bool("fallback_used", false))
|
|
||||||
// Try to authenticate with the new authenticator first
|
// Try to authenticate with the new authenticator first
|
||||||
|
span.SetAttributes(attribute.Bool("fallback_used", false))
|
||||||
newCtx, err := f.authenticator.Authenticate(ctx)
|
newCtx, err := f.authenticator.Authenticate(ctx)
|
||||||
if err != nil {
|
if err == nil {
|
||||||
// In case of error, fallback to the legacy authenticator
|
// fallback not used, authentication successful
|
||||||
newCtx, err = f.fallback.Authenticate(ctx)
|
f.metrics.requestsTotal.WithLabelValues("false", "true").Inc()
|
||||||
f.metrics.fallbackCounter.WithLabelValues(fmt.Sprintf("%t", err == nil)).Inc()
|
return newCtx, nil
|
||||||
span.SetAttributes(attribute.Bool("fallback_used", true))
|
}
|
||||||
|
|
||||||
|
// In case of error, fallback to the legacy authenticator
|
||||||
|
span.SetAttributes(attribute.Bool("fallback_used", true))
|
||||||
|
newCtx, err = f.fallback.Authenticate(ctx)
|
||||||
|
if newCtx != nil {
|
||||||
newCtx = context.WithValue(newCtx, contextFallbackKey{}, true)
|
newCtx = context.WithValue(newCtx, contextFallbackKey{}, true)
|
||||||
}
|
}
|
||||||
|
f.metrics.requestsTotal.WithLabelValues("true", fmt.Sprintf("%t", err == nil)).Inc()
|
||||||
return newCtx, err
|
return newCtx, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
metricsNamespace = "grafana"
|
metricsNamespace = "grafana"
|
||||||
metricsSubSystem = "grpc_authenticator"
|
metricsSubSystem = "grpc_authenticator_with_fallback"
|
||||||
)
|
)
|
||||||
|
|
||||||
type metrics struct {
|
type metrics struct {
|
||||||
fallbackCounter *prometheus.CounterVec
|
requestsTotal *prometheus.CounterVec
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMetrics(reg prometheus.Registerer) *metrics {
|
func newMetrics(reg prometheus.Registerer) *metrics {
|
||||||
m := &metrics{
|
m := &metrics{
|
||||||
fallbackCounter: prometheus.NewCounterVec(
|
requestsTotal: prometheus.NewCounterVec(
|
||||||
prometheus.CounterOpts{
|
prometheus.CounterOpts{
|
||||||
Namespace: metricsNamespace,
|
Namespace: metricsNamespace,
|
||||||
Subsystem: metricsSubSystem,
|
Subsystem: metricsSubSystem,
|
||||||
Name: "fallback_total",
|
Name: "requests_total",
|
||||||
Help: "Number of times the fallback authenticator was used",
|
Help: "Number requests using the authenticator with fallback",
|
||||||
}, []string{"result"}),
|
}, []string{"fallback_used", "result"}),
|
||||||
}
|
}
|
||||||
|
|
||||||
if reg != nil {
|
if reg != nil {
|
||||||
once.Do(func() {
|
once.Do(func() {
|
||||||
reg.MustRegister(m.fallbackCounter)
|
reg.MustRegister(m.requestsTotal)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ type groupResource map[string]map[string]interface{}
|
|||||||
// For now, it makes one call to the authz service for each list items. This is known to be inefficient.
|
// For now, it makes one call to the authz service for each list items. This is known to be inefficient.
|
||||||
type authzLimitedClient struct {
|
type authzLimitedClient struct {
|
||||||
client authz.AccessChecker
|
client authz.AccessChecker
|
||||||
// whitelist is a map of group to resources that are compatible with RBAC.
|
// allowlist is a map of group to resources that are compatible with RBAC.
|
||||||
whitelist groupResource
|
allowlist groupResource
|
||||||
logger *slog.Logger
|
logger *slog.Logger
|
||||||
tracer trace.Tracer
|
tracer trace.Tracer
|
||||||
}
|
}
|
||||||
@@ -57,7 +57,7 @@ func NewAuthzLimitedClient(client authz.AccessChecker, opts AuthzOptions) authz.
|
|||||||
}
|
}
|
||||||
return &authzLimitedClient{
|
return &authzLimitedClient{
|
||||||
client: client,
|
client: client,
|
||||||
whitelist: groupResource{
|
allowlist: groupResource{
|
||||||
"dashboard.grafana.app": map[string]interface{}{"dashboards": nil},
|
"dashboard.grafana.app": map[string]interface{}{"dashboards": nil},
|
||||||
"folder.grafana.app": map[string]interface{}{"folders": nil},
|
"folder.grafana.app": map[string]interface{}{"folders": nil},
|
||||||
},
|
},
|
||||||
@@ -107,7 +107,7 @@ func (c authzLimitedClient) Compile(ctx context.Context, id claims.AuthInfo, req
|
|||||||
))
|
))
|
||||||
defer span.End()
|
defer span.End()
|
||||||
if grpcutils.FallbackUsed(ctx) {
|
if grpcutils.FallbackUsed(ctx) {
|
||||||
c.logger.Debug("Check", "group", req.Group, "resource", req.Resource, "fallback", true, "rbac", false, "allowed", true)
|
c.logger.Debug("Compile.Check", "group", req.Group, "resource", req.Resource, "fallback", true, "rbac", false, "allowed", true)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// TODO: Implement For now we perform the check for each item.
|
// TODO: Implement For now we perform the check for each item.
|
||||||
@@ -134,8 +134,8 @@ func (c authzLimitedClient) Compile(ctx context.Context, id claims.AuthInfo, req
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c authzLimitedClient) IsCompatibleWithRBAC(group, resource string) bool {
|
func (c authzLimitedClient) IsCompatibleWithRBAC(group, resource string) bool {
|
||||||
if _, ok := c.whitelist[group]; ok {
|
if _, ok := c.allowlist[group]; ok {
|
||||||
if _, ok := c.whitelist[group][resource]; ok {
|
if _, ok := c.allowlist[group][resource]; ok {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user