ridley-connectors 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +10 -0
  5. data/CHANGELOG.md +8 -0
  6. data/Gemfile +18 -0
  7. data/Guardfile +22 -0
  8. data/LICENSE +16 -0
  9. data/README.md +107 -0
  10. data/Thorfile +39 -0
  11. data/lib/ridley-connectors/chef_objects/node_object.rb +17 -0
  12. data/lib/ridley-connectors/client.rb +54 -0
  13. data/lib/ridley-connectors/host_commander.rb +231 -0
  14. data/lib/ridley-connectors/host_connector/response.rb +27 -0
  15. data/lib/ridley-connectors/host_connector/ssh.rb +211 -0
  16. data/lib/ridley-connectors/host_connector/winrm/command_uploader.rb +87 -0
  17. data/lib/ridley-connectors/host_connector/winrm.rb +218 -0
  18. data/lib/ridley-connectors/host_connector.rb +83 -0
  19. data/lib/ridley-connectors/resources/node_resource.rb +198 -0
  20. data/lib/ridley-connectors/version.rb +5 -0
  21. data/lib/ridley-connectors.rb +11 -0
  22. data/ridley-connectors.gemspec +27 -0
  23. data/spec/fixtures/encrypted_data_bag_secret +1 -0
  24. data/spec/fixtures/my-fake.pem +27 -0
  25. data/spec/spec_helper.rb +40 -0
  26. data/spec/support/actor_mocking.rb +9 -0
  27. data/spec/support/spec_helpers.rb +20 -0
  28. data/spec/unit/ridley-connectors/chef_objects/node_object_spec.rb +22 -0
  29. data/spec/unit/ridley-connectors/client_spec.rb +32 -0
  30. data/spec/unit/ridley-connectors/host_commander_spec.rb +173 -0
  31. data/spec/unit/ridley-connectors/host_connector/ssh_spec.rb +57 -0
  32. data/spec/unit/ridley-connectors/host_connector/winrm/command_uploader_spec.rb +67 -0
  33. data/spec/unit/ridley-connectors/host_connector/winrm_spec.rb +145 -0
  34. data/spec/unit/ridley-connectors/host_connector_spec.rb +50 -0
  35. data/spec/unit/ridley-connectors/resources/node_resource_spec.rb +139 -0
  36. metadata +178 -0
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ridley::HostConnector::WinRM::CommandUploader do
4
+ let(:winrm_stub) {
5
+ double('WinRM',
6
+ run_cmd: run_cmd_data,
7
+ powershell: nil
8
+ )
9
+ }
10
+
11
+ subject { command_uploader }
12
+
13
+ let(:command_uploader) { described_class.new(winrm_stub) }
14
+ let(:command_string) { "a" * 2048 }
15
+ let(:run_cmd_data) { { data: [{ stdout: "abc123" }] } }
16
+ let(:command_file_name) { "my_command.bat" }
17
+
18
+ its(:winrm) { should eq(winrm_stub) }
19
+
20
+ before do
21
+ command_uploader.stub(:get_file_path).and_return("")
22
+ end
23
+
24
+ describe "#upload" do
25
+ let(:upload) { command_uploader.upload(command_string) }
26
+
27
+ it "calls winrm to upload and convert the command" do
28
+ winrm_stub.should_receive(:run_cmd).and_return(
29
+ run_cmd_data,
30
+ nil,
31
+ run_cmd_data
32
+ )
33
+ winrm_stub.should_receive(:powershell)
34
+
35
+ upload
36
+ end
37
+ end
38
+
39
+ describe "#command" do
40
+ subject { command }
41
+ let(:command) { command_uploader.command }
42
+
43
+ before do
44
+ command_uploader.stub command_file_name: command_file_name
45
+ end
46
+
47
+ it { should eq("cmd.exe /C #{command_file_name}") }
48
+ end
49
+
50
+ describe "#cleanup" do
51
+ subject { cleanup }
52
+
53
+ let(:cleanup) { command_uploader.cleanup }
54
+ let(:base64_file_name) { "my_base64_file" }
55
+
56
+ before do
57
+ command_uploader.stub command_file_name: command_file_name
58
+ command_uploader.stub base64_file_name: base64_file_name
59
+ end
60
+
61
+ it "cleans up the windows temp dir" do
62
+ winrm_stub.should_receive(:run_cmd).with("del #{base64_file_name} /F /Q")
63
+ winrm_stub.should_receive(:run_cmd).with("del #{command_file_name} /F /Q")
64
+ cleanup
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,145 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ridley::HostConnector::WinRM do
4
+ subject { connector }
5
+ let(:connector) { described_class.new }
6
+ let(:host) { 'fake.riotgames.com' }
7
+ let(:options) do
8
+ {
9
+ server_url: double('server_url'),
10
+ validator_path: fixtures_path.join('my-fake.pem'),
11
+ validator_client: double('validator_client'),
12
+ encrypted_data_bag_secret: 'encrypted_data_bag_secret',
13
+ winrm: Hash.new,
14
+ chef_version: double('chef_version')
15
+ }
16
+ end
17
+
18
+ before { described_class::CommandUploader.stub(:new).and_return(double('command_uploader')) }
19
+
20
+ describe "#get_command" do
21
+ subject(:get_command) { connector.get_command(command, command_uploader_stub) }
22
+
23
+ let(:command) { "echo %TEMP%" }
24
+ let(:command_uploader_stub) { double('CommandUploader') }
25
+
26
+ it { should eq(command) }
27
+
28
+ context "when a command is more than 2047 characters" do
29
+ let(:command) { "a" * 2048 }
30
+
31
+ it "uploads and returns a command" do
32
+ described_class::CommandUploader.stub(new: command_uploader_stub)
33
+
34
+ command_uploader_stub.should_receive :upload
35
+ command_uploader_stub.stub command: "my command"
36
+ command_uploader_stub.stub(:cleanup)
37
+
38
+ get_command.should eq("my command")
39
+ end
40
+ end
41
+ end
42
+
43
+ describe "#run" do
44
+ subject(:result) { connector.run(host, command, options) }
45
+ let(:command) { "dir" }
46
+ let(:command_uploader_stub) { double('CommandUploader', cleanup: true) }
47
+ let(:stdout) { "stdout" }
48
+ let(:stderr) { nil }
49
+ let(:winrm_stub) { double }
50
+
51
+ before do
52
+ described_class::CommandUploader.stub(:new).and_return(command_uploader_stub)
53
+ connector.stub(:winrm).and_return(winrm_stub)
54
+ winrm_stub.stub(:run_cmd).and_yield(stdout, stderr).and_return(exitcode: 0)
55
+ end
56
+
57
+ context "when the exit_code is 0" do
58
+ it "returns a non-error HostConnector::Response" do
59
+ expect(result).to be_a(Ridley::HostConnector::Response)
60
+ expect(result).to_not be_error
61
+ end
62
+
63
+ it "sets the response's stdout message" do
64
+ expect(result.stdout).to eq("stdout")
65
+ end
66
+ end
67
+
68
+ context "when the exit_code is not 0" do
69
+ let(:stderr) { "stderr" }
70
+
71
+ before do
72
+ winrm_stub.stub(:run_cmd).and_yield(stdout, stderr).and_return(exitcode: 1)
73
+ end
74
+
75
+ it "returns an error HostConnector::Response with an error" do
76
+ expect(result).to be_a(Ridley::HostConnector::Response)
77
+ expect(result).to be_error
78
+ end
79
+
80
+ it "sets the response's stderr message" do
81
+ expect(result.stderr).to eq("stderr")
82
+ end
83
+ end
84
+
85
+ context "when a WinRM::WinRMHTTPTransportError error is raised" do
86
+ let(:stderr) { "error" }
87
+ before { winrm_stub.stub(:run_cmd).and_yield(stdout, stderr).and_raise(::WinRM::WinRMHTTPTransportError) }
88
+
89
+ it "returns an error HostConnector::Response with an error" do
90
+ expect(result).to be_a(Ridley::HostConnector::Response)
91
+ expect(result).to be_error
92
+ end
93
+
94
+ it "sets the response's stderr message to the exception's message" do
95
+ expect(result.stderr).to eql("WinRM::WinRMHTTPTransportError")
96
+ end
97
+ end
98
+ end
99
+
100
+ describe "#bootstrap" do
101
+ it "sends a #run message to self to bootstrap a node" do
102
+ connector.should_receive(:run).with(host, anything, options)
103
+ connector.bootstrap(host, options)
104
+ end
105
+ end
106
+
107
+ describe "#chef_client" do
108
+ subject(:chef_client) { connector.chef_client(host, options) }
109
+
110
+ it "receives a command to run chef-client" do
111
+ connector.should_receive(:run).with(host, "chef-client", options)
112
+
113
+ chef_client
114
+ end
115
+ end
116
+
117
+ describe "#put_secret" do
118
+ subject(:put_secret) { connector.put_secret(host, secret, options) }
119
+ let(:encrypted_data_bag_secret_path) { fixtures_path.join("encrypted_data_bag_secret").to_s }
120
+ let(:secret) { File.read(encrypted_data_bag_secret_path).chomp }
121
+
122
+ it "receives a command to copy the secret" do
123
+ connector.should_receive(:run).with(host,
124
+ "echo #{secret} > C:\\chef\\encrypted_data_bag_secret",
125
+ options
126
+ )
127
+
128
+ put_secret
129
+ end
130
+ end
131
+
132
+ describe "#ruby_script" do
133
+ subject(:ruby_script) { connector.ruby_script(host, command_lines, options) }
134
+ let(:command_lines) { ["puts 'hello'", "puts 'there'"] }
135
+
136
+ it "receives a ruby call with the command" do
137
+ connector.should_receive(:run).with(host,
138
+ "#{described_class::EMBEDDED_RUBY_PATH} -e \"puts 'hello';puts 'there'\"",
139
+ options
140
+ )
141
+
142
+ ruby_script
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ridley::HostConnector::Base do
4
+ subject { Class.new(Ridley::HostConnector::Base).new }
5
+
6
+ let(:host) { double('host') }
7
+ let(:options) { Hash.new }
8
+
9
+ describe "#run" do
10
+ let(:command) { double('command') }
11
+
12
+ it "raises a RuntimeError" do
13
+ expect { subject.run(host, command, options) }.to raise_error(RuntimeError)
14
+ end
15
+ end
16
+
17
+ describe "#bootstrap" do
18
+ it "raises a RuntimeError" do
19
+ expect { subject.bootstrap(host, options) }.to raise_error(RuntimeError)
20
+ end
21
+ end
22
+
23
+ describe "#chef_client" do
24
+ it "raises a RuntimeError" do
25
+ expect { subject.chef_client(host, options) }.to raise_error(RuntimeError)
26
+ end
27
+ end
28
+
29
+ describe "#put_secret" do
30
+ let(:secret) { double('secret') }
31
+
32
+ it "raises a RuntimeError" do
33
+ expect { subject.put_secret(host, secret, options) }.to raise_error(RuntimeError)
34
+ end
35
+ end
36
+
37
+ describe "#ruby_script" do
38
+ let(:command_lines) { double('command-lines') }
39
+
40
+ it "raises a RuntimeError" do
41
+ expect { subject.ruby_script(host, command_lines, options) }.to raise_error(RuntimeError)
42
+ end
43
+ end
44
+
45
+ describe "#uninstall_chef" do
46
+ it "raises a RuntimeError" do
47
+ expect { subject.uninstall_chef(host, options) }.to raise_error(RuntimeError)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,139 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ridley::NodeResource do
4
+ let(:host) { "33.33.33.10" }
5
+ let(:host_commander) { double('host-commander') }
6
+ let(:options) do
7
+ {
8
+ server_url: double('server_url'),
9
+ validator_path: double('validator_path'),
10
+ validator_client: double('validator_client'),
11
+ encrypted_data_bag_secret: double('encrypted_data_bag_secret'),
12
+ ssh: double('ssh'),
13
+ winrm: double('winrm'),
14
+ chef_version: double('chef_version')
15
+ }
16
+ end
17
+ let(:instance) do
18
+ inst = described_class.new(double, options)
19
+ inst.stub(host_commander: host_commander)
20
+ inst
21
+ end
22
+
23
+ describe "#bootstrap" do
24
+ it "sends the message #bootstrap to the instance's host_commander" do
25
+ host_commander.should_receive(:bootstrap).with(host, options)
26
+ instance.bootstrap(host)
27
+ end
28
+
29
+ it "passes pre-configured options to #bootstrap" do
30
+ host_commander.should_receive(:bootstrap).with(host, options)
31
+ instance.bootstrap(host)
32
+ end
33
+ end
34
+
35
+ describe "#chef_run" do
36
+ it "sends the message #chef_client to the instance's host_commander" do
37
+ host_commander.should_receive(:chef_client).with(host, ssh: instance.ssh, winrm: instance.winrm)
38
+ instance.chef_run(host)
39
+ end
40
+ end
41
+
42
+ describe "#put_secret" do
43
+ let(:secret) { options[:encrypted_data_bag_secret] }
44
+
45
+ it "sends the message #put_secret to the instance's host_commander" do
46
+ host_commander.should_receive(:put_secret).with(host, secret, options.slice(:ssh, :winrm))
47
+ instance.put_secret(host)
48
+ end
49
+ end
50
+
51
+ describe "#ruby_script" do
52
+ let(:command_lines) { ["puts 'hello'", "puts 'there'"] }
53
+
54
+ it "sends the message #ruby_script to the instance's host_commander" do
55
+ host_commander.should_receive(:ruby_script).with(host, command_lines, ssh: instance.ssh, winrm: instance.winrm)
56
+ instance.ruby_script(host, command_lines)
57
+ end
58
+ end
59
+
60
+ describe "#run" do
61
+ let(:command) { "echo 'hello winrm_connectorld'" }
62
+
63
+ it "sends the message #run to the instance's host_commander" do
64
+ host_commander.should_receive(:run).with(host, command, ssh: instance.ssh, winrm: instance.winrm)
65
+ instance.run(host, command)
66
+ end
67
+ end
68
+
69
+ describe "#platform_specific_run" do
70
+ let(:ssh_command) { "hostname -f" }
71
+ let(:winrm_command) { "echo %COMPUTERNAME%" }
72
+ let(:ssh_connector) { Ridley::HostConnector::SSH.new }
73
+ let(:winrm_connector) { Ridley::HostConnector::WinRM.new }
74
+ let(:unsupported_connector) { Object.new }
75
+
76
+ describe "expecting the ssh connector" do
77
+ before do
78
+ host_commander.stub(:connector_for).and_return ssh_connector
79
+ end
80
+ it "sends the ssh command" do
81
+ instance.should_receive(:run).with(host, ssh_command)
82
+ instance.platform_specific_run(host, ssh: ssh_command, winrm: winrm_command)
83
+ end
84
+
85
+ it "raises an error if no command is provided for the ssh connector when the ssh connector is used" do
86
+ expect {
87
+ instance.platform_specific_run(host, winrm: winrm_command)
88
+ }.to raise_error(Ridley::Errors::CommandNotProvided)
89
+ end
90
+
91
+ it "raises an error if an empty command is provided for the ssh connector when the ssh connector is used" do
92
+ expect {
93
+ instance.platform_specific_run(host, ssh: "", winrm: winrm_command)
94
+ }.to raise_error(Ridley::Errors::CommandNotProvided)
95
+ end
96
+
97
+ it "raises an error if a nil command is provided for the ssh connector when the ssh connector is used" do
98
+ expect {
99
+ instance.platform_specific_run(host, ssh: nil, winrm: winrm_command)
100
+ }.to raise_error(Ridley::Errors::CommandNotProvided)
101
+ end
102
+ end
103
+
104
+ describe "expecting the winrm connector" do
105
+ before do
106
+ host_commander.stub(:connector_for).and_return winrm_connector
107
+ end
108
+ it "sends the ssh command if the connector is winrm" do
109
+ instance.should_receive(:run).with(host, winrm_command)
110
+ instance.platform_specific_run(host, ssh: ssh_command, winrm: winrm_command)
111
+ end
112
+
113
+ it "raises an error if no command is provided for the winrm connector when the winrm connector is used" do
114
+ expect {
115
+ instance.platform_specific_run(host, ssh: ssh_command)
116
+ }.to raise_error(Ridley::Errors::CommandNotProvided)
117
+ end
118
+
119
+ it "raises an error if an empty is provided for the winrm connector when the winrm connector is used" do
120
+ expect {
121
+ instance.platform_specific_run(host, ssh: ssh_command, winrm: "")
122
+ }.to raise_error(Ridley::Errors::CommandNotProvided)
123
+ end
124
+
125
+ it "raises a nil command is provided for the winrm connector when the winrm connector is used" do
126
+ expect {
127
+ instance.platform_specific_run(host, ssh: ssh_command, winrm: nil)
128
+ }.to raise_error(Ridley::Errors::CommandNotProvided)
129
+ end
130
+ end
131
+
132
+ it "raises a RuntimeError if an unsupported connector is used" do
133
+ host_commander.stub(:connector_for).and_return unsupported_connector
134
+ expect {
135
+ instance.platform_specific_run(host, ssh: ssh_command, winrm: winrm_command)
136
+ }.to raise_error(RuntimeError)
137
+ end
138
+ end
139
+ end
metadata ADDED
@@ -0,0 +1,178 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ridley-connectors
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jamie Winsor
8
+ - Kyle Allan
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-11-21 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: celluloid
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ~>
19
+ - !ruby/object:Gem::Version
20
+ version: '0.15'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ version: '0.15'
28
+ - !ruby/object:Gem::Dependency
29
+ name: celluloid-io
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: '0.15'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ~>
40
+ - !ruby/object:Gem::Version
41
+ version: '0.15'
42
+ - !ruby/object:Gem::Dependency
43
+ name: net-ssh
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: ridley
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ~>
61
+ - !ruby/object:Gem::Version
62
+ version: 2.0.0
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 2.0.0
70
+ - !ruby/object:Gem::Dependency
71
+ name: winrm
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: 1.1.0
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ~>
82
+ - !ruby/object:Gem::Version
83
+ version: 1.1.0
84
+ - !ruby/object:Gem::Dependency
85
+ name: buff-ruby_engine
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ~>
89
+ - !ruby/object:Gem::Version
90
+ version: '0.1'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ~>
96
+ - !ruby/object:Gem::Version
97
+ version: '0.1'
98
+ description: A Connector API for talking to nodes managed by Chef
99
+ email:
100
+ - jamie@vialstudios.com
101
+ - kallan@riotgames.com
102
+ executables: []
103
+ extensions: []
104
+ extra_rdoc_files: []
105
+ files:
106
+ - .gitignore
107
+ - .ruby-version
108
+ - .travis.yml
109
+ - CHANGELOG.md
110
+ - Gemfile
111
+ - Guardfile
112
+ - LICENSE
113
+ - README.md
114
+ - Thorfile
115
+ - lib/ridley-connectors.rb
116
+ - lib/ridley-connectors/chef_objects/node_object.rb
117
+ - lib/ridley-connectors/client.rb
118
+ - lib/ridley-connectors/host_commander.rb
119
+ - lib/ridley-connectors/host_connector.rb
120
+ - lib/ridley-connectors/host_connector/response.rb
121
+ - lib/ridley-connectors/host_connector/ssh.rb
122
+ - lib/ridley-connectors/host_connector/winrm.rb
123
+ - lib/ridley-connectors/host_connector/winrm/command_uploader.rb
124
+ - lib/ridley-connectors/resources/node_resource.rb
125
+ - lib/ridley-connectors/version.rb
126
+ - ridley-connectors.gemspec
127
+ - spec/fixtures/encrypted_data_bag_secret
128
+ - spec/fixtures/my-fake.pem
129
+ - spec/spec_helper.rb
130
+ - spec/support/actor_mocking.rb
131
+ - spec/support/spec_helpers.rb
132
+ - spec/unit/ridley-connectors/chef_objects/node_object_spec.rb
133
+ - spec/unit/ridley-connectors/client_spec.rb
134
+ - spec/unit/ridley-connectors/host_commander_spec.rb
135
+ - spec/unit/ridley-connectors/host_connector/ssh_spec.rb
136
+ - spec/unit/ridley-connectors/host_connector/winrm/command_uploader_spec.rb
137
+ - spec/unit/ridley-connectors/host_connector/winrm_spec.rb
138
+ - spec/unit/ridley-connectors/host_connector_spec.rb
139
+ - spec/unit/ridley-connectors/resources/node_resource_spec.rb
140
+ homepage: https://github.com/RiotGames/ridley-connectors
141
+ licenses:
142
+ - Apache 2.0
143
+ metadata: {}
144
+ post_install_message:
145
+ rdoc_options: []
146
+ require_paths:
147
+ - lib
148
+ required_ruby_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - '>='
151
+ - !ruby/object:Gem::Version
152
+ version: 1.9.1
153
+ required_rubygems_version: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ requirements: []
159
+ rubyforge_project:
160
+ rubygems_version: 2.0.3
161
+ signing_key:
162
+ specification_version: 4
163
+ summary: A Connector API for talking to nodes managed by Chef
164
+ test_files:
165
+ - spec/fixtures/encrypted_data_bag_secret
166
+ - spec/fixtures/my-fake.pem
167
+ - spec/spec_helper.rb
168
+ - spec/support/actor_mocking.rb
169
+ - spec/support/spec_helpers.rb
170
+ - spec/unit/ridley-connectors/chef_objects/node_object_spec.rb
171
+ - spec/unit/ridley-connectors/client_spec.rb
172
+ - spec/unit/ridley-connectors/host_commander_spec.rb
173
+ - spec/unit/ridley-connectors/host_connector/ssh_spec.rb
174
+ - spec/unit/ridley-connectors/host_connector/winrm/command_uploader_spec.rb
175
+ - spec/unit/ridley-connectors/host_connector/winrm_spec.rb
176
+ - spec/unit/ridley-connectors/host_connector_spec.rb
177
+ - spec/unit/ridley-connectors/resources/node_resource_spec.rb
178
+ has_rdoc: