Skip to content

Commit

Permalink
Merge pull request #11 from APoniatowski/Dev
Browse files Browse the repository at this point in the history
Dev - Sudo and knownhosts additions
  • Loading branch information
APoniatowski authored Jan 17, 2020
2 parents 49ee5ce + dde84c7 commit 001aa09
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 33 deletions.
8 changes: 4 additions & 4 deletions channelreaderlib/channelreaderlib.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ import (
"github.com/superhawk610/bar"
)

// channelReaderAll Function to read channel until it is closed (all servers only)
// ChannelReaderAll Function to read channel until it is closed (all servers only)
func ChannelReaderAll(channel <-chan string, wg *sync.WaitGroup) {
successcount := 0
barp := bar.New(yamlparser.Waittotal)
for i := 0; i < yamlparser.Waittotal; i++ {
for message := range channel {
if message == "Ok\n" {
if message == "OK\n" {
barp.Tick()
successcount++
} else {
Expand All @@ -26,7 +26,7 @@ func ChannelReaderAll(channel <-chan string, wg *sync.WaitGroup) {
defer barp.Done()
}

// channelReaderGroups Function to read channel until it is closed (groups only)
// ChannelReaderGroups Function to read channel until it is closed (groups only)
func ChannelReaderGroups(channel <-chan string, wg *sync.WaitGroup) {
loopcountval := len(yamlparser.ServersPerGroup) - 1
var totalsuccesscount int
Expand All @@ -35,7 +35,7 @@ func ChannelReaderGroups(channel <-chan string, wg *sync.WaitGroup) {
barp := bar.New(yamlparser.ServersPerGroup[i])
for im := 0; im < yamlparser.ServersPerGroup[i]; im++ {
for message := range channel {
if message == "Ok\n" {
if message == "OK\n" {
barp.Tick()
successcount++
totalsuccesscount++
Expand Down
6 changes: 5 additions & 1 deletion config/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,26 @@ ServerGroup1:
Password: password11
Key_Path: /path/to/key
Port: 22
Need_Sudo: false
Server12:
FQDN: hostname12.whatever.com
Username: user12
Password: password12
Key_Path: /path/to/key
Port: 223
Need_Sudo: true
ServerGroup2:
Server21:
FQDN: hostname21.whatever.com
Username: user21
Password: password21
Key_Path: /path/to/key
Port: 2233
Need_Sudo: false
Server22:
FQDN: hostname22.whatever.com
Username: user22
Password: password22
Key_Path: /path/to/key
Port:
Port:
Need_Sudo: true
96 changes: 68 additions & 28 deletions sshlib/sshlib.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package sshlib

import (
"bufio"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"path/filepath"
"strconv"
"strings"
"sync"
"time"

Expand All @@ -15,15 +16,13 @@ import (

"github.com/APoniatowski/GoSSH/channelreaderlib"
"github.com/APoniatowski/GoSSH/loggerlib"
knownhosts "golang.org/x/crypto/ssh/knownhosts"
)

// executeCommand function to run a command on remote servers. Arguments will run through this function and will take strings,
func executeCommand(servername string, cmd string, connection *ssh.Client) string {
func executeCommand(servername string, cmd string, password string, connection *ssh.Client) string {
session, err := connection.NewSession()
loggerlib.GeneralError(err)
defer session.Close()

modes := ssh.TerminalModes{
ssh.ECHO: 0, // disable echoing
ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
Expand All @@ -33,21 +32,48 @@ func executeCommand(servername string, cmd string, connection *ssh.Client) strin
session.Close()
log.Fatal(err)
}

in, err := session.StdinPipe()
if err != nil {
fmt.Println(err)
}
out, err := session.StdoutPipe()
if err != nil {
log.Fatal(err)
}
var validator string
// shellErr := session.Shell()
// if shellErr != nil {
// log.Fatal(shellErr)
// }
terminaloutput, err := session.CombinedOutput(cmd)
var terminaloutput []byte
go func(in io.WriteCloser, out io.Reader, terminaloutput *[]byte) {
var (
line string
read = bufio.NewReader(out)
)
for {
buffer, err := read.ReadByte()
if err != nil {
break
}
*terminaloutput = append(*terminaloutput, buffer)
if buffer == byte('\n') {
line = ""
continue
}
line += string(buffer)
if strings.HasPrefix(line, "[sudo] password for ") && strings.HasSuffix(line, ": ") {
_, err = in.Write([]byte(password + "\n"))
if err != nil {
break
}
}
}
}(in, out, &terminaloutput)
_, err = session.Output(cmd)
if err != nil {
validator = "Failed\n"
validator = "NOK\n"
loggerlib.ErrorLogger(servername, terminaloutput)
} else {
validator = "Ok\n"
validator = "OK\n"
loggerlib.OutputLogger(servername, terminaloutput)
}

return validator
}

Expand All @@ -62,22 +88,29 @@ func connectAndRun(command *string, servername string, fqdn string, username str
loggerlib.GeneralError(err)
authMethodCheck = append(authMethodCheck, ssh.PublicKeys(signer))
}
filepath.Join(os.Getenv("HOME"), ".ssh", "known_hosts")
hostKeyCallback, err := knownhosts.New(filepath.Join(os.Getenv("HOME"), ".ssh", "known_hosts"))
if err != nil {
hostKeyCallback = ssh.InsecureIgnoreHostKey()
}
// hostKeyCallback, err := knownhosts.New(filepath.Join(os.Getenv("HOME"), ".ssh", "known_hosts"))
// if err != nil {
hostKeyCallback := ssh.InsecureIgnoreHostKey()
// }
sshConfig := &ssh.ClientConfig{
User: username,
Auth: authMethodCheck,
HostKeyCallback: hostKeyCallback,
Timeout: 5 * time.Second,
HostKeyAlgorithms: []string{
ssh.KeyAlgoRSA,
ssh.KeyAlgoDSA,
ssh.KeyAlgoECDSA256,
ssh.KeyAlgoECDSA384,
ssh.KeyAlgoECDSA521,
ssh.KeyAlgoED25519,
},
Timeout: 5 * time.Second,
}
connection, err := ssh.Dial("tcp", fqdn+":"+port, sshConfig)
loggerlib.GeneralError(err)
defer connection.Close()
defer wg.Done()
output <- executeCommand(servername, *command, connection)
output <- executeCommand(servername, *command, password, connection)
}

func connectAndRunSeq(command *string, servername string, fqdn string, username string, password string, keypath string, port string) string {
Expand All @@ -90,21 +123,28 @@ func connectAndRunSeq(command *string, servername string, fqdn string, username
loggerlib.GeneralError(err)
authMethodCheck = append(authMethodCheck, ssh.PublicKeys(signer))
}
filepath.Join(os.Getenv("HOME"), ".ssh", "known_hosts")
hostKeyCallback, err := knownhosts.New(filepath.Join(os.Getenv("HOME"), ".ssh", "known_hosts"))
if err != nil {
hostKeyCallback = ssh.InsecureIgnoreHostKey()
}
// hostKeyCallback, err := knownhosts.New(filepath.Join(os.Getenv("HOME"), ".ssh", "known_hosts"))
// if err != nil {
hostKeyCallback := ssh.InsecureIgnoreHostKey()
// }
sshConfig := &ssh.ClientConfig{
User: username,
Auth: authMethodCheck,
HostKeyCallback: hostKeyCallback,
Timeout: 5 * time.Second,
HostKeyAlgorithms: []string{
ssh.KeyAlgoRSA,
ssh.KeyAlgoDSA,
ssh.KeyAlgoECDSA256,
ssh.KeyAlgoECDSA384,
ssh.KeyAlgoECDSA521,
ssh.KeyAlgoED25519,
},
Timeout: 5 * time.Second,
}
connection, err := ssh.Dial("tcp", fqdn+":"+port, sshConfig)
loggerlib.GeneralError(err)
defer connection.Close()
return servername + ": " + executeCommand(servername, *command, connection)
return servername + ": " + executeCommand(servername, *command, password, connection)
}

//=============================== sequential and concurrent functions listed below =============================
Expand Down

0 comments on commit 001aa09

Please sign in to comment.