expect4r 0.0.7.dev → 0.0.8

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