mirror of
https://github.com/appleboy/drone-scp.git
synced 2026-06-04 10:15:05 +08:00
feat: Support scp files from proxy command. (#47)
* feat: Support scp files from proxy command.
This commit is contained in:
@@ -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"),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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))
|
||||
|
||||
+72
-20
@@ -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()
|
||||
|
||||
Vendored
+5
-5
@@ -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=",
|
||||
|
||||
Reference in New Issue
Block a user