expect4r 0.0.1.dev → 0.0.2.dev

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -13,7 +13,7 @@ You talk to routers by connecting to them using ssh or telnet and send exec or c
13
13
  j = J.new_telnet :host=> '', :user=> 'lab', :pwd => 'lab'
14
14
  j.login
15
15
 
16
- * Push configigurations to routers
16
+ * Push configurations to routers
17
17
 
18
18
  ios.config 'no logging console'
19
19
 
data/lib/expect/io.rb CHANGED
@@ -52,8 +52,8 @@ end
52
52
  module Expect4r
53
53
 
54
54
  class ConnectionError < RuntimeError
55
- def initialize(output)
56
- @output = output
55
+ def initialize(*args)
56
+ @output = args[0]
57
57
  end
58
58
  def err_msg
59
59
  "Connection Error: #{@output}"
@@ -61,22 +61,20 @@ module Expect4r
61
61
  end
62
62
 
63
63
  class ExpTimeoutError < RuntimeError
64
- def initialize(output, elapsed)
65
- @output, @elapsed = output, elapsed
64
+ def initialize(*args)
65
+ @output, @timeout = args
66
66
  end
67
67
  def err_msg
68
- "Timeout Error: #{@output}"
68
+ "Timeout Error: timeout= #{@timeout}: #{@output}"
69
69
  end
70
70
  end
71
71
 
72
- class NoChildError < RuntimeError
73
- end
74
72
  class SpawnError < RuntimeError
75
- def initialize(cmd)
76
- @cmd = cmd
73
+ def initialize(*args)
74
+ @cmd = args[0]
77
75
  end
78
76
  def err_msg
79
- "Error: #{msg}"
77
+ "Spawn Error: #{@cmd}"
80
78
  end
81
79
  end
82
80
  class Expect4rIO_Error < RuntimeError
@@ -96,7 +94,6 @@ module Expect4r
96
94
  def spawn(cmd)
97
95
  begin
98
96
  child_exited = false
99
- # STDOUT.puts "*** FALSE ***"
100
97
  @thread = Thread.new do
101
98
  PTY.spawn(cmd) do |pipe_read, pipe_write, pid|
102
99
  @r, @w, @pid = pipe_read, pipe_write, pid
@@ -109,7 +106,6 @@ module Expect4r
109
106
  end
110
107
  end
111
108
  @thread.priority = -2
112
- # STDOUT.puts "*** #{child_exited} ***"
113
109
  unless child_exited
114
110
  while @r.nil?
115
111
  sleep(0.05)
@@ -122,6 +118,7 @@ module Expect4r
122
118
 
123
119
  def logout
124
120
  child_exit
121
+ @pid
125
122
  end
126
123
 
127
124
  def putc(c)
@@ -136,6 +133,7 @@ module Expect4r
136
133
  def exp_puts(s)
137
134
  exp_print "#{s}\r"
138
135
  end
136
+
139
137
  def exp_print(s)
140
138
  exp_internal "print: #{s.inspect}, io_writer: #{@w}"
141
139
  return unless @w
@@ -192,7 +190,7 @@ module Expect4r
192
190
  end
193
191
  end
194
192
  exp_internal "#{ev.inspect} buf: #{buf.inspect}"
195
- raise RuntimeError, buf if ev == :timeout
193
+ raise ExpTimeoutError.new(buf, ti) if ev == :timeout
196
194
  [buf, ev]
197
195
  end
198
196
 
@@ -244,9 +242,10 @@ module Expect4r
244
242
  when :abort
245
243
  elapsed = Time.now - t0
246
244
  if elapsed < timeout
245
+ child_exit
247
246
  raise ConnectionError.new(c)
248
247
  else
249
- raise ExpTimeoutError.new(c, elapsed)
248
+ raise ExpTimeoutError.new(c, timeout)
250
249
  end
251
250
  else
252
251
  @lp = buf.last
@@ -260,8 +259,8 @@ module Expect4r
260
259
  #FIXME ? putline to send_cmd ?
