Narnach-simple_gate 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +107 -0
- data/Rakefile +29 -0
- data/bin/gate_cp +52 -0
- data/bin/simple_gate +61 -0
- data/lib/simple_gate/router.rb +42 -0
- data/lib/simple_gate/server_definition.rb +83 -0
- data/lib/simple_gate.rb +64 -0
- data/simple_gate.gemspec +34 -0
- data/spec/simple_gate_spec.rb +6 -0
- metadata +67 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Wes Oldenbeuving
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
= SimpleGate
|
2
|
+
|
3
|
+
SimpleGate makes it possible to use net/ssh/gateway's capabilities in a simple
|
4
|
+
to use way. This makes it possible to write simple scripts that access servers that are located several hops inside a network.
|
5
|
+
|
6
|
+
The core gateway chaining logic was taken from Capistrano, but it has been
|
7
|
+
rewritten to be useful in a more generic way than Capistrano allows.
|
8
|
+
|
9
|
+
SimpleGate's Router class makes it possible to automatically find a route
|
10
|
+
through a maze of servers instead of having to manually define gateway chains.
|
11
|
+
An added benefit is that a change to one server's connections no longer
|
12
|
+
requires you to update all other servers if they relied on it as a gateway.
|
13
|
+
|
14
|
+
SimpleGate is simple, meaning it does not (yet) do fancy things such as using
|
15
|
+
~/.ssh. Because of this, you'll have to define ~/.servers.yml and add entries
|
16
|
+
to configure your servers. To use the routing functionality used by the
|
17
|
+
gate_cp and simple_gate executables, you have to define routes in
|
18
|
+
~/.servers.connections.yml
|
19
|
+
|
20
|
+
An example configuration for the servers 'foobar' and 'barfoo' would look be:
|
21
|
+
|
22
|
+
---
|
23
|
+
foobar:
|
24
|
+
address: "127.0.0.1"
|
25
|
+
username: "foo"
|
26
|
+
password: "bar
|
27
|
+
port: 22
|
28
|
+
barfoo:
|
29
|
+
address: "192.168.0.1"
|
30
|
+
username: "bar"
|
31
|
+
password: "foo
|
32
|
+
port: 22
|
33
|
+
|
34
|
+
Example of a ~/.servers.connections.yml file:
|
35
|
+
|
36
|
+
---
|
37
|
+
local:
|
38
|
+
- foo
|
39
|
+
foo:
|
40
|
+
- bar
|
41
|
+
- baz
|
42
|
+
bar:
|
43
|
+
- foobar
|
44
|
+
- foobaz
|
45
|
+
- barbaz
|
46
|
+
|
47
|
+
All keys are names of servers defined in ~/.servers.yml. The only special node
|
48
|
+
is "local", which is the starting point for all connections and not a real
|
49
|
+
connection.
|
50
|
+
|
51
|
+
== Recent changes
|
52
|
+
|
53
|
+
=== Version 0.5.1
|
54
|
+
|
55
|
+
* Updated readme and simple_gate documentation
|
56
|
+
* Implemented infinite loop prevention code in Router#find
|
57
|
+
* Cleaned up Router#find to be more readable
|
58
|
+
* Added spec to show stack overflow occurs when a cyclical graph is used to
|
59
|
+
find a route
|
60
|
+
* Added specs for Router#find
|
61
|
+
* Added a -V (verbose) flag option to simple_gate
|
62
|
+
* Removed empty method definition
|
63
|
+
|
64
|
+
=== Version 0.5.0
|
65
|
+
|
66
|
+
* Added syntax explanation to gate_cp
|
67
|
+
* Added gate_cp, which copies one local file to a remote destination
|
68
|
+
|
69
|
+
=== Version 0.4.1
|
70
|
+
|
71
|
+
* simple_gate is now executable
|
72
|
+
|
73
|
+
=== Version 0.4.0
|
74
|
+
|
75
|
+
* Updated readme with version history for previous gem versions
|
76
|
+
* Added simple_gate executable to use SimpleGate's new Router class to find a path to a server and execute a command there.
|
77
|
+
|
78
|
+
=== Version 0.3.0
|
79
|
+
|
80
|
+
* Readme now has a project description and updated credits for a bit of Capistrano code
|
81
|
+
* Added mutator and documentation for ServerDefinition.servers
|
82
|
+
* Updated comment to make more sense
|
83
|
+
|
84
|
+
=== Version 0.2.0
|
85
|
+
|
86
|
+
* Implemented SimpleGate#through_to, which establishes a real ssh session through a number of gateways
|
87
|
+
|
88
|
+
=== Version 0.1.0
|
89
|
+
|
90
|
+
* Removed simple_gate executable
|
91
|
+
* Imported SimpleGate and ServerDefinition
|
92
|
+
|
93
|
+
=== Version 0.0.1
|
94
|
+
* Created project
|
95
|
+
|
96
|
+
== Installation
|
97
|
+
=== From git
|
98
|
+
From the project root, use rake to install.
|
99
|
+
git clone http://github.com/Narnach/simple_gate
|
100
|
+
cd simple_gate
|
101
|
+
rake install
|
102
|
+
This will build the gem and install it for you.
|
103
|
+
|
104
|
+
== About
|
105
|
+
simple_gate was created by Wes Oldenbeuving. It is licensed under the MIT license.
|
106
|
+
|
107
|
+
SimpleGate#through is based on GatewayConnectionFactory#initialize, which is part of Jamis Buck's Capistrano and is also licensed under the MIT license.
|
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require "rake"
|
2
|
+
require "rake/clean"
|
3
|
+
require "rake/gempackagetask"
|
4
|
+
require 'rubygems'
|
5
|
+
|
6
|
+
################################################################################
|
7
|
+
### Gem
|
8
|
+
################################################################################
|
9
|
+
|
10
|
+
begin
|
11
|
+
# Parse gemspec using the github safety level.
|
12
|
+
data = File.read('simple_gate.gemspec')
|
13
|
+
spec = nil
|
14
|
+
Thread.new { spec = eval("$SAFE = 3
|
15
|
+
%s" % data)}.join
|
16
|
+
|
17
|
+
# Create the gem tasks
|
18
|
+
Rake::GemPackageTask.new(spec) do |package|
|
19
|
+
package.gem_spec = spec
|
20
|
+
end
|
21
|
+
rescue Exception => e
|
22
|
+
printf "WARNING: Error caught (%s): %s
|
23
|
+
", e.class.name, e.message
|
24
|
+
end
|
25
|
+
|
26
|
+
desc 'Package and install the gem for the current version'
|
27
|
+
task :install => :gem do
|
28
|
+
system "sudo gem install -l pkg/%s-%s.gem" % [spec.name, spec.version]
|
29
|
+
end
|
data/bin/gate_cp
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Copy a single local file to a remote server.
|
3
|
+
# Syntax: gate_cp <server> <source_file> <target_file>
|
4
|
+
# server: a server listed in ~/.servers.yml and reachable by a
|
5
|
+
# series of connections described in ~/.servers.connections.yml
|
6
|
+
# source_file: filename or full path+filename of local source file
|
7
|
+
# target_file: filename or full path+filename of target file
|
8
|
+
#
|
9
|
+
# Example: gate_cp foobar ~/foo.txt foo.txt
|
10
|
+
# This copies ~/foo.txt too the server foobar as foo.txt in the home dir
|
11
|
+
#
|
12
|
+
# Example: gate_cp foobar foo.txt /tmp/bar.txt
|
13
|
+
# This copies the local file foo.txt too the server foobar as /tmp/foo.txt
|
14
|
+
require 'simple_gate'
|
15
|
+
require 'simple_gate/router'
|
16
|
+
require 'net/sftp'
|
17
|
+
|
18
|
+
connections = YAML.load_file(File.expand_path('~/.servers.connections.yml'))
|
19
|
+
from = 'local'
|
20
|
+
target = ARGV.shift.to_s.strip
|
21
|
+
|
22
|
+
cmd = ARGV.join(" ")
|
23
|
+
if cmd.strip.size == 0
|
24
|
+
puts "No command was given"
|
25
|
+
exit 1
|
26
|
+
end
|
27
|
+
|
28
|
+
router = Router.new(connections)
|
29
|
+
route = router.find(from, target)
|
30
|
+
if route.nil?
|
31
|
+
puts "No route to #{target}"
|
32
|
+
exit 1
|
33
|
+
end
|
34
|
+
|
35
|
+
route.shift if route.first == 'local'
|
36
|
+
|
37
|
+
if route.size==1
|
38
|
+
puts "No gateway needed to reach #{route.last}"
|
39
|
+
exit 2
|
40
|
+
end
|
41
|
+
|
42
|
+
source = File.expand_path(ARGV.shift.to_s.strip)
|
43
|
+
target = ARGV.shift.to_s.strip
|
44
|
+
|
45
|
+
puts "Connecting to #{route.last}, using #{route.size - 1} gateway(s)"
|
46
|
+
|
47
|
+
gate = SimpleGate.new
|
48
|
+
gate.through_to(route) do |ssh|
|
49
|
+
puts "Transferring: #{source} => #{target}"
|
50
|
+
ssh.sftp.upload!(source, target)
|
51
|
+
end
|
52
|
+
|
data/bin/simple_gate
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Syntax: simple_gate [-V] <server> <command>
|
3
|
+
# Finds a route to <server>, uses the neccesary gates to connect to it and
|
4
|
+
# executes <command> on that server. Set -V for verbose output.
|
5
|
+
#
|
6
|
+
# Uses ~/.servers.connections.yml and ~/.servers.yml to find the fastest path
|
7
|
+
# from the local server to a target server, establish a series of gateways
|
8
|
+
# and then execute a command on the remote server.
|
9
|
+
# Example of a ~/.servers.connections.yml file:
|
10
|
+
#
|
11
|
+
# ---
|
12
|
+
# local:
|
13
|
+
# - foo
|
14
|
+
# foo:
|
15
|
+
# - bar
|
16
|
+
# - baz
|
17
|
+
# bar:
|
18
|
+
# - foobar
|
19
|
+
# - foobaz
|
20
|
+
# - barbaz
|
21
|
+
#
|
22
|
+
# All keys are names of servers defined in ~/.servers.yml. The only special
|
23
|
+
# node is "local", which is the starting point for all connections and not a
|
24
|
+
# real connection.
|
25
|
+
|
26
|
+
require 'simple_gate'
|
27
|
+
require 'simple_gate/router'
|
28
|
+
|
29
|
+
verbose = !ARGV.delete('-V').nil?
|
30
|
+
|
31
|
+
connections = YAML.load_file(File.expand_path('~/.servers.connections.yml'))
|
32
|
+
from = 'local'
|
33
|
+
target = ARGV.shift.to_s.strip
|
34
|
+
|
35
|
+
cmd = ARGV.join(" ")
|
36
|
+
if cmd.strip.size == 0
|
37
|
+
puts "No command was given"
|
38
|
+
exit 1
|
39
|
+
end
|
40
|
+
|
41
|
+
router = Router.new(connections)
|
42
|
+
route = router.find(from, target)
|
43
|
+
if route.nil?
|
44
|
+
puts "No route to #{target}"
|
45
|
+
exit 1
|
46
|
+
end
|
47
|
+
|
48
|
+
route.shift if route.first == 'local'
|
49
|
+
|
50
|
+
if route.size==1
|
51
|
+
puts "No gateway needed to reach #{route.last}"
|
52
|
+
exit 2
|
53
|
+
end
|
54
|
+
|
55
|
+
puts "Executing '#{cmd}' in #{route.last}, using #{route.size - 1} gateway(s)" if verbose
|
56
|
+
|
57
|
+
gate = SimpleGate.new(:verbose=>verbose)
|
58
|
+
gate.through_to(route) do |ssh|
|
59
|
+
puts ssh.exec!(cmd)
|
60
|
+
end
|
61
|
+
|
@@ -0,0 +1,42 @@
|
|
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'.
|
7
|
+
#
|
8
|
+
# router = Router.new
|
9
|
+
# router.paths = {
|
10
|
+
# 'foo' => %w[bar],
|
11
|
+
# 'bar' => ['baz']
|
12
|
+
# }
|
13
|
+
# router.find('foo', 'baz') #=> ['foo', 'bar', 'baz']
|
14
|
+
attr_accessor :paths
|
15
|
+
|
16
|
+
def initialize(paths={})
|
17
|
+
@paths = paths
|
18
|
+
end
|
19
|
+
|
20
|
+
# A simple pathfinder. Returns a route as Array or nil.
|
21
|
+
# Uses a very naieve depth-first recursive full-graph search to
|
22
|
+
# find the shortest route.
|
23
|
+
def find(start, target, current_route = [])
|
24
|
+
return [target] if start == target
|
25
|
+
return nil unless paths.has_key?(start)
|
26
|
+
|
27
|
+
# Map all possible paths to the target.
|
28
|
+
# Skip nodes we have already visited
|
29
|
+
next_nodes = paths[start] - current_route
|
30
|
+
routes = next_nodes.map do |next_node|
|
31
|
+
find(next_node, target, current_route + [start])
|
32
|
+
end
|
33
|
+
|
34
|
+
# Reduce the collection to the shortest path
|
35
|
+
shortest_route = routes.compact.inject(nil) {|shortest,possibility|
|
36
|
+
next possibility if shortest.nil?
|
37
|
+
possibility.size < shortest.size ? possibility : shortest
|
38
|
+
}
|
39
|
+
return [start] + shortest_route if shortest_route
|
40
|
+
nil
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
class ServerDefinition
|
3
|
+
attr_accessor :host, :user, :options, :port, :password
|
4
|
+
|
5
|
+
def initialize(host, options = {})
|
6
|
+
@options = {:port => 22}.merge(options)
|
7
|
+
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
|
21
|
+
end
|
22
|
+
|
23
|
+
def password=(password)
|
24
|
+
options[:password] = password
|
25
|
+
@password=password
|
26
|
+
end
|
27
|
+
|
28
|
+
def connection_info(&block)
|
29
|
+
block.call(host, user, options.merge(ssh_options))
|
30
|
+
end
|
31
|
+
|
32
|
+
def ssh_options
|
33
|
+
{
|
34
|
+
:auth_methods => %w[password keyboard-interactive]
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_s
|
39
|
+
"#{user}:#{'*' * password.to_s.size}@#{host}:#{port}"
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.lookup(server)
|
43
|
+
server = servers[server]
|
44
|
+
new(server['address'],{
|
45
|
+
:user => server['username'],
|
46
|
+
:password => server['password'],
|
47
|
+
:port => server['port']
|
48
|
+
})
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.find(server)
|
52
|
+
servers.has_key?(server) ? lookup(server) : parse(server)
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.parse(ssh_string)
|
56
|
+
user, password, host, port = ssh_string.match /\A(.*?):(.*?)@(.*?):(\d*?)\Z/
|
57
|
+
new(host, :user => user, :password => password, :port => port)
|
58
|
+
end
|
59
|
+
|
60
|
+
class << self
|
61
|
+
attr_accessor :servers
|
62
|
+
|
63
|
+
# Access the pre-configured servers. ~/.servers.yml is parsed for this.
|
64
|
+
# An example entry for the servers 'foobar' and 'barfoo' would look like:
|
65
|
+
# ---
|
66
|
+
# foobar:
|
67
|
+
# address: "127.0.0.1"
|
68
|
+
# username: "foo"
|
69
|
+
# password: "bar
|
70
|
+
# port: 22
|
71
|
+
# barfoo:
|
72
|
+
# address: "192.168.0.1"
|
73
|
+
# username: "bar"
|
74
|
+
# password: "foo
|
75
|
+
# port: 22
|
76
|
+
#
|
77
|
+
# Since the parsed Hash of servers is cached, a value can be stored and
|
78
|
+
# the configuration file ignored if desired.
|
79
|
+
def servers
|
80
|
+
@servers ||= YAML.load_file(File.expand_path('~/.servers.yml'))
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/lib/simple_gate.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'net/ssh'
|
3
|
+
require 'net/ssh/gateway'
|
4
|
+
require 'activesupport'
|
5
|
+
require 'simple_gate/server_definition'
|
6
|
+
|
7
|
+
class SimpleGate
|
8
|
+
def initialize(options={})
|
9
|
+
@options = {
|
10
|
+
:verbose => false
|
11
|
+
}.merge(options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def verbose?
|
15
|
+
@options[:verbose]
|
16
|
+
end
|
17
|
+
|
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
|
+
# Needs at least one real gateway and a real server.
|
21
|
+
def through_to(*gateways) # :yields: ssh session
|
22
|
+
gateways = gateways.flatten
|
23
|
+
raise ArgumentError.new("Need at least 2 servers") if gateways.size < 2
|
24
|
+
target = ServerDefinition.find(gateways.pop)
|
25
|
+
through(gateways) do |gate|
|
26
|
+
target.connection_info do |host, user, options|
|
27
|
+
gate.ssh(host, user, options) do |session|
|
28
|
+
yield(session)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Most of the code was taken from Capistrano and then changed to work
|
35
|
+
# outside of Capistrano.
|
36
|
+
def through(*gateways)
|
37
|
+
Thread.abort_on_exception = true
|
38
|
+
@open_connections ||= []
|
39
|
+
@gateways = gateways.flatten.collect { |g| ServerDefinition.find(g) }
|
40
|
+
tunnel = @gateways[0].connection_info do |host, user, connect_options|
|
41
|
+
puts "Setting up tunnel #{@gateways[0]}" if verbose?
|
42
|
+
gw = Net::SSH::Gateway.new(host, user, connect_options)
|
43
|
+
@open_connections << gw
|
44
|
+
gw
|
45
|
+
end
|
46
|
+
@gateway = (@gateways[1..-1]).inject(tunnel) do |tunnel, destination|
|
47
|
+
puts "Connecting to #{destination}" if verbose?
|
48
|
+
tunnel_port = tunnel.open(destination.host, (destination.port || 22))
|
49
|
+
localhost_options = {:user => destination.user, :port => tunnel_port, :password => destination.password}
|
50
|
+
local_host = ServerDefinition.new("127.0.0.1", localhost_options)
|
51
|
+
local_host.connection_info do |host, user, connect_options|
|
52
|
+
puts "Connecting using local info #{local_host}" if verbose?
|
53
|
+
gw = Net::SSH::Gateway.new(host, user, connect_options)
|
54
|
+
@open_connections << gw
|
55
|
+
gw
|
56
|
+
end
|
57
|
+
end
|
58
|
+
yield(@gateway)
|
59
|
+
ensure
|
60
|
+
while g = @open_connections.pop
|
61
|
+
g.shutdown!
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/simple_gate.gemspec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
# Project
|
3
|
+
s.name = 'simple_gate'
|
4
|
+
s.summary = "SimpleGate makes it possible to use net/ssh/gateway's capabilities in a simple to use way."
|
5
|
+
s.description = s.summary
|
6
|
+
s.version = '0.5.1'
|
7
|
+
s.date = '2009-04-18'
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Wes Oldenbeuving"]
|
10
|
+
s.email = "narnach@gmail.com"
|
11
|
+
s.homepage = "http://www.github.com/Narnach/simple_gate"
|
12
|
+
|
13
|
+
# Files
|
14
|
+
root_files = %w[MIT-LICENSE README.rdoc Rakefile simple_gate.gemspec]
|
15
|
+
bin_files = %w[simple_gate gate_cp]
|
16
|
+
lib_files = %w[simple_gate
|
17
|
+
simple_gate/server_definition
|
18
|
+
simple_gate/router]
|
19
|
+
test_files = %w[]
|
20
|
+
spec_files = %w[simple_gate]
|
21
|
+
s.bindir = "bin"
|
22
|
+
s.require_path = "lib"
|
23
|
+
s.executables = bin_files
|
24
|
+
s.test_files = test_files.map {|f| 'test/%s_test.rb' % f} + spec_files.map {|f| 'spec/%s_spec.rb' % f}
|
25
|
+
s.files = root_files + bin_files.map {|f| 'bin/%s' % f} + lib_files.map {|f| 'lib/%s.rb' % f} + s.test_files
|
26
|
+
|
27
|
+
# rdoc
|
28
|
+
s.has_rdoc = true
|
29
|
+
s.extra_rdoc_files = %w[ README.rdoc MIT-LICENSE]
|
30
|
+
s.rdoc_options << '--inline-source' << '--line-numbers' << '--main' << 'README.rdoc'
|
31
|
+
|
32
|
+
# Requirements
|
33
|
+
s.required_ruby_version = ">= 1.8.0"
|
34
|
+
end
|
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: Narnach-simple_gate
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Wes Oldenbeuving
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-04-18 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: SimpleGate makes it possible to use net/ssh/gateway's capabilities in a simple to use way.
|
17
|
+
email: narnach@gmail.com
|
18
|
+
executables:
|
19
|
+
- simple_gate
|
20
|
+
- gate_cp
|
21
|
+
extensions: []
|
22
|
+
|
23
|
+
extra_rdoc_files:
|
24
|
+
- README.rdoc
|
25
|
+
- MIT-LICENSE
|
26
|
+
files:
|
27
|
+
- MIT-LICENSE
|
28
|
+
- README.rdoc
|
29
|
+
- Rakefile
|
30
|
+
- simple_gate.gemspec
|
31
|
+
- bin/simple_gate
|
32
|
+
- bin/gate_cp
|
33
|
+
- lib/simple_gate.rb
|
34
|
+
- lib/simple_gate/server_definition.rb
|
35
|
+
- lib/simple_gate/router.rb
|
36
|
+
- spec/simple_gate_spec.rb
|
37
|
+
has_rdoc: true
|
38
|
+
homepage: http://www.github.com/Narnach/simple_gate
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options:
|
41
|
+
- --inline-source
|
42
|
+
- --line-numbers
|
43
|
+
- --main
|
44
|
+
- README.rdoc
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: 1.8.0
|
52
|
+
version:
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
version:
|
59
|
+
requirements: []
|
60
|
+
|
61
|
+
rubyforge_project:
|
62
|
+
rubygems_version: 1.2.0
|
63
|
+
signing_key:
|
64
|
+
specification_version: 2
|
65
|
+
summary: SimpleGate makes it possible to use net/ssh/gateway's capabilities in a simple to use way.
|
66
|
+
test_files:
|
67
|
+
- spec/simple_gate_spec.rb
|