netutils 0.1.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.
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