261
260
  # hide putline and expose cmd
262
261
  def putline(line, arg={})
263
- raise NoChildError if child_exited?
264
-
262
+ raise ConnectionError.new(line) if child_exited?
263
+
265
264
  arg = {:ti=>13, :no_echo=>false, :debug=>0, :sync=> false, :no_trim=>false}.merge(arg)
266
265
  no_echo = arg[:no_echo]
267
266
  ti = arg[:ti]
@@ -306,6 +305,7 @@ module Expect4r
306
305
  when :abort
307
306
  elapsed = Time.now - t0
308
307
  if elapsed < ti
308
+ child_exit
309
309
  raise ConnectionError.new(line)
310
310
  else
311
311
  raise ExpTimeoutError.new(line, elapsed)
data/lib/expect4r.rb CHANGED
@@ -32,7 +32,7 @@ module Expect4r
32
32
  end
33
33
  module Junos
34
34
  autoload :Modes, 'router/juniper/junos/modes'
35
- autoload :Show, 'router/juniper/junos/show'
35
+ autoload :Show, 'router/juniper/junos/show'
36
36
  end
37
37
  end
38
38
 
@@ -19,6 +19,19 @@ module CiscoCommon
19
19
  @lp =~ /\(config(|.+)\)/
20
20
  Regexp.last_match(1).size == 0
21
21
  end
22
+
23
+ def method_missing(name, *args, &block)
24
+ if name.to_s =~ /^show_/
25
+ cmd = name.to_s.split('_').join(' ') + args.join(' ')
26
+ cmd.gsub!(/running config/, 'running-config')
27
+ output = __send__ :exec, cmd, *args
28
+ elsif name.to_s =~ /^shell_/
29
+ cmd = name.to_s.split('_')[1..-1].join(' ') + args.join(' ')
30
+ output = __send__ :shell, cmd, *args
31
+ else
32
+ super
33
+ end
34
+ end
22
35
 
23
36
  end
24
37
  end
@@ -3,37 +3,106 @@ require 'router/error'
3
3
  module Expect4r::Router::CiscoCommon
4
4
  module Ping
5
5
  include ::Expect4r::Router::Error
6
- def ping(arg={})
7
- if arg.is_a?(Hash)
8
- arg = {:pct_success=>100}.merge(arg)
9
- pct_success = arg[:pct_success]
10
- else
11
- pct_success = 100
12
- end
13
- case arg
14
- when String
15
- dest = arg
16
- when Hash
17
- dest = arg[:dest]
6
+
7
+ def ping(target_ip_address, arg={})
8
+
9
+ pct_success = arg.delete(:pct_success) || 99
10
+
11
+ if arg.empty?
12
+
13
+ output = exec "ping #{target_ip_address}", arg
14
+
18
15
  else
19
- raise ArgumentError, "Invalid argument: #{arg.inspect}"
16
+
17
+ @matches = Set.new
18
+
19
+ set_ping_base_matches target_ip_address, arg
20
+ set_ping_extended_matches arg
21
+ set_ping_sweep_matches arg
22
+
23
+ output = exec "ping", arg
24
+
20
25
  end
21
- output = exec "ping #{dest}", arg
26
+
22
27
  r = output[0].find { |x| x =~/Success.*[^\d](\d+) percent \((\d+)\/(\d+)\)/}
28
+
23
29
  if r &&
24
- Regexp.last_match(1) &&
25
- Regexp.last_match(2) &&
26
- Regexp.last_match(3)
27
-
28
- if $1.to_i < pct_success
29
- raise PingError('router name here', dest, pct_success, $1.to_i, $2.to_i,$3.to_i, output)
30
- else
31
- [$1.to_i,[$2.to_i,$3.to_i],output]
32
- end
33
-
30
+ Regexp.last_match(1) &&
31
+ Regexp.last_match(2) &&
32
+ Regexp.last_match(3)
33
+
34
+ pct = $1.to_i
35
+ tx = $3.to_i
36
+ rx = $2.to_i
37
+
38
+ if $1.to_i < pct_success
39
+ raise ::Expect4r::Router::Error::PingError.new(@host, target_ip_address, pct_success, pct, tx, rx, output)
40
+ else
41
+ [$1.to_i,[$2.to_i,$3.to_i],output]
42
+ end
43
+
34
44
  else
