From 6b97f597bbecbcb3cc9bddbf55304440d54e8304 Mon Sep 17 00:00:00 2001 From: Andrew Seigner Date: Tue, 21 Aug 2018 16:33:03 -0700 Subject: [PATCH] Introduce grpc-downstream-authority flag The existing `grpc-downstream-server` enabled setting a downstream server host, and via Go's gRPC default, also set the authority header. Introduce a `grpc-downstream-authority` header, allowing the user to set a string for authority, distinct from `grpc-downstream-server`. This is useful when, for example, bb needs to proxy a request through Linkerd, and still provide routing information via `authority`. Fixes #9 Signed-off-by: Andrew Seigner --- CHANGES.md | 5 +++++ README.md | 26 +++++++++++++------------- cmd/root.go | 1 + protocols/grpc.go | 20 ++++++++++++++++++-- service/service.go | 1 + 5 files changed, 38 insertions(+), 15 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 768bd53..3200508 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,8 @@ +## v0.0.4 + +* Introduce `grpc-downstream-authority` flag, to enable setting authority + separately from `grpc-downstream-server`. + ## v0.0.3 * Update docs and example files to latest release. diff --git a/README.md b/README.md index fcf553b..e42e4df 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,6 @@ A test run using the Docker CLI should return usage information and confirm that $ docker run buoyantio/bb:v0.0.3 Building Blocks or `bb` is a tool that can simulate many of the typical scenarios of a cloud-native Service-Oriented Architecture based on microservices. - Usage: bb [command] @@ -98,18 +97,19 @@ A test run using the Docker CLI should return usage information and confirm that terminus Receives the request and returns a pre-defined response Flags: - --downstream-timeout duration timeout to use when making downstream connections. (default 1m0s) - --fire-and-forget do not wait for a response when contacting downstream services. - --grpc-downstream-server stringSlice list of servers (hostname:port) to send messages to using gRPC, can be repeated - --grpc-server-port int port to bind a gRPC server to (default -1) - --h1-downstream-server stringSlice list of servers (protocol://hostname:port) to send messages to using HTTP 1.1, can be repeated - --h1-server-port int port to bind a HTTP 1.1 server to (default -1) - -h, --help help for bb - --id string identifier for this container - --log-level string log level, must be one of: panic, fatal, error, warn, info, debug (default "debug") - --percent-failure int percentage of requests that this service will automatically fail - --sleep-in-millis int amount of milliseconds to wait before actually start processing a request - --terminate-after int terminate the process after this many requests + --downstream-timeout duration timeout to use when making downstream connections. (default 1m0s) + --fire-and-forget do not wait for a response when contacting downstream services. + --grpc-downstream-authority stringSlice list of authority headers to specify routing, if set, ordering and count should match grpc-downstream-server + --grpc-downstream-server stringSlice list of servers (hostname:port) to send messages to using gRPC, can be repeated + --grpc-server-port int port to bind a gRPC server to (default -1) + --h1-downstream-server stringSlice list of servers (protocol://hostname:port) to send messages to using HTTP 1.1, can be repeated + --h1-server-port int port to bind a HTTP 1.1 server to (default -1) + -h, --help help for bb + --id string identifier for this container + --log-level string log level, must be one of: panic, fatal, error, warn, info, debug (default "debug") + --percent-failure int percentage of requests that this service will automatically fail + --sleep-in-millis int amount of milliseconds to wait before actually start processing a request + --terminate-after int terminate the process after this many requests Use "bb [command] --help" for more information about a command. diff --git a/cmd/root.go b/cmd/root.go index 79cfc28..9a3f770 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -51,6 +51,7 @@ func init() { RootCmd.PersistentFlags().IntVar(&config.TerminateAfter, "terminate-after", 0, "terminate the process after this many requests") RootCmd.PersistentFlags().BoolVar(&config.FireAndForget, "fire-and-forget", false, "do not wait for a response when contacting downstream services.") RootCmd.PersistentFlags().StringSliceVar(&config.GRPCDownstreamServers, "grpc-downstream-server", []string{}, "list of servers (hostname:port) to send messages to using gRPC, can be repeated") + RootCmd.PersistentFlags().StringSliceVar(&config.GRPCDownstreamAuthorities, "grpc-downstream-authority", []string{}, "list of authority headers to specify routing, if set, ordering and count should match grpc-downstream-server") RootCmd.PersistentFlags().StringSliceVar(&config.H1DownstreamServers, "h1-downstream-server", []string{}, "list of servers (protocol://hostname:port) to send messages to using HTTP 1.1, can be repeated") RootCmd.PersistentFlags().DurationVar(&config.DownstreamConnectionTimeout, "downstream-timeout", time.Minute*1, "timeout to use when making downstream connections.") RootCmd.PersistentFlags().StringVar(&logLevel, "log-level", log.DebugLevel.String(), "log level, must be one of: panic, fatal, error, warn, info, debug") diff --git a/protocols/grpc.go b/protocols/grpc.go index 6d7afa1..ede7aa7 100644 --- a/protocols/grpc.go +++ b/protocols/grpc.go @@ -81,8 +81,24 @@ func NewGrpcServerIfConfigured(config *service.Config, serviceHandler *service.R // downstream service func NewGrpcClientsIfConfigured(config *service.Config) ([]service.Client, error) { clients := make([]service.Client, 0) - for _, serverURL := range config.GRPCDownstreamServers { - conn, err := grpc.Dial(serverURL, grpc.WithInsecure()) + + withAuthorities := false + if len(config.GRPCDownstreamAuthorities) > 0 { + if len(config.GRPCDownstreamAuthorities) != len(config.GRPCDownstreamServers) { + err := fmt.Errorf("Authorities count (%d) does not match gRPC downstream server count (%d)", len(config.GRPCDownstreamAuthorities), len(config.GRPCDownstreamServers)) + log.Error(err) + return nil, err + } + + withAuthorities = true + } + + for i, serverURL := range config.GRPCDownstreamServers { + authority := "" + if withAuthorities { + authority = config.GRPCDownstreamAuthorities[i] + } + conn, err := grpc.Dial(serverURL, grpc.WithInsecure(), grpc.WithAuthority(authority)) if err != nil { return nil, err } diff --git a/service/service.go b/service/service.go index f1283ce..0d9f096 100644 --- a/service/service.go +++ b/service/service.go @@ -16,6 +16,7 @@ type Config struct { GRPCServerPort int H1ServerPort int GRPCDownstreamServers []string + GRPCDownstreamAuthorities []string H1DownstreamServers []string PercentageFailedRequests int SleepInMillis int