diff --git a/DOCS.md b/DOCS.md index e8da985..c9adca1 100644 --- a/DOCS.md +++ b/DOCS.md @@ -8,6 +8,7 @@ The following parameters are used to configure the plugin: * **host** - address or IP of the remote machine * **port** - port to connect to on the remote machine * **user** - user to log in as on the remote machine +* **passsword** - password to log in as on the remote machine * **key** - private SSH key for the remote machine * **sleep** - sleep for seconds between host connections * **timeout** - timeout for the tcp connection attempt @@ -18,16 +19,19 @@ The following secret values can be set to configure the plugin. * **SSH_HOST** - corresponds to **host** * **SSH_PORT** - corresponds to **port** * **SSH_USER** - corresponds to **user** +* **SSH_PASSWORD** - corresponds to **password** * **SSH_KEY** - corresponds to **key** * **SSH_SLEEP** - corresponds to **sleep** * **SSH_TIMEOUT** - corresponds to **timeout** -It is highly recommended to put the **SSH_KEY** into a secret so it is not +It is highly recommended to put the **SSH_KEY** and **SSH_PASSWORD** into a secret so it is not exposed to users. This can be done using the drone-cli. ```bash drone secret add --image=plugins/ssh \ octocat/hello-world SSH_KEY @path/to/.ssh/id_rsa +drone secret add --image=plugins/ssh \ + octocat/hello-world SSH_PASSWORD admin1234 ``` Then sign the YAML file after all secrets are added. @@ -49,6 +53,7 @@ pipeline: image: plugins/ssh host: foo.com user: root + password: 1234 port: 22 script: - echo hello diff --git a/README.md b/README.md index 6d63019..b3f5b02 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Build the docker image with the following commands: ``` CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -tags netgo -docker build --rm=true -t plugins/ssh . +docker build -t plugins/ssh . ``` Please note incorrectly building the image for the correct x64 linux and with @@ -45,7 +45,7 @@ docker run --rm \ -e PLUGIN_USER=root \ -e PLUGIN_KEY="$(cat ${HOME}/.ssh/id_rsa)" \ -e PLUGIN_SCRIPT=whoami \ - -v $(pwd)/$(pwd) \ + -v $(pwd):$(pwd) \ -w $(pwd) \ plugins/ssh ``` diff --git a/main.go b/main.go index c928412..cee0403 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,7 @@ import ( "github.com/Sirupsen/logrus" "github.com/joho/godotenv" + _ "github.com/joho/godotenv/autoload" "github.com/urfave/cli" ) @@ -29,6 +30,11 @@ func main() { EnvVar: "PLUGIN_USER,SSH_USER", Value: "root", }, + cli.StringFlag{ + Name: "password", + Usage: "user password", + EnvVar: "PLUGIN_PASSWORD,SSH_PASSWORD", + }, cli.StringSliceFlag{ Name: "host", Usage: "connect to host", @@ -75,6 +81,7 @@ func run(c *cli.Context) error { Config: Config{ Key: c.String("ssh-key"), User: c.String("user"), + Password: c.String("password"), Host: c.StringSlice("host"), Port: c.Int("port"), Sleep: c.Int("sleep"), diff --git a/plugin.go b/plugin.go index 1cf7a4c..bdd9dca 100644 --- a/plugin.go +++ b/plugin.go @@ -13,13 +13,14 @@ import ( type ( Config struct { - Key string `json:"key"` - User string `json:"user"` - Host []string `json:"host"` - Port int `json:"port"` - Sleep int `json:"sleep"` - Timeout time.Duration `json:"timeout"` - Script []string `json:"script"` + Key string + User string + Password string + Host []string + Port int + Sleep int + Timeout time.Duration + Script []string } Plugin struct { @@ -28,8 +29,8 @@ type ( ) func (p Plugin) Exec() error { - if p.Config.Key == "" { - return fmt.Errorf("Error: Can't connect without a private SSH key.") + if p.Config.Key == "" && p.Config.Password == "" { + return fmt.Errorf("Error: Can't connect without a private SSH key or password.") } for i, host := range p.Config.Host { @@ -38,18 +39,28 @@ func (p Plugin) Exec() error { strconv.Itoa(p.Config.Port), ) - signer, err := ssh.ParsePrivateKey([]byte(p.Config.Key)) + // auths holds the detected ssh auth methods + auths := []ssh.AuthMethod{} - if err != nil { - return fmt.Errorf("Error: Failed to parse private key. %s", err) + if p.Config.Key != "" { + signer, err := ssh.ParsePrivateKey([]byte(p.Config.Key)) + + if err != nil { + return fmt.Errorf("Error: Failed to parse private key. %s", err) + } + + auths = append(auths, ssh.PublicKeys(signer)) + } + + // figure out what auths are requested, what is supported + if p.Config.Password != "" { + auths = append(auths, ssh.Password(p.Config.Password)) } config := &ssh.ClientConfig{ Timeout: p.Config.Timeout, User: p.Config.User, - Auth: []ssh.AuthMethod{ - ssh.PublicKeys(signer), - }, + Auth: auths, } fmt.Printf("+ ssh %s@%s -p %d\n", p.Config.User, addr, p.Config.Port) diff --git a/vendor/github.com/joho/godotenv/autoload/autoload.go b/vendor/github.com/joho/godotenv/autoload/autoload.go new file mode 100644 index 0000000..fbcd2bd --- /dev/null +++ b/vendor/github.com/joho/godotenv/autoload/autoload.go @@ -0,0 +1,15 @@ +package autoload + +/* + You can just read the .env file on import just by doing + + import _ "github.com/joho/godotenv/autoload" + + And bob's your mother's brother +*/ + +import "github.com/joho/godotenv" + +func init() { + godotenv.Load() +}