Skip to content
This repository has been archived by the owner on Apr 3, 2024. It is now read-only.

Allow overriding base Temporal server config and client options #75

Merged
merged 23 commits into from
Jun 28, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
3c7f433
added options for configuring tls
mightyshazam May 18, 2022
218bf9b
added tests for tls with and without mutal tls
mightyshazam May 18, 2022
8c64a63
renamed flags and simplified certificate generation
mightyshazam Jun 8, 2022
1e971fe
fixed some mixed case occurences of Tls
mightyshazam Jun 8, 2022
fc45b20
added docs for public methods and replaced useMtls with clientAuth
mightyshazam Jun 8, 2022
44952e9
renamed generateCa method and removed old comment
mightyshazam Jun 8, 2022
8813c39
Merge branch 'main' into adding-tls
mightyshazam Jun 8, 2022
25d67f8
Update temporaltest/options.go
mightyshazam Jun 15, 2022
a4928bb
refactored to use config file for tls options
mightyshazam Jun 16, 2022
004b821
removed superfluous tls code
mightyshazam Jun 16, 2022
09cfc2d
applied formatting for readability with temporal test server options
mightyshazam Jun 16, 2022
be16abc
refactored config construction to avoid panic
mightyshazam Jun 16, 2022
b005946
added missing comment
mightyshazam Jun 16, 2022
509f3c8
Update options.go
mightyshazam Jun 21, 2022
6e688a9
Update temporaltest/server.go
mightyshazam Jun 21, 2022
9bc5820
Update temporaltest/options.go
mightyshazam Jun 21, 2022
52c23c9
Update cmd/temporalite/main.go
mightyshazam Jun 21, 2022
7cbed53
Apply suggestions from code review
mightyshazam Jun 21, 2022
93d2254
adding review suggestions
mightyshazam Jun 21, 2022
98308a0
Merge branch 'adding-tls' of github.com:mightyshazam/temporalite into…
mightyshazam Jun 21, 2022
2246795
Merge branch 'main' into adding-tls
mightyshazam Jun 24, 2022
3cd790e
Run goimports
jlegrone Jun 28, 2022
edf33ef
Use WithBaseClientOptions to match WithBaseConfig
jlegrone Jun 28, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 65 additions & 10 deletions cmd/temporalite/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,20 @@ var (
)

const (
ephemeralFlag = "ephemeral"
dbPathFlag = "filename"
portFlag = "port"
uiPortFlag = "ui-port"
headlessFlag = "headless"
ipFlag = "ip"
logFormatFlag = "log-format"
logLevelFlag = "log-level"
namespaceFlag = "namespace"
pragmaFlag = "sqlite-pragma"
ephemeralFlag = "ephemeral"
dbPathFlag = "filename"
portFlag = "port"
uiPortFlag = "ui-port"
headlessFlag = "headless"
ipFlag = "ip"
logFormatFlag = "log-format"
logLevelFlag = "log-level"
namespaceFlag = "namespace"
pragmaFlag = "sqlite-pragma"
tlsCertFlag = "tls-certificate-file"
tlsKeyFlag = "tls-key-file"
clientAuthFlag = "require-mutual-tls"
clientCAFlag = "client-certificate-authority"
)

