ridley 1.7.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +0 -55
- data/lib/ridley.rb +0 -2
- data/lib/ridley/chef_objects/node_object.rb +0 -14
- data/lib/ridley/client.rb +0 -16
- data/lib/ridley/resources/node_resource.rb +0 -189
- data/lib/ridley/version.rb +1 -1
- data/ridley.gemspec +0 -2
- data/spec/unit/ridley/chef_objects/node_object_spec.rb +0 -16
- data/spec/unit/ridley/client_spec.rb +0 -12
- data/spec/unit/ridley/resources/node_resource_spec.rb +2 -133
- metadata +2 -46
- data/lib/ridley/host_commander.rb +0 -231
- data/lib/ridley/host_connector.rb +0 -83
- data/lib/ridley/host_connector/response.rb +0 -27
- data/lib/ridley/host_connector/ssh.rb +0 -211
- data/lib/ridley/host_connector/winrm.rb +0 -218
- data/lib/ridley/host_connector/winrm/command_uploader.rb +0 -87
- data/spec/unit/ridley/host_commander_spec.rb +0 -173
- data/spec/unit/ridley/host_connector/ssh_spec.rb +0 -57
- data/spec/unit/ridley/host_connector/winrm/command_uploader_spec.rb +0 -67
- data/spec/unit/ridley/host_connector/winrm_spec.rb +0 -145
- data/spec/unit/ridley/host_connector_spec.rb +0 -50
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ridley
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jamie Winsor
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-11-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: addressable
|
@@ -207,20 +207,6 @@ dependencies:
|
|
207
207
|
- - '>='
|
208
208
|
- !ruby/object:Gem::Version
|
209
209
|
version: '2.8'
|
210
|
-
- !ruby/object:Gem::Dependency
|
211
|
-
name: net-ssh
|
212
|
-
requirement: !ruby/object:Gem::Requirement
|
213
|
-
requirements:
|
214
|
-
- - '>='
|
215
|
-
- !ruby/object:Gem::Version
|
216
|
-
version: '0'
|
217
|
-
type: :runtime
|
218
|
-
prerelease: false
|
219
|
-
version_requirements: !ruby/object:Gem::Requirement
|
220
|
-
requirements:
|
221
|
-
- - '>='
|
222
|
-
- !ruby/object:Gem::Version
|
223
|
-
version: '0'
|
224
210
|
- !ruby/object:Gem::Dependency
|
225
211
|
name: retryable
|
226
212
|
requirement: !ruby/object:Gem::Requirement
|
@@ -249,20 +235,6 @@ dependencies:
|
|
249
235
|
- - '>='
|
250
236
|
- !ruby/object:Gem::Version
|
251
237
|
version: 0.4.4
|
252
|
-
- !ruby/object:Gem::Dependency
|
253
|
-
name: winrm
|
254
|
-
requirement: !ruby/object:Gem::Requirement
|
255
|
-
requirements:
|
256
|
-
- - ~>
|
257
|
-
- !ruby/object:Gem::Version
|
258
|
-
version: 1.1.0
|
259
|
-
type: :runtime
|
260
|
-
prerelease: false
|
261
|
-
version_requirements: !ruby/object:Gem::Requirement
|
262
|
-
requirements:
|
263
|
-
- - ~>
|
264
|
-
- !ruby/object:Gem::Version
|
265
|
-
version: 1.1.0
|
266
238
|
- !ruby/object:Gem::Dependency
|
267
239
|
name: buff-ruby_engine
|
268
240
|
requirement: !ruby/object:Gem::Requirement
|
@@ -323,12 +295,6 @@ files:
|
|
323
295
|
- lib/ridley/command_context/windows_uninstall.rb
|
324
296
|
- lib/ridley/connection.rb
|
325
297
|
- lib/ridley/errors.rb
|
326
|
-
- lib/ridley/host_commander.rb
|
327
|
-
- lib/ridley/host_connector.rb
|
328
|
-
- lib/ridley/host_connector/response.rb
|
329
|
-
- lib/ridley/host_connector/ssh.rb
|
330
|
-
- lib/ridley/host_connector/winrm.rb
|
331
|
-
- lib/ridley/host_connector/winrm/command_uploader.rb
|
332
298
|
- lib/ridley/logging.rb
|
333
299
|
- lib/ridley/middleware.rb
|
334
300
|
- lib/ridley/middleware/chef_auth.rb
|
@@ -412,11 +378,6 @@ files:
|
|
412
378
|
- spec/unit/ridley/client_spec.rb
|
413
379
|
- spec/unit/ridley/connection_spec.rb
|
414
380
|
- spec/unit/ridley/errors_spec.rb
|
415
|
-
- spec/unit/ridley/host_commander_spec.rb
|
416
|
-
- spec/unit/ridley/host_connector/ssh_spec.rb
|
417
|
-
- spec/unit/ridley/host_connector/winrm/command_uploader_spec.rb
|
418
|
-
- spec/unit/ridley/host_connector/winrm_spec.rb
|
419
|
-
- spec/unit/ridley/host_connector_spec.rb
|
420
381
|
- spec/unit/ridley/middleware/chef_auth_spec.rb
|
421
382
|
- spec/unit/ridley/middleware/chef_response_spec.rb
|
422
383
|
- spec/unit/ridley/middleware/gzip_spec.rb
|
@@ -513,11 +474,6 @@ test_files:
|
|
513
474
|
- spec/unit/ridley/client_spec.rb
|
514
475
|
- spec/unit/ridley/connection_spec.rb
|
515
476
|
- spec/unit/ridley/errors_spec.rb
|
516
|
-
- spec/unit/ridley/host_commander_spec.rb
|
517
|
-
- spec/unit/ridley/host_connector/ssh_spec.rb
|
518
|
-
- spec/unit/ridley/host_connector/winrm/command_uploader_spec.rb
|
519
|
-
- spec/unit/ridley/host_connector/winrm_spec.rb
|
520
|
-
- spec/unit/ridley/host_connector_spec.rb
|
521
477
|
- spec/unit/ridley/middleware/chef_auth_spec.rb
|
522
478
|
- spec/unit/ridley/middleware/chef_response_spec.rb
|
523
479
|
- spec/unit/ridley/middleware/gzip_spec.rb
|
@@ -1,231 +0,0 @@
|
|
1
|
-
module Ridley
|
2
|
-
class ConnectorSupervisor < ::Celluloid::SupervisionGroup
|
3
|
-
# @param [Celluloid::Registry] registry
|
4
|
-
def initialize(registry)
|
5
|
-
super(registry)
|
6
|
-
supervise_as :ssh, HostConnector::SSH
|
7
|
-
supervise_as :winrm, HostConnector::WinRM
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
class HostCommander
|
12
|
-
include Celluloid
|
13
|
-
include Ridley::Logging
|
14
|
-
|
15
|
-
PORT_CHECK_TIMEOUT = 3
|
16
|
-
|
17
|
-
finalizer :finalize_callback
|
18
|
-
|
19
|
-
def initialize
|
20
|
-
@connector_registry = Celluloid::Registry.new
|
21
|
-
@connector_supervisor = ConnectorSupervisor.new_link(@connector_registry)
|
22
|
-
end
|
23
|
-
|
24
|
-
# Execute a shell command on a node
|
25
|
-
#
|
26
|
-
# @param [String] host
|
27
|
-
# the host to perform the action on
|
28
|
-
# @param [String] command
|
29
|
-
#
|
30
|
-
# @option options [Hash] :ssh
|
31
|
-
# * :user (String) a shell user that will login to each node and perform the bootstrap command on
|
32
|
-
# * :password (String) the password for the shell user that will perform the bootstrap
|
33
|
-
# * :keys (Array, String) an array of key(s) to authenticate the ssh user with instead of a password
|
34
|
-
# * :timeout (Float) timeout value for SSH bootstrap (5.0)
|
35
|
-
# * :sudo (Boolean) run as sudo
|
36
|
-
# @option options [Hash] :winrm
|
37
|
-
# * :user (String) a user that will login to each node and perform the bootstrap command on
|
38
|
-
# * :password (String) the password for the user that will perform the bootstrap (required)
|
39
|
-
# * :port (Fixnum) the winrm port to connect on the node the bootstrap will be performed on (5985)
|
40
|
-
#
|
41
|
-
# @return [HostConnector::Response]
|
42
|
-
def run(host, command, options = {})
|
43
|
-
execute(__method__, host, command, options)
|
44
|
-
end
|
45
|
-
|
46
|
-
# Bootstrap a node
|
47
|
-
#
|
48
|
-
# @param [String] host
|
49
|
-
# the host to perform the action on
|
50
|
-
#
|
51
|
-
# @option options [Hash] :ssh
|
52
|
-
# * :user (String) a shell user that will login to each node and perform the bootstrap command on
|
53
|
-
# * :password (String) the password for the shell user that will perform the bootstrap
|
54
|
-
# * :keys (Array, String) an array of key(s) to authenticate the ssh user with instead of a password
|
55
|
-
# * :timeout (Float) timeout value for SSH bootstrap (5.0)
|
56
|
-
# * :sudo (Boolean) run as sudo
|
57
|
-
# @option options [Hash] :winrm
|
58
|
-
# * :user (String) a user that will login to each node and perform the bootstrap command on
|
59
|
-
# * :password (String) the password for the user that will perform the bootstrap (required)
|
60
|
-
# * :port (Fixnum) the winrm port to connect on the node the bootstrap will be performed on (5985)
|
61
|
-
#
|
62
|
-
# @return [HostConnector::Response]
|
63
|
-
def bootstrap(host, options = {})
|
64
|
-
execute(__method__, host, options)
|
65
|
-
end
|
66
|
-
|
67
|
-
# Perform a chef client run on a node
|
68
|
-
#
|
69
|
-
# @param [String] host
|
70
|
-
# the host to perform the action on
|
71
|
-
#
|
72
|
-
# @option options [Hash] :ssh
|
73
|
-
# * :user (String) a shell user that will login to each node and perform the bootstrap command on
|
74
|
-
# * :password (String) the password for the shell user that will perform the bootstrap
|
75
|
-
# * :keys (Array, String) an array of key(s) to authenticate the ssh user with instead of a password
|
76
|
-
# * :timeout (Float) timeout value for SSH bootstrap (5.0)
|
77
|
-
# * :sudo (Boolean) run as sudo
|
78
|
-
# @option options [Hash] :winrm
|
79
|
-
# * :user (String) a user that will login to each node and perform the bootstrap command on
|
80
|
-
# * :password (String) the password for the user that will perform the bootstrap (required)
|
81
|
-
# * :port (Fixnum) the winrm port to connect on the node the bootstrap will be performed on (5985)
|
82
|
-
#
|
83
|
-
# @return [HostConnector::Response]
|
84
|
-
def chef_client(host, options = {})
|
85
|
-
execute(__method__, host, options)
|
86
|
-
end
|
87
|
-
|
88
|
-
# Write your encrypted data bag secret on a node
|
89
|
-
#
|
90
|
-
# @param [String] host
|
91
|
-
# the host to perform the action on
|
92
|
-
# @param [String] secret
|
93
|
-
# your organization's encrypted data bag secret
|
94
|
-
#
|
95
|
-
# @option options [Hash] :ssh
|
96
|
-
# * :user (String) a shell user that will login to each node and perform the bootstrap command on
|
97
|
-
# * :password (String) the password for the shell user that will perform the bootstrap
|
98
|
-
# * :keys (Array, String) an array of key(s) to authenticate the ssh user with instead of a password
|
99
|
-
# * :timeout (Float) timeout value for SSH bootstrap (5.0)
|
100
|
-
# * :sudo (Boolean) run as sudo
|
101
|
-
# @option options [Hash] :winrm
|
102
|
-
# * :user (String) a user that will login to each node and perform the bootstrap command on
|
103
|
-
# * :password (String) the password for the user that will perform the bootstrap (required)
|
104
|
-
# * :port (Fixnum) the winrm port to connect on the node the bootstrap will be performed on (5985)
|
105
|
-
#
|
106
|
-
# @return [HostConnector::Response]
|
107
|
-
def put_secret(host, secret, options = {})
|
108
|
-
execute(__method__, host, secret, options)
|
109
|
-
end
|
110
|
-
|
111
|
-
# Execute line(s) of Ruby code on a node using Chef's embedded Ruby
|
112
|
-
#
|
113
|
-
# @param [String] host
|
114
|
-
# the host to perform the action on
|
115
|
-
# @param [Array<String>] command_lines
|
116
|
-
# An Array of lines of the command to be executed
|
117
|
-
#
|
118
|
-
# @option options [Hash] :ssh
|
119
|
-
# * :user (String) a shell user that will login to each node and perform the bootstrap command on
|
120
|
-
# * :password (String) the password for the shell user that will perform the bootstrap
|
121
|
-
# * :keys (Array, String) an array of key(s) to authenticate the ssh user with instead of a password
|
122
|
-
# * :timeout (Float) timeout value for SSH bootstrap (5.0)
|
123
|
-
# * :sudo (Boolean) run as sudo
|
124
|
-
# @option options [Hash] :winrm
|
125
|
-
# * :user (String) a user that will login to each node and perform the bootstrap command on
|
126
|
-
# * :password (String) the password for the user that will perform the bootstrap (required)
|
127
|
-
# * :port (Fixnum) the winrm port to connect on the node the bootstrap will be performed on (5985)
|
128
|
-
#
|
129
|
-
# @return [HostConnector::Response]
|
130
|
-
def ruby_script(host, command_lines, options = {})
|
131
|
-
execute(__method__, host, command_lines, options)
|
132
|
-
end
|
133
|
-
|
134
|
-
# Uninstall Chef from a node
|
135
|
-
#
|
136
|
-
# @param [String] host
|
137
|
-
# the host to perform the action on
|
138
|
-
#
|
139
|
-
# @option options [Boolena] :skip_chef (false)
|
140
|
-
# skip removal of the Chef package and the contents of the installation
|
141
|
-
# directory. Setting this to true will only remove any data and configurations
|
142
|
-
# generated by running Chef client.
|
143
|
-
# @option options [Hash] :ssh
|
144
|
-
# * :user (String) a shell user that will login to each node and perform the bootstrap command on
|
145
|
-
# * :password (String) the password for the shell user that will perform the bootstrap
|
146
|
-
# * :keys (Array, String) an array of key(s) to authenticate the ssh user with instead of a password
|
147
|
-
# * :timeout (Float) timeout value for SSH bootstrap (5.0)
|
148
|
-
# * :sudo (Boolean) run as sudo (true)
|
149
|
-
# @option options [Hash] :winrm
|
150
|
-
# * :user (String) a user that will login to each node and perform the bootstrap command on
|
151
|
-
# * :password (String) the password for the user that will perform the bootstrap (required)
|
152
|
-
# * :port (Fixnum) the winrm port to connect on the node the bootstrap will be performed on (5985)
|
153
|
-
#
|
154
|
-
# @return [HostConnector::Response]
|
155
|
-
def uninstall_chef(host, options = {})
|
156
|
-
execute(__method__, host, options)
|
157
|
-
end
|
158
|
-
|
159
|
-
# Finds and returns the best HostConnector for a given host
|
160
|
-
#
|
161
|
-
# @param [String] host
|
162
|
-
# the host to attempt to connect to
|
163
|
-
# @option options [Hash] :ssh
|
164
|
-
# * :port (Fixnum) the ssh port to connect on the node the bootstrap will be performed on (22)
|
165
|
-
# * :timeout (Float) [5.0] timeout value for testing SSH connection
|
166
|
-
# @option options [Hash] :winrm
|
167
|
-
# * :port (Fixnum) the winrm port to connect on the node the bootstrap will be performed on (5985)
|
168
|
-
# @param block [Proc]
|
169
|
-
# an optional block that is yielded the best HostConnector
|
170
|
-
#
|
171
|
-
# @return [HostConnector::SSH, HostConnector::WinRM]
|
172
|
-
def connector_for(host, options = {})
|
173
|
-
options = options.reverse_merge(ssh: Hash.new, winrm: Hash.new)
|
174
|
-
options[:ssh][:port] ||= HostConnector::SSH::DEFAULT_PORT
|
175
|
-
options[:winrm][:port] ||= HostConnector::WinRM::DEFAULT_PORT
|
176
|
-
|
177
|
-
if connector_port_open?(host, options[:winrm][:port])
|
178
|
-
options.delete(:ssh)
|
179
|
-
winrm
|
180
|
-
elsif connector_port_open?(host, options[:ssh][:port], options[:ssh][:timeout])
|
181
|
-
options.delete(:winrm)
|
182
|
-
ssh
|
183
|
-
else
|
184
|
-
raise Errors::HostConnectionError, "No connector ports open on '#{host}'"
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
private
|
189
|
-
|
190
|
-
def execute(method, host, *args)
|
191
|
-
options = args.last.is_a?(Hash) ? args.pop : Hash.new
|
192
|
-
|
193
|
-
connector_for(host, options).send(method, host, *args, options)
|
194
|
-
rescue Errors::HostConnectionError => ex
|
195
|
-
abort(ex)
|
196
|
-
rescue Resolv::ResolvError => ex
|
197
|
-
abort Errors::DNSResolvError.new(ex)
|
198
|
-
end
|
199
|
-
|
200
|
-
# Checks to see if the given port is open for TCP connections
|
201
|
-
# on the given host.
|
202
|
-
#
|
203
|
-
# @param [String] host
|
204
|
-
# the host to attempt to connect to
|
205
|
-
# @param [Fixnum] port
|
206
|
-
# the port to attempt to connect on
|
207
|
-
# @param [Float] wait_time ({PORT_CHECK_TIMEOUT})
|
208
|
-
# the number of seconds to wait
|
209
|
-
#
|
210
|
-
# @return [Boolean]
|
211
|
-
def connector_port_open?(host, port, wait_time = nil)
|
212
|
-
defer {
|
213
|
-
Timeout.timeout(wait_time || PORT_CHECK_TIMEOUT) { Celluloid::IO::TCPSocket.new(host, port).close; true }
|
214
|
-
}
|
215
|
-
rescue Errno::ETIMEDOUT, Timeout::Error, SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::EADDRNOTAVAIL => ex
|
216
|
-
false
|
217
|
-
end
|
218
|
-
|
219
|
-
def finalize_callback
|
220
|
-
@connector_supervisor.terminate if @connector_supervisor && @connector_supervisor.alive?
|
221
|
-
end
|
222
|
-
|
223
|
-
def ssh
|
224
|
-
@connector_registry[:ssh]
|
225
|
-
end
|
226
|
-
|
227
|
-
def winrm
|
228
|
-
@connector_registry[:winrm]
|
229
|
-
end
|
230
|
-
end
|
231
|
-
end
|
@@ -1,83 +0,0 @@
|
|
1
|
-
module Ridley
|
2
|
-
module HostConnector
|
3
|
-
class Base
|
4
|
-
include Celluloid
|
5
|
-
include Ridley::Logging
|
6
|
-
|
7
|
-
# Execute a shell command on a node
|
8
|
-
#
|
9
|
-
# @param [String] host
|
10
|
-
# the host to perform the action on
|
11
|
-
# @param [String] command
|
12
|
-
# @param [Hash] options
|
13
|
-
#
|
14
|
-
# @return [HostConnector::Response]
|
15
|
-
def run(host, command, options = {})
|
16
|
-
raise RuntimeError, "abstract function: must be implemented on includer"
|
17
|
-
end
|
18
|
-
|
19
|
-
# Bootstrap a node
|
20
|
-
#
|
21
|
-
# @param [String] host
|
22
|
-
# the host to perform the action on
|
23
|
-
# @param [Hash] options
|
24
|
-
#
|
25
|
-
# @return [HostConnector::Response]
|
26
|
-
def bootstrap(host, options = {})
|
27
|
-
raise RuntimeError, "abstract function: must be implemented on includer"
|
28
|
-
end
|
29
|
-
|
30
|
-
# Perform a chef client run on a node
|
31
|
-
#
|
32
|
-
# @param [String] host
|
33
|
-
# the host to perform the action on
|
34
|
-
# @param [Hash] options
|
35
|
-
#
|
36
|
-
# @return [HostConnector::Response]
|
37
|
-
def chef_client(host, options = {})
|
38
|
-
raise RuntimeError, "abstract function: must be implemented on includer"
|
39
|
-
end
|
40
|
-
|
41
|
-
# Write your encrypted data bag secret on a node
|
42
|
-
#
|
43
|
-
# @param [String] host
|
44
|
-
# the host to perform the action on
|
45
|
-
# @param [String] secret
|
46
|
-
# your organization's encrypted data bag secret
|
47
|
-
# @param [Hash] options
|
48
|
-
#
|
49
|
-
# @return [HostConnector::Response]
|
50
|
-
def put_secret(host, secret, options = {})
|
51
|
-
raise RuntimeError, "abstract function: must be implemented on includer"
|
52
|
-
end
|
53
|
-
|
54
|
-
# Execute line(s) of Ruby code on a node using Chef's embedded Ruby
|
55
|
-
#
|
56
|
-
# @param [String] host
|
57
|
-
# the host to perform the action on
|
58
|
-
# @param [Array<String>] command_lines
|
59
|
-
# An Array of lines of the command to be executed
|
60
|
-
# @param [Hash] options
|
61
|
-
#
|
62
|
-
# @return [HostConnector::Response]
|
63
|
-
def ruby_script(host, command_lines, options = {})
|
64
|
-
raise RuntimeError, "abstract function: must be implemented on includer"
|
65
|
-
end
|
66
|
-
|
67
|
-
# Uninstall Chef from a node
|
68
|
-
#
|
69
|
-
# @param [String] host
|
70
|
-
# the host to perform the action on
|
71
|
-
# @param [Hash] options
|
72
|
-
#
|
73
|
-
# @return [HostConnector::Response]
|
74
|
-
def uninstall_chef(host, options = {})
|
75
|
-
raise RuntimeError, "abstract function: must be implemented on includer"
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
require_relative 'host_connector/response'
|
80
|
-
require_relative 'host_connector/ssh'
|
81
|
-
require_relative 'host_connector/winrm'
|
82
|
-
end
|
83
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
module Ridley
|
2
|
-
module HostConnector
|
3
|
-
class Response
|
4
|
-
attr_reader :host
|
5
|
-
|
6
|
-
attr_accessor :stdout
|
7
|
-
attr_accessor :stderr
|
8
|
-
attr_accessor :exit_code
|
9
|
-
attr_accessor :exit_signal
|
10
|
-
|
11
|
-
def initialize(host, options = {})
|
12
|
-
@host = host
|
13
|
-
@stdout = options[:stdout] || String.new
|
14
|
-
@stderr = options[:stderr] || String.new
|
15
|
-
@exit_code = options[:exit_code] || -1
|
16
|
-
@exit_signal = options[:exit_signal] || nil
|
17
|
-
end
|
18
|
-
|
19
|
-
# Return true if the response was not successful
|
20
|
-
#
|
21
|
-
# @return [Boolean]
|
22
|
-
def error?
|
23
|
-
self.exit_code != 0
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,211 +0,0 @@
|
|
1
|
-
require 'net/ssh'
|
2
|
-
|
3
|
-
module Ridley
|
4
|
-
module HostConnector
|
5
|
-
class SSH < HostConnector::Base
|
6
|
-
DEFAULT_PORT = 22
|
7
|
-
EMBEDDED_RUBY_PATH = '/opt/chef/embedded/bin/ruby'.freeze
|
8
|
-
|
9
|
-
# Execute a shell command on a node
|
10
|
-
#
|
11
|
-
# @param [String] host
|
12
|
-
# the host to perform the action on
|
13
|
-
# @param [String] command
|
14
|
-
#
|
15
|
-
# @option options [Hash] :ssh
|
16
|
-
# * :user (String) a shell user that will login to each node and perform the bootstrap command on
|
17
|
-
# * :password (String) the password for the shell user that will perform the bootstrap
|
18
|
-
# * :keys (Array, String) an array of key(s) to authenticate the ssh user with instead of a password
|
19
|
-
# * :timeout (Float) timeout value for SSH bootstrap (5.0)
|
20
|
-
# * :sudo (Boolean) run as sudo
|
21
|
-
#
|
22
|
-
# @return [HostConnector::Response]
|
23
|
-
def run(host, command, options = {})
|
24
|
-
options = options.reverse_merge(ssh: Hash.new)
|
25
|
-
options[:ssh].reverse_merge!(port: DEFAULT_PORT, paranoid: false, sudo: false)
|
26
|
-
|
27
|
-
command = "sudo #{command}" if options[:ssh][:sudo]
|
28
|
-
|
29
|
-
Ridley::HostConnector::Response.new(host).tap do |response|
|
30
|
-
begin
|
31
|
-
log.info "Running SSH command: '#{command}' on: '#{host}' as: '#{options[:ssh][:user]}'"
|
32
|
-
|
33
|
-
defer {
|
34
|
-
Net::SSH.start(host, options[:ssh][:user], options[:ssh].slice(*Net::SSH::VALID_OPTIONS)) do |ssh|
|
35
|
-
ssh.open_channel do |channel|
|
36
|
-
if options[:sudo]
|
37
|
-
channel.request_pty do |channel, success|
|
38
|
-
unless success
|
39
|
-
raise "Could not aquire pty: A pty is required for running sudo commands."
|
40
|
-
end
|
41
|
-
|
42
|
-
channel_exec(channel, command, host, response)
|
43
|
-
end
|
44
|
-
else
|
45
|
-
channel_exec(channel, command, host, response)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
ssh.loop
|
49
|
-
end
|
50
|
-
}
|
51
|
-
rescue Net::SSH::AuthenticationFailed => ex
|
52
|
-
response.exit_code = -1
|
53
|
-
response.stderr = "Authentication failure for user #{ex}"
|
54
|
-
rescue Net::SSH::ConnectionTimeout, Timeout::Error
|
55
|
-
response.exit_code = -1
|
56
|
-
response.stderr = "Connection timed out"
|
57
|
-
rescue Errno::EHOSTUNREACH
|
58
|
-
response.exit_code = -1
|
59
|
-
response.stderr = "Host unreachable"
|
60
|
-
rescue Errno::ECONNREFUSED
|
61
|
-
response.exit_code = -1
|
62
|
-
response.stderr = "Connection refused"
|
63
|
-
rescue Net::SSH::Exception => ex
|
64
|
-
response.exit_code = -1
|
65
|
-
response.stderr = ex.inspect
|
66
|
-
end
|
67
|
-
|
68
|
-
case response.exit_code
|
69
|
-
when 0
|
70
|
-
log.info "Successfully ran SSH command on: '#{host}' as: '#{options[:ssh][:user]}'"
|
71
|
-
when -1
|
72
|
-
log.info "Failed to run SSH command on: '#{host}' as: '#{options[:ssh][:user]}'"
|
73
|
-
else
|
74
|
-
log.info "Successfully ran SSH command on: '#{host}' as: '#{options[:ssh][:user]}' but it failed"
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
# Bootstrap a node
|
80
|
-
#
|
81
|
-
# @param [String] host
|
82
|
-
# the host to perform the action on
|
83
|
-
#
|
84
|
-
# @option options [Hash] :ssh
|
85
|
-
# * :user (String) a shell user that will login to each node and perform the bootstrap command on
|
86
|
-
# * :password (String) the password for the shell user that will perform the bootstrap
|
87
|
-
# * :keys (Array, String) an array of key(s) to authenticate the ssh user with instead of a password
|
88
|
-
# * :timeout (Float) timeout value for SSH bootstrap (5.0)
|
89
|
-
# * :sudo (Boolean) run as sudo
|
90
|
-
#
|
91
|
-
# @return [HostConnector::Response]
|
92
|
-
def bootstrap(host, options = {})
|
93
|
-
options = options.reverse_merge(ssh: Hash.new)
|
94
|
-
options[:ssh].reverse_merge!(sudo: true, timeout: 5.0)
|
95
|
-
context = BootstrapContext::Unix.new(options)
|
96
|
-
|
97
|
-
log.info "Bootstrapping host: #{host}"
|
98
|
-
run(host, context.boot_command, options)
|
99
|
-
end
|
100
|
-
|
101
|
-
# Perform a chef client run on a node
|
102
|
-
#
|
103
|
-
# @param [String] host
|
104
|
-
# the host to perform the action on
|
105
|
-
#
|
106
|
-
# @option options [Hash] :ssh
|
107
|
-
# * :user (String) a shell user that will login to each node and perform the bootstrap command on
|
108
|
-
# * :password (String) the password for the shell user that will perform the bootstrap
|
109
|
-
# * :keys (Array, String) an array of key(s) to authenticate the ssh user with instead of a password
|
110
|
-
# * :timeout (Float) timeout value for SSH bootstrap (5.0)
|
111
|
-
# * :sudo (Boolean) run as sudo
|
112
|
-
#
|
113
|
-
# @return [HostConnector::Response]
|
114
|
-
def chef_client(host, options = {})
|
115
|
-
run(host, "chef-client", options)
|
116
|
-
end
|
117
|
-
|
118
|
-
# Write your encrypted data bag secret on a node
|
119
|
-
#
|
120
|
-
# @param [String] host
|
121
|
-
# the host to perform the action on
|
122
|
-
# @param [String] secret
|
123
|
-
# your organization's encrypted data bag secret
|
124
|
-
#
|
125
|
-
# @option options [Hash] :ssh
|
126
|
-
# * :user (String) a shell user that will login to each node and perform the bootstrap command on
|
127
|
-
# * :password (String) the password for the shell user that will perform the bootstrap
|
128
|
-
# * :keys (Array, String) an array of key(s) to authenticate the ssh user with instead of a password
|
129
|
-
# * :timeout (Float) timeout value for SSH bootstrap (5.0)
|
130
|
-
# * :sudo (Boolean) run as sudo
|
131
|
-
#
|
132
|
-
# @return [HostConnector::Response]
|
133
|
-
def put_secret(host, secret, options = {})
|
134
|
-
cmd = "echo '#{secret}' > /etc/chef/encrypted_data_bag_secret; chmod 0600 /etc/chef/encrypted_data_bag_secret"
|
135
|
-
run(host, cmd, options)
|
136
|
-
end
|
137
|
-
|
138
|
-
# Execute line(s) of Ruby code on a node using Chef's embedded Ruby
|
139
|
-
#
|
140
|
-
# @param [String] host
|
141
|
-
# the host to perform the action on
|
142
|
-
# @param [Array<String>] command_lines
|
143
|
-
# An Array of lines of the command to be executed
|
144
|
-
#
|
145
|
-
# @option options [Hash] :ssh
|
146
|
-
# * :user (String) a shell user that will login to each node and perform the bootstrap command on
|
147
|
-
# * :password (String) the password for the shell user that will perform the bootstrap
|
148
|
-
# * :keys (Array, String) an array of key(s) to authenticate the ssh user with instead of a password
|
149
|
-
# * :timeout (Float) timeout value for SSH bootstrap (5.0)
|
150
|
-
# * :sudo (Boolean) run as sudo
|
151
|
-
#
|
152
|
-
# @return [HostConnector::Response]
|
153
|
-
def ruby_script(host, command_lines, options = {})
|
154
|
-
run(host, "#{EMBEDDED_RUBY_PATH} -e \"#{command_lines.join(';')}\"", options)
|
155
|
-
end
|
156
|
-
|
157
|
-
# Uninstall Chef from a node
|
158
|
-
#
|
159
|
-
# @param [String] host
|
160
|
-
# the host to perform the action on
|
161
|
-
#
|
162
|
-
# @option options [Boolena] :skip_chef (false)
|
163
|
-
# skip removal of the Chef package and the contents of the installation
|
164
|
-
# directory. Setting this to true will only remove any data and configurations
|
165
|
-
# generated by running Chef client.
|
166
|
-
# @option options [Hash] :ssh
|
167
|
-
# * :user (String) a shell user that will login to each node and perform the bootstrap command on
|
168
|
-
# * :password (String) the password for the shell user that will perform the bootstrap
|
169
|
-
# * :keys (Array, String) an array of key(s) to authenticate the ssh user with instead of a password
|
170
|
-
# * :timeout (Float) timeout value for SSH bootstrap (5.0)
|
171
|
-
# * :sudo (Boolean) run as sudo (true)
|
172
|
-
#
|
173
|
-
# @return [HostConnector::Response]
|
174
|
-
def uninstall_chef(host, options = {})
|
175
|
-
options = options.reverse_merge(ssh: Hash.new)
|
176
|
-
options[:ssh].reverse_merge!(sudo: true, timeout: 5.0)
|
177
|
-
|
178
|
-
log.info "Uninstalling Chef from host: #{host}"
|
179
|
-
run(host, CommandContext::UnixUninstall.command(options), options)
|
180
|
-
end
|
181
|
-
|
182
|
-
private
|
183
|
-
|
184
|
-
def channel_exec(channel, command, host, response)
|
185
|
-
channel.exec(command) do |ch, success|
|
186
|
-
unless success
|
187
|
-
raise "Channel execution failed while executing command #{command}"
|
188
|
-
end
|
189
|
-
|
190
|
-
channel.on_data do |ch, data|
|
191
|
-
response.stdout += data
|
192
|
-
log.info "[#{host}](SSH) #{data}" if data.present? and data != "\r\n"
|
193
|
-
end
|
194
|
-
|
195
|
-
channel.on_extended_data do |ch, type, data|
|
196
|
-
response.stderr += data
|
197
|
-
log.info "[#{host}](SSH) #{data}" if data.present? and data != "\r\n"
|
198
|
-
end
|
199
|
-
|
200
|
-
channel.on_request("exit-status") do |ch, data|
|
201
|
-
response.exit_code = data.read_long
|
202
|
-
end
|
203
|
-
|
204
|
-
channel.on_request("exit-signal") do |ch, data|
|
205
|
-
response.exit_signal = data.read_string
|
206
|
-
end
|
207
|
-
end
|
208
|
-
end
|
209
|
-
end
|
210
|
-
end
|
211
|
-
end
|