netutils 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/README.md +36 -0
- data/Rakefile +6 -0
- data/bin/acl +109 -0
- data/bin/alaxala-deploy +271 -0
- data/bin/config-diff-check +111 -0
- data/bin/config-gets +64 -0
- data/bin/console +14 -0
- data/bin/host-locate-on-demand +102 -0
- data/bin/ipaddr-resolv +74 -0
- data/bin/ipaddr-resolv.sh +97 -0
- data/bin/mac-drop +84 -0
- data/bin/mac-nodrop +45 -0
- data/bin/port-shutdown +78 -0
- data/bin/setup +8 -0
- data/lib/netutils.rb +118 -0
- data/lib/netutils/arp.rb +28 -0
- data/lib/netutils/cli.rb +702 -0
- data/lib/netutils/cli/alaxala.rb +121 -0
- data/lib/netutils/cli/alaxala/interface.rb +137 -0
- data/lib/netutils/cli/alaxala/lldp.rb +166 -0
- data/lib/netutils/cli/alaxala/macfib.rb +62 -0
- data/lib/netutils/cli/alaxala/showarp.rb +51 -0
- data/lib/netutils/cli/alaxala/showroute.rb +86 -0
- data/lib/netutils/cli/alaxala/showvrf.rb +46 -0
- data/lib/netutils/cli/aruba.rb +15 -0
- data/lib/netutils/cli/cisco.rb +45 -0
- data/lib/netutils/cli/cisco/cdp.rb +117 -0
- data/lib/netutils/cli/cisco/ifsummary.rb +32 -0
- data/lib/netutils/cli/cisco/interface.rb +67 -0
- data/lib/netutils/cli/cisco/macfib.rb +38 -0
- data/lib/netutils/cli/cisco/showarp.rb +27 -0
- data/lib/netutils/cli/cisco/showinterface.rb +27 -0
- data/lib/netutils/cli/cisco/showroute.rb +73 -0
- data/lib/netutils/cli/cisco/showvrf.rb +45 -0
- data/lib/netutils/cli/nec.rb +20 -0
- data/lib/netutils/cli/nec/lldp.rb +16 -0
- data/lib/netutils/cli/paloalto.rb +21 -0
- data/lib/netutils/fsm.rb +43 -0
- data/lib/netutils/macaddr.rb +51 -0
- data/lib/netutils/oncequeue.rb +78 -0
- data/lib/netutils/parser.rb +30 -0
- data/lib/netutils/rib.rb +80 -0
- data/lib/netutils/switch.rb +402 -0
- data/lib/netutils/tunnel.rb +8 -0
- data/lib/netutils/version.rb +3 -0
- data/lib/netutils/vrf.rb +42 -0
- data/log/.gitignore +1 -0
- data/netutils.gemspec +33 -0
- metadata +195 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'netutils/parser'
|
2
|
+
require 'netutils/macaddr'
|
3
|
+
|
4
|
+
module Cisco
|
5
|
+
|
6
|
+
class MACFIB < Parser
|
7
|
+
attr_reader :ports
|
8
|
+
|
9
|
+
# XXX
|
10
|
+
# * 2005 082e.5f24.56a9 dynamic Yes 0 Po19
|
11
|
+
CISCO6500_RE = /^\* +[0-9]+ +[^ ]+ +dynamic +Yes +[0-9]+ +([^ ]+)$/
|
12
|
+
# 3188 f80f.41d2.e746 dynamic ip,(cut),other TenGigabitEthernet1/1
|
13
|
+
CISCO4500_RE = /^ *[0-9]+ +[^ ]+ +dynamic +ip[^ ]+ +([^ ]+) +$/
|
14
|
+
# 100 0016.c8c5.35a2 DYNAMIC Po1
|
15
|
+
CISCO2500_RE = /^ *[0-9]+ +[^ ]+ +(?:STATIC|DYNAMIC) +([^ ]+).*$/
|
16
|
+
|
17
|
+
def cmd(ma, vlan)
|
18
|
+
return "show mac address-table address #{ma.to_s} vlan #{vlan}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(sw)
|
22
|
+
@ports = {}
|
23
|
+
super()
|
24
|
+
add('Init', :init)
|
25
|
+
@sw = sw
|
26
|
+
end
|
27
|
+
|
28
|
+
def init(l, m)
|
29
|
+
case l
|
30
|
+
# XXX: other switches...
|
31
|
+
when CISCO6500_RE, CISCO4500_RE, CISCO2500_RE
|
32
|
+
name = @sw.ports.key($1)
|
33
|
+
@ports[name] = name
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'netutils/parser'
|
2
|
+
require 'netutils/arp'
|
3
|
+
|
4
|
+
module Cisco
|
5
|
+
|
6
|
+
class ShowARP < Parser
|
7
|
+
attr_reader :arps
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@arps = ARPTable.new
|
11
|
+
super()
|
12
|
+
add('Init', :init)
|
13
|
+
# Protocol Address Age (min) Hardware Addr Type Interface
|
14
|
+
# Internet 192.168.0.1 3 dead.beef.dead ARPA Vlan9999
|
15
|
+
add('Entry', :entry, /^Internet +([^ ]+) +([0-9]+|-) +([^ ]+) +ARPA+ +([^ ]+)$/)
|
16
|
+
end
|
17
|
+
|
18
|
+
def init(l, m)
|
19
|
+
changeto('Entry') if l =~ /^Protocol/
|
20
|
+
end
|
21
|
+
|
22
|
+
def entry(l, m)
|
23
|
+
@arps.add(m[1], m[3], m[4], m[2] === '-')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'netutils/parser'
|
2
|
+
require 'netutils/tunnel'
|
3
|
+
|
4
|
+
module Cisco
|
5
|
+
|
6
|
+
class ShowInterface < Parser
|
7
|
+
attr_reader :tunnel
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
super()
|
11
|
+
add('Init', :init)
|
12
|
+
add('Done', :done)
|
13
|
+
end
|
14
|
+
|
15
|
+
def init(l, m)
|
16
|
+
# Tunnel source 192.168.0.1 (Dialer1), destination 192.168.0.2
|
17
|
+
if l =~ /^ Tunnel source ([^ ]+) [^,]+, destination ([^ ]+)/
|
18
|
+
@tunnel = Tunnel.new($1, $2)
|
19
|
+
changeto('Done')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def done(l, m)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'netutils/parser'
|
2
|
+
require 'netutils/rib'
|
3
|
+
|
4
|
+
module Cisco
|
5
|
+
|
6
|
+
class ShowRoute < Parser
|
7
|
+
attr_reader :rib
|
8
|
+
|
9
|
+
def cmd(ia)
|
10
|
+
"show ip route vrf \* #{ia}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@rib = RIB.new
|
15
|
+
super
|
16
|
+
# % Network not in table
|
17
|
+
# Routing entry for 192.168.0.0/24
|
18
|
+
add('Init', :init)
|
19
|
+
# Known via "connected", distance 0, metric 0 (connected, via interface)
|
20
|
+
add('Protocol', :protocol, / Known via "([^"]+)",.*$/)
|
21
|
+
add('Descriptor', :descriptor)
|
22
|
+
# * 192.168.0.200
|
23
|
+
# * directly connected, via Vlan4000
|
24
|
+
# * 192.168.0.1, from 192.168.0.1, 00:00:19 ago, via Vlan9999
|
25
|
+
add('Nexthop', :nexthop, /^ \* ([^ ,]+)(?:,? .*, via ([^ ]+)|)$/)
|
26
|
+
# Route metric is 0, traffic share count is 1
|
27
|
+
add('Metric', :metric, /^ Route metric is .*$/)
|
28
|
+
end
|
29
|
+
|
30
|
+
def init(l, m)
|
31
|
+
return if l =~ /^% .* not in table/
|
32
|
+
return if l =~ /^$/
|
33
|
+
if l !~ /^Routing entry for ([0-9\.\/]+)(?:, supernet)?$/
|
34
|
+
raise "Invalid format: #{l}"
|
35
|
+
end
|
36
|
+
@dst = $1
|
37
|
+
changeto('Protocol')
|
38
|
+
end
|
39
|
+
|
40
|
+
def protocol(l, m)
|
41
|
+
@protocol = m[1]
|
42
|
+
changeto('Descriptor')
|
43
|
+
end
|
44
|
+
|
45
|
+
def descriptor(l, m)
|
46
|
+
# Routing Descriptor Blocks:
|
47
|
+
case l
|
48
|
+
when /^ Routing Descriptor Blocks:$/
|
49
|
+
changeto('Nexthop')
|
50
|
+
when /^ Redistributing via /, /^ Advertised by /
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def nexthop(l, m)
|
55
|
+
case m[1]
|
56
|
+
when 'directly'
|
57
|
+
@nh = nil
|
58
|
+
when /[0-9\.\/]+/
|
59
|
+
@nh = m[1]
|
60
|
+
else
|
61
|
+
raise "Invalid format: #{l}"
|
62
|
+
end
|
63
|
+
@interface = m[2]
|
64
|
+
changeto('Metric')
|
65
|
+
end
|
66
|
+
|
67
|
+
def metric(l, m)
|
68
|
+
@rib.add(@protocol, @dst, @nh, @interface)
|
69
|
+
changeto('Init')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'netutils/parser'
|
2
|
+
require 'netutils/vrf'
|
3
|
+
|
4
|
+
module Cisco
|
5
|
+
|
6
|
+
class ShowVRF < Parser
|
7
|
+
attr_reader :vrfs
|
8
|
+
|
9
|
+
def cmd
|
10
|
+
return 'show vrf'
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
super()
|
15
|
+
@vrfs = VRFTable.new
|
16
|
+
add('Init', :init)
|
17
|
+
add('VRF', :vrf)
|
18
|
+
add('Interface', :interface)
|
19
|
+
end
|
20
|
+
|
21
|
+
def init(l, m)
|
22
|
+
return if l !~ /^ +Name +Default RD +Protocols +Interfaces$/
|
23
|
+
changeto('VRF')
|
24
|
+
end
|
25
|
+
|
26
|
+
def vrf(l, m)
|
27
|
+
if l !~ /^ *([^ ]+) +([^ ]+|<not set>) +[^ ]+ +([^ ]+) *$/ &&
|
28
|
+
l !~ /^ *([^ ]+) +([^ ]+|<not set>) +[^ ]+ *$/
|
29
|
+
raise(ArgumentError, "Invalid line: \"#{l}\"")
|
30
|
+
end
|
31
|
+
@vrf = vrfs.add($1, $2)
|
32
|
+
@vrf.interface_add($3) if $3
|
33
|
+
changeto('Interface')
|
34
|
+
end
|
35
|
+
|
36
|
+
def interface(l, m)
|
37
|
+
if l =~ /^ +([^ ]+) *$/
|
38
|
+
@vrf.interface_add(m[1])
|
39
|
+
else
|
40
|
+
vrf(l, nil)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'netutils/cli/nec/lldp'
|
2
|
+
|
3
|
+
module NEC
|
4
|
+
CONFIG_RE = /^(.*\n)$/m
|
5
|
+
|
6
|
+
def disable_logging_console
|
7
|
+
# XXX
|
8
|
+
end
|
9
|
+
|
10
|
+
def enable
|
11
|
+
end
|
12
|
+
|
13
|
+
def show_running_config
|
14
|
+
return cmd('show running-config')
|
15
|
+
end
|
16
|
+
|
17
|
+
def interface_gets(sw)
|
18
|
+
# XXX
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Paloalto
|
2
|
+
CONFIG_RE = /^(config {\n(?:[^\n]+\n){1,}}\n)\n\Z/
|
3
|
+
|
4
|
+
def disable_logging_console
|
5
|
+
# XXX
|
6
|
+
end
|
7
|
+
|
8
|
+
def enable
|
9
|
+
end
|
10
|
+
|
11
|
+
def disable
|
12
|
+
end
|
13
|
+
|
14
|
+
def show_running_config
|
15
|
+
return cmd('show config running')
|
16
|
+
end
|
17
|
+
|
18
|
+
def interface_gets(sw)
|
19
|
+
# XXX
|
20
|
+
end
|
21
|
+
end
|
data/lib/netutils/fsm.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
class FSM
|
2
|
+
class State
|
3
|
+
attr_reader :cb
|
4
|
+
|
5
|
+
def initialize(cb)
|
6
|
+
@cb = cb
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
FSM_S_INIT = 0
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@state = FSM_S_INIT
|
14
|
+
@fsm = Array.new
|
15
|
+
@name2index = Hash.new
|
16
|
+
@index2name = Array.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def add(name, cb)
|
20
|
+
if @name2index.key?(name)
|
21
|
+
raise(ArgumentError, "duplicated key \"#{name}\"")
|
22
|
+
end
|
23
|
+
@fsm.push(State.new(cb))
|
24
|
+
idx = @fsm.length - 1
|
25
|
+
@name2index[name] = idx
|
26
|
+
@index2name[idx] = name
|
27
|
+
end
|
28
|
+
|
29
|
+
def cb
|
30
|
+
return @fsm[@state].cb
|
31
|
+
end
|
32
|
+
|
33
|
+
def changeto(name)
|
34
|
+
if ! @name2index.key?(name)
|
35
|
+
raise(ArgumentError, "unnown state: \"#{name}\"")
|
36
|
+
end
|
37
|
+
@state = @name2index[name]
|
38
|
+
end
|
39
|
+
|
40
|
+
def state_name
|
41
|
+
return @index2name[@state]
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
class MACAddr
|
2
|
+
NBBY = 8
|
3
|
+
Length = 6
|
4
|
+
|
5
|
+
def initialize(s)
|
6
|
+
s = s.delete('-.:')
|
7
|
+
raise if s =~ /[^0-9a-z]/i # XXX EINVAL
|
8
|
+
v = s.hex
|
9
|
+
raise if v > 0xffffffffffff # XXX ERANGE
|
10
|
+
@addr = v
|
11
|
+
end
|
12
|
+
|
13
|
+
def [](n, len)
|
14
|
+
raise if len > Length
|
15
|
+
raise if Length % len != 0
|
16
|
+
n *= len
|
17
|
+
v = 0
|
18
|
+
off = 0
|
19
|
+
while off < len do
|
20
|
+
v <<= NBBY
|
21
|
+
v |= (@addr >> (NBBY * ((Length - 1) - n - off))) & 0xff
|
22
|
+
off += 1
|
23
|
+
end
|
24
|
+
return v
|
25
|
+
end
|
26
|
+
private :[]
|
27
|
+
|
28
|
+
def to_a(len = 1)
|
29
|
+
a = Array.new
|
30
|
+
max = Length / len
|
31
|
+
for n in 0 .. max - 1 do
|
32
|
+
a.push(self[n, len])
|
33
|
+
end
|
34
|
+
return a
|
35
|
+
end
|
36
|
+
private :to_a
|
37
|
+
|
38
|
+
def to_s(sep = '.', step = 2)
|
39
|
+
to_a(step).map { |v| sprintf('%0*x', step * 2, v) }.join(sep)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# XXX: test
|
44
|
+
#x = MACAddr.new('aabb.ccdd.eeff')
|
45
|
+
#x.to_s == 'aa:bb:cc:dd:ee:ff'
|
46
|
+
#x.to_s('.') == 'aa.bb.cc.dd.ee.ff'
|
47
|
+
#x.to_s('.', 2) == 'aabb.ccdd.eeff'
|
48
|
+
#x.to_s('.', 3) == 'aabbcc.ddeeff'
|
49
|
+
#x.to_s('.', 6) == 'aabbccddeeff'
|
50
|
+
#x.to_s('.', 4) != 'aabbccddeeff'
|
51
|
+
#x.to_s('.', 7) != 'aabbccddeeff'
|
@@ -0,0 +1,78 @@
|
|
1
|
+
class OnceQueue
|
2
|
+
def initialize
|
3
|
+
@element = []
|
4
|
+
@queue = []
|
5
|
+
@mutex = Thread::Mutex.new
|
6
|
+
@cond = Thread::ConditionVariable.new
|
7
|
+
@empty = Thread::ConditionVariable.new
|
8
|
+
@processing = 0
|
9
|
+
@total = 0
|
10
|
+
@errors = 0
|
11
|
+
end
|
12
|
+
|
13
|
+
def __count
|
14
|
+
@queue.size + @processing
|
15
|
+
end
|
16
|
+
private :__count
|
17
|
+
|
18
|
+
def count
|
19
|
+
@mutex.synchronize do
|
20
|
+
__count
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def total
|
25
|
+
@mutex.synchronize do
|
26
|
+
@total
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def errors
|
31
|
+
@mutex.synchronize do
|
32
|
+
@errors
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def enqueue(v)
|
37
|
+
@mutex.synchronize do
|
38
|
+
break if @element.include?(v)
|
39
|
+
@element.push(v)
|
40
|
+
@queue.push(v)
|
41
|
+
@cond.signal
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def dequeue
|
46
|
+
@mutex.synchronize do
|
47
|
+
@cond.wait(@mutex) while @queue.empty?
|
48
|
+
@processing += 1
|
49
|
+
@queue.shift
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def done(v)
|
54
|
+
@mutex.synchronize do
|
55
|
+
@processing -= 1
|
56
|
+
@empty.signal if __count === 0
|
57
|
+
@total += 1
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def error
|
62
|
+
@mutex.synchronize do
|
63
|
+
@errors += 1
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def synchronize
|
68
|
+
@mutex.synchronize do
|
69
|
+
yield
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def wait_all
|
74
|
+
@mutex.synchronize do
|
75
|
+
@empty.wait(@mutex) if __count > 0
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|