mirror of
https://github.com/appleboy/drone-ssh.git
synced 2025-05-09 18:23:21 +08:00
feat: Support proxy command. (#55)
This commit is contained in:
parent
7e4e0224ee
commit
530df8d98b
46
main.go
46
main.go
@ -77,6 +77,43 @@ func main() {
|
|||||||
Name: "env-file",
|
Name: "env-file",
|
||||||
Usage: "source 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,user",
|
||||||
|
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
|
// Override a template
|
||||||
@ -131,6 +168,15 @@ func run(c *cli.Context) error {
|
|||||||
Timeout: c.Duration("timeout"),
|
Timeout: c.Duration("timeout"),
|
||||||
CommandTimeout: c.Int("command.timeout"),
|
CommandTimeout: c.Int("command.timeout"),
|
||||||
Script: c.StringSlice("script"),
|
Script: c.StringSlice("script"),
|
||||||
|
Proxy: defaultConfig{
|
||||||
|
Key: c.String("proxy.ssh-key"),
|
||||||
|
KeyPath: c.String("proxy.key-path"),
|
||||||
|
User: c.String("proxy.user"),
|
||||||
|
Password: c.String("proxy.password"),
|
||||||
|
Server: c.String("proxy.host"),
|
||||||
|
Port: c.String("proxy.port"),
|
||||||
|
Timeout: c.Duration("proxy.timeout"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
plugin.go
20
plugin.go
@ -19,6 +19,16 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
defaultConfig struct {
|
||||||
|
User string
|
||||||
|
Server string
|
||||||
|
Key string
|
||||||
|
KeyPath string
|
||||||
|
Port string
|
||||||
|
Password string
|
||||||
|
Timeout time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
// Config for the plugin.
|
// Config for the plugin.
|
||||||
Config struct {
|
Config struct {
|
||||||
Key string
|
Key string
|
||||||
@ -30,6 +40,7 @@ type (
|
|||||||
Timeout time.Duration
|
Timeout time.Duration
|
||||||
CommandTimeout int
|
CommandTimeout int
|
||||||
Script []string
|
Script []string
|
||||||
|
Proxy defaultConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// Plugin structure
|
// Plugin structure
|
||||||
@ -66,6 +77,15 @@ func (p Plugin) Exec() error {
|
|||||||
Key: p.Config.Key,
|
Key: p.Config.Key,
|
||||||
KeyPath: p.Config.KeyPath,
|
KeyPath: p.Config.KeyPath,
|
||||||
Timeout: p.Config.Timeout,
|
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,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
p.log(host, "commands: ", strings.Join(p.Config.Script, "\n"))
|
p.log(host, "commands: ", strings.Join(p.Config.Script, "\n"))
|
||||||
|
@ -134,3 +134,25 @@ func TestSSHCommandNotFound(t *testing.T) {
|
|||||||
err := plugin.Exec()
|
err := plugin.Exec()
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestProxyCommand(t *testing.T) {
|
||||||
|
plugin := Plugin{
|
||||||
|
Config: Config{
|
||||||
|
Host: []string{"localhost"},
|
||||||
|
UserName: "drone-scp",
|
||||||
|
Port: 22,
|
||||||
|
KeyPath: "./tests/.ssh/id_rsa",
|
||||||
|
Script: []string{"whoami"},
|
||||||
|
CommandTimeout: 1,
|
||||||
|
Proxy: defaultConfig{
|
||||||
|
Server: "localhost",
|
||||||
|
User: "drone-scp",
|
||||||
|
Port: "22",
|
||||||
|
KeyPath: "./tests/.ssh/id_rsa",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
err := plugin.Exec()
|
||||||
|
assert.Nil(t, err)
|
||||||
|
}
|
||||||
|
64
vendor/github.com/appleboy/easyssh-proxy/easyssh.go
generated
vendored
64
vendor/github.com/appleboy/easyssh-proxy/easyssh.go
generated
vendored
@ -25,7 +25,8 @@ import (
|
|||||||
// Port is SSH server port on remote machine.
|
// Port is SSH server port on remote machine.
|
||||||
// Note: easyssh looking for private key in user's home directory (ex. /home/john + Key).
|
// 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)
|
// Then ensure your Key begins from '/' (ex. /.ssh/id_rsa)
|
||||||
type MakeConfig struct {
|
type (
|
||||||
|
defaultConfig struct {
|
||||||
User string
|
User string
|
||||||
Server string
|
Server string
|
||||||
Key string
|
Key string
|
||||||
@ -33,15 +34,35 @@ type MakeConfig struct {
|
|||||||
Port string
|
Port string
|
||||||
Password string
|
Password string
|
||||||
Timeout time.Duration
|
Timeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
type sshConfig struct {
|
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
|
User string
|
||||||
Key string
|
Key string
|
||||||
KeyPath string
|
KeyPath string
|
||||||
Password string
|
Password string
|
||||||
Timeout time.Duration
|
Timeout time.Duration
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// returns ssh.Signer from user you running app home path + cutted key path.
|
// returns ssh.Signer from user you running app home path + cutted key path.
|
||||||
// (ex. pubkey,err := getKeyFile("/.ssh/id_rsa") )
|
// (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
|
// connect to remote server using MakeConfig struct and returns *ssh.Session
|
||||||
func (ssh_conf *MakeConfig) connect() (*ssh.Session, error) {
|
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,
|
User: ssh_conf.User,
|
||||||
Key: ssh_conf.Key,
|
Key: ssh_conf.Key,
|
||||||
KeyPath: ssh_conf.KeyPath,
|
KeyPath: ssh_conf.KeyPath,
|
||||||
@ -101,11 +125,39 @@ func (ssh_conf *MakeConfig) connect() (*ssh.Session, error) {
|
|||||||
Timeout: ssh_conf.Timeout,
|
Timeout: ssh_conf.Timeout,
|
||||||
})
|
})
|
||||||
|
|
||||||
client, err := ssh.Dial("tcp", net.JoinHostPort(ssh_conf.Server, ssh_conf.Port), config)
|
// 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 {
|
if err != nil {
|
||||||
return nil, err
|
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()
|
session, err := client.NewSession()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
10
vendor/vendor.json
vendored
10
vendor/vendor.json
vendored
@ -3,12 +3,12 @@
|
|||||||
"ignore": "test",
|
"ignore": "test",
|
||||||
"package": [
|
"package": [
|
||||||
{
|
{
|
||||||
"checksumSHA1": "NCdmzR+clcl2/1jUPn0vFeqjwjk=",
|
"checksumSHA1": "knoaYH97GvBuW65HyXhR0CQwEJ8=",
|
||||||
"path": "github.com/appleboy/easyssh-proxy",
|
"path": "github.com/appleboy/easyssh-proxy",
|
||||||
"revision": "89c61a4555c1578454f75ae406f4e3cdded275d2",
|
"revision": "438121ffb50f6f6de791bceb7046e74c1d818c3d",
|
||||||
"revisionTime": "2017-03-04T06:27:13Z",
|
"revisionTime": "2017-03-04T08:24:35Z",
|
||||||
"version": "=1.0.0",
|
"version": "=1.1.0",
|
||||||
"versionExact": "1.0.0"
|
"versionExact": "1.1.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "dvabztWVQX8f6oMLRyv4dLH+TGY=",
|
"checksumSHA1": "dvabztWVQX8f6oMLRyv4dLH+TGY=",
|
||||||
|
Loading…
Reference in New Issue
Block a user