From abf5398d245caf3f4210a883ff7141f97c537591 Mon Sep 17 00:00:00 2001 From: Rob Watson Date: Fri, 26 Nov 2021 17:22:25 +0100 Subject: [PATCH] Allow configuration of BindAddr and TLS certs --- backend/.env.example | 2 ++ backend/cmd/clipper/main.go | 4 +--- backend/config/config.go | 17 +++++++++++++++++ backend/server/server.go | 28 +++++++++++++++++++++------- 4 files changed, 41 insertions(+), 10 deletions(-) diff --git a/backend/.env.example b/backend/.env.example index c60e03e..ef290f7 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -7,5 +7,7 @@ S3_BUCKET= DATABASE_URL= +BIND_ADDR= + # If set, files in this location will be served over HTTP at /. ASSETS_HTTP_BASE_PATH= diff --git a/backend/cmd/clipper/main.go b/backend/cmd/clipper/main.go index 6d7521f..ae8c074 100644 --- a/backend/cmd/clipper/main.go +++ b/backend/cmd/clipper/main.go @@ -17,8 +17,7 @@ import ( ) const ( - DefaultHTTPBindAddr = "0.0.0.0:8888" - DefaultTimeout = 600 * time.Second + DefaultTimeout = 600 * time.Second ) func main() { @@ -57,7 +56,6 @@ func main() { serverOptions := server.Options{ Config: config, - BindAddr: DefaultHTTPBindAddr, Timeout: DefaultTimeout, Store: store, YoutubeClient: &youtubeClient, diff --git a/backend/config/config.go b/backend/config/config.go index 4918cfe..e1f2f56 100644 --- a/backend/config/config.go +++ b/backend/config/config.go @@ -15,6 +15,9 @@ const ( type Config struct { Environment Environment + BindAddr string + TLSCertFile string + TLSKeyFile string DatabaseURL string AWSAccessKeyID string AWSSecretAccessKey string @@ -37,6 +40,17 @@ func NewFromEnv() (Config, error) { return Config{}, fmt.Errorf("invalid ENV value: %s", envString) } + bindAddr := os.Getenv("BIND_ADDR") + if bindAddr == "" { + bindAddr = "localhost:8888" + } + + tlsCertFile := os.Getenv("TLS_CERT_FILE") + tlsKeyFile := os.Getenv("TLS_KEY_FILE") + if (tlsCertFile == "" && tlsKeyFile != "") || (tlsCertFile != "" && tlsKeyFile == "") { + return Config{}, errors.New("Both TLS_CERT_FILE and TLS_KEY_FILE must be set") + } + databaseURL := os.Getenv("DATABASE_URL") if databaseURL == "" { return Config{}, errors.New("DATABASE_URL not set") @@ -66,6 +80,9 @@ func NewFromEnv() (Config, error) { return Config{ Environment: env, + BindAddr: bindAddr, + TLSCertFile: tlsCertFile, + TLSKeyFile: tlsKeyFile, DatabaseURL: databaseURL, AWSAccessKeyID: awsAccessKeyID, AWSSecretAccessKey: awsSecretAccessKey, diff --git a/backend/server/server.go b/backend/server/server.go index 3c49350..0182f36 100644 --- a/backend/server/server.go +++ b/backend/server/server.go @@ -18,6 +18,7 @@ import ( "go.uber.org/zap" "google.golang.org/grpc" "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/durationpb" ) @@ -61,7 +62,6 @@ func newResponseError(err error) *ResponseError { type Options struct { Config config.Config - BindAddr string Timeout time.Duration Store media.Store YoutubeClient media.YoutubeClient @@ -240,7 +240,11 @@ func Start(options Options) error { logger, ) - grpcServer := buildGRPCServer(options.Config, logger) + grpcServer, err := buildGRPCServer(options.Config, logger) + if err != nil { + return fmt.Errorf("error building server: %v", err) + } + mediaSetController := &mediaSetServiceController{mediaSetService: fetchMediaSetService, logger: logger.Sugar().Named("controller")} pbmediaset.RegisterMediaSetServiceServer(grpcServer, mediaSetController) @@ -255,7 +259,7 @@ func Start(options Options) error { } httpServer := http.Server{ - Addr: options.BindAddr, + Addr: options.Config.BindAddr, ReadTimeout: options.Timeout, WriteTimeout: options.Timeout, Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -267,7 +271,7 @@ func Start(options Options) error { }), } - log.Infof("Listening at %s", options.BindAddr) + log.Infof("Listening at %s", options.Config.BindAddr) return httpServer.ListenAndServe() } @@ -279,7 +283,7 @@ func buildLogger(c config.Config) (*zap.Logger, error) { return zap.NewDevelopment() } -func buildGRPCServer(c config.Config, logger *zap.Logger) *grpc.Server { +func buildGRPCServer(c config.Config, logger *zap.Logger) (*grpc.Server, error) { unaryInterceptors := []grpc.UnaryServerInterceptor{ grpczap.UnaryServerInterceptor(logger), } @@ -296,8 +300,18 @@ func buildGRPCServer(c config.Config, logger *zap.Logger) *grpc.Server { streamInterceptors = append(streamInterceptors, grpcrecovery.StreamServerInterceptor(panicOpts...)) } - return grpc.NewServer( + options := []grpc.ServerOption{ grpc.StreamInterceptor(grpcmiddleware.ChainStreamServer(streamInterceptors...)), grpc.UnaryInterceptor(grpcmiddleware.ChainUnaryServer(unaryInterceptors...)), - ) + } + + if c.TLSCertFile != "" && c.TLSKeyFile != "" { + creds, err := credentials.NewServerTLSFromFile(c.TLSCertFile, c.TLSKeyFile) + if err != nil { + return nil, fmt.Errorf("error building credentials: %v", err) + } + options = append(options, grpc.Creds(creds)) + } + + return grpc.NewServer(options...), nil }