From b4366ebed25d8c264b110041dcdab93ee3e96e2d Mon Sep 17 00:00:00 2001 From: Karl Persson Date: Mon, 21 Oct 2024 14:58:57 +0200 Subject: [PATCH] Zanzana: bootstrap authz server (#95036) Bootstrap authz extended server --- Makefile | 1 + pkg/services/authz/zanzana.go | 19 ++++-- .../authz/zanzana/client/client_test.go | 2 +- .../authz/zanzana/proto/v1/buf.gen.yaml | 10 +++ pkg/services/authz/zanzana/proto/v1/buf.yaml | 7 ++ .../authz/zanzana/proto/v1/extention.pb.go | 66 +++++++++++++++++++ .../authz/zanzana/proto/v1/extention.proto | 7 ++ .../zanzana/proto/v1/extention_grpc.pb.go | 62 +++++++++++++++++ pkg/services/authz/zanzana/server.go | 9 ++- .../authz/zanzana/server/authz_server.go | 32 +++++++++ .../server/{server.go => openfga_server.go} | 2 +- 11 files changed, 209 insertions(+), 8 deletions(-) create mode 100644 pkg/services/authz/zanzana/proto/v1/buf.gen.yaml create mode 100644 pkg/services/authz/zanzana/proto/v1/buf.yaml create mode 100644 pkg/services/authz/zanzana/proto/v1/extention.pb.go create mode 100644 pkg/services/authz/zanzana/proto/v1/extention.proto create mode 100644 pkg/services/authz/zanzana/proto/v1/extention_grpc.pb.go create mode 100644 pkg/services/authz/zanzana/server/authz_server.go rename pkg/services/authz/zanzana/server/{server.go => openfga_server.go} (96%) diff --git a/Makefile b/Makefile index f38835b5c60..ccabdbd733a 100644 --- a/Makefile +++ b/Makefile @@ -416,6 +416,7 @@ protobuf: ## Compile protobuf definitions buf generate pkg/plugins/backendplugin/pluginextensionv2 --template pkg/plugins/backendplugin/pluginextensionv2/buf.gen.yaml buf generate pkg/plugins/backendplugin/secretsmanagerplugin --template pkg/plugins/backendplugin/secretsmanagerplugin/buf.gen.yaml buf generate pkg/storage/unified/resource --template pkg/storage/unified/resource/buf.gen.yaml + buf generate pkg/services/authz/zanzana/proto/v1 --template pkg/services/authz/zanzana/proto/v1/buf.gen.yaml .PHONY: clean clean: ## Clean up intermediate build artifacts. diff --git a/pkg/services/authz/zanzana.go b/pkg/services/authz/zanzana.go index c47e680f709..762ecc1403b 100644 --- a/pkg/services/authz/zanzana.go +++ b/pkg/services/authz/zanzana.go @@ -6,6 +6,7 @@ import ( "fmt" "github.com/fullstorydev/grpchan/inprocgrpc" + authzv1 "github.com/grafana/authlib/authz/proto/v1" "github.com/grafana/dskit/services" openfgav1 "github.com/openfga/api/proto/openfga/v1" "github.com/prometheus/client_golang/prometheus" @@ -17,6 +18,7 @@ import ( "github.com/grafana/grafana/pkg/infra/tracing" "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/authz/zanzana/client" + authzextv1 "github.com/grafana/grafana/pkg/services/authz/zanzana/proto/v1" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/grpcserver" "github.com/grafana/grafana/pkg/setting" @@ -49,13 +51,16 @@ func ProvideZanzana(cfg *setting.Cfg, db db.DB, features featuremgmt.FeatureTogg return nil, fmt.Errorf("failed to start zanzana: %w", err) } - srv, err := zanzana.NewServer(cfg, store, logger) + openfga, err := zanzana.NewOpenFGAServer(cfg, store, logger) if err != nil { return nil, fmt.Errorf("failed to start zanzana: %w", err) } + srv := zanzana.NewAuthzServer(openfga) channel := &inprocgrpc.Channel{} - openfgav1.RegisterOpenFGAServiceServer(channel, srv) + openfgav1.RegisterOpenFGAServiceServer(channel, openfga) + authzv1.RegisterAuthzServiceServer(channel, srv) + authzextv1.RegisterAuthzExtentionServiceServer(channel, srv) client, err = zanzana.NewClient(context.Background(), channel, cfg) if err != nil { @@ -104,11 +109,13 @@ func (z *Zanzana) start(ctx context.Context) error { return fmt.Errorf("failed to initilize zanana store: %w", err) } - srv, err := zanzana.NewServer(z.cfg, store, z.logger) + openfga, err := zanzana.NewOpenFGAServer(z.cfg, store, z.logger) if err != nil { return fmt.Errorf("failed to start zanzana: %w", err) } + srv := zanzana.NewAuthzServer(openfga) + tracingCfg, err := tracing.ProvideTracingConfig(z.cfg) if err != nil { return err @@ -127,7 +134,11 @@ func (z *Zanzana) start(ctx context.Context) error { return fmt.Errorf("failed to create zanzana grpc server: %w", err) } - openfgav1.RegisterOpenFGAServiceServer(z.handle.GetServer(), srv) + s := z.handle.GetServer() + openfgav1.RegisterOpenFGAServiceServer(s, openfga) + authzv1.RegisterAuthzServiceServer(s, srv) + authzextv1.RegisterAuthzExtentionServiceServer(s, srv) + if _, err := grpcserver.ProvideReflectionService(z.cfg, z.handle); err != nil { return fmt.Errorf("failed to register reflection for zanzana: %w", err) } diff --git a/pkg/services/authz/zanzana/client/client_test.go b/pkg/services/authz/zanzana/client/client_test.go index 35bdde46088..cd9e4308810 100644 --- a/pkg/services/authz/zanzana/client/client_test.go +++ b/pkg/services/authz/zanzana/client/client_test.go @@ -107,7 +107,7 @@ func zanzanaServerIntegrationTest(tb testing.TB) *inprocgrpc.Channel { store, err := zstore.NewEmbeddedStore(cfg, db, logger) require.NoError(tb, err) - srv, err := zserver.New(&cfg.Zanzana, store, logger) + srv, err := zserver.NewOpenFGA(&cfg.Zanzana, store, logger) require.NoError(tb, err) channel := &inprocgrpc.Channel{} diff --git a/pkg/services/authz/zanzana/proto/v1/buf.gen.yaml b/pkg/services/authz/zanzana/proto/v1/buf.gen.yaml new file mode 100644 index 00000000000..f75391ff05c --- /dev/null +++ b/pkg/services/authz/zanzana/proto/v1/buf.gen.yaml @@ -0,0 +1,10 @@ +version: v1 +plugins: + - plugin: go + out: pkg/services/authz/zanzana/proto/v1 + opt: paths=source_relative + - plugin: go-grpc + out: pkg/services/authz/zanzana/proto/v1 + opt: + - paths=source_relative + - require_unimplemented_servers=false diff --git a/pkg/services/authz/zanzana/proto/v1/buf.yaml b/pkg/services/authz/zanzana/proto/v1/buf.yaml new file mode 100644 index 00000000000..4cb6a23ed85 --- /dev/null +++ b/pkg/services/authz/zanzana/proto/v1/buf.yaml @@ -0,0 +1,7 @@ +version: v2 +lint: + use: + - DEFAULT +breaking: + use: + - FILE diff --git a/pkg/services/authz/zanzana/proto/v1/extention.pb.go b/pkg/services/authz/zanzana/proto/v1/extention.pb.go new file mode 100644 index 00000000000..e4e8841dfb9 --- /dev/null +++ b/pkg/services/authz/zanzana/proto/v1/extention.pb.go @@ -0,0 +1,66 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.2 +// protoc (unknown) +// source: extention.proto + +package v1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +var File_extention_proto protoreflect.FileDescriptor + +var file_extention_proto_rawDesc = []byte{ + 0x0a, 0x0f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x12, 0x61, 0x75, 0x74, 0x68, 0x7a, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x32, 0x17, 0x0a, 0x15, 0x41, 0x75, 0x74, 0x68, 0x7a, 0x45, 0x78, + 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x38, + 0x5a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, + 0x66, 0x61, 0x6e, 0x61, 0x2f, 0x67, 0x72, 0x61, 0x66, 0x61, 0x6e, 0x61, 0x2f, 0x70, 0x6b, 0x67, + 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x7a, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var file_extention_proto_goTypes = []any{} +var file_extention_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_extention_proto_init() } +func file_extention_proto_init() { + if File_extention_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_extention_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_extention_proto_goTypes, + DependencyIndexes: file_extention_proto_depIdxs, + }.Build() + File_extention_proto = out.File + file_extention_proto_rawDesc = nil + file_extention_proto_goTypes = nil + file_extention_proto_depIdxs = nil +} diff --git a/pkg/services/authz/zanzana/proto/v1/extention.proto b/pkg/services/authz/zanzana/proto/v1/extention.proto new file mode 100644 index 00000000000..a5684ff29c9 --- /dev/null +++ b/pkg/services/authz/zanzana/proto/v1/extention.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +option go_package = "github.com/grafana/grafana/pkg/services/authz/proto/v1"; + +package authz.extention.v1; + +service AuthzExtentionService {} diff --git a/pkg/services/authz/zanzana/proto/v1/extention_grpc.pb.go b/pkg/services/authz/zanzana/proto/v1/extention_grpc.pb.go new file mode 100644 index 00000000000..a611452e54d --- /dev/null +++ b/pkg/services/authz/zanzana/proto/v1/extention_grpc.pb.go @@ -0,0 +1,62 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.4.0 +// - protoc (unknown) +// source: extention.proto + +package v1 + +import ( + grpc "google.golang.org/grpc" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.62.0 or later. +const _ = grpc.SupportPackageIsVersion8 + +// AuthzExtentionServiceClient is the client API for AuthzExtentionService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type AuthzExtentionServiceClient interface { +} + +type authzExtentionServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewAuthzExtentionServiceClient(cc grpc.ClientConnInterface) AuthzExtentionServiceClient { + return &authzExtentionServiceClient{cc} +} + +// AuthzExtentionServiceServer is the server API for AuthzExtentionService service. +// All implementations should embed UnimplementedAuthzExtentionServiceServer +// for forward compatibility +type AuthzExtentionServiceServer interface { +} + +// UnimplementedAuthzExtentionServiceServer should be embedded to have forward compatible implementations. +type UnimplementedAuthzExtentionServiceServer struct { +} + +// UnsafeAuthzExtentionServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AuthzExtentionServiceServer will +// result in compilation errors. +type UnsafeAuthzExtentionServiceServer interface { + mustEmbedUnimplementedAuthzExtentionServiceServer() +} + +func RegisterAuthzExtentionServiceServer(s grpc.ServiceRegistrar, srv AuthzExtentionServiceServer) { + s.RegisterService(&AuthzExtentionService_ServiceDesc, srv) +} + +// AuthzExtentionService_ServiceDesc is the grpc.ServiceDesc for AuthzExtentionService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var AuthzExtentionService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "authz.extention.v1.AuthzExtentionService", + HandlerType: (*AuthzExtentionServiceServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{}, + Metadata: "extention.proto", +} diff --git a/pkg/services/authz/zanzana/server.go b/pkg/services/authz/zanzana/server.go index 33730ae9341..813fbba1123 100644 --- a/pkg/services/authz/zanzana/server.go +++ b/pkg/services/authz/zanzana/server.go @@ -1,6 +1,7 @@ package zanzana import ( + openfgav1 "github.com/openfga/api/proto/openfga/v1" "github.com/openfga/openfga/pkg/server" "github.com/openfga/openfga/pkg/storage" @@ -11,8 +12,12 @@ import ( zserver "github.com/grafana/grafana/pkg/services/authz/zanzana/server" ) -func NewServer(cfg *setting.Cfg, store storage.OpenFGADatastore, logger log.Logger) (*server.Server, error) { - return zserver.New(&cfg.Zanzana, store, logger) +func NewOpenFGAServer(cfg *setting.Cfg, store storage.OpenFGADatastore, logger log.Logger) (*server.Server, error) { + return zserver.NewOpenFGA(&cfg.Zanzana, store, logger) +} + +func NewAuthzServer(openfga openfgav1.OpenFGAServiceServer) *zserver.Server { + return zserver.NewAuthz(openfga) } func StartOpenFGAHttpSever(cfg *setting.Cfg, srv grpcserver.Provider, logger log.Logger) error { diff --git a/pkg/services/authz/zanzana/server/authz_server.go b/pkg/services/authz/zanzana/server/authz_server.go new file mode 100644 index 00000000000..ee9a20e5aa2 --- /dev/null +++ b/pkg/services/authz/zanzana/server/authz_server.go @@ -0,0 +1,32 @@ +package server + +import ( + "context" + + authzv1 "github.com/grafana/authlib/authz/proto/v1" + openfgav1 "github.com/openfga/api/proto/openfga/v1" + "go.opentelemetry.io/otel" + + authzextv1 "github.com/grafana/grafana/pkg/services/authz/zanzana/proto/v1" +) + +var _ authzv1.AuthzServiceServer = (*Server)(nil) +var _ authzextv1.AuthzExtentionServiceServer = (*Server)(nil) + +var tracer = otel.Tracer("github.com/grafana/grafana/pkg/services/authz/zanzana/server") + +func NewAuthz(openfga openfgav1.OpenFGAServiceServer) *Server { + return &Server{openfga: openfga} +} + +type Server struct { + authzv1.UnimplementedAuthzServiceServer + authzextv1.UnimplementedAuthzExtentionServiceServer + + openfga openfgav1.OpenFGAServiceServer +} + +func (s *Server) Check(ctx context.Context, r *authzv1.CheckRequest) (*authzv1.CheckResponse, error) { + tracer.Start(ctx, "authzServer.Check") + return &authzv1.CheckResponse{}, nil +} diff --git a/pkg/services/authz/zanzana/server/server.go b/pkg/services/authz/zanzana/server/openfga_server.go similarity index 96% rename from pkg/services/authz/zanzana/server/server.go rename to pkg/services/authz/zanzana/server/openfga_server.go index dc1f935c810..635b9e24c63 100644 --- a/pkg/services/authz/zanzana/server/server.go +++ b/pkg/services/authz/zanzana/server/openfga_server.go @@ -27,7 +27,7 @@ import ( zlogger "github.com/grafana/grafana/pkg/services/authz/zanzana/logger" ) -func New(cfg *setting.ZanzanaSettings, store storage.OpenFGADatastore, logger log.Logger) (*server.Server, error) { +func NewOpenFGA(cfg *setting.ZanzanaSettings, store storage.OpenFGADatastore, logger log.Logger) (*server.Server, error) { opts := []server.OpenFGAServiceV1Option{ server.WithDatastore(store), server.WithLogger(zlogger.New(logger)),