expect4r 0.0.1.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.
@@ -0,0 +1,42 @@
1
+
2
+ require 'rubygems'
3
+ require 'highline/import'
4
+ require 'misc/passwd'
5
+
6
+ module Expect4r::Router
7
+ module Common
8
+
9
+ def console?
10
+ @port.to_i > 0
11
+ end
12
+
13
+ def io_escape_char_cb
14
+ putc "\n" if console?
15
+ end
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
+ end
42
+ end
@@ -0,0 +1,76 @@
1
+ module Expect4r::Router
2
+ module Error
3
+ class RouterError < RuntimeError
4
+ def initialize(rname, msg)
5
+ @rname = rname
6
+ @msg = msg
7
+ end
8
+ def err_msg
9
+ "#{@rname} [Error] : #{@msg}"
10
+ end
11
+ end
12
+
13
+ class SyntaxError < RouterError
14
+ def err_msg
15
+ "#{@rname} [SyntaxError] : #{@msg}"
16
+ end
17
+ end
18
+
19
+ class SemanticError < RouterError
20
+ def err_msg
21
+ "#{@rname} [SemanticError] : #{@msg}"
22
+ end
23
+ end
24
+
25
+ class PingError < RuntimeError
26
+ attr_reader :rname, :dest, :exp_pct, :act_pct, :sent, :recv
27
+ def initialize(rname, dest, exp_pct, act_pct, sent, recv, output)
28
+ @rname, @dest, @exp_pct, @act_pct, @sent, @recv = rname, dest, exp_pct, act_pct, sent, recv
29
+ end
30
+ def err_msg
31
+ "#{@rname} [PingError] : failed to ping #{@dest}, expected/actual pct: #{@exp_pct}/#{@act_pct}"
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+
38
+ if __FILE__ == $0
39
+
40
+ require "test/unit"
41
+
42
+ # require "router/error"
43
+
44
+ class TestRouterError < Test::Unit::TestCase
45
+ include Expect4r::Router::Error
46
+ def test_raise
47
+ assert_raise(RouterError) {raise RouterError.new('paris','show bogus command')}
48
+ assert_err_msg 'paris [Error] : show bogus command', lambda {raise RouterError.new('paris','show bogus command')}
49
+ assert_err_msg 'paris [SyntaxError] : show bogus command', lambda {raise SyntaxError.new('paris','show bogus command')}
50
+ assert_err_msg 'paris [SemanticError] : show bogus command', lambda {raise SemanticError.new('paris','show bogus command')}
51
+ assert_err_msg 'paris [PingError] : failed to ping 1.1.1.1, expected/actual pct: 100/90', lambda {raise PingError.new('paris','1.1.1.1', 100, 90, 10, 9, '')}
52
+ assert_equal 100, exception(lambda {raise PingError.new('paris','1.1.1.1', 100, 90, 10, 9,'')}).exp_pct
53
+ assert_equal 'paris', exception(lambda {raise PingError.new('paris','1.1.1.1', 100, 90, 10, 9,'')}).rname
54
+ end
55
+
56
+ private
57
+
58
+ def assert_err_msg(err_msg, block)
59
+ begin
60
+ block.call
61
+ rescue RouterError, PingError => re
62
+ assert_equal err_msg, re.err_msg
63
+ end
64
+ end
65
+
66
+ def exception(block)
67
+ begin
68
+ block.call
69
+ rescue RouterError, PingError => re
70
+ re
71
+ end
72
+ end
73
+
74
+ end
75
+
76
+ end
@@ -0,0 +1,53 @@
1
+ class Expect4r::J < ::Expect4r::BaseObject
2
+ include Expect4r
3
+ include Expect4r::Router::Error
4
+ include Expect4r::Router::Common
5
+ include Expect4r::Router::Common::Modes
6
+ include Expect4r::Router::Junos::Modes
7
+ include Expect4r::Router::Junos::Show
8
+
9
+ def initialize(*args)
10
+ super
11
+ @ps1 = /(^|\r\r)([-a-zA-z@_~=\.\(\)\d]+(>|\#|%)|%|\$) $/
12
+ @more = /---\(more(| \d+\%)\)---/
13
+ end
14
+
15
+ def login
16
+ ENV['TERM']='dumb'
17
+ super(spawnee)
18
+ exec 'set cli screen-length 0'
19
+ self
20
+ end
21
+
22
+ def console?
23
+ @port>0
24
+ end
25
+
26
+ def putline(line,arg={})
27
+ o, rc = super
28
+ raise SyntaxError.new(self.class.to_s, line) if o.join =~ /(unknown command|syntax error)\./
29
+ o
30
+ end
31
+
32
+ def top
33
+ putline 'top'
34
+ end
35
+
36
+ def exit
37
+ putline 'exit'
38
+ end
39
+
40
+ def commit(arg={})
41
+ return unless config?
42
+ @matches << [/Exit with uncommitted changes.+\(yes\)/, 'yes']
43
+ output = putline "commit", arg
44
+ if /error: configuration check-out failed/.match(output.join)
45
+ putline 'rollback'
46
+ raise SemanticError.new(self.class.to_s, output)
47
+ end
48
+ output
49
+ end
50
+
51
+ private
52
+
53
+ end
@@ -0,0 +1,109 @@
1
+ require 'router/modes'
2
+
3
+ module Expect4r::Router::Junos
4
+ module Modes
5
+
6
+ def config(stmts=nil, arg={})
7
+ login unless connected?
8
+ if stmts
9
+ mode = in?
10
+ to_config
11
+ output = exp_send(stmts, arg)
12
+ output << commit
13
+ change_mode_to(mode)
14
+ output
15
+ else
16
+ mode
17
+ end
18
+ end
19
+
20
+ def exec(cmd=nil, *args)
21
+ login unless connected?
22
+ if cmd.nil?
23
+ to_exec
24
+ else
25
+ if config?
26
+ exp_send("run #{cmd}", *args)
27
+ elsif exec?
28
+ exp_send cmd, *args
29
+ else
30
+ mode = _mode_?
31
+ to_exec
32
+ output = exp_send(cmd, *args)
33
+ change_mode_to mode
34
+ output
35
+ end
36
+ end
37
+ end
38
+
39
+ def shell(cmd=nil, *args)
40
+ connected = connected?
41
+ login unless connected?
42
+ if cmd.nil?
43
+ to_shell
44
+ else
45
+ mode = _mode_?
46
+ to_shell
47
+ output = exp_send(cmd, *args)
48
+ change_mode_to mode
49
+ output
50
+ end
51
+ end
52
+
53
+ def exec?
54
+ @lp =~ /> $/ ? true : false
55
+ end
56
+
57
+ def config?
58
+ @lp =~ /^.+# $/ ? true : false
59
+ end
60
+
61
+ def shell?
62
+ @lp == '% ' ? true : false
63
+ end
64
+
65
+ def set_cli_logical_router(logical_router)
66
+ return if @ps1_bis
67
+ to_exec
68
+ arr= @lp.split(">")
69
+ @ps1_bis = /#{arr[0]}:#{logical_router}(\#|>)\s*$/
70
+ p @ps1_bis
71
+ putline "set cli logical-router #{logical_router}"
72
+ end
73
+
74
+ def clear_cli_logical_router()
75
+ return unless @ps1_bis
76
+ to_exec
77
+ @ps1_bis=nil
78
+ putline "clear cli logical-router"
79
+ end
80
+
81
+ private
82
+
83
+ def to_config
84
+ return :config if config?
85
+ to_exec
86
+ putline 'edit', :debug=>1
87
+ raise RuntimeError, "unable to got to config mode" unless config?
88
+ :config
89
+ end
90
+
91
+ def to_shell
92
+ return in? if @ps1_bis
93
+ return :shell if shell?
94
+ to_exec
95
+ putline 'start shell'
96
+ raise RuntimeError, "unable to got to shell mode" unless shell?
97
+ :shell
98
+ end
99
+
100
+ def to_exec
101
+ return :exec if exec?
102
+ top if config?
103
+ exit
104
+ raise RuntimeError, "unable to got to exec mode" unless exec?
105
+ :exec
106
+ end
107
+
108
+ end
109
+ end
@@ -0,0 +1,23 @@
1
+
2
+ module Expect4r::Router::Junos
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,37 @@
1
+ module Expect4r
2
+ module Router
3
+ module Common
4
+ module Modes
5
+ def in?(mode=:none)
6
+ login unless connected?
7
+ case mode
8
+ when :exec ; exec?
9
+ when :shell ; shell?
10
+ when :config ; config?
11
+ else
12
+ _mode_?
13
+ end
14
+ end
15
+ def change_mode_to(mode)
16
+ login unless connected?
17
+ case mode
18
+ when :exec ; to_exec
19
+ when :shell ; to_shell
20
+ when :config ; to_config
21
+ end
22
+ end
23
+ def _mode_?
24
+ putline ' ', :no_trim=>true, :no_echo=>true unless @lp
25
+ if exec?
26
+ :exec
27
+ elsif config?
28
+ :config
29
+ elsif shell?
30
+ :shell
31
+ else
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,9 @@
1
+ require "test/unit"
2
+ require "misc/passwd"
3
+
4
+ class TestMiscPasswd < Test::Unit::TestCase
5
+ def test_cipher
6
+ assert_not_equal 'my password', Expect4r.cipher('my password')
7
+ assert_equal 'my password', Expect4r.decipher(Expect4r.cipher('my password'))
8
+ end
9
+ end
@@ -0,0 +1,67 @@
1
+ require "test/unit"
2
+
3
+ require "router/cisco/iox/iox"
4
+
5
+ class TestRouterCiscoIoxIox < Test::Unit::TestCase
6
+ def test_new_hash_terse
7
+ x = Iox.new :ssh,
8
+ :host=> '1.1.1.1',
9
+ :user=> 'username',
10
+ :pwd=> 'lab',
11
+ :method=> :ssh
12
+ assert_equal '1.1.1.1', x.host
13
+ assert_equal '1.1.1.1', x.hostname
14
+ assert_equal 0, x.port
15
+ assert_equal 'username', x.user
16
+ assert_equal 'username', x.username
17
+ assert_raise(NoMethodError) { x.pwd }
18
+ assert_not_equal "lab", x.instance_eval { @pwd }
19
+ end
20
+ def test_new_hash
21
+ x = Iox.new :ssh,
22
+ :hostname=> '1.1.1.1',
23
+ :username=> 'username',
24
+ :password=> 'lab'
25
+ assert_equal '1.1.1.1', x.host
26
+ assert_equal '1.1.1.1', x.hostname
27
+ assert_equal 0, x.port
28
+ assert_equal 'username', x.user
29
+ assert_equal 'username', x.username
30
+ assert_raise(NoMethodError) { x.pwd }
31
+ assert_not_equal "lab", x.instance_eval { @pwd }
32
+ assert_equal :ssh, x.instance_eval { @method }
33
+ end
34
+ def test_new
35
+ x = Iox.new :telnet, '1.1.1.1 4002', 'username', 'lab'
36
+ assert_equal '1.1.1.1', x.host
37
+ assert_equal 4002, x.port
38
+ assert_equal '1.1.1.1', x.hostname
39
+ assert_equal 'username', x.user
40
+ assert_equal 'username', x.username
41
+ assert_raise(NoMethodError) { x.pwd }
42
+ assert_not_equal "lab", x.instance_eval { @pwd }
43
+ assert_equal :telnet, x.instance_eval { @method }
44
+ end
45
+ def test_new_ssh
46
+ x = Iox.new_ssh :hostname=> '1.1.1.1'
47
+ assert_equal '1.1.1.1', x.host
48
+ assert_equal '1.1.1.1', x.hostname
49
+ assert_equal 0, x.port
50
+ assert_nil x.user
51
+ assert_nil x.username
52
+ assert_raise(NoMethodError) { x.pwd }
53
+ assert_not_equal "lab", x.instance_eval { @pwd }
54
+ assert_equal :ssh, x.instance_eval { @method }
55
+ end
56
+ def test_new_telnet
57
+ x = Iox.new_telnet :hostname=> '1.1.1.1'
58
+ assert_equal '1.1.1.1', x.host
59
+ assert_equal '1.1.1.1', x.hostname
60
+ assert_equal 0, x.port
61
+ assert_nil x.user
62
+ assert_nil x.username
63
+ assert_raise(NoMethodError) { x.pwd }
64
+ assert_not_equal "lab", x.instance_eval { @pwd }
65
+ assert_equal :telnet, x.instance_eval { @method }
66
+ end
67
+ end
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: expect4r
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: true
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ - dev
10
+ version: 0.0.1.dev
11
+ platform: ruby
12
+ authors:
13
+ - Jean-Michel Esnault
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-10-24 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ 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
32
+ version: 1.5.0
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ description: A Ruby Library for interacting with Ios, IosXR, and Junos CLI.
36
+ email: jesnault@gmail.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - LICENSE
43
+ - README.rdoc
44
+ files:
45
+ - COPYING
46
+ - LICENSE
47
+ - README.rdoc
48
+ - lib/expect/io.rb
49
+ - lib/expect4r.rb
50
+ - lib/misc/passwd.rb
51
+ - lib/misc/shell.rb
52
+ - lib/router/cisco/common/common.rb
53
+ - lib/router/cisco/common/ping.rb
54
+ - lib/router/cisco/common/show.rb
55
+ - lib/router/cisco/ios/ios.rb
56
+ - lib/router/cisco/ios/modes.rb
57
+ - lib/router/cisco/ios/termserver.rb
58
+ - lib/router/cisco/iox/iox.rb
59
+ - lib/router/cisco/iox/modes.rb
60
+ - lib/router/common.rb
61
+ - lib/router/error.rb
62
+ - lib/router/juniper/junos/junos.rb
63
+ - lib/router/juniper/junos/modes.rb
64
+ - lib/router/juniper/junos/show.rb
65
+ - lib/router/modes.rb
66
+ has_rdoc: true
67
+ homepage:
68
+ licenses: []
69
+
70
+ post_install_message:
71
+ rdoc_options:
72
+ - --quiet
73
+ - --title
74
+ - Expect4r
75
+ - --line-numbers
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ segments:
83
+ - 1
84
+ - 8
85
+ - 7
86
+ version: 1.8.7
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">"
90
+ - !ruby/object:Gem::Version
91
+ segments:
92
+ - 1
93
+ - 3
94
+ - 1
95
+ version: 1.3.1
96
+ requirements: []
97
+
98
+ rubyforge_project:
99
+ rubygems_version: 1.3.6
100
+ signing_key:
101
+ specification_version: 3
102
+ summary: Expect4r
103
+ test_files:
104
+ - test/misc/passwd_test.rb
105
+ - test/router/cisco/iox/iox_test.rb