expect4r 0.0.7.dev → 0.0.8

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.
@@ -119,6 +119,7 @@ module Expect4r
119
119
 
120
120
  def logout
121
121
  child_exit
122
+ @lp, @_lp_1 = nil,nil
122
123
  @pid
123
124
  end
124
125
 
@@ -150,11 +151,13 @@ module Expect4r
150
151
  raise
151
152
  end
152
153
 
153
- def interact(k=?\C-z)
154
+ def interact(k="C-z")
155
+ k.upcase!
156
+ raise unless k =~ /C\-[A-Z]/
154
157
  login unless connected?
155
- STDOUT.puts "\n\#\n\# #{ctrl_key k} to terminate.\n\#\n"
158
+ STDOUT.puts "\n\#\n\# #{k.gsub(/C\-/,'^')} to terminate.\n\#\n"
156
159
  reader :start
157
- writer k
160
+ writer(eval "?\\#{k}")
158
161
  rescue
159
162
  ensure
160
163
  begin
@@ -228,74 +231,6 @@ module Expect4r
228
231
  def get_prompt
229
232
  putline '', :no_trim=>true, :no_echo=>true
230
233
  end
231
-
232
- def putline(line, arg={})
233
- raise ConnectionError.new(line) if child_exited?
234
-
235
- arg = {:ti=>13, :no_echo=>false, :debug=>0, :sync=> false, :no_trim=>false}.merge(arg)
236
- no_echo = arg[:no_echo]
237
- ti = arg[:ti]
238
- unless arg[:no_trim]==true
239
- line = line.gsub(/\s+/,' ').gsub(/^\s+/,'')
240
- if line.size==0
241
- log "DEBUG PUTLINE: NOT SENDING **** line = '#{line.inspect}' arg=#{arg.inspect}"
242
- return [[], :empty_line]
243
- end
244
- end
245
- sync if arg[:sync]
246
- t0 = Time.now
247
- exp_puts line
248
- output=[]
249
- rc, buf = catch(:done) do
250
- @r.readbuf(arg[:ti]) do |r|
251
- if r._io_exit?
252
- r._io_save(no_echo)
253
- throw :done, [ :abort, r._io_buf1]
254
- end
255
- case r._io_string
256
- when @ps1, @ps1_bis
257
- unless r._io_more?
258
- r._io_save no_echo, "matching PROMPT"
259
- # puts "debug IO BUF 1 #{r._io_buf1.inspect}"
260
- throw(:done, [:ok, r._io_buf1])
261
- end
262
- exp_internal "more..."
263
- when /(.+)\r\n/, "\r\n"
264
- r._io_save no_echo, "matching EOL"
265
- when @more
266
- r._io_save no_echo, "matching MORE"
267
- putc ' '
268
- else
269
- # For objects that include Expect4r but do not subclass base Login class.
270
- @matches ||= []
271
- @matches.each { |match, _send|
272
- if r._io_string =~ match
273
- r._io_save no_echo, "match #{match}"
274
- if _send.is_a?(Proc)
275
- _send.call(self)
276
- else
277
- exp_puts _send
278
- end
279
- end
280
- }
281
- end
282
- end
283
- end
284
-
285
- case rc
286
- when :abort
287
- elapsed = Time.now - t0
288
- if elapsed < ti
289
- child_exit
290
- raise ConnectionError.new(line)
291
- else
292
- raise ExpTimeoutError.new(line, elapsed)
293
- end
294
- else
295
- @lp = buf.last
296
- end
297
- [buf, rc]
298
- end
299
234
 
300
235
  def readline(ti=0.2, matches=[])
301
236
  ret = expect(/(.+)\r\n/, ti, matches)
@@ -383,6 +318,7 @@ module Expect4r
383
318
  err_msg += buf.join("\n ")
384
319
  raise ConnectionError.new(err_msg)
385
320
  else
321
+ @_lp_1 = buf[-2]
386
322
  @lp = buf.last
387
323
  end
388
324
  [buf, ev]
@@ -457,17 +393,11 @@ module Expect4r
457
393
  raise ExpTimeoutError.new(line, elapsed)
458
394
  end
459
395
  else
396
+ @_lp_1 = buf[-2]
460
397
  @lp = buf.last
461
398
  end
462
399
  [buf, rc]
463
400
  end
464
- def ctrl_key(k)
465
- case k
466
- when ?\C-c ; '^C'
467
- when ?\C-q ; '^Q'
468
- when ?\C-z ; '^Z'
469
- end
470
- end
471
401
 
