Expect4r – Interact with Cisco IOS, IOS-XR, and Juniper JUNOS CLI.¶ ↑
Expect4r is a library that enables a ruby program to ‘talk’ to routers following a written ruby script. You talk to routers by connecting to them using ssh or telnet and send exec or config command and collect router output than can be parsed using ruby.
-
Connect to routers
ios = Ios.new_telnet :host=> "hostname", :user=> "username", :pwd => "password" ios.login iox = Iox.new_telnet 'host', 'username', 'password' iox.login j = J.new_telnet :host=> '', :user=> 'lab', :pwd => 'lab' j.login
-
Connect to a box via another
my_mac = RShell.new_ssh 'mac', 'me' router = Iox.new_telnet 'hostname', 'username' router.login_via my_mac
-
Re-establish connection
irb> localhost = Expect4r::BaseLoginObject.new_ssh :hostname=>'localhost' irb> localhost.connect_retry=10 irb> localhost.login irb> localhost.interact irb> s.interact # # ^T to terminate. # [jme@localhost ~]$ ps -ax | grep localhost 5497 pts/8 Ss+ 0:00 ssh localhost 5592 pts/9 S+ 0:00 grep --color=auto localhost [jme@localhost ~]$ kill 5497 Killed by signal 15. [jme@localhost ~]$ [jme@localhost ~]$ ls Desktop Downloads Music Public Videos Documents expect4r-0.0.11.gem Pictures Templates [jme@localhost ~]$ ps -ax | grep localhost 5648 pts/9 Ss+ 0:00 ssh localhost 5777 pts/10 S+ 0:00 grep --color=auto localhost [jme@localhost ~]$ [jme@localhost ~]$ ^T irb>
-
Push configurations to routers
ios.config 'no logging console' ios.config %{ interface loopback0 shutdown } iox.config iox.exp_send 'interface GigabitEthernet0/2/0/0' iox.exp_send 'desc to switch port 13' iox.exp_send 'ipv4 address 190.0.0.9 255.255.255.252' iox.exp_send 'no shut' iox.commit iox.config %| interface GigabitEthernet0/2/0/0 desc to switch port 13' ipv4 address 190.0.0.9 255.255.255.252' no shut | j.config %{ edit logical-router Orleans protocols bgp edit group session-to-200 set type external set peer-as 200 set neighbor 40.0.2.1 peer-as 200 }
-
exec commands
j.exec 'set cli screen-length 0' iox.exec "terminal len 0\nterminal width 0"
-
exec shell commands
iox.shell 'pidin'
-
interact with CLI.
irb> r.interact # # ^T to terminate. # router#clear line 2 [confirm] [OK] router# ^T => nil irb> irb(main):210:0* j.interact # # ^T to terminate. # jme@router> configure Entering configuration mode The configuration has been changed but not committed [edit] jme@router# rollback load complete [edit] jme@router# show | compare [edit] jme@router# ^T => nil irb(main):211:0>
-
Parsing output
The output is returned as an array of arrays of responses to commands. Each response is returned as an array of lines. Parsing a response becomes a matter of iterating an array using the Arrays's enumerator methods such as find, find_all ... irb> output = ts.exec %{ irb" show terminal | include History irb" show line | include AUX irb" } => [ ["show terminal | include History", "History is enabled, history size is 10.", "ios#"], ["show line | include AUX", " 17 AUX 9600/9600 - 0/0 -", "ios#"] ] output[0] contains output for 1st command 'show terminal'. output[1] contains output for 1st command 'show line'. ... output[n-1] contains output for nth command.
-
Ios Ping
irb(main):016:0> ios.ping '192.168.1.23', :count=> 100, :pct_success=>90, :sweep_max_size=> 1500 => [ 99, [146148, 146500], [["ping", "Protocol [ip]: ", "", "Target IP address: ", "192.168.1.23", "Repeat count [5]: ", "100", "Datagram size [100]: ", "", "Timeout in seconds [2]: ", "", "Extended commands [n]: ", "", "Sweep range of sizes [n]: ", "yes", "Sweep min size [36]: ", "", "Sweep max size [18024]: ", "1500", "Sweep interval [1]: ", "", "Type escape sequence to abort.", "Sending 146500, [36..1500]-byte ICMP Echos to 192.168.1.23, timeout is 2 seconds:", "!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!!!!!!!!.!!!!!!!!.!!!!!!!!!!!!!!!!!!!", "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", ... "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", "Success rate is 99 percent (146148/146500), round-trip min/avg/max = 1/7/924 ms", "ios#"]]]
-
Iox ping
irb> iox.ping '192.168.1.100' => [100, [5, 5], [["ping 192.168.1.100", "\rTue Oct 26 08:42:58.235 UTC", "Type escape sequence to abort.", "Sending 5, 100-byte ICMP Echos to 192.168.1.100, timeout is 2 seconds:", "!!!!!", "Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/2 ms", "RP/0/0/CPU0:Paris-rp0#"]]] irb> iox.ping '192.168.1.100', :sweep_min_size => 1000, :sweep_max_size => 1300 => [100, [1505, 1505], [["ping", "\rTue Oct 26 08:44:33.024 UTC", "Protocol [ipv4]: ", "", "\rTarget IP address: ", "192.168.1.100", "\rRepeat count [5]: ", "", "\rDatagram size [100]: ", "", "\rTimeout in seconds [2]: ", "", "\rExtended commands? [no]: ", "", "\rSweep range of sizes? [no]: ", "yes", "\rSweep min size [36]: ", "1000", "\rSweep max size [18024]: ", "1300", "\rSweep interval [1]: ", "", "\rType escape sequence to abort.", "Sending 1505, [1000..1300]-byte ICMP Echos to 192.168.1.100, timeout is 2 seconds:", "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", ... "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", "Success rate is 100 percent (1505/1505), round-trip min/avg/max = 1/1/3 ms", "RP/0/0/CPU0:Paris-rp0#"]]]
-
Junos ping
irb> j.ping '192.168.1.123' => [5, [5, 0], [["ping 192.168.1.123 rapid ", "PING 192.168.1.123 (192.168.1.123): 56 data bytes", "!!!!!", "--- 192.168.1.123 ping statistics ---", "5 packets transmitted, 5 packets received, 0% packet loss", "round-trip min/avg/max/stddev = 2.310/2.943/4.390/0.753 ms", "", junos> "]]]