Narnach-simple_gate 0.5.2 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -50,6 +50,13 @@ connection.
50
50
 
51
51
  == Recent changes
52
52
 
53
+ === Version 0.5.3
54
+
55
+ * Added yardoc documentation to all classes.
56
+ * SimpleGate#through raises an error when no gates are chosen
57
+ * SimpleGate#through uses local variables instead of instance variables
58
+ * ServerDefinition#options is created on the fly
59
+
53
60
  === Version 0.5.2
54
61
 
55
62
  * Added -V verbose flag to gate_cp
@@ -1,25 +1,33 @@
1
1
  class Router
2
- # Graph of server connections.
3
- # It's a Hash of Arrays, which contains strings. Keys are server names with
4
- # a connection to other servers. Each of these servers is a string in the
5
- # associated Array.
6
- # An example graph with three servers 'foo', 'bar' and 'baz'.
2
+ # Graph of server connections.
3
+ attr_accessor :paths
4
+
5
+ # Create a new Router for a network of interconnected servers.
6
+ # An example connections graph with three servers 'foo', 'bar' and 'baz':
7
7
  #
8
8
  # router = Router.new
9
+ # # Define a graph: foo -> bar -> baz
9
10
  # router.paths = {
10
11
  # 'foo' => %w[bar],
11
- # 'bar' => ['baz']
12
+ # 'bar' => %w[baz]
12
13
  # }
13
14
  # router.find('foo', 'baz') #=> ['foo', 'bar', 'baz']
14
- attr_accessor :paths
15
-
15
+ # @param [Hash] paths Graph of server connections.
16
+ # It's a Hash of Arrays, which contains strings. Keys are server
17
+ # names with a connection to other servers. Each of these servers is a
18
+ # string in the associated Array.
16
19
  def initialize(paths={})
17
20
  @paths = paths
18
21
  end
19
22
 
20
- # A simple pathfinder. Returns a route as Array or nil.
23
+ # A simple recursive pathfinder.
21
24
  # Uses a very naieve depth-first recursive full-graph search to
22
25
  # find the shortest route.
26
+ # @param [String] start The node to start searching from for +target+.
27
+ # @param [String] target The node to look for. Once it is found, return the shortest route to it.
28
+ # @param [Array] current_route Internal variable that holds the route so far. Helps in preventing cyclic routes from being checked an infinite amount of times.
29
+ # @return [Array] The sequence of nodes that connect +start+ to +target+.
30
+ # @return [nil] When no route was found.
23
31
  def find(start, target, current_route = [])
24
32
  return [target] if start == target
25
33
  return nil unless paths.has_key?(start)
@@ -1,57 +1,72 @@
1
1
  require 'yaml'
2
2
  class ServerDefinition
3
- attr_accessor :host, :user, :options, :port, :password
4
-
3
+ attr_accessor :host, :user, :port, :password, :auth_methods
4
+
5
+ # Create a new ServerDefinition.
6
+ #
7
+ # @param [String] host Name of server.
8
+ # @param [Hash] options Override the server's own configuration.
9
+ # @option options [Integer] port (22) Server port
10
+ # @option options [String] user SSH user
11
+ # @option options [String] password SSH password
5
12
  def initialize(host, options = {})
6
- @options = {:port => 22}.merge(options)
7
13
  self.host = host
8
- self.user = @options[:user]
9
- self.password = @options[:password]
10
- self.port = @options[:port]
11
- end
12
-
13
- def user=(user)
14
- options[:user] = user
15
- @user=user
16
- end
17
-
18
- def port=(port)
19
- options[:port] = port
20
- @port=port
14
+ self.user = options[:user]
15
+ self.password = options[:password]
16
+ self.port = options[:port] || 22
17
+ self.auth_methods = options[:auth_methods] || %w[password keyboard-interactive]
21
18
  end
22
19
 
23
- def password=(password)
24
- options[:password] = password
25
- @password=password
20
+ # SSH options
21
+ # @return [Hash]
22
+ def options
23
+ {
24
+ :user => user,
25
+ :password => password,
26
+ :port => port,
27
+ :auth_methods => auth_methods
28
+ }
26
29
  end
27
30
 
31
+ # Yield connection information.
32
+ # @yieldparam [String] host SSH host
33
+ # @yieldparam [String] user SSH user
34
+ # @yieldparam [Hash] options SSH connection options
35
+ # @see ServerDefinition#initialize
36
+ # @see ServerDefinition#ssh_options
28
37
  def connection_info(&block)
29
- block.call(host, user, options.merge(ssh_options))
38
+ block.call(host, user, options)
30
39
  end
31
-
32
- def ssh_options
33
- {
34
- :auth_methods => %w[password keyboard-interactive]
35
- }
36
- end
37
-
40
+
41
+ # Represent server definition as URL-like string
42
+ # @return [String]
38
43
  def to_s
39
44
  "#{user}:#{'*' * password.to_s.size}@#{host}:#{port}"
40
45
  end
41
-
46
+
47
+ # Factory method that uses pre-defined server configurations.
48
+ # @return [ServerDefinition]
42
49
  def self.lookup(server)
43
50
  server = servers[server]
