// Run shells out external program and store the output on c.Data. func (s *Shell) Run() error { if s.Command != "" { s.Command = libstring.ExpandTildeAndEnv(s.Command) readersDataJsonBytes, err := json.Marshal(s.GetReadersData()) if err != nil { return err } cmd := libprocess.NewCmd(s.Command) cmd.Stdin = bytes.NewReader(readersDataJsonBytes) outputJson, err := cmd.CombinedOutput() var output map[string]interface{} json.Unmarshal(outputJson, &output) s.Data["Output"] = output if err != nil { s.Data["ExitStatus"] = 1 } else { s.Data["ExitStatus"] = 0 } } return nil }
// Run NagiosPlugins out external program and store the output on c.Data. func (s *NagiosPlugin) Run() error { if s.Command != "" { s.Command = libstring.ExpandTildeAndEnv(s.Command) nagiosPluginOutputBytes, err := libprocess.NewCmd(s.Command).CombinedOutput() if err != nil { s.Data["ExitStatus"] = 1 } else { s.Data["ExitStatus"] = 0 } nagiosPluginOutput := strings.TrimSpace(string(nagiosPluginOutputBytes)) if strings.Contains(nagiosPluginOutput, "OK") { s.Data["ExitStatus"] = 0 s.Data["Message"] = nagiosPluginOutput } else if strings.Contains(nagiosPluginOutput, "WARNING") { s.Data["ExitStatus"] = 1 s.Data["Message"] = nagiosPluginOutput } else if strings.Contains(nagiosPluginOutput, "CRITICAL") { s.Data["ExitStatus"] = 2 s.Data["Message"] = nagiosPluginOutput } else if strings.Contains(nagiosPluginOutput, "UNKNOWN") { s.Data["ExitStatus"] = 3 s.Data["Message"] = nagiosPluginOutput } } return nil }
// GetJsonProcessor returns json processor path. func (b *Base) GetJsonProcessor() string { path := "" if b.JsonProcessor != "" { path = libstring.ExpandTildeAndEnv(b.JsonProcessor) } return path }
// NewGeneralConfig is the constructor for GeneralConfig. func NewGeneralConfig(configDir string) (GeneralConfig, error) { configDir = libstring.ExpandTildeAndEnv(configDir) fullpath := path.Join(configDir, "general.toml") var config GeneralConfig _, err := toml.DecodeFile(fullpath, &config) if config.LogLevel == "" { config.LogLevel = "info" } return config, err }
// NewConfig creates Config struct given fullpath and kind. func NewConfig(fullpath, kind string) (Config, error) { fullpath = libstring.ExpandTildeAndEnv(fullpath) var config Config _, err := toml.DecodeFile(fullpath, &config) if config.Interval == "" { config.Interval = "1m" } config.Kind = kind return config, err }
// Run shells out external program and store the output on c.Data. func (dc *DiskCleaner) Run() error { dc.Data["Conditions"] = dc.Conditions if dc.IsConditionMet() && dc.LowThresholdExceeded() && !dc.HighThresholdExceeded() { successOutput := make([]string, 0) failOutput := make([]string, 0) for _, globInterface := range dc.Globs { glob := globInterface.(string) glob = libstring.ExpandTildeAndEnv(glob) matches, err := filepath.Glob(glob) if err != nil { dc.Data["Error"] = err.Error() dc.Data["ExitStatus"] = 1 return err } for _, fullpath := range matches { err := os.RemoveAll(fullpath) if err != nil { failOutput = append(failOutput, fullpath) } else { successOutput = append(successOutput, fullpath) } } } if len(failOutput) > 0 { dc.Data["ExitStatus"] = 1 } else { dc.Data["ExitStatus"] = 0 } dc.Data["Success"] = successOutput dc.Data["Failure"] = failOutput if len(failOutput) > 0 || len(successOutput) > 0 { logrus.WithFields(logrus.Fields{ "Success": successOutput, "Failure": failOutput, "ExitStatus": dc.Data["ExitStatus"], }).Info("Deleted files") } } return nil }
func TestDiskCleanerRun(t *testing.T) { ResetConditionsMetByPath() config := newConfigExecutorForTest(t) config.GoStruct = "DiskCleaner" config.Kind = "executor" config.Path = "/x/disk-cleaner/home" config.GoStructFields = make(map[string]interface{}) config.GoStructFields["Globs"] = make([]interface{}, 0) config.GoStructFields["Globs"] = append(config.GoStructFields["Globs"].([]interface{}), "~/*.log") // Create a file to be deleted seed, _ := libstring.GeneratePassword(32) err := ioutil.WriteFile(libstring.ExpandTildeAndEnv(fmt.Sprintf("~/testing-%v.log", seed)), []byte(""), 0644) if err != nil { t.Fatalf("Creating a file should always work. Error: %v", err) } executor, err := NewGoStructByConfig(config) if executor == nil { t.Fatalf("Shell constructor did not do its job") } if err != nil { t.Errorf("Shell constructor did not do its job. Error: %v", err) } executor.Run() dataJson, err := executor.ToJson() if err != nil { t.Fatalf("Failed to serialize data to JSON. Error: %v", err) } var data map[string]interface{} json.Unmarshal(dataJson, &data) if data["Success"] == nil { t.Fatalf("There should always be output from uptime.") } if len(data["Success"].([]interface{})) == 0 { t.Fatalf("There should be success cleaned file data. Success: %v", data["Success"].([]interface{})) } }
// Run shells out external program and store the output on c.Data. func (s *Shell) Run() error { if s.Command != "" { s.Command = libstring.ExpandTildeAndEnv(s.Command) outputJson, err := libprocess.NewCmd(s.Command).CombinedOutput() var output map[string]interface{} json.Unmarshal(outputJson, &output) s.Data["Output"] = output if err != nil { s.Data["ExitStatus"] = 1 } else { s.Data["ExitStatus"] = 0 } } return nil }
func (a *Agent) setTags() error { a.Tags = make(map[string]string) configDir := os.Getenv("RESOURCED_CONFIG_DIR") if configDir == "" { return nil } configDir = libstring.ExpandTildeAndEnv(configDir) tagFiles, err := ioutil.ReadDir(path.Join(configDir, "tags")) if err != nil { return nil } for _, f := range tagFiles { fullpath := path.Join(configDir, "tags", f.Name()) file, err := os.Open(fullpath) if err != nil { continue } defer file.Close() scanner := bufio.NewScanner(file) for scanner.Scan() { tagsPerLine := strings.Split(scanner.Text(), ",") for _, tagKeyValue := range tagsPerLine { keyValue := strings.Split(tagKeyValue, "=") if len(keyValue) >= 2 { a.Tags[keyValue[0]] = strings.Join(keyValue[1:], "=") } } } } return nil }
// NewConfigs creates Configs struct given configDir. func NewConfigs(configDir string) (*Configs, error) { storage := &Configs{} storage.Readers = make([]Config, 0) storage.Writers = make([]Config, 0) storage.Executors = make([]Config, 0) var err error configDir = libstring.ExpandTildeAndEnv(configDir) for _, configKind := range []string{"reader", "writer", "executor"} { configKindPlural := configKind + "s" configFiles, err := ioutil.ReadDir(path.Join(configDir, configKindPlural)) if err == nil { for _, f := range configFiles { fullpath := path.Join(configDir, configKindPlural, f.Name()) conf, err := NewConfig(fullpath, configKind) if err == nil { if configKind == "reader" { storage.Readers = append(storage.Readers, conf) } if configKind == "writer" { storage.Writers = append(storage.Writers, conf) } if configKind == "executor" { storage.Executors = append(storage.Executors, conf) } } } } } return storage, err }
// NewDefaultConfigs provide default config setup. // This function is called on first boot. func NewDefaultConfigs(configDir string) error { configDir = libstring.ExpandTildeAndEnv(configDir) // Create configDir if it does not exist if _, err := os.Stat(configDir); err != nil { if os.IsNotExist(err) { err := os.MkdirAll(configDir, 0755) if err != nil { return err } logrus.WithFields(logrus.Fields{ "Directory": configDir, }).Infof("Created config directory") } } // Create subdirectories for _, subdirConfigs := range []string{"readers", "writers", "executors", "tags"} { subdirPath := path.Join(configDir, subdirConfigs) if _, err := os.Stat(subdirPath); err != nil { if os.IsNotExist(err) { err := os.MkdirAll(subdirPath, 0755) if err != nil { return err } logrus.WithFields(logrus.Fields{ "Directory": subdirPath, }).Infof("Created config directory") // Download default reader config files // Ignore errors as it's not important. if subdirConfigs == "readers" { output, err := exec.Command( "svn", "checkout", "https://github.com/resourced/resourced/trunk/tests/data/resourced-configs/readers", subdirPath, ).CombinedOutput() if err != nil { logrus.WithFields(logrus.Fields{ "Error": err.Error(), }).Error("Failed to download default reader config files: " + string(output)) } // Remove .svn artifacts os.RemoveAll(path.Join(subdirPath, ".svn")) } } } } // Create default tags defaultTagsTemplate := `GOOS=%v uname=%v ` unameBytes, err := exec.Command("uname", "-a").CombinedOutput() if err != nil { return err } uname := strings.TrimSpace(string(unameBytes)) err = ioutil.WriteFile(path.Join(configDir, "tags", "default"), []byte(fmt.Sprintf(defaultTagsTemplate, runtime.GOOS, uname)), 0755) if err != nil { return err } logrus.WithFields(logrus.Fields{ "File": path.Join(configDir, "tags", "default"), }).Infof("Created default tags file") // Create a default general.toml generalToml := `# Addr is the host and port of ResourceD Agent HTTP/S server Addr = "localhost:55555" # Valid LogLevel are: debug, info, warning, error, fatal, panic LogLevel = "info" [HTTPS] CertFile = "" KeyFile = "" [ResourcedMaster] # Url is the root endpoint to Resourced Master URL = "http://localhost:55655" # General purpose AccessToken, it will be used when AccessToken is not defined elsewhere. AccessToken = "{access-token}" ` err = ioutil.WriteFile(path.Join(configDir, "general.toml"), []byte(generalToml), 0644) if err != nil { return err } logrus.WithFields(logrus.Fields{ "File": path.Join(configDir, "general.toml"), }).Infof("Created general config file") return nil }