module Canals

a gem for managing ssh tunnel connections

Constants

CanalOptionError
VERSION

Canals gem current version

Attributes

logger[RW]

Public Class Methods

create_tunnel(tunnel_opts) click to toggle source
# File lib/canals/core.rb, line 10
def create_tunnel(tunnel_opts)
  Canals.repository.add tunnel_opts
end
isalive?(tunnel_opts) click to toggle source
# File lib/canals/core.rb, line 44
def isalive?(tunnel_opts)
  if tunnel_opts.instance_of? String
    if (Canals.repository.has?(tunnel_opts))
      tunnel_opts = Canals.repository.get(tunnel_opts)
    else
      tunnel_opts = Canals.session.get_obj(tunnel_opts)
    end
  end
  !!tunnel_pid(tunnel_opts)
end
restart(tunnel_opts) click to toggle source
# File lib/canals/core.rb, line 39
def restart(tunnel_opts)
  stop(tunnel_opts)
  start(tunnel_opts)
end
start(tunnel_opts) click to toggle source
# File lib/canals/core.rb, line 14
def start(tunnel_opts)
  if tunnel_opts.instance_of? String
    tunnel_opts = Canals.repository.get(tunnel_opts)
  end
  exit_code = tunnel_start(tunnel_opts)
  raise Canals::Exception, "could not start tunnel" unless exit_code.success?
  pid = tunnel_pid(tunnel_opts)
  session_data = {name: tunnel_opts.name, pid: pid, socket: socket_file(tunnel_opts)}
  session_data = tunnel_opts.to_hash(:full).merge(session_data) if tunnel_opts.adhoc
  Canals.session.add(session_data)
  pid.to_i
end
stop(tunnel_opts, remove_from_session: true) click to toggle source
# File lib/canals/core.rb, line 27
def stop(tunnel_opts, remove_from_session: true)
  if tunnel_opts.instance_of? String
    if (Canals.repository.has?(tunnel_opts))
      tunnel_opts = Canals.repository.get(tunnel_opts)
    else
      tunnel_opts = Canals.session.get_obj(tunnel_opts)
    end
  end
  tunnel_close(tunnel_opts)
  Canals.session.del(tunnel_opts.name) if remove_from_session
end

Private Class Methods

socket_file(tunnel_opts) click to toggle source
# File lib/canals/core.rb, line 57
def socket_file(tunnel_opts)
  "/tmp/canals/canal.#{tunnel_opts.name}.sock"
end
tunnel_check(tunnel_opts) click to toggle source
# File lib/canals/core.rb, line 72
def tunnel_check(tunnel_opts)
  cmd = "ssh -S #{socket_file(tunnel_opts)} -O check #{tunnel_opts.proxy}"
  Open3.capture2e(cmd)
end
tunnel_close(tunnel_opts) click to toggle source
# File lib/canals/core.rb, line 77
def tunnel_close(tunnel_opts)
  cmd = "ssh -S #{socket_file(tunnel_opts)} -O exit #{tunnel_opts.proxy}"
  Open3.capture2e(cmd)
end
tunnel_pid(tunnel_opts) click to toggle source
# File lib/canals/core.rb, line 82
def tunnel_pid(tunnel_opts)
  stdout, _ = tunnel_check(tunnel_opts)
  m = /\(pid=(.*)\)/.match(stdout)
  m[1].to_i if m
end
tunnel_start(tunnel_opts) click to toggle source
# File lib/canals/core.rb, line 61
def tunnel_start(tunnel_opts)
  FileUtils.mkdir_p("/tmp/canals")
  if (tunnel_opts.socks)
    cmd = "ssh -M -S #{socket_file(tunnel_opts)} -o 'ExitOnForwardFailure=yes' -fnNT -D \"#{tunnel_opts.bind_address}:#{tunnel_opts.local_port}\" #{tunnel_opts.proxy}"
  else
    cmd = "ssh -M -S #{socket_file(tunnel_opts)} -o 'ExitOnForwardFailure=yes' -fnNT -L #{tunnel_opts.bind_address}:#{tunnel_opts.local_port}:#{tunnel_opts.remote_host}:#{tunnel_opts.remote_port} #{tunnel_opts.proxy}"
  end
  system(cmd)
  $?
end

Public Instance Methods

config() click to toggle source
# File lib/canals.rb, line 16
def config
  return @config if defined?(@config)
  @config = Config.new(File.join(Dir.home, '.canals'))
end
environments() click to toggle source
# File lib/canals.rb, line 26
def environments
  return @repository.environments if defined?(@repository)
  @repository = Repository.new
  @repository.environments
end
repository() click to toggle source
# File lib/canals.rb, line 21
def repository
  return @repository if defined?(@repository)
  @repository = Repository.new
end
session() click to toggle source
# File lib/canals.rb, line 32
def session
  return @session if defined?(@session)
  @session = Session.new
end