Compare commits

..

2 Commits

170
backup.go
View File

@ -13,47 +13,75 @@ import (
"git.andrewnw.xyz/CyberShell/backy/pkg/backy" "git.andrewnw.xyz/CyberShell/backy/pkg/backy"
"github.com/kevinburke/ssh_config" "github.com/kevinburke/ssh_config"
"github.com/spf13/viper"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
) )
// const logFile = "backy.log"
type backupCommand struct { type backupCommand struct {
// command to run // command to run
cmd string Cmd string
// host on which to run cmd // host on which to run cmd
host string Host string
// 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 not local // Not applicable when host is not local
shell string Shell string
// path to the command
path string
// cmdArgs is an array that holds the arguments to cmd // cmdArgs is an array that holds the arguments to cmd
cmdArgs []string CmdArgs []string
} }
var remoteHost *backy.Host // type config struct {
// Commands struct {
// backupCommand `mapstructure:",squash"`
// }
// }
var testCmd = &backupCommand{
Cmd: "hostname",
Shell: "bash",
CmdArgs: []string{},
}
var remoteHost backy.Host
func main() { func main() {
var test = true
if test {
readConfigFile()
} else {
remoteHost.User = "root"
testCmd.runCmd()
// shutdownEmailSvr.runCmd()
// backupEmailSvrRestic.runCmd()
// backupEmailSvrRsync.runCmd()
// startEmailSvr.runCmd()
}
} }
func (command *backupCommand) runCmd() { func (command *backupCommand) runCmd() {
var cmdArgsStr string var cmdArgsStr string
for _, v := range command.cmdArgs { for _, v := range command.CmdArgs {
cmdArgsStr += fmt.Sprintf(" %s", v) cmdArgsStr += fmt.Sprintf(" %s", v)
} }
fmt.Printf("\n\nRunning command: " + command.cmd + " " + cmdArgsStr + " on host " + command.host + "...\n\n")
if command.host != "local" { fmt.Printf("\n\nRunning command: " + command.Cmd + " " + cmdArgsStr + " on host " + command.Host + "...\n\n")
if command.Host != "local" {
remoteHost.Port = 22 remoteHost.Port = 22
remoteHost.Host = command.host remoteHost.Host = command.Host
sshc, err := connectToSSHHost(remoteHost) sshc, err := connectToSSHHost(&remoteHost)
if err != nil { if err != nil {
panic(fmt.Errorf("ssh dial: %w", err)) panic(fmt.Errorf("ssh dial: %w", err))
} }
@ -64,8 +92,8 @@ func (command *backupCommand) runCmd() {
} }
defer s.Close() defer s.Close()
cmd := command.cmd cmd := command.Cmd
for _, a := range command.cmdArgs { for _, a := range command.CmdArgs {
cmd += " " + a cmd += " " + a
} }
@ -76,31 +104,31 @@ func (command *backupCommand) runCmd() {
if err != nil { if err != nil {
panic(fmt.Errorf("error when running cmd " + cmd + "\n Error: " + err.Error())) panic(fmt.Errorf("error when running cmd " + cmd + "\n Error: " + err.Error()))
} }
// fmt.Printf("Output: %s\n", string(output))
} else { } else {
// shell := "/bin/bash" // shell := "/bin/bash"
var err error var err error
if command.shell != "" { if command.Shell != "" {
cmdArgsStr = fmt.Sprintf("%s %s", command.cmd, cmdArgsStr) cmdArgsStr = fmt.Sprintf("%s %s", command.Cmd, cmdArgsStr)
localCMD := exec.Command(command.shell, "-c", cmdArgsStr) localCMD := exec.Command(command.Shell, "-c", cmdArgsStr)
var stdoutBuf, stderrBuf bytes.Buffer var stdoutBuf, stderrBuf bytes.Buffer
localCMD.Stdout = io.MultiWriter(os.Stdout, &stdoutBuf) localCMD.Stdout = io.MultiWriter(os.Stdout, &stdoutBuf)
localCMD.Stderr = io.MultiWriter(os.Stderr, &stderrBuf) localCMD.Stderr = io.MultiWriter(os.Stderr, &stderrBuf)
err = localCMD.Run() err = localCMD.Run()
if err != nil { if err != nil {
panic(fmt.Errorf("error when running cmd: %s: %w", command.cmd, err)) panic(fmt.Errorf("error when running cmd: %s: %w", command.Cmd, err))
} }
return
} }
// localCMD := exec.Command(command.cmd, command.args...) localCMD := exec.Command(command.Cmd, command.CmdArgs...)
// var stdoutBuf, stderrBuf bytes.Buffer var stdoutBuf, stderrBuf bytes.Buffer
// localCMD.Stdout = io.MultiWriter(os.Stdout, &stdoutBuf) localCMD.Stdout = io.MultiWriter(os.Stdout, &stdoutBuf)
// localCMD.Stderr = io.MultiWriter(os.Stderr, &stderrBuf) localCMD.Stderr = io.MultiWriter(os.Stderr, &stderrBuf)
// err = localCMD.Run() err = localCMD.Run()
if err != nil { if err != nil {
panic(fmt.Errorf("error when running cmd: %s: %w", command.cmd, err)) panic(fmt.Errorf("error when running cmd: %s: %w", command.Cmd, err))
} }
// fmt.Printf("%s\n", string(output)) // fmt.Printf("%s\n", string(output))
} }
@ -147,7 +175,7 @@ func connectToSSHHost(remoteConfig *backy.Host) (*ssh.Client, error) {
panic(fmt.Errorf("parse private key: %w", err)) panic(fmt.Errorf("parse private key: %w", err))
} }
sshConfig := &ssh.ClientConfig{ sshConfig := &ssh.ClientConfig{
User: "root", User: remoteHost.User,
Auth: []ssh.AuthMethod{ssh.PublicKeys(signer)}, Auth: []ssh.AuthMethod{ssh.PublicKeys(signer)},
HostKeyCallback: ssh.InsecureIgnoreHostKey(), HostKeyCallback: ssh.InsecureIgnoreHostKey(),
} }
@ -158,3 +186,91 @@ func connectToSSHHost(remoteConfig *backy.Host) (*ssh.Client, error) {
} }
return sshc, connectErr return sshc, connectErr
} }
func readConfigFile() {
viper.SetConfigName("backy") // name of config file (without extension)
viper.SetConfigType("yaml") // REQUIRED if the config file does not have the extension in the name
viper.AddConfigPath("$HOME/.config/backy") // call multiple times to add many search paths
viper.AddConfigPath(".") // optionally look for config in the working directory
err := viper.ReadInConfig() // Find and read the config file
if err != nil { // Handle errors reading the config file
panic(fmt.Errorf("fatal error config file: %w", err))
}
// if err := viper.ReadInConfig(); err != nil {
// if _, ok := err.(viper.ConfigFileNotFoundError); ok {
// // Config file not found; ignore error if desired
// } else {
// // Config file was found but another error was produced
// }
// }
// Config file found and successfully parsed
// viper.WriteConfig() // writes current config to predefined path set by 'viper.AddConfigPath()' and 'viper.SetConfigName'
// err = viper.Unmarshal(&C)
// if err != nil {
// panic(fmt.Errorf("unable to decode into struct, %v", err))
// }
commandsMap := viper.GetStringMapString("commands")
var cmdNames []string
for k := range commandsMap {
cmdNames = append(cmdNames, k)
}
var cmdStructs []backupCommand
for _, cmdName := range cmdNames {
var backupCmdStruct backupCommand
println(cmdName)
subCmd := viper.Sub(getNestedConfig("commands", cmdName))
hostSet := subCmd.IsSet("host")
host := subCmd.GetString("host")
cmdSet := subCmd.IsSet("cmd")
cmd := subCmd.GetString("cmd")
cmdArgsSet := subCmd.IsSet("cmdargs")
cmdArgs := subCmd.GetStringSlice("cmdargs")
if hostSet {
println("Host:")
println(host)
backupCmdStruct.Host = host
} else {
println("Host is not set")
}
if cmdSet {
println("Cmd:")
println(cmd)
backupCmdStruct.Cmd = cmd
} else {
println("Cmd is not set")
}
if cmdArgsSet {
println("CmdArgs:")
for _, arg := range cmdArgs {
println(arg)
}
backupCmdStruct.CmdArgs = cmdArgs
} else {
println("CmdArgs is not set")
}
cmdStructs = append(cmdStructs, backupCmdStruct)
for _, cmd := range cmdStructs {
fmt.Printf("Cmd is %s\n", cmd.Cmd)
fmt.Printf("Host is %s\n", cmd.Host)
}
}
cmdOrder := viper.GetStringMapStringSlice("cmd-order")
for cmd, orderSlice := range cmdOrder {
println("Cmd name: ", cmd)
println("Cmd order: ")
for _, v := range orderSlice {
println(v)
}
}
}
func getNestedConfig(nestedConfig, key string) string {
return fmt.Sprintf("%s.%s", nestedConfig, key)
}