From 645b31fa009a745ca00effca4a3e74f189b4a769 Mon Sep 17 00:00:00 2001 From: samiralajmovic Date: Sat, 6 Aug 2022 01:14:35 +0200 Subject: [PATCH 1/4] Fix too many auth connections --- core/run/client.go | 5 ++ core/run/exec.go | 110 ++++++++++----------------------- core/run/ssh.go | 150 ++++++++++++++++++++++++++++++++------------- 3 files changed, 147 insertions(+), 118 deletions(-) diff --git a/core/run/client.go b/core/run/client.go index 171be6c..e5fa56b 100644 --- a/core/run/client.go +++ b/core/run/client.go @@ -28,3 +28,8 @@ type ErrConnect struct { Port uint16 Reason string } + +func (e *ErrConnect) Error() string { + return "" +} + diff --git a/core/run/exec.go b/core/run/exec.go index 21f6e38..0fbf776 100644 --- a/core/run/exec.go +++ b/core/run/exec.go @@ -5,7 +5,6 @@ import ( "golang.org/x/crypto/ssh" "os" "os/signal" - "os/user" "path/filepath" "strconv" "strings" @@ -161,45 +160,6 @@ func (run *Run) SetClients( clientCh chan Client, errCh chan ErrConnect, ) ([]ErrConnect, error) { - globalIdentityFile, globalPassword := getGlobalIdentity(runFlags) - - // Iterate through servers and create a singleton AuthMethod, which is used for - // connecting to all hosts using a identity key. Servers which only use a password - // are not included here and are handled separately. - var identities []Identity - for _, server := range run.Servers { - if server.Local { - continue - } - - var pass *string - if server.Password != nil { - pw, err := dao.EvaluatePassword(*server.Password) - pass = &pw - if err != nil { - errConnect := &ErrConnect{ - Name: server.Name, - User: server.User, - Host: server.Host, - Port: server.Port, - Reason: err.Error(), - } - return []ErrConnect{*errConnect}, nil - } - } - - identities = append(identities, Identity{ - IdentityFile: server.IdentityFile, - Password: pass, - }) - } - - // VerifyHost - authMethod, err := InitAuthMethod(globalIdentityFile, globalPassword, identities) - if err != nil { - return []ErrConnect{}, err - } - createLocalClient := func(server dao.Server, wg *sync.WaitGroup, mu *sync.Mutex) { defer wg.Done() @@ -212,9 +172,10 @@ func (run *Run) SetClients( clientCh <- local } - createRemoteClient := func(server dao.Server, wg *sync.WaitGroup, mu *sync.Mutex) { + createRemoteClient := func(authMethod ssh.AuthMethod, server dao.Server, wg *sync.WaitGroup, mu *sync.Mutex) { defer wg.Done() + // PASSWORD ONLY? var auth ssh.AuthMethod if server.IdentityFile == nil && server.Password != nil { // Password only logic @@ -255,13 +216,44 @@ func (run *Run) SetClients( var wg sync.WaitGroup var mu sync.Mutex + + agentSigners, err := GetSSHAgentSigners() + if err != nil { + return []ErrConnect{}, err + } + + globalSigner, err := GetGlobalIdentitySigner(runFlags) + if err != nil { + return []ErrConnect{}, err + } + for _, server := range run.Servers { wg.Add(1) go createLocalClient(server, &wg, &mu) if !server.Local { wg.Add(1) - go createRemoteClient(server, &wg, &mu) + + var signers []ssh.Signer + identitySigner, err := GetIdentitySigner(server) + if err != nil { + fmt.Println(123) + return []ErrConnect{*err}, nil + } + + if globalSigner != nil { + signers = append(signers, globalSigner) + } + if identitySigner != nil { + signers = append(signers, identitySigner) + } + if agentSigners != nil { + signers = append(signers, agentSigners...) + } + + authMethod := ssh.PublicKeys(signers...) + + go createRemoteClient(authMethod, server, &wg, &mu) } } wg.Wait() @@ -412,40 +404,6 @@ func (run *Run) setKnownHostsFile(knownHostsFileFlag string) error { return nil } -func getGlobalIdentity(runFlags *core.RunFlags) (string, string) { - var identityFile string - var password string - - if runFlags.IdentityFile != "" { - identityFile = runFlags.IdentityFile - } else { - value, found := os.LookupEnv("SAKE_IDENTITY_FILE") - if found { - if strings.HasPrefix(value, "~/") { - usr, err := user.Current() - if err != nil { - panic(err) - } - dir := usr.HomeDir - identityFile = filepath.Join(dir, value[2:]) - } else { - identityFile = value - } - } - } - - if runFlags.Password != "" { - password = runFlags.Password - } else { - value, found := os.LookupEnv("SAKE_PASSWORD") - if found { - password = value - } - } - - return identityFile, password -} - func getWorkDir(cmd dao.TaskCmd, server dao.Server) string { if cmd.Local || server.Local { rootDir := os.ExpandEnv(cmd.RootDir) diff --git a/core/run/ssh.go b/core/run/ssh.go index 5b02956..9fe98ad 100644 --- a/core/run/ssh.go +++ b/core/run/ssh.go @@ -9,15 +9,20 @@ import ( "fmt" "io" "io/ioutil" + "os/user" "net" "os" "strings" "sync" "time" + "path/filepath" "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/agent" "golang.org/x/crypto/ssh/knownhosts" + + "github.com/alajmo/sake/core" + "github.com/alajmo/sake/core/dao" ) var ResetColor = "\033[0m" @@ -50,82 +55,143 @@ type Identity struct { Password *string } -// InitAuthMethod initiates SSH authentications. -// 1. Load keys from SSH Agent if available -// 2. if global identity_file, use that file and return -// 3. if global identity_file + passphrase, use that file with the passphrase and return -// 4. [] TODO: if global passphrase, use passphrase connect and return -// 5. if server identity_file, use that file -// 7. if server identity_file + passphrase, use that file with the passphrase -// 8. [] TODO: if passphrase, use passphrase connect -func InitAuthMethod(globalIdentityFile string, globalPassword string, identities []Identity) (ssh.AuthMethod, error) { - var signers []ssh.Signer - +func GetSSHAgentSigners() ([]ssh.Signer, error) { // Load keys from SSH Agent if it's running sockPath, found := os.LookupEnv("SSH_AUTH_SOCK") if found { sock, err := net.Dial("unix", sockPath) if err != nil { - return ssh.PublicKeys(), err + return []ssh.Signer{}, err } else { agent := agent.NewClient(sock) - s, _ := agent.Signers() - signers = append(signers, s...) + s, err := agent.Signers() + return s, err + } + } + + return []ssh.Signer{}, nil +} + +func GetGlobalIdentitySigner(runFlags *core.RunFlags) (ssh.Signer, error) { + var identityFile string + var password string + + if runFlags.IdentityFile != "" { + identityFile = runFlags.IdentityFile + } else { + value, found := os.LookupEnv("SAKE_IDENTITY_FILE") + if found { + if strings.HasPrefix(value, "~/") { + usr, err := user.Current() + if err != nil { + panic(err) + } + dir := usr.HomeDir + identityFile = filepath.Join(dir, value[2:]) + } else { + identityFile = value + } + } + } + + if runFlags.Password != "" { + password = runFlags.Password + } else { + value, found := os.LookupEnv("SAKE_PASSWORD") + if found { + password = value } } // User provides global identity/password via flag/env - if globalIdentityFile != "" { - data, err := ioutil.ReadFile(globalIdentityFile) + if identityFile != "" { + data, err := ioutil.ReadFile(identityFile) if err != nil { - return ssh.PublicKeys(), fmt.Errorf("failed to parse `%s`\n %w", globalIdentityFile, err) + return nil, fmt.Errorf("failed to parse `%s`\n %w", identityFile, err) } - if globalPassword != "" { - signer, err := ssh.ParsePrivateKeyWithPassphrase(data, []byte(globalPassword)) + if password != "" { + signer, err := ssh.ParsePrivateKeyWithPassphrase(data, []byte(password)) if err != nil { - return ssh.PublicKeys(), fmt.Errorf("failed to parse `%s`\n %w", globalIdentityFile, err) + return nil, fmt.Errorf("failed to parse `%s`\n %w", identityFile, err) } - return ssh.PublicKeys(signer), nil + return signer, nil } else { signer, err := ssh.ParsePrivateKey(data) if err != nil { - return ssh.PublicKeys(), fmt.Errorf("failed to parse `%s`\n %w", globalIdentityFile, err) + return nil, fmt.Errorf("failed to parse `%s`\n %w", identityFile, err) } - return ssh.PublicKeys(signer), nil + return signer, nil } } - // User provides identity/passphrase via config - for _, identity := range identities { - var signer ssh.Signer + return nil, nil +} - if identity.IdentityFile != nil { - // Identity IdentityFile - data, err := ioutil.ReadFile(*identity.IdentityFile) - if err != nil { - return ssh.PublicKeys(), fmt.Errorf("failed to parse `%s`\n %w", *identity.IdentityFile, err) +func GetIdentitySigner(server dao.Server) (ssh.Signer, *ErrConnect) { + var pass *string + if server.Password != nil { + pw, err := dao.EvaluatePassword(*server.Password) + pass = &pw + if err != nil { + errConnect := &ErrConnect{ + Name: server.Name, + User: server.User, + Host: server.Host, + Port: server.Port, + Reason: err.Error(), } + return nil, errConnect + } + } - if identity.Password != nil { - signer, err = ssh.ParsePrivateKeyWithPassphrase(data, []byte(*identity.Password)) - if err != nil { - return ssh.PublicKeys(), fmt.Errorf("failed to parse `%s`\n %w", *identity.IdentityFile, err) + var signer ssh.Signer + if server.IdentityFile != nil { + // Identity IdentityFile + data, err := ioutil.ReadFile(*server.IdentityFile) + if err != nil { + errConnect := &ErrConnect{ + Name: server.Name, + User: server.User, + Host: server.Host, + Port: server.Port, + Reason: fmt.Errorf("failed to parse `%s`\n %w", *server.IdentityFile, err).Error(), + } + return nil, errConnect + } + + if pass != nil { + signer, err = ssh.ParsePrivateKeyWithPassphrase(data, []byte(*pass)) + if err != nil { + errConnect := &ErrConnect{ + Name: server.Name, + User: server.User, + Host: server.Host, + Port: server.Port, + Reason: fmt.Errorf("failed to parse `%s`\n %w", *server.IdentityFile, err).Error(), } - } else { - signer, err = ssh.ParsePrivateKey(data) - if err != nil { - return ssh.PublicKeys(), fmt.Errorf("failed to parse `%s`\n %w", *identity.IdentityFile, err) + return nil, errConnect + } + } else { + signer, err = ssh.ParsePrivateKey(data) + if err != nil { + errConnect := &ErrConnect{ + Name: server.Name, + User: server.User, + Host: server.Host, + Port: server.Port, + Reason: fmt.Errorf("failed to parse `%s`\n %w", *server.IdentityFile, err).Error(), } + return nil, errConnect } - - signers = append(signers, signer) } + + return signer, nil } - return ssh.PublicKeys(signers...), nil + return nil, nil } // SSHDialFunc can dial an ssh server and return a client From 10d24c7c5756f6ab427bf519665576d530ddbad9 Mon Sep 17 00:00:00 2001 From: samiralajmovic Date: Sun, 7 Aug 2022 11:21:01 +0200 Subject: [PATCH 2/4] wip --- core/run/exec.go | 9 ++- core/run/ssh.go | 2 + test/docker-compose-performance.yaml | 97 ++++++++++++++++++++++++++++ test/playground/sake.yaml | 6 +- 4 files changed, 109 insertions(+), 5 deletions(-) create mode 100644 test/docker-compose-performance.yaml diff --git a/core/run/exec.go b/core/run/exec.go index 0fbf776..0a7f29d 100644 --- a/core/run/exec.go +++ b/core/run/exec.go @@ -175,7 +175,7 @@ func (run *Run) SetClients( createRemoteClient := func(authMethod ssh.AuthMethod, server dao.Server, wg *sync.WaitGroup, mu *sync.Mutex) { defer wg.Done() - // PASSWORD ONLY? + // TODO: Did i already evalute the password? var auth ssh.AuthMethod if server.IdentityFile == nil && server.Password != nil { // Password only logic @@ -227,6 +227,12 @@ func (run *Run) SetClients( return []ErrConnect{}, err } + for _, server := range run.Servers { + } + + // Loop through servers and find the identity file, then create a hashmap with string -> signer + // Loop through servers and fetch the signer from the previous hashmap and connect + for _, server := range run.Servers { wg.Add(1) go createLocalClient(server, &wg, &mu) @@ -237,7 +243,6 @@ func (run *Run) SetClients( var signers []ssh.Signer identitySigner, err := GetIdentitySigner(server) if err != nil { - fmt.Println(123) return []ErrConnect{*err}, nil } diff --git a/core/run/ssh.go b/core/run/ssh.go index 9fe98ad..abd0a7c 100644 --- a/core/run/ssh.go +++ b/core/run/ssh.go @@ -163,6 +163,7 @@ func GetIdentitySigner(server dao.Server) (ssh.Signer, *ErrConnect) { } if pass != nil { + // Password protected key signer, err = ssh.ParsePrivateKeyWithPassphrase(data, []byte(*pass)) if err != nil { errConnect := &ErrConnect{ @@ -175,6 +176,7 @@ func GetIdentitySigner(server dao.Server) (ssh.Signer, *ErrConnect) { return nil, errConnect } } else { + // Unprotected key signer, err = ssh.ParsePrivateKey(data) if err != nil { errConnect := &ErrConnect{ diff --git a/test/docker-compose-performance.yaml b/test/docker-compose-performance.yaml new file mode 100644 index 0000000..95dd5f4 --- /dev/null +++ b/test/docker-compose-performance.yaml @@ -0,0 +1,97 @@ +--- +version: "3.9" + +services: + server-1: + container_name: "server-1" + build: . + ports: + - "222:22" + networks: + sake: + ipv4_address: 172.24.2.2 + + server-2: + container_name: "server-2" + build: . + ports: + - "223:22" + networks: + sake: + ipv4_address: 172.24.2.3 + + server-3: + container_name: "server-3" + build: . + ports: + - "224:22" + networks: + sake: + ipv4_address: 172.24.2.4 + + server-4: + container_name: "server-4" + build: . + ports: + - "225:22" + networks: + sake: + ipv4_address: 172.24.2.5 + + server-5: + container_name: "server-5" + build: . + ports: + - "226:22" + networks: + sake: + ipv4_address: 172.24.2.6 + + server-6: + container_name: "server-6" + build: . + ports: + - "227:22" + networks: + sake: + ipv4_address: 172.24.2.7 + + server-7: + container_name: "server-7" + build: . + ports: + - "228:22" + networks: + sake: + ipv4_address: 172.24.2.8 + + server-8: + container_name: "server-8" + build: . + ports: + - "229:22" + networks: + sake: + ipv4_address: 172.24.2.9 + + server-9: + container_name: "server-9" + build: . + ports: + - "230:22" + networks: + sake: + ipv6_address: 2001:3984:3989::10 + +networks: + sake: + name: sake + enable_ipv6: true + ipam: + driver: default + config: + - subnet: 172.24.2.0/16 + gateway: 172.24.2.1 + + - subnet: 2001:3984:3989::/64 + gateway: 2001:3984:3989::1 diff --git a/test/playground/sake.yaml b/test/playground/sake.yaml index 5a96f5c..e6d1a62 100644 --- a/test/playground/sake.yaml +++ b/test/playground/sake.yaml @@ -9,20 +9,20 @@ servers: work_dir: /opt server-1: - desc: hosts mealie, node-red + desc: misc server hosting host: 172.24.2.2 tags: [remote, pi] work_dir: /home/samir pihole-1: - desc: runs pihole + desc: pihole server host: 172.24.2.3 tags: [remote, pi, pihole] user: test identity_file: ../keys/id_ed25519_pem_no pihole-2: - desc: runs pihole + desc: pihole server duplicate host: 172.24.2.3 tags: [remote, pi, pihole] user: test From 6e17f046991b7e497a033eeae2c4c9ebe92f26cf Mon Sep 17 00:00:00 2001 From: samiralajmovic Date: Fri, 12 Aug 2022 08:57:57 +0200 Subject: [PATCH 3/4] Try only specified auth method --- core/dao/server.go | 12 ++++ core/run/client.go | 1 - core/run/exec.go | 87 ++++++++++++++------------ core/run/ssh.go | 148 +++++++++++++++++++++++++++------------------ 4 files changed, 149 insertions(+), 99 deletions(-) diff --git a/core/dao/server.go b/core/dao/server.go index cb793f8..e6e85eb 100644 --- a/core/dao/server.go +++ b/core/dao/server.go @@ -27,6 +27,7 @@ type Server struct { WorkDir string IdentityFile *string Password *string + AuthMethod string context string // config path contextLine int // defined at @@ -45,6 +46,7 @@ type ServerYAML struct { WorkDir string `yaml:"work_dir"` IdentityFile *string `yaml:"identity_file"` Password *string `yaml:"password"` + AuthMethod string `yaml:"-"` } func (s Server) GetValue(key string, _ int) string { @@ -188,6 +190,16 @@ func (c *ConfigYAML) ParseServersYAML() ([]Server, []ResourceErrors[Server]) { server.Password = serverYAML.Password } + if server.IdentityFile != nil && server.Password != nil { + server.AuthMethod = "password-key" + } else if server.IdentityFile != nil { + server.AuthMethod = "key" + } else if server.Password != nil { + server.AuthMethod = "password" + } else { + server.AuthMethod = "none" + } + servers = append(servers, *server) } diff --git a/core/run/client.go b/core/run/client.go index e5fa56b..9cba729 100644 --- a/core/run/client.go +++ b/core/run/client.go @@ -32,4 +32,3 @@ type ErrConnect struct { func (e *ErrConnect) Error() string { return "" } - diff --git a/core/run/exec.go b/core/run/exec.go index 0a7f29d..4d17217 100644 --- a/core/run/exec.go +++ b/core/run/exec.go @@ -172,38 +172,15 @@ func (run *Run) SetClients( clientCh <- local } - createRemoteClient := func(authMethod ssh.AuthMethod, server dao.Server, wg *sync.WaitGroup, mu *sync.Mutex) { + createRemoteClient := func(authMethod []ssh.AuthMethod, server dao.Server, wg *sync.WaitGroup, mu *sync.Mutex) { defer wg.Done() - // TODO: Did i already evalute the password? - var auth ssh.AuthMethod - if server.IdentityFile == nil && server.Password != nil { - // Password only logic - password, err := dao.EvaluatePassword(*server.Password) - if err != nil { - errConnect := &ErrConnect{ - Name: server.Name, - User: server.User, - Host: server.Host, - Port: server.Port, - Reason: err.Error(), - } - errCh <- *errConnect - } - - passwordAuth := ssh.Password(password) - auth = passwordAuth - } else { - // Identity key logic - auth = authMethod - } - remote := &SSHClient{ Name: server.Name, User: server.User, Host: server.Host, Port: server.Port, - AuthMethod: auth, + AuthMethod: authMethod, } if err := remote.Connect(run.Config.DisableVerifyHost, run.Config.KnownHostsFile, mu); err != nil { @@ -227,12 +204,45 @@ func (run *Run) SetClients( return []ErrConnect{}, err } + // Loop through servers and find the identity file, + // then create a hashmap with string -> signer + // Loop through servers and fetch the signer from the previous hashmap and connect + + // TODO: Check errors + identities := make(map[string]ssh.Signer) + passwordAuthMethods := make(map[string]ssh.AuthMethod) for _, server := range run.Servers { + if server.AuthMethod == "password-key" { + _, found := identities[*server.IdentityFile] + if !found { + signer, err := GetPassworIdentitySigner(server) + if err != nil { + return []ErrConnect{*err}, nil + } + identities[*server.IdentityFile] = signer + } + } else if server.AuthMethod == "key" { + _, found := identities[*server.IdentityFile] + if !found { + signer, err := GetIdentity(server) + if err != nil { + return []ErrConnect{*err}, nil + } + identities[*server.IdentityFile] = signer + } + } else if server.AuthMethod == "password" { + _, found := passwordAuthMethods[*server.Password] + if !found { + passAuthMethod, err := GetPasswordAuth(server) + if err != nil { + return []ErrConnect{*err}, nil + } + passwordAuthMethods[*server.Password] = passAuthMethod + } + } } - // Loop through servers and find the identity file, then create a hashmap with string -> signer - // Loop through servers and fetch the signer from the previous hashmap and connect - + // TODO: Check errors for _, server := range run.Servers { wg.Add(1) go createLocalClient(server, &wg, &mu) @@ -240,25 +250,26 @@ func (run *Run) SetClients( if !server.Local { wg.Add(1) + var authMethods []ssh.AuthMethod var signers []ssh.Signer - identitySigner, err := GetIdentitySigner(server) - if err != nil { - return []ErrConnect{*err}, nil - } if globalSigner != nil { signers = append(signers, globalSigner) - } - if identitySigner != nil { + } else if server.AuthMethod == "password" { + pwAuth := passwordAuthMethods[*server.Password] + authMethods = append(authMethods, pwAuth) + } else if server.AuthMethod == "key" || server.AuthMethod == "password-key" { + identitySigner := identities[*server.IdentityFile] signers = append(signers, identitySigner) - } - if agentSigners != nil { + } else if agentSigners != nil { signers = append(signers, agentSigners...) } - authMethod := ssh.PublicKeys(signers...) + if len(signers) > 0 { + authMethods = append(authMethods, ssh.PublicKeys(signers...)) + } - go createRemoteClient(authMethod, server, &wg, &mu) + go createRemoteClient(authMethods, server, &wg, &mu) } } wg.Wait() diff --git a/core/run/ssh.go b/core/run/ssh.go index abd0a7c..9abbfe3 100644 --- a/core/run/ssh.go +++ b/core/run/ssh.go @@ -9,13 +9,13 @@ import ( "fmt" "io" "io/ioutil" - "os/user" "net" "os" + "os/user" + "path/filepath" "strings" "sync" "time" - "path/filepath" "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/agent" @@ -39,7 +39,7 @@ type SSHClient struct { Port uint16 IdentityFile string Password string - AuthMethod ssh.AuthMethod + AuthMethod []ssh.AuthMethod connString string remoteStdin io.WriteCloser @@ -130,70 +130,97 @@ func GetGlobalIdentitySigner(runFlags *core.RunFlags) (ssh.Signer, error) { return nil, nil } -func GetIdentitySigner(server dao.Server) (ssh.Signer, *ErrConnect) { - var pass *string - if server.Password != nil { - pw, err := dao.EvaluatePassword(*server.Password) - pass = &pw - if err != nil { - errConnect := &ErrConnect{ - Name: server.Name, - User: server.User, - Host: server.Host, - Port: server.Port, - Reason: err.Error(), - } - return nil, errConnect +func GetPasswordAuth(server dao.Server) (ssh.AuthMethod, *ErrConnect) { + password, err := dao.EvaluatePassword(*server.Password) + if err != nil { + errConnect := &ErrConnect{ + Name: server.Name, + User: server.User, + Host: server.Host, + Port: server.Port, + Reason: err.Error(), } + + return nil, errConnect } + return ssh.Password(password), nil +} + +// Password protected key +func GetPassworIdentitySigner(server dao.Server) (ssh.Signer, *ErrConnect) { var signer ssh.Signer - if server.IdentityFile != nil { - // Identity IdentityFile - data, err := ioutil.ReadFile(*server.IdentityFile) - if err != nil { - errConnect := &ErrConnect{ - Name: server.Name, - User: server.User, - Host: server.Host, - Port: server.Port, - Reason: fmt.Errorf("failed to parse `%s`\n %w", *server.IdentityFile, err).Error(), - } - return nil, errConnect + + data, err := ioutil.ReadFile(*server.IdentityFile) + if err != nil { + errConnect := &ErrConnect{ + Name: server.Name, + User: server.User, + Host: server.Host, + Port: server.Port, + Reason: fmt.Errorf("failed to parse `%s`\n %w", *server.IdentityFile, err).Error(), } + return nil, errConnect + } - if pass != nil { - // Password protected key - signer, err = ssh.ParsePrivateKeyWithPassphrase(data, []byte(*pass)) - if err != nil { - errConnect := &ErrConnect{ - Name: server.Name, - User: server.User, - Host: server.Host, - Port: server.Port, - Reason: fmt.Errorf("failed to parse `%s`\n %w", *server.IdentityFile, err).Error(), - } - return nil, errConnect - } - } else { - // Unprotected key - signer, err = ssh.ParsePrivateKey(data) - if err != nil { - errConnect := &ErrConnect{ - Name: server.Name, - User: server.User, - Host: server.Host, - Port: server.Port, - Reason: fmt.Errorf("failed to parse `%s`\n %w", *server.IdentityFile, err).Error(), - } - return nil, errConnect - } + var pass *string + pw, err := dao.EvaluatePassword(*server.Password) + pass = &pw + if err != nil { + errConnect := &ErrConnect{ + Name: server.Name, + User: server.User, + Host: server.Host, + Port: server.Port, + Reason: err.Error(), } + return nil, errConnect + } - return signer, nil + signer, err = ssh.ParsePrivateKeyWithPassphrase(data, []byte(*pass)) + if err != nil { + errConnect := &ErrConnect{ + Name: server.Name, + User: server.User, + Host: server.Host, + Port: server.Port, + Reason: fmt.Errorf("failed to parse `%s`\n %w", *server.IdentityFile, err).Error(), + } + return nil, errConnect } - return nil, nil + return signer, nil +} + +// Unprotected key +func GetIdentity(server dao.Server) (ssh.Signer, *ErrConnect) { + var signer ssh.Signer + + data, err := ioutil.ReadFile(*server.IdentityFile) + if err != nil { + errConnect := &ErrConnect{ + Name: server.Name, + User: server.User, + Host: server.Host, + Port: server.Port, + Reason: fmt.Errorf("failed to parse `%s`\n %w", *server.IdentityFile, err).Error(), + } + return nil, errConnect + } + + signer, err = ssh.ParsePrivateKey(data) + if err != nil { + errConnect := &ErrConnect{ + Name: server.Name, + User: server.User, + Host: server.Host, + Port: server.Port, + Reason: fmt.Errorf("failed to parse `%s`\n %w", *server.IdentityFile, err).Error(), + } + return nil, errConnect + } + + return signer, nil } // SSHDialFunc can dial an ssh server and return a client @@ -222,9 +249,10 @@ func (c *SSHClient) ConnectWith(dialer SSHDialFunc, disableVerifyHost bool, know config := &ssh.ClientConfig{ User: c.User, - Auth: []ssh.AuthMethod{ - c.AuthMethod, - }, + Auth: c.AuthMethod, + // Auth: []ssh.AuthMethod{ + // c.AuthMethod, + // }, HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error { if !disableVerifyHost { return VerifyHost(knownHostsFile, mu, hostname, remote, key) From 0c7d2c3a01b6584607210cf09643551404029c0e Mon Sep 17 00:00:00 2001 From: samiralajmovic Date: Fri, 12 Aug 2022 20:49:37 +0200 Subject: [PATCH 4/4] Add performance docker-compose --- Makefile | 3 + core/run/exec.go | 6 - test/docker-compose-performance.yaml | 842 +++++++++++++++++++++++++- test/playground/performance/sake.yaml | 741 +++++++++++++++++++++++ test/playground/sake.yaml | 3 +- 5 files changed, 1575 insertions(+), 20 deletions(-) create mode 100644 test/playground/performance/sake.yaml diff --git a/Makefile b/Makefile index 916992f..84d17ba 100644 --- a/Makefile +++ b/Makefile @@ -37,6 +37,9 @@ update-golden-files: mock-ssh: cd ./test && docker-compose up +mock-performance-ssh: + cd ./test && docker-compose -f docker-compose-performance.yaml up + build: CGO_ENABLED=0 go build \ -ldflags "-s -w -X '${PACKAGE}/cmd.version=${VERSION}' -X '${PACKAGE}/cmd.commit=${GIT}' -X '${PACKAGE}/cmd.date=${DATE}'" \ diff --git a/core/run/exec.go b/core/run/exec.go index 4d17217..1f9c66c 100644 --- a/core/run/exec.go +++ b/core/run/exec.go @@ -204,11 +204,6 @@ func (run *Run) SetClients( return []ErrConnect{}, err } - // Loop through servers and find the identity file, - // then create a hashmap with string -> signer - // Loop through servers and fetch the signer from the previous hashmap and connect - - // TODO: Check errors identities := make(map[string]ssh.Signer) passwordAuthMethods := make(map[string]ssh.AuthMethod) for _, server := range run.Servers { @@ -242,7 +237,6 @@ func (run *Run) SetClients( } } - // TODO: Check errors for _, server := range run.Servers { wg.Add(1) go createLocalClient(server, &wg, &mu) diff --git a/test/docker-compose-performance.yaml b/test/docker-compose-performance.yaml index 95dd5f4..e891add 100644 --- a/test/docker-compose-performance.yaml +++ b/test/docker-compose-performance.yaml @@ -4,7 +4,7 @@ version: "3.9" services: server-1: container_name: "server-1" - build: . + image: test_server-1 ports: - "222:22" networks: @@ -13,7 +13,7 @@ services: server-2: container_name: "server-2" - build: . + image: test_server-1 ports: - "223:22" networks: @@ -22,7 +22,7 @@ services: server-3: container_name: "server-3" - build: . + image: test_server-1 ports: - "224:22" networks: @@ -31,7 +31,7 @@ services: server-4: container_name: "server-4" - build: . + image: test_server-1 ports: - "225:22" networks: @@ -40,7 +40,7 @@ services: server-5: container_name: "server-5" - build: . + image: test_server-1 ports: - "226:22" networks: @@ -49,7 +49,7 @@ services: server-6: container_name: "server-6" - build: . + image: test_server-1 ports: - "227:22" networks: @@ -58,7 +58,7 @@ services: server-7: container_name: "server-7" - build: . + image: test_server-1 ports: - "228:22" networks: @@ -67,7 +67,7 @@ services: server-8: container_name: "server-8" - build: . + image: test_server-1 ports: - "229:22" networks: @@ -76,12 +76,831 @@ services: server-9: container_name: "server-9" - build: . + image: test_server-1 ports: - "230:22" networks: sake: - ipv6_address: 2001:3984:3989::10 + ipv4_address: 172.24.2.10 + + server-10: + container_name: "server-10" + image: test_server-1 + ports: + - "231:22" + networks: + sake: + ipv4_address: 172.24.2.11 + + server-11: + container_name: "server-11" + image: test_server-1 + ports: + - "232:22" + networks: + sake: + ipv4_address: 172.24.2.12 + + server-12: + container_name: "server-12" + image: test_server-1 + ports: + - "233:22" + networks: + sake: + ipv4_address: 172.24.2.13 + + server-13: + container_name: "server-13" + image: test_server-1 + ports: + - "234:22" + networks: + sake: + ipv4_address: 172.24.2.14 + + server-14: + container_name: "server-14" + image: test_server-1 + ports: + - "235:22" + networks: + sake: + ipv4_address: 172.24.2.15 + + server-15: + container_name: "server-15" + image: test_server-1 + ports: + - "236:22" + networks: + sake: + ipv4_address: 172.24.2.16 + + server-16: + container_name: "server-16" + image: test_server-1 + ports: + - "237:22" + networks: + sake: + ipv4_address: 172.24.2.17 + + server-17: + container_name: "server-17" + image: test_server-1 + ports: + - "238:22" + networks: + sake: + ipv4_address: 172.24.2.18 + + server-18: + container_name: "server-18" + image: test_server-1 + ports: + - "239:22" + networks: + sake: + ipv4_address: 172.24.2.19 + + server-19: + container_name: "server-19" + image: test_server-1 + ports: + - "240:22" + networks: + sake: + ipv4_address: 172.24.2.20 + + server-20: + container_name: "server-20" + image: test_server-1 + ports: + - "241:22" + networks: + sake: + ipv4_address: 172.24.2.21 + + server-21: + container_name: "server-21" + image: test_server-1 + ports: + - "242:22" + networks: + sake: + ipv4_address: 172.24.2.22 + + server-22: + container_name: "server-22" + image: test_server-1 + ports: + - "243:22" + networks: + sake: + ipv4_address: 172.24.2.23 + + server-23: + container_name: "server-23" + image: test_server-1 + ports: + - "244:22" + networks: + sake: + ipv4_address: 172.24.2.24 + + server-24: + container_name: "server-24" + image: test_server-1 + ports: + - "245:22" + networks: + sake: + ipv4_address: 172.24.2.25 + + server-25: + container_name: "server-25" + image: test_server-1 + ports: + - "246:22" + networks: + sake: + ipv4_address: 172.24.2.26 + + server-26: + container_name: "server-26" + image: test_server-1 + ports: + - "247:22" + networks: + sake: + ipv4_address: 172.24.2.27 + + server-27: + container_name: "server-27" + image: test_server-1 + ports: + - "248:22" + networks: + sake: + ipv4_address: 172.24.2.28 + + server-28: + container_name: "server-28" + image: test_server-1 + ports: + - "249:22" + networks: + sake: + ipv4_address: 172.24.2.29 + + server-29: + container_name: "server-29" + image: test_server-1 + ports: + - "250:22" + networks: + sake: + ipv4_address: 172.24.2.30 + + server-30: + container_name: "server-30" + image: test_server-1 + ports: + - "251:22" + networks: + sake: + ipv4_address: 172.24.2.31 + + server-31: + container_name: "server-31" + image: test_server-1 + ports: + - "252:22" + networks: + sake: + ipv4_address: 172.24.2.32 + + server-32: + container_name: "server-32" + image: test_server-1 + ports: + - "253:22" + networks: + sake: + ipv4_address: 172.24.2.33 + + server-33: + container_name: "server-33" + image: test_server-1 + ports: + - "254:22" + networks: + sake: + ipv4_address: 172.24.2.34 + + server-34: + container_name: "server-34" + image: test_server-1 + ports: + - "255:22" + networks: + sake: + ipv4_address: 172.24.2.35 + + server-35: + container_name: "server-35" + image: test_server-1 + ports: + - "256:22" + networks: + sake: + ipv4_address: 172.24.2.36 + + server-36: + container_name: "server-36" + image: test_server-1 + ports: + - "257:22" + networks: + sake: + ipv4_address: 172.24.2.37 + + server-37: + container_name: "server-37" + image: test_server-1 + ports: + - "258:22" + networks: + sake: + ipv4_address: 172.24.2.38 + + server-38: + container_name: "server-38" + image: test_server-1 + ports: + - "259:22" + networks: + sake: + ipv4_address: 172.24.2.39 + + server-39: + container_name: "server-39" + image: test_server-1 + ports: + - "260:22" + networks: + sake: + ipv4_address: 172.24.2.40 + + server-40: + container_name: "server-40" + image: test_server-1 + ports: + - "261:22" + networks: + sake: + ipv4_address: 172.24.2.41 + + server-41: + container_name: "server-41" + image: test_server-1 + ports: + - "262:22" + networks: + sake: + ipv4_address: 172.24.2.42 + + server-42: + container_name: "server-42" + image: test_server-1 + ports: + - "263:22" + networks: + sake: + ipv4_address: 172.24.2.43 + + server-43: + container_name: "server-43" + image: test_server-1 + ports: + - "264:22" + networks: + sake: + ipv4_address: 172.24.2.44 + + server-44: + container_name: "server-44" + image: test_server-1 + ports: + - "265:22" + networks: + sake: + ipv4_address: 172.24.2.45 + + server-45: + container_name: "server-45" + image: test_server-1 + ports: + - "266:22" + networks: + sake: + ipv4_address: 172.24.2.46 + + server-46: + container_name: "server-46" + image: test_server-1 + ports: + - "267:22" + networks: + sake: + ipv4_address: 172.24.2.47 + + server-47: + container_name: "server-47" + image: test_server-1 + ports: + - "268:22" + networks: + sake: + ipv4_address: 172.24.2.48 + + server-48: + container_name: "server-48" + image: test_server-1 + ports: + - "269:22" + networks: + sake: + ipv4_address: 172.24.2.49 + + server-49: + container_name: "server-49" + image: test_server-1 + ports: + - "270:22" + networks: + sake: + ipv4_address: 172.24.2.50 + + server-50: + container_name: "server-50" + image: test_server-1 + ports: + - "271:22" + networks: + sake: + ipv4_address: 172.24.2.51 + + server-51: + container_name: "server-51" + image: test_server-1 + ports: + - "272:22" + networks: + sake: + ipv4_address: 172.24.2.52 + + server-52: + container_name: "server-52" + image: test_server-1 + ports: + - "273:22" + networks: + sake: + ipv4_address: 172.24.2.53 + + server-53: + container_name: "server-53" + image: test_server-1 + ports: + - "274:22" + networks: + sake: + ipv4_address: 172.24.2.54 + + server-54: + container_name: "server-54" + image: test_server-1 + ports: + - "275:22" + networks: + sake: + ipv4_address: 172.24.2.55 + + server-55: + container_name: "server-55" + image: test_server-1 + ports: + - "276:22" + networks: + sake: + ipv4_address: 172.24.2.56 + + server-56: + container_name: "server-56" + image: test_server-1 + ports: + - "277:22" + networks: + sake: + ipv4_address: 172.24.2.57 + + server-57: + container_name: "server-57" + image: test_server-1 + ports: + - "278:22" + networks: + sake: + ipv4_address: 172.24.2.58 + + server-58: + container_name: "server-58" + image: test_server-1 + ports: + - "279:22" + networks: + sake: + ipv4_address: 172.24.2.59 + + server-59: + container_name: "server-59" + image: test_server-1 + ports: + - "280:22" + networks: + sake: + ipv4_address: 172.24.2.60 + + server-60: + container_name: "server-60" + image: test_server-1 + ports: + - "281:22" + networks: + sake: + ipv4_address: 172.24.2.61 + + server-61: + container_name: "server-61" + image: test_server-1 + ports: + - "282:22" + networks: + sake: + ipv4_address: 172.24.2.62 + + server-62: + container_name: "server-62" + image: test_server-1 + ports: + - "283:22" + networks: + sake: + ipv4_address: 172.24.2.63 + + server-63: + container_name: "server-63" + image: test_server-1 + ports: + - "284:22" + networks: + sake: + ipv4_address: 172.24.2.64 + + server-64: + container_name: "server-64" + image: test_server-1 + ports: + - "285:22" + networks: + sake: + ipv4_address: 172.24.2.65 + + server-65: + container_name: "server-65" + image: test_server-1 + ports: + - "286:22" + networks: + sake: + ipv4_address: 172.24.2.66 + + server-66: + container_name: "server-66" + image: test_server-1 + ports: + - "287:22" + networks: + sake: + ipv4_address: 172.24.2.67 + + server-67: + container_name: "server-67" + image: test_server-1 + ports: + - "288:22" + networks: + sake: + ipv4_address: 172.24.2.68 + + server-68: + container_name: "server-68" + image: test_server-1 + ports: + - "289:22" + networks: + sake: + ipv4_address: 172.24.2.69 + + server-69: + container_name: "server-69" + image: test_server-1 + ports: + - "290:22" + networks: + sake: + ipv4_address: 172.24.2.70 + + server-70: + container_name: "server-70" + image: test_server-1 + ports: + - "291:22" + networks: + sake: + ipv4_address: 172.24.2.71 + + server-71: + container_name: "server-71" + image: test_server-1 + ports: + - "292:22" + networks: + sake: + ipv4_address: 172.24.2.72 + + server-72: + container_name: "server-72" + image: test_server-1 + ports: + - "293:22" + networks: + sake: + ipv4_address: 172.24.2.73 + + server-73: + container_name: "server-73" + image: test_server-1 + ports: + - "294:22" + networks: + sake: + ipv4_address: 172.24.2.74 + + server-74: + container_name: "server-74" + image: test_server-1 + ports: + - "295:22" + networks: + sake: + ipv4_address: 172.24.2.75 + + server-75: + container_name: "server-75" + image: test_server-1 + ports: + - "296:22" + networks: + sake: + ipv4_address: 172.24.2.76 + + server-76: + container_name: "server-76" + image: test_server-1 + ports: + - "297:22" + networks: + sake: + ipv4_address: 172.24.2.77 + + server-77: + container_name: "server-77" + image: test_server-1 + ports: + - "298:22" + networks: + sake: + ipv4_address: 172.24.2.78 + + server-78: + container_name: "server-78" + image: test_server-1 + ports: + - "299:22" + networks: + sake: + ipv4_address: 172.24.2.79 + + server-79: + container_name: "server-79" + image: test_server-1 + ports: + - "300:22" + networks: + sake: + ipv4_address: 172.24.2.80 + + server-80: + container_name: "server-80" + image: test_server-1 + ports: + - "301:22" + networks: + sake: + ipv4_address: 172.24.2.81 + + server-81: + container_name: "server-81" + image: test_server-1 + ports: + - "302:22" + networks: + sake: + ipv4_address: 172.24.2.82 + + server-82: + container_name: "server-82" + image: test_server-1 + ports: + - "303:22" + networks: + sake: + ipv4_address: 172.24.2.83 + + server-83: + container_name: "server-83" + image: test_server-1 + ports: + - "304:22" + networks: + sake: + ipv4_address: 172.24.2.84 + + server-84: + container_name: "server-84" + image: test_server-1 + ports: + - "305:22" + networks: + sake: + ipv4_address: 172.24.2.85 + + server-85: + container_name: "server-85" + image: test_server-1 + ports: + - "306:22" + networks: + sake: + ipv4_address: 172.24.2.86 + + server-86: + container_name: "server-86" + image: test_server-1 + ports: + - "307:22" + networks: + sake: + ipv4_address: 172.24.2.87 + + server-87: + container_name: "server-87" + image: test_server-1 + ports: + - "308:22" + networks: + sake: + ipv4_address: 172.24.2.88 + + server-88: + container_name: "server-88" + image: test_server-1 + ports: + - "309:22" + networks: + sake: + ipv4_address: 172.24.2.89 + + server-89: + container_name: "server-89" + image: test_server-1 + ports: + - "310:22" + networks: + sake: + ipv4_address: 172.24.2.90 + + server-90: + container_name: "server-90" + image: test_server-1 + ports: + - "311:22" + networks: + sake: + ipv4_address: 172.24.2.91 + + server-91: + container_name: "server-91" + image: test_server-1 + ports: + - "312:22" + networks: + sake: + ipv4_address: 172.24.2.92 + + server-92: + container_name: "server-92" + image: test_server-1 + ports: + - "313:22" + networks: + sake: + ipv4_address: 172.24.2.93 + + server-93: + container_name: "server-93" + image: test_server-1 + ports: + - "314:22" + networks: + sake: + ipv4_address: 172.24.2.94 + + server-94: + container_name: "server-94" + image: test_server-1 + ports: + - "315:22" + networks: + sake: + ipv4_address: 172.24.2.95 + + server-95: + container_name: "server-95" + image: test_server-1 + ports: + - "316:22" + networks: + sake: + ipv4_address: 172.24.2.96 + + server-96: + container_name: "server-96" + image: test_server-1 + ports: + - "317:22" + networks: + sake: + ipv4_address: 172.24.2.97 + + server-97: + container_name: "server-97" + image: test_server-1 + ports: + - "318:22" + networks: + sake: + ipv4_address: 172.24.2.98 + + server-98: + container_name: "server-98" + image: test_server-1 + ports: + - "319:22" + networks: + sake: + ipv4_address: 172.24.2.99 + + server-99: + container_name: "server-99" + image: test_server-1 + ports: + - "320:22" + networks: + sake: + ipv4_address: 172.24.2.100 + + server-100: + container_name: "server-100" + image: test_server-1 + ports: + - "321:22" + networks: + sake: + ipv4_address: 172.24.2.101 networks: sake: @@ -92,6 +911,3 @@ networks: config: - subnet: 172.24.2.0/16 gateway: 172.24.2.1 - - - subnet: 2001:3984:3989::/64 - gateway: 2001:3984:3989::1 diff --git a/test/playground/performance/sake.yaml b/test/playground/performance/sake.yaml new file mode 100644 index 0000000..d4d0cc0 --- /dev/null +++ b/test/playground/performance/sake.yaml @@ -0,0 +1,741 @@ +disable_verify_host: true + +servers: + localhost: + desc: localhost + host: localhost + local: true + tags: [local] + work_dir: /opt + + server-1: + desc: misc server hosting + host: 172.24.2.2 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-2: + desc: misc server hosting + host: 172.24.2.3 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-3: + desc: misc server hosting + host: 172.24.2.4 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-4: + desc: misc server hosting + host: 172.24.2.5 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_rsa_pem_no + + server-5: + desc: misc server hosting + host: 172.24.2.6 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-6: + desc: misc server hosting + host: 172.24.2.7 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-7: + desc: misc server hosting + host: 172.24.2.8 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-8: + desc: misc server hosting + host: 172.24.2.9 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-9: + desc: misc server hosting + host: 172.24.2.10 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-10: + desc: misc server hosting + host: 172.24.2.11 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-11: + desc: misc server hosting + host: 172.24.2.12 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-12: + desc: misc server hosting + host: 172.24.2.13 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-13: + desc: misc server hosting + host: 172.24.2.14 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-14: + desc: misc server hosting + host: 172.24.2.15 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-15: + desc: misc server hosting + host: 172.24.2.16 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-16: + desc: misc server hosting + host: 172.24.2.17 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-17: + desc: misc server hosting + host: 172.24.2.18 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-18: + desc: misc server hosting + host: 172.24.2.19 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-19: + desc: misc server hosting + host: 172.24.2.20 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-20: + desc: misc server hosting + host: 172.24.2.21 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-21: + desc: misc server hosting + host: 172.24.2.22 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-22: + desc: misc server hosting + host: 172.24.2.23 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-23: + desc: misc server hosting + host: 172.24.2.24 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-24: + desc: misc server hosting + host: 172.24.2.25 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-25: + desc: misc server hosting + host: 172.24.2.26 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-26: + desc: misc server hosting + host: 172.24.2.27 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-27: + desc: misc server hosting + host: 172.24.2.28 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-28: + desc: misc server hosting + host: 172.24.2.29 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-29: + desc: misc server hosting + host: 172.24.2.30 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-30: + desc: misc server hosting + host: 172.24.2.31 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-31: + desc: misc server hosting + host: 172.24.2.32 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-32: + desc: misc server hosting + host: 172.24.2.33 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-33: + desc: misc server hosting + host: 172.24.2.34 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-34: + desc: misc server hosting + host: 172.24.2.35 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-35: + desc: misc server hosting + host: 172.24.2.36 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-36: + desc: misc server hosting + host: 172.24.2.37 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-37: + desc: misc server hosting + host: 172.24.2.38 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-38: + desc: misc server hosting + host: 172.24.2.39 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-39: + desc: misc server hosting + host: 172.24.2.40 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-40: + desc: misc server hosting + host: 172.24.2.41 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-41: + desc: misc server hosting + host: 172.24.2.42 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-42: + desc: misc server hosting + host: 172.24.2.43 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-43: + desc: misc server hosting + host: 172.24.2.44 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-44: + desc: misc server hosting + host: 172.24.2.45 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-45: + desc: misc server hosting + host: 172.24.2.46 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-46: + desc: misc server hosting + host: 172.24.2.47 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-47: + desc: misc server hosting + host: 172.24.2.48 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-48: + desc: misc server hosting + host: 172.24.2.49 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-49: + desc: misc server hosting + host: 172.24.2.50 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-50: + desc: misc server hosting + host: 172.24.2.51 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-51: + desc: misc server hosting + host: 172.24.2.52 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-52: + desc: misc server hosting + host: 172.24.2.53 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-53: + desc: misc server hosting + host: 172.24.2.54 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-54: + desc: misc server hosting + host: 172.24.2.55 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-55: + desc: misc server hosting + host: 172.24.2.56 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-56: + desc: misc server hosting + host: 172.24.2.57 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-57: + desc: misc server hosting + host: 172.24.2.58 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-58: + desc: misc server hosting + host: 172.24.2.59 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-59: + desc: misc server hosting + host: 172.24.2.60 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-60: + desc: misc server hosting + host: 172.24.2.61 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-61: + desc: misc server hosting + host: 172.24.2.62 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-62: + desc: misc server hosting + host: 172.24.2.63 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-63: + desc: misc server hosting + host: 172.24.2.64 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-64: + desc: misc server hosting + host: 172.24.2.65 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-65: + desc: misc server hosting + host: 172.24.2.66 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-66: + desc: misc server hosting + host: 172.24.2.67 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-67: + desc: misc server hosting + host: 172.24.2.68 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-68: + desc: misc server hosting + host: 172.24.2.69 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-69: + desc: misc server hosting + host: 172.24.2.70 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-70: + desc: misc server hosting + host: 172.24.2.71 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-71: + desc: misc server hosting + host: 172.24.2.72 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-72: + desc: misc server hosting + host: 172.24.2.73 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-73: + desc: misc server hosting + host: 172.24.2.74 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-74: + desc: misc server hosting + host: 172.24.2.75 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-75: + desc: misc server hosting + host: 172.24.2.76 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-76: + desc: misc server hosting + host: 172.24.2.77 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-77: + desc: misc server hosting + host: 172.24.2.78 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-78: + desc: misc server hosting + host: 172.24.2.79 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-79: + desc: misc server hosting + host: 172.24.2.80 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-80: + desc: misc server hosting + host: 172.24.2.81 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-81: + desc: misc server hosting + host: 172.24.2.82 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-82: + desc: misc server hosting + host: 172.24.2.83 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-83: + desc: misc server hosting + host: 172.24.2.84 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-84: + desc: misc server hosting + host: 172.24.2.85 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-85: + desc: misc server hosting + host: 172.24.2.86 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-86: + desc: misc server hosting + host: 172.24.2.87 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-87: + desc: misc server hosting + host: 172.24.2.88 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-88: + desc: misc server hosting + host: 172.24.2.89 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-89: + desc: misc server hosting + host: 172.24.2.90 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-90: + desc: misc server hosting + host: 172.24.2.91 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-91: + desc: misc server hosting + host: 172.24.2.92 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-92: + desc: misc server hosting + host: 172.24.2.93 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-93: + desc: misc server hosting + host: 172.24.2.94 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-94: + desc: misc server hosting + host: 172.24.2.95 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-95: + desc: misc server hosting + host: 172.24.2.96 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-96: + desc: misc server hosting + host: 172.24.2.97 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-97: + desc: misc server hosting + host: 172.24.2.98 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-98: + desc: misc server hosting + host: 172.24.2.99 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-99: + desc: misc server hosting + host: 172.24.2.100 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + + server-100: + desc: misc server hosting + host: 172.24.2.101 + tags: [remote, pi] + user: test + identity_file: ../../keys/id_ed25519_pem_no + +targets: + all: + all: true + +specs: + table: + output: table + + text: + output: text + + info: + output: table + parallel: true + ignore_errors: true + ignore_unreachable: true + any_errors_fatal: false + +env: + VERSION: v0.1.0 + DATE: $(date -u +"%Y-%m-%dT%H:%M:%S%Z") + +tasks: + exit: + local: true + cmd: exit 3 + + ping: + target: all + desc: ping server + cmd: echo pong diff --git a/test/playground/sake.yaml b/test/playground/sake.yaml index e6d1a62..57409ca 100644 --- a/test/playground/sake.yaml +++ b/test/playground/sake.yaml @@ -12,7 +12,8 @@ servers: desc: misc server hosting host: 172.24.2.2 tags: [remote, pi] - work_dir: /home/samir + user: test + identity_file: ../keys/id_ed25519_pem_no pihole-1: desc: pihole server