2021-03-01 19:49:43 +00:00
package steward
import (
"flag"
"fmt"
2021-03-25 10:28:26 +00:00
"log"
2021-03-01 19:49:43 +00:00
"os"
"path/filepath"
2022-06-23 07:36:46 +00:00
toml "github.com/pelletier/go-toml/v2"
2021-03-01 19:49:43 +00:00
)
2021-09-09 06:19:53 +00:00
// Configuration are the structure that holds all the different
// configuration options used both with flags and the config file.
// If a new field is added to this struct there should also be
// added the same field to the ConfigurationFromFile struct, and
// an if check should be added to the checkConfigValues function
// to set default values when reading from config file.
2021-03-01 19:49:43 +00:00
type Configuration struct {
2022-06-23 07:36:46 +00:00
// RingBufferPersistStore, enable or disable the persisting of
2022-06-21 14:44:39 +00:00
// messages being processed to local db.
2022-06-23 07:36:46 +00:00
RingBufferPersistStore bool ` comment:"RingBufferPersistStore, enable or disable the persisting of messages being processed to local db" `
2021-12-21 06:21:12 +00:00
// RingBufferSize
2022-06-23 07:36:46 +00:00
RingBufferSize int ` comment:"RingBufferSize" `
// ConfigFolder, the location for the configuration folder on disk
ConfigFolder string ` comment:"ConfigFolder, the location for the configuration folder on disk" `
2021-05-12 07:50:03 +00:00
// The folder where the socket file should live
2022-06-23 07:36:46 +00:00
SocketFolder string ` comment:"The folder where the socket file should live" `
2023-01-08 07:32:58 +00:00
// The folder where the readfolder should live
2023-01-09 03:25:03 +00:00
ReadFolder string ` comment:"The folder where the readfolder should live" `
2023-01-08 07:32:58 +00:00
// EnableReadFolder for enabling the read messages api from readfolder
EnableReadFolder bool ` comment:"EnableReadFolder for enabling the read messages api from readfolder" `
2022-06-23 07:36:46 +00:00
// TCP Listener for sending messages to the system, <host>:<port>
TCPListener string ` comment:"TCP Listener for sending messages to the system, <host>:<port>" `
// HTTP Listener for sending messages to the system, <host>:<port>
HTTPListener string ` comment:"HTTP Listener for sending messages to the system, <host>:<port>" `
2021-05-12 07:50:03 +00:00
// The folder where the database should live
2022-06-23 07:36:46 +00:00
DatabaseFolder string ` comment:"The folder where the database should live" `
// Unique string to identify this Edge unit
NodeName string ` comment:"Unique string to identify this Edge unit" `
// The address of the message broker, <address>:<port>
BrokerAddress string ` comment:"The address of the message broker, <address>:<port>" `
2021-12-17 16:28:57 +00:00
// NatsConnOptTimeout the timeout for trying the connect to nats broker
2022-06-23 07:36:46 +00:00
NatsConnOptTimeout int ` comment:"NatsConnOptTimeout the timeout for trying the connect to nats broker" `
// Nats connect retry interval in seconds
NatsConnectRetryInterval int ` comment:"Nats connect retry interval in seconds" `
2021-12-16 10:01:01 +00:00
// NatsReconnectJitter in milliseconds
2022-06-23 07:36:46 +00:00
NatsReconnectJitter int ` comment:"NatsReconnectJitter in milliseconds" `
2021-12-16 10:01:01 +00:00
// NatsReconnectJitterTLS in seconds
2022-06-23 07:36:46 +00:00
NatsReconnectJitterTLS int ` comment:"NatsReconnectJitterTLS in seconds" `
2022-05-26 06:07:23 +00:00
// REQKeysRequestUpdateInterval in seconds
2022-06-23 07:36:46 +00:00
REQKeysRequestUpdateInterval int ` comment:"REQKeysRequestUpdateInterval in seconds" `
2022-05-26 06:07:23 +00:00
// REQAclRequestUpdateInterval in seconds
2022-06-23 07:36:46 +00:00
REQAclRequestUpdateInterval int ` comment:"REQAclRequestUpdateInterval in seconds" `
2021-03-01 19:49:43 +00:00
// The number of the profiling port
2022-06-23 07:36:46 +00:00
ProfilingPort string ` comment:"The number of the profiling port" `
// Host and port for prometheus listener, e.g. localhost:2112
PromHostAndPort string ` comment:"Host and port for prometheus listener, e.g. localhost:2112" `
// Set to true if this is the node that should receive the error log's from other nodes
DefaultMessageTimeout int ` comment:"Set to true if this is the node that should receive the error log's from other nodes" `
// Default value for how long can a request method max be allowed to run in seconds
DefaultMethodTimeout int ` comment:"Default value for how long can a request method max be allowed to run in seconds" `
// Default amount of retries that will be done before a message is thrown away, and out of the system
DefaultMessageRetries int ` comment:"Default amount of retries that will be done before a message is thrown away, and out of the system" `
// The path to the data folder
SubscribersDataFolder string ` comment:"The path to the data folder" `
// Name of central node to receive logs, errors, key/acl handling
CentralNodeName string ` comment:"Name of central node to receive logs, errors, key/acl handling" `
// The full path to the certificate of the root CA
RootCAPath string ` comment:"The full path to the certificate of the root CA" `
2021-05-14 13:23:04 +00:00
// Full path to the NKEY's seed file
2022-06-23 07:36:46 +00:00
NkeySeedFile string ` comment:"Full path to the NKEY's seed file" `
// The full path to the NKEY user file
2022-04-04 08:29:14 +00:00
NkeyPublicKey string ` toml:"-" `
2022-06-23 07:36:46 +00:00
// The host and port to expose the data folder, <host>:<port>
ExposeDataFolder string ` comment:"The host and port to expose the data folder, <host>:<port>" `
// Timeout in seconds for error messages
ErrorMessageTimeout int ` comment:"Timeout in seconds for error messages" `
// Retries for error messages
ErrorMessageRetries int ` comment:"Retries for error messages" `
// Compression z for zstd or g for gzip
Compression string ` comment:"Compression z for zstd or g for gzip" `
// Serialization, supports cbor or gob,default is gob. Enable cbor by setting the string value cbor
Serialization string ` comment:"Serialization, supports cbor or gob,default is gob. Enable cbor by setting the string value cbor" `
2021-12-31 05:59:09 +00:00
// SetBlockProfileRate for block profiling
2022-06-23 07:36:46 +00:00
SetBlockProfileRate int ` comment:"SetBlockProfileRate for block profiling" `
2022-01-07 06:21:21 +00:00
// EnableSocket for enabling the creation of a steward.sock file
2022-06-23 07:36:46 +00:00
EnableSocket bool ` comment:"EnableSocket for enabling the creation of a steward.sock file" `
2022-01-07 10:17:10 +00:00
// EnableTUI will enable the Terminal User Interface
2022-06-23 07:36:46 +00:00
EnableTUI bool ` comment:"EnableTUI will enable the Terminal User Interface" `
// EnableSignatureCheck to enable signature checking
EnableSignatureCheck bool ` comment:"EnableSignatureCheck to enable signature checking" `
// EnableAclCheck to enable ACL checking
EnableAclCheck bool ` comment:"EnableAclCheck to enable ACL checking" `
// IsCentralAuth, enable to make this instance take the role as the central auth server
IsCentralAuth bool ` comment:"IsCentralAuth, enable to make this instance take the role as the central auth server" `
// EnableDebug will also enable printing all the messages received in the errorKernel to STDERR.
EnableDebug bool ` comment:"EnableDebug will also enable printing all the messages received in the errorKernel to STDERR." `
2023-01-11 05:09:42 +00:00
// LogLevel
2023-01-12 11:06:29 +00:00
LogLevel string ` comment:"LogLevel error/info/warning/debug/none." `
2023-01-11 05:09:42 +00:00
LogConsoleTimestamps bool ` comment:"LogConsoleTimestamps true/false for enabling or disabling timestamps when printing errors and information to stderr" `
2022-06-23 07:36:46 +00:00
// KeepPublishersAliveFor number of seconds
2022-06-22 06:59:03 +00:00
// Timer that will be used for when to remove the sub process
// publisher. The timer is reset each time a message is published with
// the process, so the sub process publisher will not be removed until
// it have not received any messages for the given amount of time.
2022-06-23 07:36:46 +00:00
KeepPublishersAliveFor int ` comment:"KeepPublishersAliveFor number of seconds Timer that will be used for when to remove the sub process publisher. The timer is reset each time a message is published with the process, so the sub process publisher will not be removed until it have not received any messages for the given amount of time." `
2021-09-20 04:40:34 +00:00
2022-06-23 07:36:46 +00:00
// StartPubREQHello, sets the interval in seconds for how often we send hello messages to central server
StartPubREQHello int ` comment:"StartPubREQHello, sets the interval in seconds for how often we send hello messages to central server" `
2022-05-30 05:14:15 +00:00
// Enable the updates of public keys
2022-06-23 07:36:46 +00:00
EnableKeyUpdates bool ` comment:"Enable the updates of public keys" `
2022-05-26 06:07:23 +00:00
2022-05-30 05:14:15 +00:00
// Enable the updates of acl's
2022-06-23 07:36:46 +00:00
EnableAclUpdates bool ` comment:"Enable the updates of acl's" `
2022-05-26 06:07:23 +00:00
2021-03-24 09:14:17 +00:00
// Start the central error logger.
2022-06-23 07:36:46 +00:00
IsCentralErrorLogger bool ` comment:"Start the central error logger." `
// Start subscriber for hello messages
StartSubREQHello bool ` comment:"Start subscriber for hello messages" `
// Start subscriber for text logging
StartSubREQToFileAppend bool ` comment:"Start subscriber for text logging" `
// Start subscriber for writing to file
StartSubREQToFile bool ` comment:"Start subscriber for writing to file" `
// Start subscriber for writing to file without ACK
StartSubREQToFileNACK bool ` comment:"Start subscriber for writing to file without ACK" `
// Start subscriber for reading files to copy
StartSubREQCopySrc bool ` comment:"Start subscriber for reading files to copy" `
// Start subscriber for writing copied files to disk
StartSubREQCopyDst bool ` comment:"Start subscriber for writing copied files to disk" `
// Start subscriber for Echo Request
StartSubREQPing bool ` comment:"Start subscriber for Echo Request" `
// Start subscriber for Echo Reply
StartSubREQPong bool ` comment:"Start subscriber for Echo Reply" `
// Start subscriber for CLICommandRequest
StartSubREQCliCommand bool ` comment:"Start subscriber for CLICommandRequest" `
// Start subscriber for REQToConsole
StartSubREQToConsole bool ` comment:"Start subscriber for REQToConsole" `
// Start subscriber for REQHttpGet
StartSubREQHttpGet bool ` comment:"Start subscriber for REQHttpGet" `
// Start subscriber for REQHttpGetScheduled
StartSubREQHttpGetScheduled bool ` comment:"Start subscriber for REQHttpGetScheduled" `
// Start subscriber for tailing log files
StartSubREQTailFile bool ` comment:"Start subscriber for tailing log files" `
// Start subscriber for continously delivery of output from cli commands.
StartSubREQCliCommandCont bool ` comment:"Start subscriber for continously delivery of output from cli commands." `
2021-03-01 19:49:43 +00:00
}
2021-09-09 06:19:53 +00:00
// ConfigurationFromFile should have the same structure as
// Configuration. This structure is used when parsing the
// configuration values from file, so we are able to detect
// if a value were given or not when parsing.
type ConfigurationFromFile struct {
2022-05-26 06:07:23 +00:00
ConfigFolder * string
2022-06-21 14:44:39 +00:00
RingBufferPersistStore * bool
2022-05-26 06:07:23 +00:00
RingBufferSize * int
SocketFolder * string
2023-01-08 07:32:58 +00:00
ReadFolder * string
EnableReadFolder * bool
2022-05-26 06:07:23 +00:00
TCPListener * string
HTTPListener * string
DatabaseFolder * string
NodeName * string
BrokerAddress * string
NatsConnOptTimeout * int
NatsConnectRetryInterval * int
NatsReconnectJitter * int
NatsReconnectJitterTLS * int
REQKeysRequestUpdateInterval * int
REQAclRequestUpdateInterval * int
ProfilingPort * string
PromHostAndPort * string
DefaultMessageTimeout * int
DefaultMessageRetries * int
DefaultMethodTimeout * int
SubscribersDataFolder * string
CentralNodeName * string
RootCAPath * string
NkeySeedFile * string
ExposeDataFolder * string
ErrorMessageTimeout * int
ErrorMessageRetries * int
Compression * string
Serialization * string
SetBlockProfileRate * int
EnableSocket * bool
EnableTUI * bool
EnableSignatureCheck * bool
2022-05-27 04:22:51 +00:00
EnableAclCheck * bool
2022-05-26 06:07:23 +00:00
IsCentralAuth * bool
EnableDebug * bool
2023-01-11 05:09:42 +00:00
LogLevel * string
LogConsoleTimestamps * bool
2022-06-17 22:03:25 +00:00
KeepPublishersAliveFor * int
2021-12-27 10:40:29 +00:00
2022-05-30 05:14:15 +00:00
StartPubREQHello * int
EnableKeyUpdates * bool
EnableAclUpdates * bool
2022-06-03 04:02:27 +00:00
IsCentralErrorLogger * bool
2022-05-30 05:14:15 +00:00
StartSubREQHello * bool
StartSubREQToFileAppend * bool
StartSubREQToFile * bool
StartSubREQToFileNACK * bool
2022-06-09 03:59:37 +00:00
StartSubREQCopySrc * bool
StartSubREQCopyDst * bool
2022-05-30 05:14:15 +00:00
StartSubREQPing * bool
StartSubREQPong * bool
StartSubREQCliCommand * bool
StartSubREQToConsole * bool
StartSubREQHttpGet * bool
StartSubREQHttpGetScheduled * bool
StartSubREQTailFile * bool
StartSubREQCliCommandCont * bool
2021-09-09 06:19:53 +00:00
}
// NewConfiguration will return a *Configuration.
2021-03-01 19:49:43 +00:00
func NewConfiguration ( ) * Configuration {
c := Configuration { }
return & c
}
2021-09-09 06:19:53 +00:00
// Get a Configuration struct with the default values set.
2021-03-02 05:51:08 +00:00
func newConfigurationDefaults ( ) Configuration {
c := Configuration {
2022-05-26 06:07:23 +00:00
ConfigFolder : "./etc/" ,
2022-06-21 14:44:39 +00:00
RingBufferPersistStore : true ,
2022-05-26 06:07:23 +00:00
RingBufferSize : 1000 ,
SocketFolder : "./tmp" ,
2023-01-08 07:32:58 +00:00
ReadFolder : "./readfolder" ,
EnableReadFolder : true ,
2022-05-26 06:07:23 +00:00
TCPListener : "" ,
HTTPListener : "" ,
DatabaseFolder : "./var/lib" ,
NodeName : "" ,
BrokerAddress : "127.0.0.1:4222" ,
NatsConnOptTimeout : 20 ,
NatsConnectRetryInterval : 10 ,
NatsReconnectJitter : 100 ,
NatsReconnectJitterTLS : 1 ,
REQKeysRequestUpdateInterval : 60 ,
REQAclRequestUpdateInterval : 60 ,
ProfilingPort : "" ,
PromHostAndPort : "" ,
DefaultMessageTimeout : 10 ,
DefaultMessageRetries : 1 ,
DefaultMethodTimeout : 10 ,
SubscribersDataFolder : "./data" ,
CentralNodeName : "" ,
RootCAPath : "" ,
NkeySeedFile : "" ,
ExposeDataFolder : "" ,
ErrorMessageTimeout : 60 ,
ErrorMessageRetries : 10 ,
Compression : "" ,
Serialization : "" ,
SetBlockProfileRate : 0 ,
EnableSocket : true ,
EnableTUI : false ,
EnableSignatureCheck : false ,
2022-05-27 04:22:51 +00:00
EnableAclCheck : false ,
2022-05-26 06:07:23 +00:00
IsCentralAuth : false ,
EnableDebug : false ,
2023-01-12 12:37:22 +00:00
LogLevel : "debug" ,
2023-01-11 05:09:42 +00:00
LogConsoleTimestamps : false ,
2022-06-17 22:03:25 +00:00
KeepPublishersAliveFor : 10 ,
2021-09-07 07:43:54 +00:00
2022-05-30 05:14:15 +00:00
StartPubREQHello : 30 ,
EnableKeyUpdates : true ,
EnableAclUpdates : true ,
2022-06-03 04:02:27 +00:00
IsCentralErrorLogger : false ,
2022-05-30 05:14:15 +00:00
StartSubREQHello : true ,
StartSubREQToFileAppend : true ,
StartSubREQToFile : true ,
StartSubREQToFileNACK : true ,
2022-06-09 03:59:37 +00:00
StartSubREQCopySrc : true ,
StartSubREQCopyDst : true ,
2022-05-30 05:14:15 +00:00
StartSubREQPing : true ,
StartSubREQPong : true ,
StartSubREQCliCommand : true ,
StartSubREQToConsole : true ,
StartSubREQHttpGet : true ,
StartSubREQHttpGetScheduled : true ,
StartSubREQTailFile : true ,
StartSubREQCliCommandCont : true ,
2021-03-02 05:51:08 +00:00
}
return c
}
2021-09-09 06:19:53 +00:00
// Check if all values are present in config file, and if not
// found use the default value.
func checkConfigValues ( cf ConfigurationFromFile ) Configuration {
var conf Configuration
cd := newConfigurationDefaults ( )
2021-12-21 06:21:12 +00:00
if cf . RingBufferSize == nil {
conf . RingBufferSize = cd . RingBufferSize
} else {
conf . RingBufferSize = * cf . RingBufferSize
}
2022-06-21 14:44:39 +00:00
if cf . RingBufferPersistStore == nil {
conf . RingBufferPersistStore = cd . RingBufferPersistStore
} else {
conf . RingBufferPersistStore = * cf . RingBufferPersistStore
}
2021-09-09 06:19:53 +00:00
if cf . ConfigFolder == nil {
conf . ConfigFolder = cd . ConfigFolder
} else {
conf . ConfigFolder = * cf . ConfigFolder
}
if cf . SocketFolder == nil {
conf . SocketFolder = cd . SocketFolder
} else {
conf . SocketFolder = * cf . SocketFolder
}
2023-01-08 07:32:58 +00:00
if cf . ReadFolder == nil {
conf . ReadFolder = cd . ReadFolder
} else {
conf . ReadFolder = * cf . ReadFolder
}
if cf . EnableReadFolder == nil {
conf . EnableReadFolder = cd . EnableReadFolder
} else {
conf . EnableReadFolder = * cf . EnableReadFolder
}
2021-09-09 06:19:53 +00:00
if cf . TCPListener == nil {
conf . TCPListener = cd . TCPListener
} else {
conf . TCPListener = * cf . TCPListener
}
2021-09-10 03:26:16 +00:00
if cf . HTTPListener == nil {
conf . HTTPListener = cd . HTTPListener
} else {
conf . HTTPListener = * cf . HTTPListener
}
2021-09-09 06:19:53 +00:00
if cf . DatabaseFolder == nil {
conf . DatabaseFolder = cd . DatabaseFolder
} else {
conf . DatabaseFolder = * cf . DatabaseFolder
}
if cf . NodeName == nil {
conf . NodeName = cd . NodeName
} else {
conf . NodeName = * cf . NodeName
}
if cf . BrokerAddress == nil {
conf . BrokerAddress = cd . BrokerAddress
} else {
conf . BrokerAddress = * cf . BrokerAddress
}
2021-12-17 16:28:57 +00:00
if cf . NatsConnOptTimeout == nil {
conf . NatsConnOptTimeout = cd . NatsConnOptTimeout
} else {
conf . NatsConnOptTimeout = * cf . NatsConnOptTimeout
}
2021-09-09 06:19:53 +00:00
if cf . NatsConnectRetryInterval == nil {
conf . NatsConnectRetryInterval = cd . NatsConnectRetryInterval
} else {
conf . NatsConnectRetryInterval = * cf . NatsConnectRetryInterval
}
2021-12-16 10:01:01 +00:00
if cf . NatsReconnectJitter == nil {
conf . NatsReconnectJitter = cd . NatsReconnectJitter
} else {
conf . NatsReconnectJitter = * cf . NatsReconnectJitter
}
if cf . NatsReconnectJitterTLS == nil {
conf . NatsReconnectJitterTLS = cd . NatsReconnectJitterTLS
} else {
conf . NatsReconnectJitterTLS = * cf . NatsReconnectJitterTLS
}
2022-05-26 06:07:23 +00:00
if cf . REQKeysRequestUpdateInterval == nil {
conf . REQKeysRequestUpdateInterval = cd . REQKeysRequestUpdateInterval
} else {
conf . REQKeysRequestUpdateInterval = * cf . REQKeysRequestUpdateInterval
}
if cf . REQAclRequestUpdateInterval == nil {
conf . REQAclRequestUpdateInterval = cd . REQAclRequestUpdateInterval
2022-04-07 07:34:06 +00:00
} else {
2022-05-26 06:07:23 +00:00
conf . REQAclRequestUpdateInterval = * cf . REQAclRequestUpdateInterval
2022-04-07 07:34:06 +00:00
}
2021-09-09 06:19:53 +00:00
if cf . ProfilingPort == nil {
conf . ProfilingPort = cd . ProfilingPort
} else {
conf . ProfilingPort = * cf . ProfilingPort
}
if cf . PromHostAndPort == nil {
conf . PromHostAndPort = cd . PromHostAndPort
} else {
conf . PromHostAndPort = * cf . PromHostAndPort
}
if cf . DefaultMessageTimeout == nil {
conf . DefaultMessageTimeout = cd . DefaultMessageTimeout
} else {
conf . DefaultMessageTimeout = * cf . DefaultMessageTimeout
}
if cf . DefaultMessageRetries == nil {
conf . DefaultMessageRetries = cd . DefaultMessageRetries
} else {
conf . DefaultMessageRetries = * cf . DefaultMessageRetries
}
2021-11-18 05:36:16 +00:00
if cf . DefaultMethodTimeout == nil {
conf . DefaultMethodTimeout = cd . DefaultMethodTimeout
} else {
conf . DefaultMethodTimeout = * cf . DefaultMethodTimeout
}
2021-09-09 06:19:53 +00:00
if cf . SubscribersDataFolder == nil {
conf . SubscribersDataFolder = cd . SubscribersDataFolder
} else {
conf . SubscribersDataFolder = * cf . SubscribersDataFolder
}
if cf . CentralNodeName == nil {
conf . CentralNodeName = cd . CentralNodeName
} else {
conf . CentralNodeName = * cf . CentralNodeName
}
if cf . RootCAPath == nil {
conf . RootCAPath = cd . RootCAPath
} else {
conf . RootCAPath = * cf . RootCAPath
}
if cf . NkeySeedFile == nil {
conf . NkeySeedFile = cd . NkeySeedFile
} else {
conf . NkeySeedFile = * cf . NkeySeedFile
}
if cf . ExposeDataFolder == nil {
conf . ExposeDataFolder = cd . ExposeDataFolder
} else {
conf . ExposeDataFolder = * cf . ExposeDataFolder
}
if cf . ErrorMessageTimeout == nil {
conf . ErrorMessageTimeout = cd . ErrorMessageTimeout
} else {
conf . ErrorMessageTimeout = * cf . ErrorMessageTimeout
}
if cf . ErrorMessageRetries == nil {
conf . ErrorMessageRetries = cd . ErrorMessageRetries
} else {
conf . ErrorMessageRetries = * cf . ErrorMessageRetries
}
2021-12-26 06:16:14 +00:00
if cf . Compression == nil {
conf . Compression = cd . Compression
} else {
conf . Compression = * cf . Compression
}
2021-12-29 05:17:40 +00:00
if cf . Serialization == nil {
conf . Serialization = cd . Serialization
} else {
conf . Serialization = * cf . Serialization
}
2021-12-31 05:59:09 +00:00
if cf . SetBlockProfileRate == nil {
conf . SetBlockProfileRate = cd . SetBlockProfileRate
} else {
conf . SetBlockProfileRate = * cf . SetBlockProfileRate
}
2022-01-07 06:21:21 +00:00
if cf . EnableSocket == nil {
conf . EnableSocket = cd . EnableSocket
} else {
conf . EnableSocket = * cf . EnableSocket
}
2022-01-07 10:17:10 +00:00
if cf . EnableTUI == nil {
conf . EnableTUI = cd . EnableTUI
} else {
conf . EnableTUI = * cf . EnableTUI
}
2022-02-09 13:59:40 +00:00
if cf . EnableSignatureCheck == nil {
conf . EnableSignatureCheck = cd . EnableSignatureCheck
2022-02-03 10:11:21 +00:00
} else {
2022-02-09 13:59:40 +00:00
conf . EnableSignatureCheck = * cf . EnableSignatureCheck
2022-02-03 10:11:21 +00:00
}
2022-05-27 04:22:51 +00:00
if cf . EnableAclCheck == nil {
conf . EnableAclCheck = cd . EnableAclCheck
} else {
conf . EnableAclCheck = * cf . EnableAclCheck
}
2022-02-09 08:06:06 +00:00
if cf . IsCentralAuth == nil {
conf . IsCentralAuth = cd . IsCentralAuth
} else {
conf . IsCentralAuth = * cf . IsCentralAuth
}
2022-02-18 05:24:27 +00:00
if cf . EnableDebug == nil {
conf . EnableDebug = cd . EnableDebug
} else {
conf . EnableDebug = * cf . EnableDebug
}
2023-01-11 05:09:42 +00:00
if cf . LogLevel == nil {
conf . LogLevel = cd . LogLevel
} else {
conf . LogLevel = * cf . LogLevel
}
if cf . LogConsoleTimestamps == nil {
conf . LogConsoleTimestamps = cd . LogConsoleTimestamps
} else {
conf . LogConsoleTimestamps = * cf . LogConsoleTimestamps
}
2022-06-17 22:03:25 +00:00
if cf . KeepPublishersAliveFor == nil {
conf . KeepPublishersAliveFor = cd . KeepPublishersAliveFor
} else {
conf . KeepPublishersAliveFor = * cf . KeepPublishersAliveFor
}
2022-01-07 10:17:10 +00:00
// --- Start pub/sub
2021-12-26 06:16:14 +00:00
2021-09-09 06:19:53 +00:00
if cf . StartPubREQHello == nil {
conf . StartPubREQHello = cd . StartPubREQHello
} else {
conf . StartPubREQHello = * cf . StartPubREQHello
}
2022-05-30 05:14:15 +00:00
if cf . EnableKeyUpdates == nil {
conf . EnableKeyUpdates = cd . EnableKeyUpdates
2022-04-07 07:34:06 +00:00
} else {
2022-05-30 05:14:15 +00:00
conf . EnableKeyUpdates = * cf . EnableKeyUpdates
2022-04-07 07:34:06 +00:00
}
2022-05-26 06:07:23 +00:00
2022-05-30 05:14:15 +00:00
if cf . EnableAclUpdates == nil {
conf . EnableAclUpdates = cd . EnableAclUpdates
2022-05-26 06:07:23 +00:00
} else {
2022-05-30 05:14:15 +00:00
conf . EnableAclUpdates = * cf . EnableAclUpdates
2022-05-26 06:07:23 +00:00
}
2022-06-03 04:02:27 +00:00
if cf . IsCentralErrorLogger == nil {
conf . IsCentralErrorLogger = cd . IsCentralErrorLogger
2021-09-09 06:19:53 +00:00
} else {
2022-06-03 04:02:27 +00:00
conf . IsCentralErrorLogger = * cf . IsCentralErrorLogger
2021-09-09 06:19:53 +00:00
}
if cf . StartSubREQHello == nil {
conf . StartSubREQHello = cd . StartSubREQHello
} else {
conf . StartSubREQHello = * cf . StartSubREQHello
}
if cf . StartSubREQToFileAppend == nil {
conf . StartSubREQToFileAppend = cd . StartSubREQToFileAppend
} else {
conf . StartSubREQToFileAppend = * cf . StartSubREQToFileAppend
}
if cf . StartSubREQToFile == nil {
conf . StartSubREQToFile = cd . StartSubREQToFile
} else {
conf . StartSubREQToFile = * cf . StartSubREQToFile
}
2022-03-04 14:02:43 +00:00
if cf . StartSubREQToFileNACK == nil {
conf . StartSubREQToFileNACK = cd . StartSubREQToFileNACK
} else {
conf . StartSubREQToFileNACK = * cf . StartSubREQToFileNACK
}
2022-06-09 03:59:37 +00:00
if cf . StartSubREQCopySrc == nil {
conf . StartSubREQCopySrc = cd . StartSubREQCopySrc
} else {
conf . StartSubREQCopySrc = * cf . StartSubREQCopySrc
}
if cf . StartSubREQCopyDst == nil {
conf . StartSubREQCopyDst = cd . StartSubREQCopyDst
} else {
conf . StartSubREQCopyDst = * cf . StartSubREQCopyDst
}
2021-09-09 06:19:53 +00:00
if cf . StartSubREQPing == nil {
conf . StartSubREQPing = cd . StartSubREQPing
} else {
conf . StartSubREQPing = * cf . StartSubREQPing
}
if cf . StartSubREQPong == nil {
conf . StartSubREQPong = cd . StartSubREQPong
} else {
conf . StartSubREQPong = * cf . StartSubREQPong
}
if cf . StartSubREQCliCommand == nil {
conf . StartSubREQCliCommand = cd . StartSubREQCliCommand
} else {
conf . StartSubREQCliCommand = * cf . StartSubREQCliCommand
}
if cf . StartSubREQToConsole == nil {
conf . StartSubREQToConsole = cd . StartSubREQToConsole
} else {
conf . StartSubREQToConsole = * cf . StartSubREQToConsole
}
if cf . StartSubREQHttpGet == nil {
conf . StartSubREQHttpGet = cd . StartSubREQHttpGet
} else {
conf . StartSubREQHttpGet = * cf . StartSubREQHttpGet
}
2022-02-11 06:27:51 +00:00
if cf . StartSubREQHttpGetScheduled == nil {
conf . StartSubREQHttpGetScheduled = cd . StartSubREQHttpGetScheduled
} else {
conf . StartSubREQHttpGetScheduled = * cf . StartSubREQHttpGetScheduled
}
2021-09-09 06:19:53 +00:00
if cf . StartSubREQTailFile == nil {
conf . StartSubREQTailFile = cd . StartSubREQTailFile
} else {
conf . StartSubREQTailFile = * cf . StartSubREQTailFile
}
2021-09-17 08:17:10 +00:00
if cf . StartSubREQCliCommandCont == nil {
conf . StartSubREQCliCommandCont = cd . StartSubREQCliCommandCont
2021-09-09 06:19:53 +00:00
} else {
2021-09-17 08:17:10 +00:00
conf . StartSubREQCliCommandCont = * cf . StartSubREQCliCommandCont
2021-09-09 06:19:53 +00:00
}
return conf
}
2021-04-06 09:02:58 +00:00
// CheckFlags will parse all flags
2023-04-12 07:56:08 +00:00
func ( c * Configuration ) CheckFlags ( version string ) error {
2021-03-02 05:51:08 +00:00
// Create an empty default config
var fc Configuration
2021-08-23 09:45:31 +00:00
// Set default configfolder if no env was provided.
2021-08-27 08:49:06 +00:00
configFolder := os . Getenv ( "CONFIG_FOLDER" )
2021-08-23 09:45:31 +00:00
2021-08-27 10:19:35 +00:00
if configFolder == "" {
configFolder = "./etc/"
}
2021-08-23 09:45:31 +00:00
// Read file config. Set system default if it can't find config file.
2021-05-28 12:48:53 +00:00
fc , err := c . ReadConfigFile ( configFolder )
2021-03-25 10:28:26 +00:00
if err != nil {
log . Printf ( "%v\n" , err )
fc = newConfigurationDefaults ( )
}
2021-08-27 08:49:06 +00:00
if configFolder == "" {
fc . ConfigFolder = "./etc/"
} else {
fc . ConfigFolder = configFolder
}
2021-03-25 10:28:26 +00:00
* c = fc
2021-03-01 19:49:43 +00:00
2021-08-23 09:45:31 +00:00
//flag.StringVar(&c.ConfigFolder, "configFolder", fc.ConfigFolder, "Defaults to ./usr/local/steward/etc/. *NB* This flag is not used, if your config file are located somwhere else than default set the location in an env variable named CONFIGFOLDER")
2022-06-21 14:44:39 +00:00
flag . BoolVar ( & c . RingBufferPersistStore , "ringBufferPersistStore" , fc . RingBufferPersistStore , "true/false for enabling the persisting of ringbuffer to disk" )
2021-12-21 06:21:12 +00:00
flag . IntVar ( & c . RingBufferSize , "ringBufferSize" , fc . RingBufferSize , "size of the ringbuffer" )
2021-05-12 07:50:03 +00:00
flag . StringVar ( & c . SocketFolder , "socketFolder" , fc . SocketFolder , "folder who contains the socket file. Defaults to ./tmp/. If other folder is used this flag must be specified at startup." )
2023-01-10 07:30:06 +00:00
flag . StringVar ( & c . ReadFolder , "readFolder" , fc . ReadFolder , "folder who contains the readfolder. Defaults to ./readfolder/. If other folder is used this flag must be specified at startup." )
2021-08-23 14:00:48 +00:00
flag . StringVar ( & c . TCPListener , "tcpListener" , fc . TCPListener , "start up a TCP listener in addition to the Unix Socket, to give messages to the system. e.g. localhost:8888. No value means not to start the listener, which is default. NB: You probably don't want to start this on any other interface than localhost" )
2021-09-10 03:26:16 +00:00
flag . StringVar ( & c . HTTPListener , "httpListener" , fc . HTTPListener , "start up a HTTP listener in addition to the Unix Socket, to give messages to the system. e.g. localhost:8888. No value means not to start the listener, which is default. NB: You probably don't want to start this on any other interface than localhost" )
2021-05-12 07:50:03 +00:00
flag . StringVar ( & c . DatabaseFolder , "databaseFolder" , fc . DatabaseFolder , "folder who contains the database file. Defaults to ./var/lib/. If other folder is used this flag must be specified at startup." )
2021-03-24 09:14:17 +00:00
flag . StringVar ( & c . NodeName , "nodeName" , fc . NodeName , "some unique string to identify this Edge unit" )
2021-03-01 19:49:43 +00:00
flag . StringVar ( & c . BrokerAddress , "brokerAddress" , fc . BrokerAddress , "the address of the message broker" )
2021-12-28 11:05:09 +00:00
flag . IntVar ( & c . NatsConnOptTimeout , "natsConnOptTimeout" , fc . NatsConnOptTimeout , "default nats client conn timeout in seconds" )
2021-09-01 11:39:54 +00:00
flag . IntVar ( & c . NatsConnectRetryInterval , "natsConnectRetryInterval" , fc . NatsConnectRetryInterval , "default nats retry connect interval in seconds." )
2021-12-16 10:01:01 +00:00
flag . IntVar ( & c . NatsReconnectJitter , "natsReconnectJitter" , fc . NatsReconnectJitter , "default nats ReconnectJitter interval in milliseconds." )
flag . IntVar ( & c . NatsReconnectJitterTLS , "natsReconnectJitterTLS" , fc . NatsReconnectJitterTLS , "default nats ReconnectJitterTLS interval in seconds." )
2022-05-26 06:07:23 +00:00
flag . IntVar ( & c . REQKeysRequestUpdateInterval , "REQKeysRequestUpdateInterval" , fc . REQKeysRequestUpdateInterval , "default interval in seconds for asking the central for public keys" )
flag . IntVar ( & c . REQAclRequestUpdateInterval , "REQAclRequestUpdateInterval" , fc . REQAclRequestUpdateInterval , "default interval in seconds for asking the central for acl updates" )
2021-03-01 19:49:43 +00:00
flag . StringVar ( & c . ProfilingPort , "profilingPort" , fc . ProfilingPort , "The number of the profiling port" )
flag . StringVar ( & c . PromHostAndPort , "promHostAndPort" , fc . PromHostAndPort , "host and port for prometheus listener, e.g. localhost:2112" )
flag . IntVar ( & c . DefaultMessageTimeout , "defaultMessageTimeout" , fc . DefaultMessageTimeout , "default message timeout in seconds. This can be overridden on the message level" )
flag . IntVar ( & c . DefaultMessageRetries , "defaultMessageRetries" , fc . DefaultMessageRetries , "default amount of retries that will be done before a message is thrown away, and out of the system" )
2021-11-18 05:36:16 +00:00
flag . IntVar ( & c . DefaultMethodTimeout , "defaultMethodTimeout" , fc . DefaultMethodTimeout , "default amount of seconds a request method max will be allowed to run" )
2021-03-02 12:46:02 +00:00
flag . StringVar ( & c . SubscribersDataFolder , "subscribersDataFolder" , fc . SubscribersDataFolder , "The data folder where subscribers are allowed to write their data if needed" )
2021-03-12 10:13:42 +00:00
flag . StringVar ( & c . CentralNodeName , "centralNodeName" , fc . CentralNodeName , "The name of the central node to receive messages published by this node" )
2021-04-19 19:06:37 +00:00
flag . StringVar ( & c . RootCAPath , "rootCAPath" , fc . RootCAPath , "If TLS, enter the path for where to find the root CA certificate" )
2021-05-14 13:23:04 +00:00
flag . StringVar ( & c . NkeySeedFile , "nkeySeedFile" , fc . NkeySeedFile , "The full path of the nkeys seed file" )
2021-08-23 10:47:33 +00:00
flag . StringVar ( & c . ExposeDataFolder , "exposeDataFolder" , fc . ExposeDataFolder , "If set the data folder will be exposed on the given host:port. Default value is not exposed at all" )
2021-09-07 07:43:54 +00:00
flag . IntVar ( & c . ErrorMessageTimeout , "errorMessageTimeout" , fc . ErrorMessageTimeout , "The number of seconds to wait for an error message to time out" )
flag . IntVar ( & c . ErrorMessageRetries , "errorMessageRetries" , fc . ErrorMessageRetries , "The number of if times to retry an error message before we drop it" )
2022-01-03 11:30:28 +00:00
flag . StringVar ( & c . Compression , "compression" , fc . Compression , "compression method to use. defaults to no compression, z = zstd, g = gzip. Undefined value will default to no compression" )
2021-12-29 05:17:40 +00:00
flag . StringVar ( & c . Serialization , "serialization" , fc . Serialization , "Serialization method to use. defaults to gob, other values are = cbor. Undefined value will default to gob" )
2021-12-31 05:59:09 +00:00
flag . IntVar ( & c . SetBlockProfileRate , "setBlockProfileRate" , fc . SetBlockProfileRate , "Enable block profiling by setting the value to f.ex. 1. 0 = disabled" )
2022-02-09 13:59:40 +00:00
flag . BoolVar ( & c . EnableSocket , "enableSocket" , fc . EnableSocket , "true/false, for enabling the creation of a steward.sock file" )
2022-01-07 10:17:10 +00:00
flag . BoolVar ( & c . EnableTUI , "enableTUI" , fc . EnableTUI , "true/false for enabling the Terminal User Interface" )
2022-02-09 13:59:40 +00:00
flag . BoolVar ( & c . EnableSignatureCheck , "enableSignatureCheck" , fc . EnableSignatureCheck , "true/false *TESTING* enable signature checking." )
2022-05-27 04:22:51 +00:00
flag . BoolVar ( & c . EnableAclCheck , "enableAclCheck" , fc . EnableAclCheck , "true/false *TESTING* enable Acl checking." )
2022-02-09 13:59:40 +00:00
flag . BoolVar ( & c . IsCentralAuth , "isCentralAuth" , fc . IsCentralAuth , "true/false, *TESTING* is this the central auth server" )
2022-02-18 05:24:27 +00:00
flag . BoolVar ( & c . EnableDebug , "enableDebug" , fc . EnableDebug , "true/false, will enable debug logging so all messages sent to the errorKernel will also be printed to STDERR" )
2023-01-12 11:06:29 +00:00
flag . StringVar ( & c . LogLevel , "logLevel" , fc . LogLevel , "error/info/warning/debug/none" )
2023-01-11 05:09:42 +00:00
flag . BoolVar ( & c . LogConsoleTimestamps , "LogConsoleTimestamps" , fc . LogConsoleTimestamps , "true/false for enabling or disabling timestamps when printing errors and information to stderr" )
2022-06-17 22:03:25 +00:00
flag . IntVar ( & c . KeepPublishersAliveFor , "keepPublishersAliveFor" , fc . KeepPublishersAliveFor , "The amount of time we allow a publisher to stay alive without receiving any messages to publish" )
2021-03-02 12:46:02 +00:00
2022-05-26 06:07:23 +00:00
// Start of Request publishers/subscribers
2021-04-06 03:46:07 +00:00
flag . IntVar ( & c . StartPubREQHello , "startPubREQHello" , fc . StartPubREQHello , "Make the current node send hello messages to central at given interval in seconds" )
2021-03-25 12:39:59 +00:00
2022-05-30 05:14:15 +00:00
flag . BoolVar ( & c . EnableKeyUpdates , "EnableKeyUpdates" , fc . EnableKeyUpdates , "true/false" )
2022-05-26 06:07:23 +00:00
2022-05-30 05:14:15 +00:00
flag . BoolVar ( & c . EnableAclUpdates , "EnableAclUpdates" , fc . EnableAclUpdates , "true/false" )
2022-05-26 06:07:23 +00:00
2022-06-03 04:02:27 +00:00
flag . BoolVar ( & c . IsCentralErrorLogger , "isCentralErrorLogger" , fc . IsCentralErrorLogger , "true/false" )
2021-09-08 16:56:23 +00:00
flag . BoolVar ( & c . StartSubREQHello , "startSubREQHello" , fc . StartSubREQHello , "true/false" )
flag . BoolVar ( & c . StartSubREQToFileAppend , "startSubREQToFileAppend" , fc . StartSubREQToFileAppend , "true/false" )
flag . BoolVar ( & c . StartSubREQToFile , "startSubREQToFile" , fc . StartSubREQToFile , "true/false" )
2022-03-04 14:02:43 +00:00
flag . BoolVar ( & c . StartSubREQToFileNACK , "startSubREQToFileNACK" , fc . StartSubREQToFileNACK , "true/false" )
2022-06-09 03:59:37 +00:00
flag . BoolVar ( & c . StartSubREQCopySrc , "startSubREQCopySrc" , fc . StartSubREQCopySrc , "true/false" )
flag . BoolVar ( & c . StartSubREQCopyDst , "startSubREQCopyDst" , fc . StartSubREQCopyDst , "true/false" )
2021-09-08 16:56:23 +00:00
flag . BoolVar ( & c . StartSubREQPing , "startSubREQPing" , fc . StartSubREQPing , "true/false" )
flag . BoolVar ( & c . StartSubREQPong , "startSubREQPong" , fc . StartSubREQPong , "true/false" )
flag . BoolVar ( & c . StartSubREQCliCommand , "startSubREQCliCommand" , fc . StartSubREQCliCommand , "true/false" )
flag . BoolVar ( & c . StartSubREQToConsole , "startSubREQToConsole" , fc . StartSubREQToConsole , "true/false" )
flag . BoolVar ( & c . StartSubREQHttpGet , "startSubREQHttpGet" , fc . StartSubREQHttpGet , "true/false" )
2022-02-11 06:27:51 +00:00
flag . BoolVar ( & c . StartSubREQHttpGetScheduled , "startSubREQHttpGetScheduled" , fc . StartSubREQHttpGetScheduled , "true/false" )
2021-09-08 16:56:23 +00:00
flag . BoolVar ( & c . StartSubREQTailFile , "startSubREQTailFile" , fc . StartSubREQTailFile , "true/false" )
2021-09-17 08:17:10 +00:00
flag . BoolVar ( & c . StartSubREQCliCommandCont , "startSubREQCliCommandCont" , fc . StartSubREQCliCommandCont , "true/false" )
2021-03-24 09:14:17 +00:00
2022-02-10 05:19:13 +00:00
purgeBufferDB := flag . Bool ( "purgeBufferDB" , false , "true/false, purge the incoming buffer db and all it's state" )
2023-04-12 07:56:08 +00:00
ver := flag . Bool ( "version" , false , "print version and exit" )
2021-03-01 19:49:43 +00:00
flag . Parse ( )
2023-04-12 07:56:08 +00:00
if * ver {
fmt . Printf ( "version %v\n" , version )
os . Exit ( 0 )
}
2021-03-24 09:14:17 +00:00
// Check that mandatory flag values have been set.
switch {
case c . NodeName == "" :
return fmt . Errorf ( "error: the nodeName config option or flag cannot be empty, check -help" )
case c . CentralNodeName == "" :
return fmt . Errorf ( "error: the centralNodeName config option or flag cannot be empty, check -help" )
2021-03-01 19:49:43 +00:00
}
2021-03-24 09:14:17 +00:00
2021-03-25 10:28:26 +00:00
if err := c . WriteConfigFile ( ) ; err != nil {
log . Printf ( "error: checkFlags: failed writing config file: %v\n" , err )
os . Exit ( 1 )
}
2021-03-24 09:14:17 +00:00
2022-02-10 05:19:13 +00:00
if * purgeBufferDB {
fp := filepath . Join ( c . DatabaseFolder , "incomingBuffer.db" )
err := os . Remove ( fp )
if err != nil {
log . Printf ( "error: failed to purge buffer state database: %v\n" , err )
}
}
2021-03-24 09:14:17 +00:00
return nil
2021-03-01 19:49:43 +00:00
}
2021-03-24 06:05:41 +00:00
// Reads the current config file from disk.
2021-05-28 12:48:53 +00:00
func ( c * Configuration ) ReadConfigFile ( configFolder string ) ( Configuration , error ) {
2021-09-09 06:19:53 +00:00
fPath := filepath . Join ( configFolder , "config.toml" )
2021-03-01 19:49:43 +00:00
2021-09-09 06:19:53 +00:00
if _ , err := os . Stat ( fPath ) ; os . IsNotExist ( err ) {
return Configuration { } , fmt . Errorf ( "error: no config file found %v: %v" , fPath , err )
2021-03-01 19:49:43 +00:00
}
2023-01-10 05:50:28 +00:00
f , err := os . OpenFile ( fPath , os . O_RDONLY , 0660 )
2021-03-01 19:49:43 +00:00
if err != nil {
2021-03-02 12:46:02 +00:00
return Configuration { } , fmt . Errorf ( "error: ReadConfigFile: failed to open file: %v" , err )
2021-03-01 19:49:43 +00:00
}
defer f . Close ( )
2021-09-09 06:19:53 +00:00
var cFile ConfigurationFromFile
2021-03-01 19:49:43 +00:00
dec := toml . NewDecoder ( f )
2021-09-09 06:19:53 +00:00
err = dec . Decode ( & cFile )
2021-03-01 19:49:43 +00:00
if err != nil {
2021-09-09 06:19:53 +00:00
log . Printf ( "error: decoding config.toml file. The program will automatically try to correct the problem, and use sane default where it kind find a value to use, but beware of this error in case the program start to behave in not expected ways: path=%v: err=%v" , fPath , err )
2021-03-01 19:49:43 +00:00
}
2021-09-09 06:19:53 +00:00
// Check that all values read are ok.
conf := checkConfigValues ( cFile )
2021-03-01 19:49:43 +00:00
return conf , nil
}
2021-03-02 05:51:08 +00:00
// WriteConfigFile will write the current config to file. If the file or the
// directory for the config file does not exist it will be created.
2021-03-01 19:49:43 +00:00
func ( c * Configuration ) WriteConfigFile ( ) error {
if _ , err := os . Stat ( c . ConfigFolder ) ; os . IsNotExist ( err ) {
2023-01-10 05:50:28 +00:00
err := os . MkdirAll ( c . ConfigFolder , 0770 )
2021-03-01 19:49:43 +00:00
if err != nil {
2021-05-20 10:27:25 +00:00
return fmt . Errorf ( "error: failed to create config directory %v: %v" , c . ConfigFolder , err )
2021-03-01 19:49:43 +00:00
}
}
fp := filepath . Join ( c . ConfigFolder , "config.toml" )
2023-01-10 05:50:28 +00:00
f , err := os . OpenFile ( fp , os . O_RDWR | os . O_CREATE | os . O_TRUNC , 0660 )
2021-03-01 19:49:43 +00:00
if err != nil {
2021-03-02 12:46:02 +00:00
return fmt . Errorf ( "error: WriteConfigFile: failed to open file: %v" , err )
2021-03-01 19:49:43 +00:00
}
defer f . Close ( )
enc := toml . NewEncoder ( f )
enc . Encode ( c )
return nil
}