expect4r 0.0.2.dev → 0.0.3.dev

Sign up to get free protection for your applications and to get access to all the features.
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