472
402
  def writer(k)
473
403
  stty_raw
@@ -494,6 +424,7 @@ module Expect4r
494
424
  break if c.nil?
495
425
  STDOUT.putc c
496
426
  end
427
+ rescue Errno::EIO
497
428
  rescue => e
498
429
  p e
499
430
  p '7777777'
@@ -6,6 +6,7 @@ module Expect4r
6
6
  autoload :Iox, 'router/cisco/iox/iox'
7
7
  autoload :Ios, 'router/cisco/ios/ios'
8
8
  autoload :J, 'router/juniper/junos/junos'
9
+ autoload :V, 'router/vyatta/vyatta'
9
10
  autoload :Shell, 'misc/shell'
10
11
  autoload :RShell, 'misc/shell'
11
12
 
@@ -31,6 +32,11 @@ module Expect4r
31
32
  module Iox
32
33
  autoload :Modes, 'router/cisco/iox/modes'
33
34
  end
35
+ module Vyatta
36
+ autoload :Modes, 'router/vyatta/modes'
37
+ autoload :Ping, 'router/vyatta/ping'
38
+ autoload :Show, 'router/vyatta/show'
39
+ end
34
40
  module Junos
35
41
  autoload :Modes, 'router/juniper/junos/modes'
36
42
  autoload :Show, 'router/juniper/junos/show'
@@ -27,7 +27,7 @@ module Ping
27
27
  # :size=> 512
28
28
  # :protocol=> 'ipv4', :count=> 20, :size=> 1500, :timeout=>5
29
29
  #
30
- def ping(target_ip_address, arg={})
30
+ def ping(target_ip_address, arg={}, &on_error)
31
31
 
32
32
  pct_success = arg.delete(:pct_success) || 99
33
33
 
@@ -47,7 +47,8 @@ module Ping
47
47
 
48
48
  end
49
49
 
50
- r = output[0].find { |x| x =~/Success.*[^\d](\d+) percent \((\d+)\/(\d+)\)/}
50
+ # r = output[0].find { |x| x =~/Success.*[^\d](\d+) percent \((\d+)\/(\d+)\)/}
51
+ r = output.join =~/Success.*[^\d](\d+) percent \((\d+)\/(\d+)\)/
51
52
 
52
53
  if r &&
53
54
  Regexp.last_match(1) &&
@@ -65,7 +66,13 @@ module Ping
65
66
  end
66
67
 
67
68
  else
68
- raise ::Expect4r::Router::Error::PingError.new(@host, target_ip_adress, pct_success, pct, tx, rx, output)
69
+
70
+ if on_error
71
+ on_error.call(self)
72
+ else
73
+ raise ::Expect4r::Router::Error::PingError.new(@host, target_ip_address, pct_success, pct, tx, rx, output)
74
+ end
75
+
69
76
  end
70
77
 
71
78
  end
@@ -21,7 +21,7 @@ module Ping
21
21
  # :size=> 512
22
22
  # :protocol=> 'ipv4', :count=> 20, :size=> 1500, :timeout=>5, :ttl=>16
23
23
  #
24
- def ping(host, arg={})
24
+ def ping(host, arg={}, &on_error)
25
25
 
26
26
  pct_success = arg.delete(:pct_success) || 99
27
27
 
@@ -45,7 +45,11 @@ module Ping
45
45
  end
46
46
 
47
47
  else
48
- raise ::Expect4r::Router::Error::PingError.new(@host, host, pct_success, $1.to_i, tx, rx, output)
48
+ if on_error
49
+ on_error.call(self)
50
+ else
51
+ raise ::Expect4r::Router::Error::PingError.new(@host, host, pct_success, $1.to_i, tx, rx, output)
52
+ end
49
53
  end
50
54
 
51
55
  end
