Class: Bcome::Ssh::Driver
- Inherits:
-
Object
- Object
- Bcome::Ssh::Driver
- Defined in:
- lib/objects/ssh/driver.rb
Constant Summary collapse
- DEFAULT_TIMEOUT_IN_SECONDS =
5
- PROXY_CONNECT_PREFIX =
'-o StrictHostKeyChecking=no -W %h:%p'.freeze
- PROXY_SSH_PREFIX =
'-o UserKnownHostsFile=/dev/null -o "ProxyCommand ssh -W %h:%p'.freeze
Instance Attribute Summary collapse
-
#bootstrap_settings ⇒ Object
readonly
Returns the value of attribute bootstrap_settings.
-
#config ⇒ Object
readonly
Returns the value of attribute config.
Instance Method Summary collapse
- #bastion_host_user ⇒ Object
- #bootstrap? ⇒ Boolean
- #bootstrap_proxy_connection_string ⇒ Object
- #bootstrap_rsync_command(local_path, remote_path) ⇒ Object
- #bootstrap_ssh_command ⇒ Object
- #close_ssh_connection ⇒ Object
- #do_ssh ⇒ Object
- #fallback_local_user ⇒ Object
- #get(remote_path, local_path) ⇒ Object
- #has_bootstrap_settings? ⇒ Boolean
- #has_open_ssh_con? ⇒ Boolean
- #has_proxy? ⇒ Boolean
-
#initialize(config, context_node) ⇒ Driver
constructor
A new instance of Driver.
- #local_port_forward(start_port, end_port) ⇒ Object
- #net_ssh_params(verbose = false) ⇒ Object
- #node_host_or_ip ⇒ Object
- #ping ⇒ Object
- #pretty_config_details ⇒ Object
- #proxy ⇒ Object
- #proxy_connection_string ⇒ Object
- #put(local_path, remote_path) ⇒ Object
- #rsync(local_path, remote_path) ⇒ Object
- #rsync_command(local_path, remote_path) ⇒ Object
- #scp ⇒ Object
- #ssh_command ⇒ Object
- #ssh_connect!(_verbose = false) ⇒ Object
- #ssh_connection(_bootstrap = false) ⇒ Object
- #ssh_keys ⇒ Object
- #timeout_in_seconds ⇒ Object
- #user ⇒ Object
Constructor Details
#initialize(config, context_node) ⇒ Driver
Returns a new instance of Driver.
9 10 11 12 13 14 |
# File 'lib/objects/ssh/driver.rb', line 9 def initialize(config, context_node) @config = config @context_node = context_node @proxy_data = @config[:proxy] ? ::Bcome::Ssh::ProxyData.new(@config[:proxy], @context_node) : nil @bootstrap_settings = @config[:bootstrap_settings] ? ::Bcome::Ssh::Bootstrap.new(@config[:bootstrap_settings]) : nil end |
Instance Attribute Details
#bootstrap_settings ⇒ Object (readonly)
Returns the value of attribute bootstrap_settings.
3 4 5 |
# File 'lib/objects/ssh/driver.rb', line 3 def bootstrap_settings @bootstrap_settings end |
#config ⇒ Object (readonly)
Returns the value of attribute config.
3 4 5 |
# File 'lib/objects/ssh/driver.rb', line 3 def config @config end |
Instance Method Details
#bastion_host_user ⇒ Object
69 70 71 |
# File 'lib/objects/ssh/driver.rb', line 69 def bastion_host_user bootstrap? && @bootstrap_settings.bastion_host_user ? @bootstrap_settings.bastion_host_user : @proxy_data.bastion_host_user ? @proxy_data.bastion_host_user : user end |
#bootstrap? ⇒ Boolean
16 17 18 |
# File 'lib/objects/ssh/driver.rb', line 16 def bootstrap? @context_node.bootstrap? && has_bootstrap_settings? end |
#bootstrap_proxy_connection_string ⇒ Object
60 61 62 |
# File 'lib/objects/ssh/driver.rb', line 60 def bootstrap_proxy_connection_string "ssh -i #{@bootstrap_settings.ssh_key_path} -o StrictHostKeyChecking=no -W %h:%p #{@bootstrap_settings.bastion_host_user}@#{@proxy_data.host}" end |
#bootstrap_rsync_command(local_path, remote_path) ⇒ Object
155 156 157 158 159 160 161 |
# File 'lib/objects/ssh/driver.rb', line 155 def bootstrap_rsync_command(local_path, remote_path) if has_proxy? "rsync -av -e \"ssh -i #{@bootstrap_settings.ssh_key_path} -A #{bastion_host_user}@#{@proxy_data.host} ssh -o StrictHostKeyChecking=no\" #{local_path} #{user}@#{@context_node.internal_ip_address}:#{remote_path}" else "rsync -i #{@bootstrap_settings.ssh_key_path} -av #{local_path} #{user}@#{@context_node.public_ip_address}:#{remote_path}" end end |
#bootstrap_ssh_command ⇒ Object
103 104 105 106 107 108 109 |
# File 'lib/objects/ssh/driver.rb', line 103 def bootstrap_ssh_command if has_proxy? "ssh -i #{@bootstrap_settings.ssh_key_path} -t #{bastion_host_user}@#{@proxy_data.host} ssh -t #{user}@#{@context_node.internal_ip_address}" else "ssh -i #{@bootstrap_settings.ssh_key_path} #{user}@#{@context_node.public_ip_address}" end end |
#close_ssh_connection ⇒ Object
211 212 213 214 215 |
# File 'lib/objects/ssh/driver.rb', line 211 def close_ssh_connection return unless @connection @connection.close unless @connection.closed? @connection = nil end |
#do_ssh ⇒ Object
64 65 66 67 |
# File 'lib/objects/ssh/driver.rb', line 64 def do_ssh cmd = ssh_command @context_node.execute_local(cmd) end |
#fallback_local_user ⇒ Object
115 116 117 |
# File 'lib/objects/ssh/driver.rb', line 115 def fallback_local_user @fallback_local_user ||= ::Bcome::System::Local.instance.local_user end |
#get(remote_path, local_path) ⇒ Object
198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/objects/ssh/driver.rb', line 198 def get(remote_path, local_path) raise Bcome::Exception::MissingParamsForScp, "'get' requires a local_path and a remote_path" if local_path.to_s.empty? || remote_path.to_s.empty? puts "\n(#{@context_node.namespace})\s".namespace + "Downloading #{remote_path} to #{local_path}\n".informational begin scp.download!(remote_path, local_path, recursive: true) do |_ch, name, sent, total| puts "#{name}: #{sent}/#{total}".progress end rescue Exception => e # scp just throws generic exceptions :-/ puts e..error end end |
#has_bootstrap_settings? ⇒ Boolean
20 21 22 |
# File 'lib/objects/ssh/driver.rb', line 20 def has_bootstrap_settings? !@bootstrap_settings.nil? end |
#has_open_ssh_con? ⇒ Boolean
221 222 223 |
# File 'lib/objects/ssh/driver.rb', line 221 def has_open_ssh_con? !@connection.nil? && !@connection.closed? end |
#has_proxy? ⇒ Boolean
52 53 54 |
# File 'lib/objects/ssh/driver.rb', line 52 def has_proxy? !@config[:proxy].nil? end |
#local_port_forward(start_port, end_port) ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/objects/ssh/driver.rb', line 82 def local_port_forward(start_port, end_port) if has_proxy? if bootstrap? tunnel_command = "ssh -N -L #{start_port}:#{@context_node.internal_ip_address}:#{end_port} -i #{@bootstrap_settings.ssh_key_path} #{bastion_host_user}@#{@proxy_data.host}" else tunnel_command = "ssh -N -L #{start_port}:#{@context_node.internal_ip_address}:#{end_port} #{bastion_host_user}@#{@proxy_data.host}" end else if bootstrap? tunnel_command = "ssh -i #{@bootstrap_settings.ssh_key_path} -N -L #{start_port}:#{@context_node.public_ip_address}:#{end_port}" else tunnel_command = "ssh -N -L #{start_port}:#{@context_node.public_ip_address}:#{end_port}" end end tunnel = ::Bcome::Ssh::Tunnel::LocalPortForward.new(tunnel_command) tunnel.open! return tunnel end |
#net_ssh_params(verbose = false) ⇒ Object
123 124 125 126 127 128 129 130 |
# File 'lib/objects/ssh/driver.rb', line 123 def net_ssh_params(verbose = false) raise Bcome::Exception::InvalidSshConfig, "Missing ssh keys for #{@context_node.namespace}" unless ssh_keys params = { keys: ssh_keys, paranoid: false } params[:proxy] = proxy if has_proxy? params[:timeout] = timeout_in_seconds params[:verbose] = :debug if verbose params end |
#node_host_or_ip ⇒ Object
119 120 121 |
# File 'lib/objects/ssh/driver.rb', line 119 def node_host_or_ip has_proxy? ? @context_node.internal_ip_address : @context_node.public_ip_address end |
#ping ⇒ Object
173 174 175 176 177 178 |
# File 'lib/objects/ssh/driver.rb', line 173 def ping ssh_connect! return { success: true } rescue Exception => e return { success: false, error: e } end |
#pretty_config_details ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/objects/ssh/driver.rb', line 24 def pretty_config_details config = { user: user, ssh_keys: ssh_keys, timeout: timeout_in_seconds } if has_proxy? config[:host_or_ip] = @context_node.internal_ip_address config[:proxy] = { bastion_host: @proxy_data.host, bastion_host_user: bastion_host_user } else config[:host_or_ip] = @context_node.public_ip_address end config end |
#proxy ⇒ Object
46 47 48 49 50 |
# File 'lib/objects/ssh/driver.rb', line 46 def proxy return nil unless has_proxy? connection_string = bootstrap? ? bootstrap_proxy_connection_string : proxy_connection_string ::Net::SSH::Proxy::Command.new(connection_string) end |
#proxy_connection_string ⇒ Object
56 57 58 |
# File 'lib/objects/ssh/driver.rb', line 56 def proxy_connection_string "ssh #{PROXY_CONNECT_PREFIX} #{bastion_host_user}@#{@proxy_data.host}" end |
#put(local_path, remote_path) ⇒ Object
184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/objects/ssh/driver.rb', line 184 def put(local_path, remote_path) raise Bcome::Exception::MissingParamsForScp, "'put' requires a local_path and a remote_path" if local_path.to_s.empty? || remote_path.to_s.empty? puts "\n(#{@context_node.namespace})\s".namespace + "Uploading #{local_path} to #{remote_path}\n".informational begin scp.upload!(local_path, remote_path, recursive: true) do |_ch, name, sent, total| puts "#{name}: #{sent}/#{total}".progress end rescue Exception => e # scp just throws generic exceptions :-/ puts e..error end nil end |
#rsync(local_path, remote_path) ⇒ Object
140 141 142 143 144 |
# File 'lib/objects/ssh/driver.rb', line 140 def rsync(local_path, remote_path) raise Bcome::Exception::MissingParamsForRsync, "'rsync' requires a local_path and a remote_path" if local_path.to_s.empty? || remote_path.to_s.empty? command = rsync_command(local_path, remote_path) @context_node.execute_local(command) end |
#rsync_command(local_path, remote_path) ⇒ Object
146 147 148 149 150 151 152 153 |
# File 'lib/objects/ssh/driver.rb', line 146 def rsync_command(local_path, remote_path) return bootstrap_rsync_command(local_path, remote_path) if bootstrap? && @bootstrap_settings.ssh_key_path if has_proxy? "rsync -av -e \"ssh -A #{bastion_host_user}@#{@proxy_data.host} ssh -o StrictHostKeyChecking=no\" #{local_path} #{user}@#{@context_node.internal_ip_address}:#{remote_path}" else "rsync -av #{local_path} #{user}@#{@context_node.public_ip_address}:#{remote_path}" end end |
#scp ⇒ Object
180 181 182 |
# File 'lib/objects/ssh/driver.rb', line 180 def scp ssh_connection.scp end |
#ssh_command ⇒ Object
73 74 75 76 77 78 79 80 |
# File 'lib/objects/ssh/driver.rb', line 73 def ssh_command return bootstrap_ssh_command if bootstrap? && @bootstrap_settings.ssh_key_path if has_proxy? "ssh #{PROXY_SSH_PREFIX} #{bastion_host_user}@#{@proxy_data.host}\" #{user}@#{@context_node.internal_ip_address}" else "ssh #{user}@#{@context_node.public_ip_address}" end end |
#ssh_connect!(_verbose = false) ⇒ Object
163 164 165 166 167 168 169 170 171 |
# File 'lib/objects/ssh/driver.rb', line 163 def ssh_connect!(_verbose = false) @connection = nil begin @connection = ::Net::SSH.start(node_host_or_ip, user, net_ssh_params) rescue Net::SSH::Proxy::ConnectError, Net::SSH::ConnectionTimeout, Errno::EPIPE => e raise Bcome::Exception::CouldNotInitiateSshConnection, @context_node.namespace + "\s-\s#{e.}" end @connection end |
#ssh_connection(_bootstrap = false) ⇒ Object
217 218 219 |
# File 'lib/objects/ssh/driver.rb', line 217 def ssh_connection(_bootstrap = false) has_open_ssh_con? ? @connection : ssh_connect! end |
#ssh_keys ⇒ Object
132 133 134 135 136 137 138 |
# File 'lib/objects/ssh/driver.rb', line 132 def ssh_keys if bootstrap? [@bootstrap_settings.ssh_key_path] else @config[:ssh_keys] end end |
#timeout_in_seconds ⇒ Object
42 43 44 |
# File 'lib/objects/ssh/driver.rb', line 42 def timeout_in_seconds @config[:timeout_in_seconds] ||= Bcome::Ssh::Driver::DEFAULT_TIMEOUT_IN_SECONDS end |
#user ⇒ Object
111 112 113 |
# File 'lib/objects/ssh/driver.rb', line 111 def user bootstrap? && @bootstrap_settings.user ? @bootstrap_settings.user : @config[:user] ? @config[:user] : fallback_local_user end |