44
- new(server['address'],{
51
+ new(server['address'],{
45
52
  :user => server['username'],
46
- :password => server['password'],
53
+ :password => server['password'],
47
54
  :port => server['port']
48
55
  })
49
56
  end
50
-
57
+
58
+ # Factory method that chooses between a lookup and parse.
59
+ # @param [String] server Server name or ssh string
60
+ # @return [ServerDefinition]
61
+ # @see ServerDefinition.lookup
62
+ # @see ServerDefinition.parse
51
63
  def self.find(server)
52
64
  servers.has_key?(server) ? lookup(server) : parse(server)
53
65
  end
54
-
66
+
67
+ # Factory method that parses a connection string.
68
+ # @param [String] ssh_string String formatted as "user:password@host:port"
69
+ # @return [ServerDefinition]
55
70
  def self.parse(ssh_string)
56
71
  user, password, host, port = ssh_string.match /\A(.*?):(.*?)@(.*?):(\d*?)\Z/
57
72
  new(host, :user => user, :password => password, :port => port)
@@ -76,6 +91,7 @@ class ServerDefinition
76
91
  #
77
92
  # Since the parsed Hash of servers is cached, a value can be stored and
78
93
  # the configuration file ignored if desired.
94
+ # @return [Hash] Server name to server configuration pairs.
79
95
  def servers
80
96
  @servers ||= YAML.load_file(File.expand_path('~/.servers.yml'))
81
97
  end
data/lib/simple_gate.rb CHANGED
@@ -5,19 +5,26 @@ require 'activesupport'
5
5
  require 'simple_gate/server_definition'
6
6
 
7
7
  class SimpleGate
8
+ # Initialize a new SimpleGate
9
+ # @param [Hash] options Hash with options to configure SimpleGate. Defaults to set :verbose to false.
8
10
  def initialize(options={})
9
11
  @options = {
10
12
  :verbose => false
11
13
  }.merge(options)
12
14
  end
13
15
 
16
+ # Is the verbose option turned on?
14
17
  def verbose?
15
18
  @options[:verbose]
16
19
  end
17
20
 
18
- # Connect through a list of gateways to the real server.
19
- # Treats the last 'gateway' as the real server and the others as gateways.
20
- def through_to(*gateways) # :yields: ssh session
21
+ # Connect through a list of gateways to a target server.
22
+ # Treats the last 'gateway' as the target server and the others as gateways.
23
+ #
24
+ # @param [Array] *gateways A list of gateway server names that can be found using ServerDefinition.find(). Should have at least one server name.
25
+ # @yieldparam [Net::SSH::Connection::Session] session SSH Session to the target server.
26
+ # @raise [ArgumentError] When no gateways are chosen.
27
+ def through_to(*gateways)
21
28
  gateways = gateways.flatten
22
29
  raise ArgumentError.new("No target chosen") if gateways.size == 0
23
30
  target = ServerDefinition.find(gateways.pop)
@@ -39,19 +46,27 @@ class SimpleGate
39
46
  nil
40
47
  end
41
48
 
49
+ # Establish a series of gateways and yields the last one created.
50
+ # Will automatically shut down gateway connections when the block closes.
51
+ #
42
52
  # Most of the code was taken from Capistrano and then changed to work
43
53
  # outside of Capistrano.
54
+ #
55
+ # @param [Array] *gateways A list of gateway server names that can be found using ServerDefinition.find(). Should have at least one server name.
56
+ # @yieldparam [Net::SSH::Gateway] gateway Gateway object of the last tunnel endpoint.
57
+ # @raise [ArgumentError] When no gateways are chosen.
44
58
  def through(*gateways)
45
59
  Thread.abort_on_exception = true
46
- @open_connections ||= []
47
- @gateways = gateways.flatten.collect { |g| ServerDefinition.find(g) }
48
- tunnel = @gateways[0].connection_info do |host, user, connect_options|
49
- STDERR.puts "Setting up tunnel #{@gateways[0]}" if verbose?
60
+ open_connections = []
61
+ gateways = gateways.flatten.collect { |g| ServerDefinition.find(g) }
62
+ raise ArgumentError.new("No target chosen") if gateways.size == 0
63
+ tunnel = gateways[0].connection_info do |host, user, connect_options|
64
+ STDERR.puts "Setting up tunnel #{gateways[0]}" if verbose?
50
65
  gw = Net::SSH::Gateway.new(host, user, connect_options)
51
- @open_connections << gw
66
+ open_connections << gw
52
67
  gw
53
68
  end
54
- @gateway = (@gateways[1..-1]).inject(tunnel) do |tunnel, destination|
69
+ gateway = (gateways[1..-1]).inject(tunnel) do |tunnel, destination|
55
70
  STDERR.puts "Connecting to #{destination}" if verbose?
56
71
  tunnel_port = tunnel.open(destination.host, (destination.port || 22))
57
72
  localhost_options = {:user => destination.user, :port => tunnel_port, :password => destination.password}
@@ -59,13 +74,13 @@ class SimpleGate
59
74
  local_host.connection_info do |host, user, connect_options|
60
75
  STDERR.puts "Connecting using local info #{local_host}" if verbose?
61
76
  gw = Net::SSH::Gateway.new(host, user, connect_options)
62
- @open_connections << gw
77
+ open_connections << gw
63
78
  gw
64
79
  end
65
80
  end
66
- yield(@gateway)
81
+ yield(gateway)
67
82
  ensure
68
- while g = @open_connections.pop
83
+ while g = open_connections.pop
69
84
  g.shutdown!
70
85
  end
71
86
  end
data/simple_gate.gemspec CHANGED
@@ -3,8 +3,8 @@ Gem::Specification.new do |s|
3
3
  s.name = 'simple_gate'
4
4
  s.summary = "SimpleGate makes it possible to use net/ssh/gateway's capabilities in a simple to use way."
5
5
  s.description = s.summary
6
- s.version = '0.5.2'
7
- s.date = '2009-04-18'
6
+ s.version = '0.5.3'
7
+ s.date = '2009-05-16'
8
8
  s.platform = Gem::Platform::RUBY
9
9
  s.authors = ["Wes Oldenbeuving"]
10
10
  s.email = "narnach@gmail.com"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: Narnach-simple_gate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wes Oldenbeuving
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-04-18 00:00:00 -07:00
12
+ date: 2009-05-16 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15