func init() {
Expand Down Expand Up @@ -125,6 +129,34 @@ func buildCLI() *cli.App {
EnvVars: nil,
Value: nil,
},
&cli.BoolFlag{
Name: clientAuthFlag,
Aliases: []string{"mtls"},
Usage: `require mutual tls`,
EnvVars: nil,
Value: false,
},
&cli.StringFlag{
Name: tlsCertFlag,
Aliases: []string{"cert"},
Usage: `path to tls certificate`,
EnvVars: nil,
Value: "",
},
&cli.StringFlag{
Name: tlsKeyFlag,
Aliases: []string{"key"},
Usage: `path to tls key`,
EnvVars: nil,
mightyshazam marked this conversation as resolved.
Show resolved Hide resolved
Value: "",
},
&cli.StringSliceFlag{
Name: clientCAFlag,
Aliases: []string{},
Usage: `path to client certificate authority`,
EnvVars: nil,
Value: cli.NewStringSlice(),
},
},
Before: func(c *cli.Context) error {
if c.Args().Len() > 0 {
Expand All @@ -151,6 +183,27 @@ func buildCLI() *cli.App {
return cli.Exit(fmt.Sprintf("bad value %q passed for flag %q", c.String(ipFlag), ipFlag), 1)
}

if c.IsSet(tlsCertFlag) || c.IsSet(tlsKeyFlag) {
if c.String(tlsCertFlag) == "" {
return cli.Exit("tls certificate path and key file path must both be set", 1)
}

if c.String(tlsKeyFlag) == "" {
return cli.Exit("tls certificate path and key file path must both be set", 1)
}
}

if c.IsSet(clientAuthFlag) {
if !(c.IsSet(tlsCertFlag) && c.IsSet(tlsKeyFlag)) {
return cli.Exit("tls certificate path and key file path must both be set to enable mutual tls", 1)
}

clientAuthorities := c.StringSlice(clientCAFlag)
if !c.IsSet(clientCAFlag) || clientAuthorities == nil || len(clientAuthorities) == 0 {
return cli.Exit("client certificate authority required for mutual tls", 1)
}
}
jlegrone marked this conversation as resolved.
Show resolved Hide resolved

return nil
},
Action: func(c *cli.Context) error {
Expand Down Expand Up @@ -179,6 +232,8 @@ func buildCLI() *cli.App {
temporalite.WithUpstreamOptions(
temporal.InterruptOn(temporal.InterruptCh()),
),
temporalite.WithTLSOptions(c.StringSlice(clientCAFlag),
c.String(tlsCertFlag), c.String(tlsKeyFlag), c.Bool(clientAuthFlag)),
}
if !c.Bool(headlessFlag) {
opt := newUIOption(fmt.Sprintf(":%d", c.Int(portFlag)), ip, uiPort)
Expand Down
31 changes: 31 additions & 0 deletions internal/liteconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ type Config struct {
portProvider *portProvider
FrontendIP string
UIServer UIServer
TLS config.ServerTLS
}

var SupportedPragmas = map[string]struct{}{
Expand Down Expand Up @@ -93,6 +94,7 @@ func NewDefaultConfig() (*Config, error) {
})),
portProvider: &portProvider{},
FrontendIP: "",
TLS: config.ServerTLS{},
}, nil
}

Expand Down Expand Up @@ -135,6 +137,34 @@ func Convert(cfg *Config) *config.Config {
pprofPort = cfg.FrontendPort + 201
}

tls := config.RootTLS{
Frontend: config.GroupTLS{
Server: config.ServerTLS{
CertFile: cfg.TLS.CertFile,
KeyFile: cfg.TLS.KeyFile,
RequireClientAuth: cfg.TLS.RequireClientAuth,
ClientCAFiles: cfg.TLS.ClientCAFiles,
},
Client: config.ClientTLS{
RootCAFiles: cfg.TLS.ClientCAFiles,
},
},
}

if tls.Frontend.Server.RequireClientAuth {
tls.Internode = config.GroupTLS{
Server: config.ServerTLS{
CertFile: cfg.TLS.CertFile,
KeyFile: cfg.TLS.KeyFile,
RequireClientAuth: cfg.TLS.RequireClientAuth,
ClientCAFiles: cfg.TLS.ClientCAFiles,
},
Client: config.ClientTLS{
RootCAFiles: cfg.TLS.ClientCAFiles,
},
}
}

return &config.Config{
Global: config.Global{
Membership: config.Membership{
Expand All @@ -148,6 +178,7 @@ func Convert(cfg *Config) *config.Config {
},
},
PProf: config.PProf{Port: pprofPort},
TLS: tls,
},
Persistence: config.Persistence{
DefaultStore: PersistenceStoreName,
Expand Down
13 changes: 13 additions & 0 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,19 @@ func WithUpstreamOptions(options ...temporal.ServerOption) ServerOption {
})
}

// WithTLSOptions configures tls for the Temporal server
func WithTLSOptions(caCertificates []string, certificate, key string, clientAuth bool) ServerOption {
return newApplyFuncContainer(func(cfg *liteconfig.Config) {
for _, v := range caCertificates {
cfg.TLS.ClientCAFiles = append(cfg.TLS.ClientCAFiles, v)
}

cfg.TLS.CertFile = certificate
cfg.TLS.KeyFile = key
cfg.TLS.RequireClientAuth = clientAuth
})
}

