Class: Bcome::Ssh::ConnectionHandler

Inherits:
Object
  • Object
show all
Defined in:
lib/objects/ssh/connection_handler.rb

Constant Summary collapse

MAX_CONNECTION_ATTEMPTS =
3

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(node, config = {}) ⇒ ConnectionHandler

Returns a new instance of ConnectionHandler.



12
13
14
15
16
17
18
# File 'lib/objects/ssh/connection_handler.rb', line 12

def initialize(node, config = {})
  @node = node
  @config = config
  @servers_to_connect = machines.dup
  @connection_exceptions = {}
  reset_progress if show_progress?
end

Class Method Details

.connect(node, config = {}) ⇒ Object



6
7
8
9
# File 'lib/objects/ssh/connection_handler.rb', line 6

def connect(node, config = {})
  handler = new(node, config)
  handler.connect
end

Instance Method Details

#connectObject



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
# File 'lib/objects/ssh/connection_handler.rb', line 40

def connect
  connection_attempt = 0
  ::Bcome::ProgressBar.instance.indicate(progress_bar_config, true) if show_progress?

  # So here we have a bit of a hack: If you're connecting to a network via a bastion host, it may not be able to handle over a certain amount of consecutive/parallelized ssh connection attempts
  # from bcome, so, we'll sweep up failures and re-try to connect up to MAX_CONNECTION_ATTEMPTS.  Once connected, we're generally good - and any subsequent connection failures
  # within a specific session will be handled ad-hoc and re-connection is automatic.
  while @servers_to_connect.any? && connection_attempt <= MAX_CONNECTION_ATTEMPTS
    puts "Retrying failed connections\n".warning if connection_attempt > 1
    do_connect
    connection_attempt += 1
  end

  if show_progress?
    ::Bcome::ProgressBar.instance.indicate(progress_bar_config, false)
    reset_progress
  end

  if ping?
    # If any machines remain, then we couldn't connect to them
    @servers_to_connect.each do |server|
      ping_result = {
        success: false,
        error: last_connection_exception_for(server)
      }
      puts server.print_ping_result(ping_result)
    end
  end

  if @servers_to_connect.any?
    puts "Failed to connect to #{@servers_to_connect.size} nodes".error
  else
    puts 'All nodes reachable   '.success
  end
end

#do_connectObject



80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/objects/ssh/connection_handler.rb', line 80

def do_connect
  @servers_to_connect.pmap do |server|
    begin
      server.open_ssh_connection unless server.has_ssh_connection?
      Bcome::ProgressBar.instance.indicate_and_increment!(progress_bar_config, true) if show_progress?
      @servers_to_connect -= [server]
      puts server.print_ping_result if ping?
    rescue Exception => e
      @connection_exceptions[server] = e
    end
  end
end

#last_connection_exception_for(server) ⇒ Object



76
77
78
# File 'lib/objects/ssh/connection_handler.rb', line 76

def last_connection_exception_for(server)
  @connection_exceptions[server]
end

#machinesObject



20
21
22
# File 'lib/objects/ssh/connection_handler.rb', line 20

def machines
  @node.server? ? [@node] : @node.machines
end

#pingObject



36
37
38
# File 'lib/objects/ssh/connection_handler.rb', line 36

def ping
  connect
end

#ping?Boolean

Returns:

  • (Boolean)


28
29
30
# File 'lib/objects/ssh/connection_handler.rb', line 28

def ping?
  @config[:is_ping] ? true : false
end

#progress_bar_configObject



93
94
95
96
97
98
99
# File 'lib/objects/ssh/connection_handler.rb', line 93

def progress_bar_config
  {
    prefix: "\sOpening SSH connections\s",
    indice: '...',
    indice_descriptor: "of #{machines.size}"
  }
end

#reset_progressObject



32
33
34
# File 'lib/objects/ssh/connection_handler.rb', line 32

def reset_progress
  ::Bcome::ProgressBar.instance.reset!
end

#show_progress?Boolean

Returns:

  • (Boolean)


24
25
26
# File 'lib/objects/ssh/connection_handler.rb', line 24

def show_progress?
  @config[:show_progress] ? true : false
end