diff options
| author | Paul Buetow <pbuetow@mimecast.com> | 2022-02-04 21:37:29 +0000 |
|---|---|---|
| committer | Paul Buetow <pbuetow@mimecast.com> | 2022-02-04 21:37:29 +0000 |
| commit | 20bd2a6330b2a5da3dc42c92e4c4e634c78561ff (patch) | |
| tree | cab22128af9e54131facd0062a474459383a1c90 /internal/config | |
| parent | 8c714057a07ab494689c9e262d95519e34c204e1 (diff) | |
| parent | 1e205898c1270915b192db51acfdfc6e1a92e3e3 (diff) | |
merge 4.0.0-RC
Diffstat (limited to 'internal/config')
| -rw-r--r-- | internal/config/args.go | 172 | ||||
| -rw-r--r-- | internal/config/client.go | 191 | ||||
| -rw-r--r-- | internal/config/common.go | 26 | ||||
| -rw-r--r-- | internal/config/config.go | 71 | ||||
| -rw-r--r-- | internal/config/env.go | 18 | ||||
| -rw-r--r-- | internal/config/initializer.go | 197 | ||||
| -rw-r--r-- | internal/config/read.go | 37 | ||||
| -rw-r--r-- | internal/config/server.go | 22 |
8 files changed, 634 insertions, 100 deletions
diff --git a/internal/config/args.go b/internal/config/args.go new file mode 100644 index 0000000..87ef393 --- /dev/null +++ b/internal/config/args.go @@ -0,0 +1,172 @@ +package config + +import ( + "encoding/base64" + "fmt" + "strconv" + "strings" + + "github.com/mimecast/dtail/internal/lcontext" + "github.com/mimecast/dtail/internal/omode" + + gossh "golang.org/x/crypto/ssh" +) + +// Args is a helper struct to summarize common client arguments. +type Args struct { + lcontext.LContext + Arguments []string + ConfigFile string + ConnectionsPerCPU int + Discovery string + LogDir string + Logger string + LogLevel string + Mode omode.Mode + NoColor bool + QueryStr string + Quiet bool + RegexInvert bool + RegexStr string + SSHAuthMethods []gossh.AuthMethod + SSHBindAddress string + SSHHostKeyCallback gossh.HostKeyCallback + SSHPort int + SSHPrivateKeyFilePath string + Serverless bool + ServersStr string + Plain bool + Timeout int + TrustAllHosts bool + UserName string + What string +} + +func (a *Args) String() string { + var sb strings.Builder + + sb.WriteString("Args(") + + sb.WriteString(fmt.Sprintf("%s:%v,", "Arguments", a.Arguments)) + sb.WriteString(fmt.Sprintf("%s:%v,", "ConfigFile", a.ConfigFile)) + sb.WriteString(fmt.Sprintf("%s:%v,", "ConnectionsPerCPU", a.ConnectionsPerCPU)) + sb.WriteString(fmt.Sprintf("%s:%v,", "Discovery", a.Discovery)) + sb.WriteString(fmt.Sprintf("%s:%v,", "LogDir", a.LogDir)) + sb.WriteString(fmt.Sprintf("%s:%v,", "LogLevel", a.LogLevel)) + sb.WriteString(fmt.Sprintf("%s:%v,", "Logger", a.Logger)) + sb.WriteString(fmt.Sprintf("%s:%v,", "Mode", a.Mode)) + sb.WriteString(fmt.Sprintf("%s:%v,", "NoColor", a.NoColor)) + sb.WriteString(fmt.Sprintf("%s:%v,", "QueryStr", a.QueryStr)) + sb.WriteString(fmt.Sprintf("%s:%v,", "Quiet", a.Quiet)) + sb.WriteString(fmt.Sprintf("%s:%v,", "RegexInvert", a.RegexInvert)) + sb.WriteString(fmt.Sprintf("%s:%v,", "RegexStr", a.RegexStr)) + sb.WriteString(fmt.Sprintf("%s:%v,", "SSHAuthMethods", a.SSHAuthMethods)) + sb.WriteString(fmt.Sprintf("%s:%v,", "SSHBindAddress", a.SSHBindAddress)) + sb.WriteString(fmt.Sprintf("%s:%v,", "SSHHostKeyCallback", a.SSHHostKeyCallback)) + sb.WriteString(fmt.Sprintf("%s:%v,", "SSHPrivateKeyFilePath", a.SSHPrivateKeyFilePath)) + sb.WriteString(fmt.Sprintf("%s:%v,", "SSHPort", a.SSHPort)) + sb.WriteString(fmt.Sprintf("%s:%v,", "Serverless", a.Serverless)) + sb.WriteString(fmt.Sprintf("%s:%v,", "ServersStr", a.ServersStr)) + sb.WriteString(fmt.Sprintf("%s:%v,", "Plain", a.Plain)) + sb.WriteString(fmt.Sprintf("%s:%v,", "Timeout", a.Timeout)) + sb.WriteString(fmt.Sprintf("%s:%v,", "TrustAllHosts", a.TrustAllHosts)) + sb.WriteString(fmt.Sprintf("%s:%v,", "UserName", a.UserName)) + sb.WriteString(fmt.Sprintf("%s:%v", "What", a.What)) + sb.WriteString(")") + + return sb.String() +} + +// SerializeOptions returns a string ready to be sent over the wire to the server. +func (a *Args) SerializeOptions() string { + options := make(map[string]string) + + if a.Quiet { + options["quiet"] = fmt.Sprintf("%v", a.Quiet) + } + if a.Plain { + options["plain"] = fmt.Sprintf("%v", a.Plain) + } + if a.Serverless { + options["serverless"] = fmt.Sprintf("%v", a.Serverless) + } + if a.LContext.MaxCount != 0 { + options["max"] = fmt.Sprintf("%d", a.LContext.MaxCount) + } + if a.LContext.BeforeContext != 0 { + options["before"] = fmt.Sprintf("%d", a.LContext.BeforeContext) + } + if a.LContext.AfterContext != 0 { + options["after"] = fmt.Sprintf("%d", a.LContext.AfterContext) + } + + var sb strings.Builder + var i int + for k, v := range options { + if i > 0 { + sb.WriteString(":") + } + sb.WriteString(k) + sb.WriteString("=") + sb.WriteString(v) + i++ + } + return sb.String() +} + +// DeserializeOptions deserializes the options, but into a map. +func DeserializeOptions(opts []string) (map[string]string, lcontext.LContext, error) { + options := make(map[string]string, len(opts)) + var ltx lcontext.LContext + + for _, o := range opts { + kv := strings.SplitN(o, "=", 2) + if len(kv) != 2 { + return options, ltx, fmt.Errorf("Unable to parse options: %v", kv) + } + key := kv[0] + val := kv[1] + + if strings.HasPrefix(val, "base64%") { + s := strings.SplitN(val, "%", 2) + decoded, err := base64.StdEncoding.DecodeString(s[1]) + if err != nil { + return options, ltx, err + } + val = string(decoded) + } + + var err error + if options, err = setOption(key, val, options, <x); err != nil { + return options, ltx, err + } + } + + return options, ltx, nil +} + +func setOption(key, val string, options map[string]string, ltx *lcontext.LContext) (map[string]string, error) { + switch key { + case "before": + iVal, err := strconv.Atoi(val) + if err != nil { + return options, err + } + ltx.BeforeContext = iVal + case "after": + iVal, err := strconv.Atoi(val) + if err != nil { + return options, err + } + ltx.AfterContext = iVal + case "max": + iVal, err := strconv.Atoi(val) + if err != nil { + return options, err + } + ltx.MaxCount = iVal + default: + options[key] = val + } + return options, nil +} diff --git a/internal/config/client.go b/internal/config/client.go index 1515aae..9f4df97 100644 --- a/internal/config/client.go +++ b/internal/config/client.go @@ -1,11 +1,200 @@ package config +import "github.com/mimecast/dtail/internal/color" + +type remoteTermColors struct { + DelimiterAttr color.Attribute + DelimiterBg color.BgColor + DelimiterFg color.FgColor + RemoteAttr color.Attribute + RemoteBg color.BgColor + RemoteFg color.FgColor + CountAttr color.Attribute + CountBg color.BgColor + CountFg color.FgColor + HostnameAttr color.Attribute + HostnameBg color.BgColor + HostnameFg color.FgColor + IDAttr color.Attribute + IDBg color.BgColor + IDFg color.FgColor + StatsOkAttr color.Attribute + StatsOkBg color.BgColor + StatsOkFg color.FgColor + StatsWarnAttr color.Attribute + StatsWarnBg color.BgColor + StatsWarnFg color.FgColor + TextAttr color.Attribute + TextBg color.BgColor + TextFg color.FgColor +} + +type clientTermColors struct { + DelimiterAttr color.Attribute + DelimiterBg color.BgColor + DelimiterFg color.FgColor + ClientAttr color.Attribute + ClientBg color.BgColor + ClientFg color.FgColor + HostnameAttr color.Attribute + HostnameBg color.BgColor + HostnameFg color.FgColor + TextAttr color.Attribute + TextBg color.BgColor + TextFg color.FgColor +} + +type serverTermColors struct { + DelimiterAttr color.Attribute + DelimiterBg color.BgColor + DelimiterFg color.FgColor + ServerAttr color.Attribute + ServerBg color.BgColor + ServerFg color.FgColor + HostnameAttr color.Attribute + HostnameBg color.BgColor + HostnameFg color.FgColor + TextAttr color.Attribute + TextBg color.BgColor + TextFg color.FgColor +} + +type commonTermColors struct { + SeverityErrorAttr color.Attribute + SeverityErrorBg color.BgColor + SeverityErrorFg color.FgColor + SeverityFatalAttr color.Attribute + SeverityFatalBg color.BgColor + SeverityFatalFg color.FgColor + SeverityWarnAttr color.Attribute + SeverityWarnBg color.BgColor + SeverityWarnFg color.FgColor +} + +type maprTableTermColors struct { + DataAttr color.Attribute + DataBg color.BgColor + DataFg color.FgColor + DelimiterAttr color.Attribute + DelimiterBg color.BgColor + DelimiterFg color.FgColor + HeaderAttr color.Attribute + HeaderBg color.BgColor + HeaderDelimiterAttr color.Attribute + HeaderDelimiterBg color.BgColor + HeaderDelimiterFg color.FgColor + HeaderFg color.FgColor + HeaderGroupKeyAttr color.Attribute + HeaderSortKeyAttr color.Attribute + RawQueryAttr color.Attribute + RawQueryBg color.BgColor + RawQueryFg color.FgColor +} + +type termColors struct { + Remote remoteTermColors + Client clientTermColors + Server serverTermColors + Common commonTermColors + MaprTable maprTableTermColors +} + // ClientConfig represents a DTail client configuration (empty as of now as there // are no available config options yet, but that may changes in the future). type ClientConfig struct { + TermColorsEnable bool `json:",omitempty"` + TermColors termColors `json:",omitempty"` } // Create a new default client configuration. func newDefaultClientConfig() *ClientConfig { - return &ClientConfig{} + return &ClientConfig{ + TermColorsEnable: true, + TermColors: termColors{ + Remote: remoteTermColors{ + DelimiterAttr: color.AttrDim, + DelimiterBg: color.BgBlue, + DelimiterFg: color.FgCyan, + RemoteAttr: color.AttrDim, + RemoteBg: color.BgBlue, + RemoteFg: color.FgWhite, + CountAttr: color.AttrDim, + CountBg: color.BgBlue, + CountFg: color.FgWhite, + HostnameAttr: color.AttrBold, + HostnameBg: color.BgBlue, + HostnameFg: color.FgWhite, + IDAttr: color.AttrDim, + IDBg: color.BgBlue, + IDFg: color.FgWhite, + StatsOkAttr: color.AttrNone, + StatsOkBg: color.BgGreen, + StatsOkFg: color.FgBlack, + StatsWarnAttr: color.AttrNone, + StatsWarnBg: color.BgRed, + StatsWarnFg: color.FgWhite, + TextAttr: color.AttrNone, + TextBg: color.BgBlack, + TextFg: color.FgWhite, + }, + Client: clientTermColors{ + DelimiterAttr: color.AttrDim, + DelimiterBg: color.BgYellow, + DelimiterFg: color.FgBlack, + ClientAttr: color.AttrDim, + ClientBg: color.BgYellow, + ClientFg: color.FgBlack, + HostnameAttr: color.AttrDim, + HostnameBg: color.BgYellow, + HostnameFg: color.FgBlack, + TextAttr: color.AttrNone, + TextBg: color.BgBlack, + TextFg: color.FgWhite, + }, + Server: serverTermColors{ + DelimiterAttr: color.AttrDim, + DelimiterBg: color.BgCyan, + DelimiterFg: color.FgBlack, + ServerAttr: color.AttrDim, + ServerBg: color.BgCyan, + ServerFg: color.FgBlack, + HostnameAttr: color.AttrBold, + HostnameBg: color.BgCyan, + HostnameFg: color.FgBlack, + TextAttr: color.AttrNone, + TextBg: color.BgBlack, + TextFg: color.FgWhite, + }, + Common: commonTermColors{ + SeverityErrorAttr: color.AttrBold, + SeverityErrorBg: color.BgRed, + SeverityErrorFg: color.FgWhite, + SeverityFatalAttr: color.AttrBold, + SeverityFatalBg: color.BgMagenta, + SeverityFatalFg: color.FgWhite, + SeverityWarnAttr: color.AttrBold, + SeverityWarnBg: color.BgBlack, + SeverityWarnFg: color.FgWhite, + }, + MaprTable: maprTableTermColors{ + DataAttr: color.AttrNone, + DataBg: color.BgBlue, + DataFg: color.FgWhite, + DelimiterAttr: color.AttrDim, + DelimiterBg: color.BgBlue, + DelimiterFg: color.FgWhite, + HeaderAttr: color.AttrBold, + HeaderBg: color.BgBlue, + HeaderFg: color.FgWhite, + HeaderDelimiterAttr: color.AttrDim, + HeaderDelimiterBg: color.BgBlue, + HeaderDelimiterFg: color.FgWhite, + HeaderSortKeyAttr: color.AttrUnderline, + HeaderGroupKeyAttr: color.AttrReverse, + RawQueryAttr: color.AttrDim, + RawQueryBg: color.BgBlack, + RawQueryFg: color.FgCyan, + }, + }, + } } diff --git a/internal/config/common.go b/internal/config/common.go index c3e203e..7a72cfe 100644 --- a/internal/config/common.go +++ b/internal/config/common.go @@ -6,31 +6,27 @@ type CommonConfig struct { SSHPort int // Enable experimental features (mainly for dev purposes) ExperimentalFeaturesEnable bool `json:",omitempty"` - // Enable debug logging. Don't enable in production. - DebugEnable bool `json:",omitempty"` - // Enable trace logging. Don't enable in production. - TraceEnable bool `json:",omitempty"` - // The log strategy to use, one of - // stdout: only log to stdout (useful when used with systemd) - // daily: create a log file for every day - LogStrategy string - // The log directory + // LogDir defines the log directory. LogDir string + // Logger defines the name of the logger implementation. + Logger string + // LogLevel defines how much is logged. + LogLevel string `json:",omitempty"` + // LogRotation strategy to be used. + LogRotation string // The cache directory CacheDir string - // The temp directory - TmpDir string `json:",omitempty"` } // Create a new default configuration. func newDefaultCommonConfig() *CommonConfig { return &CommonConfig{ - SSHPort: 2222, - DebugEnable: false, - TraceEnable: false, + SSHPort: DefaultSSHPort, ExperimentalFeaturesEnable: false, LogDir: "log", + Logger: "stdout", + LogLevel: DefaultLogLevel, + LogRotation: "daily", CacheDir: "cache", - TmpDir: "/tmp", } } diff --git a/internal/config/config.go b/internal/config/config.go index 276ddcf..ee23829 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -1,23 +1,30 @@ package config -import ( - "encoding/json" - "io/ioutil" - "os" +import "github.com/mimecast/dtail/internal/source" + +const ( + // HealthUser is used for the health check + HealthUser string = "DTAIL-HEALTH" + // ScheduleUser is used for non-interactive scheduled mapreduce queries. + ScheduleUser string = "DTAIL-SCHEDULE" + // ContinuousUser is used for non-interactive continuous mapreduce queries. + ContinuousUser string = "DTAIL-CONTINUOUS" + // InterruptTimeoutS specifies the Ctrl+C log pause interval. + InterruptTimeoutS int = 3 + // DefaultConnectionsPerCPU controls how many connections are established concurrently. + DefaultConnectionsPerCPU int = 10 + // DefaultSSHPort is the default DServer port. + DefaultSSHPort int = 2222 + // DefaultLogLevel specifies the default log level (obviously) + DefaultLogLevel string = "info" + // DefaultClientLogger specifies the default logger for the client commands. + DefaultClientLogger string = "fout" + // DefaultServerLogger specifies the default logger for dtail server. + DefaultServerLogger string = "file" + // DefaultHealthCheckLogger specifies the default logger used for health checks. + DefaultHealthCheckLogger string = "none" ) -// ControlUser is used for various DTail specific operations. -const ControlUser string = "DTAIL-CONTROL" - -// ScheduleUser is used for non-interactive scheduled mapreduce queries. -const ScheduleUser string = "DTAIL-SCHEDULE" - -// ContinuousUser is used for non-interactive continuous mapreduce queries. -const ContinuousUser string = "DTAIL-CONTINUOUS" - -// InterruptTimeoutS is used to terminate DTail when Ctrl+C was pressed twice within a given interval. -const InterruptTimeoutS int = 3 - // Client holds a DTail client configuration. var Client *ClientConfig @@ -27,28 +34,22 @@ var Server *ServerConfig // Common holds common configs of both both, client and server. var Common *CommonConfig -// Used to initialize the configuration. -type configInitializer struct { - Common *CommonConfig - Server *ServerConfig - Client *ClientConfig -} - -// Parse and read a given config file in JSON format. -func (c *configInitializer) parseConfig(configFile string) { - fd, err := os.Open(configFile) - if err != nil { - panic(err) +// Setup the DTail configuration. +func Setup(sourceProcess source.Source, args *Args, additionalArgs []string) { + initializer := initializer{ + Common: newDefaultCommonConfig(), + Server: newDefaultServerConfig(), + Client: newDefaultClientConfig(), } - defer fd.Close() - - cfgBytes, err := ioutil.ReadAll(fd) - if err != nil { + if err := initializer.parseConfig(args); err != nil { panic(err) } - - err = json.Unmarshal([]byte(cfgBytes), c) - if err != nil { + if err := initializer.transformConfig(sourceProcess, args, additionalArgs); err != nil { panic(err) } + + // Make config accessible globally + Server = initializer.Server + Client = initializer.Client + Common = initializer.Common } diff --git a/internal/config/env.go b/internal/config/env.go new file mode 100644 index 0000000..1ccac9c --- /dev/null +++ b/internal/config/env.go @@ -0,0 +1,18 @@ +package config + +import "os" + +// Env returns true when a given environment variable is set to "yes". +func Env(env string) bool { + return "yes" == os.Getenv(env) +} + +// Hostname returns the current hostname. It can be overriden with +// DTAIL_HOSTNAME_OVERRIDE environment variable (useful for integration tests). +func Hostname() (string, error) { + hostname := os.Getenv("DTAIL_HOSTNAME_OVERRIDE") + if len(hostname) > 0 { + return hostname, nil + } + return os.Hostname() +} diff --git a/internal/config/initializer.go b/internal/config/initializer.go new file mode 100644 index 0000000..9724902 --- /dev/null +++ b/internal/config/initializer.go @@ -0,0 +1,197 @@ +package config + +import ( + "encoding/json" + "flag" + "fmt" + "io/ioutil" + "os" + "strings" + + "github.com/mimecast/dtail/internal/source" +) + +// Used to initialize the configuration. +type initializer struct { + Common *CommonConfig + Server *ServerConfig + Client *ClientConfig +} + +type transformCb func(*initializer, *Args, []string) error + +func (in *initializer) parseConfig(args *Args) error { + if strings.ToLower(args.ConfigFile) == "none" { + return nil + } + + if args.ConfigFile != "" { + return in.parseSpecificConfig(args.ConfigFile) + } + + if homeDir, err := os.UserHomeDir(); err != nil { + var paths []string + paths = append(paths, fmt.Sprintf("%s/.config/dtail/dtail.conf", homeDir)) + paths = append(paths, fmt.Sprintf("%s/.dtail.conf", homeDir)) + for _, configPath := range paths { + if _, err := os.Stat(configPath); !os.IsNotExist(err) { + in.parseSpecificConfig(configPath) + } + } + } + + return nil +} + +func (in *initializer) parseSpecificConfig(configFile string) error { + fd, err := os.Open(configFile) + if err != nil { + return fmt.Errorf("Unable to read config file: %v", err) + } + defer fd.Close() + + cfgBytes, err := ioutil.ReadAll(fd) + if err != nil { + return fmt.Errorf("Unable to read config file %s: %v", configFile, err) + } + + if err := json.Unmarshal([]byte(cfgBytes), in); err != nil { + return fmt.Errorf("Unable to parse config file %s: %v", configFile, err) + } + + return nil +} + +func (in *initializer) transformConfig(sourceProcess source.Source, args *Args, + additionalArgs []string) error { + + in.processEnvVars(args) + + switch sourceProcess { + case source.Server: + return in.setupConfig(transformServer, args, additionalArgs) + case source.Client: + return in.setupConfig(transformClient, args, additionalArgs) + case source.HealthCheck: + return in.setupConfig(transformHealthCheck, args, additionalArgs) + default: + return fmt.Errorf("Unable to transform config, unknown source '%s'", + sourceProcess) + } +} + +func (in *initializer) processEnvVars(args *Args) { + if Env("DTAIL_INTEGRATION_TEST_RUN_MODE") { + os.Setenv("DTAIL_HOSTNAME_OVERRIDE", "integrationtest") + in.Server.MaxLineLength = 1024 + } + sshPrivateKeyPathFile := os.Getenv("DTAIL_SSH_PRIVATE_KEYFILE_PATH") + if len(sshPrivateKeyPathFile) > 0 && args.SSHPrivateKeyFilePath == "" { + args.SSHPrivateKeyFilePath = sshPrivateKeyPathFile + } +} + +func (in *initializer) setupConfig(sourceCb transformCb, args *Args, + additionalArgs []string) error { + + // Copy args to config objects. + // NEXT: Maybe unify args and config structs? + if args.SSHPort != DefaultSSHPort { + in.Common.SSHPort = args.SSHPort + } + if args.LogLevel != DefaultLogLevel { + in.Common.LogLevel = args.LogLevel + } + if args.NoColor { + in.Client.TermColorsEnable = false + } + if args.LogDir != "" { + in.Common.LogDir = args.LogDir + } + if args.Logger != "" { + in.Common.Logger = args.Logger + } + if args.ConnectionsPerCPU == 0 { + args.ConnectionsPerCPU = DefaultConnectionsPerCPU + } + + setupLogDirectory(in) + sourceCb(in, args, additionalArgs) + if args.Plain { + setupPlainMode(in, args) + } + if args.What == "" { + setupAdditionalArgs(in, args) + } + + return nil +} + +func setupLogDirectory(in *initializer) { + // Setup log directory. + if strings.Contains(in.Common.LogDir, "~/") { + homeDir, err := os.UserHomeDir() + if err != nil { + panic(err) + } + in.Common.LogDir = strings.ReplaceAll(in.Common.LogDir, "~/", + fmt.Sprintf("%s/", homeDir)) + } +} + +func setupPlainMode(in *initializer, args *Args) { + args.Quiet = true + args.NoColor = true + in.Client.TermColorsEnable = false + if args.LogLevel == "" { + args.LogLevel = "ERROR" + in.Common.LogLevel = "ERROR" + } +} + +func setupAdditionalArgs(in *initializer, args *Args) { + // Interpret additional args as file list or as query. + if args.What == "" { + var files []string + for _, arg := range flag.Args() { + if args.QueryStr == "" && strings.Contains(strings.ToLower(arg), "select ") { + args.QueryStr = arg + continue + } + files = append(files, arg) + } + args.What = strings.Join(files, ",") + } +} + +func transformClient(in *initializer, args *Args, additionalArgs []string) error { + // Serverless mode. + if args.Discovery == "" && (args.ServersStr == "" || + strings.ToLower(args.ServersStr) == "serverless") { + // We are not connecting to any servers. + args.Serverless = true + if args.LogLevel == DefaultLogLevel { + in.Common.LogLevel = "warn" + } + } + return nil +} + +func transformServer(in *initializer, args *Args, additionalArgs []string) error { + if args.SSHBindAddress != "" { + in.Server.SSHBindAddress = args.SSHBindAddress + } + return nil +} + +func transformHealthCheck(in *initializer, args *Args, additionalArgs []string) error { + // Serverless mode. + if args.Discovery == "" && (args.ServersStr == "" || + strings.ToLower(args.ServersStr) == "serverless") { + // We are not connecting to any servers. + args.Serverless = true + in.Common.LogLevel = "warn" + } + args.TrustAllHosts = true + return nil +} diff --git a/internal/config/read.go b/internal/config/read.go deleted file mode 100644 index a4e605b..0000000 --- a/internal/config/read.go +++ /dev/null @@ -1,37 +0,0 @@ -package config - -import ( - "os" -) - -// Read the DTail configuration. -func Read(configFile string, sshPort int) { - initializer := configInitializer{ - Common: newDefaultCommonConfig(), - Server: newDefaultServerConfig(), - Client: newDefaultClientConfig(), - } - - if configFile == "" { - configFile = "./cfg/dtail.json" - } - - if _, err := os.Stat(configFile); !os.IsNotExist(err) { - initializer.parseConfig(configFile) - } - - // Assign pointers to global variables, so that we can access the - // configuration from any place of the program. - Common = initializer.Common - Server = initializer.Server - Client = initializer.Client - - if Server.MapreduceLogFormat == "" { - Server.MapreduceLogFormat = "default" - } - - // If non-standard port specified, overwrite config - if sshPort != 2222 { - Common.SSHPort = sshPort - } -} diff --git a/internal/config/server.go b/internal/config/server.go index dc0d587..4c96567 100644 --- a/internal/config/server.go +++ b/internal/config/server.go @@ -4,8 +4,8 @@ import ( "errors" ) -// Permissions map. Each SSH user has a list of permissions which -// log files it is allowed to follow and which ones not. +// Permissions map. Each SSH user has a list of permissions which log files it +// is allowed to follow and which ones not. type Permissions struct { // The default user permissions. Default []string @@ -47,6 +47,8 @@ type ServerConfig struct { MaxConcurrentCats int // The max amount of concurrent tails per server. MaxConcurrentTails int + // The max line length until it's split up into multiple smaller lines. + MaxLineLength int // The user permissions. Permissions Permissions `json:",omitempty"` // The mapr log format @@ -61,21 +63,19 @@ type ServerConfig struct { Continuous []Continuous `json:",omitempty"` } -// ServerRelaxedAuthEnable should be used for development and testing purposes only. -var ServerRelaxedAuthEnable bool - // Create a new default server configuration. func newDefaultServerConfig() *ServerConfig { defaultPermissions := []string{"^/.*"} defaultBindAddress := "0.0.0.0" - return &ServerConfig{ - SSHBindAddress: defaultBindAddress, - MaxConnections: 10, + HostKeyBits: 4096, + HostKeyFile: "./cache/ssh_host_key", + MapreduceLogFormat: "default", MaxConcurrentCats: 2, MaxConcurrentTails: 50, - HostKeyFile: "./cache/ssh_host_key", - HostKeyBits: 4096, + MaxConnections: 10, + MaxLineLength: 1024 * 1024, + SSHBindAddress: defaultBindAddress, Permissions: Permissions{ Default: defaultPermissions, }, @@ -88,10 +88,8 @@ func ServerUserPermissions(userName string) (permissions []string, err error) { if p, ok := Server.Permissions.Users[userName]; ok { permissions = p } - if len(permissions) == 0 { err = errors.New("Empty set of permission, user won't be able to open any files") } - return } |
