aaalex-cloudy_integrate 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
File without changes
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'getoptlong'
4
+ require 'rubygems'
5
+ require 'rake'
6
+ require 'net/ssh'
7
+
8
+ require 'cloudy_integrate'
9
+
10
+
11
+ include CloudyIntegrate
12
+
13
+ USAGE = "USAGE: cloudy_integrate [options] [command] (try cloudy_integrate --help)"
14
+
15
+ HELP = <<-end_doc
16
+ cloudy_integrate - virtually integrate an EC2 instance into your local network
17
+
18
+ USAGE: cloudy_integrate [options] [command]
19
+
20
+ COMMANDS:
21
+ #{CloudyIntegrate::Session.commands_with_description.map{|method, desc| " %-17s %s" % [method, desc]}.join("\n")}
22
+ The default command is "list"
23
+
24
+ OPTIONS:
25
+ --help -h You're reading it
26
+ --verbose -v Show work
27
+ --version -V Show version
28
+ --backtrace Show ruby backtrace on error
29
+
30
+ end_doc
31
+
32
+ VERSION_STRING = <<-end_doc
33
+ #{USAGE}
34
+ Version: #{CloudyIntegrate::Version::String}
35
+
36
+ end_doc
37
+
38
+ @verbose = false
39
+
40
+ GetoptLong.new(
41
+ ['--help', '-h', GetoptLong::NO_ARGUMENT],
42
+ ['--verbose', '-v', GetoptLong::NO_ARGUMENT],
43
+ ['--version', '-V', GetoptLong::NO_ARGUMENT],
44
+ ['--backtrace', GetoptLong::NO_ARGUMENT]
45
+ ).each do |opt, arg|
46
+ case opt
47
+ when '--help' then STDOUT << HELP; exit true
48
+ when '--verbose' then @verbose = true
49
+ when '--version' then STDOUT << VERSION_STRING; exit true
50
+ when '--backtrace' then @backtrace = true
51
+ end
52
+ end
53
+
54
+ begin
55
+ # run a cloudy_integrate command
56
+ raise "Unknown command: #{ARGV.first}" unless ARGV.empty? || CloudyIntegrate::Session.commands.include?(ARGV.first)
57
+
58
+ # configure the garlic runner
59
+ CloudyIntegrate::Session.runner.verbose = @verbose
60
+ # garlic.run_targets = @run_targets
61
+
62
+ # run the command
63
+ ARGV << 'list' if ARGV.empty?
64
+ CloudyIntegrate::Session.call_command *ARGV
65
+
66
+ rescue Exception => e
67
+ STDERR << "\n#{USAGE}\n\nError: #{e.message}\n\n"
68
+ raise e if @backtrace
69
+ exit false
70
+ end
@@ -0,0 +1,18 @@
1
+ require "cloudy_integrate/session"
2
+ require "cloudy_integrate/help_command"
3
+ require "cloudy_integrate/check_command"
4
+ require "cloudy_integrate/list_command"
5
+ require "cloudy_integrate/start_command"
6
+ require "cloudy_integrate/stop_command"
7
+
8
+ module CloudyIntegrate
9
+
10
+ module Version
11
+ Major = 0
12
+ Minor = 0
13
+ Tiny = 1
14
+
15
+ String = [Major, Minor, Tiny].join('.')
16
+ end
17
+
18
+ end
@@ -0,0 +1,22 @@
1
+ module CloudyIntegrate
2
+
3
+ class Session
4
+
5
+ define_command :list, "List all running tunnels on remote host" do |a_end_name|
6
+
7
+ ssh = Net::SSH.start(a_end_name, 'root', :forward_agent => true, :paranoid => false)
8
+ res = ssh.exec!("ps -ef | egrep autossh.*-Nqw | grep -v egrep")
9
+ if res
10
+ while( mtch = res.match( /\w+ *(\d+).*-Nqw (\d+):(\d+).*Checking=no ([\w\d.\-]+)/ )) do
11
+ puts "#{mtch[1]} #{mtch[2]} #{mtch[3]} #{mtch[4]}"
12
+ res = mtch.post_match
13
+ end
14
+ else
15
+ puts "no tunnels found on #{a_end_name}"
16
+ end
17
+ ssh.close
18
+
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,41 @@
1
+ module CloudyIntegrate
2
+ # this class runs the top level garlic commands
3
+ class Session
4
+
5
+ attr_accessor :verbose
6
+
7
+ # meta data about command methods which can be used by both rake and the cli tool
8
+ @@commands, @@command_descriptions = [], {}
9
+
10
+ class << self
11
+ def define_command(name, desc, &block)
12
+ @@commands << name
13
+ @@command_descriptions[name] = desc
14
+ define_method name, &block
15
+ end
16
+
17
+ def commands_with_description
18
+ @@commands.map{ |m| [m, @@command_descriptions[m]]}
19
+ end
20
+
21
+ def command_description(name)
22
+ @@command_descriptions[name]
23
+ end
24
+
25
+ def commands
26
+ @@command_descriptions.keys.map { |c| c.to_s}
27
+ end
28
+
29
+ def call_command(id, *args)
30
+ meth = runner.method(id.to_sym)
31
+ raise ArgumentError.new("Wrong number of arguments for #{meth.to_s}. Need #{meth.arity}}") unless meth.arity == args.size
32
+ meth.call *args
33
+ end
34
+
35
+ def runner
36
+ @runner ||= new
37
+ end
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,94 @@
1
+ # TODO: make tun interface discovery automatic
2
+ # TODO: make tun ip discovery dynamic
3
+
4
+ module CloudyIntegrate
5
+
6
+ class Session
7
+
8
+ define_command :start, "Integrate a cloudy instance into your network" do |a_end_name, b_end_name, a_end_ip, b_end_ip|
9
+ puts "connecting #{a_end_name} to #{b_end_name}"
10
+
11
+ # require 'ifconfig'
12
+ class Node
13
+ attr_reader :name, :tun, :tun_ip
14
+ def initialize(name)
15
+ @name = name
16
+ @ssh = Net::SSH.start(name, 'root', :forward_agent => true, :paranoid => false)
17
+ end
18
+
19
+ def prepare_for_tunneling(tun_ip = nil, tun = nil)
20
+ # find unused ip on network
21
+ @tun_ip = tun_ip || find_free_ip
22
+ # find free tun interface
23
+ @tun = tun || find_free_tunnel_interface
24
+ end
25
+ def find_free_ip
26
+ raise NotImplementedError.new "find_free_ip not implemented"
27
+ end
28
+ def find_free_tunnel_interface
29
+ tun_arr = exec "netstat -in | tail --lines=+3".inject([]) do |arr,line|
30
+ f = line.match(/^tun(\d+)/)
31
+ arr << f[1] if f
32
+ arr
33
+ end
34
+ free_tun = (0..(tun_arr.size)).each do |num|
35
+ return num unless tun_arr.include? num
36
+ end
37
+ free_tun
38
+ end
39
+
40
+ def exec(cmd);
41
+ # system cmd
42
+ puts "executing #{name}:#{cmd}" if true
43
+ @ssh.exec!(cmd)
44
+ end
45
+
46
+ def set_tun_ip(remote_ip)
47
+ exec "ifconfig tun#{tun} #{tun_ip} pointopoint #{remote_ip}"
48
+ end
49
+ def network; "192.168.1.0"; end
50
+ def netmask; "255.255.255.0"; end
51
+ def interface; "eth0"; end
52
+
53
+ def set_proc_ipv4(proc_name); exec "echo 1 > /proc/sys/net/ipv4/#{ proc_name}"; end
54
+ def enable_ip_forward; set_proc_ipv4 "ip_forward"; end
55
+ def enable_proxy_arp; set_proc_ipv4 "conf/#{ interface}/proxy_arp"; end
56
+ end
57
+
58
+ aEnd = Node.new a_end_name
59
+ aEnd.prepare_for_tunneling a_end_ip, 2
60
+ bEnd = Node.new b_end_name
61
+ bEnd.prepare_for_tunneling b_end_ip, 2
62
+
63
+ # prepare ssh tunnel
64
+
65
+ # check for PermitTunnel option in sshd_config on bEnd
66
+ # should check if really needed
67
+ if true
68
+ bEnd.exec( 'echo "PermitTunnel yes" >> /etc/ssh/sshd_config')
69
+ bEnd.exec( 'invoke-rc.d ssh reload')
70
+ end
71
+
72
+ # start ssh on aEnd
73
+ aEnd.exec "autossh -f -Nqw #{aEnd.tun}:#{bEnd.tun} -o StrictHostKeyChecking=no #{bEnd.name}"
74
+
75
+ # wait for stable tunnel
76
+ # TODO: better checking
77
+ begin
78
+ sleep 2
79
+ end while aEnd.exec("ifconfig tun#{aEnd.tun} | grep 'Device not found'")
80
+
81
+ # setup ip networking
82
+ aEnd.set_tun_ip bEnd.tun_ip
83
+ bEnd.set_tun_ip aEnd.tun_ip
84
+ bEnd.exec "route add -net #{aEnd.network} netmask #{aEnd.netmask} gw #{aEnd.tun_ip} tun#{aEnd.tun}"
85
+
86
+ # enable forwarding and proxy_arp in a_end
87
+ aEnd.enable_ip_forward
88
+ aEnd.enable_proxy_arp
89
+
90
+ puts "integrated node #{bEnd.name} with IP #{bEnd.tun_ip}"
91
+ end
92
+
93
+ end
94
+ end
@@ -0,0 +1,18 @@
1
+ module CloudyIntegrate
2
+
3
+ class Session
4
+
5
+ define_command :stop, "Stop one integration" do |a_end_name, local_tun|
6
+
7
+ ssh = Net::SSH.start(a_end_name, 'root', :forward_agent => true, :paranoid => false)
8
+ res = ssh.exec!("ps -ef | grep -v egrep | egrep 'autossh.*-Nqw #{local_tun}'")
9
+ if res
10
+ pid = res.match( /\w+ *(\d+)/ )[1]
11
+ ssh.exec!("kill -TERM #{pid}")
12
+ ssh.close
13
+ end
14
+
15
+ end
16
+
17
+ end
18
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: aaalex-cloudy_integrate
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Alex Peuchert
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-12-11 00:00:00 -08:00
13
+ default_executable: cloudy_integrate
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: aaalex-ruby-ifconfig
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.2.3
23
+ version:
24
+ description: Set of commands/rake-tasks .
25
+ email: apeuchert@googlemail.com
26
+ executables:
27
+ - cloudy_integrate
28
+ extensions: []
29
+
30
+ extra_rdoc_files: []
31
+
32
+ files:
33
+ - lib/cloudy_integrate/session.rb
34
+ - lib/cloudy_integrate/list_command.rb
35
+ - lib/cloudy_integrate/start_command.rb
36
+ - lib/cloudy_integrate/stop_command.rb
37
+ - lib/cloudy_integrate.rb
38
+ - README.textile
39
+ - History.txt
40
+ - bin/cloudy_integrate
41
+ has_rdoc: false
42
+ homepage: http://github.com/aaalex/cloudy_integrate
43
+ post_install_message:
44
+ rdoc_options: []
45
+
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: "0"
53
+ version:
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ requirements: []
61
+
62
+ rubyforge_project:
63
+ rubygems_version: 1.2.0
64
+ signing_key:
65
+ specification_version: 2
66
+ summary: Virtually integrate an EC2 instance into your local network.
67
+ test_files: []
68
+