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"
|
StorageTypeLegacy StorageType = "legacy"
|
||||||
StorageTypeUnified StorageType = "unified"
|
StorageTypeUnified StorageType = "unified"
|
||||||
StorageTypeUnifiedGrpc StorageType = "unified-grpc"
|
StorageTypeUnifiedGrpc StorageType = "unified-grpc"
|
||||||
|
// TODO(drclau): add StorageTypeUnifiedCloud?
|
||||||
)
|
)
|
||||||
|
|
||||||
type StorageOptions struct {
|
type StorageOptions struct {
|
||||||
|
@ -288,6 +288,7 @@ func (s *service) start(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a client instance
|
// Create a client instance
|
||||||
|
// TODO(drclau): differentiate based on grpc_mode (e.g. on-prem vs. cloud)
|
||||||
client, err := resource.NewResourceStoreClientGRPC(conn)
|
client, err := resource.NewResourceStoreClientGRPC(conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package grpcutils
|
package grpcutils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -10,7 +12,7 @@ type GrpcClientConfig struct {
|
|||||||
TokenNamespace string
|
TokenNamespace string
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReadCfg(cfg *setting.Cfg) *GrpcClientConfig {
|
func ReadGrpcClientConfig(cfg *setting.Cfg) *GrpcClientConfig {
|
||||||
section := cfg.SectionWithEnvOverrides("grpc_client_authentication")
|
section := cfg.SectionWithEnvOverrides("grpc_client_authentication")
|
||||||
|
|
||||||
return &GrpcClientConfig{
|
return &GrpcClientConfig{
|
||||||
@ -19,3 +21,41 @@ func ReadCfg(cfg *setting.Cfg) *GrpcClientConfig {
|
|||||||
TokenNamespace: section.Key("token_namespace").MustString("stack-" + cfg.StackID),
|
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
|
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) {
|
func (s *legacyServer) Read(ctx context.Context, req *authzv1.ReadRequest) (*authzv1.ReadResponse, error) {
|
||||||
ctx, span := s.tracer.Start(ctx, "authz.grpc.Read")
|
ctx, span := s.tracer.Start(ctx, "authz.grpc.Read")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
@ -6,6 +6,8 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
authnlib "github.com/grafana/authlib/authn"
|
||||||
|
authzlib "github.com/grafana/authlib/authz"
|
||||||
"github.com/grafana/dskit/instrument"
|
"github.com/grafana/dskit/instrument"
|
||||||
"github.com/grafana/dskit/middleware"
|
"github.com/grafana/dskit/middleware"
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
"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
|
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
|
// Default auth is admin token check, but this can be overridden by
|
||||||
// services which implement ServiceAuthFuncOverride interface.
|
// services which implement ServiceAuthFuncOverride interface.
|
||||||
// See https://github.com/grpc-ecosystem/go-grpc-middleware/blob/main/interceptors/auth/auth.go#L30.
|
// See https://github.com/grpc-ecosystem/go-grpc-middleware/blob/main/interceptors/auth/auth.go#L30.
|
||||||
opts = append(opts, []grpc.ServerOption{
|
opts = append(opts, []grpc.ServerOption{
|
||||||
grpc.ChainUnaryInterceptor(
|
grpc.ChainUnaryInterceptor(
|
||||||
grpcAuth.UnaryServerInterceptor(authenticator.Authenticate),
|
grpcAuth.UnaryServerInterceptor(authenticator.Authenticate),
|
||||||
|
authzlib.UnaryNamespaceAccessInterceptor(namespaceChecker, stackIdExtractor),
|
||||||
interceptors.TracingUnaryInterceptor(tracer),
|
interceptors.TracingUnaryInterceptor(tracer),
|
||||||
interceptors.LoggingUnaryInterceptor(s.cfg, s.logger), // needs to be registered after tracing interceptor to get trace id
|
interceptors.LoggingUnaryInterceptor(s.cfg, s.logger), // needs to be registered after tracing interceptor to get trace id
|
||||||
middleware.UnaryServerInstrumentInterceptor(grpcRequestDuration),
|
middleware.UnaryServerInstrumentInterceptor(grpcRequestDuration),
|
||||||
@ -83,6 +94,7 @@ func ProvideService(cfg *setting.Cfg, features featuremgmt.FeatureToggles, authe
|
|||||||
grpc.ChainStreamInterceptor(
|
grpc.ChainStreamInterceptor(
|
||||||
interceptors.TracingStreamInterceptor(tracer),
|
interceptors.TracingStreamInterceptor(tracer),
|
||||||
grpcAuth.StreamServerInterceptor(authenticator.Authenticate),
|
grpcAuth.StreamServerInterceptor(authenticator.Authenticate),
|
||||||
|
authzlib.StreamNamespaceAccessInterceptor(namespaceChecker, stackIdExtractor),
|
||||||
middleware.StreamServerInstrumentInterceptor(grpcRequestDuration),
|
middleware.StreamServerInstrumentInterceptor(grpcRequestDuration),
|
||||||
),
|
),
|
||||||
}...)
|
}...)
|
||||||
|
@ -3,6 +3,7 @@ package sql
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
authnlib "github.com/grafana/authlib/authn"
|
||||||
"github.com/grafana/dskit/services"
|
"github.com/grafana/dskit/services"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"google.golang.org/grpc/health/grpc_health_v1"
|
"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/log"
|
||||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
"github.com/grafana/grafana/pkg/modules"
|
"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/featuremgmt"
|
||||||
"github.com/grafana/grafana/pkg/services/grpcserver"
|
"github.com/grafana/grafana/pkg/services/grpcserver"
|
||||||
"github.com/grafana/grafana/pkg/services/grpcserver/interceptors"
|
"github.com/grafana/grafana/pkg/services/grpcserver/interceptors"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
||||||
"github.com/grafana/grafana/pkg/storage/unified/resource/grpc"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -62,7 +63,38 @@ func ProvideService(
|
|||||||
return nil, err
|
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{
|
s := &service{
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
|
Loading…
Reference in New Issue
Block a user