diff --git a/plugin.go b/plugin.go index e0cfa00..af40264 100644 --- a/plugin.go +++ b/plugin.go @@ -254,14 +254,15 @@ func (p *Plugin) Exec() error { errChannel := make(chan error) finished := make(chan struct{}) for _, host := range hosts { - go func(host string) { + go func(h string) { defer wg.Done() + host, port := p.hostPort(h) // Create MakeConfig instance with remote username, server address and path to private key. ssh := &easyssh.MakeConfig{ Server: host, User: p.Config.Username, Password: p.Config.Password, - Port: p.Config.Port, + Port: port, Key: p.Config.Key, KeyPath: p.Config.KeyPath, Passphrase: p.Config.Passphrase, @@ -385,6 +386,22 @@ func (p *Plugin) Exec() error { return nil } +// This function takes a Plugin struct and a host string and returns the host and port as separate strings. +func (p Plugin) hostPort(host string) (string, string) { + // Split the host string by colon (":") to get the host and port + hosts := strings.Split(host, ":") + // Get the default port from the Plugin's Config field + port := p.Config.Port + // If the host string contains a port (i.e. it has more than one element after splitting), set the port to that value + if len(hosts) > 1 { + host = hosts[0] + port = hosts[1] + } + + // Return the host and port as separate strings + return host, port +} + func trimValues(keys []string) []string { var newKeys []string diff --git a/plugin_test.go b/plugin_test.go index a3ff1e4..2706258 100644 --- a/plugin_test.go +++ b/plugin_test.go @@ -804,3 +804,69 @@ func TestTargetFolderWithSpaces(t *testing.T) { t.Fatalf("SCP-error: %v", err) } } + +func TestHostPortString(t *testing.T) { + if os.Getenv("SSH_AUTH_SOCK") != "" { + if err := exec.Command("eval", "`ssh-agent -k`").Run(); err != nil { + t.Fatalf("exec: %v", err) + } + } + + u, err := user.Lookup("drone-scp") + if err != nil { + t.Fatalf("Lookup: %v", err) + } + + plugin := Plugin{ + Config: Config{ + Host: []string{"localhost:22", "localhost:22"}, + Username: "drone-scp", + Port: "8080", + KeyPath: "tests/.ssh/id_rsa", + Source: []string{"tests/global/*"}, + StripComponents: 2, + Target: []string{filepath.Join(u.HomeDir, "1234")}, + CommandTimeout: 60 * time.Second, + TarExec: "tar", + }, + } + + err = plugin.Exec() + assert.Nil(t, err) + + // check file exist + if _, err := os.Stat(filepath.Join(u.HomeDir, "1234", "c.txt")); os.IsNotExist(err) { + t.Fatalf("SCP-error: %v", err) + } + + if _, err := os.Stat(filepath.Join(u.HomeDir, "1234", "d.txt")); os.IsNotExist(err) { + t.Fatalf("SCP-error: %v", err) + } +} + +// Unit test for hostPort +func TestHostPort(t *testing.T) { + p := Plugin{ + Config: Config{ + Port: "8080", + }, + } + + // Test case 1: host string with port + host1 := "example.com:1234" + expectedHost1 := "example.com" + expectedPort1 := "1234" + actualHost1, actualPort1 := p.hostPort(host1) + if actualHost1 != expectedHost1 || actualPort1 != expectedPort1 { + t.Errorf("hostPort(%s) = (%s, %s); expected (%s, %s)", host1, actualHost1, actualPort1, expectedHost1, expectedPort1) + } + + // Test case 2: host string without port + host2 := "example.com" + expectedHost2 := "example.com" + expectedPort2 := "8080" // default port + actualHost2, actualPort2 := p.hostPort(host2) + if actualHost2 != expectedHost2 || actualPort2 != expectedPort2 { + t.Errorf("hostPort(%s) = (%s, %s); expected (%s, %s)", host2, actualHost2, actualPort2, expectedHost2, expectedPort2) + } +}