intitial
This commit is contained in:
104
internal/cli/cli.go
Normal file
104
internal/cli/cli.go
Normal file
@@ -0,0 +1,104 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var re = regexp.MustCompile(`\w|\%|^(\+|,|\.|:|\/|\\|=|_|-|[a-z]|[A-Z]|[0-9]|\s)+$`)
|
||||
|
||||
func validateCliArgument(arg string) bool {
|
||||
return re.Match([]byte(arg))
|
||||
}
|
||||
|
||||
func validateCliArguments(args []string) bool {
|
||||
for _, p := range args {
|
||||
if !validateCliArgument(p) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func execNoCheck(ctx context.Context, command string, args []string) (string, string, error) {
|
||||
cmd := exec.CommandContext(ctx, command, args...)
|
||||
cmdStr := cmd.String()
|
||||
|
||||
pStdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return "", cmdStr, err
|
||||
}
|
||||
|
||||
pStderr, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
return "", cmdStr, err
|
||||
}
|
||||
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
return "", cmdStr, err
|
||||
}
|
||||
|
||||
stdout, _ := io.ReadAll(pStdout)
|
||||
stderr, _ := io.ReadAll(pStderr)
|
||||
|
||||
err = cmd.Wait()
|
||||
if err != nil {
|
||||
return "", cmdStr, errors.New(err.Error() + " | " + string(stderr) + " | " + string(stdout))
|
||||
}
|
||||
return string(stdout), cmdStr, nil
|
||||
}
|
||||
|
||||
type Pipe struct {
|
||||
Command string
|
||||
Args []string
|
||||
}
|
||||
|
||||
func (p *Pipe) IsSanatory() bool {
|
||||
return validateCliArguments(p.Args) && validateCliArgument(p.Command)
|
||||
}
|
||||
|
||||
func (p *Pipe) Execute(ctx context.Context) (string, string, error) {
|
||||
if !p.IsSanatory() {
|
||||
return "", "", errors.New("failed to execute cli command: " + p.Command + " " + strings.Join(p.Args, " ") + " some arguments are not allowed")
|
||||
} else {
|
||||
return execNoCheck(ctx, p.Command, p.Args)
|
||||
}
|
||||
}
|
||||
|
||||
func ExecuteCLIPipeLine(ctx context.Context, pipes []Pipe) (string, string, error) {
|
||||
|
||||
pipeLen := len(pipes)
|
||||
if pipeLen == 0 {
|
||||
return "", "", errors.New("failed to execute cli command: no pipes provided")
|
||||
}
|
||||
argLen := 0
|
||||
for _, p := range pipes {
|
||||
if !p.IsSanatory() {
|
||||
return "", "", errors.New("failed to execute cli command: " + p.Command + " " + strings.Join(p.Args, " ") + " some arguments are not allowed")
|
||||
}
|
||||
argLen += len(p.Args) + 1
|
||||
}
|
||||
|
||||
command := "/bin/sh"
|
||||
var args []string = []string{}
|
||||
args = append(args, "-c")
|
||||
pipeLen -= 1
|
||||
|
||||
cmdArg := ""
|
||||
|
||||
for i, p := range pipes {
|
||||
cmdArg += p.Command + " " + strings.Join(p.Args, " ")
|
||||
if i != pipeLen {
|
||||
cmdArg += " | "
|
||||
}
|
||||
}
|
||||
|
||||
args = append(args, cmdArg)
|
||||
|
||||
return execNoCheck(ctx, command, args)
|
||||
}
|
||||
Reference in New Issue
Block a user