func parseCmd(in string) []values.String { result := []values.String{} inEscape := false inQuotes := false buf := "" for i := 0; i < len(in); i++ { c := in[i] if inEscape { buf += string(c) inEscape = false } else if c == '\\' { inEscape = true } else if inQuotes { if c == '"' { inQuotes = false } else { buf += string(c) } } else if c == ' ' || c == '\t' || c == '\r' || c == '\n' { result = append(result, values.String(buf)) buf = "" } else if c == '"' { inQuotes = true } else { buf += string(c) } } if len(buf) > 0 { result = append(result, values.String(buf)) } return result }
func (s *ConfigTest) TestNewGenerateToFileConfig(c *C) { actual := NewGenerateToFileConfig(ReadOnly, values.String("foo/bar.pem")) c.Assert(actual.Type, Equals, GenerateToFile) c.Assert(actual.Permission, Equals, ReadOnly) c.Assert(actual.PemFile, Equals, values.String("foo/bar.pem")) c.Assert(actual.PemFilePermission, Equals, DefaultFilePermission()) c.Assert(actual.PemFileUser, IsEmpty) }
// NewGenerateToFileConfig creates a new Config with the given permission // and will force a creation of certificates to the given pemFile. func NewGenerateToFileConfig(permission Permission, pemFile values.String) Config { return Config{ Type: GenerateToFile, Permission: permission, PemFile: values.String(pemFile), PemFileUser: values.String(""), PemFilePermission: DefaultFilePermission(), } }
func (s *CheckersTest) TestIsEmpty(c *C) { c.Assert("abc", Not(IsEmpty)) c.Assert("", IsEmpty) c.Assert(values.String("abc"), Not(IsEmpty)) c.Assert(values.String(""), IsEmpty) c.Assert([]string{"abc"}, Not(IsEmpty)) c.Assert([]string{}, IsEmpty) c.Assert([]int{1}, Not(IsEmpty)) c.Assert([]int{}, IsEmpty) c.Assert(map[string]int{"abc": 1}, Not(IsEmpty)) c.Assert(map[string]int{}, IsEmpty) }
func (s *ConfigTest) TestValidateNotRequiredPemFile(c *C) { for _, t := range AllTypes { if !t.IsTakingFilename() { actual := Config{ Type: t, Permission: ReadOnly, PemFile: values.String(""), } c.Assert(actual.Validate(), IsNil) actual.PemFile = values.String("foo/bar.pem") c.Assert(actual.Validate(), IsNil) } } }
func (s *ConfigTest) TestValidateRequiredPemFile(c *C) { for _, t := range AllTypes { if t.IsTakingFilename() { actual := Config{ Type: t, Permission: ReadOnly, PemFile: values.String(""), } c.Assert(actual.Validate(), ErrorMatches, "There is no pemFile set for type "+t.String()+".") actual.PemFile = values.String("foo/bar.pem") c.Assert(actual.Validate(), IsNil) } } }
func (s *ConfigTest) TestValidateAllowedPemFileUser(c *C) { for _, t := range AllTypes { if t.IsTakingFileUser() { actual := Config{ Type: t, Permission: ReadOnly, PemFile: values.String("foo/bar.pem"), } actual.PemFileUser = values.String("") c.Assert(actual.Validate(), IsNil) actual.PemFileUser = values.String("foo") c.Assert(actual.Validate(), IsNil) } } }
func (s *ConfigTest) TestValidateNotAllowedPemFileUser(c *C) { for _, t := range AllTypes { if !t.IsTakingFileUser() { actual := Config{ Type: t, Permission: ReadOnly, PemFile: values.String(""), } actual.PemFileUser = values.String("") c.Assert(actual.Validate(), IsNil) actual.PemFileUser = values.String("foo") c.Assert(actual.Validate(), ErrorMatches, "There is no pemFileUser allowed for type "+t.String()+".") } } }
func attachArgsToMasterIfPossible(args []string, to *caretakerd.Config) { if len(args) > 0 { if masterName, ok := to.Services.GetMasterName(); ok { master := to.Services[masterName] for i := 0; i < len(args); i++ { master.Command = append(master.Command, values.String(args[i])) } to.Services[masterName] = master } } }
func (instance *Config) init() { (*instance).Logger = logger.NewConfig() (*instance).Command = []values.String{} (*instance).PreCommands = [][]values.String{} (*instance).PostCommands = [][]values.String{} (*instance).Type = AutoStart (*instance).CronExpression = NewCronExpression() (*instance).StartDelayInSeconds = values.NonNegativeInteger(0) (*instance).RestartDelayInSeconds = values.NonNegativeInteger(5) (*instance).SuccessExitCodes = values.ExitCodes{values.ExitCode(0)} (*instance).StopSignal = defaultStopSignal() (*instance).StopSignalTarget = values.ProcessGroup (*instance).StopCommand = []values.String{} (*instance).StopWaitInSeconds = values.NonNegativeInteger(30) (*instance).User = values.String("") (*instance).Environment = Environments{} (*instance).Directory = values.String("") (*instance).AutoRestart = values.OnFailures (*instance).InheritEnvironment = values.Boolean(true) (*instance).Access = access.NewNoneConfig() }
// Set sets the given string to the current object from a string. // Returns an error object if there are problems while transforming the string. func (instance *ConfigWrapper) Set(value string) error { if len(value) == 0 { return errors.New("There is an empty filename for configuration provided.") } filename := values.String(value) conf, err := caretakerd.LoadFromYamlFile(filename) if err != nil { return err } conf = conf.EnrichFromEnvironment() instance.filename = filename instance.instance = &conf instance.explicitSet = true return nil }
// Validate validates an action on this object and returns an error object if there is any. func (instance Config) Validate() error { err := instance.Type.Validate() if err == nil { err = instance.Permission.Validate() } if err == nil { err = instance.validateRequireStringValue(instance.PemFile, "pemFile", instance.Type.IsTakingFilename) } if err == nil { err = instance.validateStringOnlyAllowedValue(instance.PemFileUser, "pemFileUser", instance.Type.IsTakingFileUser, values.String("")) } if err == nil { err = instance.validateUint32OnlyAllowedValue(uint32(instance.PemFilePermission), "pemFilePermission", instance.Type.IsTakingFilePermission, uint32(DefaultFilePermission())) } return err }
package keyStore import ( "github.com/echocat/caretakerd/errors" "github.com/echocat/caretakerd/values" "strconv" "strings" ) var defaults = map[string]interface{}{ "Type": Generated, "PemFile": values.String(""), "Hints": values.String("algorithm:`rsa` bits:`1024`"), "CaFile": values.String(""), } // # Description // // Defines the keyStore of caretakerd. type Config struct { // @default generated // // Defines the type of the instance keyStore. Type Type `json:"type" yaml:"type"` // @default "" // // Defines the pemFile which contains the key and certificate to be used. // This has to be of type PEM and has to contain the certificate and private key. // Currently only private keys of type RSA are supported. //
// ListenAddress represents the default address caretakerd listens to. ListenAddress values.SocketAddress // AuthFileKeyFilename represents the default file name caretakerd uses to store // the key for the caretakerctl/control process. AuthFileKeyFilename values.String // ConfigFilename represents the default location where caretakerd searches for its config file (yaml). ConfigFilename values.String } var listenAddress = values.SocketAddress{ Protocol: values.TCP, Target: "localhost", Port: 57955, } const unixAuthFileKeyFilename = values.String("/var/run/caretakerd.key") const windowsAuthFileKeyFilename = values.String("C:\\ProgramData\\caretakerd\\access.key") const unixConfigFilename = values.String("/etc/caretakerd.yaml") const windowsConfigFilename = values.String("C:\\ProgramData\\caretakerd\\config.yaml") var allDefaults = map[string]Defaults{ "linux": { ListenAddress: listenAddress, AuthFileKeyFilename: unixAuthFileKeyFilename, ConfigFilename: unixConfigFilename, }, "windows": { ListenAddress: listenAddress, AuthFileKeyFilename: windowsAuthFileKeyFilename, ConfigFilename: windowsConfigFilename, },
package logger import ( "github.com/echocat/caretakerd/values" ) var defaults = map[string]interface{}{ "Level": Info, "StdoutLevel": Info, "StderrLevel": Error, "Filename": values.String("console"), "MaxSizeInMb": values.NonNegativeInteger(500), "MaxBackups": values.NonNegativeInteger(5), "MaxAgeInDays": values.NonNegativeInteger(1), "Pattern": Pattern("%d{YYYY-MM-DD HH:mm:ss} [%-5.5p] [%c] %m%n%P{%m}"), } // # Description // // A logger handles every output generated by the daemon itself, the process or other parts controlled by the daemon. type Config struct { // @default info // // Minimal log level the logger uses to log error messages. All levels below are ignored. Level Level `json:"level" yaml:"level"` // @default info // // If the service prints something to ``stdout``, the instance will be logged with the corresponding instance level. StdoutLevel Level `json:"stdoutLevel" yaml:"stdoutLevel"`