35
- raise PingError.new('router name here', dest, pct_success, $1.to_i, $2.to_i,$3.to_i, output)
45
+ raise ::Expect4r::Router::Error::PingError.new(@host, target_ip_adress, pct_success, pct, tx, rx, output)
36
46
  end
47
+
37
48
  end
49
+
50
+ private
51
+
52
+ def set_ping_base_matches(target_ip_address, arg={})
53
+ protocol = arg[:protocol] || ''
54
+ repeat_count = arg[:repeat_count] || arg[:count] || ''
55
+ datagram_size = arg[:datagram_size] || arg[:size] || ''
56
+ timeout = arg[:timeout] || ''
57
+ @matches << [/Protocol.+\: $/, protocol]
58
+ @matches << [/Target IP address\: $/, target_ip_address]
59
+ @matches << [/Repeat count.+\: $/, repeat_count]
60
+ @matches << [/Datagram size.+\: $/, datagram_size]
61
+ @matches << [/Timeout.+\: $/, timeout]
62
+ end
63
+
64
+ def set_ping_extended_matches(arg={})
65
+ extended_keys = [:source_address, :tos, :df, :pattern]
66
+ if (extended_keys & arg.keys).empty? and ! arg[:source_address]
67
+ @matches << [/Extended.+\: $/, '']
68
+ else
69
+ src_adr = arg[:source_address]
70
+ tos = arg[:tos] || ''
71
+ df = arg[:df] || ''
72
+ pattern = arg[:pattern] || ''
73
+ @matches << [/Extended.+\: $/, 'yes']
74
+ @matches << [/Source address or interface\: $/, src_adr]
75
+ @matches << [/Type of service.+\: $/, tos]
76
+ @matches << [/Set DF bit.+\: $/, df]
77
+ @matches << [/Data pattern.+\: $/, pattern]
78
+ @matches << [/Validate reply.+\: $/, ''] #TODO
79
+ @matches << [/Loose, Strict,.+\: $/, ''] #TODO
80
+ end
81
+ end
82
+
83
+ def set_ping_sweep_matches(arg={})
84
+ sweep_keys = [:sweep_min_size, :sweep_max_size, :sweep_interval]
85
+ if (sweep_keys & arg.keys).empty?
86
+ @matches << [/Sweep range of sizes.+: $/, 'no']
87
+ else
88
+ min_size = arg[:sweep_min_size] || ''
89
+ max_size = arg[:sweep_max_size] || ''
90
+ interval = arg[:sweep_interval] || ''
91
+ @matches << [/Sweep range of sizes.+: $/, 'yes']
92
+ @matches << [/Sweep min size.+\: $/, min_size]
93
+ @matches << [/Sweep max size.+\: $/, max_size]
94
+ @matches << [/Sweep interval.+\: $/, interval]
95
+ end
96
+ end
97
+
38
98
  end
39
99
  end
100
+
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
+
@@ -3,20 +3,13 @@ module Show
3
3
 
4
4
  def show(s, arg={})
5
5
  output = []
6
+ nlines = 0
6
7
  s.each_line { |l|
8
+ next unless l.strip.size>0
7
9
  output << exec("show #{l}", arg) if l.strip.size>0
10
+ nlines +=1
8
11
  }
9
- output
10
- end
11
-
12
- def method_missing(name, *args, &block)
13
- if name.to_s =~ /^show_/
14
- cmd = name.to_s.split('_').join(' ') + args.join(' ')
15
- cmd.gsub!(/running config/, 'running-config')
16
- output = __send__ :exec, cmd, *args
17
- else
18
- super
19
- end
12
+ nlines > 1 ? output : output[0]
20
13
  end
21
14
 
22
15
  end
