mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
wip
This commit is contained in:
parent
c46b42a595
commit
763961210c
@ -19,6 +19,7 @@ const (
|
||||
StorageTypeLegacy StorageType = "legacy"
|
||||
StorageTypeUnified StorageType = "unified"
|
||||
StorageTypeUnifiedGrpc StorageType = "unified-grpc"
|
||||
// TODO(drclau): add StorageTypeUnifiedCloud?
|
||||
)
|
||||
|
||||
type StorageOptions struct {
|
||||
|
@ -288,6 +288,7 @@ func (s *service) start(ctx context.Context) error {
|
||||
}
|
||||
|
||||
// Create a client instance
|
||||
// TODO(drclau): differentiate based on grpc_mode (e.g. on-prem vs. cloud)
|
||||
client, err := resource.NewResourceStoreClientGRPC(conn)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -1,6 +1,8 @@
|
||||
package grpcutils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
@ -10,7 +12,7 @@ type GrpcClientConfig struct {
|
||||
TokenNamespace string
|
||||
}
|
||||
|
||||
func ReadCfg(cfg *setting.Cfg) *GrpcClientConfig {
|
||||
func ReadGrpcClientConfig(cfg *setting.Cfg) *GrpcClientConfig {
|
||||
section := cfg.SectionWithEnvOverrides("grpc_client_authentication")
|
||||
|
||||
return &GrpcClientConfig{
|
||||
@ -19,3 +21,41 @@ func ReadCfg(cfg *setting.Cfg) *GrpcClientConfig {
|
||||
TokenNamespace: section.Key("token_namespace").MustString("stack-" + cfg.StackID),
|
||||
}
|
||||
}
|
||||
|
||||
type Mode string
|
||||
|
||||
func (s Mode) IsValid() bool {
|
||||
switch s {
|
||||
case ModeGRPC, ModeInProc, ModeCloud:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
const (
|
||||
ModeGRPC Mode = "grpc"
|
||||
ModeInProc Mode = "inproc"
|
||||
ModeCloud Mode = "cloud"
|
||||
)
|
||||
|
||||
type GrpcServerConfig struct {
|
||||
Mode Mode
|
||||
|
||||
SigningKeysURL string
|
||||
AllowedAudiences []string
|
||||
}
|
||||
|
||||
func ReadGprcServerConfig(cfg *setting.Cfg) (*GrpcServerConfig, error) {
|
||||
section := cfg.SectionWithEnvOverrides("grpc_server_authentication")
|
||||
|
||||
mode := Mode(section.Key("mode").MustString(string(ModeGRPC)))
|
||||
if !mode.IsValid() {
|
||||
return nil, fmt.Errorf("grpc_server_authentication: invalid mode %q", mode)
|
||||
}
|
||||
|
||||
return &GrpcServerConfig{
|
||||
Mode: mode,
|
||||
SigningKeysURL: section.Key("signing_keys_url").MustString(""),
|
||||
AllowedAudiences: section.Key("allowed_audiences").Strings(","),
|
||||
}, nil
|
||||
}
|
||||
|
@ -44,6 +44,12 @@ func newLegacyServer(
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// AuthFuncOverride
|
||||
// FIXME(drclau): make sure we only run this when app_mode = development
|
||||
func (s *legacyServer) AuthFuncOverride(ctx context.Context, _ string) (context.Context, error) {
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
func (s *legacyServer) Read(ctx context.Context, req *authzv1.ReadRequest) (*authzv1.ReadResponse, error) {
|
||||
ctx, span := s.tracer.Start(ctx, "authz.grpc.Read")
|
||||
defer span.End()
|
||||
|
@ -6,6 +6,8 @@ import (
|
||||
"net"
|
||||
"time"
|
||||
|
||||
authnlib "github.com/grafana/authlib/authn"
|
||||
authzlib "github.com/grafana/authlib/authz"
|
||||
"github.com/grafana/dskit/instrument"
|
||||
"github.com/grafana/dskit/middleware"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
@ -70,12 +72,21 @@ func ProvideService(cfg *setting.Cfg, features featuremgmt.FeatureToggles, authe
|
||||
|
||||
var opts []grpc.ServerOption
|
||||
|
||||
namespaceFmt := authnlib.OnPremNamespaceFormatter
|
||||
// TODO(drclau): check the actual mode setting here
|
||||
if cfg.StackID != "" {
|
||||
namespaceFmt = authnlib.CloudNamespaceFormatter
|
||||
}
|
||||
namespaceChecker := authzlib.NewNamespaceAccessChecker(namespaceFmt)
|
||||
stackIdExtractor := authzlib.MetadataStackIDExtractor(authzlib.DefaultStackIDMetadataKey)
|
||||
|
||||
// Default auth is admin token check, but this can be overridden by
|
||||
// services which implement ServiceAuthFuncOverride interface.
|
||||
// See https://github.com/grpc-ecosystem/go-grpc-middleware/blob/main/interceptors/auth/auth.go#L30.
|
||||
opts = append(opts, []grpc.ServerOption{
|
||||
grpc.ChainUnaryInterceptor(
|
||||
grpcAuth.UnaryServerInterceptor(authenticator.Authenticate),
|
||||
authzlib.UnaryNamespaceAccessInterceptor(namespaceChecker, stackIdExtractor),
|
||||
interceptors.TracingUnaryInterceptor(tracer),
|
||||
interceptors.LoggingUnaryInterceptor(s.cfg, s.logger), // needs to be registered after tracing interceptor to get trace id
|
||||
middleware.UnaryServerInstrumentInterceptor(grpcRequestDuration),
|
||||
@ -83,6 +94,7 @@ func ProvideService(cfg *setting.Cfg, features featuremgmt.FeatureToggles, authe
|
||||
grpc.ChainStreamInterceptor(
|
||||
interceptors.TracingStreamInterceptor(tracer),
|
||||
grpcAuth.StreamServerInterceptor(authenticator.Authenticate),
|
||||
authzlib.StreamNamespaceAccessInterceptor(namespaceChecker, stackIdExtractor),
|
||||
middleware.StreamServerInstrumentInterceptor(grpcRequestDuration),
|
||||
),
|
||||
}...)
|
||||
|
@ -3,6 +3,7 @@ package sql
|
||||
import (
|
||||
"context"
|
||||
|
||||
authnlib "github.com/grafana/authlib/authn"
|
||||
"github.com/grafana/dskit/services"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"google.golang.org/grpc/health/grpc_health_v1"
|
||||
@ -11,12 +12,12 @@ import (
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/modules"
|
||||
"github.com/grafana/grafana/pkg/services/authn/grpcutils"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/grpcserver"
|
||||
"github.com/grafana/grafana/pkg/services/grpcserver/interceptors"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resource/grpc"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -62,7 +63,38 @@ func ProvideService(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
authn := &grpc.Authenticator{}
|
||||
authCfg, err := grpcutils.ReadGprcServerConfig(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
grpcAuthCfg := authnlib.GrpcAuthenticatorConfig{
|
||||
KeyRetrieverConfig: authnlib.KeyRetrieverConfig{
|
||||
SigningKeysURL: authCfg.SigningKeysURL,
|
||||
},
|
||||
VerifierConfig: authnlib.VerifierConfig{
|
||||
AllowedAudiences: authCfg.AllowedAudiences,
|
||||
},
|
||||
}
|
||||
|
||||
grpcOpts := []authnlib.GrpcAuthenticatorOption{}
|
||||
switch authCfg.Mode {
|
||||
case grpcutils.ModeInProc:
|
||||
// NOOP: IDTokenClaims are added to ctx client-side
|
||||
// TODO(drclau): do we need orgId?
|
||||
case grpcutils.ModeGRPC:
|
||||
grpcOpts = append(grpcOpts,
|
||||
authnlib.WithDisableAccessTokenAuthOption(),
|
||||
authnlib.WithIDTokenAuthOption(true),
|
||||
)
|
||||
case grpcutils.ModeCloud:
|
||||
grpcOpts = append(grpcOpts, authnlib.WithIDTokenAuthOption(true))
|
||||
}
|
||||
|
||||
authn, err := authnlib.NewGrpcAuthenticator(
|
||||
&grpcAuthCfg,
|
||||
grpcOpts...,
|
||||
)
|
||||
|
||||
s := &service{
|
||||
cfg: cfg,
|
||||
|
Loading…
Reference in New Issue
Block a user