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
|
package embeddednats
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
server "github.com/nats-io/nats-server/v2/server"
|
server "github.com/nats-io/nats-server/v2/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Start launches an embedded nats-server with JetStream enabled, listening on
|
// ServerConfig is the full set of knobs for the embedded NATS server. The zero
|
||||||
// the given port and persisting JetStream state under storeDir. The listen host
|
// value (empty StoreDir aside) yields a dev-friendly server: JetStream on, bound
|
||||||
// is left at the nats-server default ("0.0.0.0", all interfaces). It blocks
|
// to all interfaces, no client auth, no TLS. Secured deployments set Auth and
|
||||||
// until the server is ready to accept connections (up to 5s) and returns the
|
// TLS; tests set Host to loopback and a free Port.
|
||||||
// running server. The caller is responsible for calling Shutdown on it.
|
type ServerConfig struct {
|
||||||
//
|
StoreDir string // JetStream store directory
|
||||||
// Start is a thin backward-compatible wrapper over StartHost; callers that need
|
Host string // bind interface; "" = nats-server default ("0.0.0.0")
|
||||||
// to control the bind interface (loopback vs LAN) should use StartHost directly.
|
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) {
|
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
|
// 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
|
// 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).
|
// 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) {
|
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
|
// StartHostAuth is StartHost with an optional custom client authenticator. When
|
||||||
// auth is non-nil it is installed as Options.CustomClientAuthentication, so the
|
// auth is non-nil only clients the authenticator approves may connect; when nil
|
||||||
// data plane only accepts clients the authenticator approves (nkey signature +
|
// the server accepts any client (legacy, network-trusted behavior).
|
||||||
// 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.
|
|
||||||
func StartHostAuth(storeDir, host string, port int, auth server.Authentication) (*server.Server, error) {
|
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{
|
opts := &server.Options{
|
||||||
JetStream: true,
|
JetStream: true,
|
||||||
StoreDir: storeDir,
|
StoreDir: cfg.StoreDir,
|
||||||
Host: host,
|
Host: cfg.Host,
|
||||||
Port: port,
|
Port: cfg.Port,
|
||||||
DontListen: false,
|
DontListen: false,
|
||||||
// Keep the embedded server quiet by default; the host app logs the URLs.
|
// Keep the embedded server quiet by default; the host app logs the URLs.
|
||||||
NoLog: true,
|
NoLog: true,
|
||||||
NoSigs: true,
|
NoSigs: true,
|
||||||
}
|
}
|
||||||
if auth != nil {
|
if cfg.Auth != nil {
|
||||||
opts.CustomClientAuthentication = auth
|
opts.CustomClientAuthentication = cfg.Auth
|
||||||
// A CustomClientAuthentication alone does not make the server advertise a
|
// 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
|
// 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
|
// server that does not ("nkeys not supported by the server"). Forcing the
|
||||||
// nonce makes nkey clients sign the challenge our authenticator verifies.
|
// nonce makes nkey clients sign the challenge our authenticator verifies.
|
||||||
opts.AlwaysEnableNonce = true
|
opts.AlwaysEnableNonce = true
|
||||||
}
|
}
|
||||||
|
if cfg.TLS != nil {
|
||||||
|
opts.TLSConfig = cfg.TLS
|
||||||
|
opts.TLS = true
|
||||||
|
}
|
||||||
|
|
||||||
ns, err := server.NewServer(opts)
|
ns, err := server.NewServer(opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user