ridley 0.12.4 → 1.0.0.rc1
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.
- data/Gemfile +1 -1
- data/lib/ridley.rb +3 -3
- data/lib/ridley/bootstrap_context.rb +100 -0
- data/lib/ridley/bootstrap_context/unix.rb +74 -0
- data/lib/ridley/bootstrap_context/windows.rb +120 -0
- data/lib/ridley/chef_objects/node_object.rb +8 -5
- data/lib/ridley/host_commander.rb +207 -0
- data/lib/ridley/host_connector.rb +49 -87
- data/lib/ridley/host_connector/ssh.rb +153 -39
- data/lib/ridley/host_connector/winrm.rb +164 -39
- data/lib/ridley/resources/node_resource.rb +52 -56
- data/lib/ridley/version.rb +1 -1
- data/ridley.gemspec +0 -2
- data/spec/spec_helper.rb +4 -4
- data/spec/support/chef_server.rb +9 -3
- data/spec/unit/ridley/{bootstrap_bindings/unix_template_binding_spec.rb → bootstrap_context/unix_spec.rb} +2 -2
- data/spec/unit/ridley/{bootstrap_bindings/windows_template_binding_spec.rb → bootstrap_context/windows_spec.rb} +2 -2
- data/spec/unit/ridley/{mixin/bootstrap_binding_spec.rb → bootstrap_context_spec.rb} +2 -6
- data/spec/unit/ridley/host_commander_spec.rb +208 -0
- data/spec/unit/ridley/host_connector/ssh_spec.rb +37 -31
- data/spec/unit/ridley/host_connector/winrm_spec.rb +124 -31
- data/spec/unit/ridley/host_connector_spec.rb +23 -147
- data/spec/unit/ridley/resources/node_resource_spec.rb +55 -115
- metadata +17 -66
- data/lib/ridley/bootstrap_bindings.rb +0 -3
- data/lib/ridley/bootstrap_bindings/unix_template_binding.rb +0 -108
- data/lib/ridley/bootstrap_bindings/windows_template_binding.rb +0 -163
- data/lib/ridley/bootstrapper.rb +0 -89
- data/lib/ridley/bootstrapper/context.rb +0 -81
- data/lib/ridley/host_connector/response_set.rb +0 -98
- data/lib/ridley/host_connector/ssh/worker.rb +0 -135
- data/lib/ridley/host_connector/winrm/worker.rb +0 -159
- data/lib/ridley/log.rb +0 -10
- data/lib/ridley/mixin/bootstrap_binding.rb +0 -77
- data/spec/unit/ridley/bootstrapper/context_spec.rb +0 -45
- data/spec/unit/ridley/bootstrapper_spec.rb +0 -96
- data/spec/unit/ridley/host_connector/response_set_spec.rb +0 -112
- data/spec/unit/ridley/host_connector/ssh/worker_spec.rb +0 -57
- data/spec/unit/ridley/host_connector/winrm/worker_spec.rb +0 -139
@@ -1,111 +1,73 @@
|
|
1
|
-
require 'socket'
|
2
|
-
require 'timeout'
|
3
|
-
|
4
1
|
module Ridley
|
5
2
|
# @author Kyle Allan <kallan@riotgames.com>
|
6
3
|
module HostConnector
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
require_relative 'host_connector/winrm'
|
11
|
-
|
12
|
-
DEFAULT_SSH_PORT = 22.freeze
|
13
|
-
DEFAULT_WINRM_PORT = 5985.freeze
|
4
|
+
class Base
|
5
|
+
include Celluloid
|
6
|
+
include Ridley::Logging
|
14
7
|
|
15
|
-
|
16
|
-
# Create a new connection worker for the given host. An SSH or WinRM connection will be returned
|
17
|
-
# depending on which ports are open on the target host.
|
8
|
+
# Execute a shell command on a node
|
18
9
|
#
|
19
10
|
# @param [String] host
|
20
|
-
# host to
|
11
|
+
# the host to perform the action on
|
12
|
+
# @param [String] command
|
13
|
+
# @param [Hash] options
|
21
14
|
#
|
22
|
-
# @
|
23
|
-
|
24
|
-
|
25
|
-
# * :keys (Array, String) an array of keys (or a single key) to authenticate the ssh user with instead of a password
|
26
|
-
# * :timeout (Float) [5.0] timeout value for SSH bootstrap
|
27
|
-
# @option options [Hash] :winrm
|
28
|
-
# * :user (String) a user that will login to each node and perform the bootstrap command on
|
29
|
-
# * :password (String) the password for the user that will perform the bootstrap
|
30
|
-
# * :port (Fixnum) the winrm port to connect on the node the bootstrap will be performed on
|
31
|
-
#
|
32
|
-
# @return [SSH::Worker, WinRM::Worker]
|
33
|
-
def new(host, options = {})
|
34
|
-
HostConnector.best_connector_for(host, options) do |host_connector|
|
35
|
-
host_connector::Worker.new(host, options)
|
36
|
-
end
|
15
|
+
# @return [HostConnector::Response]
|
16
|
+
def run(host, command, options = {})
|
17
|
+
raise RuntimeError, "abstract function: must be implemented on includer"
|
37
18
|
end
|
38
19
|
|
39
|
-
#
|
20
|
+
# Bootstrap a node
|
40
21
|
#
|
41
|
-
# @param
|
42
|
-
# the host to
|
43
|
-
# @
|
44
|
-
# * :port (Fixnum) the ssh port to connect on the node the bootstrap will be performed on (22)
|
45
|
-
# * :timeout (Float) [5.0] timeout value for testing SSH connection
|
46
|
-
# @option options [Hash] :winrm
|
47
|
-
# * :port (Fixnum) the winrm port to connect on the node the bootstrap will be performed on (5985)
|
48
|
-
# @param block [Proc]
|
49
|
-
# an optional block that is yielded the best HostConnector
|
22
|
+
# @param [String] host
|
23
|
+
# the host to perform the action on
|
24
|
+
# @param [Hash] options
|
50
25
|
#
|
51
|
-
# @return [
|
52
|
-
def
|
53
|
-
|
54
|
-
timeout = options[:ssh] && options[:ssh][:timeout]
|
55
|
-
|
56
|
-
if connector_port_open?(host, winrm_port)
|
57
|
-
host_connector = Ridley::HostConnector::WinRM
|
58
|
-
elsif connector_port_open?(host, ssh_port, timeout)
|
59
|
-
host_connector = Ridley::HostConnector::SSH
|
60
|
-
else
|
61
|
-
raise Ridley::Errors::HostConnectionError, "No available connection method available on #{host}."
|
62
|
-
end
|
63
|
-
|
64
|
-
if block_given?
|
65
|
-
yield host_connector
|
66
|
-
else
|
67
|
-
host_connector
|
68
|
-
end
|
26
|
+
# @return [HostConnector::Response]
|
27
|
+
def bootstrap(host, options = {})
|
28
|
+
raise RuntimeError, "abstract function: must be implemented on includer"
|
69
29
|
end
|
70
30
|
|
71
|
-
#
|
72
|
-
# on the given host.
|
31
|
+
# Perform a chef client run on a node
|
73
32
|
#
|
74
|
-
# @param
|
75
|
-
# the host to
|
76
|
-
# @param
|
77
|
-
# the port to attempt to connect on
|
78
|
-
# @param timeout [Float]
|
79
|
-
# the number of seconds to wait (default: 3)
|
33
|
+
# @param [String] host
|
34
|
+
# the host to perform the action on
|
35
|
+
# @param [Hash] options
|
80
36
|
#
|
81
|
-
# @return [
|
82
|
-
def
|
83
|
-
|
84
|
-
|
85
|
-
Timeout::timeout(timeout) do
|
86
|
-
socket = TCPSocket.new(host, port)
|
87
|
-
socket.close
|
88
|
-
end
|
37
|
+
# @return [HostConnector::Response]
|
38
|
+
def chef_client(host, options = {})
|
39
|
+
raise RuntimeError, "abstract function: must be implemented on includer"
|
40
|
+
end
|
89
41
|
|
90
|
-
|
91
|
-
|
92
|
-
|
42
|
+
# Write your encrypted data bag secret on a node
|
43
|
+
#
|
44
|
+
# @param [String] host
|
45
|
+
# the host to perform the action on
|
46
|
+
# @param [String] secret
|
47
|
+
# your organization's encrypted data bag secret
|
48
|
+
# @param [Hash] options
|
49
|
+
#
|
50
|
+
# @return [HostConnector::Response]
|
51
|
+
def put_secret(host, secret, options = {})
|
52
|
+
raise RuntimeError, "abstract function: must be implemented on includer"
|
93
53
|
end
|
94
54
|
|
95
|
-
#
|
96
|
-
# [SSH_PORT, WINRM_PORT] used to attempt to connect to.
|
55
|
+
# Execute line(s) of Ruby code on a node using Chef's embedded Ruby
|
97
56
|
#
|
98
|
-
# @
|
99
|
-
#
|
100
|
-
# @
|
101
|
-
#
|
57
|
+
# @param [String] host
|
58
|
+
# the host to perform the action on
|
59
|
+
# @param [Array<String>] command_lines
|
60
|
+
# An Array of lines of the command to be executed
|
61
|
+
# @param [Hash] options
|
102
62
|
#
|
103
|
-
# @return [
|
104
|
-
def
|
105
|
-
|
106
|
-
winrm_port = options[:winrm][:port] if options[:winrm]
|
107
|
-
[ssh_port || DEFAULT_SSH_PORT, winrm_port || DEFAULT_WINRM_PORT]
|
63
|
+
# @return [HostConnector::Response]
|
64
|
+
def ruby_script(host, command_lines, options = {})
|
65
|
+
raise RuntimeError, "abstract function: must be implemented on includer"
|
108
66
|
end
|
109
67
|
end
|
68
|
+
|
69
|
+
require_relative 'host_connector/response'
|
70
|
+
require_relative 'host_connector/ssh'
|
71
|
+
require_relative 'host_connector/winrm'
|
110
72
|
end
|
111
73
|
end
|
@@ -3,56 +3,170 @@ require 'net/ssh'
|
|
3
3
|
module Ridley
|
4
4
|
module HostConnector
|
5
5
|
# @author Jamie Winsor <reset@riotgames.com>
|
6
|
-
class SSH
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
6
|
+
class SSH < HostConnector::Base
|
7
|
+
DEFAULT_PORT = 22
|
8
|
+
EMBEDDED_RUBY_PATH = '/opt/chef/embedded/bin/ruby'.freeze
|
9
|
+
|
10
|
+
# Execute a shell command on a node
|
11
|
+
#
|
12
|
+
# @param [String] host
|
13
|
+
# the host to perform the action on
|
14
|
+
# @param [String] command
|
15
|
+
#
|
16
|
+
# @option options [Hash] :ssh
|
17
|
+
# * :user (String) a shell user that will login to each node and perform the bootstrap command on
|
18
|
+
# * :password (String) the password for the shell user that will perform the bootstrap
|
19
|
+
# * :keys (Array, String) an array of key(s) to authenticate the ssh user with instead of a password
|
20
|
+
# * :timeout (Float) timeout value for SSH bootstrap (5.0)
|
21
|
+
# * :sudo (Boolean) run as sudo
|
22
|
+
#
|
23
|
+
# @return [HostConnector::Response]
|
24
|
+
def run(host, command, options = {})
|
25
|
+
options = options.reverse_merge(ssh: Hash.new)
|
26
|
+
options[:ssh].reverse_merge!(port: DEFAULT_PORT, paranoid: false, sudo: false)
|
27
|
+
|
28
|
+
command = "sudo #{command}" if options[:sudo]
|
29
|
+
|
30
|
+
Ridley::HostConnector::Response.new(host).tap do |response|
|
31
|
+
begin
|
32
|
+
log.info "Running SSH command: '#{command}' on: '#{host}' as: '#{options[:ssh][:user]}'"
|
33
|
+
|
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
|
+
rescue Net::SSH::Exception => ex
|
51
|
+
response.exit_code = -1
|
52
|
+
response.stderr = ex.message
|
53
|
+
return response
|
54
|
+
end
|
55
|
+
|
56
|
+
case response.exit_code
|
57
|
+
when 0
|
58
|
+
log.info "Successfully ran SSH command on: '#{host}' as: '#{options[:ssh][:user]}'"
|
59
|
+
else
|
60
|
+
log.info "Successfully ran SSH command on: '#{host}' as: '#{options[:ssh][:user]}' but it failed"
|
61
|
+
end
|
20
62
|
end
|
21
63
|
end
|
22
64
|
|
23
|
-
|
24
|
-
|
65
|
+
# Bootstrap a node
|
66
|
+
#
|
67
|
+
# @param [String] host
|
68
|
+
# the host to perform the action on
|
69
|
+
#
|
70
|
+
# @option options [Hash] :ssh
|
71
|
+
# * :user (String) a shell user that will login to each node and perform the bootstrap command on
|
72
|
+
# * :password (String) the password for the shell user that will perform the bootstrap
|
73
|
+
# * :keys (Array, String) an array of key(s) to authenticate the ssh user with instead of a password
|
74
|
+
# * :timeout (Float) timeout value for SSH bootstrap (5.0)
|
75
|
+
# * :sudo (Boolean) run as sudo
|
76
|
+
#
|
77
|
+
# @return [HostConnector::Response]
|
78
|
+
def bootstrap(host, options = {})
|
79
|
+
options = options.reverse_merge(ssh: Hash.new)
|
80
|
+
options[:ssh].reverse_merge!(sudo: true, timeout: 5.0)
|
81
|
+
context = BootstrapContext::Unix.new(options)
|
25
82
|
|
26
|
-
|
27
|
-
|
83
|
+
log.info "Bootstrapping host: #{host}"
|
84
|
+
run(host, context.boot_command, options)
|
85
|
+
end
|
28
86
|
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
|
33
|
-
|
34
|
-
|
87
|
+
# Perform a chef client run on a node
|
88
|
+
#
|
89
|
+
# @param [String] host
|
90
|
+
# the host to perform the action on
|
91
|
+
#
|
92
|
+
# @option options [Hash] :ssh
|
93
|
+
# * :user (String) a shell user that will login to each node and perform the bootstrap command on
|
94
|
+
# * :password (String) the password for the shell user that will perform the bootstrap
|
95
|
+
# * :keys (Array, String) an array of key(s) to authenticate the ssh user with instead of a password
|
96
|
+
# * :timeout (Float) timeout value for SSH bootstrap (5.0)
|
97
|
+
# * :sudo (Boolean) run as sudo
|
98
|
+
#
|
99
|
+
# @return [HostConnector::Response]
|
100
|
+
def chef_client(host, options = {})
|
101
|
+
run(host, "chef-client", options)
|
35
102
|
end
|
36
103
|
|
37
|
-
#
|
104
|
+
# Write your encrypted data bag secret on a node
|
38
105
|
#
|
39
|
-
# @
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
106
|
+
# @param [String] host
|
107
|
+
# the host to perform the action on
|
108
|
+
# @param [String] secret
|
109
|
+
# your organization's encrypted data bag secret
|
110
|
+
#
|
111
|
+
# @option options [Hash] :ssh
|
112
|
+
# * :user (String) a shell user that will login to each node and perform the bootstrap command on
|
113
|
+
# * :password (String) the password for the shell user that will perform the bootstrap
|
114
|
+
# * :keys (Array, String) an array of key(s) to authenticate the ssh user with instead of a password
|
115
|
+
# * :timeout (Float) timeout value for SSH bootstrap (5.0)
|
116
|
+
# * :sudo (Boolean) run as sudo
|
117
|
+
#
|
118
|
+
# @return [HostConnector::Response]
|
119
|
+
def put_secret(host, secret, options = {})
|
120
|
+
cmd = "echo '#{secret}' > /etc/chef/encrypted_data_bag_secret; chmod 0600 /etc/chef/encrypted_data_bag_secret"
|
121
|
+
run(host, cmd, options)
|
122
|
+
end
|
46
123
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
124
|
+
# Execute line(s) of Ruby code on a node using Chef's embedded Ruby
|
125
|
+
#
|
126
|
+
# @param [String] host
|
127
|
+
# the host to perform the action on
|
128
|
+
# @param [Array<String>] command_lines
|
129
|
+
# An Array of lines of the command to be executed
|
130
|
+
#
|
131
|
+
# @option options [Hash] :ssh
|
132
|
+
# * :user (String) a shell user that will login to each node and perform the bootstrap command on
|
133
|
+
# * :password (String) the password for the shell user that will perform the bootstrap
|
134
|
+
# * :keys (Array, String) an array of key(s) to authenticate the ssh user with instead of a password
|
135
|
+
# * :timeout (Float) timeout value for SSH bootstrap (5.0)
|
136
|
+
# * :sudo (Boolean) run as sudo
|
137
|
+
#
|
138
|
+
# @return [HostConnector::Response]
|
139
|
+
def ruby_script(host, command_lines, options = {})
|
140
|
+
run(host, "#{EMBEDDED_RUBY_PATH} -e \"#{command_lines.join(';')}\"", options)
|
141
|
+
end
|
142
|
+
|
143
|
+
private
|
144
|
+
|
145
|
+
def channel_exec(channel, command, host, response)
|
146
|
+
channel.exec(command) do |ch, success|
|
147
|
+
unless success
|
148
|
+
raise "Channel execution failed while executing command #{command}"
|
149
|
+
end
|
150
|
+
|
151
|
+
channel.on_data do |ch, data|
|
152
|
+
response.stdout += data
|
153
|
+
log.info "[#{host}](SSH) #{data}" if data.present? and data != "\r\n"
|
154
|
+
end
|
155
|
+
|
156
|
+
channel.on_extended_data do |ch, type, data|
|
157
|
+
response.stderr += data
|
158
|
+
log.info "[#{host}](SSH) #{data}" if data.present? and data != "\r\n"
|
159
|
+
end
|
160
|
+
|
161
|
+
channel.on_request("exit-status") do |ch, data|
|
162
|
+
response.exit_code = data.read_long
|
163
|
+
end
|
164
|
+
|
165
|
+
channel.on_request("exit-signal") do |ch, data|
|
166
|
+
response.exit_signal = data.read_string
|
167
|
+
end
|
51
168
|
end
|
52
169
|
end
|
53
|
-
ensure
|
54
|
-
workers.map(&:terminate)
|
55
|
-
end
|
56
170
|
end
|
57
171
|
end
|
58
172
|
end
|
@@ -1,56 +1,181 @@
|
|
1
|
+
require 'active_support/core_ext/kernel/reporting'
|
2
|
+
# Silencing warnings because not all versions of GSSAPI support all of the GSSAPI methods
|
3
|
+
# the gssapi gem attempts to attach to and these warnings are dumped to STDERR.
|
4
|
+
silence_warnings do
|
5
|
+
require 'winrm'
|
6
|
+
end
|
7
|
+
|
1
8
|
module Ridley
|
2
9
|
module HostConnector
|
3
10
|
# @author Kyle Allan <kallan@riotgames.com>
|
4
|
-
class WinRM
|
11
|
+
class WinRM < HostConnector::Base
|
5
12
|
require_relative 'winrm/command_uploader'
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
13
|
+
|
14
|
+
DEFAULT_PORT = 5985
|
15
|
+
EMBEDDED_RUBY_PATH = 'C:\opscode\chef\embedded\bin\ruby'.freeze
|
16
|
+
|
17
|
+
# Execute a shell command on a node
|
18
|
+
#
|
19
|
+
# @param [String] host
|
20
|
+
# the host to perform the action on
|
21
|
+
# @param [String] command
|
22
|
+
#
|
23
|
+
# @option options [Hash] :winrm
|
24
|
+
# * :user (String) a user that will login to each node and perform the bootstrap command on
|
25
|
+
# * :password (String) the password for the user that will perform the bootstrap (required)
|
26
|
+
# * :port (Fixnum) the winrm port to connect on the node the bootstrap will be performed on (5985)
|
27
|
+
#
|
28
|
+
# @return [HostConnector::Response]
|
29
|
+
def run(host, command, options = {})
|
30
|
+
options = options.reverse_merge(winrm: Hash.new)
|
31
|
+
options[:winrm].reverse_merge!(port: DEFAULT_PORT)
|
32
|
+
|
33
|
+
command_uploaders = Array.new
|
34
|
+
user = options[:winrm][:user]
|
35
|
+
password = options[:winrm][:password]
|
36
|
+
port = options[:winrm][:port]
|
37
|
+
connection = winrm(host, port, options[:winrm].slice(:user, :password))
|
38
|
+
|
39
|
+
HostConnector::Response.new(host).tap do |response|
|
40
|
+
command_uploaders << command_uploader = CommandUploader.new(connection)
|
41
|
+
command = get_command(command, command_uploader)
|
42
|
+
|
43
|
+
begin
|
44
|
+
log.info "Running WinRM Command: '#{command}' on: '#{host}' as: '#{user}'"
|
45
|
+
|
46
|
+
output = connection.run_cmd(command) do |stdout, stderr|
|
47
|
+
if stdout
|
48
|
+
response.stdout += stdout
|
49
|
+
log.info "[#{host}](WinRM) #{stdout}"
|
50
|
+
end
|
51
|
+
|
52
|
+
if stderr
|
53
|
+
response.stderr += stderr unless stderr.nil?
|
54
|
+
log.info "[#{host}](WinRM) #{stdout}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
response.exit_code = output[:exitcode]
|
59
|
+
rescue ::WinRM::WinRMHTTPTransportError => ex
|
60
|
+
response.exit_code = -1
|
61
|
+
response.stderr = ex.message
|
62
|
+
return response
|
63
|
+
end
|
64
|
+
|
65
|
+
case response.exit_code
|
66
|
+
when 0
|
67
|
+
log.info "Successfully ran WinRM command on: '#{host}' as: '#{user}'"
|
68
|
+
else
|
69
|
+
log.info "Successfully ran WinRM command on: '#{host}' as: '#{user}', but it failed"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
ensure
|
73
|
+
command_uploaders.map(&:cleanup)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Returns the command if it does not break the WinRM command length
|
77
|
+
# limit. Otherwise, we return an execution of the command as a batch file.
|
78
|
+
#
|
79
|
+
# @param command [String]
|
80
|
+
#
|
81
|
+
# @return [String]
|
82
|
+
def get_command(command, command_uploader)
|
83
|
+
if command.length < CommandUploader::CHUNK_LIMIT
|
84
|
+
command
|
85
|
+
else
|
86
|
+
log.debug "Detected a command that was longer than #{CommandUploader::CHUNK_LIMIT} characters. " +
|
87
|
+
"Uploading command as a file to the host."
|
88
|
+
command_uploader.upload(command)
|
89
|
+
command_uploader.command
|
19
90
|
end
|
20
91
|
end
|
21
92
|
|
22
|
-
|
23
|
-
|
93
|
+
# Bootstrap a node
|
94
|
+
#
|
95
|
+
# @param [String] host
|
96
|
+
# the host to perform the action on
|
97
|
+
#
|
98
|
+
# @option options [Hash] :winrm
|
99
|
+
# * :user (String) a user that will login to each node and perform the bootstrap command on
|
100
|
+
# * :password (String) the password for the user that will perform the bootstrap (required)
|
101
|
+
# * :port (Fixnum) the winrm port to connect on the node the bootstrap will be performed on (5985)
|
102
|
+
#
|
103
|
+
# @return [HostConnector::Response]
|
104
|
+
def bootstrap(host, options = {})
|
105
|
+
context = BootstrapContext::Windows.new(options)
|
24
106
|
|
25
|
-
|
26
|
-
|
107
|
+
log.info "Bootstrapping host: #{host}"
|
108
|
+
run(host, context.boot_command, options)
|
109
|
+
end
|
27
110
|
|
28
|
-
#
|
29
|
-
#
|
30
|
-
|
31
|
-
|
32
|
-
|
111
|
+
# Perform a chef client run on a node
|
112
|
+
#
|
113
|
+
# @param [String] host
|
114
|
+
# the host to perform the action on
|
115
|
+
#
|
116
|
+
# @option options [Hash] :winrm
|
117
|
+
# * :user (String) a user that will login to each node and perform the bootstrap command on
|
118
|
+
# * :password (String) the password for the user that will perform the bootstrap (required)
|
119
|
+
# * :port (Fixnum) the winrm port to connect on the node the bootstrap will be performed on (5985)
|
120
|
+
#
|
121
|
+
# @return [HostConnector::Response]
|
122
|
+
def chef_client(host, options = {})
|
123
|
+
run(host, "chef-client", options)
|
33
124
|
end
|
34
125
|
|
35
|
-
#
|
126
|
+
# Write your encrypted data bag secret on a node
|
36
127
|
#
|
37
|
-
# @
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
128
|
+
# @param [String] host
|
129
|
+
# the host to perform the action on
|
130
|
+
# @param [String] secret
|
131
|
+
# your organization's encrypted data bag secret
|
132
|
+
#
|
133
|
+
# @option options [Hash] :winrm
|
134
|
+
# * :user (String) a user that will login to each node and perform the bootstrap command on
|
135
|
+
# * :password (String) the password for the user that will perform the bootstrap (required)
|
136
|
+
# * :port (Fixnum) the winrm port to connect on the node the bootstrap will be performed on (5985)
|
137
|
+
#
|
138
|
+
# @return [HostConnector::Response]
|
139
|
+
def put_secret(host, secret, options = {})
|
140
|
+
command = "echo #{secret} > C:\\chef\\encrypted_data_bag_secret"
|
141
|
+
run(host, command, options)
|
142
|
+
end
|
44
143
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
144
|
+
# Execute line(s) of Ruby code on a node using Chef's embedded Ruby
|
145
|
+
#
|
146
|
+
# @param [String] host
|
147
|
+
# the host to perform the action on
|
148
|
+
# @param [Array<String>] command_lines
|
149
|
+
# An Array of lines of the command to be executed
|
150
|
+
#
|
151
|
+
# @option options [Hash] :winrm
|
152
|
+
# * :user (String) a user that will login to each node and perform the bootstrap command on
|
153
|
+
# * :password (String) the password for the user that will perform the bootstrap (required)
|
154
|
+
# * :port (Fixnum) the winrm port to connect on the node the bootstrap will be performed on (5985)
|
155
|
+
#
|
156
|
+
# @return [HostConnector::Response]
|
157
|
+
def ruby_script(host, command_lines, options = {})
|
158
|
+
command = "#{EMBEDDED_RUBY_PATH} -e \"#{command_lines.join(';')}\""
|
159
|
+
run(host, command, options)
|
53
160
|
end
|
161
|
+
|
162
|
+
private
|
163
|
+
|
164
|
+
# @param [String] host
|
165
|
+
# @param [Integer] port
|
166
|
+
#
|
167
|
+
# @option options [String] :user
|
168
|
+
# @option options [String] :password
|
169
|
+
#
|
170
|
+
# @return [WinRM::WinRMWebService]
|
171
|
+
def winrm(host, port, options = {})
|
172
|
+
winrm_opts = { disable_sspi: true, basic_auth_only: true }
|
173
|
+
winrm_opts[:user] = options[:user]
|
174
|
+
winrm_opts[:pass] = options[:password]
|
175
|
+
client = ::WinRM::WinRMWebService.new("http://#{host}:#{port}/wsman", :plaintext, winrm_opts)
|
176
|
+
client.set_timeout(6000)
|
177
|
+
client
|
178
|
+
end
|
54
179
|
end
|
55
180
|
end
|
56
181
|
end
|