diff --git a/main.go b/main.go index 5f28a12..16bd81a 100644 --- a/main.go +++ b/main.go @@ -140,6 +140,43 @@ func main() { Name: "env-file", Usage: "source env file", }, + cli.StringFlag{ + Name: "proxy.ssh-key", + Usage: "private ssh key of proxy", + EnvVar: "PLUGIN_PROXY_SSH_KEY,PLUGIN_PROXY_KEY,PROXY_SSH_KEY", + }, + cli.StringFlag{ + Name: "proxy.key-path", + Usage: "ssh private key path of proxy", + EnvVar: "PLUGIN_PROXY_KEY_PATH,PROXY_SSH_KEY_PATH", + }, + cli.StringFlag{ + Name: "proxy.username", + Usage: "connect as user of proxy", + EnvVar: "PLUGIN_PROXY_USERNAME,PLUGIN_PROXY_USER,PROXY_SSH_USERNAME", + Value: "root", + }, + cli.StringFlag{ + Name: "proxy.password", + Usage: "user password of proxy", + EnvVar: "PLUGIN_PROXY_PASSWORD,PROXY_SSH_PASSWORD", + }, + cli.StringFlag{ + Name: "proxy.host", + Usage: "connect to host of proxy", + EnvVar: "PLUGIN_PROXY_HOST,PROXY_SSH_HOST", + }, + cli.StringFlag{ + Name: "proxy.port", + Usage: "connect to port of proxy", + EnvVar: "PLUGIN_PROXY_PORT,PROXY_SSH_PORT", + Value: "22", + }, + cli.DurationFlag{ + Name: "proxy.timeout", + Usage: "proxy connection timeout", + EnvVar: "PLUGIN_PROXY_TIMEOUT,PROXY_SSH_TIMEOUT", + }, } // Override a template @@ -209,6 +246,15 @@ func run(c *cli.Context) error { Target: c.StringSlice("target"), Source: c.StringSlice("source"), Remove: c.Bool("rm"), + Proxy: defaultConfig{ + Key: c.String("proxy.ssh-key"), + KeyPath: c.String("proxy.key-path"), + User: c.String("proxy.username"), + Password: c.String("proxy.password"), + Server: c.String("proxy.host"), + Port: c.String("proxy.port"), + Timeout: c.Duration("proxy.timeout"), + }, }, } diff --git a/plugin.go b/plugin.go index 7be6bb0..2c18629 100644 --- a/plugin.go +++ b/plugin.go @@ -17,6 +17,16 @@ import ( ) type ( + defaultConfig struct { + User string + Server string + Key string + KeyPath string + Port string + Password string + Timeout time.Duration + } + // Repo information. Repo struct { Owner string @@ -48,6 +58,7 @@ type ( Target []string Source []string Remove bool + Proxy defaultConfig } // Plugin values. @@ -142,6 +153,15 @@ func (p Plugin) Exec() error { Key: p.Config.Key, KeyPath: p.Config.KeyPath, Timeout: p.Config.Timeout, + Proxy: defaultConfig{ + Server: p.Config.Proxy.Server, + User: p.Config.Proxy.User, + Password: p.Config.Proxy.Password, + Port: p.Config.Proxy.Port, + Key: p.Config.Proxy.Key, + KeyPath: p.Config.Proxy.KeyPath, + Timeout: p.Config.Proxy.Timeout, + }, } // Call Scp method with file you want to upload to remote server. diff --git a/plugin_test.go b/plugin_test.go index 06f70a5..2a9e306 100644 --- a/plugin_test.go +++ b/plugin_test.go @@ -141,6 +141,43 @@ func TestSCPWildcardFileList(t *testing.T) { } } +func TestSCPFromProxySetting(t *testing.T) { + u, err := user.Lookup("drone-scp") + if err != nil { + t.Fatalf("Lookup: %v", err) + } + + plugin := Plugin{ + Config: Config{ + Host: []string{"localhost"}, + Username: "drone-scp", + Port: "22", + KeyPath: "tests/.ssh/id_rsa", + Source: []string{"tests/global/*"}, + Target: []string{u.HomeDir + "/def"}, + CommandTimeout: 60, + Proxy: defaultConfig{ + Server: "localhost", + User: "drone-scp", + Port: "22", + KeyPath: "./tests/.ssh/id_rsa", + }, + }, + } + + err = plugin.Exec() + assert.Nil(t, err) + + // check file exist + if _, err := os.Stat(u.HomeDir + "/def/tests/global/c.txt"); os.IsNotExist(err) { + t.Fatalf("SCP-error: %v", err) + } + + if _, err := os.Stat(u.HomeDir + "/def/tests/global/d.txt"); os.IsNotExist(err) { + t.Fatalf("SCP-error: %v", err) + } +} + // func TestSCPFileFromSSHAgent(t *testing.T) { // if os.Getenv("SSH_AUTH_SOCK") == "" { // exec.Command("eval", "`ssh-agent -s`").Run() @@ -235,6 +272,7 @@ func TestGlobList(t *testing.T) { expects = []string{"tests/a.txt", "tests/b.txt"} assert.Equal(t, expects, globList(paterns)) + // remove item which file not found. paterns = []string{"tests/aa.txt", "tests/b.txt"} expects = []string{"tests/b.txt"} assert.Equal(t, expects, globList(paterns)) diff --git a/vendor/github.com/appleboy/easyssh-proxy/easyssh.go b/vendor/github.com/appleboy/easyssh-proxy/easyssh.go index 27a074d..3f7aaeb 100644 --- a/vendor/github.com/appleboy/easyssh-proxy/easyssh.go +++ b/vendor/github.com/appleboy/easyssh-proxy/easyssh.go @@ -25,23 +25,44 @@ import ( // Port is SSH server port on remote machine. // Note: easyssh looking for private key in user's home directory (ex. /home/john + Key). // Then ensure your Key begins from '/' (ex. /.ssh/id_rsa) -type MakeConfig struct { - User string - Server string - Key string - KeyPath string - Port string - Password string - Timeout time.Duration -} +type ( + defaultConfig struct { + User string + Server string + Key string + KeyPath string + Port string + Password string + Timeout time.Duration + } -type sshConfig struct { - User string - Key string - KeyPath string - Password string - Timeout time.Duration -} + MakeConfig struct { + User string + Server string + Key string + KeyPath string + Port string + Password string + Timeout time.Duration + Proxy struct { + User string + Server string + Key string + KeyPath string + Port string + Password string + Timeout time.Duration + } + } + + sshConfig struct { + User string + Key string + KeyPath string + Password string + Timeout time.Duration + } +) // returns ssh.Signer from user you running app home path + cutted key path. // (ex. pubkey,err := getKeyFile("/.ssh/id_rsa") ) @@ -93,7 +114,10 @@ func getSSHConfig(config sshConfig) *ssh.ClientConfig { // connect to remote server using MakeConfig struct and returns *ssh.Session func (ssh_conf *MakeConfig) connect() (*ssh.Session, error) { - config := getSSHConfig(sshConfig{ + var client *ssh.Client + var err error + + targetConfig := getSSHConfig(sshConfig{ User: ssh_conf.User, Key: ssh_conf.Key, KeyPath: ssh_conf.KeyPath, @@ -101,9 +125,37 @@ func (ssh_conf *MakeConfig) connect() (*ssh.Session, error) { Timeout: ssh_conf.Timeout, }) - client, err := ssh.Dial("tcp", net.JoinHostPort(ssh_conf.Server, ssh_conf.Port), config) - if err != nil { - return nil, err + // Enable proxy command + if ssh_conf.Proxy.Server != "" { + proxyConfig := getSSHConfig(sshConfig{ + User: ssh_conf.Proxy.User, + Key: ssh_conf.Proxy.Key, + KeyPath: ssh_conf.Proxy.KeyPath, + Password: ssh_conf.Proxy.Password, + Timeout: ssh_conf.Proxy.Timeout, + }) + + proxyClient, err := ssh.Dial("tcp", net.JoinHostPort(ssh_conf.Proxy.Server, ssh_conf.Proxy.Port), proxyConfig) + if err != nil { + return nil, err + } + + conn, err := proxyClient.Dial("tcp", net.JoinHostPort(ssh_conf.Server, ssh_conf.Port)) + if err != nil { + return nil, err + } + + ncc, chans, reqs, err := ssh.NewClientConn(conn, net.JoinHostPort(ssh_conf.Server, ssh_conf.Port), targetConfig) + if err != nil { + return nil, err + } + + client = ssh.NewClient(ncc, chans, reqs) + } else { + client, err = ssh.Dial("tcp", net.JoinHostPort(ssh_conf.Server, ssh_conf.Port), targetConfig) + if err != nil { + return nil, err + } } session, err := client.NewSession() diff --git a/vendor/vendor.json b/vendor/vendor.json index 99441dc..7f8f8c6 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -11,12 +11,12 @@ "versionExact": "master" }, { - "checksumSHA1": "NCdmzR+clcl2/1jUPn0vFeqjwjk=", + "checksumSHA1": "knoaYH97GvBuW65HyXhR0CQwEJ8=", "path": "github.com/appleboy/easyssh-proxy", - "revision": "89c61a4555c1578454f75ae406f4e3cdded275d2", - "revisionTime": "2017-03-04T06:27:13Z", - "version": "=1.0.0", - "versionExact": "1.0.0" + "revision": "438121ffb50f6f6de791bceb7046e74c1d818c3d", + "revisionTime": "2017-03-04T08:24:35Z", + "version": "=1.1.0", + "versionExact": "1.1.0" }, { "checksumSHA1": "dvabztWVQX8f6oMLRyv4dLH+TGY=",