This commit is contained in:
		@@ -20,7 +20,7 @@ package cmd
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// func config(cmd *cobra.Command, args []string) {
 | 
					// func config(cmd *cobra.Command, args []string) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 	opts := backy.NewOpts(cfgFile, backy.UseCron())
 | 
					// 	opts := backy.NewOpts(cfgFile, backy.cronEnabled())
 | 
				
			||||||
// 	opts.InitConfig()
 | 
					// 	opts.InitConfig()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// }
 | 
					// }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,7 @@ var (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func cron(cmd *cobra.Command, args []string) {
 | 
					func cron(cmd *cobra.Command, args []string) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	opts := backy.NewOpts(cfgFile, backy.UseCron())
 | 
						opts := backy.NewOpts(cfgFile, backy.CronEnabled())
 | 
				
			||||||
	opts.InitConfig()
 | 
						opts.InitConfig()
 | 
				
			||||||
	backy.ReadConfig(opts)
 | 
						backy.ReadConfig(opts)
 | 
				
			||||||
	opts.Cron()
 | 
						opts.Cron()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,6 +30,8 @@ var Sprintf = fmt.Sprintf
 | 
				
			|||||||
// The environment of local commands will be the machine's environment plus any extra
 | 
					// The environment of local commands will be the machine's environment plus any extra
 | 
				
			||||||
// variables specified in the Env file or Environment.
 | 
					// variables specified in the Env file or Environment.
 | 
				
			||||||
// Dir can also be specified for local commands.
 | 
					// Dir can also be specified for local commands.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Returns the output as a slice and an error, if any
 | 
				
			||||||
