server.garden privileged automation agent

main.go 3.3KB

    package main import ( "fmt" "os" "os/exec" "os/user" "regexp" "strings" "time" errors "git.sequentialread.com/forest/pkg-errors" "git.sequentialread.com/forest/rootsystem/configuration" "git.sequentialread.com/forest/rootsystem/objectStorage" ) func main() { config, _, err := configuration.LoadConfiguration() if err != nil { panic(errors.Wrap(err, "host-key-poller failed because loadConfiguration() returned")) } storage, err := objectStorage.InitializeObjectStorage(config, false) if err != nil { panic(errors.Wrap(err, "host-key-poller failed to initialize object storage")) } iterations := 0 for iterations < 200 { // waits for a maximum of 200*5 seconds = 1000 seconds iterations++ filename := fmt.Sprintf("rootsystem/known-hosts/%s", os.Args[1]) fmt.Printf("polling for %s...\n", filename) file, notFound, err := storage.Get(filename) if err != nil && !notFound { fmt.Printf("the error was: %s\n", err) } if err == nil && !notFound { lines := strings.Split(string(file.Content), "\n") validLines := []string{} ipAddress := "" for _, line := range lines { if len(strings.Trim(line, "\t \n\r")) > 10 { fields := strings.Split(line, " ") if len(fields) >= 3 { ip := fields[0] hostKeyType := fields[1] base64PublicKey := fields[2] ipValid := regexp.MustCompile("(\\d+\\.)+\\d+").FindString(ip) != "" typeValid := (hostKeyType == "ecdsa-sha2-nistp256" || hostKeyType == "ssh-rsa" || hostKeyType == "ssh-ed25519") base64Valid := regexp.MustCompile("[A-Za-z0-9+/=]+").FindString(base64PublicKey) != "" if ipValid && typeValid && base64Valid { ipAddress = ip validLines = append(validLines, fmt.Sprintf("%s %s %s", ip, hostKeyType, base64PublicKey)) } } } } if len(validLines) > 0 { sshFolder := getCurrentUserSSHFolder() _, err := os.Stat(sshFolder) if err != nil { err := os.Mkdir(sshFolder, 0700) if err != nil { panic(err) } } knownHostsFilename := getKnownHostsFilename() _, err = os.Stat(knownHostsFilename) if err == nil { fmt.Printf("Removing %s from %s:\n", ipAddress, knownHostsFilename) fmt.Printf("ssh-keygen -f %s -R %s\n", knownHostsFilename, ipAddress) process := exec.Command("ssh-keygen", "-f", knownHostsFilename, "-R", ipAddress) err := process.Start() if err != nil { panic(err) } err = process.Wait() if err != nil { panic(err) } } else { fmt.Printf("%s doesn't exist yet, creating it...\n", knownHostsFilename) } file, err := os.OpenFile(knownHostsFilename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600) if err != nil { panic(err) } defer file.Close() fmt.Printf("Writing to %s:\n", knownHostsFilename) for _, line := range validLines { fmt.Println(line) if _, err = file.WriteString(fmt.Sprintf("\n%s", line)); err != nil { panic(err) } } os.Exit(0) } } time.Sleep(time.Second * time.Duration(5)) } panic(errors.New("Timed Out")) } func getCurrentUserSSHFolder() string { user, err := user.Current() if err != nil { panic(errors.Wrap(err, "getKnownHostsFilename(): ")) } return fmt.Sprintf("%s/.ssh", user.HomeDir) } func getKnownHostsFilename() string { return fmt.Sprintf("%s/known_hosts", getCurrentUserSSHFolder()) }