Class: Ridley::HostConnector::WinRM
- Defined in:
- lib/ridley-connectors/host_connector/winrm.rb,
lib/ridley-connectors/host_connector/winrm/command_uploader.rb
Defined Under Namespace
Classes: CommandUploader
Constant Summary collapse
- DEFAULT_PORT =
5985
- EMBEDDED_RUBY_PATH =
'C:\opscode\chef\embedded\bin\ruby'.freeze
- SESSION_TYPE_COMMAND_METHODS =
{ powershell: :run_powershell_script, cmd: :run_cmd }.freeze
Constants inherited from Base
Base::CONNECTOR_PORT_ERRORS, Base::PORT_CHECK_TIMEOUT, Base::RETRY_COUNT
Instance Method Summary collapse
-
#bootstrap(host, options = {}) ⇒ HostConnector::Response
Bootstrap a node.
-
#chef_client(host, options = {}) ⇒ HostConnector::Response
Perform a chef client run on a node.
-
#connector_port_open?(host, options = {}) ⇒ Boolean
Checks to see if the given port is open for TCP connections on the given host.
-
#put_secret(host, secret, options = {}) ⇒ HostConnector::Response
Write your encrypted data bag secret on a node.
-
#ruby_script(host, command_lines, options = {}) ⇒ HostConnector::Response
Execute line(s) of Ruby code on a node using Chef’s embedded Ruby.
-
#run(host, command, options = {}) ⇒ HostConnector::Response
Execute a shell command on a node.
-
#uninstall_chef(host, options = {}) ⇒ HostConnector::Response
Uninstall Chef from a node.
- #update_omnibus(host, options = {}) ⇒ Object
Methods inherited from Base
Instance Method Details
#bootstrap(host, options = {}) ⇒ HostConnector::Response
Bootstrap a node
122 123 124 125 126 127 128 |
# File 'lib/ridley-connectors/host_connector/winrm.rb', line 122 def bootstrap(host, = {}) context = BootstrapContext::Windows.new() log.info "Bootstrapping host: #{host}" log.filter_param(context.boot_command) run(host, context.boot_command, ) end |
#chef_client(host, options = {}) ⇒ HostConnector::Response
Perform a chef client run on a node
141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/ridley-connectors/host_connector/winrm.rb', line 141 def chef_client(host, = {}) log_level = case log.level when 0 "debug" when 1 "info" when 2 "warn" else "info" end run(host, "chef-client -l #{log_level}", ) end |
#connector_port_open?(host, options = {}) ⇒ Boolean
Checks to see if the given port is open for TCP connections on the given host.
231 232 233 234 235 236 |
# File 'lib/ridley-connectors/host_connector/winrm.rb', line 231 def connector_port_open?(host, = {}) [:winrm] ||= Hash.new [:winrm][:port] ||= HostConnector::WinRM::DEFAULT_PORT port_open?(host, [:winrm][:port], [:retries]) end |
#put_secret(host, secret, options = {}) ⇒ HostConnector::Response
Write your encrypted data bag secret on a node
168 169 170 171 172 |
# File 'lib/ridley-connectors/host_connector/winrm.rb', line 168 def put_secret(host, secret, = {}) log.filter_param(secret) command = "echo #{secret} > C:\\chef\\encrypted_data_bag_secret" run(host, command, ) end |
#ruby_script(host, command_lines, options = {}) ⇒ HostConnector::Response
Execute line(s) of Ruby code on a node using Chef’s embedded Ruby. This will always run via a batch file due to WinRM having difficulty handling long ruby scripts being passed via ruby -e.
190 191 192 193 |
# File 'lib/ridley-connectors/host_connector/winrm.rb', line 190 def ruby_script(host, command_lines, = {}) command = "#{EMBEDDED_RUBY_PATH} -e \"#{command_lines.join(';')}\"" run(host, command, .merge(force_batch_file: true)) end |
#run(host, command, options = {}) ⇒ HostConnector::Response
Execute a shell command on a node
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/ridley-connectors/host_connector/winrm.rb', line 36 def run(host, command, = {}) = .reverse_merge(winrm: Hash.new, session_type: :cmd) [:winrm].reverse_merge!(port: DEFAULT_PORT) command_uploaders = Array.new user = [:winrm][:user] password = [:winrm][:password] port = [:winrm][:port] connection = winrm(host, port, [:winrm].slice(:user, :password)) unless command_method = SESSION_TYPE_COMMAND_METHODS[[:session_type]] raise RuntimeError, "unknown session type: #{[:session_type]}. Known session types " + "are: #{SESSION_TYPE_COMMAND_METHODS.keys}" end HostConnector::Response.new(host).tap do |response| begin if [:force_batch_file] || command.length > CommandUploader::CHUNK_LIMIT log.debug "Detected a command that was longer than #{CommandUploader::CHUNK_LIMIT} characters. " + "Uploading command as a file to the host." command_uploaders << command_uploader = CommandUploader.new(connection) command_uploader.upload(command) command = command_uploader.command end log.info "Running WinRM command: '#{command}' on: '#{host}' as: '#{user}'" defer { output = connection.send(command_method, command) do |stdout, stderr| if stdout && stdout.present? response.stdout += stdout log.info "[#{host}](WinRM) #{stdout}" end if stderr && stderr.present? response.stderr += stderr log.info "[#{host}](WinRM) #{stderr}" end end response.exit_code = output[:exitcode] } rescue ::WinRM::WinRMHTTPTransportError => ex response.exit_code = :transport_error response.stderr = ex. rescue SocketError, Errno::EHOSTUNREACH response.exit_code = -1 response.stderr = "Host unreachable" rescue Errno::ECONNREFUSED response.exit_code = -1 response.stderr = "Connection refused" rescue => ex response.exit_code = -1 response.stderr = "An unknown error occurred: #{ex.class} - #{ex.}" end case response.exit_code when 0 log.info "Successfully ran WinRM command on: '#{host}' as: '#{user}'" when :transport_error log.info "A transport error occured while attempting to run a WinRM command on: '#{host}' as: '#{user}'" when -1 log.info "Failed to run WinRM command on: '#{host}' as: '#{user}'" else log.info "Successfully ran WinRM command on: '#{host}' as: '#{user}', but it failed" end end ensure begin command_uploaders.map(&:cleanup) rescue ::WinRM::WinRMHTTPTransportError, SocketError, Errno::EHOSTUNREACH, Errno::ECONNREFUSED => ex log.info "Error cleaning up leftover Powershell scripts on some hosts due to: " + "#{ex.class} - #{ex.}" end end |
#uninstall_chef(host, options = {}) ⇒ HostConnector::Response
Uninstall Chef from a node
210 211 212 213 214 |
# File 'lib/ridley-connectors/host_connector/winrm.rb', line 210 def uninstall_chef(host, = {}) [:session_type] = :powershell log.info "Uninstalling Chef from host: #{host}" run(host, CommandContext::WindowsUninstall.command(), ) end |
#update_omnibus(host, options = {}) ⇒ Object
216 217 218 219 |
# File 'lib/ridley-connectors/host_connector/winrm.rb', line 216 def update_omnibus(host, = {}) log.info "Updating Omnibus installation on host: #{host}" run(host, CommandContext::WindowsUpdateOmnibus.command(), ) end |