Skip to content

Commit

Permalink
feat: --file
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexanderGrooff committed Jul 30, 2023
1 parent a5464f8 commit 1feec98
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 6 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,14 @@ INFO[0000] testalex.h: j6yt29-testalex-magweb-do.nodes.hypernode.io
$ aboxes run -t theta,testalex.h -c hostname --format "{{.Target}} -> {{.Stdout}}"
INFO[0000] theta -> theta
INFO[0000] testalex.h -> j6yt29-testalex-magweb-do.nodes.hypernode.io

# Prevent shell escaping hell by placing commands in scripts
$ cat testscript.sh
#!/usr/bin/env bash
ip a | grep eth0 | awk '{print $2}' | awk -F '/' '{print $1}'
$ aboxes run -t theta,testalex.h --file ./testscript.sh
INFO[0001] theta: eth0:
1.2.3.4
INFO[0001] testalex.h: eth0:
2.3.4.5
```
6 changes: 4 additions & 2 deletions cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ var runCmd = &cobra.Command{
commands, _ := cmd.Flags().GetStringSlice("command")
outputFile, _ := cmd.Flags().GetString("output")
format, _ := cmd.Flags().GetString("format")
files, _ := cmd.Flags().GetStringSlice("file")

// Execute the commands
executeCommands(targets, commands, outputFile, format)
executeCommands(targets, commands, outputFile, format, files)
},
}

Expand All @@ -29,7 +30,8 @@ func init() {

runCmd.Flags().StringSliceP("target", "t", []string{}, "Target host")
runCmd.Flags().StringSliceP("command", "c", []string{}, "Command to run")
runCmd.Flags().StringP("format", "f", "{{.Target}}: {{.Stdout}}",
runCmd.Flags().StringSliceP("file", "f", []string{}, "Files to run")
runCmd.Flags().StringP("format", "", "{{.Target}}: {{.Stdout}}",
"Output format in Go template syntax. Available fields: Target, Hostname, Stdout, Stderr, Error")
runCmd.Flags().StringP("output", "o", "", "Output file")
}
46 changes: 42 additions & 4 deletions cmd/ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
log "github.com/sirupsen/logrus"
)

func executeCommands(targets []string, commands []string, outputFile string, format string) {
func executeCommands(targets []string, commands []string, outputFile string, format string, files []string) {
// Open output file in append mode
var file *os.File
var err error
Expand All @@ -30,8 +30,8 @@ func executeCommands(targets []string, commands []string, outputFile string, for
ssh := getConfigForHost(target)
// TODO: Use same SSH connection for all commands
for _, command := range commands {
result := RunAndParse(target, command, ssh)
if err != nil {
result := runAndParse(target, command, ssh)
if result.Error != nil {
log.Warn("Error running command on ", target, ": ", err)
continue
}
Expand All @@ -44,12 +44,28 @@ func executeCommands(targets []string, commands []string, outputFile string, for
}
}
}
for _, script := range files {
log.Debug("Running script ", script, " on ", target)
result := runScriptOnHost(target, script, ssh)
if result.Error != nil {
log.Warn("Error running script on ", target, ": ", err)
continue
}
output := result.toString(format)
log.Info(output)
// Write output to file if given
if file != nil {
if _, err := file.WriteString(fmt.Sprintf("%s\n", output)); err != nil {
log.Warn("Error writing to file: ", err)
}
}
}
}(target)
}
wg.Wait()
}

func RunAndParse(target string, command string, ssh *easyssh.MakeConfig) Result {
func runAndParse(target string, command string, ssh *easyssh.MakeConfig) Result {
stdout, stderr, _, err := ssh.Run(command)
return Result{
Target: target,
Expand All @@ -59,3 +75,25 @@ func RunAndParse(target string, command string, ssh *easyssh.MakeConfig) Result
Error: err,
}
}

func runScriptOnHost(target string, script string, ssh *easyssh.MakeConfig) Result {
remotePath := fmt.Sprintf("/tmp/%s", script)
if err := ssh.Scp(script, remotePath); err != nil {
log.Warn("Error copying script to host: ", err)
return Result{
Target: target,
Hostname: ssh.Server,
Error: err,
}
}
cmd := fmt.Sprintf("bash -s < %s", remotePath)
result := runAndParse(target, cmd, ssh)

// Remove script from host in background
go func() {
if _, _, _, err := ssh.Run(fmt.Sprintf("rm %s", remotePath)); err != nil {
log.Warn("Error removing script from host: ", err)
}
}()
return result
}

0 comments on commit 1feec98

Please sign in to comment.