diff --git a/plugins/ssh/plugin.go b/plugins/ssh/plugin.go new file mode 100644 index 000000000..54875bdaa --- /dev/null +++ b/plugins/ssh/plugin.go @@ -0,0 +1,22 @@ +package ssh + +import ( + "github.com/1Password/shell-plugins/sdk" + "github.com/1Password/shell-plugins/sdk/schema" +) + +func New() schema.Plugin { + return schema.Plugin{ + Name: "ssh", + Platform: schema.PlatformInfo{ + Name: "SSH", + Homepage: sdk.URL("https://www.openssh.com"), + }, + Credentials: []schema.CredentialType{ + UserLogin(), + }, + Executables: []schema.Executable{ + SSHCLI(), + }, + } +} diff --git a/plugins/ssh/sshpass.go b/plugins/ssh/sshpass.go new file mode 100644 index 000000000..bd0b3b5c8 --- /dev/null +++ b/plugins/ssh/sshpass.go @@ -0,0 +1,24 @@ +package ssh + +import ( + "github.com/1Password/shell-plugins/sdk" + "github.com/1Password/shell-plugins/sdk/needsauth" + "github.com/1Password/shell-plugins/sdk/schema" + "github.com/1Password/shell-plugins/sdk/schema/credname" +) + +func SSHCLI() schema.Executable { + return schema.Executable{ + Name: "SSH CLI", + Runs: []string{"sshpass"}, + DocsURL: sdk.URL("https://linux.die.net/man/1/sshpass"), + NeedsAuth: needsauth.IfAll( + needsauth.NotForHelpOrVersion(), + ), + Uses: []schema.CredentialUsage{ + { + Name: credname.UserLogin, + }, + }, + } +} diff --git a/plugins/ssh/user_login.go b/plugins/ssh/user_login.go new file mode 100644 index 000000000..2f1b449e2 --- /dev/null +++ b/plugins/ssh/user_login.go @@ -0,0 +1,51 @@ +package ssh + +import ( + "context" + "github.com/1Password/shell-plugins/sdk/importer" + + "github.com/1Password/shell-plugins/sdk" + "github.com/1Password/shell-plugins/sdk/schema" + "github.com/1Password/shell-plugins/sdk/schema/credname" + "github.com/1Password/shell-plugins/sdk/schema/fieldname" +) + +func UserLogin() schema.CredentialType { + return schema.CredentialType{ + Name: credname.UserLogin, + DocsURL: sdk.URL("https://linux.die.net/man/1/sshpass"), + Fields: []schema.CredentialField{ + { + Name: fieldname.Host, + AlternativeNames: []string{fieldname.HostAddress.String(), fieldname.URL.String()}, + MarkdownDescription: "SSH Host to connect to.", + }, + { + Name: fieldname.Username, + MarkdownDescription: "User to authenticate as.", + }, + { + Name: fieldname.Password, + MarkdownDescription: "Password used to authenticate.", + Secret: true, + }, + }, + DefaultProvisioner: sshProvisioner{}, + Importer: importer.NoOp(), + } +} + +type sshProvisioner struct{} + +func (s sshProvisioner) Description() string { + return "SSH password provisioner" +} + +func (s sshProvisioner) Provision(_ context.Context, input sdk.ProvisionInput, output *sdk.ProvisionOutput) { + output.AddArgs("-p", input.ItemFields[fieldname.Password], + "ssh", input.ItemFields[fieldname.Username]+"@"+input.ItemFields[fieldname.Host]) +} + +func (s sshProvisioner) Deprovision(_ context.Context, _ sdk.DeprovisionInput, _ *sdk.DeprovisionOutput) { + // no-op +} diff --git a/plugins/ssh/user_login_test.go b/plugins/ssh/user_login_test.go new file mode 100644 index 000000000..d4723d444 --- /dev/null +++ b/plugins/ssh/user_login_test.go @@ -0,0 +1,24 @@ +package ssh + +import ( + "testing" + + "github.com/1Password/shell-plugins/sdk" + "github.com/1Password/shell-plugins/sdk/plugintest" + "github.com/1Password/shell-plugins/sdk/schema/fieldname" +) + +func TestUserLoginProvisioner(t *testing.T) { + plugintest.TestProvisioner(t, UserLogin().DefaultProvisioner, map[string]plugintest.ProvisionCase{ + "default": { + ItemFields: map[sdk.FieldName]string{ + fieldname.Password: "zhexample", + fieldname.Username: "user", + fieldname.Host: "192.168.1.20", + }, + ExpectedOutput: sdk.ProvisionOutput{ + CommandLine: []string{"-p", "zhexample", "ssh", "user@192.168.1.20"}, + }, + }, + }) +}