type applyFuncContainer struct {
applyInternal func(*liteconfig.Config)
}
Expand Down
10 changes: 10 additions & 0 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (
"go.temporal.io/server/common/authorization"
"go.temporal.io/server/common/config"
"go.temporal.io/server/common/dynamicconfig"
"go.temporal.io/server/common/metrics"
"go.temporal.io/server/common/rpc/encryption"
"go.temporal.io/server/schema/sqlite"
"go.temporal.io/server/temporal"

Expand Down Expand Up @@ -94,6 +96,14 @@ func NewServer(opts ...ServerOption) (*Server, error) {
serverOpts = append(serverOpts, c.UpstreamOptions...)
}

if cfg.Global.TLS.Frontend.Server.CertFile != "" {
provider, err := encryption.NewLocalStoreTlsProvider(&cfg.Global.TLS, metrics.NoopClient.Scope(0), c.Logger, encryption.NewLocalStoreCertProvider)
if err != nil {
return nil, fmt.Errorf("unable to instiate tls provider: %w", err)
}
serverOpts = append(serverOpts, temporal.WithTLSConfigFactory(provider))
}

s := &Server{
internal: temporal.NewServer(serverOpts...),
ui: c.UIServer,
Expand Down
20 changes: 19 additions & 1 deletion temporaltest/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@

package temporaltest

import "testing"
import (
"github.com/DataDog/temporalite"
"go.temporal.io/sdk/client"
"testing"
)

type TestServerOption interface {
apply(*TestServer)
Expand All @@ -20,6 +24,20 @@ func WithT(t *testing.T) TestServerOption {
})
}

// WithClientOptions configures options for the default client of the test server
mightyshazam marked this conversation as resolved.
Show resolved Hide resolved
func WithClientOptions(o client.Options) TestServerOption {
return newApplyFuncContainer(func(server *TestServer) {
server.defaultClientOptions = o
})
}

// WithTLS configures the tls options for the server
func WithTLS(caCertificates []string, certificate, key string, clientAuth bool) TestServerOption {
return newApplyFuncContainer(func(server *TestServer) {
server.serverOptions = append(server.serverOptions, temporalite.WithTLSOptions(caCertificates, certificate, key, clientAuth))
})
}
jlegrone marked this conversation as resolved.
Show resolved Hide resolved

type applyFuncContainer struct {
applyInternal func(*TestServer)
}
Expand Down
18 changes: 13 additions & 5 deletions temporaltest/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ type TestServer struct {
clients []client.Client
workers []worker.Worker
t *testing.T
defaultClientOptions client.Options
serverOptions []temporalite.ServerOption
}

func (ts *TestServer) fatal(err error) {
Expand Down Expand Up @@ -56,7 +58,7 @@ func (ts *TestServer) Worker(taskQueue string, registerFunc func(registry worker
// be closed on TestServer.Stop.
func (ts *TestServer) Client() client.Client {
if ts.defaultClient == nil {
ts.defaultClient = ts.NewClientWithOptions(client.Options{})
ts.defaultClient = ts.NewClientWithOptions(ts.defaultClientOptions)
}
return ts.defaultClient
}
Expand Down Expand Up @@ -120,11 +122,12 @@ func NewServer(opts ...TestServerOption) *TestServer {
}

s, err := temporalite.NewServer(
temporalite.WithNamespaces(ts.defaultTestNamespace),
temporalite.WithPersistenceDisabled(),
temporalite.WithDynamicPorts(),
temporalite.WithLogger(log.NewNoopLogger()),
append([]temporalite.ServerOption{temporalite.WithNamespaces(ts.defaultTestNamespace),
temporalite.WithPersistenceDisabled(),
temporalite.WithDynamicPorts(),
temporalite.WithLogger(log.NewNoopLogger())}, ts.serverOptions...)...,
)

jlegrone marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
ts.fatal(fmt.Errorf("error creating server: %w", err))
}
Expand All @@ -138,3 +141,8 @@ func NewServer(opts ...TestServerOption) *TestServer {

return &ts
}

// NewServerWithTls starts and returns a new TestServer.
//
// If not specifying the WithT option, the caller should execute Stop when finished to close
// the server and release resources.
mightyshazam marked this conversation as resolved.
Show resolved Hide resolved
Loading