class Opsicle::SSH

Attributes

client[R]

Public Class Methods

new(environment) click to toggle source
# File lib/opsicle/commands/ssh.rb, line 7
def initialize(environment)
  @client = Client.new(environment)
  @stack = Opsicle::Stack.new(@client)
  @user_profile = Opsicle::UserProfile.new(@client)
end

Public Instance Methods

bastion_ip() click to toggle source
# File lib/opsicle/commands/ssh.rb, line 45
def bastion_ip
  if client.config.opsworks_config[:bastion_layer_id]
    online_bastions = client.api_call(
      :describe_instances, {layer_id: client.config.opsworks_config[:bastion_layer_id] }
    )[:instances].select { |instance| instance[:status].to_s == 'online'}
    bastion_ip = online_bastions.sample[:public_ip]
    Output.say "Connecting via bastion with IP #{bastion_ip}"
    bastion_ip
  elsif client.config.opsworks_config[:bastion_hostname]
    bastion_hostname = client.config.opsworks_config[:bastion_hostname]
    Output.say "Connecting via bastion with hostname '#{bastion_hostname}'"
    bastion_hostname
  end
end
execute(options={}) click to toggle source
# File lib/opsicle/commands/ssh.rb, line 13
def execute(options={})

  if instances.length == 1
    choice = 1
  else
    Output.say "Choose an Opsworks instance:"
    instances.each_with_index do |instance, index|
      Output.say "#{index+1}) #{instance[:hostname]} #{instance_info(instance)}"
    end
    choice = Output.ask("? ", Integer) { |q| q.in = 1..instances.length }
  end

  command = ssh_command(instances[choice-1], options)

  Output.say_verbose "Executing shell command: #{command}"
  system(command)
end
instance_info(instance) click to toggle source
# File lib/opsicle/commands/ssh.rb, line 91
def instance_info(instance)
  infos = []
  infos << instance[:layer_ids].map{ |layer_id| @stack.layer_name(layer_id) } if instance[:layer_ids]
  infos << "EIP" if instance[:elastic_ip]
  "(#{infos.join(', ')})"
end
instances() click to toggle source
# File lib/opsicle/commands/ssh.rb, line 31
def instances
  @instances ||= client.api_call(:describe_instances, { stack_id: client.config.opsworks_config[:stack_id] })[:instances]
                       .select { |instance| instance[:status].to_s == 'online'}
                       .sort { |a,b| a[:hostname] <=> b[:hostname] }
end
public_ips() click to toggle source
# File lib/opsicle/commands/ssh.rb, line 37
def public_ips
  instances.map{|instance| instance[:elastic_ip] || instance[:public_ip] }.compact
end
ssh_command(instance, options={}) click to toggle source
# File lib/opsicle/commands/ssh.rb, line 73
def ssh_command(instance, options={})
  ssh_command = " \"#{options[:"ssh-cmd"].gsub(/'/){ %q(\') }}\"" if options[:"ssh-cmd"] #escape single quotes
  ssh_options = options[:"ssh-opts"] ? "#{options[:"ssh-opts"]} " : ""
  external_ip = public_ips.sample
  if use_bastion?
    external_ip = bastion_ip
    ssh_string = "#{ssh_username}@#{external_ip} ssh #{instance[:private_ip]}"
    ssh_options.concat('-A -t ')
  elsif instance_ip = ssh_ip(instance)
    ssh_string = "#{ssh_username}@#{instance_ip}"
  else
    ssh_string = "#{ssh_username}@#{external_ip} ssh #{instance[:private_ip]}"
    ssh_options.concat('-A -t ')
  end

  "ssh #{ssh_options}#{ssh_string}#{ssh_command}"
end
ssh_ip(instance) click to toggle source
# File lib/opsicle/commands/ssh.rb, line 64
def ssh_ip(instance)
  if client.config.opsworks_config[:internal_ssh_only]
    Output.say "This stack requires a private connection, only using internal IPs."
    instance[:private_ip]
  else
    instance[:elastic_ip] || instance[:public_ip]
  end
end
ssh_username() click to toggle source
# File lib/opsicle/commands/ssh.rb, line 41
def ssh_username
  @user_profile.ssh_username
end
use_bastion?() click to toggle source
# File lib/opsicle/commands/ssh.rb, line 60
def use_bastion?
  !!(client.config.opsworks_config[:bastion_layer_id] || client.config.opsworks_config[:bastion_hostname])
end