diff --git a/backend/pkg/api/api.go b/backend/pkg/api/api.go index 97cacbd1d..df9936e38 100644 --- a/backend/pkg/api/api.go +++ b/backend/pkg/api/api.go @@ -14,27 +14,20 @@ package api import ( - "context" - "errors" "io/fs" "math" - connect_go "connectrpc.com/connect" - "connectrpc.com/grpcreflect" - "github.com/bufbuild/protovalidate-go" "github.com/cloudhut/common/logging" "github.com/cloudhut/common/rest" "go.uber.org/zap" "golang.org/x/net/http2" "golang.org/x/net/http2/h2c" - "google.golang.org/protobuf/reflect/protoreflect" "github.com/redpanda-data/console/backend/pkg/config" "github.com/redpanda-data/console/backend/pkg/connect" "github.com/redpanda-data/console/backend/pkg/console" "github.com/redpanda-data/console/backend/pkg/embed" "github.com/redpanda-data/console/backend/pkg/git" - "github.com/redpanda-data/console/backend/pkg/protogen/redpanda/api/console/v1alpha/consolev1alphaconnect" "github.com/redpanda-data/console/backend/pkg/redpanda" "github.com/redpanda-data/console/backend/pkg/version" ) @@ -129,27 +122,6 @@ func (api *API) Start() { mux := api.routes() - v, err := protovalidate.New() - if err != nil { - api.Logger.Fatal("failed to create proto validator", zap.Error(err)) - } - - interceptors := []connect_go.Interceptor{} - - // we want the actual request validation after all authorization and permission checks - interceptors = append(interceptors, NewRequestValidationInterceptor(api.Logger, v)) - - // Connect service(s) - mux.Mount(consolev1alphaconnect.NewConsoleServiceHandler( - api, - connect_go.WithInterceptors(interceptors...), - )) - - // Connect reflection - reflector := grpcreflect.NewStaticReflector(consolev1alphaconnect.ConsoleServiceName) - mux.Mount(grpcreflect.NewHandlerV1(reflector)) - mux.Mount(grpcreflect.NewHandlerV1Alpha(reflector)) - // Server api.server, err = rest.NewServer(&api.Cfg.REST.Config, api.Logger, mux) if err != nil { @@ -164,26 +136,3 @@ func (api *API) Start() { api.Logger.Fatal("REST Server returned an error", zap.Error(err)) } } - -func NewRequestValidationInterceptor(logger *zap.Logger, validator *protovalidate.Validator) connect_go.UnaryInterceptorFunc { - interceptor := func(next connect_go.UnaryFunc) connect_go.UnaryFunc { - return connect_go.UnaryFunc(func( - ctx context.Context, - req connect_go.AnyRequest, - ) (connect_go.AnyResponse, error) { - msg, ok := req.Any().(protoreflect.ProtoMessage) - if !ok { - return nil, connect_go.NewError(connect_go.CodeInvalidArgument, errors.New("request is not a protocol buffer message")) - } - - err := validator.Validate(msg) - if err != nil { - return nil, err - } - - return next(ctx, req) - }) - } - - return connect_go.UnaryInterceptorFunc(interceptor) -} diff --git a/backend/pkg/api/routes.go b/backend/pkg/api/routes.go index 82c84a77c..16036f692 100644 --- a/backend/pkg/api/routes.go +++ b/backend/pkg/api/routes.go @@ -10,8 +10,13 @@ package api import ( + "context" + "errors" "net/http" + connect_go "connectrpc.com/connect" + "connectrpc.com/grpcreflect" + "github.com/bufbuild/protovalidate-go" "github.com/cloudhut/common/middleware" "github.com/cloudhut/common/rest" "github.com/go-chi/chi/v5" @@ -19,7 +24,9 @@ import ( "github.com/go-chi/cors" "github.com/prometheus/client_golang/prometheus/promhttp" "go.uber.org/zap" + "google.golang.org/protobuf/reflect/protoreflect" + "github.com/redpanda-data/console/backend/pkg/protogen/redpanda/api/console/v1alpha/consolev1alphaconnect" "github.com/redpanda-data/console/backend/pkg/version" ) @@ -157,6 +164,28 @@ func (api *API) routes() *chi.Mux { api.Hooks.Route.ConfigAPIRouterPostRegistration(r) }) + // Connect RPC + v, err := protovalidate.New() + if err != nil { + api.Logger.Fatal("failed to create proto validator", zap.Error(err)) + } + + interceptors := []connect_go.Interceptor{} + + // we want the actual request validation after all authorization and permission checks + interceptors = append(interceptors, NewRequestValidationInterceptor(api.Logger, v)) + + // Connect service(s) + router.Mount(consolev1alphaconnect.NewConsoleServiceHandler( + api, + connect_go.WithInterceptors(interceptors...), + )) + + // Connect reflection + reflector := grpcreflect.NewStaticReflector(consolev1alphaconnect.ConsoleServiceName) + router.Mount(grpcreflect.NewHandlerV1(reflector)) + router.Mount(grpcreflect.NewHandlerV1Alpha(reflector)) + if api.Cfg.ServeFrontend { // SPA Files router.Group(func(r chi.Router) { @@ -176,3 +205,26 @@ func (api *API) routes() *chi.Mux { return baseRouter } + +func NewRequestValidationInterceptor(logger *zap.Logger, validator *protovalidate.Validator) connect_go.UnaryInterceptorFunc { + interceptor := func(next connect_go.UnaryFunc) connect_go.UnaryFunc { + return connect_go.UnaryFunc(func( + ctx context.Context, + req connect_go.AnyRequest, + ) (connect_go.AnyResponse, error) { + msg, ok := req.Any().(protoreflect.ProtoMessage) + if !ok { + return nil, connect_go.NewError(connect_go.CodeInvalidArgument, errors.New("request is not a protocol buffer message")) + } + + err := validator.Validate(msg) + if err != nil { + return nil, err + } + + return next(ctx, req) + }) + } + + return connect_go.UnaryInterceptorFunc(interceptor) +} diff --git a/backend/pkg/kafka/testdata/proto/gen/index/v1/data.pb.go b/backend/pkg/kafka/testdata/proto/gen/index/v1/data.pb.go index 1445c0a46..ad7b8b853 100644 --- a/backend/pkg/kafka/testdata/proto/gen/index/v1/data.pb.go +++ b/backend/pkg/kafka/testdata/proto/gen/index/v1/data.pb.go @@ -7,10 +7,11 @@ package v1 import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" ) const ( diff --git a/backend/pkg/kafka/testdata/proto/gen/shop/v1/order.pb.go b/backend/pkg/kafka/testdata/proto/gen/shop/v1/order.pb.go index 69c2085f3..29b694a4e 100644 --- a/backend/pkg/kafka/testdata/proto/gen/shop/v1/order.pb.go +++ b/backend/pkg/kafka/testdata/proto/gen/shop/v1/order.pb.go @@ -7,11 +7,12 @@ package v1 import ( + reflect "reflect" + sync "sync" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" - sync "sync" ) const ( diff --git a/backend/pkg/kafka/testdata/proto/gen/shop/v2/address.pb.go b/backend/pkg/kafka/testdata/proto/gen/shop/v2/address.pb.go index aae209b49..26cca53c7 100644 --- a/backend/pkg/kafka/testdata/proto/gen/shop/v2/address.pb.go +++ b/backend/pkg/kafka/testdata/proto/gen/shop/v2/address.pb.go @@ -7,11 +7,12 @@ package v2 import ( + reflect "reflect" + sync "sync" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" - sync "sync" ) const ( diff --git a/backend/pkg/kafka/testdata/proto/gen/shop/v2/customer.pb.go b/backend/pkg/kafka/testdata/proto/gen/shop/v2/customer.pb.go index 006fc5e9f..2d88889c0 100644 --- a/backend/pkg/kafka/testdata/proto/gen/shop/v2/customer.pb.go +++ b/backend/pkg/kafka/testdata/proto/gen/shop/v2/customer.pb.go @@ -7,10 +7,11 @@ package v2 import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" ) const ( diff --git a/backend/pkg/kafka/testdata/proto/gen/shop/v2/order.pb.go b/backend/pkg/kafka/testdata/proto/gen/shop/v2/order.pb.go index b1f8f8333..f5e47b3f7 100644 --- a/backend/pkg/kafka/testdata/proto/gen/shop/v2/order.pb.go +++ b/backend/pkg/kafka/testdata/proto/gen/shop/v2/order.pb.go @@ -7,11 +7,12 @@ package v2 import ( + reflect "reflect" + sync "sync" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" - sync "sync" ) const ( diff --git a/backend/pkg/protogen/redpanda/api/console/v1alpha/consolev1alphaconnect/list_messages.connect.go b/backend/pkg/protogen/redpanda/api/console/v1alpha/consolev1alphaconnect/list_messages.connect.go index 0d2deddad..a80da5103 100644 --- a/backend/pkg/protogen/redpanda/api/console/v1alpha/consolev1alphaconnect/list_messages.connect.go +++ b/backend/pkg/protogen/redpanda/api/console/v1alpha/consolev1alphaconnect/list_messages.connect.go @@ -5,12 +5,14 @@ package consolev1alphaconnect import ( - connect "connectrpc.com/connect" context "context" errors "errors" - v1alpha "github.com/redpanda-data/console/backend/pkg/protogen/redpanda/api/console/v1alpha" http "net/http" strings "strings" + + connect "connectrpc.com/connect" + + v1alpha "github.com/redpanda-data/console/backend/pkg/protogen/redpanda/api/console/v1alpha" ) // This is a compile-time assertion to ensure that this generated file and the connect package are diff --git a/backend/pkg/protogen/redpanda/api/console/v1alpha/list_messages.pb.go b/backend/pkg/protogen/redpanda/api/console/v1alpha/list_messages.pb.go index ed7f8fb10..60df267e7 100644 --- a/backend/pkg/protogen/redpanda/api/console/v1alpha/list_messages.pb.go +++ b/backend/pkg/protogen/redpanda/api/console/v1alpha/list_messages.pb.go @@ -7,11 +7,12 @@ package consolev1alpha import ( + reflect "reflect" + sync "sync" + _ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" ) const ( diff --git a/backend/pkg/serde/testdata/proto/gen/index/v1/data.pb.go b/backend/pkg/serde/testdata/proto/gen/index/v1/data.pb.go index 3945d1e8a..40a967963 100644 --- a/backend/pkg/serde/testdata/proto/gen/index/v1/data.pb.go +++ b/backend/pkg/serde/testdata/proto/gen/index/v1/data.pb.go @@ -7,10 +7,11 @@ package v1 import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" ) const ( diff --git a/backend/pkg/serde/testdata/proto/gen/shop/v1/order.pb.go b/backend/pkg/serde/testdata/proto/gen/shop/v1/order.pb.go index 0e520a202..0d5fbd080 100644 --- a/backend/pkg/serde/testdata/proto/gen/shop/v1/order.pb.go +++ b/backend/pkg/serde/testdata/proto/gen/shop/v1/order.pb.go @@ -7,11 +7,12 @@ package v1 import ( + reflect "reflect" + sync "sync" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" - sync "sync" ) const ( diff --git a/backend/pkg/serde/testdata/proto/gen/shop/v2/address.pb.go b/backend/pkg/serde/testdata/proto/gen/shop/v2/address.pb.go index 50402f225..bda1e88f6 100644 --- a/backend/pkg/serde/testdata/proto/gen/shop/v2/address.pb.go +++ b/backend/pkg/serde/testdata/proto/gen/shop/v2/address.pb.go @@ -7,11 +7,12 @@ package v2 import ( + reflect "reflect" + sync "sync" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" - sync "sync" ) const ( diff --git a/backend/pkg/serde/testdata/proto/gen/shop/v2/customer.pb.go b/backend/pkg/serde/testdata/proto/gen/shop/v2/customer.pb.go index 56f6b030f..f3eacc7a1 100644 --- a/backend/pkg/serde/testdata/proto/gen/shop/v2/customer.pb.go +++ b/backend/pkg/serde/testdata/proto/gen/shop/v2/customer.pb.go @@ -7,10 +7,11 @@ package v2 import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" ) const ( diff --git a/backend/pkg/serde/testdata/proto/gen/shop/v2/order.pb.go b/backend/pkg/serde/testdata/proto/gen/shop/v2/order.pb.go index a4ae4e423..d4ab02b02 100644 --- a/backend/pkg/serde/testdata/proto/gen/shop/v2/order.pb.go +++ b/backend/pkg/serde/testdata/proto/gen/shop/v2/order.pb.go @@ -7,11 +7,12 @@ package v2 import ( + reflect "reflect" + sync "sync" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" - sync "sync" ) const ( diff --git a/buf.gen.yaml b/buf.gen.yaml index 370778d67..951993fe5 100644 --- a/buf.gen.yaml +++ b/buf.gen.yaml @@ -12,20 +12,20 @@ plugins: opt: paths=source_relative out: backend/pkg/protogen - - plugin: buf.build/connectrpc/go + - plugin: connect-go opt: - paths=source_relative - require_unimplemented_servers=false out: backend/pkg/protogen # Typescript plugins - - plugin: buf.build/bufbuild/connect-es + - plugin: buf.build/bufbuild/es opt: - target=ts - import_extension= out: frontend/src/protogen - - plugin: buf.build/bufbuild/es + - plugin: buf.build/connectrpc/es opt: - target=ts - import_extension= diff --git a/frontend/src/protogen/redpanda/api/console/v1alpha/list_messages_connect.ts b/frontend/src/protogen/redpanda/api/console/v1alpha/list_messages_connect.ts index 98b302ac3..4dfbdad7a 100644 --- a/frontend/src/protogen/redpanda/api/console/v1alpha/list_messages_connect.ts +++ b/frontend/src/protogen/redpanda/api/console/v1alpha/list_messages_connect.ts @@ -1,4 +1,4 @@ -// @generated by protoc-gen-connect-es v0.13.0 with parameter "target=ts,import_extension=" +// @generated by protoc-gen-connect-es v0.13.2 with parameter "target=ts,import_extension=" // @generated from file redpanda/api/console/v1alpha/list_messages.proto (package redpanda.api.console.v1alpha, syntax proto3) /* eslint-disable */ // @ts-nocheck diff --git a/proto/redpanda/api/console/v1alpha/list_messages.proto b/proto/redpanda/api/console/v1alpha/list_messages.proto index 4b5a5a627..857bf0728 100644 --- a/proto/redpanda/api/console/v1alpha/list_messages.proto +++ b/proto/redpanda/api/console/v1alpha/list_messages.proto @@ -85,7 +85,7 @@ message KafkaRecordPayload { bytes normalized_payload = 2; // Normilized user friendly representation of the payload. PayloadEncoding encoding = 3; // Payload encoding if we have been able to detect. int32 schema_id = 4; // Optionally, the schema ID used to deserialized the message. - int32 payload_size = 5; // Payload size in bytes. + int32 payload_size = 5; // Payload size in bytes. bool is_payload_too_large = 6; // If payload is too large for deserialization. repeated TroubleshootReport troubleshoot_report = 7; // Troubleshooting data for debugging. } @@ -98,7 +98,7 @@ message TroubleshootReport { // KafkaRecordHeader is the record header. message KafkaRecordHeader { string key = 1; // Header key. - bytes value = 2; // Header value. + bytes value = 2; // Header value. } enum CompressionType { diff --git a/taskfiles/backend.yaml b/taskfiles/backend.yaml index 816fd07cf..df5cd47c0 100644 --- a/taskfiles/backend.yaml +++ b/taskfiles/backend.yaml @@ -72,21 +72,6 @@ tasks: status: - "[ -f '{{ .BUILD_ROOT }}/bin/go' ] || command -v {{ .BUILD_ROOT }}/bin/go/ifacemaker >/dev/null 2>&1" - install-buf: - desc: install buf - vars: - BUF_VERSION: 1.25.0 - BUF_URL: https://github.com/bufbuild/buf/releases/download/v{{.BUF_VERSION}}/buf-{{OS}}-{{ARCH}} - cmds: - - mkdir -p {{.BUILD_ROOT}}/bin - - platforms: [arm64] - cmd: curl -sSLf --retry 3 --retry-connrefused --retry-delay 2 https://github.com/bufbuild/buf/releases/download/v{{.BUF_VERSION}}/buf-{{OS}}-arm64 -o '{{.BUILD_ROOT}}/bin/buf' - - platforms: [386] - cmd: curl -sSLf --retry 3 --retry-connrefused --retry-delay 2 https://github.com/bufbuild/buf/releases/download/v{{.BUF_VERSION}}/buf-{{OS}}-x86_64 -o '{{.BUILD_ROOT}}/bin/buf' - - chmod +x '{{.BUILD_ROOT}}/bin/buf' - status: - - "[[ $({{ .BUILD_ROOT }}/bin/buf --version) == '{{.BUF_VERSION}}' ]]" - fmt: desc: Format Go code deps: diff --git a/taskfiles/proto.yaml b/taskfiles/proto.yaml index 89bd841b6..a8cb0430d 100644 --- a/taskfiles/proto.yaml +++ b/taskfiles/proto.yaml @@ -49,12 +49,13 @@ tasks: install-buf: desc: install buf vars: - BUF_VERSION: 1.25.0 - BUF_URL: https://github.com/bufbuild/buf/releases/download/v{{.BUF_VERSION}}/buf-$(uname -s)-$(uname -m) + BUF_VERSION: 1.26.1 + BUF_URL: https://github.com/bufbuild/buf/releases/download/v{{.BUF_VERSION}}/buf-{{OS}}-{{ARCH}} cmds: - mkdir -p {{.BUILD_ROOT}}/bin - - curl -sSLf --retry 3 --retry-connrefused --retry-delay 2 {{.BUF_URL}} -o '{{.BUILD_ROOT}}/bin/buf' + - curl -sSLf --retry 3 --retry-connrefused --retry-delay 2 https://github.com/bufbuild/buf/releases/download/v{{.BUF_VERSION}}/buf-{{OS}}-arm64 -o '{{.BUILD_ROOT}}/bin/buf' + - curl -sSLf --retry 3 --retry-connrefused --retry-delay 2 https://github.com/bufbuild/buf/releases/download/v{{.BUF_VERSION}}/buf-{{OS}}-x86_64 -o '{{.BUILD_ROOT}}/bin/buf' - chmod +x '{{.BUILD_ROOT}}/bin/buf' status: - test -f '{{.BUILD_ROOT}}/bin/buf' - - '[[ $({{ .BUILD_ROOT }}/bin/buf --version) == {{.BUF_VERSION}} ]]' + - "[[ $({{ .BUILD_ROOT }}/bin/buf --version) == '{{.BUF_VERSION}}' ]]" \ No newline at end of file