@@ -1,3 +1,5 @@
1
+ require 'router/cisco/common/common'
2
+
1
3
  class Expect4r::Ios < ::Expect4r::BaseObject
2
4
 
3
5
  include Expect4r
@@ -59,7 +61,8 @@ class Expect4r::Ios < ::Expect4r::BaseObject
59
61
  end
60
62
 
61
63
  def error?(output)
62
- string_start_with_pct_char?(output[-2]) || string_start_with_pct_char?(output[-3])
64
+ string_start_with_pct_char?(output[-2]) ||
65
+ string_start_with_pct_char?(output[-3])
63
66
  end
64
67
 
65
68
  end
@@ -1,3 +1,6 @@
1
+
2
+ require 'router/cisco/common/common'
3
+
1
4
  class Expect4r::Iox < ::Expect4r::BaseObject
2
5
 
3
6
  include Expect4r
@@ -28,14 +31,14 @@ class Expect4r::Iox < ::Expect4r::BaseObject
28
31
  if /\% Failed to commit/.match(output.join)
29
32
  err = show_configuration_failed
30
33
  abort_config
31
- raise Iox::SemanticError.new(show_configuration_failed)
34
+ raise Iox::SemanticError.new(self.class.to_s, show_configuration_failed)
32
35
  end
33
36
  output
34
37
  end
35
38
 
36
39
  def putline(line,*args)
37
40
  output, rc = super
38
- raise SyntaxError.new(line) if output.join =~ /\% Invalid input detected at/
41
+ raise SyntaxError.new(self.class.to_s, line) if output.join =~ /\% Invalid input detected at/
39
42
  output
40
43
  end
41
44
 
@@ -5,6 +5,7 @@ class Expect4r::J < ::Expect4r::BaseObject
5
5
  include Expect4r::Router::Common::Modes
6
6
  include Expect4r::Router::Junos::Modes
7
7
  include Expect4r::Router::Junos::Show
8
+ include Expect4r::Router::Junos::Ping
8
9
 
9
10
  def initialize(*args)
10
11
  super
