Class: Ridley::HostConnector::WinRM
- Defined in:
- lib/ridley/host_connector/winrm.rb,
lib/ridley/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
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.
-
#get_command(command, command_uploader) ⇒ String
Returns the command if it does not break the WinRM command length limit.
-
#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.
Methods included from Logging
Instance Method Details
#bootstrap(host, options = {}) ⇒ HostConnector::Response
Bootstrap a node
119 120 121 122 123 124 |
# File 'lib/ridley/host_connector/winrm.rb', line 119 def bootstrap(host, = {}) context = BootstrapContext::Windows.new() log.info "Bootstrapping host: #{host}" run(host, context.boot_command, ) end |
#chef_client(host, options = {}) ⇒ HostConnector::Response
Perform a chef client run on a node
137 138 139 |
# File 'lib/ridley/host_connector/winrm.rb', line 137 def chef_client(host, = {}) run(host, "chef-client", ) end |
#get_command(command, command_uploader) ⇒ String
Returns the command if it does not break the WinRM command length limit. Otherwise, we return an execution of the command as a batch file.
97 98 99 100 101 102 103 104 105 106 |
# File 'lib/ridley/host_connector/winrm.rb', line 97 def get_command(command, command_uploader) if command.length < CommandUploader::CHUNK_LIMIT command else log.debug "Detected a command that was longer than #{CommandUploader::CHUNK_LIMIT} characters. " + "Uploading command as a file to the host." command_uploader.upload(command) command_uploader.command end end |
#put_secret(host, secret, options = {}) ⇒ HostConnector::Response
Write your encrypted data bag secret on a node
154 155 156 157 |
# File 'lib/ridley/host_connector/winrm.rb', line 154 def put_secret(host, 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
172 173 174 175 |
# File 'lib/ridley/host_connector/winrm.rb', line 172 def ruby_script(host, command_lines, = {}) command = "#{EMBEDDED_RUBY_PATH} -e \"#{command_lines.join(';')}\"" run(host, command, ) end |
#run(host, command, options = {}) ⇒ HostConnector::Response
Execute a shell command on a node
35 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 |
# File 'lib/ridley/host_connector/winrm.rb', line 35 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| command_uploaders << command_uploader = CommandUploader.new(connection) command = get_command(command, command_uploader) begin 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 = -1 response.stderr = ex. end case response.exit_code when 0 log.info "Successfully ran 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 => ex log.info "Error cleaning up leftover Powershell scripts on some hosts" end end |
#uninstall_chef(host, options = {}) ⇒ HostConnector::Response
Uninstall Chef from a node
192 193 194 195 196 |
# File 'lib/ridley/host_connector/winrm.rb', line 192 def uninstall_chef(host, = {}) [:session_type] = :powershell log.info "Uninstalling Chef from host: #{host}" run(host, CommandContext::WindowsUninstall.command(), ) end |