mirror of
https://github.com/appleboy/drone-ssh.git
synced 2026-03-05 22:57:00 -05:00
style: improve code readability with consistent multi-line formatting
- Add golines to the list of golangci-lint formatters - Format multi-line env variable declarations for CLI flags for consistency - Split string slice initializations onto multiple lines for improved readability in tests - Use multi-line function calls for better readability in plugin and test code - Improve readability of script command appends in logic and tests Signed-off-by: appleboy <appleboy.tw@gmail.com>
This commit is contained in:
parent
7a94dda076
commit
36b01aed49
@ -46,6 +46,7 @@ formatters:
|
||||
- gci
|
||||
- gofmt
|
||||
- goimports
|
||||
- golines
|
||||
exclusions:
|
||||
generated: lax
|
||||
paths:
|
||||
|
||||
117
main.go
117
main.go
@ -84,9 +84,14 @@ func main() {
|
||||
EnvVars: []string{"PLUGIN_SSH_KEY", "PLUGIN_KEY", "SSH_KEY", "INPUT_KEY"},
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "ssh-passphrase",
|
||||
Usage: "The purpose of the passphrase is usually to encrypt the private key.",
|
||||
EnvVars: []string{"PLUGIN_SSH_PASSPHRASE", "PLUGIN_PASSPHRASE", "SSH_PASSPHRASE", "INPUT_PASSPHRASE"},
|
||||
Name: "ssh-passphrase",
|
||||
Usage: "The purpose of the passphrase is usually to encrypt the private key.",
|
||||
EnvVars: []string{
|
||||
"PLUGIN_SSH_PASSPHRASE",
|
||||
"PLUGIN_PASSPHRASE",
|
||||
"SSH_PASSPHRASE",
|
||||
"INPUT_PASSPHRASE",
|
||||
},
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "key-path",
|
||||
@ -100,9 +105,13 @@ func main() {
|
||||
EnvVars: []string{"PLUGIN_CIPHERS", "SSH_CIPHERS", "INPUT_CIPHERS"},
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "useInsecureCipher",
|
||||
Usage: "include more ciphers with use_insecure_cipher",
|
||||
EnvVars: []string{"PLUGIN_USE_INSECURE_CIPHER", "SSH_USE_INSECURE_CIPHER", "INPUT_USE_INSECURE_CIPHER"},
|
||||
Name: "useInsecureCipher",
|
||||
Usage: "include more ciphers with use_insecure_cipher",
|
||||
EnvVars: []string{
|
||||
"PLUGIN_USE_INSECURE_CIPHER",
|
||||
"SSH_USE_INSECURE_CIPHER",
|
||||
"INPUT_USE_INSECURE_CIPHER",
|
||||
},
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "fingerprint",
|
||||
@ -118,8 +127,12 @@ func main() {
|
||||
Name: "command.timeout",
|
||||
Aliases: []string{"T"},
|
||||
Usage: "command timeout",
|
||||
EnvVars: []string{"PLUGIN_COMMAND_TIMEOUT", "SSH_COMMAND_TIMEOUT", "INPUT_COMMAND_TIMEOUT"},
|
||||
Value: 10 * time.Minute,
|
||||
EnvVars: []string{
|
||||
"PLUGIN_COMMAND_TIMEOUT",
|
||||
"SSH_COMMAND_TIMEOUT",
|
||||
"INPUT_COMMAND_TIMEOUT",
|
||||
},
|
||||
Value: 10 * time.Minute,
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Name: "script",
|
||||
@ -154,36 +167,63 @@ func main() {
|
||||
Value: "22",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "proxy.protocol",
|
||||
Usage: "The IP protocol to use for the proxy. Valid values are \"tcp\". \"tcp4\" or \"tcp6\". Default to tcp.",
|
||||
EnvVars: []string{"PLUGIN_PROXY_PROTOCOL", "SSH_PROXY_PROTOCOL", "INPUT_PROXY_PROTOCOL"},
|
||||
Value: "tcp",
|
||||
Name: "proxy.protocol",
|
||||
Usage: "The IP protocol to use for the proxy. Valid values are \"tcp\". \"tcp4\" or \"tcp6\". Default to tcp.",
|
||||
EnvVars: []string{
|
||||
"PLUGIN_PROXY_PROTOCOL",
|
||||
"SSH_PROXY_PROTOCOL",
|
||||
"INPUT_PROXY_PROTOCOL",
|
||||
},
|
||||
Value: "tcp",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "proxy.username",
|
||||
Usage: "connect as user of proxy",
|
||||
EnvVars: []string{"PLUGIN_PROXY_USERNAME", "PLUGIN_PROXY_USER", "PROXY_SSH_USERNAME", "INPUT_PROXY_USERNAME"},
|
||||
Value: "root",
|
||||
Name: "proxy.username",
|
||||
Usage: "connect as user of proxy",
|
||||
EnvVars: []string{
|
||||
"PLUGIN_PROXY_USERNAME",
|
||||
"PLUGIN_PROXY_USER",
|
||||
"PROXY_SSH_USERNAME",
|
||||
"INPUT_PROXY_USERNAME",
|
||||
},
|
||||
Value: "root",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "proxy.password",
|
||||
Usage: "user password of proxy",
|
||||
EnvVars: []string{"PLUGIN_PROXY_PASSWORD", "PROXY_SSH_PASSWORD", "INPUT_PROXY_PASSWORD"},
|
||||
Name: "proxy.password",
|
||||
Usage: "user password of proxy",
|
||||
EnvVars: []string{
|
||||
"PLUGIN_PROXY_PASSWORD",
|
||||
"PROXY_SSH_PASSWORD",
|
||||
"INPUT_PROXY_PASSWORD",
|
||||
},
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "proxy.ssh-key",
|
||||
Usage: "private ssh key of proxy",
|
||||
EnvVars: []string{"PLUGIN_PROXY_SSH_KEY", "PLUGIN_PROXY_KEY", "PROXY_SSH_KEY", "INPUT_PROXY_KEY"},
|
||||
Name: "proxy.ssh-key",
|
||||
Usage: "private ssh key of proxy",
|
||||
EnvVars: []string{
|
||||
"PLUGIN_PROXY_SSH_KEY",
|
||||
"PLUGIN_PROXY_KEY",
|
||||
"PROXY_SSH_KEY",
|
||||
"INPUT_PROXY_KEY",
|
||||
},
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "proxy.ssh-passphrase",
|
||||
Usage: "The purpose of the passphrase is usually to encrypt the private key.",
|
||||
EnvVars: []string{"PLUGIN_PROXY_SSH_PASSPHRASE", "PLUGIN_PROXY_PASSPHRASE", "PROXY_SSH_PASSPHRASE", "INPUT_PROXY_PASSPHRASE"},
|
||||
Name: "proxy.ssh-passphrase",
|
||||
Usage: "The purpose of the passphrase is usually to encrypt the private key.",
|
||||
EnvVars: []string{
|
||||
"PLUGIN_PROXY_SSH_PASSPHRASE",
|
||||
"PLUGIN_PROXY_PASSPHRASE",
|
||||
"PROXY_SSH_PASSPHRASE",
|
||||
"INPUT_PROXY_PASSPHRASE",
|
||||
},
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "proxy.key-path",
|
||||
Usage: "ssh private key path of proxy",
|
||||
EnvVars: []string{"PLUGIN_PROXY_KEY_PATH", "PROXY_SSH_KEY_PATH", "INPUT_PROXY_KEY_PATH"},
|
||||
Name: "proxy.key-path",
|
||||
Usage: "ssh private key path of proxy",
|
||||
EnvVars: []string{
|
||||
"PLUGIN_PROXY_KEY_PATH",
|
||||
"PROXY_SSH_KEY_PATH",
|
||||
"INPUT_PROXY_KEY_PATH",
|
||||
},
|
||||
},
|
||||
&cli.DurationFlag{
|
||||
Name: "proxy.timeout",
|
||||
@ -196,14 +236,23 @@ func main() {
|
||||
EnvVars: []string{"PLUGIN_PROXY_CIPHERS", "PROXY_SSH_CIPHERS", "INPUT_PROXY_CIPHERS"},
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "proxy.useInsecureCipher",
|
||||
Usage: "include more ciphers with use_insecure_cipher",
|
||||
EnvVars: []string{"PLUGIN_PROXY_USE_INSECURE_CIPHER", "PROXY_SSH_USE_INSECURE_CIPHER", "INPUT_PROXY_USE_INSECURE_CIPHER"},
|
||||
Name: "proxy.useInsecureCipher",
|
||||
Usage: "include more ciphers with use_insecure_cipher",
|
||||
EnvVars: []string{
|
||||
"PLUGIN_PROXY_USE_INSECURE_CIPHER",
|
||||
"PROXY_SSH_USE_INSECURE_CIPHER",
|
||||
"INPUT_PROXY_USE_INSECURE_CIPHER",
|
||||
},
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "proxy.fingerprint",
|
||||
Usage: "fingerprint SHA256 of the host public key, default is to skip verification",
|
||||
EnvVars: []string{"PLUGIN_PROXY_FINGERPRINT", "PROXY_SSH_FINGERPRINT", "PROXY_FINGERPRINT", "INPUT_PROXY_FINGERPRINT"},
|
||||
Name: "proxy.fingerprint",
|
||||
Usage: "fingerprint SHA256 of the host public key, default is to skip verification",
|
||||
EnvVars: []string{
|
||||
"PLUGIN_PROXY_FINGERPRINT",
|
||||
"PROXY_SSH_FINGERPRINT",
|
||||
"PROXY_FINGERPRINT",
|
||||
"INPUT_PROXY_FINGERPRINT",
|
||||
},
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Name: "envs",
|
||||
|
||||
23
plugin.go
23
plugin.go
@ -15,9 +15,11 @@ import (
|
||||
|
||||
var (
|
||||
errMissingHost = errors.New("error: missing server host")
|
||||
errMissingPasswordOrKey = errors.New("error: can't connect without a private SSH key or password")
|
||||
errCommandTimeOut = errors.New("error: command timeout")
|
||||
envsFormat = "export {NAME}={VALUE}"
|
||||
errMissingPasswordOrKey = errors.New(
|
||||
"error: can't connect without a private SSH key or password",
|
||||
)
|
||||
errCommandTimeOut = errors.New("error: command timeout")
|
||||
envsFormat = "export {NAME}={VALUE}"
|
||||
)
|
||||
|
||||
type (
|
||||
@ -119,7 +121,10 @@ func (p Plugin) exec(host string, wg *sync.WaitGroup, errChannel chan error) {
|
||||
for _, key := range p.Config.Envs {
|
||||
key = strings.ToUpper(key)
|
||||
if val, found := os.LookupEnv(key); found {
|
||||
env = append(env, p.format(p.Config.EnvsFormat, "{NAME}", key, "{VALUE}", escapeArg(val)))
|
||||
env = append(
|
||||
env,
|
||||
p.format(p.Config.EnvsFormat, "{NAME}", key, "{VALUE}", escapeArg(val)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,7 +136,10 @@ func (p Plugin) exec(host string, wg *sync.WaitGroup, errChannel chan error) {
|
||||
p.log(host, "======END======")
|
||||
}
|
||||
|
||||
stdoutChan, stderrChan, doneChan, errChan, err := ssh.Stream(strings.Join(p.Config.Script, "\n"), p.Config.CommandTimeout)
|
||||
stdoutChan, stderrChan, doneChan, errChan, err := ssh.Stream(
|
||||
strings.Join(p.Config.Script, "\n"),
|
||||
p.Config.CommandTimeout,
|
||||
)
|
||||
if err != nil {
|
||||
errChannel <- err
|
||||
return
|
||||
@ -257,7 +265,10 @@ func (p Plugin) scriptCommands() []string {
|
||||
}
|
||||
commands = append(commands, cmd)
|
||||
if p.Config.ScriptStop && cmd[(len(cmd)-1):] != "\\" {
|
||||
commands = append(commands, "DRONE_SSH_PREV_COMMAND_EXIT_CODE=$? ; if [ $DRONE_SSH_PREV_COMMAND_EXIT_CODE -ne 0 ]; then exit $DRONE_SSH_PREV_COMMAND_EXIT_CODE; fi;")
|
||||
commands = append(
|
||||
commands,
|
||||
"DRONE_SSH_PREV_COMMAND_EXIT_CODE=$? ; if [ $DRONE_SSH_PREV_COMMAND_EXIT_CODE -ne 0 ]; then exit $DRONE_SSH_PREV_COMMAND_EXIT_CODE; fi;",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -153,11 +153,15 @@ func TestSSHIPv6OnlyError(t *testing.T) {
|
||||
func TestStreamFromSSHCommand(t *testing.T) {
|
||||
plugin := Plugin{
|
||||
Config: Config{
|
||||
Host: []string{"localhost", "127.0.0.1"},
|
||||
Username: "drone-scp",
|
||||
Port: 22,
|
||||
KeyPath: "./tests/.ssh/id_rsa",
|
||||
Script: []string{"whoami", "for i in {1..5}; do echo ${i}; sleep 1; done", "echo 'done'"},
|
||||
Host: []string{"localhost", "127.0.0.1"},
|
||||
Username: "drone-scp",
|
||||
Port: 22,
|
||||
KeyPath: "./tests/.ssh/id_rsa",
|
||||
Script: []string{
|
||||
"whoami",
|
||||
"for i in {1..5}; do echo ${i}; sleep 1; done",
|
||||
"echo 'done'",
|
||||
},
|
||||
CommandTimeout: 60 * time.Second,
|
||||
},
|
||||
}
|
||||
@ -289,13 +293,20 @@ func TestSetExistingENV(t *testing.T) {
|
||||
os.Setenv("BAR", "")
|
||||
plugin := Plugin{
|
||||
Config: Config{
|
||||
Host: []string{"localhost"},
|
||||
Username: "drone-scp",
|
||||
Port: 22,
|
||||
KeyPath: "./tests/.ssh/id_rsa",
|
||||
Envs: []string{"foo", "bar", "baz"},
|
||||
Debug: true,
|
||||
Script: []string{"export FOO", "export BAR", "export BAZ", "env | grep -q '^FOO=Value for foo$'", "env | grep -q '^BAR=$'", "if env | grep -q BAZ; then false; else true; fi"},
|
||||
Host: []string{"localhost"},
|
||||
Username: "drone-scp",
|
||||
Port: 22,
|
||||
KeyPath: "./tests/.ssh/id_rsa",
|
||||
Envs: []string{"foo", "bar", "baz"},
|
||||
Debug: true,
|
||||
Script: []string{
|
||||
"export FOO",
|
||||
"export BAR",
|
||||
"export BAZ",
|
||||
"env | grep -q '^FOO=Value for foo$'",
|
||||
"env | grep -q '^BAR=$'",
|
||||
"if env | grep -q BAZ; then false; else true; fi",
|
||||
},
|
||||
CommandTimeout: 1 * time.Second,
|
||||
Proxy: easyssh.DefaultConfig{
|
||||
Server: "localhost",
|
||||
@ -313,11 +324,15 @@ func TestSetExistingENV(t *testing.T) {
|
||||
func TestSyncMode(t *testing.T) {
|
||||
plugin := Plugin{
|
||||
Config: Config{
|
||||
Host: []string{"localhost", "127.0.0.1"},
|
||||
Username: "drone-scp",
|
||||
Port: 22,
|
||||
KeyPath: "./tests/.ssh/id_rsa",
|
||||
Script: []string{"whoami", "for i in {1..3}; do echo ${i}; sleep 1; done", "echo 'done'"},
|
||||
Host: []string{"localhost", "127.0.0.1"},
|
||||
Username: "drone-scp",
|
||||
Port: 22,
|
||||
KeyPath: "./tests/.ssh/id_rsa",
|
||||
Script: []string{
|
||||
"whoami",
|
||||
"for i in {1..3}; do echo ${i}; sleep 1; done",
|
||||
"echo 'done'",
|
||||
},
|
||||
CommandTimeout: 60 * time.Second,
|
||||
Sync: true,
|
||||
},
|
||||
@ -671,7 +686,12 @@ func TestPlugin_scriptCommands(t *testing.T) {
|
||||
ScriptStop: true,
|
||||
},
|
||||
},
|
||||
want: []string{"mkdir a", "DRONE_SSH_PREV_COMMAND_EXIT_CODE=$? ; if [ $DRONE_SSH_PREV_COMMAND_EXIT_CODE -ne 0 ]; then exit $DRONE_SSH_PREV_COMMAND_EXIT_CODE; fi;", "mkdir b", "DRONE_SSH_PREV_COMMAND_EXIT_CODE=$? ; if [ $DRONE_SSH_PREV_COMMAND_EXIT_CODE -ne 0 ]; then exit $DRONE_SSH_PREV_COMMAND_EXIT_CODE; fi;"},
|
||||
want: []string{
|
||||
"mkdir a",
|
||||
"DRONE_SSH_PREV_COMMAND_EXIT_CODE=$? ; if [ $DRONE_SSH_PREV_COMMAND_EXIT_CODE -ne 0 ]; then exit $DRONE_SSH_PREV_COMMAND_EXIT_CODE; fi;",
|
||||
"mkdir b",
|
||||
"DRONE_SSH_PREV_COMMAND_EXIT_CODE=$? ; if [ $DRONE_SSH_PREV_COMMAND_EXIT_CODE -ne 0 ]; then exit $DRONE_SSH_PREV_COMMAND_EXIT_CODE; fi;",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "normal testing 2",
|
||||
@ -681,7 +701,14 @@ func TestPlugin_scriptCommands(t *testing.T) {
|
||||
ScriptStop: true,
|
||||
},
|
||||
},
|
||||
want: []string{"mkdir a", "DRONE_SSH_PREV_COMMAND_EXIT_CODE=$? ; if [ $DRONE_SSH_PREV_COMMAND_EXIT_CODE -ne 0 ]; then exit $DRONE_SSH_PREV_COMMAND_EXIT_CODE; fi;", "mkdir c", "DRONE_SSH_PREV_COMMAND_EXIT_CODE=$? ; if [ $DRONE_SSH_PREV_COMMAND_EXIT_CODE -ne 0 ]; then exit $DRONE_SSH_PREV_COMMAND_EXIT_CODE; fi;", "mkdir b", "DRONE_SSH_PREV_COMMAND_EXIT_CODE=$? ; if [ $DRONE_SSH_PREV_COMMAND_EXIT_CODE -ne 0 ]; then exit $DRONE_SSH_PREV_COMMAND_EXIT_CODE; fi;"},
|
||||
want: []string{
|
||||
"mkdir a",
|
||||
"DRONE_SSH_PREV_COMMAND_EXIT_CODE=$? ; if [ $DRONE_SSH_PREV_COMMAND_EXIT_CODE -ne 0 ]; then exit $DRONE_SSH_PREV_COMMAND_EXIT_CODE; fi;",
|
||||
"mkdir c",
|
||||
"DRONE_SSH_PREV_COMMAND_EXIT_CODE=$? ; if [ $DRONE_SSH_PREV_COMMAND_EXIT_CODE -ne 0 ]; then exit $DRONE_SSH_PREV_COMMAND_EXIT_CODE; fi;",
|
||||
"mkdir b",
|
||||
"DRONE_SSH_PREV_COMMAND_EXIT_CODE=$? ; if [ $DRONE_SSH_PREV_COMMAND_EXIT_CODE -ne 0 ]; then exit $DRONE_SSH_PREV_COMMAND_EXIT_CODE; fi;",
|
||||
},
|
||||
},
|
||||
// See: https://github.com/appleboy/ssh-action/issues/75#issuecomment-668314271
|
||||
{
|
||||
@ -692,7 +719,13 @@ func TestPlugin_scriptCommands(t *testing.T) {
|
||||
ScriptStop: true,
|
||||
},
|
||||
},
|
||||
want: []string{"ls \\", "-lah", "DRONE_SSH_PREV_COMMAND_EXIT_CODE=$? ; if [ $DRONE_SSH_PREV_COMMAND_EXIT_CODE -ne 0 ]; then exit $DRONE_SSH_PREV_COMMAND_EXIT_CODE; fi;", "mkdir a", "DRONE_SSH_PREV_COMMAND_EXIT_CODE=$? ; if [ $DRONE_SSH_PREV_COMMAND_EXIT_CODE -ne 0 ]; then exit $DRONE_SSH_PREV_COMMAND_EXIT_CODE; fi;"},
|
||||
want: []string{
|
||||
"ls \\",
|
||||
"-lah",
|
||||
"DRONE_SSH_PREV_COMMAND_EXIT_CODE=$? ; if [ $DRONE_SSH_PREV_COMMAND_EXIT_CODE -ne 0 ]; then exit $DRONE_SSH_PREV_COMMAND_EXIT_CODE; fi;",
|
||||
"mkdir a",
|
||||
"DRONE_SSH_PREV_COMMAND_EXIT_CODE=$? ; if [ $DRONE_SSH_PREV_COMMAND_EXIT_CODE -ne 0 ]; then exit $DRONE_SSH_PREV_COMMAND_EXIT_CODE; fi;",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "trim space",
|
||||
@ -938,12 +971,19 @@ func runSSHContainerTest(t *testing.T, cfg SSHTestConfig) {
|
||||
WaitingFor: wait.ForListeningPort("2222/tcp").WithStartupTimeout(180 * time.Second),
|
||||
}
|
||||
|
||||
sshContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
|
||||
ContainerRequest: req,
|
||||
Started: true,
|
||||
})
|
||||
sshContainer, err := testcontainers.GenericContainer(
|
||||
ctx,
|
||||
testcontainers.GenericContainerRequest{
|
||||
ContainerRequest: req,
|
||||
Started: true,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
t.Skipf("Could not start container with image %s: %v. Check Docker environment and image availability. Skipping test.", req.Image, err)
|
||||
t.Skipf(
|
||||
"Could not start container with image %s: %v. Check Docker environment and image availability. Skipping test.",
|
||||
req.Image,
|
||||
err,
|
||||
)
|
||||
}
|
||||
defer func() {
|
||||
if err := sshContainer.Terminate(ctx); err != nil {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user