runssh 0.2.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +22 -8
- data/README.rdoc +39 -9
- data/bin/runssh_comp.sh +1 -1
- data/features/add_bookmarks.feature +58 -0
- data/features/cli_help.feature +32 -0
- data/features/copy_id.feature +26 -0
- data/features/delete_bookmarks.feature +45 -0
- data/features/export_bookmarks.feature +19 -0
- data/features/import_bookmarks.feature +35 -0
- data/features/print_bookmarks.feature +42 -0
- data/features/run_shell.feature +83 -0
- data/features/step_definitions/argument_steps.rb +51 -0
- data/features/step_definitions/bookmarks_steps.rb +109 -0
- data/features/step_definitions/output_steps.rb +77 -0
- data/features/support/env.rb +36 -0
- data/features/update_bookmarks.feature +24 -0
- data/lib/runsshlib/cli.rb +248 -120
- data/lib/runsshlib/ssh_backend.rb +34 -4
- data/lib/runsshlib/ssh_host_def.rb +12 -2
- data/lib/runsshlib/version.rb +3 -3
- data/lib/runsshlib.rb +3 -0
- data/runssh.gemspec +0 -5
- data/spec/runsshlib/cli_spec.rb +181 -319
- data/spec/runsshlib/config_file_spec.rb +3 -5
- data/spec/runsshlib/ssh_backend_spec.rb +48 -3
- data/spec/runsshlib/ssh_host_def_spec.rb +5 -1
- data/spec/spec_helper.rb +4 -65
- data/spec/support/utils.rb +149 -0
- metadata +34 -86
data/.gitignore
CHANGED
data/Gemfile
CHANGED
@@ -2,3 +2,13 @@ source "http://rubygems.org"
|
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in testme.gemspec
|
4
4
|
gemspec
|
5
|
+
|
6
|
+
group :test do
|
7
|
+
gem 'rspec', '~> 2.1.0'
|
8
|
+
gem 'simplecov', '~> 0.3.9', :require => false
|
9
|
+
gem 'autotest', '4.4.6'
|
10
|
+
gem 'autotest-fsevent', '0.2.4'
|
11
|
+
gem 'autotest-growl', '0.2.9'
|
12
|
+
gem 'cucumber', "0.10.0"
|
13
|
+
gem 'rake', ">= 0.8.7"
|
14
|
+
end
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
runssh (0.
|
4
|
+
runssh (0.3.0.beta.3)
|
5
5
|
highline (~> 1.6.1)
|
6
6
|
trollop (~> 1.16.2)
|
7
7
|
|
@@ -14,9 +14,19 @@ GEM
|
|
14
14
|
autotest-fsevent (0.2.4)
|
15
15
|
sys-uname
|
16
16
|
autotest-growl (0.2.9)
|
17
|
+
builder (3.0.0)
|
18
|
+
cucumber (0.10.0)
|
19
|
+
builder (>= 2.1.2)
|
20
|
+
diff-lcs (~> 1.1.2)
|
21
|
+
gherkin (~> 2.3.2)
|
22
|
+
json (~> 1.4.6)
|
23
|
+
term-ansicolor (~> 1.0.5)
|
17
24
|
diff-lcs (1.1.2)
|
25
|
+
gherkin (2.3.3)
|
26
|
+
json (~> 1.4.6)
|
18
27
|
highline (1.6.1)
|
19
|
-
|
28
|
+
json (1.4.6)
|
29
|
+
rake (0.8.7)
|
20
30
|
rspec (2.1.0)
|
21
31
|
rspec-core (~> 2.1.0)
|
22
32
|
rspec-expectations (~> 2.1.0)
|
@@ -25,18 +35,22 @@ GEM
|
|
25
35
|
rspec-expectations (2.1.0)
|
26
36
|
diff-lcs (~> 1.1.2)
|
27
37
|
rspec-mocks (2.1.0)
|
38
|
+
simplecov (0.3.9)
|
39
|
+
simplecov-html (>= 0.3.7)
|
40
|
+
simplecov-html (0.3.9)
|
28
41
|
sys-uname (0.8.5)
|
42
|
+
term-ansicolor (1.0.5)
|
29
43
|
trollop (1.16.2)
|
30
44
|
|
31
45
|
PLATFORMS
|
32
46
|
ruby
|
33
47
|
|
34
48
|
DEPENDENCIES
|
35
|
-
autotest (
|
36
|
-
autotest-fsevent (
|
37
|
-
autotest-growl (
|
38
|
-
|
39
|
-
|
49
|
+
autotest (= 4.4.6)
|
50
|
+
autotest-fsevent (= 0.2.4)
|
51
|
+
autotest-growl (= 0.2.9)
|
52
|
+
cucumber (= 0.10.0)
|
53
|
+
rake (>= 0.8.7)
|
40
54
|
rspec (~> 2.1.0)
|
41
55
|
runssh!
|
42
|
-
|
56
|
+
simplecov (~> 0.3.9)
|
data/README.rdoc
CHANGED
@@ -1,6 +1,16 @@
|
|
1
1
|
== Introduction
|
2
|
-
A CLI utility to bookmark ssh connections with hierarchy and
|
3
|
-
these bookmarks.
|
2
|
+
A CLI utility to bookmark ssh connections with hierarchy and run various
|
3
|
+
ssh commands on these bookmarks. Supported operations are:
|
4
|
+
|
5
|
+
* Login
|
6
|
+
* Copy ssh key
|
7
|
+
* Run remote command
|
8
|
+
* Create local tunnel
|
9
|
+
|
10
|
+
I am planning to add scp support as well.
|
11
|
+
|
12
|
+
This requires you to have the _ssh_ binary in your path and optionally the
|
13
|
+
<i>ssh-copy-id</i> binary (for copying ssh key).
|
4
14
|
|
5
15
|
=== Installation
|
6
16
|
You must have ruby[http://www.ruby-lang.org/] and
|
@@ -29,8 +39,8 @@ For usage run _runssh_ without arguments.
|
|
29
39
|
|
30
40
|
=== Host Definition
|
31
41
|
Host definition is a collection of attributes that help us define a host
|
32
|
-
bookmark.
|
33
|
-
|
42
|
+
bookmark. The only required attribute is a hostname. All other attributes
|
43
|
+
(login, remote command, local tunnel info, ssh option, etc) is optional.
|
34
44
|
|
35
45
|
=== Bookmarks
|
36
46
|
The bookmarks consists of a host definition inside nested groups. These
|
@@ -70,7 +80,7 @@ This program is distributed under the GPL v2 license.
|
|
70
80
|
== History
|
71
81
|
|
72
82
|
=== 0.1.0
|
73
|
-
* Initial release. Simple bookmarks (host and user),only _shell_ operation
|
83
|
+
* Initial release. Simple bookmarks (host and user),only _shell_ operation
|
74
84
|
supported.
|
75
85
|
|
76
86
|
=== 0.1.1
|
@@ -93,12 +103,32 @@ This program is distributed under the GPL v2 license.
|
|
93
103
|
* Enabled definition of (local) ssh tunneling. Currently only in the
|
94
104
|
+shell+ command.
|
95
105
|
|
106
|
+
=== 0.3
|
107
|
+
* The print subcommand now prints the local tunnel if defined.
|
108
|
+
* It's possible to bookmark (local) tunnels.
|
109
|
+
* Remote command are run with pseudo terminal (ssh -t) by default. Can be
|
110
|
+
disabled with -T.
|
111
|
+
* Added (_unsafe_) option for deleting conflicting host key - The conflicting
|
112
|
+
line must be specified manually (probably from the error message in the
|
113
|
+
previous command), and currently we only deal with <code>~/.ssh/known_hosts</code>
|
114
|
+
file.
|
115
|
+
* Added ssh options support. These could be specified when saving or when
|
116
|
+
running shell. As an _unsafe_ shortcut, there is an option to connect
|
117
|
+
to a host without verifying the key. This is mainly useful for local
|
118
|
+
virtual machines, or similar occasion where security is not an issue.
|
119
|
+
* Implemented copying public key to remote host's authorized_keys file (via
|
120
|
+
ssh-copy-id).
|
121
|
+
* Documentation fixes.
|
122
|
+
* Changed behavior upon prompt cancellation (in _delete_ and _import_) - It now
|
123
|
+
aborts execution instead of exit 0.
|
124
|
+
* Some code refactoring (CLI class).
|
125
|
+
* CLI Tests refactorings:
|
126
|
+
* Created cucumber features.
|
127
|
+
* Fixed tests to test features and not implementations.
|
128
|
+
|
96
129
|
== TODO
|
97
|
-
* Refactor of RunSSHLib::CLI to avoid repetition of so many options between
|
98
|
-
_add_, _update_ and _shell_.
|
99
130
|
* Create a _proper_ zsh completion script.
|
100
|
-
* Add scp capabilities
|
101
|
-
* Add support for bookmarking tunnels
|
131
|
+
* Add scp capabilities.
|
102
132
|
* Shell via gateway (connect to a firewall and from there open shell to the host).
|
103
133
|
* Rename (or move) host definition
|
104
134
|
* Maybe replace invoking ssh from the command line with some library.
|
data/bin/runssh_comp.sh
CHANGED
@@ -14,7 +14,7 @@ function _runssh () {
|
|
14
14
|
options=$(${COMP_WORDS[@]:0:COMP_CWORD} ? 2>/dev/null) # BASH
|
15
15
|
# options=$(${COMP_WORDS[0,COMP_CWORD-1]} ? 2>/dev/null) # ZSH
|
16
16
|
elif [ $COMP_CWORD -eq $COM_POSITION ]; then
|
17
|
-
options="shell add del update print import export"
|
17
|
+
options="shell cpid add del update print import export"
|
18
18
|
fi
|
19
19
|
COMPREPLY=( $(compgen -W "${options}" -- ${cur}) )
|
20
20
|
return 0
|
@@ -0,0 +1,58 @@
|
|
1
|
+
Feature: Adding bookmarks
|
2
|
+
In order to make it easier to remember all the hosts I have to connect
|
3
|
+
I want to be able to store them in a logical way so I can easily retrieve them.
|
4
|
+
|
5
|
+
The bookmarks will be arranged in groups so it'll be easier to navigate
|
6
|
+
logically to find a host bookmark. e.g., In order to connect to the mail
|
7
|
+
server in the office of a certain customer, I might save this bookmark as:
|
8
|
+
customer1 => office => mail_server.
|
9
|
+
|
10
|
+
Scenario: Automatically creating database
|
11
|
+
Given No database
|
12
|
+
When I bookmark host: "some.host.com" as "group1 somehost"
|
13
|
+
Then It should run successfully
|
14
|
+
And A database should be created
|
15
|
+
And Bookmark: "group1 somehost" should point to "some.host.com"
|
16
|
+
|
17
|
+
Scenario: All available options
|
18
|
+
Given Empty database
|
19
|
+
When I run the "add" command with "one two three -n some.host -l mylogin -L 8080:localhost:8080 -o StrictHostKeyChecking=no"
|
20
|
+
Then It should run successfully
|
21
|
+
And Bookmark "one two three" should contain:
|
22
|
+
| name | value |
|
23
|
+
| host_name | some.host |
|
24
|
+
| login | mylogin |
|
25
|
+
| local_tunnel | 8080:localhost:8080 |
|
26
|
+
| option | StrictHostKeyChecking=no |
|
27
|
+
|
28
|
+
Scenario: Shortcut for insecure connection (no known_hosts)
|
29
|
+
Given Empty database
|
30
|
+
When I run the "add" command with "one two three -n some.host --no-host-key-checking"
|
31
|
+
Then It should run successfully
|
32
|
+
And Bookmark "one two three" should contain:
|
33
|
+
| name | value |
|
34
|
+
| host_name | some.host |
|
35
|
+
| option | StrictHostKeyChecking=no |
|
36
|
+
| option | UserKnownHostsFile=/dev/null |
|
37
|
+
|
38
|
+
Scenario: Automatic database backup
|
39
|
+
Given Existing database
|
40
|
+
When I bookmark host: "somehost" as "group somehost"
|
41
|
+
Then It should run successfully
|
42
|
+
And A backup database should be created with ".bak" suffix
|
43
|
+
|
44
|
+
Scenario: Adding host
|
45
|
+
Given Empty database
|
46
|
+
When I bookmark host: "somehost" as "group somehost"
|
47
|
+
Then It should run successfully
|
48
|
+
And Bookmark: "group somehost" should point to "somehost"
|
49
|
+
|
50
|
+
Scenario: Required hostname
|
51
|
+
Given Empty database
|
52
|
+
When I bookmark host: "" as "group somehost"
|
53
|
+
Then I should get a "option '-n' needs a parameter" error
|
54
|
+
|
55
|
+
Scenario: Overwriting bookmark is forbidden
|
56
|
+
Given Bookmark "group subgroup" exists
|
57
|
+
When I bookmark host: "host" as "group subgroup"
|
58
|
+
Then I should get a "path already exist!" error
|
@@ -0,0 +1,32 @@
|
|
1
|
+
Feature: Cli help
|
2
|
+
In order to know how to run the command
|
3
|
+
As a user
|
4
|
+
I want get assistance about the command.
|
5
|
+
|
6
|
+
Scenario: Running without arguments
|
7
|
+
When I run without arguments
|
8
|
+
Then It should exit normally
|
9
|
+
And The output should include "Usage: runssh \[global_options\] COMMAND \[options\] <path>"
|
10
|
+
And The output should include "Available commands:"
|
11
|
+
|
12
|
+
Scenario: Running with 'help' subcommand (and no further arguments)
|
13
|
+
When I run the "help" command with ""
|
14
|
+
Then It should exit normally
|
15
|
+
And The output should include "Usage: runssh \[global_options\] COMMAND \[options\] <path>"
|
16
|
+
And The output should include "Available commands:"
|
17
|
+
|
18
|
+
Scenario Outline: Subcommand help
|
19
|
+
When I run the "help" command with "<subcommand>"
|
20
|
+
Then It should exit normally
|
21
|
+
And The output should include "<output>"
|
22
|
+
|
23
|
+
Scenarios: Various subcommands help
|
24
|
+
| subcommand | output |
|
25
|
+
| shell | Connect to the specified host using ssh. |
|
26
|
+
| add | Add a new host definition at the supplied <path> |
|
27
|
+
| del | Delete host definitions or `empty` groups |
|
28
|
+
| update | Update host definition specified by <path> |
|
29
|
+
| print | Print host configuration to the console. |
|
30
|
+
| import | Imports a configuration. |
|
31
|
+
| export | Exports the configuration to a YAML file. |
|
32
|
+
| cpid | Copy ssh public key to authorized_keys |
|
@@ -0,0 +1,26 @@
|
|
1
|
+
Feature: Using ssh-copy-id to copy ssh keys to remote host
|
2
|
+
In order to be able to login to remote host using key based ssh authentication
|
3
|
+
I want to be able to copy my ssh private key to the remote host named by the
|
4
|
+
bookmark.
|
5
|
+
|
6
|
+
Scenario: Normal usage (no user info)
|
7
|
+
Given Bookmark "some host" exist with:
|
8
|
+
| name | value |
|
9
|
+
| host-name | some.host |
|
10
|
+
When I run the "cpid" command with "some host"
|
11
|
+
Then It should execute "ssh-copy-id some.host"
|
12
|
+
|
13
|
+
Scenario: Normal usage (with user info)
|
14
|
+
Given Bookmark "some host" exist with:
|
15
|
+
| name | value |
|
16
|
+
| host-name | some.host |
|
17
|
+
| login | someone |
|
18
|
+
When I run the "cpid" command with "some host"
|
19
|
+
Then It should execute "ssh-copy-id someone@some.host"
|
20
|
+
|
21
|
+
Scenario: Specifying identity
|
22
|
+
Given Bookmark "some host" exist with:
|
23
|
+
| name | value |
|
24
|
+
| host-name | some.host |
|
25
|
+
When I run the "cpid" command with "-i ~/.ssh/id_dsa some host"
|
26
|
+
Then It should execute "ssh-copy-id -i ~/.ssh/id_dsa some.host"
|
@@ -0,0 +1,45 @@
|
|
1
|
+
Feature: Deleting bookmarks
|
2
|
+
In order to remove old/invalid host definitions or empty groups
|
3
|
+
I want to be able to delete them by specifying the path.
|
4
|
+
|
5
|
+
Scenario: Deleting existing host definition
|
6
|
+
Given Bookmark "one two three" exists
|
7
|
+
When I delete "one two three"
|
8
|
+
And I confirm the prompt
|
9
|
+
Then It should run successfully
|
10
|
+
And Bookmark "one two three" should not exist
|
11
|
+
|
12
|
+
Scenario: Approving deletion with -y option
|
13
|
+
Given Bookmark "one two three" exists
|
14
|
+
When I delete "one two three" with confirmation
|
15
|
+
Then It should run successfully
|
16
|
+
And Bookmark "one two three" should not exist
|
17
|
+
|
18
|
+
Scenario: Cancel deletion upon dis-approving confirmation
|
19
|
+
Given Bookmark "one two three" exists
|
20
|
+
When I delete "one two three"
|
21
|
+
And I answer "no" at the prompt
|
22
|
+
Then I should get a "Cancelled" error
|
23
|
+
And Bookmark "one two three" should exist
|
24
|
+
|
25
|
+
Scenario: Prompting before deleting
|
26
|
+
Given Bookmark "one two three" exists
|
27
|
+
When I delete "one two three"
|
28
|
+
Then I should be prompted with "Are you sure you want to delete"
|
29
|
+
|
30
|
+
Scenario: Displaying error when deleting non-existing bookmarks
|
31
|
+
Given Empty database
|
32
|
+
When I delete "one two three" with confirmation
|
33
|
+
Then I should get a "Invalid path!" error
|
34
|
+
|
35
|
+
Scenario: Deleting empty groups
|
36
|
+
Given Bookmark "one two" is an empty group
|
37
|
+
When I delete "one two"
|
38
|
+
And I confirm the prompt
|
39
|
+
Then It should run successfully
|
40
|
+
And Bookmark "one two" should not exist
|
41
|
+
|
42
|
+
Scenario: Refusing to delete non-empty groups
|
43
|
+
Given Bookmark "one two three" exists
|
44
|
+
When I delete "one two" with confirmation
|
45
|
+
Then I should get a "on-empty group!" error
|
@@ -0,0 +1,19 @@
|
|
1
|
+
Feature: Export bookmarks
|
2
|
+
In order to view a list of all my bookmarks
|
3
|
+
I want be able to export it to readable format.
|
4
|
+
|
5
|
+
The export feature dumps the database into YAML file. This file
|
6
|
+
could be edited and later imported into the database.
|
7
|
+
|
8
|
+
Scenario: Missing required output file argument
|
9
|
+
Given Existing database
|
10
|
+
When I run the "export" command with "one two"
|
11
|
+
Then I should get a "Error: option --output-file must be specified" error
|
12
|
+
|
13
|
+
Scenario: Exporting bookmarks
|
14
|
+
Given Bookmark "one two" exist with:
|
15
|
+
|name|value|
|
16
|
+
|host-name|ahost|
|
17
|
+
When I export the database
|
18
|
+
Then It should run successfully
|
19
|
+
And The output file should contain ":host_name: ahost"
|
@@ -0,0 +1,35 @@
|
|
1
|
+
Feature: Importing Bookmarks
|
2
|
+
In order to reuse exported bookmarks (maybe after some editing)
|
3
|
+
I want to be able to import them back to the database.
|
4
|
+
|
5
|
+
This is currently a lacking feature as the import mechanism
|
6
|
+
OVERWRITES the existing database!.
|
7
|
+
|
8
|
+
Scenario: Warning before overwriting database
|
9
|
+
Given Existing database
|
10
|
+
When I import yml file
|
11
|
+
Then I should be prompted with "Importing a file OVERWRITES existing configuration"
|
12
|
+
|
13
|
+
Scenario: Importing databas and approving import
|
14
|
+
When I import yml file
|
15
|
+
And I answer "yes" at the prompt
|
16
|
+
Then It should run successfully
|
17
|
+
And Bookmark "cust1 dc1 host1" should contain:
|
18
|
+
| name | value |
|
19
|
+
| host_name | a.host.com |
|
20
|
+
| login | user1 |
|
21
|
+
And Bookmark "cust1 dc1 host2" should contain:
|
22
|
+
| name | value |
|
23
|
+
| host_name | b.host.com |
|
24
|
+
| login | user1 |
|
25
|
+
And Bookmark "cust1 dc2 host1" should contain:
|
26
|
+
| name | value |
|
27
|
+
| host_name | c.host.com |
|
28
|
+
| login | user3 |
|
29
|
+
|
30
|
+
Scenario: Cancel import on prompt
|
31
|
+
Given Existing database
|
32
|
+
When I import yml file
|
33
|
+
And I answer "no" at the prompt
|
34
|
+
Then I should get a "Cancelled" error
|
35
|
+
And Bookmark "cust1 dc1 host1" should not exist
|
@@ -0,0 +1,42 @@
|
|
1
|
+
Feature: Print bookmarks
|
2
|
+
In order to see the content of a bookmark
|
3
|
+
I want to be able to print it to the console.
|
4
|
+
|
5
|
+
Scenario: Printing bookmark (only host and user)
|
6
|
+
Given Bookmark "one two" exist with:
|
7
|
+
| name | value |
|
8
|
+
| host-name | some.host |
|
9
|
+
| login | myuser |
|
10
|
+
When I run the "print" command with "one two"
|
11
|
+
Then It should run successfully
|
12
|
+
And The output should include "host: some.host"
|
13
|
+
And The output should include "login: myuser"
|
14
|
+
And The output should not include "local tunnel:"
|
15
|
+
And The output should not include "ssh options:"
|
16
|
+
|
17
|
+
Scenario: Printing bookmark (with local tunnel)
|
18
|
+
Given Bookmark "one two" exist with:
|
19
|
+
| name | value |
|
20
|
+
| host-name | some.host |
|
21
|
+
| local-tunnel | 7070:localhost:7070 |
|
22
|
+
When I run the "print" command with "one two"
|
23
|
+
Then It should run successfully
|
24
|
+
And The output should include "host: some.host"
|
25
|
+
And The output should include "local tunnel: 7070:localhost:7070"
|
26
|
+
|
27
|
+
Scenario: Printing bookmark (with ssh options)
|
28
|
+
Given Bookmark "one two" exist with:
|
29
|
+
| name | value |
|
30
|
+
| host-name | some.host |
|
31
|
+
| option | UserKnownHostsFile=/dev/null |
|
32
|
+
| option | StrictHostKeyChecking=no |
|
33
|
+
When I run the "print" command with "one two"
|
34
|
+
Then It should run successfully
|
35
|
+
And The output should include "ssh options:\n"
|
36
|
+
And The output should include "- UserKnownHostsFile=/dev/null"
|
37
|
+
And The output should include "- StrictHostKeyChecking=no"
|
38
|
+
|
39
|
+
Scenario: Invalid bookmark
|
40
|
+
Given Empty database
|
41
|
+
When I run the "print" command with "one two"
|
42
|
+
Then I should get a "Error: host definition (one => two) doesn't exist" error
|
@@ -0,0 +1,83 @@
|
|
1
|
+
Feature: Connect to other hosts by ssh
|
2
|
+
In order to connect to a bookmarked host
|
3
|
+
I want to run the shell subcommand on a bookmark.
|
4
|
+
|
5
|
+
The `shell` subcommand invokes the 'ssh' shell command
|
6
|
+
with the appropriate parameters. You can override every
|
7
|
+
option in the bookmark using the same option.
|
8
|
+
|
9
|
+
Scenario: Connect to bookmark with host_name only
|
10
|
+
Given Bookmark "one two three" exist with:
|
11
|
+
| name | value |
|
12
|
+
| host-name | some.host |
|
13
|
+
When I run the "shell" command with "one two three"
|
14
|
+
Then It should execute "ssh some.host"
|
15
|
+
|
16
|
+
Scenario: Connect to bookmark with host and login
|
17
|
+
Given Bookmark "one two three" exist with:
|
18
|
+
| name | value |
|
19
|
+
| host-name | some.host |
|
20
|
+
| login | someuser |
|
21
|
+
When I run the "shell" command with "one two three"
|
22
|
+
Then It should execute "ssh -l someuser some.host"
|
23
|
+
|
24
|
+
Scenario: Connect to bookmark with abbreviated tunneling
|
25
|
+
Given Bookmark "one two three" exist with:
|
26
|
+
| name | value |
|
27
|
+
| host-name | some.host |
|
28
|
+
| local-tunnel | 8080 |
|
29
|
+
When I run the "shell" command with "one two three"
|
30
|
+
Then It should execute "ssh some.host -L 8080:localhost:8080"
|
31
|
+
|
32
|
+
Scenario: Connect to bookmark with custom tunnel definition
|
33
|
+
Given Bookmark "one two three" exist with:
|
34
|
+
| name | value |
|
35
|
+
| host-name | some.host |
|
36
|
+
When I run the "shell" command with "one two three -L 10000:localhost:10000"
|
37
|
+
Then It should execute "ssh some.host -L 10000:localhost:10000"
|
38
|
+
|
39
|
+
Scenario: Expand abbreviated tunnel syntax when connecting
|
40
|
+
Given Bookmark "one two three" exist with:
|
41
|
+
| name | value |
|
42
|
+
| host-name | some.host |
|
43
|
+
When I run the "shell" command with "one two three -L 10000"
|
44
|
+
Then It should execute "ssh some.host -L 10000:localhost:10000"
|
45
|
+
|
46
|
+
Scenario Outline: Various shell manipulations
|
47
|
+
Given Bookmark "one two three" exist with:
|
48
|
+
| name | value |
|
49
|
+
| host-name | some.host |
|
50
|
+
| login | mylogin |
|
51
|
+
When I run the "shell" command with "one two three <all_arguments>"
|
52
|
+
Then It should execute "<command>"
|
53
|
+
|
54
|
+
Scenarios: Overriding arguments
|
55
|
+
| all_arguments | command |
|
56
|
+
| -n other.host | ssh -l mylogin other.host |
|
57
|
+
| -l otherlogin | ssh -l otherlogin some.host |
|
58
|
+
|
59
|
+
Scenarios: Adding ssh options
|
60
|
+
| all_arguments | command |
|
61
|
+
| -o ForwardAgent=true | ssh -l mylogin some.host -o ForwardAgent=true |
|
62
|
+
|
63
|
+
Scenarios: Remote command pseudo terminal and quoting (e.g., to avoid wrong parsing of '&')
|
64
|
+
| all_arguments | command |
|
65
|
+
| -- ls | ssh -t -l mylogin some.host -- \"ls\" |
|
66
|
+
| -- ls && ls /tmp/ | ssh -t -l mylogin some.host -- \"ls && ls /tmp/\" |
|
67
|
+
|
68
|
+
Scenarios: Disable pseudo terminal on remote command
|
69
|
+
| all_arguments | command |
|
70
|
+
| -T -- ls | ssh -l mylogin some.host -- \"ls\" |
|
71
|
+
|
72
|
+
Scenario: Display error if no bookmark given
|
73
|
+
When Running "shell" without path
|
74
|
+
Then I should get a "not host definition!" error
|
75
|
+
|
76
|
+
Scenario: Experimental support for deleting conflicting host keys
|
77
|
+
Given Bookmark "some host" exist with:
|
78
|
+
| name | value |
|
79
|
+
| host-name | some.host |
|
80
|
+
And Conflicting key for "some.host" exists in known_hosts file
|
81
|
+
When I run the "shell" command with "some host --insecure-host-key 1"
|
82
|
+
And I confirm the prompt
|
83
|
+
Then The conflicting line for "some host" should be removed
|
@@ -0,0 +1,51 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (C) 2010 Haim Ashkenazi
|
3
|
+
#
|
4
|
+
# This program is free software; you can redistribute it and/or
|
5
|
+
# modify it under the terms of the GNU General Public License
|
6
|
+
# as published by the Free Software Foundation; either version 2
|
7
|
+
# of the License, or (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program; if not, write to the Free Software
|
16
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
17
|
+
#
|
18
|
+
|
19
|
+
When /^I run the "([^"]*)" command with "([^"]*)"$/ do |command, options|
|
20
|
+
@args = @test_args.clone
|
21
|
+
@args << command unless (command.nil? or command.empty?)
|
22
|
+
@args += options.split
|
23
|
+
end
|
24
|
+
|
25
|
+
When /^I run without arguments$/ do
|
26
|
+
@args = []
|
27
|
+
end
|
28
|
+
|
29
|
+
When /^I bookmark host: "([^"]*)" as "([^"]*)"$/ do |host, path|
|
30
|
+
@args = @test_args + %W(add) + path.split + %W(-n)
|
31
|
+
@args += [host] unless host.empty? # otherwise it gets ""
|
32
|
+
end
|
33
|
+
|
34
|
+
When /^I delete "([^"]*)"( with confirmation){0,1}$/ do |group, confirm|
|
35
|
+
@args = @test_args + ['del'] + group.split
|
36
|
+
@args += ['-y'] if confirm
|
37
|
+
end
|
38
|
+
|
39
|
+
When /^Running "([^"]*)" without path$/ do |subcommand|
|
40
|
+
steps %Q{
|
41
|
+
When I run the "#{subcommand}" command with ""
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
When /^I import yml file$/ do
|
46
|
+
@args = @test_args + %W(import -i #{YML_FIXTURE})
|
47
|
+
end
|
48
|
+
|
49
|
+
When /^I export the database$/ do
|
50
|
+
@args = @test_args << 'export' << '-o' << TMP_YML
|
51
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (C) 2010 Haim Ashkenazi
|
3
|
+
#
|
4
|
+
# This program is free software; you can redistribute it and/or
|
5
|
+
# modify it under the terms of the GNU General Public License
|
6
|
+
# as published by the Free Software Foundation; either version 2
|
7
|
+
# of the License, or (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program; if not, write to the Free Software
|
16
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
17
|
+
#
|
18
|
+
require 'runsshlib'
|
19
|
+
|
20
|
+
Given /^No database$/ do
|
21
|
+
cleanup_tmp_file
|
22
|
+
end
|
23
|
+
|
24
|
+
Given /^Existing database$/ do
|
25
|
+
dump_config 'VERSION' => RunSSHLib::ConfigFile::Version
|
26
|
+
end
|
27
|
+
|
28
|
+
Given /^Empty database$/ do
|
29
|
+
dump_config 'VERSION' => RunSSHLib::ConfigFile::Version
|
30
|
+
end
|
31
|
+
|
32
|
+
Then /^A database should be created$/ do
|
33
|
+
File.exist?(TMP_FILE).should be_true
|
34
|
+
end
|
35
|
+
|
36
|
+
Then /^Bookmark: "([^"]*)" should point to "([^"]*)"$/ do |group, host|
|
37
|
+
h = get_host(group)
|
38
|
+
h.definition[:host_name].should == host
|
39
|
+
end
|
40
|
+
|
41
|
+
Then /^A backup database should be created with "([^"]*)" suffix$/ do |suffix|
|
42
|
+
File.exist?(TMP_FILE + suffix).should be_true
|
43
|
+
end
|
44
|
+
|
45
|
+
Then /^Bookmark "([^"]*)" should not exist$/ do |group|
|
46
|
+
bookmark_exist?(group).should be_false
|
47
|
+
end
|
48
|
+
|
49
|
+
Then /^Bookmark "([^"]*)" should exist$/ do |group|
|
50
|
+
bookmark_exist?(group).should be_true
|
51
|
+
end
|
52
|
+
|
53
|
+
Given /^Bookmark "([^"]*)" is an empty group$/ do |group|
|
54
|
+
host_path = group + " somehost"
|
55
|
+
Given %Q(Bookmark "#{host_path}" exists)
|
56
|
+
When %Q(I delete "#{host_path}") # What's left is an empty group
|
57
|
+
And "I confirm the prompt"
|
58
|
+
Then %Q(It should run successfully)
|
59
|
+
end
|
60
|
+
|
61
|
+
Given /^Bookmark "([^"]*)" exists$/ do |group|
|
62
|
+
steps %Q{
|
63
|
+
Given Bookmark "#{group}" exist with:
|
64
|
+
| name | value |
|
65
|
+
| host-name | some.host |
|
66
|
+
}
|
67
|
+
end
|
68
|
+
|
69
|
+
Given /^Bookmark "([^"]*)" exist with:$/ do |group, options|
|
70
|
+
args = @test_args + %W(add) + group.split
|
71
|
+
options.rows.each do |row|
|
72
|
+
args << "--#{row[0]}" << row[1]
|
73
|
+
end
|
74
|
+
RunSSHLib::CLI.new(args).run
|
75
|
+
end
|
76
|
+
|
77
|
+
When /^Bookmark "([^"]*)" should contain:$/ do |group, options|
|
78
|
+
host = get_host(group)
|
79
|
+
options.rows.each do |row|
|
80
|
+
# the `option` option is a list of arguments
|
81
|
+
if row[0] == 'option'
|
82
|
+
host.definition[row[0].to_sym].should include(row[1])
|
83
|
+
else
|
84
|
+
host.definition[row[0].to_sym].should == row[1]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
Given /^Conflicting key for "([^"]*)" exists in known_hosts file$/ do |host|
|
90
|
+
# TODO: This should be moved to somewhere where ALL tests uses
|
91
|
+
# it. We should never touch the real known_hosts file during testing.
|
92
|
+
module RunSSHLib
|
93
|
+
module SshBackend
|
94
|
+
class KnownHostsUtils
|
95
|
+
def initialize
|
96
|
+
@known_hosts_file = KNOWN_HOSTS_FILE
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
create_known_hosts_file host
|
102
|
+
end
|
103
|
+
|
104
|
+
Then /^The conflicting line for "([^"]*)" should be removed$/ do |host|
|
105
|
+
# we're hiding this as it is not interesting for our tests
|
106
|
+
Then "It should run successfully"
|
107
|
+
contents = IO.read(KNOWN_HOSTS_FILE)
|
108
|
+
contents.should_not =~ /#{host}/
|
109
|
+
end
|