func (command *Command) RunCmd(cmdCtxLogger zerolog.Logger, opts *ConfigOpts) ([]string, error) {
 | 
					func (command *Command) RunCmd(cmdCtxLogger zerolog.Logger, opts *ConfigOpts) ([]string, error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
@@ -53,9 +55,9 @@ func (command *Command) RunCmd(cmdCtxLogger zerolog.Logger, opts *ConfigOpts) ([
 | 
				
			|||||||
		command.Type = strings.TrimSpace(command.Type)
 | 
							command.Type = strings.TrimSpace(command.Type)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if command.Type != "" {
 | 
							if command.Type != "" {
 | 
				
			||||||
			cmdCtxLogger.Info().Str("Command", fmt.Sprintf("Running script %s on host %s", command.Cmd, *command.Host)).Send()
 | 
								cmdCtxLogger.Info().Str("Command", fmt.Sprintf("Running script %s on host %s", command.Name, *command.Host)).Send()
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			cmdCtxLogger.Info().Str("Command", fmt.Sprintf("Running command %s %s on host %s", command.Cmd, ArgsStr, *command.Host)).Send()
 | 
								cmdCtxLogger.Info().Str("Command", fmt.Sprintf("Running command %s on host %s", command.Name, *command.Host)).Send()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if command.RemoteHost.SshClient == nil {
 | 
							if command.RemoteHost.SshClient == nil {
 | 
				
			||||||
@@ -165,7 +167,7 @@ func (command *Command) RunCmd(cmdCtxLogger zerolog.Logger, opts *ConfigOpts) ([
 | 
				
			|||||||
					outScanner := bufio.NewScanner(&cmdOutBuf)
 | 
										outScanner := bufio.NewScanner(&cmdOutBuf)
 | 
				
			||||||
					for outScanner.Scan() {
 | 
										for outScanner.Scan() {
 | 
				
			||||||
						outMap := make(map[string]interface{})
 | 
											outMap := make(map[string]interface{})
 | 
				
			||||||
						outMap["cmd"] = cmd
 | 
											outMap["cmd"] = command.Name
 | 
				
			||||||
						outMap["output"] = outScanner.Text()
 | 
											outMap["output"] = outScanner.Text()
 | 
				
			||||||
						if str, ok := outMap["output"].(string); ok {
 | 
											if str, ok := outMap["output"].(string); ok {
 | 
				
			||||||
							outputArr = append(outputArr, str)
 | 
												outputArr = append(outputArr, str)
 | 
				
			||||||
@@ -178,7 +180,7 @@ func (command *Command) RunCmd(cmdCtxLogger zerolog.Logger, opts *ConfigOpts) ([
 | 
				
			|||||||
				outScanner := bufio.NewScanner(&cmdOutBuf)
 | 
									outScanner := bufio.NewScanner(&cmdOutBuf)
 | 
				
			||||||
				for outScanner.Scan() {
 | 
									for outScanner.Scan() {
 | 
				
			||||||
					outMap := make(map[string]interface{})
 | 
										outMap := make(map[string]interface{})
 | 
				
			||||||
					outMap["cmd"] = cmd
 | 
										outMap["cmd"] = command.Name
 | 
				
			||||||
					outMap["output"] = outScanner.Text()
 | 
										outMap["output"] = outScanner.Text()
 | 
				
			||||||
					if str, ok := outMap["output"].(string); ok {
 | 
										if str, ok := outMap["output"].(string); ok {
 | 
				
			||||||
						outputArr = append(outputArr, str)
 | 
											outputArr = append(outputArr, str)
 | 
				
			||||||
@@ -288,7 +290,7 @@ func (command *Command) RunCmd(cmdCtxLogger zerolog.Logger, opts *ConfigOpts) ([
 | 
				
			|||||||
		outScanner := bufio.NewScanner(&cmdOutBuf)
 | 
							outScanner := bufio.NewScanner(&cmdOutBuf)
 | 
				
			||||||
		for outScanner.Scan() {
 | 
							for outScanner.Scan() {
 | 
				
			||||||
			outMap := make(map[string]interface{})
 | 
								outMap := make(map[string]interface{})
 | 
				
			||||||
			outMap["cmd"] = cmd
 | 
								outMap["cmd"] = command.Name
 | 
				
			||||||
			outMap["output"] = outScanner.Text()
 | 
								outMap["output"] = outScanner.Text()
 | 
				
			||||||
			if str, ok := outMap["output"].(string); ok {
 | 
								if str, ok := outMap["output"].(string); ok {
 | 
				
			||||||
				outputArr = append(outputArr, str)
 | 
									outputArr = append(outputArr, str)
 | 
				
			||||||
@@ -297,14 +299,14 @@ func (command *Command) RunCmd(cmdCtxLogger zerolog.Logger, opts *ConfigOpts) ([
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			cmdCtxLogger.Error().Err(fmt.Errorf("error when running cmd: %s: %w", command.Cmd, err)).Send()
 | 
								cmdCtxLogger.Error().Err(fmt.Errorf("error when running cmd: %s: %w", command.Name, err)).Send()
 | 
				
			||||||
			return outputArr, err
 | 
								return outputArr, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		var err error
 | 
							var err error
 | 
				
			||||||
		if command.Shell != "" {
 | 
							if command.Shell != "" {
 | 
				
			||||||
			cmdCtxLogger.Info().Str("Command", fmt.Sprintf("Running command %s %s on local machine in %s", command.Cmd, ArgsStr, command.Shell)).Send()
 | 
								cmdCtxLogger.Info().Str("Command", fmt.Sprintf("Running command %s on local machine in %s", command.Name, command.Shell)).Send()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			ArgsStr = fmt.Sprintf("%s %s", command.Cmd, ArgsStr)
 | 
								ArgsStr = fmt.Sprintf("%s %s", command.Cmd, ArgsStr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -330,7 +332,7 @@ func (command *Command) RunCmd(cmdCtxLogger zerolog.Logger, opts *ConfigOpts) ([
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			for outScanner.Scan() {
 | 
								for outScanner.Scan() {
 | 
				
			||||||
				outMap := make(map[string]interface{})
 | 
									outMap := make(map[string]interface{})
 | 
				
			||||||
				outMap["cmd"] = command.Cmd
 | 
									outMap["cmd"] = command.Name
 | 
				
			||||||
				outMap["output"] = outScanner.Text()
 | 
									outMap["output"] = outScanner.Text()
 | 
				
			||||||
				if str, ok := outMap["output"].(string); ok {
 | 
									if str, ok := outMap["output"].(string); ok {
 | 
				
			||||||
					outputArr = append(outputArr, str)
 | 
										outputArr = append(outputArr, str)
 | 
				
			||||||
@@ -339,13 +341,13 @@ func (command *Command) RunCmd(cmdCtxLogger zerolog.Logger, opts *ConfigOpts) ([
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				cmdCtxLogger.Error().Err(fmt.Errorf("error when running cmd %s: %w", command.Cmd, err)).Send()
 | 
									cmdCtxLogger.Error().Err(fmt.Errorf("error when running cmd %s: %w", command.Name, err)).Send()
 | 
				
			||||||
				return outputArr, err
 | 
									return outputArr, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return outputArr, nil
 | 
								return outputArr, nil
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		cmdCtxLogger.Info().Str("Command", fmt.Sprintf("Running command %s %s on local machine", command.Cmd, ArgsStr)).Send()
 | 
							cmdCtxLogger.Info().Str("Command", fmt.Sprintf("Running command %s on local machine", command.Name)).Send()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		localCMD := exec.Command(command.Cmd, command.Args...)
 | 
							localCMD := exec.Command(command.Cmd, command.Args...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -379,7 +381,7 @@ func (command *Command) RunCmd(cmdCtxLogger zerolog.Logger, opts *ConfigOpts) ([
 | 
				
			|||||||
			cmdCtxLogger.Info().Fields(outMap).Send()
 | 
								cmdCtxLogger.Info().Fields(outMap).Send()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			cmdCtxLogger.Error().Err(fmt.Errorf("error when running cmd %s: %w", command.Cmd, err)).Send()
 | 
								cmdCtxLogger.Error().Err(fmt.Errorf("error when running cmd %s: %w", command.Name, err)).Send()
 | 
				
			||||||
			return outputArr, err
 | 
								return outputArr, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -388,9 +390,9 @@ func (command *Command) RunCmd(cmdCtxLogger zerolog.Logger, opts *ConfigOpts) ([
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// cmdListWorker
 | 
					// cmdListWorker
 | 
				
			||||||
func cmdListWorker(msgTemps *msgTemplates, jobs <-chan *CmdList, results chan<- string, opts *ConfigOpts) {
 | 
					func cmdListWorker(msgTemps *msgTemplates, jobs <-chan *CmdList, results chan<- string, opts *ConfigOpts) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
	// iterate over list to run
 | 
						// iterate over list to run
 | 
				
			||||||
	for list := range jobs {
 | 
						for list := range jobs {
 | 
				
			||||||
 | 
							res := CmdListResults{}
 | 
				
			||||||
		fieldsMap := make(map[string]interface{})
 | 
							fieldsMap := make(map[string]interface{})
 | 
				
			||||||
		fieldsMap["list"] = list.Name
 | 
							fieldsMap["list"] = list.Name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -401,9 +403,10 @@ func cmdListWorker(msgTemps *msgTemplates, jobs <-chan *CmdList, results chan<-
 | 
				
			|||||||
		var outStructArr []outStruct // stores output messages
 | 
							var outStructArr []outStruct // stores output messages
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for _, cmd := range list.Order {
 | 
							for _, cmd := range list.Order {
 | 
				
			||||||
			currentCmd := opts.Cmds[cmd].Cmd
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			fieldsMap["cmd"] = opts.Cmds[cmd].Cmd
 | 
								currentCmd := opts.Cmds[cmd].Name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								fieldsMap["cmd"] = opts.Cmds[cmd].Name
 | 
				
			||||||
			cmdToRun := opts.Cmds[cmd]
 | 
								cmdToRun := opts.Cmds[cmd]
 | 
				
			||||||
			cmdLog.Fields(fieldsMap).Send()
 | 
								cmdLog.Fields(fieldsMap).Send()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -418,12 +421,13 @@ func cmdListWorker(msgTemps *msgTemplates, jobs <-chan *CmdList, results chan<-
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			outputArr, runOutErr := cmdToRun.RunCmd(cmdLogger, opts)
 | 
								outputArr, runOutErr := cmdToRun.RunCmd(cmdLogger, opts)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if list.NotifyConfig != nil {
 | 
								if list.NotifyConfig != nil {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// check if the command output should be included
 | 
									// check if the command output should be included
 | 
				
			||||||
				if cmdToRun.GetOutput || list.GetOutput {
 | 
									if cmdToRun.GetOutput || list.GetOutput {
 | 
				
			||||||
					outputStruct := outStruct{
 | 
										outputStruct := outStruct{
 | 
				
			||||||
						CmdName:     cmd,
 | 
											CmdName:     cmdToRun.Name,
 | 
				
			||||||
						CmdExecuted: currentCmd,
 | 
											CmdExecuted: currentCmd,
 | 
				
			||||||
						Output:      outputArr,
 | 
											Output:      outputArr,
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
@@ -434,6 +438,7 @@ func cmdListWorker(msgTemps *msgTemplates, jobs <-chan *CmdList, results chan<-
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			count++
 | 
								count++
 | 
				
			||||||
			if runOutErr != nil {
 | 
								if runOutErr != nil {
 | 
				
			||||||
 | 
									res.ErrCmd = cmd
 | 
				
			||||||
				if list.NotifyConfig != nil {
 | 
									if list.NotifyConfig != nil {
 | 
				
			||||||
					var errMsg bytes.Buffer
 | 
										var errMsg bytes.Buffer
 | 
				
			||||||
					errStruct := make(map[string]interface{})
 | 
										errStruct := make(map[string]interface{})
 | 
				
			||||||
@@ -466,8 +471,9 @@ func cmdListWorker(msgTemps *msgTemplates, jobs <-chan *CmdList, results chan<-
 | 
				
			|||||||
				break
 | 
									break
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if count == len(list.Order) {
 | 
					 | 
				
			||||||
				cmdsRan = append(cmdsRan, cmd)
 | 
									cmdsRan = append(cmdsRan, cmd)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if count == len(list.Order) {
 | 
				
			||||||
					var successMsg bytes.Buffer
 | 
										var successMsg bytes.Buffer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					// if notification config is not nil, and NotifyOnSuccess is true or GetOuput is true,
 | 
										// if notification config is not nil, and NotifyOnSuccess is true or GetOuput is true,
 | 
				
			||||||
@@ -487,19 +493,17 @@ func cmdListWorker(msgTemps *msgTemplates, jobs <-chan *CmdList, results chan<-
 | 
				
			|||||||
							break
 | 
												break
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						err := list.NotifyConfig.Send(context.Background(), fmt.Sprintf("List %s succeded", list.Name), successMsg.String())
 | 
											err := list.NotifyConfig.Send(context.Background(), fmt.Sprintf("List %s succeeded", list.Name), successMsg.String())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						if err != nil {
 | 
											if err != nil {
 | 
				
			||||||
							opts.Logger.Err(err).Send()
 | 
												opts.Logger.Err(err).Send()
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				} else {
 | 
					 | 
				
			||||||
					cmdsRan = append(cmdsRan, cmd)
 | 
					 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		results <- "done"
 | 
							results <- res.ErrCmd
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -534,8 +538,20 @@ func (opts *ConfigOpts) RunListConfig(cron string) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	close(listChan)
 | 
						close(listChan)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for a := 1; a <= configListsLen; a++ {
 | 
						for a := 0; a <= configListsLen; a++ {
 | 
				
			||||||
		<-results
 | 
							l := <-results
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							opts.Logger.Debug().Msg(l)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if l != "" {
 | 
				
			||||||
 | 
								// execute error hooks
 | 
				
			||||||
 | 
								opts.Logger.Debug().Msg("hooks are working")
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								// execute success hooks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// execute final hooks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	opts.closeHostConnections()
 | 
						opts.closeHostConnections()
 | 
				
			||||||
@@ -550,7 +566,14 @@ func (config *ConfigOpts) ExecuteCmds(opts *ConfigOpts) {
 | 
				
			|||||||
		_, runErr := cmdToRun.RunCmd(cmdLogger, opts)
 | 
							_, runErr := cmdToRun.RunCmd(cmdLogger, opts)
 | 
				
			||||||
		if runErr != nil {
 | 
							if runErr != nil {
 | 
				
			||||||
			opts.Logger.Err(runErr).Send()
 | 
								opts.Logger.Err(runErr).Send()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ExecuteHooks(*cmdToRun, "error", opts)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ExecuteHooks(*cmdToRun, "success", opts)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ExecuteHooks(*cmdToRun, "final", opts)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	opts.closeHostConnections()
 | 
						opts.closeHostConnections()
 | 
				
			||||||
@@ -593,3 +616,17 @@ func (c *ConfigOpts) closeHostConnections() {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func ExecuteHooks(cmd Command, hookType string, opts *ConfigOpts) {
 | 
				
			||||||
 | 
						switch hookType {
 | 
				
			||||||
 | 
						case "error":
 | 
				
			||||||
 | 
							for _, v := range cmd.Hooks.Error {
 | 
				
			||||||
 | 
								errCmd := opts.Cmds[v]
 | 
				
			||||||
 | 
								cmdLogger := opts.Logger.With().
 | 
				
			||||||
 | 
									Str("backy-cmd", v).
 | 
				
			||||||
 | 
									Logger()
 | 
				
			||||||
 | 
								errCmd.RunCmd(cmdLogger, opts)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -245,6 +245,7 @@ func ReadConfig(opts *ConfigOpts) *ConfigOpts {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				cmdListFilePath := path.Clean(opts.CmdListFile)
 | 
									cmdListFilePath := path.Clean(opts.CmdListFile)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// if path is not absolute, check config directory
 | 
				
			||||||
				if !strings.HasPrefix(cmdListFilePath, "/") {
 | 
									if !strings.HasPrefix(cmdListFilePath, "/") {
 | 
				
			||||||
					opts.CmdListFile = path.Join(backyConfigFileDir, cmdListFilePath)
 | 
										opts.CmdListFile = path.Join(backyConfigFileDir, cmdListFilePath)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -259,7 +260,7 @@ func ReadConfig(opts *ConfigOpts) *ConfigOpts {
 | 
				
			|||||||
					logging.ExitWithMSG(fmt.Sprintf("error loading config: %v", err), 1, &opts.Logger)
 | 
										logging.ExitWithMSG(fmt.Sprintf("error loading config: %v", err), 1, &opts.Logger)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				log.Info().Str("lists config file", opts.CmdListFile).Send()
 | 
									log.Info().Str("using lists config file", opts.CmdListFile).Send()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -269,7 +270,7 @@ func ReadConfig(opts *ConfigOpts) *ConfigOpts {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	var cmdNotFoundSliceErr []error
 | 
						var cmdNotFoundSliceErr []error
 | 
				
			||||||
	for cmdListName, cmdList := range opts.CmdConfigLists {
 | 
						for cmdListName, cmdList := range opts.CmdConfigLists {
 | 
				
			||||||
		if opts.useCron {
 | 
							if opts.cronEnabled {
 | 
				
			||||||
			cron := strings.TrimSpace(cmdList.Cron)
 | 
								cron := strings.TrimSpace(cmdList.Cron)
 | 
				
			||||||
			if cron == "" {
 | 
								if cron == "" {
 | 
				
			||||||
				delete(opts.CmdConfigLists, cmdListName)
 | 
									delete(opts.CmdConfigLists, cmdListName)
 | 
				
			||||||
@@ -291,23 +292,20 @@ func ReadConfig(opts *ConfigOpts) *ConfigOpts {
 | 
				
			|||||||
		cmdNotFoundErrorLog.Errs("commands not found", cmdNotFoundSliceErr).Send()
 | 
							cmdNotFoundErrorLog.Errs("commands not found", cmdNotFoundSliceErr).Send()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if opts.useCron && (len(opts.CmdConfigLists) == 0) {
 | 
						if opts.cronEnabled && (len(opts.CmdConfigLists) == 0) {
 | 
				
			||||||
		logging.ExitWithMSG("No cron fields detected in any command lists", 1, nil)
 | 
							logging.ExitWithMSG("No cron fields detected in any command lists", 1, nil)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for c := range opts.Cmds {
 | 
						// process commands
 | 
				
			||||||
		if opts.executeCmds != nil && !contains(opts.executeCmds, c) {
 | 
						if err := processCmds(opts); err != nil {
 | 
				
			||||||
			delete(opts.Cmds, c)
 | 
							log.Panic().Err(err).Send()
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(opts.executeLists) > 0 {
 | 
					 | 
				
			||||||
	for l := range opts.CmdConfigLists {
 | 
						for l := range opts.CmdConfigLists {
 | 
				
			||||||
		if !contains(opts.executeLists, l) {
 | 
							if !contains(opts.executeLists, l) {
 | 
				
			||||||
			delete(opts.CmdConfigLists, l)
 | 
								delete(opts.CmdConfigLists, l)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if backyKoanf.Exists("notifications") {
 | 
						if backyKoanf.Exists("notifications") {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -317,23 +315,8 @@ func ReadConfig(opts *ConfigOpts) *ConfigOpts {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, cmd := range opts.Cmds {
 | 
					 | 
				
			||||||
		if cmd.Host != nil {
 | 
					 | 
				
			||||||
			host, hostFound := opts.Hosts[*cmd.Host]
 | 
					 | 
				
			||||||
			if hostFound {
 | 
					 | 
				
			||||||
				cmd.RemoteHost = host
 | 
					 | 
				
			||||||
				cmd.RemoteHost.Host = host.Host
 | 
					 | 
				
			||||||
				if host.HostName != "" {
 | 
					 | 
				
			||||||
					cmd.RemoteHost.HostName = host.HostName
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				opts.Hosts[*cmd.Host] = &Host{Host: *cmd.Host}
 | 
					 | 
				
			||||||
				cmd.RemoteHost = &Host{Host: *cmd.Host}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	opts.SetupNotify()
 | 
						opts.SetupNotify()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := opts.setupVault(); err != nil {
 | 
						if err := opts.setupVault(); err != nil {
 | 
				
			||||||
		log.Err(err).Send()
 | 
							log.Err(err).Send()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -460,3 +443,94 @@ func GetVaultKey(str string, opts *ConfigOpts, log zerolog.Logger) string {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	return value
 | 
						return value
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func processCmds(opts *ConfigOpts) error {
 | 
				
			||||||
 | 
						// process commands
 | 
				
			||||||
 | 
						for cmdName, cmd := range opts.Cmds {
 | 
				
			||||||
 | 
							cmd.hookRefs = map[string]map[string]*Command{}
 | 
				
			||||||
 | 
							cmd.hookRefs["error"] = map[string]*Command{}
 | 
				
			||||||
 | 
							cmd.hookRefs["success"] = map[string]*Command{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if cmd.Name == "" {
 | 
				
			||||||
 | 
								cmd.Name = cmdName
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// println("Cmd.Name = " + cmd.Name)
 | 
				
			||||||
 | 
							hooks := cmd.Hooks
 | 
				
			||||||
 | 
							// resolve hooks
 | 
				
			||||||
 | 
							if hooks != nil {
 | 
				
			||||||
 | 
								opts.Logger.Debug().Msg("Hooks found")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								errHook, hookRefs, processHookErr := processHooks(hooks.Error, opts.Cmds, "error")
 | 
				
			||||||
 | 
								if !processHookErr {
 | 
				
			||||||
 | 
									return fmt.Errorf("error in command %s hook list: hook command %s not found", cmd.Name, errHook)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								cmd.hookRefs["error"] = hookRefs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								successHook, SuccessHookRefs, processHookSuccess := processHooks(hooks.Error, opts.Cmds, "error")
 | 
				
			||||||
 | 
								if !processHookSuccess {
 | 
				
			||||||
 | 
									return fmt.Errorf("error in command %s hook list: hook command %s not found", cmd.Name, successHook)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								cmd.hookRefs["success"] = SuccessHookRefs
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// resolve hosts
 | 
				
			||||||
 | 
							if cmd.Host != nil {
 | 
				
			||||||
 | 
								host, hostFound := opts.Hosts[*cmd.Host]
 | 
				
			||||||
 | 
								if hostFound {
 | 
				
			||||||
 | 
									cmd.RemoteHost = host
 | 
				
			||||||
 | 
									cmd.RemoteHost.Host = host.Host
 | 
				
			||||||
 | 
									if host.HostName != "" {
 | 
				
			||||||
 | 
										cmd.RemoteHost.HostName = host.HostName
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									opts.Hosts[*cmd.Host] = &Host{Host: *cmd.Host}
 | 
				
			||||||
 | 
									cmd.RemoteHost = &Host{Host: *cmd.Host}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// processHooks evaluates if hooks are valid Commands
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Takes the following arguments:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//  1. a []string of hooks
 | 
				
			||||||
 | 
					//  2. a map of Commands as arguments
 | 
				
			||||||
 | 
					//  3. a string hookType, must be the hook type
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The cmds.hookRef is modified in this function.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Returns the following:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//  1. command string
 | 
				
			||||||
 | 
					//  2. each hook type's command map
 | 
				
			||||||
 | 
					//  2. a bool which determines if the command is valid
 | 
				
			||||||
 | 
					func processHooks(hooks []string, cmds map[string]*Command, hookType string) (hook string, hookRefs map[string]*Command, hookCmdFound bool) {
 | 
				
			||||||
 | 
						// fmt.Printf("%v\n", hooks)
 | 
				
			||||||
 | 
						// for _, v := range cmds {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 	fmt.Printf("CmdName=%v\n", v.Name)
 | 
				
			||||||
 | 
						// 	fmt.Printf("Cmd=%v\n", v.Cmd)
 | 
				
			||||||
 | 
						// }
 | 
				
			||||||
 | 
						// initialize hook type
 | 
				
			||||||
 | 
						hookRefs = make(map[string]*Command)
 | 
				
			||||||
 | 
						// hookRefs[hookType] = map[string]*Command{}
 | 
				
			||||||
 | 
						for _, hook = range hooks {
 | 
				
			||||||
 | 
							var hookCmd *Command
 | 
				
			||||||
 | 
							// TODO: match by Command.Name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							hookCmd, hookCmdFound = cmds[hook]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if !hookCmdFound {
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							hookRefs[hook] = hookCmd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Recursive, decide if this is good
 | 
				
			||||||
 | 
							// if hookCmd.hookRefs == nil {
 | 
				
			||||||
 | 
							// }
 | 
				
			||||||
 | 
							// hookRef[hookType][h] = hookCmd
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,17 +43,24 @@ type (
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Command struct {
 | 
						Command struct {
 | 
				
			||||||
 | 
							Name string `yaml:"name,omitempty"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// command to run
 | 
							// command to run
 | 
				
			||||||
		Cmd string `yaml:"cmd"`
 | 
							Cmd string `yaml:"cmd"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Possible values: script, scriptFile
 | 
							// Possible values: script, scriptFile
 | 
				
			||||||
		// If blank, it is regualar command.
 | 
							// If blank, it is regular command.
 | 
				
			||||||
		Type string `yaml:"type"`
 | 
							Type string `yaml:"type,omitempty"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// host on which to run cmd
 | 
							// host on which to run cmd
 | 
				
			||||||
		Host *string `yaml:"host,omitempty"`
 | 
							Host *string `yaml:"host,omitempty"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Hooks are for running commands on certain events
 | 
				
			||||||
 | 
							Hooks *Hooks `yaml:"hooks,omitempty"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// hook refs are internal references of commands for each hook type
 | 
				
			||||||
 | 
							hookRefs map[string]map[string]*Command
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
			Shell specifies which shell to run the command in, if any.
 | 
								Shell specifies which shell to run the command in, if any.
 | 
				
			||||||
			Not applicable when host is defined.
 | 
								Not applicable when host is defined.
 | 
				
			||||||
@@ -123,7 +130,7 @@ type (
 | 
				
			|||||||
		CmdListFile string
 | 
							CmdListFile string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// use command lists using cron
 | 
							// use command lists using cron
 | 
				
			||||||
		useCron bool
 | 
							cronEnabled bool
 | 
				
			||||||
		// Holds commands to execute for the exec command
 | 
							// Holds commands to execute for the exec command
 | 
				
			||||||
		executeCmds []string
 | 
							executeCmds []string
 | 
				
			||||||
		// Holds lists to execute for the backup command
 | 
							// Holds lists to execute for the backup command
 | 
				
			||||||
@@ -188,4 +195,17 @@ type (
 | 
				
			|||||||
		Commands []string
 | 
							Commands []string
 | 
				
			||||||
		Hosts    []string
 | 
							Hosts    []string
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Hooks struct {
 | 
				
			||||||
 | 
							Error        []string `yaml:"error,omitempty"`
 | 
				
			||||||
 | 
							SuccessHooks []string `yaml:"success,omitempty"`
 | 
				
			||||||
 | 
							FinalHooks   []string `yaml:"final,omitempty"`
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						CmdListResults struct {
 | 
				
			||||||
 | 
							// name of the list
 | 
				
			||||||
 | 
							ListName string
 | 
				
			||||||
 | 
							// command that caused the list to fail
 | 
				
			||||||
 | 
							ErrCmd string
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -56,10 +56,10 @@ func SetCmdsToSearch(cmds []string) BackyOptionFunc {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// UseCron enables the execution of command lists at specified times
 | 
					// cronEnabled enables the execution of command lists at specified times
 | 
				
			||||||
func UseCron() BackyOptionFunc {
 | 
					func CronEnabled() BackyOptionFunc {
 | 
				
			||||||
	return func(bco *ConfigOpts) {
 | 
						return func(bco *ConfigOpts) {
 | 
				
			||||||
		bco.useCron = true
 | 
							bco.cronEnabled = true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user