expect4r 0.0.2.dev → 0.0.3.dev

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.
data/README.rdoc CHANGED
@@ -1,3 +1,5 @@
1
+ = Expect4r -- Interact with Cisco IOS, IOS-XR, and Juniper JUNOS CLI.
2
+
1
3
  Expect4r is a library that enables a ruby program to 'talk' to routers following a written ruby script.
2
4
  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.
3
5
 
@@ -21,16 +23,21 @@ You talk to routers by connecting to them using ssh or telnet and send exec or c
21
23
  interface loopback0
22
24
  shutdown
23
25
  }
24
-
25
-
26
+
26
27
  iox.config
27
28
  iox.exp_send 'interface GigabitEthernet0/2/0/0'
28
29
  iox.exp_send 'desc to switch port 13'
29
30
  iox.exp_send 'ipv4 address 190.0.0.9 255.255.255.252'
30
31
  iox.exp_send 'no shut'
31
32
  iox.commit
32
-
33
-
33
+
34
+ iox.config %|
35
+ interface GigabitEthernet0/2/0/0
36
+ desc to switch port 13'
37
+ ipv4 address 190.0.0.9 255.255.255.252'
38
+ no shut'
39
+ |
40
+
34
41
  j.config %{
35
42
  edit logical-router Orleans protocols bgp
36
43
  edit group session-to-200
@@ -41,7 +48,6 @@ You talk to routers by connecting to them using ssh or telnet and send exec or c
41
48
 
42
49
  * exec commands
43
50
 
44
-
45
51
  j.exec 'set cli screen-length 0'
46
52
 
47
53
  iox.exec "terminal len 0\nterminal width 0"
@@ -54,7 +60,6 @@ You talk to routers by connecting to them using ssh or telnet and send exec or c
54
60
 
55
61
  * interact with CLI.
56
62
 
57
-
58
63
  irb> r.interact
59
64
 
60
65
  #
@@ -98,13 +103,13 @@ You talk to routers by connecting to them using ssh or telnet and send exec or c
98
103
  Parsing a response becomes a matter of iterating an array using the
99
104
  Arrays's enumerator methods such as find, find_all ...
100
105
 
101
- irb(main):025:0> output = ts.exec %{
102
- irb(main):026:0" show terminal | include History
103
- irb(main):027:0" show line | include AUX
104
- irb(main):028:0" }
106
+ irb> output = ts.exec %{
107
+ irb" show terminal | include History
108
+ irb" show line | include AUX
109
+ irb" }
105
110
  => [
106
- ["show terminal | include History", "History is enabled, history size is 10.", "PEA#"],
107
- ["show line | include AUX", " 17 AUX 9600/9600 - 0/0 -", "PEA#"]
111
+ ["show terminal | include History", "History is enabled, history size is 10.", "ios#"],
112
+ ["show line | include AUX", " 17 AUX 9600/9600 - 0/0 -", "ios#"]
108
113
  ]
109
114
 
110
115
  output[0] contains output for 1st command 'show terminal'.
@@ -113,14 +118,63 @@ You talk to routers by connecting to them using ssh or telnet and send exec or c
113
118
  output[n-1] contains output for nth command.
114
119
 
115
120
 
116
-
117
-
118
-
119
-
120
-
121
-
122
-
123
-
124
-
125
-
121
+ * Ping
122
+
123
+ irb(main):016:0> ios.ping '192.168.1.23', :count=> 100, :pct_success=>90, :sweep_max_size=> 1500
124
+ => [ 99, [146148, 146500],
125
+ [["ping",
126
+ "Protocol [ip]: ", "",
127
+ "Target IP address: ", "192.168.1.23",
128
+ "Repeat count [5]: ", "100",
129
+ "Datagram size [100]: ", "",
130
+ "Timeout in seconds [2]: ", "",
131
+ "Extended commands [n]: ", "",
132
+ "Sweep range of sizes [n]: ", "yes",
133
+ "Sweep min size [36]: ", "",
134
+ "Sweep max size [18024]: ", "1500",
135
+ "Sweep interval [1]: ", "",
136
+ "Type escape sequence to abort.",
137
+ "Sending 146500, [36..1500]-byte ICMP Echos to 192.168.1.23, timeout is 2 seconds:",
138
+ "!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!!!!!!!!.!!!!!!!!.!!!!!!!!!!!!!!!!!!!",
139
+ "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!",
140
+ ...
141
+ "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!",
142
+ "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!",
143
+ "Success rate is 99 percent (146148/146500), round-trip min/avg/max = 1/7/924 ms",
144
+ "ios#"]]]
145
+
146
+
147
+ irb> iox.ping '192.168.1.100'
148
+ => [100, [5, 5],
149
+ [["ping 192.168.1.100",
150
+ "\rTue Oct 26 08:42:58.235 UTC",
151
+ "Type escape sequence to abort.",
152
+ "Sending 5, 100-byte ICMP Echos to 192.168.1.100, timeout is 2 seconds:",
153
+ "!!!!!",
154
+ "Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/2 ms",
155
+ "RP/0/0/CPU0:Paris-rp0#"]]]
156
+
157
+
158
+ irb> iox.ping '192.168.1.100', :sweep_min_size => 1000, :sweep_max_size => 1300
159
+ => [100, [1505, 1505],
160
+ [["ping",
161
+ "\rTue Oct 26 08:44:33.024 UTC",
162
+ "Protocol [ipv4]: ", "",
163
+ "\rTarget IP address: ", "192.168.1.100",
164
+ "\rRepeat count [5]: ", "", "\rDatagram size [100]: ", "",
165
+ "\rTimeout in seconds [2]: ", "",
166
+ "\rExtended commands? [no]: ", "",
167
+ "\rSweep range of sizes? [no]: ", "yes",
168
+ "\rSweep min size [36]: ", "1000",
169
+ "\rSweep max size [18024]: ", "1300",
170
+ "\rSweep interval [1]: ", "",
171
+ "\rType escape sequence to abort.",
172
+ "Sending 1505, [1000..1300]-byte ICMP Echos to 192.168.1.100, timeout is 2 seconds:",
173
+ "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!",
174
+ "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!",
175
+ ...
176
+ "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!",
177
+ "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!",
178
+ "Success rate is 100 percent (1505/1505), round-trip min/avg/max = 1/1/3 ms",
179
+ "RP/0/0/CPU0:Paris-rp0#"]]]
126
180
 
data/lib/expect/io.rb CHANGED
@@ -81,14 +81,15 @@ module Expect4r
81
81
  end
82
82
 
83
83
  def child_exit
84
- if @pid
85
- Process.kill(:KILL, @pid)
86
- @thread.kill
87
- @lp, @r, @w, @pid = [nil]*4
84
+ if @proxy
85
+ @proxy.logout
86
+ else
87
+ Process.kill(:KILL, @pid) if @pid
88
+ @thread.kill if @thread
88
89
  end
89
90
  rescue Errno::ESRCH, Errno::ECHILD => e
90
91
  ensure
91
- @lp, @r, @w, @pid = [nil]*4
92
+ @lp, @r, @w, @pid, @proxy = [nil]*5
92
93
  end
93
94
 
94
95
  def spawn(cmd)
@@ -150,6 +151,7 @@ module Expect4r
150
151
  end
151
152
 
152
153
  def interact(k=?\C-z)
154
+ login unless connected?
153
155
  STDOUT.puts "\n\#\n\# #{ctrl_key k} to terminate.\n\#\n"
154
156
  reader :start
155
157
  writer k
@@ -202,14 +204,25 @@ module Expect4r
202
204
  @r && (not child_exited?)
203
205
  end
204
206
 
205
- def login(c, o={})
207
+ def login_by_proxy(proxy)
208
+ raise ArgumentError, "Don't know how to login to #{proxy}" unless proxy.respond_to? :_login_
209
+ _login_ :proxy=> proxy
210
+ end
211
+ alias :login_via :login_by_proxy
212
+
213
+ def login(cmd, arg={})
214
+
206
215
  return if connected?
207
216
 
208
- spawn c
217
+ if arg[:proxy]
218
+ login_proxy cmd, arg
219
+ else
220
+ spawn cmd
221
+ end
209
222
 
210
- o={:timeout=>13, :no_echo=>false}.merge(o)
211
- timeout = o[:timeout]
212
- no_echo = o[:no_echo]
223
+ arg={:timeout=>13, :no_echo=>false}.merge(arg)
224
+ timeout = arg[:timeout]
225
+ no_echo = arg[:no_echo]
213
226
 
214
227
  output=[]
215
228
  t0 = Time.now
@@ -223,7 +236,9 @@ module Expect4r
223
236
  when spawnee_prompt
224
237
  read_pipe._io_save false, "match PROMPT"
225
238
  throw(:done, [:ok, output])
226
- when /(user\s*name\s*|login):\r*$/i
239
+ when /Last (L|l)ogin:/
240
+ read_pipe._io_save no_echo # consumes
241
+ when /(user\s*name\s*|login):\s*$/i
227
242
  read_pipe._io_save no_echo, "match USERNAME"
228
243
  exp_puts spawnee_username
229
244
  when /password:\s*$/i
@@ -235,6 +250,9 @@ module Expect4r
235
250
  when /.*\r\n/
236
251
  exp_internal "match EOL"
237
252
  read_pipe._io_save no_echo, "match EOL", "\r\n"
253
+ when /Are you sure you want to continue connecting \(yes\/no\)\?/
254
+ read_pipe._io_save no_echo, "match continue connecting"
255
+ exp_puts 'yes'
238
256
  end
239
257
  end
240
258
  end
@@ -243,18 +261,24 @@ module Expect4r
243
261
  elapsed = Time.now - t0
244
262
  if elapsed < timeout
245
263
  child_exit
246
- raise ConnectionError.new(c)
264
+ raise ConnectionError.new(cmd)
247
265
  else
248
- raise ExpTimeoutError.new(c, timeout)
266
+ raise ExpTimeoutError.new(cmd, timeout)
249
267
  end
250
268
  else
251
269
  @lp = buf.last
252
270
  end
253
271
  [buf, ev]
254
-
255
272
  end
256
273
 
257
274
  private
275
+
276
+ def login_proxy(cmd, arg)
277
+ @proxy = arg[:proxy].dup
278
+ @proxy.login
279
+ @proxy.exp_puts cmd
280
+ @r, @w, @pid = @proxy.instance_eval { [@r, @w, @pid] }
281
+ end
258
282
 
259
283
  #FIXME ? putline to send_cmd ?
260
284
  # hide putline and expose cmd
@@ -407,7 +431,7 @@ module Kernel
407
431
  end
408
432
 
409
433
  module Expect4r
410
- class BaseObject
434
+ class BaseLoginObject
411
435
  class << self
412
436
  def new_telnet(*args)
413
437
  new :telnet, *args
@@ -421,11 +445,26 @@ module Expect4r
421
445
  @routers << r
422
446
  end
423
447
  end
424
- attr_reader :host, :user, :method, :port
448
+ attr_reader :host, :user, :method, :port, :proxy
425
449
  alias :username :user
426
450
  alias :hostname :host
451
+ # Adds a login to a Expect4r::BaseLoginObject"
452
+ #
453
+ # Constructor:
454
+ # * <tt>new</tt> <method>, <username>, <password>, [port_number]
455
+ # * <tt>new</tt> <method>, options={}
456
+ #
457
+ # Options are:
458
+ # * <tt>:host</tt> or <tt>:hostname</tt>
459
+ # * <tt>:user</tt> or <tt>:username</tt>
460
+ # * <tt>:pwd</tt> or <tt>:password</tt>
461
+ #
462
+ # Examples:
463
+ # new :telnet, :user=> 'lab', :password=>'lab'
464
+ # new :ssh, :user=> 'jme'
465
+ #
427
466
  def initialize(*args)
428
- ciphered_pwd=nil
467
+ ciphered_password=nil
429
468
  if args.size>2 and args[1].is_a?(String)
430
469
  @method, host, @user, pwd = args
431
470
  elsif args.size == 2 and args[1].is_a?(Hash) and args[0].is_a?(Symbol)
@@ -433,29 +472,62 @@ module Expect4r
433
472
  host = args[1][:host] || args[1][:hostname]
434
473
  @user = args[1][:user]|| args[1][:username]
435
474
  pwd = args[1][:pwd] || args[1][:password]
436
- ciphered_pwd = args[1][:ciphered_pwd]
475
+ ciphered_password = args[1][:ciphered_password]
437
476
  end
438
477
  @host, port = host.split
439
478
  @port = port.to_i
440
- @pwd = if ciphered_pwd
441
- ciphered_pwd
479
+ @pwd = if ciphered_password
480
+ ciphered_password
442
481
  else
443
482
  Expect4r.cipher(pwd) if pwd
444
483
  end
445
484
  @ps1 = /(.*)(>|#|\$)\s*$/
446
485
  @more = / --More-- /
447
486
  @matches=Set.new
448
- BaseObject.add(self)
487
+ BaseLoginObject.add(self)
449
488
  self
450
489
  end
490
+
491
+ def spawnee
492
+ case method
493
+ when :telnet ; "telnet #{host} #{port if port>0}"
494
+ when :ssh ; "ssh #{spawnee_username}@#{host}"
495
+ else
496
+ raise RuntimeError
497
+ end
498
+ end
499
+
500
+ def spawnee_username
501
+ @user
502
+ end
503
+
504
+ def spawnee_prompt
505
+ @ps1
506
+ end
507
+
508
+ def dup
509
+ if @pwd
510
+ self.class.new @method, @host, @user, Expect4r.decipher(@pwd)
511
+ else
512
+ self.class.new @method, @host, @user
513
+ end
514
+ end
515
+
516
+ private
517
+
518
+ def spawnee_password
519
+ @pwd = Expect4r.cipher( ask("(#{self}) Enter your password: ") { |q| q.echo = "X" } ) unless @pwd
520
+ Expect4r.decipher(@pwd)
521
+ end
522
+
451
523
  end
452
524
  end
453
525
 
454
526
  if __FILE__ != $0
455
527
 
456
528
  at_exit {
457
- if Expect4r::BaseObject.routers
458
- Expect4r::BaseObject.routers.each { |r| r.logout if r.respond_to? :logout }
529
+ if Expect4r::BaseLoginObject.routers
530
+ Expect4r::BaseLoginObject.routers.each { |r| r.logout if r.respond_to? :logout }
459
531
  end
460
532
  }
461
533
 
@@ -463,21 +535,21 @@ else
463
535
 
464
536
  require "test/unit"
465
537
 
466
- class Expect4r::BaseObject
538
+ class Expect4r::BaseLoginObject
467
539
  def initialize
468
- Expect4r::BaseObject.add(self)
540
+ Expect4r::BaseLoginObject.add(self)
469
541
  end
470
542
  end
471
543
 
472
- class TestRouterBaseObject < Test::Unit::TestCase
544
+ class TestRouterBaseLoginObject < Test::Unit::TestCase
473
545
  include Expect4r
474
546
 
475
547
  def test_add
476
- assert [], BaseObject.routers
477
- BaseObject.new
478
- assert 1, BaseObject.routers.size
479
- BaseObject.new
480
- assert_equal 2, BaseObject.routers.size
548
+ assert [], BaseLoginObject.routers
549
+ BaseLoginObject.new
550
+ assert 1, BaseLoginObject.routers.size
551
+ BaseLoginObject.new
552
+ assert_equal 2, BaseLoginObject.routers.size
481
553
  end
482
554
  end
483
555
 
data/lib/expect4r.rb CHANGED
@@ -7,6 +7,7 @@ module Expect4r
7
7
  autoload :Ios, 'router/cisco/ios/ios'
8
8
  autoload :J, 'router/juniper/junos/junos'
9
9
  autoload :Shell, 'misc/shell'
10
+ autoload :RShell, 'misc/shell'
10
11
 
11
12
  module Router
12
13
  autoload :Common, 'router/common'
@@ -33,6 +34,7 @@ module Expect4r
33
34
  module Junos
34
35
  autoload :Modes, 'router/juniper/junos/modes'
35
36
  autoload :Show, 'router/juniper/junos/show'
37
+ autoload :Ping, 'router/juniper/junos/ping'
36
38
  end
37
39
  end
38
40
 
data/lib/misc/shell.rb CHANGED
@@ -1,7 +1,4 @@
1
- require 'expect/io'
2
-
3
1
  module Expect4r
4
-
5
2
  class Shell
6
3
  include Expect4r
7
4
  def initialize()
@@ -15,5 +12,44 @@ module Expect4r
15
12
  spawn @shell
16
13
  end
17
14
  end
15
+ class RShell < ::Expect4r::BaseLoginObject
16
+ include Expect4r
17
+ def initialize(*args)
18
+ super
19
+ default_ps1
20
+ end
21
+ def logout
22
+ default_ps1
23
+ super
24
+ end
25
+ def login(arg={})
26
+ super(spawnee, arg)
27
+ cmd %{export COLUMNS=1024}
28
+ end
29
+ # FIXME: 1.9.2 bug:
30
+ # It calls LoginBaseOject#login() instead of calling J#login()
31
+ # modified login_by_proxy to call _login_ seems to work.
32
+ alias :_login_ :login
33
+
34
+ def ps1=(val)
35
+ # Assumes bash
36
+ @ps1_bis = /#{val}$/
37
+ cmd %? export PS1='#{val}' ?
38
+ @ps1 = @ps1_bi
39
+ end
40
+ def cmd(*args)
41
+ exp_send *args
42
+ end
43
+
44
+ private
45
+
46
+ def default_ps1
47
+ @ps1 = /.+[^\#](\#|\$)\s+$/
48
+ end
49
+ end
50
+ end
51
+
52
+ __END__
53
+
18
54
 
19
- end
55
+ cmd %? PROMPT_COMMAND="echo -n [$(date +%k:%m:%S)]: && pwd" && export PS1='#{val}' ?
@@ -2,6 +2,16 @@
2
2
  module Expect4r::Router
3
3
  module CiscoCommon
4
4
 
5
+ #
6
+ # Returns the config level depths:
7
+ #
8
+ # Example:
9
+ #
10
+ # iox(config-ospf-ar)#
11
+ #
12
+ # irb> iox.config_lvl?
13
+ # => 3
14
+ #
5
15
  def config_lvl?
6
16
  return -1 unless config?
7
17
  @lp =~ /\(config(|.+)\)/
@@ -4,6 +4,29 @@ module Expect4r::Router::CiscoCommon
4
4
  module Ping
5
5
  include ::Expect4r::Router::Error
6
6
 
7
+ # Adds a <tt>ping</tt> method to <tt>CiscoCommon::Ping mixin</tt>:
8
+ #
9
+ # Options are:
10
+ # * <tt>:protocol</tt>
11
+ # * <tt>:repeat_count</tt> or <tt>:count</tt>
12
+ # * <tt>:datagram_size</tt> or <tt>:size</tt>
13
+ # * <tt>:timeout</tt>
14
+ # * <tt>:source_address</tt>
15
+ # * <tt>:tos</tt>
16
+ # * <tt>:df</tt>
17
+ # * <tt>:pattern</tt>
18
+ # * <tt>:sweep_min_size</tt>
19
+ # * <tt>:sweep_max_size</tt>
20
+ # * <tt>:sweep_interval</tt>
21
+ # * <tt>:pct_success</tt> - default is 99.
22
+ #
23
+ # Option examples:
24
+ # :protocol => 'ipv4'
25
+ # :count => 10
26
+ # :timeout => 1
27
+ # :size=> 512
28
+ # :protocol=> 'ipv4', :count=> 20, :size=> 1500, :timeout=>5
29
+ #
7
30
  def ping(target_ip_address, arg={})
8
31
 
9
32
  pct_success = arg.delete(:pct_success) || 99
@@ -98,11 +121,3 @@ private
98
121
  end
99
122
  end
100
123
 
101
- __END__
102
-
103
- p.ping '192.168.1.23'
104
- p.ping '192.168.1.23', :sweep_max_size=> 1512, :pct_success => 95
105
- p.ping '192.168.1.23', :source_address => '192.168.1.199', :count=> 100, :pct_success=> 90
106
-
107
- puts output[2][0].join("\n").split(": \n").join(": ")
108
-
@@ -1,6 +1,6 @@
1
1
  require 'router/cisco/common/common'
2
2
 
3
- class Expect4r::Ios < ::Expect4r::BaseObject
3
+ class Expect4r::Ios < ::Expect4r::BaseLoginObject
4
4
 
5
5
  include Expect4r
6
6
  include Expect4r::Router::Common
@@ -33,12 +33,17 @@ class Expect4r::Ios < ::Expect4r::BaseObject
33
33
  Expect4r.decipher(@pwd) # password is ciphered ...
34
34
  end
35
35
 
36
- def login
37
- super(spawnee)
36
+ def login(arg={})
37
+ super(spawnee,arg)
38
38
  enable
39
39
  exec "term len 0\nterm width 0"
40
40
  self
41
41
  end
42
+ # FIXME: 1.9.2 bug:
43
+ # It calls LoginBaseOject#login() instead of calling J#login()
44
+ # modified login_by_proxy to call _login_ seems to work.
45
+ alias :_login_ :login
46
+
42
47
 
43
48
  def putline(line,*args)
44
49
  output, rc = super
@@ -3,6 +3,10 @@ require 'router/modes'
3
3
  module Expect4r::Router::Ios
4
4
  module Modes
5
5
 
6
+ # Adds a <tt>in?</tt> mixin.
7
+ #
8
+ # Returns the mode the router is in: :user, :exec, :config
9
+ #
6
10
  def in?(mode=:none)
7
11
  login unless connected?
8
12
  case mode
@@ -61,10 +65,16 @@ module Modes
61
65
  @lp =~ /\(config(|.+)\)/
62
66
  end
63
67
 
68
+ #
69
+ # returns <tt>true</tt> if router is in <tt>:exec</tt> (enabled) mode, <tt>false</tt> otherwise.
70
+ #
64
71
  def exec?
65
72
  ! user? and ! config?
66
73
  end
67
74
 
75
+ #
76
+ # returns <tt>true</tt> if router is in <tt>:user</tt> mode, <tt>false</tt> otherwise.
77
+ #
68
78
  def user?
69
79
  @lp =~ /.+>\s*$/
70
80
  end
@@ -1,7 +1,7 @@
1
1
 
2
2
  require 'router/cisco/common/common'
3
3
 
4
- class Expect4r::Iox < ::Expect4r::BaseObject
4
+ class Expect4r::Iox < ::Expect4r::BaseLoginObject
5
5
 
6
6
  include Expect4r
7
7
  include Expect4r::Router
@@ -18,12 +18,16 @@ class Expect4r::Iox < ::Expect4r::BaseObject
18
18
  @more = / --More-- /
19
19
  end
20
20
 
21
- def login
22
- super(spawnee)
21
+ def login(arg={})
22
+ super(spawnee, arg)
23
23
  config 'no logging console' if port>0
24
24
  exec "terminal len 0\nterminal width 0"
25
25
  self
26
26
  end
27
+ # FIXME: 1.9.2 bug:
28
+ # It calls LoginBaseOject#login() instead of calling J#login()
29
+ # modified login_by_proxy to call _login_ seems to work.
30
+ alias :_login_ :login
27
31
 
28
32
  def commit(arg={})
29
33
  return unless config?
@@ -3,6 +3,19 @@ require 'router/modes'
3
3
  module Expect4r::Router::Iox
4
4
  module Modes
5
5
 
6
+ # Adds an Iox <tt>config>/tt> mixin.
7
+ #
8
+ # Options are:
9
+ #
10
+ # Option examples:
11
+ #
12
+ # iox.config %{
13
+ # interface GigabitEthernet0/2/0/0
14
+ # desc to switch port 13'
15
+ # ipv4 address 190.0.0.9 255.255.255.252'
16
+ # no shut'
17
+ # }
18
+ #
6
19
  def config(config=nil, arg={})
7
20
  login unless connected?
8
21
  if config
@@ -0,0 +1,55 @@
1
+
2
+ __END__
3
+
4
+ RP/0/0/CPU0:Paris-rp0#ping ipv4 1.1.1.1 count 5 ?
5
+ donotfrag set DF bit in IP header
6
+ pattern data pattern
7
+ size datagram size
8
+ source source address or source interface
9
+ sweep sweep ping
10
+ timeout timeout in seconds
11
+ type type of service
12
+ validate validate return packet
13
+ verbose verbose output
14
+ <cr>
15
+ RP/0/0/CPU0:Paris-rp0#ping ipv4 1.1.1.1 count 5 size ?
16
+ <36-18024> datagram size
17
+ RP/0/0/CPU0:Paris-rp0#ping ipv4 1.1.1.1 count 5 size 100 ?
18
+ donotfrag set DF bit in IP header
19
+ pattern data pattern
20
+ source source address or source interface
21
+ sweep sweep ping
22
+ timeout timeout in seconds
23
+ type type of service
24
+ validate validate return packet
25
+ verbose verbose output
26
+ <cr>
27
+ RP/0/0/CPU0:Paris-rp0#ping ipv4 1.1.1.1 count 5 size 100 donotfrag ?
28
+ pattern data pattern
29
+ source source address or source interface
30
+ sweep sweep ping
31
+ timeout timeout in seconds
32
+ type type of service
33
+ validate validate return packet
34
+ verbose verbose output
35
+ <cr>
36
+ RP/0/0/CPU0:Paris-rp0#ping ipv4 1.1.1.1 count 5 size 100 donotfrag pattern ?
37
+ <0-65535> data pattern
38
+ RP/0/0/CPU0:Paris-rp0#ping ipv4 1.1.1.1 count 5 size 100 donotfrag pattern 0xdead type 2 ?
39
+ source source address or source interface
40
+ sweep sweep ping
41
+ timeout timeout in seconds
42
+ validate validate return packet
43
+ verbose verbose output
44
+ <cr>
45
+ RP/0/0/CPU0:Paris-rp0#ping ipv4 1.1.1.1 count 5 size 100 donotfrag pattern 0xdead type 2 timeout 10 sweep ?
46
+ source source address or source interface
47
+ validate validate return packet
48
+ verbose verbose output
49
+ <cr>
50
+ RP/0/0/CPU0:Paris-rp0#ping ipv4 1.1.1.1 count 5 size 100 donotfrag pattern 0xdead type 2 timeout 10 sweep ?
51
+ source source address or source interface
52
+ validate validate return packet
53
+ verbose verbose output
54
+ <cr>
55
+ RP/0/0/CPU0:Paris-rp0#
data/lib/router/common.rb CHANGED
@@ -14,29 +14,5 @@ module Common
14
14
  putc "\n" if console?
15
15
  end
16
16
 
17
- def spawnee
18
- case method
19
- when :telnet ; "telnet #{host} #{port if port>0}"
20
- when :ssh ; "ssh #{spawnee_username}@#{host}"
21
- else
22
- raise RuntimeError
23
- end
24
- end
25
-
26
- def spawnee_username
27
- @user
28
- end
29
-
30
- def spawnee_prompt
31
- @ps1
32
- end
33
-
34
- private
35
-
36
- def spawnee_password
37
- @pwd = Expect4r.cipher( ask("Enter your password: ") { |q| q.echo = "X" } ) unless @pwd
38
- Expect4r.decipher(@pwd)
39
- end
40
-
41
17
  end
42
18
  end
@@ -1,4 +1,4 @@
1
- class Expect4r::J < ::Expect4r::BaseObject
1
+ class Expect4r::J < ::Expect4r::BaseLoginObject
2
2
  include Expect4r
3
3
  include Expect4r::Router::Error
4
4
  include Expect4r::Router::Common
@@ -13,12 +13,15 @@ class Expect4r::J < ::Expect4r::BaseObject
13
13
  @more = /---\(more(| \d+\%)\)---/
14
14
  end
15
15
 
16
- def login
17
- ENV['TERM']='dumb'
18
- super(spawnee)
16
+ def login(arg={})
17
+ super(spawnee, arg)
19
18
  exec 'set cli screen-length 0'
20
19
  self
21
20
  end
21
+ # FIXME: 1.9.2 bug:
22
+ # It calls LoginBaseOject#login() instead of calling J#login()
23
+ # modified login_by_proxy to call _login_ seems to work.
24
+ alias :_login_ :login
22
25
 
23
26
  def console?
24
27
  @port>0
@@ -3,6 +3,18 @@ require 'router/modes'
3
3
  module Expect4r::Router::Junos
4
4
  module Modes
5
5
 
6
+ # Adds a Junos <tt>config</tt> mixin.
7
+ #
8
+ # Example:
9
+ #
10
+ # j.config %{
11
+ # edit logical-router Orleans protocols bgp
12
+ # edit group session-to-200
13
+ # set type external
14
+ # set peer-as 200
15
+ # set neighbor 40.0.2.1 peer-as 200
16
+ # }
17
+ #
6
18
  def config(stmts=nil, arg={})
7
19
  login unless connected?
8
20
  if stmts
@@ -13,10 +25,16 @@ def config(stmts=nil, arg={})
13
25
  change_mode_to(mode)
14
26
  output
15
27
  else
16
- mode
28
+ to_config
17
29
  end
18
30
  end
19
31
 
32
+ # Adds a Junos <tt>exec</tt> mixin.
33
+ #
34
+ # Example:
35
+ #
36
+ # j.exec 'set cli screen-length 0'
37
+ #
20
38
  def exec(cmd=nil, *args)
21
39
  login unless connected?
22
40
  if cmd.nil?
@@ -50,14 +68,23 @@ def shell(cmd=nil, *args)
50
68
  end
51
69
  end
52
70
 
71
+ #
72
+ # returns <tt>true</tt> if router is in <tt>:exec</tt> mode, <tt>false</tt> otherwise.
73
+ #
53
74
  def exec?
54
75
  @lp =~ /> $/ ? true : false
55
76
  end
56
77
 
78
+ #
79
+ # returns <tt>true</tt> if router is in <tt>:config</tt> mode, <tt>false</tt> otherwise.
80
+ #
57
81
  def config?
58
82
  @lp =~ /^.+# $/ ? true : false
59
83
  end
60
84
 
85
+ #
86
+ # returns <tt>true</tt> if router is in <tt>:shell</tt> mode, <tt>false</tt> otherwise.
87
+ #
61
88
  def shell?
62
89
  @lp == '% ' ? true : false
63
90
  end
@@ -3,6 +3,24 @@ require 'router/error'
3
3
  module Expect4r::Router::Junos
4
4
  module Ping
5
5
 
6
+ # Adds a ping method to J class:
7
+ #
8
+ # Options are:
9
+ # * <tt>:count</tt> or <tt>:repeat_count</tt>
10
+ # * <tt>:size</tt> or <tt>:datagram_size</tt>
11
+ # * <tt>:datagram_size</tt> or <tt>:size</tt>
12
+ # * <tt>:timeout</tt>
13
+ # * <tt>:tos</tt>
14
+ # * <tt>:ttl</tt>
15
+ # * <tt>:pattern</tt>
16
+ # * <tt>:pct_success</tt> - default is 99.
17
+ #
18
+ # Option examples:
19
+ # :count => 10
20
+ # :timeout => 1
21
+ # :size=> 512
22
+ # :protocol=> 'ipv4', :count=> 20, :size=> 1500, :timeout=>5, :ttl=>16
23
+ #
6
24
  def ping(host, arg={})
7
25
 
8
26
  pct_success = arg.delete(:pct_success) || 99
data/lib/router/modes.rb CHANGED
@@ -2,6 +2,21 @@ module Expect4r
2
2
  module Router
3
3
  module Common
4
4
  module Modes
5
+
6
+ # Adds a <tt>in?</tt> mixin.
7
+ #
8
+ # Examples:
9
+ #
10
+ # irb(main):007:0> iox.in?
11
+ # => :exec
12
+ # irb(main):008:0> iox.config
13
+ # => :config
14
+ # irb(main):009:0> iox.in?
15
+ # => :config
16
+ # irb(main):010:0> iox.shell
17
+ # => :shell
18
+ # irb(main):011:0> iox.in?
19
+ # => :shell
5
20
  def in?(mode=:none)
6
21
  login unless connected?
7
22
  case mode
metadata CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 2
8
+ - 3
9
9
  - dev
10
- version: 0.0.2.dev
10
+ version: 0.0.3.dev
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jean-Michel Esnault
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-10-25 00:00:00 -07:00
18
+ date: 2010-10-27 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: 1.5.0
33
33
  type: :runtime
34
34
  version_requirements: *id001
35
- description: A Ruby Library for interacting with IOS, IOS-XR, and JUNOS CLI.
35
+ description: A Ruby Library for interacting with IOS, IOS-XR, and JUNOS CLI.
36
36
  email: jesnault@gmail.com
37
37
  executables: []
38
38
 
@@ -57,6 +57,7 @@ files:
57
57
  - lib/router/cisco/ios/termserver.rb
58
58
  - lib/router/cisco/iox/iox.rb
59
59
  - lib/router/cisco/iox/modes.rb
60
+ - lib/router/cisco/iox/ping.rb
60
61
  - lib/router/common.rb
61
62
  - lib/router/error.rb
62
63
  - lib/router/juniper/junos/junos.rb