@@ -0,0 +1,124 @@
1
+ require 'router/modes'
2
+
3
+ module Expect4r::Router::Vyatta
4
+ module Modes
5
+
6
+ # Adds a Vyatta <tt>config</tt> mixin.
7
+ #
8
+ # Example:
9
+ #
10
+ # c.config %{
11
+ # edit protocols bgp 100
12
+ # set neighbor 192.168.129.1
13
+ # set neighbor 192.168.129.1 capability orf prefix-list receive
14
+ # set neighbor 192.168.129.1 ebgp-multihop 10
15
+ # set neighbor 192.168.129.1 remote-as 200
16
+ # }
17
+ #
18
+ def config(stmts=nil, arg={})
19
+ login unless connected?
20
+ if stmts
21
+ mode = in?
22
+ to_config
23
+ output = exp_send(stmts, arg)
24
+ output << commit
25
+ change_mode_to(mode)
26
+ output.flatten
27
+ else
28
+ to_config
29
+ end
30
+ end
31
+
32
+ # Adds a Vyatta <tt>exec</tt> mixin.
33
+ #
34
+ # Example:
35
+ #
36
+ # v.exec 'set cli screen-length 0'
37
+ #
38
+ def exec(cmd=nil, *args)
39
+ login unless connected?
40
+ if cmd.nil?
41
+ to_exec
42
+ else
43
+ if config?
44
+ exp_send("run #{cmd}", *args)
45
+ elsif exec?
46
+ exp_send cmd, *args
47
+ else
48
+ mode = _mode_?
49
+ to_exec
50
+ output = exp_send(cmd, *args)
51
+ change_mode_to mode
52
+ output
53
+ end
54
+ end
55
+ end
56
+
57
+ def exec?
58
+ if logged_as_root?
59
+ ! config?
60
+ else
61
+ @lp =~ /\$ $/ ? true : false
62
+ end
63
+ end
64
+
65
+ def config?
66
+ if logged_as_root?
67
+ @_lp_1 =~ /\[edit\]/ ? true : false
68
+ else
69
+ @lp =~ /^.+# $/ ? true : false
70
+ end
71
+ end
72
+
73
+ def in?(mode=:none)
74
+ login unless connected?
75
+ case mode
76
+ when :exec ; exec?
77
+ when :config ; config?
78
+ else
79
+ _mode_?
80
+ end
81
+ end
82
+
83
+ def to_config
84
+ return :config if config?
85
+ to_exec
86
+ putline 'configure', :debug=>1
87
+ raise RuntimeError, "unable to get to config mode" unless config?
88
+ :config
89
+ end
90
+
91
+ def to_exec
92
+ return :exec if exec?
93
+ top if config?
94
+ exit
95
+ raise RuntimeError, "unable to get to exec mode" unless exec?
96
+ :exec
97
+ end
98
+
99
+ def change_mode_to(mode)
100
+ login unless connected?
101
+ case mode
102
+ when :exec ; to_exec
103
+ when :config ; to_config
104
+ end
105
+ end
106
+
107
+ private
108
+
109
+ def logged_as_root?
110
+ ! (@_is_root_ ||= (@user=='root' and @lp =~ /root@/)).nil?
111
+ end
112
+
113
+ def _mode_?
114
+ putline ' ', :no_trim=>true, :no_echo=>true unless @lp
115
+ if exec?
116
+ :exec
117
+ elsif config?
118
+ :config
119
+ else
120
+ end
121
+ end
122
+
123
+ end
124
+ end
@@ -0,0 +1,96 @@
1
+ require 'router/error'
2
+
3
+ module Expect4r::Router::Vyatta
4
+ module Ping
5
+
6
+ # Adds a ping method to V 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
+ # Example:
24
+ # v.ping('192.168.129.1', :count=>10, :size=>256) { |r| r.interact }
25
+ #--
26
+ # PING 192.168.129.1 (192.168.129.1) 56(84) bytes of data.
27
+ # 64 bytes from 192.168.129.1: icmp_req=1 ttl=64 time=0.173 ms
28
+ # 64 bytes from 192.168.129.1: icmp_req=2 ttl=64 time=0.132 ms
29
+ # 64 bytes from 192.168.129.1: icmp_req=3 ttl=64 time=0.144 ms
30
+ # 64 bytes from 192.168.129.1: icmp_req=4 ttl=64 time=0.128 ms
31
+ # 64 bytes from 192.168.129.1: icmp_req=5 ttl=64 time=0.225 ms
32
+ #
33
+ # --- 192.168.129.1 ping statistics ---
34
+ # 5 packets transmitted, 5 received, 0% packet loss, time 3996ms
35
+ # rtt min/avg/max/mdev = 0.128/0.160/0.225/0.037 ms
36
+ # vyatta@vyatta2:~$
37
+ #++
38
+ def ping(host, arg={}, &on_error)
39
+
40
+ pct_success = arg.delete(:pct_success) || 99
41
+
42
+ output = exp_send(ping_cmd(host, arg), arg)
43
+
44
+ r = output[0].find { |x| x =~/(\d+) packets transmitted, (\d+) received, (\d+)\% packet loss/}
45
+
46
+ if r &&
47
+ Regexp.last_match(1) &&
48
+ Regexp.last_match(2) &&
49
+ Regexp.last_match(3)
50
+
51
+ success = 100 - $3.to_i
52
+ tx = $2.to_i
53
+ rx = $3.to_i
54
+
55
+ if (100 - $3.to_i) < pct_success
56
+ raise ::Expect4r::Router::Error::PingError.new(@host, host, pct_success, tx, rx, output)
57
+ else
58
+ [$1.to_i,[$2.to_i,$3.to_i],output]
59
+ end
60
+
61
+ else
62
+
63
+ if on_error
64
+ on_error.call(self)
65
+ else
66
+ raise ::Expect4r::Router::Error::PingError.new(@host, host, pct_success, $1.to_i, tx, rx, output)
67
+ end
68
+
69
+ end
70
+
71
+ end
72
+
73
+ private
74
+
75
+ # vyatta@vyatta2:~$ /bin/ping
76
+ # Usage: ping [-LRUbdfnqrvVaAD] [-c count] [-i interval] [-w deadline]
77
+ # [-p pattern] [-s packetsize] [-t ttl] [-I interface]
78
+ # [-M pmtudisc-hint] [-m mark] [-S sndbuf]
79
+ # [-T tstamp-options] [-Q tos] [hop1 ...] destination
80
+ def ping_cmd(host, arg={})
81
+ arg = {:count=>5}.merge(arg)
82
+ cmd = "/bin/ping"
83
+ cmd += " -c #{arg[:count] || arg[:repeat_count]}" if arg[:count] || arg[:repeat_count]
84
+ cmd += " -s #{arg[:size] || arg[:datagram_size]}" if arg[:size] || arg[:datagram_size]
85
+ cmd += " -p #{arg[:pattern]}" if arg[:pattern]
86
+ cmd += " -Q #{arg[:tos]}" if arg[:tos]
87
+ cmd += " -t #{arg[:ttl]}" if arg[:ttl]
88
+ cmd += " -S #{arg[:sndbuf]}" if arg[:sndbuf]
89
+ cmd += " -c #{arg[:intf] || arg[:interface]}" if arg[:intf] || arg[:interface]
90
+ cmd += " -w #{arg[:deadline]}" if arg[:deadline]
91
+ cmd += " #{host}"
92
+ cmd
93
+ end
94
+
95
+ end
96
+ end
@@ -0,0 +1,23 @@
1
+
2
+ module Expect4r::Router::Vyatta
3
+ module Show
4
+
5
+ def show(s, arg={})
6
+ output = []
7
+ s.each_line { |l|
8
+ output << exec("show #{l}", arg) if l.strip.size>0
9
+ }
10
+ output
11
+ end
12
+
13
+ def method_missing(name, *args, &block)
14
+ if name.to_s =~ /^show_/
15
+ cmd = name.to_s.split('_').join(' ') + args.join(' ')
16
+ output = __send__ :exec, cmd, *args
17
+ else
18
+ super
19
+ end
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,74 @@
1
+ class Expect4r::V < ::Expect4r::BaseLoginObject
2
+ include Expect4r
3
+ include Expect4r::Router::Error
4
+ include Expect4r::Router::Common
5
+ include Expect4r::Router::Common::Modes
6
+ include Expect4r::Router::Vyatta::Modes
7
+ include Expect4r::Router::Vyatta::Ping
8
+ include Expect4r::Router::Vyatta::Show
9
+
10
+ class << self
11
+ # v = V.new_telnet 'hostname'
12
+ def new_telnet(*args)
13
+ if args.size==1 and args[0].is_a?(String)
14
+ super :host=> args[0], :user=>'vyatta', :pwd=>'vyatta'
15
+ else
16
+ super
17
+ end
18
+ end
19
+
20
+ # v = V.new_ssh 'hostname'
21
+ def new_ssh(*args)
22
+ if args.size==1 and args[0].is_a?(String)
23
+ super :host=> args[0], :user=>'vyatta', :pwd=>'vyatta'
24
+ else
25
+ super
26
+ end
27
+ end
28
+ end
29
+
30
+ def initialize(*args)
31
+ super
32
+ @ps1 = /([A-z\d]+)@([A-z\d]+)(:[^\$]+|)(#|\$) $/
33
+ end
34
+
35
+ def login(arg={})
36
+ super(spawnee, arg)
37
+ putline "terminal length 0"
38
+ putline "terminal width 0"
39
+ self
40
+ end
41
+ alias :_login_ :login
42
+
43
+ def putline(line,arg={})
44
+ o, rc = super
45
+ raise SyntaxError.new(self.class.to_s, line) if o.join =~ /(% unknown|Invalid command)/
46
+ o
47
+ end
48
+
49
+ def top
50
+ putline 'top'
51
+ end
52
+
53
+ def exit
54
+ putline 'exit'
55
+ end
56
+
57
+ def exit_discard
58
+ putline 'exit discard'
59
+ end
60
+
61
+ def commit(arg={})
62
+ return unless config?
63
+ @matches << [/Exit with uncommitted changes.+\(yes\)/, 'yes']
64
+ output = putline "commit", arg
65
+ if /error: configuration check-out failed/.match(output.join)
66
+ rollack
67
+ raise SemanticError.new(self.class.to_s, output)
68
+ end
69
+ output
70
+ end
71
+
72
+ private
73
+
74
+ end
metadata CHANGED
@@ -1,47 +1,35 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: expect4r
3
- version: !ruby/object:Gem::Version
4
- prerelease: true
5
- segments:
6
- - 0
7
- - 0
8
- - 7
9
- - dev
10
- version: 0.0.7.dev
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.8
5
+ prerelease:
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Jean-Michel Esnault
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2010-12-16 00:00:00 -08:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
12
+ date: 2012-02-20 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
22
15
  name: highline
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- segments:
29
- - 1
30
- - 5
31
- - 0
16
+ requirement: &70302466268900 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
32
21
  version: 1.5.0
33
22
  type: :runtime
34
- version_requirements: *id001
23
+ prerelease: false
24
+ version_requirements: *70302466268900
35
25
  description: A Ruby Library for interacting with IOS, IOS-XR, and JUNOS CLI.
36
26
  email: jesnault@gmail.com
37
27
  executables: []
38
-
39
28
  extensions: []
40
-
41
- extra_rdoc_files:
29
+ extra_rdoc_files:
42
30
  - LICENSE
43
31
  - README.rdoc
44
- files:
32
+ files:
45
33
  - COPYING
46
34
  - LICENSE
47
35
  - README.rdoc
@@ -67,44 +55,42 @@ files:
67
55
  - lib/router/juniper/junos/ping.rb
68
56
  - lib/router/juniper/junos/show.rb
69
57
  - lib/router/modes.rb
70
- has_rdoc: true
58
+ - lib/router/vyatta/modes.rb
59
+ - lib/router/vyatta/ping.rb
60
+ - lib/router/vyatta/show.rb
61
+ - lib/router/vyatta/vyatta.rb
62
+ - test/expect4r_test.rb
63
+ - test/misc/passwd_test.rb
64
+ - test/router/cisco/iox/iox_test.rb
71
65
  homepage: http://github.com/jesnault/expect4r
72
66
  licenses: []
73
-
74
67
  post_install_message:
75
- rdoc_options:
68
+ rdoc_options:
76
69
  - --quiet
77
70
  - --title
78
71
  - Expect4r
79
72
  - --line-numbers
80
- require_paths:
73
+ require_paths:
81
74
  - lib
82
- required_ruby_version: !ruby/object:Gem::Requirement
83
- requirements:
84
- - - ">="
85
- - !ruby/object:Gem::Version
86
- segments:
87
- - 1
88
- - 8
89
- - 6
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ! '>='
79
+ - !ruby/object:Gem::Version
90
80
  version: 1.8.6
91
- required_rubygems_version: !ruby/object:Gem::Requirement
92
- requirements:
93
- - - ">"
94
- - !ruby/object:Gem::Version
95
- segments:
96
- - 1
97
- - 3
98
- - 1
99
- version: 1.3.1
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
100
87
  requirements: []
101
-
102
88
  rubyforge_project:
103
- rubygems_version: 1.3.6
89
+ rubygems_version: 1.8.10
104
90
  signing_key:
105
91
  specification_version: 3
106
92
  summary: Expect4r
107
- test_files:
93
+ test_files:
108
94
  - test/expect4r_test.rb
109
95
  - test/misc/passwd_test.rb
110
96
  - test/router/cisco/iox/iox_test.rb