@@ -0,0 +1,120 @@
1
+ require 'router/error'
2
+
3
+ module Expect4r::Router::Junos
4
+ module Ping
5
+
6
+ def ping(host, arg={})
7
+
8
+ pct_success = arg.delete(:pct_success) || 99
9
+
10
+ output = exec(ping_cmd(host, arg), arg)
11
+
12
+ r = output[0].find { |x| p x ; x =~/(\d+) packets transmitted, (\d+) packets received, (\d+)\% packet loss/}
13
+
14
+ if r &&
15
+ Regexp.last_match(1) &&
16
+ Regexp.last_match(2) &&
17
+ Regexp.last_match(3)
18
+
19
+ success = 100 - $3.to_i
20
+ tx = $2.to_i
21
+ rx = $3.to_i
22
+
23
+ if (100 - $3.to_i) < pct_success
24
+ raise ::Expect4r::Router::Error::PingError.new(@host, host, pct_success, tx, rx, output)
25
+ else
26
+ [$1.to_i,[$2.to_i,$3.to_i],output]
27
+ end
28
+
29
+ else
30
+ raise ::Expect4r::Router::Error::PingError.new(@host, host, pct_success, $1.to_i, tx, rx, output)
31
+ end
32
+
33
+ end
34
+
35
+ private
36
+
37
+ def ping_cmd(host, arg={})
38
+ cmd = "ping #{host}"
39
+ cmd += " rapid"
40
+ cmd += " count #{arg[:count] || arg[:repeat_count]}" if arg[:count] || arg[:repeat_count]
41
+ cmd += " size #{arg[:size] || arg[:datagram_size]}" if arg[:size] || arg[:datagram_size]
42
+ cmd += " pattern #{arg[:pattern]}" if arg[:pattern]
43
+ cmd += " tos #{arg[:tos]}" if arg[:tos]
44
+ cmd += " ttl #{arg[:ttl]}" if arg[:ttl]
45
+ cmd
46
+ end
47
+
48
+ end
49
+ end
50
+
51
+ __END__
52
+
53
+
54
+ if __FILE__ == $0
55
+
56
+ module Expect4r
57
+ module Router
58
+ module Junos
59
+ end
60
+ end
61
+ end
62
+
63
+ end
64
+
65
+ if __FILE__ == $0
66
+
67
+ require "test/unit"
68
+
69
+ class TestLibraryFileName < Test::Unit::TestCase
70
+ include Expect4r::Router::Junos::Ping
71
+ def test_case_name
72
+
73
+ assert_equal 'ping 1.1.1.1 rapid', ping_cmd( '1.1.1.1')
74
+ assert_equal 'ping 1.1.1.1 rapid size 256', ping_cmd( '1.1.1.1', :size=>256)
75
+ assert_equal 'ping 1.1.1.1 rapid size 256', ping_cmd( '1.1.1.1', :datagram_size=>256)
76
+ assert_equal 'ping 1.1.1.1 rapid pattern 0xdead', ping_cmd( '1.1.1.1', :pattern=>'0xdead')
77
+ assert_equal 'ping 1.1.1.1 rapid tos 2', ping_cmd( '1.1.1.1', :tos=>2)
78
+ assert_equal 'ping 1.1.1.1 rapid ttl 2', ping_cmd( '1.1.1.1', :ttl=>2)
79
+
80
+ end
81
+ end
82
+
83
+ end
84
+
85
+
86
+ __END__
87
+
88
+ 5 packets transmitted, 5 packets received, 0% packet loss
89
+ round-trip min/avg/max/stddev = 1.483/17.024/78.904/30.940 ms
90
+
91
+
92
+
93
+ Possible completions:
94
+ <host> Hostname or IP address of remote host
95
+ atm Ping remote Asynchronous Transfer Mode node
96
+ bypass-routing Bypass routing table, use specified interface
97
+ count Number of ping requests to send (1..2000000000 packets)
98
+ detail Display incoming interface of received packet
99
+ do-not-fragment Don't fragment echo request packets (IPv4)
100
+ inet Force ping to IPv4 destination
101
+ inet6 Force ping to IPv6 destination
102
+ interface Source interface (multicast, all-ones, unrouted packets)
103
+ interval Delay between ping requests (seconds)
104
+ logical-router Name of logical router
105
+ + loose-source Intermediate loose source route entry (IPv4)
106
+ mpls Ping label-switched path
107
+ no-resolve Don't attempt to print addresses symbolically
108
+ pattern Hexadecimal fill pattern
109
+ rapid Send requests rapidly (default count of 5)
110
+ record-route Record and report packet's path (IPv4)
111
+ routing-instance Routing instance for ping attempt
112
+ size Size of request packets (0..65468 bytes)
113
+ source Source address of echo request
114
+ strict Use strict source route option (IPv4)
115
+ + strict-source Intermediate strict source route entry (IPv4)
116
+ tos IP type-of-service value (0..255)
117
+ ttl IP time-to-live value (IPv6 hop-limit value) (hops)
118
+ verbose Display detailed output
119
+ vpls Ping VPLS MAC address
120
+ wait Delay after sending last packet (seconds)
metadata CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 1
8
+ - 2
9
9
  - dev
10
- version: 0.0.1.dev
10
+ version: 0.0.2.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-24 00:00:00 -07:00
18
+ date: 2010-10-25 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, IosXR, 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
 
@@ -61,10 +61,11 @@ files:
61
61
  - lib/router/error.rb
62
62
  - lib/router/juniper/junos/junos.rb
63
63
  - lib/router/juniper/junos/modes.rb
64
+ - lib/router/juniper/junos/ping.rb
64
65
  - lib/router/juniper/junos/show.rb
65
66
  - lib/router/modes.rb
66
67
  has_rdoc: true
67
- homepage:
68
+ homepage: http://github.com/jesnault/expect4r
68
69
  licenses: []
69
70
 
70
71
  post_install_message: