ispunity 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -0
- data/Gemfile +8 -0
- data/README +31 -0
- data/Rakefile +1 -0
- data/config/locale/en.yml +30 -0
- data/config/sample.json +42 -0
- data/config/settings.yml +9 -0
- data/doc/algorithm.txt +33 -0
- data/isp_unity.gemspec +24 -0
- data/lib/isp_unity.rb +72 -0
- data/lib/isp_unity/isp.rb +18 -0
- data/lib/isp_unity/routing_table.rb +65 -0
- data/lib/isp_unity/version.rb +3 -0
- data/lib/isp_unity_log.rb +13 -0
- data/lib/load_balance/load_balance.rb +36 -0
- data/lib/route/route.rb +20 -0
- data/lib/rule/rule.rb +16 -0
- data/lib/system_call.rb +39 -0
- data/license +7 -0
- data/monitor.rb +3 -0
- data/setup.rb +6 -0
- data/spec/config/sample.json +41 -0
- data/spec/lib/isp_unity/route/route_spec.rb +1 -0
- data/spec/lib/isp_unity/routing_table_spec.rb +23 -0
- data/spec/lib/load_balance/load_balance_spec.rb +29 -0
- data/spec/lib/route/route_spec.rb +21 -0
- data/spec/lib/rule/rule_spec.rb +17 -0
- data/spec/rt_tables +3 -0
- data/spec/spec_helper.rb +9 -0
- data/test/clear_rules.rb +5 -0
- metadata +93 -0
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/README
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
1.Install rvm
|
2
|
+
|
3
|
+
curl -L get.rvm.io | bash -s stable
|
4
|
+
source /etc/profile.d/rvm.sh
|
5
|
+
|
6
|
+
Find the requirements;
|
7
|
+
|
8
|
+
rvm requirements
|
9
|
+
|
10
|
+
install the additional dependencies as mentioned.
|
11
|
+
|
12
|
+
2. Install ruby
|
13
|
+
rvm install 1.9.3
|
14
|
+
|
15
|
+
3. cd /opt
|
16
|
+
|
17
|
+
4. Install IspUnity ( make sure you have git installed)
|
18
|
+
|
19
|
+
git clone git://github.com/aruntomar/isp_unity.git
|
20
|
+
|
21
|
+
4. cd /opt/isp_unity
|
22
|
+
|
23
|
+
5. bundle install
|
24
|
+
|
25
|
+
6. cp -v config/sample.json config/sample.json.bak
|
26
|
+
|
27
|
+
7. modify the json file to suit your network.
|
28
|
+
|
29
|
+
8. Ruby ispunity
|
30
|
+
ruby setup.rb
|
31
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,30 @@
|
|
1
|
+
en:
|
2
|
+
no_ip_addr: 'No ip address found for '
|
3
|
+
file:
|
4
|
+
read:
|
5
|
+
success: 'Configuration file successfully read'
|
6
|
+
error: 'Configuration file is corrupted!!'
|
7
|
+
no_isp: 'No Isp found in configuration file!!'
|
8
|
+
enter_isp: 'Please enter configuration of ISP'
|
9
|
+
write: "New Isp's successfully added to rt_table"
|
10
|
+
isp:
|
11
|
+
created: 'Isp Object succesfully created!'
|
12
|
+
routing_table:
|
13
|
+
read:
|
14
|
+
success: 'Routing Rable file successfully read!'
|
15
|
+
error: 'Error while writing to routing table'
|
16
|
+
route:
|
17
|
+
build_commands: 'Route commands successfully built'
|
18
|
+
rule:
|
19
|
+
build_commands: 'Rule commands successfully built'
|
20
|
+
load_balance:
|
21
|
+
build_commands: 'Load Balancing commands successfully built'
|
22
|
+
system_call:
|
23
|
+
execute:
|
24
|
+
error: 'Error while executing commands!!'
|
25
|
+
route:
|
26
|
+
success: 'Successfully created routes'
|
27
|
+
rule:
|
28
|
+
success: 'Successfully created rules'
|
29
|
+
load_balance:
|
30
|
+
success: 'Successfully load balancing done'
|
data/config/sample.json
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
{
|
2
|
+
"no_of_isp":3,
|
3
|
+
"status":"balancing",
|
4
|
+
"interval":300,
|
5
|
+
"public_dns":["8.8.8.8","8.8.4.4","4.2.2.2","4.2.2.1"],
|
6
|
+
"log_level":1,
|
7
|
+
"isp": [
|
8
|
+
{
|
9
|
+
"id":"isp1",
|
10
|
+
"name":"tata",
|
11
|
+
"interface":"eth0",
|
12
|
+
"gateway":"61.17.193.1",
|
13
|
+
"subnet":"255.255.255.0",
|
14
|
+
"network":"61.17.193.0/24",
|
15
|
+
"weight":1,
|
16
|
+
"enabled":"true",
|
17
|
+
"online":"true"
|
18
|
+
},
|
19
|
+
{
|
20
|
+
"id":"isp2",
|
21
|
+
"name":"ttml",
|
22
|
+
"interface":"eth2",
|
23
|
+
"gateway":"192.168.0.2",
|
24
|
+
"subnet":"255.255.255.0",
|
25
|
+
"network":"192.168.0.0/24",
|
26
|
+
"weight":1,
|
27
|
+
"enabled":"true",
|
28
|
+
"online":"true"
|
29
|
+
},
|
30
|
+
{
|
31
|
+
"id":"isp3",
|
32
|
+
"name":"bsnl",
|
33
|
+
"interface":"wlan0",
|
34
|
+
"gateway":"192.168.2.1",
|
35
|
+
"subnet":"255.255.255.0",
|
36
|
+
"network":"192.168.2.0/24",
|
37
|
+
"weight":1,
|
38
|
+
"enabled":"false",
|
39
|
+
"online":"true"
|
40
|
+
}
|
41
|
+
]
|
42
|
+
}
|
data/config/settings.yml
ADDED
data/doc/algorithm.txt
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
For reference of the commands http://lartc.org/
|
2
|
+
|
3
|
+
1) Read Json file and build json object of all ISP's
|
4
|
+
Execute step2 to step4 for all the ISP's
|
5
|
+
2) Make the entry in rt_tables for ISP's
|
6
|
+
3) Add route
|
7
|
+
# Set a route table for particular ISP
|
8
|
+
ip route add $P1_NET dev $IF1 src $IP1 table T1(tata)
|
9
|
+
ip route add default via $P1_NET table T1
|
10
|
+
|
11
|
+
# For manual check if route is added properly:
|
12
|
+
Execute following command:
|
13
|
+
ip route show table tata which gives output as
|
14
|
+
|
15
|
+
default via 61.17.193.1 dev eth0
|
16
|
+
61.17.193.0/24 dev eth0 scope link src 61.17.193.163
|
17
|
+
|
18
|
+
4) Add rule for IP table
|
19
|
+
ip rule add from $IP1 table T1
|
20
|
+
|
21
|
+
5) Check ISP is in online are not
|
22
|
+
|
23
|
+
6) Fire Load balancing query across ISP's which are in online
|
24
|
+
# For more than one gateway.
|
25
|
+
# If there is no state change ISP's then don't follwing query.
|
26
|
+
# else fire following query:
|
27
|
+
/sbin/ip route replace default scope global nexthop via "source ip of the interface"
|
28
|
+
dev eth0 weight 1 nexthop via "ip gateway" dev "interface name" weight "weightage"
|
29
|
+
|
30
|
+
#and flush IP routing table cache by following command
|
31
|
+
ip route flush table cache
|
32
|
+
# If there is only one ISP
|
33
|
+
ip route replace default via "ip gateway" dev "interface name"
|
data/isp_unity.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "isp_unity/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "ispunity"
|
7
|
+
s.version = IspUnity::VERSION
|
8
|
+
s.authors = ["Pratik Shah", "Siva Gollapalli", "Arun Tomar"]
|
9
|
+
s.email = ["pratik14shah@gmail.com", "sivagollapalli@yahoo.com", "arun@solutionenterprises.co.in"]
|
10
|
+
s.homepage = "http://www.ispunity.com"
|
11
|
+
s.summary = %q{IspUnity is a open source framework, build to integrate (load balance & failover) multiple internet connections simultaneously}
|
12
|
+
s.description = %q{With IspUnity, you can 1.Use multiple internet connections simultaneously and get all their throughput. 2.Automatic failover on working net connection if any on of the internet connection goes down.}
|
13
|
+
|
14
|
+
s.rubyforge_project = "ispunity"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
# s.add_development_dependency "rspec"
|
23
|
+
# s.add_runtime_dependency "rest-client"
|
24
|
+
end
|
data/lib/isp_unity.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
$LOAD_PATH << File.expand_path(File.dirname(__FILE__))
|
2
|
+
require 'json'
|
3
|
+
require 'yaml'
|
4
|
+
require 'isp_unity_log'
|
5
|
+
require 'route/route'
|
6
|
+
require 'load_balance/load_balance'
|
7
|
+
require 'system_call'
|
8
|
+
require 'rule/rule'
|
9
|
+
require 'isp_unity/isp'
|
10
|
+
require 'isp_unity/version'
|
11
|
+
require 'isp_unity/routing_table'
|
12
|
+
require 'isp_unity/version'
|
13
|
+
|
14
|
+
|
15
|
+
module IspUnity
|
16
|
+
|
17
|
+
config_file = File.join([File.expand_path(File.dirname(__FILE__)), '..', 'config', 'settings.yml'])
|
18
|
+
ENV['GEM_ENV'] ||= 'development'
|
19
|
+
PATH = YAML.load_file( config_file )[ENV['GEM_ENV']]['ubuntu']
|
20
|
+
ConfigFilePath = File.join([File.expand_path(File.dirname(__FILE__)), '..',PATH['config_file_path']])
|
21
|
+
RoutingTablePath = PATH['rt_table_path'].to_s
|
22
|
+
|
23
|
+
class IspUnityException < Exception
|
24
|
+
def initialize(message)
|
25
|
+
message = message['error'] if message.class == Hash
|
26
|
+
super "[IspUnity] #{message}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class << self
|
31
|
+
|
32
|
+
def setup
|
33
|
+
IspUnity.config
|
34
|
+
IspUnityLog.info(I18n.t('file.write'))
|
35
|
+
Route.build_commands(IspUnity.isp_config_list)
|
36
|
+
IspUnityLog.info(I18n.t('route.build_commands'))
|
37
|
+
if SystemCall.execute(Route.commands)
|
38
|
+
IspUnityLog.info(I18n.t('system_call.execute.route.success'))
|
39
|
+
Rule.build_commands(IspUnity.isp_config_list)
|
40
|
+
IspUnityLog.info(I18n.t('rule.build_commands'))
|
41
|
+
SystemCall.execute(Rule.commands)
|
42
|
+
IspUnityLog.info(I18n.t('system_call.execute.rule.success'))
|
43
|
+
LoadBalance.build_commands(IspUnity.isp_config_list)
|
44
|
+
IspUnityLog.info(I18n.t('load_balance.build_commands'))
|
45
|
+
SystemCall.execute(LoadBalance.commands)
|
46
|
+
IspUnityLog.info(I18n.t('system_call.execute.load_balance.success'))
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def monitor
|
51
|
+
IspUnity.config
|
52
|
+
new_list = []
|
53
|
+
IspUnity.isp_config_list.each do |isp|
|
54
|
+
new_list << isp if LoadBalance.is_alive(isp)
|
55
|
+
end
|
56
|
+
unless new_list == isp_config_list
|
57
|
+
LoadBalance.build_commands(IspUnity.isp_config_list)
|
58
|
+
IspUnityLog.info(I18n.t('load_balance.build_commands'))
|
59
|
+
SystemCall.execute(LoadBalance.commands)
|
60
|
+
IspUnityLog.info(I18n.t('system_call.execute.load_balance.success'))
|
61
|
+
SystemCall.execute('ip route flush cache')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def version
|
66
|
+
version = "0.0.1"
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class Isp
|
2
|
+
|
3
|
+
attr_accessor :id, :name, :interface, :gateway, :subnet, :network, :online, :enabled, :ip_address, :weight
|
4
|
+
|
5
|
+
def initialize(config_isp)
|
6
|
+
@id = config_isp['id']
|
7
|
+
@name = config_isp['name']
|
8
|
+
@interface = config_isp['interface']
|
9
|
+
@gateway = config_isp['gateway']
|
10
|
+
@subnet = config_isp['subnet']
|
11
|
+
@network = config_isp['network']
|
12
|
+
@online = config_isp["online"]
|
13
|
+
@enabled = config_isp['enabled']
|
14
|
+
@ip_address = config_isp['ip_address']
|
15
|
+
@weight = config_isp['weight']
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'i18n'
|
2
|
+
path = File.join([[File.expand_path(File.dirname(__FILE__)), '../..', 'config', 'locale', 'en.yml']])
|
3
|
+
I18n.load_path = [path]
|
4
|
+
|
5
|
+
module IspUnity
|
6
|
+
|
7
|
+
$ip_cluster = []
|
8
|
+
class << self
|
9
|
+
|
10
|
+
attr_reader :isp_config_list
|
11
|
+
|
12
|
+
def config
|
13
|
+
begin
|
14
|
+
configurations = JSON.parse(File.read(ConfigFilePath))
|
15
|
+
IspUnityLog.info(I18n.t('file.read.success'))
|
16
|
+
rescue Exception => e
|
17
|
+
IspUnityLog.debug("#{e}")
|
18
|
+
IspUnityLog.error(I18n.t('file.read.error'))
|
19
|
+
raise IspUnityException.new(I18n.t('file.read.error'))
|
20
|
+
end
|
21
|
+
|
22
|
+
@isp_config_list = []
|
23
|
+
no_of_isp = configurations['no_of_isp']
|
24
|
+
isp_list = configurations['isp']
|
25
|
+
$ip_cluster = configurations['public_dns']
|
26
|
+
|
27
|
+
if no_of_isp
|
28
|
+
isp_list.each do|data|
|
29
|
+
if data['enabled'] == 'true'
|
30
|
+
ip_addr = SystemCall.get_ip(data['interface'].to_s)
|
31
|
+
if ip_addr
|
32
|
+
data['ip_address'] = SystemCall.get_ip(data['interface'])
|
33
|
+
@isp_config_list.push(Isp.new(data))
|
34
|
+
else
|
35
|
+
puts I18n.t('no_ip_addr') + data['name']
|
36
|
+
IspUnityLog.error(I18n.t('no_ip_addr') + data['name'] )
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
IspUnityLog.info('Isp Object succesfully created!')
|
41
|
+
else
|
42
|
+
raise IspUnityException.new(I18n.t('file.enter_isp'))
|
43
|
+
IspUnityLog.error(I18n.t('file.read.no_isp_found'))
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
routing_table = File.read(RoutingTablePath)
|
48
|
+
IspUnityLog.info(I18n.t('routing_table.read.success'))
|
49
|
+
begin
|
50
|
+
@isp_config_list.each do|isp_list|
|
51
|
+
unless routing_table.include?(isp_list.name)
|
52
|
+
File.open(RoutingTablePath, 'a') {|f| f.write("#{rand(100)} #{isp_list.name} \n")}
|
53
|
+
end
|
54
|
+
IspUnityLog.info(I18n.t('isp.created'))
|
55
|
+
end
|
56
|
+
rescue Exception => e
|
57
|
+
IspUnityLog.debug("#{e}")
|
58
|
+
IspUnityLog.error(I18n.t('routing_table.read.error'))
|
59
|
+
raise IspUnityException.new(I18n.t('routing_table.read.error'))
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
$LOAD_PATH << File.expand_path(File.dirname(__FILE__))
|
2
|
+
require 'rubygems'
|
3
|
+
require 'log4r'
|
4
|
+
|
5
|
+
include Log4r
|
6
|
+
|
7
|
+
filename = "ispunity.log"
|
8
|
+
|
9
|
+
IspUnityLog = Logger.new("log")
|
10
|
+
IspUnityLog.level = DEBUG
|
11
|
+
pf = PatternFormatter.new(:pattern => "%d %l %m")
|
12
|
+
IspUnityLog.outputters = FileOutputter.new("IspUnity", :filename => File.join(File.dirname(__FILE__),"..","log",filename), :formatter => pf)
|
13
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class LoadBalance
|
2
|
+
|
3
|
+
class << self
|
4
|
+
attr_reader :commands
|
5
|
+
|
6
|
+
def build_commands(isps)
|
7
|
+
@commands = []
|
8
|
+
alive_isps = []
|
9
|
+
isps.each do |isp|
|
10
|
+
alive_isps << isp if is_alive(isp)
|
11
|
+
end
|
12
|
+
if alive_isps.size == 1
|
13
|
+
@commands << "/sbin/ip route replace default via #{alive_isps[0].gateway} dev #{alive_isps[0].interface}"
|
14
|
+
else
|
15
|
+
@commands << "/sbin/ip route replace default scope global "
|
16
|
+
alive_isps.each do |isp|
|
17
|
+
@commands[0] += " nexthop via #{isp.gateway} dev #{isp.interface} weight #{isp.weight} "
|
18
|
+
end
|
19
|
+
end
|
20
|
+
return @commands[0]
|
21
|
+
end
|
22
|
+
|
23
|
+
def is_alive(isp)
|
24
|
+
return true if ENV['GEM_ENV']=='test'
|
25
|
+
return false unless isp.enabled == 'true'
|
26
|
+
result = `/bin/ping -c 3 -I #{isp.ip_address} #{$ip_cluster.sample}`
|
27
|
+
if result.match("100% packet loss")
|
28
|
+
return false
|
29
|
+
else
|
30
|
+
return true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
data/lib/route/route.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# How to route answers to packets coming in over a particular provider,
|
2
|
+
# say Provider 1, back out again over that same provider
|
3
|
+
|
4
|
+
class Route
|
5
|
+
|
6
|
+
class << self
|
7
|
+
|
8
|
+
attr_reader :commands
|
9
|
+
|
10
|
+
def build_commands(isps=[])
|
11
|
+
@commands = []
|
12
|
+
isps.each do |isp|
|
13
|
+
@commands << "/sbin/ip route add #{isp.network} dev #{isp.interface} src #{isp.ip_address} table #{isp.name}"
|
14
|
+
@commands << "/sbin/ip route add default via #{isp.gateway} table #{isp.name}"
|
15
|
+
end
|
16
|
+
@commands
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
data/lib/rule/rule.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
class Rule
|
2
|
+
|
3
|
+
class << self
|
4
|
+
|
5
|
+
attr_reader :commands
|
6
|
+
|
7
|
+
def build_commands(isps=[])
|
8
|
+
@commands = []
|
9
|
+
isps.each do |isp|
|
10
|
+
output = `/sbin/ip rule show`
|
11
|
+
@commands << "/sbin/ip rule add from #{isp.gateway} table #{isp.name}" unless output.include?(isp.name)
|
12
|
+
end
|
13
|
+
@commands
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/system_call.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
class SystemCall
|
2
|
+
class << self
|
3
|
+
def execute(commands=[])
|
4
|
+
begin
|
5
|
+
if commands.is_a?(Array)
|
6
|
+
commands.each {|cmd| `#{cmd}`}
|
7
|
+
else
|
8
|
+
`#{commands}`
|
9
|
+
end
|
10
|
+
return true
|
11
|
+
rescue Exception => e
|
12
|
+
IspUnityLog.debug("#{e}")
|
13
|
+
IspUnityLog.error(I18n.t('system_call.execute.error'))
|
14
|
+
IspUnityException.new(I18n.t('system_call.execute.error'))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def get_ip(interface)
|
19
|
+
return '127.0.0.1' if ENV['GEM_ENV'] == 'test'
|
20
|
+
begin
|
21
|
+
result = `/sbin/ifconfig #{interface}`
|
22
|
+
ip = /inet addr:(?<ip>(\d+[.]){3}\d+)/.match(result)
|
23
|
+
ip = ip[0].split(':')[1] if ip
|
24
|
+
rescue Exception => e
|
25
|
+
IspUnityLog.debug("#{e}")
|
26
|
+
IspUnityLog.error(I18n.t('system_call.execute.error'))
|
27
|
+
IspUnityException.new(I18n.t('system_call.execute.error'))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class IspUnityException < Exception
|
33
|
+
def initialize(message)
|
34
|
+
message = message['error'] if message.class == Hash
|
35
|
+
super "[IspUnity] #{message}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
data/license
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
IspUnity Copyright (C) 2012 Arun Tomar
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/monitor.rb
ADDED
data/setup.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
{
|
2
|
+
"no_of_isp":3,
|
3
|
+
"status":"balancing",
|
4
|
+
"interval":300,
|
5
|
+
"public_dns":["8.8.8.8","8.8.4.4","4.2.2.2","4.2.2.1"],
|
6
|
+
"isp": [
|
7
|
+
{
|
8
|
+
"id":"isp1",
|
9
|
+
"name":"tata",
|
10
|
+
"interface":"eth0",
|
11
|
+
"gateway":"61.17.193.163",
|
12
|
+
"subnet":"255.255.255.0",
|
13
|
+
"network":"61.17.193.0/24",
|
14
|
+
"weight":1,
|
15
|
+
"enabled":false,
|
16
|
+
"online":"true"
|
17
|
+
},
|
18
|
+
{
|
19
|
+
"id":"isp2",
|
20
|
+
"name":"ttml",
|
21
|
+
"interface":"eth1",
|
22
|
+
"gateway":"192.168.0.2",
|
23
|
+
"subnet":"255.255.255.0",
|
24
|
+
"network":"192.168.0.0/24",
|
25
|
+
"weight":1,
|
26
|
+
"enabled":false,
|
27
|
+
"online":"true"
|
28
|
+
},
|
29
|
+
{
|
30
|
+
"id":"isp3",
|
31
|
+
"name":"bsnl",
|
32
|
+
"interface":"wlan0",
|
33
|
+
"gateway":"192.168.2.1",
|
34
|
+
"subnet":"255.255.255.0",
|
35
|
+
"network":"192.168.2.0/24",
|
36
|
+
"weight":1,
|
37
|
+
"enabled":false,
|
38
|
+
"online":"true"
|
39
|
+
}
|
40
|
+
]
|
41
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
# rt_tables located at /etc/iproute2 dir
|
4
|
+
|
5
|
+
describe "RoutingTable(Assuming currently there are 3[tata, ttml, bsnl] service providers)" do
|
6
|
+
def check_entry
|
7
|
+
IspUnity.config
|
8
|
+
count = File.open('./spec/rt_tables', 'rb') { |f| f.readlines.count }
|
9
|
+
count.should == 3
|
10
|
+
end
|
11
|
+
|
12
|
+
after(:all) { File.open('./spec/rt_tables', 'w') {|file| file.truncate(0) } }
|
13
|
+
|
14
|
+
context "#config" do
|
15
|
+
it "should make an entry in rt tables file for each isp" do
|
16
|
+
check_entry
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should make no entry if there is an entry already exists of particular isp" do
|
20
|
+
check_entry
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "LoadBalance" do
|
4
|
+
|
5
|
+
before(:each) { IspUnity.config }
|
6
|
+
|
7
|
+
context "build commands" do
|
8
|
+
before(:each) do
|
9
|
+
isp = IspUnity.isp_config_list.first
|
10
|
+
isp.enabled = true
|
11
|
+
@command = LoadBalance.build_commands([isp])
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should return load balance command as 'ip route replace default via 61.17.193.163 dev tata' if only one is enabled" do
|
15
|
+
@command.should == "ip route replace default via 61.17.193.163 dev eth0"
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
it "build commands should return load balance command as none if neither isps are enabled" do
|
20
|
+
isp = IspUnity.isp_config_list.first
|
21
|
+
@command = LoadBalance.build_commands([isp])
|
22
|
+
@command.should == nil
|
23
|
+
end
|
24
|
+
|
25
|
+
it "build commands should return command if all isps are alive" do
|
26
|
+
@command = LoadBalance.build_commands(IspUnity.isp_config_list)
|
27
|
+
@command.should == "ip route replace default scope global nexthop via 61.17.193.163 dev eth0 weight 1 nexthop via 192.168.0.2 dev eth1 weight 1 nexthop via 192.168.2.1 dev wlan0 weight 1 "
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "Route" do
|
4
|
+
|
5
|
+
before(:each) { IspUnity.config }
|
6
|
+
let(:commands) { Route.build_commands(IspUnity.isp_config_list) }
|
7
|
+
|
8
|
+
context "build commands" do
|
9
|
+
it "should six commands" do
|
10
|
+
commands.count.should == 6
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should return route command for an isp" do
|
14
|
+
commands.first.should == 'ip route add 61.17.193.0/24 dev eth0 src 127.0.0.1 table tata'
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should return gateway command for an isp" do
|
18
|
+
commands.last.should == 'ip route add default via 192.168.2.1 table bsnl'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "Rule" do
|
4
|
+
|
5
|
+
before(:each) { IspUnity.config }
|
6
|
+
let(:commands) { Rule.build_commands(IspUnity.isp_config_list) }
|
7
|
+
|
8
|
+
context "build commands" do
|
9
|
+
it "should 3 commands" do
|
10
|
+
commands.count.should == 3
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should return rule command for an isp" do
|
14
|
+
commands.first.should == "ip rule add from 61.17.193.163 table tata"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/spec/rt_tables
ADDED
data/spec/spec_helper.rb
ADDED
data/test/clear_rules.rb
ADDED
metadata
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ispunity
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Pratik Shah
|
9
|
+
- Siva Gollapalli
|
10
|
+
- Arun Tomar
|
11
|
+
autorequire:
|
12
|
+
bindir: bin
|
13
|
+
cert_chain: []
|
14
|
+
date: 2012-04-20 00:00:00.000000000 Z
|
15
|
+
dependencies: []
|
16
|
+
description: With IspUnity, you can 1.Use multiple internet connections simultaneously
|
17
|
+
and get all their throughput. 2.Automatic failover on working net connection if
|
18
|
+
any on of the internet connection goes down.
|
19
|
+
email:
|
20
|
+
- pratik14shah@gmail.com
|
21
|
+
- sivagollapalli@yahoo.com
|
22
|
+
- arun@solutionenterprises.co.in
|
23
|
+
executables: []
|
24
|
+
extensions: []
|
25
|
+
extra_rdoc_files: []
|
26
|
+
files:
|
27
|
+
- .gitignore
|
28
|
+
- .rspec
|
29
|
+
- Gemfile
|
30
|
+
- README
|
31
|
+
- Rakefile
|
32
|
+
- config/locale/en.yml
|
33
|
+
- config/sample.json
|
34
|
+
- config/settings.yml
|
35
|
+
- doc/algorithm.txt
|
36
|
+
- isp_unity.gemspec
|
37
|
+
- lib/isp_unity.rb
|
38
|
+
- lib/isp_unity/isp.rb
|
39
|
+
- lib/isp_unity/routing_table.rb
|
40
|
+
- lib/isp_unity/version.rb
|
41
|
+
- lib/isp_unity_log.rb
|
42
|
+
- lib/load_balance/load_balance.rb
|
43
|
+
- lib/route/route.rb
|
44
|
+
- lib/rule/rule.rb
|
45
|
+
- lib/system_call.rb
|
46
|
+
- license
|
47
|
+
- log/isp_unity.log
|
48
|
+
- monitor.rb
|
49
|
+
- setup.rb
|
50
|
+
- spec/config/sample.json
|
51
|
+
- spec/lib/isp_unity/route/route_spec.rb
|
52
|
+
- spec/lib/isp_unity/routing_table_spec.rb
|
53
|
+
- spec/lib/load_balance/load_balance_spec.rb
|
54
|
+
- spec/lib/route/route_spec.rb
|
55
|
+
- spec/lib/rule/rule_spec.rb
|
56
|
+
- spec/rt_tables
|
57
|
+
- spec/spec_helper.rb
|
58
|
+
- test/clear_rules.rb
|
59
|
+
homepage: http://www.ispunity.com
|
60
|
+
licenses: []
|
61
|
+
post_install_message:
|
62
|
+
rdoc_options: []
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ! '>='
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
requirements: []
|
78
|
+
rubyforge_project: ispunity
|
79
|
+
rubygems_version: 1.8.21
|
80
|
+
signing_key:
|
81
|
+
specification_version: 3
|
82
|
+
summary: IspUnity is a open source framework, build to integrate (load balance & failover)
|
83
|
+
multiple internet connections simultaneously
|
84
|
+
test_files:
|
85
|
+
- spec/config/sample.json
|
86
|
+
- spec/lib/isp_unity/route/route_spec.rb
|
87
|
+
- spec/lib/isp_unity/routing_table_spec.rb
|
88
|
+
- spec/lib/load_balance/load_balance_spec.rb
|
89
|
+
- spec/lib/route/route_spec.rb
|
90
|
+
- spec/lib/rule/rule_spec.rb
|
91
|
+
- spec/rt_tables
|
92
|
+
- spec/spec_helper.rb
|
93
|
+
- test/clear_rules.rb
|