refactor(embeddednats): ServerConfig with optional TLS
Collapses Start/StartHost/StartHostAuth onto StartServer(ServerConfig) so auth and a TLS config can be set without growing the parameter list further. When TLS is set the server presents the certificate and requires TLS on the data plane; the wrappers preserve the existing no-auth/no-TLS behavior. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,22 +6,33 @@
|
||||
package embeddednats
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
server "github.com/nats-io/nats-server/v2/server"
|
||||
)
|
||||
|
||||
// Start launches an embedded nats-server with JetStream enabled, listening on
|
||||
// the given port and persisting JetStream state under storeDir. The listen host
|
||||
// is left at the nats-server default ("0.0.0.0", all interfaces). It blocks
|
||||
// until the server is ready to accept connections (up to 5s) and returns the
|
||||
// running server. The caller is responsible for calling Shutdown on it.
|
||||
//
|
||||
// Start is a thin backward-compatible wrapper over StartHost; callers that need
|
||||
// to control the bind interface (loopback vs LAN) should use StartHost directly.
|
||||
// ServerConfig is the full set of knobs for the embedded NATS server. The zero
|
||||
// value (empty StoreDir aside) yields a dev-friendly server: JetStream on, bound
|
||||
// to all interfaces, no client auth, no TLS. Secured deployments set Auth and
|
||||
// TLS; tests set Host to loopback and a free Port.
|
||||
type ServerConfig struct {
|
||||
StoreDir string // JetStream store directory
|
||||
Host string // bind interface; "" = nats-server default ("0.0.0.0")
|
||||
Port int // listen port
|
||||
// Auth, when non-nil, is installed as CustomClientAuthentication so the data
|
||||
// plane only accepts approved clients (nkey signature + bus allowlist).
|
||||
Auth server.Authentication
|
||||
// TLS, when non-nil, makes the server present a certificate and require TLS
|
||||
// on the data plane. Clients must trust the issuing CA (see busauth).
|
||||
TLS *tls.Config
|
||||
}
|
||||
|
||||
// Start is a thin backward-compatible wrapper: embedded JetStream server on the
|
||||
// default interface, no auth, no TLS.
|
||||
func Start(storeDir string, port int) (*server.Server, error) {
|
||||
return StartHost(storeDir, "", port)
|
||||
return StartServer(ServerConfig{StoreDir: storeDir, Port: port})
|
||||
}
|
||||
|
||||
// StartHost is Start with explicit control over the bind interface. host selects
|
||||
@@ -30,34 +41,42 @@ func Start(storeDir string, port int) (*server.Server, error) {
|
||||
// to expose it to the LAN so remote peers (phones, other PCs) can connect. An
|
||||
// empty host falls back to the nats-server default ("0.0.0.0", all interfaces).
|
||||
func StartHost(storeDir, host string, port int) (*server.Server, error) {
|
||||
return StartHostAuth(storeDir, host, port, nil)
|
||||
return StartServer(ServerConfig{StoreDir: storeDir, Host: host, Port: port})
|
||||
}
|
||||
|
||||
// StartHostAuth is StartHost with an optional custom client authenticator. When
|
||||
// auth is non-nil it is installed as Options.CustomClientAuthentication, so the
|
||||
// data plane only accepts clients the authenticator approves (nkey signature +
|
||||
// bus allowlist). When auth is nil the server accepts any client (the legacy,
|
||||
// network-trusted behavior) — used by dev stacks and tests that have not enabled
|
||||
// bus auth.
|
||||
// auth is non-nil only clients the authenticator approves may connect; when nil
|
||||
// the server accepts any client (legacy, network-trusted behavior).
|
||||
func StartHostAuth(storeDir, host string, port int, auth server.Authentication) (*server.Server, error) {
|
||||
return StartServer(ServerConfig{StoreDir: storeDir, Host: host, Port: port, Auth: auth})
|
||||
}
|
||||
|
||||
// StartServer launches an embedded nats-server with JetStream from cfg. It
|
||||
// blocks until the server is ready to accept connections (up to 5s) and returns
|
||||
// the running server; the caller must Shutdown it.
|
||||
func StartServer(cfg ServerConfig) (*server.Server, error) {
|
||||
opts := &server.Options{
|
||||
JetStream: true,
|
||||
StoreDir: storeDir,
|
||||
Host: host,
|
||||
Port: port,
|
||||
StoreDir: cfg.StoreDir,
|
||||
Host: cfg.Host,
|
||||
Port: cfg.Port,
|
||||
DontListen: false,
|
||||
// Keep the embedded server quiet by default; the host app logs the URLs.
|
||||
NoLog: true,
|
||||
NoSigs: true,
|
||||
}
|
||||
if auth != nil {
|
||||
opts.CustomClientAuthentication = auth
|
||||
if cfg.Auth != nil {
|
||||
opts.CustomClientAuthentication = cfg.Auth
|
||||
// A CustomClientAuthentication alone does not make the server advertise a
|
||||
// nonce in its INFO line, and nats.go refuses to connect with an nkey to a
|
||||
// server that does not ("nkeys not supported by the server"). Forcing the
|
||||
// nonce makes nkey clients sign the challenge our authenticator verifies.
|
||||
opts.AlwaysEnableNonce = true
|
||||
}
|
||||
if cfg.TLS != nil {
|
||||
opts.TLSConfig = cfg.TLS
|
||||
opts.TLS = true
|
||||
}
|
||||
|
||||
ns, err := server.NewServer(opts)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user