feat(raft): TLS config surface with fail-closed startup
This commit is contained in:
@@ -44,6 +44,11 @@ type
|
||||
raftPeerClientAddrs*: Table[string, tuple[host: string, port: int]]
|
||||
raftWriteTimeoutMs*: int
|
||||
raftLogMaxEntries*: int
|
||||
raftTlsEnabled*: bool
|
||||
raftTlsCertFile*: string
|
||||
raftTlsKeyFile*: string
|
||||
raftTlsCaFile*: string
|
||||
raftTlsVerifyPeer*: bool
|
||||
|
||||
CompactionStrategy* = enum
|
||||
csSizeTiered = "size_tiered"
|
||||
@@ -86,6 +91,11 @@ proc defaultConfig*(): BaraConfig =
|
||||
raftPeerClientAddrs: initTable[string, tuple[host: string, port: int]](),
|
||||
raftWriteTimeoutMs: 5_000,
|
||||
raftLogMaxEntries: 256,
|
||||
raftTlsEnabled: false,
|
||||
raftTlsCertFile: "",
|
||||
raftTlsKeyFile: "",
|
||||
raftTlsCaFile: "",
|
||||
raftTlsVerifyPeer: false,
|
||||
)
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
@@ -213,6 +223,11 @@ proc loadConfigFromEnv*(cfg: var BaraConfig) =
|
||||
cfg.raftNodeId = getEnv("BARADB_RAFT_NODE_ID", cfg.raftNodeId)
|
||||
cfg.raftWriteTimeoutMs = parseEnvInt(getEnv("BARADB_RAFT_WRITE_TIMEOUT_MS", ""), cfg.raftWriteTimeoutMs)
|
||||
cfg.raftLogMaxEntries = parseEnvInt(getEnv("BARADB_RAFT_LOG_MAX_ENTRIES", ""), cfg.raftLogMaxEntries)
|
||||
cfg.raftTlsEnabled = parseEnvBool(getEnv("BARADB_RAFT_TLS_ENABLED", ""), cfg.raftTlsEnabled)
|
||||
cfg.raftTlsCertFile = getEnv("BARADB_RAFT_TLS_CERT_FILE", cfg.raftTlsCertFile)
|
||||
cfg.raftTlsKeyFile = getEnv("BARADB_RAFT_TLS_KEY_FILE", cfg.raftTlsKeyFile)
|
||||
cfg.raftTlsCaFile = getEnv("BARADB_RAFT_TLS_CA_FILE", cfg.raftTlsCaFile)
|
||||
cfg.raftTlsVerifyPeer = parseEnvBool(getEnv("BARADB_RAFT_TLS_VERIFY_PEER", ""), cfg.raftTlsVerifyPeer)
|
||||
# Optional: client (SQL) addresses for leader write forwarding.
|
||||
# Same id@host:port shape as BARADB_RAFT_PEERS, but ports are BARADB_PORT values.
|
||||
let clientPeersEnv = getEnv("BARADB_RAFT_CLIENT_PEERS", "")
|
||||
|
||||
@@ -338,6 +338,12 @@ proc main() =
|
||||
var raftNet: RaftNetwork = nil
|
||||
if config.raftEnabled:
|
||||
info("Starting Raft node " & config.raftNodeId & " on port " & $config.raftPort)
|
||||
if config.raftTlsEnabled:
|
||||
if config.raftTlsCertFile.len == 0 or config.raftTlsKeyFile.len == 0 or
|
||||
not fileExists(config.raftTlsCertFile) or not fileExists(config.raftTlsKeyFile):
|
||||
raise newException(ValueError,
|
||||
"BARADB_RAFT_TLS_ENABLED=true but cert/key missing " &
|
||||
"(BARADB_RAFT_TLS_CERT_FILE / BARADB_RAFT_TLS_KEY_FILE)")
|
||||
let raftDataDir = config.dataDir / "raft"
|
||||
createDir(raftDataDir) # idempotent; loadState reads from it, saveState writes
|
||||
# Raft convention: `peers` excludes the node itself (majority math and
|
||||
|
||||
@@ -521,3 +521,34 @@ suite "Raft write classification":
|
||||
check not isRaftDdl(parse("CREATE DATABASE other").stmts[0])
|
||||
check not isRaftDdl(parse("INSERT INTO t (id) VALUES (1)").stmts[0])
|
||||
check not isRaftDdl(parse("SELECT 1").stmts[0])
|
||||
|
||||
|
||||
suite "Raft TLS config":
|
||||
|
||||
test "default config has raft TLS disabled with empty paths":
|
||||
let cfg = defaultConfig()
|
||||
check cfg.raftTlsEnabled == false
|
||||
check cfg.raftTlsCertFile == ""
|
||||
check cfg.raftTlsKeyFile == ""
|
||||
check cfg.raftTlsCaFile == ""
|
||||
check cfg.raftTlsVerifyPeer == false
|
||||
|
||||
test "env vars parse into raft TLS config":
|
||||
putEnv("BARADB_RAFT_TLS_ENABLED", "true")
|
||||
putEnv("BARADB_RAFT_TLS_CERT_FILE", "/tmp/raft.crt")
|
||||
putEnv("BARADB_RAFT_TLS_KEY_FILE", "/tmp/raft.key")
|
||||
putEnv("BARADB_RAFT_TLS_CA_FILE", "/tmp/raft-ca.crt")
|
||||
putEnv("BARADB_RAFT_TLS_VERIFY_PEER", "1")
|
||||
defer:
|
||||
delEnv("BARADB_RAFT_TLS_ENABLED")
|
||||
delEnv("BARADB_RAFT_TLS_CERT_FILE")
|
||||
delEnv("BARADB_RAFT_TLS_KEY_FILE")
|
||||
delEnv("BARADB_RAFT_TLS_CA_FILE")
|
||||
delEnv("BARADB_RAFT_TLS_VERIFY_PEER")
|
||||
var cfg = defaultConfig()
|
||||
loadConfigFromEnv(cfg)
|
||||
check cfg.raftTlsEnabled == true
|
||||
check cfg.raftTlsCertFile == "/tmp/raft.crt"
|
||||
check cfg.raftTlsKeyFile == "/tmp/raft.key"
|
||||
check cfg.raftTlsCaFile == "/tmp/raft-ca.crt"
|
||||
check cfg.raftTlsVerifyPeer == true
|
||||
|
||||
Reference in New Issue
Block a user