netutils 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +4 -0
  7. data/README.md +36 -0
  8. data/Rakefile +6 -0
  9. data/bin/acl +109 -0
  10. data/bin/alaxala-deploy +271 -0
  11. data/bin/config-diff-check +111 -0
  12. data/bin/config-gets +64 -0
  13. data/bin/console +14 -0
  14. data/bin/host-locate-on-demand +102 -0
  15. data/bin/ipaddr-resolv +74 -0
  16. data/bin/ipaddr-resolv.sh +97 -0
  17. data/bin/mac-drop +84 -0
  18. data/bin/mac-nodrop +45 -0
  19. data/bin/port-shutdown +78 -0
  20. data/bin/setup +8 -0
  21. data/lib/netutils.rb +118 -0
  22. data/lib/netutils/arp.rb +28 -0
  23. data/lib/netutils/cli.rb +702 -0
  24. data/lib/netutils/cli/alaxala.rb +121 -0
  25. data/lib/netutils/cli/alaxala/interface.rb +137 -0
  26. data/lib/netutils/cli/alaxala/lldp.rb +166 -0
  27. data/lib/netutils/cli/alaxala/macfib.rb +62 -0
  28. data/lib/netutils/cli/alaxala/showarp.rb +51 -0
  29. data/lib/netutils/cli/alaxala/showroute.rb +86 -0
  30. data/lib/netutils/cli/alaxala/showvrf.rb +46 -0
  31. data/lib/netutils/cli/aruba.rb +15 -0
  32. data/lib/netutils/cli/cisco.rb +45 -0
  33. data/lib/netutils/cli/cisco/cdp.rb +117 -0
  34. data/lib/netutils/cli/cisco/ifsummary.rb +32 -0
  35. data/lib/netutils/cli/cisco/interface.rb +67 -0
  36. data/lib/netutils/cli/cisco/macfib.rb +38 -0
  37. data/lib/netutils/cli/cisco/showarp.rb +27 -0
  38. data/lib/netutils/cli/cisco/showinterface.rb +27 -0
  39. data/lib/netutils/cli/cisco/showroute.rb +73 -0
  40. data/lib/netutils/cli/cisco/showvrf.rb +45 -0
  41. data/lib/netutils/cli/nec.rb +20 -0
  42. data/lib/netutils/cli/nec/lldp.rb +16 -0
  43. data/lib/netutils/cli/paloalto.rb +21 -0
  44. data/lib/netutils/fsm.rb +43 -0
  45. data/lib/netutils/macaddr.rb +51 -0
  46. data/lib/netutils/oncequeue.rb +78 -0
  47. data/lib/netutils/parser.rb +30 -0
  48. data/lib/netutils/rib.rb +80 -0
  49. data/lib/netutils/switch.rb +402 -0
  50. data/lib/netutils/tunnel.rb +8 -0
  51. data/lib/netutils/version.rb +3 -0
  52. data/lib/netutils/vrf.rb +42 -0
  53. data/log/.gitignore +1 -0
  54. data/netutils.gemspec +33 -0
  55. metadata +195 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4337b8ba35a0b0febbea6e122cc64282245a10df86c7d8b6d52e8e45fb9dc4af
