Skip to content

Commit

Permalink
Add middleware to return the server version when requested, unless di…
Browse files Browse the repository at this point in the history
…sabled
  • Loading branch information
josephschorr committed Apr 28, 2022
1 parent 41bd3d1 commit a042362
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 9 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.18
require (
cloud.google.com/go/spanner v1.30.1
github.com/Masterminds/squirrel v1.5.2
github.com/authzed/authzed-go v0.5.1-0.20220303182356-243e79ca06fa
github.com/authzed/authzed-go v0.5.1-0.20220428172639-fe11c14e32af
github.com/authzed/grpcutil v0.0.0-20220104222419-f813f77722e5
github.com/aws/aws-sdk-go v1.43.31
github.com/benbjohnson/clock v1.3.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/authzed/authzed-go v0.5.1-0.20220303182356-243e79ca06fa h1:MUNOdz3U1UxmLL4ZQ+jjIRNvfMm/yuREwCJsk52ifac=
github.com/authzed/authzed-go v0.5.1-0.20220303182356-243e79ca06fa/go.mod h1:bsUniBRroq4l5WZMYLO+T9osQa/P2qMwZ+Af8zoJK8Y=
github.com/authzed/authzed-go v0.5.1-0.20220428172639-fe11c14e32af h1:pWgcOErXA0Az13tjurxvm6CM3XFgRP2UKACZPD6RU8Y=
github.com/authzed/authzed-go v0.5.1-0.20220428172639-fe11c14e32af/go.mod h1:bsUniBRroq4l5WZMYLO+T9osQa/P2qMwZ+Af8zoJK8Y=
github.com/authzed/grpcutil v0.0.0-20210913124023-cad23ae5a9e8/go.mod h1:HwO/KbRU3fWXEYHE96kvXnwxzi97tkXD1hfi5UaZ71Y=
github.com/authzed/grpcutil v0.0.0-20220104222419-f813f77722e5 h1:sZM7XzdyuLyxj7pC/g7uX+XAqZ7m6NMxZzuQRovgBPw=
github.com/authzed/grpcutil v0.0.0-20220104222419-f813f77722e5/go.mod h1:rqjY3zyK/YP7NID9+B2BdIRRkvnK+cdf9/qya/zaFZE=
Expand Down
51 changes: 51 additions & 0 deletions internal/middleware/serverversion/serverversion.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package serverversion

import (
"context"

"github.com/authzed/authzed-go/pkg/requestmeta"
"github.com/authzed/authzed-go/pkg/responsemeta"
"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors"
"github.com/rs/zerolog/log"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"

"github.com/authzed/spicedb/pkg/releases"
)

type handleServerVersion struct {
isEnabled bool
}

func (r *handleServerVersion) ServerReporter(ctx context.Context, _ interceptors.CallMeta) (interceptors.Reporter, context.Context) {
if r.isEnabled {
if md, ok := metadata.FromIncomingContext(ctx); ok {
if _, isRequestingVersion := md[string(requestmeta.RequestServerVersion)]; isRequestingVersion {
version, err := releases.CurrentVersion()
if err != nil {
log.Ctx(ctx).Err(err).Msg("could not load current software version")
return interceptors.NoopReporter{}, ctx
}

err = responsemeta.SetResponseHeaderMetadata(ctx, map[responsemeta.ResponseMetadataHeaderKey]string{
responsemeta.ServerVersion: version,
})
if err != nil {
log.Ctx(ctx).Err(err).Msg("could not report metadata")
}
}
}
}

return interceptors.NoopReporter{}, ctx
}

// UnaryServerInterceptor returns a new interceptor which handles server version requests.
func UnaryServerInterceptor(isEnabled bool) grpc.UnaryServerInterceptor {
return interceptors.UnaryServerInterceptor(&handleServerVersion{isEnabled})
}

// StreamServerInterceptor returns a new interceptor which handles server version requests.
func StreamServerInterceptor(isEnabled bool) grpc.StreamServerInterceptor {
return interceptors.StreamServerInterceptor(&handleServerVersion{isEnabled})
}
1 change: 1 addition & 0 deletions pkg/cmd/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ func RegisterServeFlags(cmd *cobra.Command, config *server.Config) {

// Flags for configuring API behavior
cmd.Flags().BoolVar(&config.DisableV1SchemaAPI, "disable-v1-schema-api", false, "disables the V1 schema API")
cmd.Flags().BoolVar(&config.DisableVersionResponse, "disable-version-response", false, "disables version response support in the API")

// Flags for misc services
util.RegisterHTTPServerFlags(cmd.Flags(), &config.DashboardAPI, "dashboard", "dashboard", ":8080", true)
Expand Down
5 changes: 4 additions & 1 deletion pkg/cmd/server/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
consistencymw "github.com/authzed/spicedb/internal/middleware/consistency"
datastoremw "github.com/authzed/spicedb/internal/middleware/datastore"
dispatchmw "github.com/authzed/spicedb/internal/middleware/dispatcher"
"github.com/authzed/spicedb/internal/middleware/serverversion"
"github.com/authzed/spicedb/internal/middleware/servicespecific"
logmw "github.com/authzed/spicedb/pkg/middleware/logging"
"github.com/authzed/spicedb/pkg/middleware/requestid"
Expand Down Expand Up @@ -73,7 +74,7 @@ func MetricsHandler(telemetryRegistry *prometheus.Registry) http.Handler {
return mux
}

func DefaultMiddleware(logger zerolog.Logger, authFunc grpcauth.AuthFunc, dispatcher dispatch.Dispatcher, ds datastore.Datastore) ([]grpc.UnaryServerInterceptor, []grpc.StreamServerInterceptor) {
func DefaultMiddleware(logger zerolog.Logger, authFunc grpcauth.AuthFunc, enableVersionResponse bool, dispatcher dispatch.Dispatcher, ds datastore.Datastore) ([]grpc.UnaryServerInterceptor, []grpc.StreamServerInterceptor) {
return []grpc.UnaryServerInterceptor{
requestid.UnaryServerInterceptor(requestid.GenerateIfMissing(true)),
logmw.UnaryServerInterceptor(logmw.ExtractMetadataField("x-request-id", "requestID")),
Expand All @@ -85,6 +86,7 @@ func DefaultMiddleware(logger zerolog.Logger, authFunc grpcauth.AuthFunc, dispat
datastoremw.UnaryServerInterceptor(ds),
consistencymw.UnaryServerInterceptor(),
servicespecific.UnaryServerInterceptor,
serverversion.UnaryServerInterceptor(enableVersionResponse),
}, []grpc.StreamServerInterceptor{
requestid.StreamServerInterceptor(requestid.GenerateIfMissing(true)),
logmw.StreamServerInterceptor(logmw.ExtractMetadataField("x-request-id", "requestID")),
Expand All @@ -96,6 +98,7 @@ func DefaultMiddleware(logger zerolog.Logger, authFunc grpcauth.AuthFunc, dispat
datastoremw.StreamServerInterceptor(ds),
consistencymw.StreamServerInterceptor(),
servicespecific.StreamServerInterceptor,
serverversion.StreamServerInterceptor(enableVersionResponse),
}
}

Expand Down
12 changes: 7 additions & 5 deletions pkg/cmd/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,11 @@ import (
//go:generate go run github.com/ecordell/optgen -output zz_generated.options.go . Config
type Config struct {
// API config
GRPCServer util.GRPCServerConfig
GRPCAuthFunc grpc_auth.AuthFunc
PresharedKey []string
ShutdownGracePeriod time.Duration
GRPCServer util.GRPCServerConfig
GRPCAuthFunc grpc_auth.AuthFunc
PresharedKey []string
ShutdownGracePeriod time.Duration
DisableVersionResponse bool

// GRPC Gateway config
HTTPGateway util.HTTPServerConfig
Expand Down Expand Up @@ -219,8 +220,9 @@ func (c *Config) Complete() (RunnableServer, error) {
}

if len(c.UnaryMiddleware) == 0 && len(c.StreamingMiddleware) == 0 {
c.UnaryMiddleware, c.StreamingMiddleware = DefaultMiddleware(log.Logger, c.GRPCAuthFunc, dispatcher, ds)
c.UnaryMiddleware, c.StreamingMiddleware = DefaultMiddleware(log.Logger, c.GRPCAuthFunc, !c.DisableVersionResponse, dispatcher, ds)
}

grpcServer, err := c.GRPCServer.Complete(zerolog.InfoLevel,
func(server *grpc.Server) {
services.RegisterGrpcServices(
Expand Down
8 changes: 8 additions & 0 deletions pkg/cmd/server/zz_generated.options.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit a042362

Please sign in to comment.