Class: CLI
- Inherits:
-
Object
- Object
- CLI
- Defined in:
- lib/netutils/cli.rb
Defined Under Namespace
Modules: Maker
Constant Summary collapse
- FIRST_PROMPT_RE =
/^.*\n+\(?!?([^\r\n\(\)\s>#]+)\)? ?([>#]) ?\r?\n?.*$/m
- TIMEOUT =
30
- LOGIN_TIMEOUT =
3
- PRODUCT_DETECTION_MAXRETRIES =
3
Instance Attribute Summary collapse
-
#enable_passwds ⇒ Object
readonly
Returns the value of attribute enable_passwds.
-
#ia ⇒ Object
readonly
Returns the value of attribute ia.
-
#maker ⇒ Object
readonly
Returns the value of attribute maker.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#passwds ⇒ Object
readonly
Returns the value of attribute passwds.
-
#product ⇒ Object
readonly
Returns the value of attribute product.
-
#prompt ⇒ Object
readonly
Returns the value of attribute prompt.
-
#users ⇒ Object
readonly
Returns the value of attribute users.
Instance Method Summary collapse
- #acl_add(type, name, addr, seq = nil) ⇒ Object
- #acl_delete(type, name, seq) ⇒ Object
- #acl_exists?(type, name) ⇒ Boolean
- #arp_resolve(ia, vrf) ⇒ Object
- #cmd(s, nextprompt = nil, ignoreerror = false) ⇒ Object
- #config_get ⇒ Object
- #configure ⇒ Object
- #enable ⇒ Object
- #error?(r) ⇒ Boolean
-
#initialize(name, ia, types = CLI_SESSION_TYPES, maker = Maker::UNKNOWN) ⇒ CLI
constructor
A new instance of CLI.
- #interface_gets(sw) ⇒ Object
- #interface_name(port) ⇒ Object
- #interface_name_cli(port) ⇒ Object
- #interface_noshutdown(port) ⇒ Object
- #interface_shutdown(port) ⇒ Object
- #login ⇒ Object
- #logout ⇒ Object
- #mac_address_table_get(sw, ma, vlan) ⇒ Object
- #maker_to_s ⇒ Object
- #name_update(name) ⇒ Object
- #neighbor_gets(sw, port = nil) ⇒ Object
- #no(re = nil) ⇒ Object
- #pager_disable_wlc ⇒ Object
- #route_gets(ia) ⇒ Object
- #unconfigure ⇒ Object
- #vrf_gets ⇒ Object
- #yes(re = nil) ⇒ Object
Constructor Details
#initialize(name, ia, types = CLI_SESSION_TYPES, maker = Maker::UNKNOWN) ⇒ CLI
Returns a new instance of CLI.
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/netutils/cli.rb', line 46 def initialize(name, ia, types = CLI_SESSION_TYPES, maker = Maker::UNKNOWN) @ia = ia @users = USERS.dup @passwds = PASSWORDS.dup @enable_passwds = ENABLES.dup @enabled = false @type = nil @types = types @session = nil @maker = maker @product = nil @cr = '' @name_supplied = name name_update(nil) @userprompt = [ 'login:', # Alaxala '[Uu]sername:', # Cisco 'User:' # Cisco WiSM/WLC ] # Cisco has trailing space, ``Password: '', but Alaxala not @passwdprompt = 'Password:' @telnetopt = Hash.new @telnetopt['Timeout' ] = TIMEOUT if defined?(LOGDIR) path = File.dirname(__FILE__) path += "/../../" path += "/#{LOGDIR}/#{ia}.log" path = File.(path).untaint @telnetopt['Output_log'] = path end #@telnetopt['Dump_log'] = '/dev/stdout' end |
Instance Attribute Details
#enable_passwds ⇒ Object (readonly)
Returns the value of attribute enable_passwds.
43 44 45 |
# File 'lib/netutils/cli.rb', line 43 def enable_passwds @enable_passwds end |
#ia ⇒ Object (readonly)
Returns the value of attribute ia.
43 44 45 |
# File 'lib/netutils/cli.rb', line 43 def ia @ia end |
#maker ⇒ Object (readonly)
Returns the value of attribute maker.
43 44 45 |
# File 'lib/netutils/cli.rb', line 43 def maker @maker end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
43 44 45 |
# File 'lib/netutils/cli.rb', line 43 def name @name end |
#passwds ⇒ Object (readonly)
Returns the value of attribute passwds.
43 44 45 |
# File 'lib/netutils/cli.rb', line 43 def passwds @passwds end |
#product ⇒ Object (readonly)
Returns the value of attribute product.
43 44 45 |
# File 'lib/netutils/cli.rb', line 43 def product @product end |
#prompt ⇒ Object (readonly)
Returns the value of attribute prompt.
43 44 45 |
# File 'lib/netutils/cli.rb', line 43 def prompt @prompt end |
#users ⇒ Object (readonly)
Returns the value of attribute users.
43 44 45 |
# File 'lib/netutils/cli.rb', line 43 def users @users end |
Instance Method Details
#acl_add(type, name, addr, seq = nil) ⇒ Object
657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 |
# File 'lib/netutils/cli.rb', line 657 def acl_add(type, name, addr, seq = nil) case type when 'ip' # XXX: we may need sanity check. when 'mac', 'advance' addr = MACAddr.new(addr) else raise("Unknown ACL type: #type") end cmd = acl_type_to_cmd(type) configure cmd(acl_definition(type, name)) cmd("#{seq} deny #{cmd} host #{addr} any") unconfigure end |
#acl_delete(type, name, seq) ⇒ Object
673 674 675 676 677 678 |
# File 'lib/netutils/cli.rb', line 673 def acl_delete(type, name, seq) configure cmd(acl_definition(type, name)) cmd("no #{seq}") unconfigure end |
#acl_exists?(type, name) ⇒ Boolean
650 651 652 653 654 655 |
# File 'lib/netutils/cli.rb', line 650 def acl_exists?(type, name) configure filters = cmd("show #{acl_definition(type, name)}") unconfigure ! filters.empty? end |
#arp_resolve(ia, vrf) ⇒ Object
600 601 602 603 604 605 606 607 608 609 |
# File 'lib/netutils/cli.rb', line 600 def arp_resolve(ia, vrf) if vrf.name == 'default' output = cmd("show ip arp #{ia}") else output = cmd("show ip arp vrf #{vrf.name} #{ia}") end a = _new(:ShowARP) a.parse(output) return a.arps[ia] end |
#cmd(s, nextprompt = nil, ignoreerror = false) ⇒ Object
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
# File 'lib/netutils/cli.rb', line 215 def cmd(s, nextprompt = nil, ignoreerror = false) re = [ @prompt ] re.push('#') if @maker == Maker::UNKNOWN # XXX dirty hack for now... re.push(nextprompt) if nextprompt re = '(?:' + re.join('|') + ')' r = @session.cmd('String' => s + @cr, 'Match' => /#{re}\Z/) r = handle_control_characters(r) # # XXX: allows a command not to be echo-ed like FTP server. # if r !~ /^#{re}?(?:#{s.sub('*', '\\*')})?\n+(.*)#{re}\Z/m raise(ArgumentError, "CLI output error: \"#{r}\"") end r = $1 r.slice!(-1) if @maker === Maker::ALAXALA && r[-1] === '!' if ignoreerror === false && error?(r) raise(ArgumentError, "Command failed on #{@name}: #{s}: #{r}") end @prompt = nextprompt if nextprompt return r end |
#config_get ⇒ Object
568 569 570 571 572 573 574 575 |
# File 'lib/netutils/cli.rb', line 568 def config_get enable re = Module.const_get(maker_to_s).const_get('CONFIG_RE') if show_running_config !~ re raise("Invalid configuration format for #{@name}") end return $1 end |
#configure ⇒ Object
557 558 559 560 561 |
# File 'lib/netutils/cli.rb', line 557 def configure raise "already configuring" if @prompt == @configprompt enable return cmd('configure terminal', @configprompt) end |
#enable ⇒ Object
550 551 552 553 554 555 |
# File 'lib/netutils/cli.rb', line 550 def enable return if @enabled passwd(nil, @enable_passwds.dup, @enable_passwds.dup, @enableprompt.dup, 'enable') @enabled = true end |
#error?(r) ⇒ Boolean
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/netutils/cli.rb', line 189 def error?(r) case r when /%[^\n]+\n+\Z/m # XXX: this is not accurate maker = Maker::CISCO when /Error: Bad command\. \n\Z/m, /[^\s]+: not found\n\Z/m, /% The command or parameter at the ^ marker is invalid\./m, /Error: Invalid parameter\./m maker = Maker::ALAXALA when /Invalid syntax\..*\Z/m, /Unknown command: .*\Z/m maker = Maker::PALOALTO when /^ *\^ *\n% [^\n]+ error/m, /^ *\^ *\n% Invalid input detected at/m # same as Cisco maker = Maker::ARUBA else return false end #maker_update(maker) return true end |
#interface_gets(sw) ⇒ Object
617 618 619 620 621 622 623 624 625 626 |
# File 'lib/netutils/cli.rb', line 617 def interface_gets(sw) i = _new(:Interface, sw) i.parse(cmd(i.cmd)) # # XXX: hack for Cisco because Cisco cannot obtain up/down of # an interface with interfaces capability command... # is = _new(:IfSummary, sw) is.parse(cmd(is.cmd)) if is end |
#interface_name(port) ⇒ Object
628 629 630 |
# File 'lib/netutils/cli.rb', line 628 def interface_name(port) port end |
#interface_name_cli(port) ⇒ Object
632 633 634 |
# File 'lib/netutils/cli.rb', line 632 def interface_name_cli(port) port end |
#interface_noshutdown(port) ⇒ Object
643 644 645 646 647 648 |
# File 'lib/netutils/cli.rb', line 643 def interface_noshutdown(port) configure cmd("interface #{port}") cmd('no shutdown') unconfigure end |
#interface_shutdown(port) ⇒ Object
636 637 638 639 640 641 |
# File 'lib/netutils/cli.rb', line 636 def interface_shutdown(port) configure cmd("interface #{port}") cmd('shutdown') unconfigure end |
#login ⇒ Object
375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 |
# File 'lib/netutils/cli.rb', line 375 def login users = @users.dup passwds = @passwds.dup @type = @types[0] begin r = send("login_#{@type}", users, passwds) rescue Errno::ECONNREFUSED => e raise e if @type === @types.last @type = @types[@types.index(@type) + 1] retry end r = handle_control_characters(r) if r =~ FIRST_PROMPT_RE name_update($1) if $2 === '#' @enabled = true end end if r =~ /NEC Corporation.*OpenROUTE.*J\. Noel Chiappa/m maker_update(Maker::NEC) end product_detect end |
#logout ⇒ Object
480 481 482 |
# File 'lib/netutils/cli.rb', line 480 def logout @session.close end |
#mac_address_table_get(sw, ma, vlan) ⇒ Object
611 612 613 614 615 |
# File 'lib/netutils/cli.rb', line 611 def mac_address_table_get(sw, ma, vlan) fib = _new(:MACFIB, sw) fib.parse(cmd(fib.cmd(ma, vlan))) return fib.ports end |
#maker_to_s ⇒ Object
445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 |
# File 'lib/netutils/cli.rb', line 445 def maker_to_s # XXX: smarter way please... case @maker when Maker::CISCO 'Cisco' when Maker::WLC 'WLC' when Maker::ALAXALA 'Alaxala' when Maker::PALOALTO 'Paloalto' when Maker::ARUBA 'Aruba' when Maker::NEC 'NEC' else 'Unknown' end end |
#name_update(name) ⇒ Object
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/netutils/cli.rb', line 79 def name_update(name) if name =~ /^([^@]*)@(.*)$/ @user = $1 name = $2 end raise "Invalid host name given: \"#{name}\"" if name =~ /[>#\n]/ if @name === nil && name != nil && @name_supplied != nil && name != @name_supplied raise(ArgumentError, "host name mismatch: " + "\"#{@name_supplied}\" is supplied " + "but actually \"#{name}\"") end @name = name case @maker when Maker::CISCO prefix = suffix = trailer = '' when Maker::ALAXALA prefix = '!?' suffix = '' trailer = "\0? " when Maker::PALOALTO raise('Invalid host name for Paloalto') if ! @user prefix = "#{@user}@" suffix = '' trailer = ' ' when Maker::ARUBA prefix = '\(' suffix = '\) ' trailer = '' else prefix = '\(?' if @user prefix = "#{prefix}#{@user}@" else prefix = "#{prefix}.*" end suffix = '\)? ?' trailer = "\0? ?" end name = '[^\r\n\(\)]+' if ! name @normalprompt = "#{prefix}#{name}#{suffix}>#{trailer}" @enableprompt = "#{prefix}#{name}#{suffix}##{trailer}" @configprompt = "#{prefix}#{name}#{suffix}\\(config[^ ]*\\)##{trailer}" if @enabled @prompt = @enableprompt else # XXX configuring node... dirty.... @prompt = @normalprompt end end |
#neighbor_gets(sw, port = nil) ⇒ Object
680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 |
# File 'lib/netutils/cli.rb', line 680 def neighbor_gets(sw, port = nil) c = _new(:CDP, sw) if c begin c.parse(cmd(c.cmd(port))) return c.rsw if port && c.rsw rescue ArgumentError => e if e.to_s !~ /% CDP is not enabled/ raise e end end end l = _new(:LLDP, sw) if l l.parse(cmd(l.cmd(port))) return l.rsw if port && l.rsw end if ! c && ! l raise 'No method found for retrieving a neighbor!!' end nil end |
#no(re = nil) ⇒ Object
476 477 478 |
# File 'lib/netutils/cli.rb', line 476 def no(re = nil) yes_or_no('n', re) end |
#pager_disable_wlc ⇒ Object
496 497 498 |
# File 'lib/netutils/cli.rb', line 496 def pager_disable_wlc cmd('config paging disable') end |
#route_gets(ia) ⇒ Object
587 588 589 590 591 |
# File 'lib/netutils/cli.rb', line 587 def route_gets(ia) r = _new(:ShowRoute) r.parse(cmd(r.cmd(ia), nil, true)) return r.rib.get(ia) end |
#unconfigure ⇒ Object
563 564 565 566 |
# File 'lib/netutils/cli.rb', line 563 def unconfigure raise "currently not configuring" if @prompt != @configprompt return cmd('end', @enableprompt) end |
#vrf_gets ⇒ Object
593 594 595 596 597 598 |
# File 'lib/netutils/cli.rb', line 593 def vrf_gets v = _new(:ShowVRF) v.parse(cmd(v.cmd)) v.vrfs.add('default', '0:0') if v.vrfs.empty? return v.vrfs end |
#yes(re = nil) ⇒ Object
472 473 474 |
# File 'lib/netutils/cli.rb', line 472 def yes(re = nil) yes_or_no('y', re) end |