4
+ data.tar.gz: 59bbc51b9ccce2333fe8ada98787c341845a53b1b9ca78e71eb06c27cd26bfac
5
+ SHA512:
6
+ metadata.gz: 1b69938caa6c89a849ea1eed54b525243588ed4ebeafd92bfce7521802b0282abd5e3eb73477ee1fc74e100d2c885ee3f3a38eaa0e4bd8976644a17354597e43
7
+ data.tar.gz: c91e953d6776071026ea164cb483be97e7c6ec100ad27ee10e658b44e6edefeea63196d1d6bb71ca7ad3adfcfa462b0c73abc1642f7295236d7967d16dc6c15b
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
13
+
14
+ #
15
+ *.swp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.3
5
+ before_install: gem install bundler -v 1.14.3
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at ohmori@tottori-u.ac.jp. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in netutils.gemspec
4
+ gemspec
@@ -0,0 +1,36 @@
1
+ # Netutils
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/netutils`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'netutils'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install netutils
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ohmori7/netutils. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
36
+
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/acl ADDED
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.join(File.expand_path(File.dirname(__FILE__)).untaint, '/..')
3
+
4
+ require 'netutils'
5
+
6
+ ################################################################################
7
+ def usage(errmsg = nil)
8
+ progname = File.basename($0)
9
+ STDERR.print "ERROR: #{errmsg}\n\n" if errmsg
10
+ STDERR.print "\
11
+ Usage:
12
+ #{progname} -h
13
+ #{progname} [-d] (add|delete) <switch> <type> <name> <number> <address>
14
+ Description:
15
+ configure IP/MAC address filtering on a specified switch.
16
+ Arguments:
17
+ switch: an IP address of a switch.
18
+ type: access-list type. possible values are:
19
+ ip: IP address base
20
+ mac: MAC address base (for non IP packet only)
21
+ advance: MAC address base (Alaxala only)
22
+ name: access-list name.
23
+ number: a sequence number of an access list entry.
24
+ address: a MAC or IP address to be filtered.
25
+ Options:
26
+ -h: output this help message.
27
+ -d: dry run.
28
+ Example:
29
+ #{progname} add 192.168.0.1 advance INCIDENT-FILTER 999 dead.beef.dead
30
+ #{progname} delete 192.168.0.2 advance INCIDENT-FILTER 999 dead.beef.dead
31
+ "
32
+ exit 1
33
+ end
34
+
35
+ usage if ARGV[0] === '-h'
36
+ if ARGV[0] === '-d'
37
+ ARGV.shift
38
+ dry = true
39
+ end
40
+
41
+ case ARGV.size
42
+ when 6
43
+ else
44
+ usage("Wrong number (#{ARGV.size}) of arguments")
45
+ end
46
+
47
+ cmd = ARGV.shift
48
+ case cmd
49
+ when 'add'
50
+ add = true
51
+ when 'delete'
52
+ else
53
+ usage("Invalid command: #{cmd}")
54
+ end
55
+
56
+ swname = 'unknown'
57
+ ia = ARGV.shift
58
+ type = ARGV.shift
59
+ name = ARGV.shift
60
+ seq = ARGV.shift.to_i
61
+ addr = ARGV.shift
62
+
63
+ usage("Invalid IP address format: #{ia}") if ia !~ /^[0-9\.]+$/
64
+ # we assume that max. sequence # is used for ``permit any any''
65
+ usage if seq >= ACL_MAX_SEQ
66
+
67
+ begin
68
+ log_without_newline "#{cmd} a filter for #{addr} on #{ia}... "
69
+ sw = Switch.new(nil, Switch::Type::ROUTER, ia)
70
+ sw.login
71
+ swname = sw.name
72
+ if ! sw.acl_exists?(type, name)
73
+ raise(ArgumentError, "No such ACL found: #{type} #{name}")
74
+ end
75
+ if dry
76
+ log_without_newline "(skip due to dry run)... "
77
+ elsif add
78
+ sw.acl_add(type, name, addr, seq)
79
+ else
80
+ sw.acl_delete(type, name, seq)
81
+ end
82
+ log 'done'
83
+ if add
84
+ m = "please run below command on recovery:\n"
85
+ s = File.expand_path(__FILE__)
86
+ m += "\t#{s} delete #{ia} #{type} #{name} #{seq} #{addr}\n"
87
+ puts m
88
+ else
89
+ m = "Allow traffic from #{addr} on #{swname}\n"
90
+ end
91
+ exitcode = 0
92
+ rescue => e
93
+ r = ' FAILED'
94
+ m = e.to_s
95
+ puts "\n#{r}: #{m}"
96
+ exitcode = 1
97
+ end
98
+
99
+ #
100
+ m += <<EOL
101
+
102
+ log:
103
+ #{log_buffer}
104
+ EOL
105
+
106
+ #
107
+ mail "Filter #{cmd.upcase}#{r}: #{addr} on #{swname} (#{ia})", m
108
+
109
+ exit exitcode
@@ -0,0 +1,271 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.join(File.expand_path(File.dirname(__FILE__)).untaint, '/..')
3
+ #
4
+ require 'io/console' # Ruby 1.9.3 or later
5
+ require 'time'
6
+ require 'thread'
7
+ require 'optparse'
8
+ require 'netutils'
9
+
10
+ #
11
+ PATH = '/home/conf/net/certs'
12
+ CERT = "#{WEBAUTH_HOST}.cer"
13
+ KEY = "#{WEBAUTH_HOST}.key"
14
+ INT = 'nii-odca3sha2.cer'
15
+ CERTFILES = [
16
+ CERT,
17
+ KEY,
18
+ INT
19
+ ]
20
+ #
21
+ HTML = '/home/conf/net/html/wired'
22
+ HTMLFILES = [
23
+ 'favicon.ico',
24
+ 'login.html',
25
+ 'loginNG.html',
26
+ 'loginOK.html',
27
+ 'loginProcess.html',
28
+ 'logout.html',
29
+ 'logoutNG.html',
30
+ 'logoutOK.html',
31
+ 'webauth.msg'
32
+ ]
33
+ HTMLDIR = 'html' # a directory on a switch for HTML files
34
+ #
35
+ def usage(errmsg = nil)
36
+ progname = File.basename($0)
37
+ STDERR.print "ERROR: #{errmsg}\n\n" if errmsg
38
+ STDERR.print "\
39
+ Usage:
40
+ #{progname} -h
41
+ #{progname} [-c] [-w] [-r] -a
42
+ #{progname} [-c] [-w] [-r] <switch IP address1> <switch IP address2> ...
43
+ Description:
44
+ deploy files to Alaxala switches, such as certificate files (i.e.,
45
+ certificate itself, private key, intermediate CA certificate), HTML
46
+ files for Web authentication.
47
+ If an option, ``-a,'' is given, deploy to all switches using LLDP or
48
+ CDP. All files should be placed into the FTP server,
49
+ #{FTP_SERVER}:#{PATH} (for certificate files),
50
+ #{FTP_SERVER}:#{HTML} (for HTML files),
51
+ in advance.
52
+ Arguments:
53
+ switch IP address: an IP address of a switch.
54
+ Options:
55
+ -h: output this help message.
56
+ -c: deploy certificate files.
57
+ -w: deploy HTML files.
58
+ -r: reload a switch if necessary (only for certificate files).
59
+ -a: deploy to all switches.
60
+ Example:
61
+ output information:
62
+ #{progname} 192.168.0.1
63
+ #{progname} -a
64
+ installing certificate files:
65
+ #{progname} -c 192.168.0.1
66
+ #{progname} -c -a
67
+ installing certificate and HTML files:
68
+ #{progname} -c -w 192.168.0.1
69
+ #{progname} -c -w -a
70
+ reload switches if and only if necessary (only for certificate files):
71
+ #{progname} -r 192.168.0.1
72
+ #{progname} -r -a
73
+ "
74
+ exit 1
75
+ end
76
+
77
+ ##
78
+ # inject() requires Ruby2.4... take a more operational way.
79
+ options0 = ARGV.getopts('hcwra', 'help', 'certificate', 'web', 'reload', 'all')
80
+ options = {}
81
+ options0.map { |k, v| options[k.to_sym] = v }
82
+
83
+ usage if options[:h]
84
+ if options[:a]
85
+ if ARGV.length != 0
86
+ usage('Extra argument specified')
87
+ end
88
+ Switch.set_retrieve_all
89
+ SWITCHES.each { |name, ia| Switch.new(name, Switch::Type::ROUTER, ia, ) }
90
+ elsif ARGV.length > 0
91
+ ARGV.each do |ia|
92
+ Switch.new(nil, Switch::Type::ROUTER, ia)
93
+ end
94
+ else
95
+ usage('No IP address is given.')
96
+ end
97
+
98
+ ##
99
+ user = nil
100
+ password = nil
101
+ if options[:c] || options[:w]
102
+ print 'Input FTP user name: '
103
+ user = STDIN.gets.strip
104
+ print 'Input FTP password: '
105
+ password = STDIN.noecho(&:gets).strip
106
+ puts
107
+ end
108
+
109
+ ##
110
+ reboots = Queue.new
111
+ Switch.retrieve do |sw|
112
+ if sw.name
113
+ print "Connecting: ``#{sw.name}'' (#{sw.ia})\n"
114
+ else
115
+ print "Connecting: #{sw.ia}\n"
116
+ end
117
+ sw.login
118
+ msg = " Connected: ``#{sw.name}'' (#{sw.ia}) (#{sw.maker_to_s} " +
119
+ "#{sw.product})"
120
+ if sw.maker != CLI::Maker::ALAXALA
121
+ puts "#{msg} SKIP non-Alaxala equipment."
122
+ next
123
+ end
124
+ config = sw.config_get
125
+ if config !~ /web-authentication system-auth-control/m
126
+ puts "#{msg} SKIP no Web authentication configured."
127
+ next
128
+ end
129
+ puts msg
130
+ r = sw.cmd('show web-authentication ssl-crt')
131
+ # SSL key : default now
132
+ # SSL certificate : 2018/04/03 20:04:11
133
+ # SSL intermediate cert : 2018/04/03 20:04:11
134
+ sep = ''
135
+ installedtime = nil
136
+ msg = " #{sw.name} (#{sw.ia}): CERT:"
137
+ r.scan(/SSL ([^:]*) : ([^\n]+)/) do |k, v|
138
+ k.strip!
139
+ v.strip!
140
+ if v =~ /^default/
141
+ v = 'none'
142
+ elsif installedtime === nil
143
+ installedtime = Time.parse(v)
144
+ end
145
+ msg += "#{sep} #{k}: #{v}"
146
+ sep = ','
147
+ end
148
+ r = sw.cmd('show system')
149
+ if r =~ /^.*Boot Date[^:]+: ([^\n]+).*$/
150
+ v = $1.strip
151
+ boottime = Time.parse(v)
152
+ msg += ", boot: #{v}"
153
+ if boottime < installedtime || options[:c]
154
+ reboots.push(sw)
155
+ msg += ' (need reboot)'
156
+ end
157
+ end
158
+ puts msg
159
+
160
+ #
161
+ r = sw.cmd('show web-authentication html-files')
162
+ sep = ''
163
+ msg = " #{sw.name} (#{sw.ia}): HTML:"
164
+ r.scan(/^ +([0-9\/]+ [0-9:]+) + ([0-9,]+) ([^\n]+)/) do |date, size, f|
165
+ date.strip!
166
+ size.strip!
167
+ f.strip!
168
+ msg += "#{sep} #{f} #{size} (#{date})"
169
+ sep = ','
170
+ end
171
+ puts msg
172
+
173
+ next if ! options[:c] && ! options[:w]
174
+
175
+ oprompt = sw.prompt
176
+ sw.cmd("ftp #{FTP_SERVER}", 'Name: ')
177
+ sw.cmd(user, 'Password:')
178
+ r = sw.cmd(password, "ftp> |#{oprompt}")
179
+ if r =~ /530 Login incorrect./
180
+ raise('Invalid FTP password')
181
+ end
182
+ r = sw.cmd('passive')
183
+ r += sw.cmd('bin')
184
+ if options[:c]
185
+ r += sw.cmd("cd #{PATH}")
186
+ CERTFILES.each { |f| r += sw.cmd("get #{f}") }
187
+ if r =~ /Failed/
188
+ raise('cannot get certificate files')
189
+ end
190
+ end
191
+ htmlfiles = nil
192
+ if options[:w]
193
+ r = sw.cmd("cd #{HTML}")
194
+ r += sw.cmd('mget *', 'mget.*\? ?')
195
+ r += sw.cmd('a', 'ftp> ')
196
+ if r =~ /Failed/
197
+ raise('cannot get html files')
198
+ end
199
+ htmlfiles = r.scan(/nnection for ([^ ]+) /).collect { |a| a[0] }
200
+ HTMLFILES.each do |f|
201
+ next if htmlfiles.include?(f)
202
+ raise("missing HTML file: #{f}")
203
+ end
204
+ end
205
+ sw.cmd('exit', oprompt)
206
+ if options[:c]
207
+ sw.cmd('set web-authentication ssl-crt', '[^:]+: ')
208
+ sw.cmd(KEY)
209
+ sw.cmd(CERT)
210
+ sw.cmd(INT, '[^:]+:')
211
+ sw.cmd('y', oprompt)
212
+ CERTFILES.each { |f| sw.cmd("del ramdisk #{f}") }
213
+ end
214
+ if options[:w]
215
+ #
216
+ # here create a directory and move files in order to avoid that
217
+ # unnecessary files are loaded into HTML files area.
218
+ #
219
+ sw.cmd("mkdir ramdisk #{HTMLDIR}")
220
+ htmlfiles.each do |f|
221
+ # they do not have ``move''...sign...
222
+ sw.cmd("copy ramdisk #{f} ramdisk #{HTMLDIR}")
223
+ sw.cmd("del ramdisk #{f}")
224
+ end
225
+
226
+ sw.cmd("set web-authentication html-files ramdisk #{HTMLDIR}",
227
+ '[^:]+: ')
228
+ # Do you wish to install new html-files? (y/n): y
229
+ sw.cmd('y', oprompt)
230
+
231
+ # okay remove our files.
232
+ htmlfiles.each do |f|
233
+ sw.cmd("del ramdisk #{HTMLDIR}/#{f}")
234
+ end
235
+ sw.cmd("rmdir ramdisk #{HTMLDIR}")
236
+ end
237
+ print " Done: ``#{sw.name}'' (#{sw.ia}) " +
238
+ "(#{sw.maker_to_s} #{sw.product})\n"
239
+ end
240
+ Switch.warn
241
+
242
+ exit if ! options[:r]
243
+
244
+ thread_concurrency = 64
245
+ threads = []
246
+ for i in 1..thread_concurrency do
247
+ threads <<= Thread.new do
248
+ begin
249
+ while sw = reboots.pop(true) do
250
+ sw.configure
251
+ sw.cmd('save')
252
+ sw.unconfigure
253
+ begin
254
+ #
255
+ # note that pager configuration or
256
+ # other configurations barks without
257
+ # an option, ``-f.''
258
+ #
259
+ sw.cmd('reload -f')
260
+ rescue
261
+ end
262
+ puts " Reboot: ``#{sw.name}'' (#{sw.ia}) done"
263
+ end
264
+ rescue
265
+ end
266
+ end
267
+ end
268
+
269
+ threads.each do |thread|
270
+ thread.join
271
+ end