net-netconf 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,13 +3,13 @@ require 'net/netconf/serial'
3
3
  require 'net/netconf/jnpr'
4
4
 
5
5
  module Netconf
6
- module Junos
7
- module TransSerial
6
+ module Junos
7
+ module TransSerial
8
8
  def trans_start_netconf( last_console )
9
9
  last_console.match(/[^%]\s+$/)
10
10
  netconf_cmd = ($1 == '%') ? Netconf::Junos::NETCONF_SHELL : Netconf::Junos::NETCONF_CLI
11
11
  puts netconf_cmd
12
- end
13
- end
12
+ end
13
+ end
14
14
  end
15
15
  end
@@ -2,26 +2,26 @@ require 'net/netconf'
2
2
  require 'net/netconf/jnpr'
3
3
 
4
4
  module Netconf
5
- module Junos
5
+ module Junos
6
6
  module TransSSH
7
-
7
+
8
8
  ##
9
9
  ## this is used to handle the case where NETCONF (port 830) is disabled. We can still access
10
10
  ## the NETCONF subsystem from the CLI using a hidden command 'netconf'
11
11
  ##
12
-
13
- def trans_on_connect_refused( start_args )
14
- start_args[:port] = 22
12
+
13
+ def trans_on_connect_refused( start_args )
14
+ start_args[:port] = 22
15
15
  @trans[:conn] = Net::SSH.start( @args[:target], @args[:username], start_args )
16
16
  do_once = true
17
- @trans[:conn].exec( NETCONF_CLI ) do |chan, success|
17
+ @trans[:conn].exec( NETCONF_CLI ) do |chan, success|
18
18
  @trans[:chan] = chan
19
19
  do_once = false
20
20
  end
21
- @trans[:conn].loop { do_once }
21
+ @trans[:conn].loop { do_once }
22
22
  @trans[:chan]
23
23
  end
24
-
24
+
25
25
  end
26
- end
27
- end
26
+ end
27
+ end
@@ -3,21 +3,21 @@ require 'net/netconf/telnet'
3
3
  require 'net/netconf/jnpr'
4
4
 
5
5
  module Netconf
6
- module Junos
6
+ module Junos
7
7
  module TransTelnet
8
-
8
+
9
9
  def trans_login
10
10
  l_rsp = @trans.login( @args[:username], @args[:password] )
11
- # @@@/JLS: need to rescue the timeout ... ???
11
+ # @@@/JLS: need to rescue the timeout ... ???
12
12
  l_rsp.match("([>%])\s+$")
13
13
  @exec_netconf = ($1 == '%') ? Netconf::Junos::NETCONF_SHELL : Netconf::Junos::NETCONF_CLI
14
14
  end
15
-
15
+
16
16
  def trans_start_netconf
17
17
  @trans.puts @exec_netconf
18
18
  end
19
-
19
+
20
20
  end
21
- end
22
- end
21
+ end
22
+ end
23
23
 
@@ -1,32 +1,32 @@
1
1
  require 'net/netconf/rpc_std'
2
2
 
3
- module Netconf
4
- module RPC
5
-
3
+ module Netconf
4
+ module RPC
5
+
6
6
  def RPC.add_attributes( ele_nx, attr_h )
7
- attr_h.each{ |k,v| ele_nx[k] = v }
7
+ attr_h.each{ |k,v| ele_nx[k] = v }
8
8
  end
9
-
9
+
10
10
  def RPC.set_exception( rpc_nx, exception )
11
11
  rpc_nx.instance_variable_set(:@netconf_exception, exception )
12
12
  end
13
-
13
+
14
14
  def RPC.get_exception( rpc_nx )
15
15
  rpc_nx.instance_variable_get(:@netconf_exception) || Netconf::RpcError
16
16
  end
17
-
18
- module Builder
17
+
18
+ module Builder
19
19
  # autogenerate an <rpc>, converting underscores (_)
20
20
  # to hyphens (-) along the way ...
21
-
22
- def Builder.method_missing( method, params = nil, attrs = nil )
23
-
24
- rpc_name = method.to_s.tr('_','-').to_sym
21
+
22
+ def Builder.method_missing( method, params = nil, attrs = nil )
23
+
24
+ rpc_name = method.to_s.tr('_','-').to_sym
25
25
 
26
26
  if params
27
27
  # build the XML starting at <rpc>, envelope the <method> toplevel element,
28
28
  # and then create name/value elements for each of the additional params. An element
29
- # without a value should simply be set to true
29
+ # without a value should simply be set to true
30
30
  rpc_nx = Nokogiri::XML::Builder.new { |xml|
31
31
  xml.rpc { xml.send( rpc_name ) {
32
32
  params.each{ |k,v|
@@ -36,36 +36,36 @@ module Netconf
36
36
  }}
37
37
  }.doc.root
38
38
  else
39
- # -- no params
39
+ # -- no params
40
40
  rpc_nx = Nokogiri::XML("<rpc><#{rpc_name}/></rpc>").root
41
41
  end
42
-
43
- # if a block is given it is used to set the attributes of the toplevel element
44
- RPC.add_attributes( rpc_nx.at( rpc_name ), attrs ) if attrs
45
-
42
+
43
+ # if a block is given it is used to set the attributes of the toplevel element
44
+ RPC.add_attributes( rpc_nx.at( rpc_name ), attrs ) if attrs
45
+
46
46
  # return the rpc command
47
- rpc_nx
48
- end # def: method-missing?
49
-
50
- end # module: Builder
51
-
47
+ rpc_nx
48
+ end # def: method-missing?
49
+
50
+ end # module: Builder
51
+
52
52
  class Executor
53
53
  include Netconf::RPC::Standard
54
-
54
+
55
55
  def initialize( trans, os_type )
56
56
  @trans = trans
57
- begin
58
- extend Netconf::RPC::const_get( os_type )
57
+ begin
58
+ extend Netconf::RPC::const_get( os_type )
59
59
  rescue NameError
60
60
  # no extensions available ...
61
- end
61
+ end
62
62
  end
63
-
63
+
64
64
  def method_missing( method, params = nil, attrs = nil )
65
65
  @trans.rpc_exec( Netconf::RPC::Builder.send( method, params, attrs ))
66
- end
66
+ end
67
67
  end # class: Executor
68
-
68
+
69
69
  end # module: RPC
70
70
  end # module: Netconf
71
-
71
+
@@ -13,11 +13,9 @@ module Netconf
13
13
  EOM
14
14
 
15
15
  module Standard
16
-
17
16
  def lock( target )
18
- rpc = Nokogiri::XML( "<rpc><lock><target><#{target}/></target></lock></rpc>" ).root
19
- Netconf::RPC.set_exception( rpc, Netconf::LockError )
20
- @trans.rpc_exec( rpc )
17
+ run_valid_or_lock_rpc "<rpc><lock><target><#{target}/></target></lock></rpc>",
18
+ Netconf::LockError
21
19
  end
22
20
 
23
21
  def unlock( target )
@@ -26,8 +24,13 @@ EOM
26
24
  end
27
25
 
28
26
  def validate( source )
29
- rpc = Nokogiri::XML( "<rpc><validate><source><#{source}/></source></validate></rpc>" ).root
30
- Netconf::RPC.set_exception( rpc, Netconf::ValidateError )
27
+ run_valid_or_lock_rpc "<rpc><validate><source><#{source}/></source></validate></rpc>",
28
+ Netconf::ValidateError
29
+ end
30
+
31
+ def run_valid_or_lock_rpc(rpc_string, error_type)
32
+ rpc = Nokogiri::XML(rpc_string).root
33
+ Netconf::RPC.set_exception( rpc, error_type )
31
34
  @trans.rpc_exec( rpc )
32
35
  end
33
36
 
@@ -42,11 +45,7 @@ EOM
42
45
  @trans.rpc_exec( rpc )
43
46
  end
44
47
 
45
- def get_config( *args ) # :yeield: filter_builder
46
-
47
- source = 'running' # default source is 'running'
48
- filter = nil # no filter by default
49
-
48
+ def process_args(args)
50
49
  while arg = args.shift
51
50
  case arg.class.to_s
52
51
  when /^Nokogiri/
@@ -59,6 +58,14 @@ EOM
59
58
  when 'String' then source = arg
60
59
  end
61
60
  end
61
+ end
62
+
63
+ def get_config( *args ) # :yeield: filter_builder
64
+
65
+ source = 'running' # default source is 'running'
66
+ filter = nil # no filter by default
67
+
68
+ arg = process_args(args)
62
69
 
63
70
  rpc = Nokogiri::XML("<rpc><get-config><source><#{source}/></source></get-config></rpc>").root
64
71
 
@@ -87,18 +94,7 @@ EOM
87
94
  config = nil
88
95
  options = {}
89
96
 
90
- while arg = args.shift
91
- case arg.class.to_s
92
- when /^Nokogiri/
93
- config = case arg
94
- when Nokogiri::XML::Builder then arg.doc.root
95
- when Nokogiri::XML::Document then arg.root
96
- else arg
97
- end
98
- when 'Hash' then options = arg
99
- when 'String' then target = arg
100
- end
101
- end
97
+ arg = process_args(args)
102
98
 
103
99
  toplevel = options[:toplevel] if options[:toplevel]
104
100
 
@@ -1,41 +1,41 @@
1
1
  require 'serialport'
2
2
 
3
3
  module Netconf
4
-
4
+
5
5
  class Serial < Netconf::Transport
6
-
6
+
7
7
  DEFAULT_BAUD = 9600
8
8
  DEFAULT_DATABITS = 8
9
9
  DEFAULT_STOPBITS = 1
10
10
  DEFAULT_PARITY = SerialPort::NONE
11
11
  DEFAULT_RDBLKSZ = (1024*1024)
12
-
12
+
13
13
  attr_reader :args
14
-
14
+
15
15
  def initialize( args_h, &block )
16
16
  os_type = args_h[:os_type] || Netconf::DEFAULT_OS_TYPE
17
-
17
+
18
18
  raise Netconf::InitError, "Missing 'port' param" unless args_h[:port]
19
19
  raise Netconf::InitError, "Missing 'username' param" unless args_h[:username]
20
-
20
+
21
21
  @args = args_h.clone
22
22
  @args[:prompt] ||= /([%>])\s+$/
23
-
23
+
24
24
  # extend this instance with the capabilities of the specific console
25
25
  # type; it needs to define #trans_start_netconf session
26
- # this must be provided! if the caller does not, this will
26
+ # this must be provided! if the caller does not, this will
27
27
  # throw a NameError exception.
28
-
29
- extend Netconf::const_get( os_type )::TransSerial
30
-
28
+
29
+ extend Netconf::const_get( os_type )::TransSerial
30
+
31
31
  @trans_timeout = @args[:timeout] || Netconf::DEFAULT_TIMEOUT
32
32
  @trans_waitio = @args[:waitio] || Netconf::DEFAULT_WAITIO
33
33
 
34
- super( &block )
35
- end
36
-
34
+ super( &block )
35
+ end
36
+
37
37
  def login
38
-
38
+
39
39
  begin
40
40
  puts
41
41
  waitfor(/ogin:/)
@@ -43,93 +43,62 @@ module Netconf
43
43
  puts
44
44
  waitfor(/ogin:/)
45
45
  end
46
-
46
+
47
47
  puts @args[:username]
48
-
48
+
49
49
  waitfor(/assword:/)
50
50
  puts @args[:password]
51
-
51
+
52
52
  waitfor( @args[:prompt] )
53
53
  end
54
-
54
+
55
55
  def trans_open # :yield: self
56
-
56
+
57
57
  baud = @args[:speed] || DEFAULT_BAUD
58
58
  data_bits = @args[:bits] || DEFAULT_DATABITS
59
59
  stop_bits = @args[:stop] || DEFAULT_STOPBITS
60
60
  parity = @args[:parity] || DEFAULT_PARITY
61
-
62
- @trans = SerialPort.new( @args[:port], baud, data_bits, stop_bits, parity )
63
-
64
- got = login()
65
- yield self if block_given?
66
- trans_start_netconf( got )
67
-
61
+
62
+ @trans = SerialPort.new( @args[:port], baud, data_bits, stop_bits, parity )
63
+
64
+ got = login()
65
+ yield self if block_given?
66
+ trans_start_netconf( got )
67
+
68
68
  self
69
69
  end
70
-
70
+
71
71
  def trans_receive_hello
72
72
  hello_str = trans_receive()
73
73
  so_xml = hello_str.index("\n") + 1
74
74
  hello_str.slice!(0, so_xml)
75
75
  hello_str
76
76
  end
77
-
77
+
78
78
  def trans_send_hello
79
79
  nil
80
80
  end
81
-
81
+
82
82
  def trans_close
83
83
  @trans.write Netconf::RPC::MSG_CLOSE_SESSION
84
84
  @trans.close
85
85
  end
86
-
86
+
87
87
  def trans_send( cmd_str )
88
88
  @trans.write( cmd_str )
89
89
  end
90
-
90
+
91
91
  def trans_receive
92
- got = waitfor( Netconf::RPC::MSG_END_RE )
93
- msg_end = got.rindex( Netconf::RPC::MSG_END )
94
- got[msg_end .. -1] = ''
95
- got
92
+ Netconf.trans_receive
96
93
  end
97
-
94
+
98
95
  def puts( str = nil )
99
- @trans.puts str
96
+ @trans.puts str
100
97
  end
101
-
102
- def waitfor( this_re = nil )
103
- on_re = this_re || @args[:prompt]
104
-
105
- time_out = @trans_timeout
106
- wait_io = @trans_waitio
107
-
108
- time_out = nil if time_out == false
109
- done = false
110
- rx_buf = ''
111
-
112
- until( rx_buf.match( on_re ) and not IO::select( [@trans], nil, nil, wait_io ) )
113
-
114
- unless IO::select( [@trans], nil, nil, time_out )
115
- raise TimeoutError, "Netconf IO timed out while waiting for more data"
116
- end
117
-
118
- begin
119
-
120
- rx_some = @trans.readpartial( DEFAULT_RDBLKSZ )
121
-
122
- rx_buf += rx_some
123
- break if rx_buf.match( on_re )
124
-
125
- rescue EOFError # End of file reached
126
- rx_buf = nil if rx_buf == ''
127
- break # out of outer 'until' loop
128
- end
129
-
130
- end
131
- rx_buf
132
- end
133
-
98
+
99
+ def waitfor( this_re = nil )
100
+ Netconf.waitfor(on_re)
101
+ end
102
+
134
103
  end # class: Serial
135
104
  end # module: Netconf
@@ -1,94 +1,95 @@
1
1
  require 'net/ssh'
2
+ require 'net/netconf/ssh'
2
3
 
3
- module Netconf
4
+ module Netconf
4
5
  class SSH < Netconf::Transport
5
-
6
6
  NETCONF_PORT = 830
7
- NETCONF_SUBSYSTEM = 'netconf'
8
-
9
- def initialize( args_h, &block )
7
+ NETCONF_SUBSYSTEM = 'netconf'
8
+
9
+ def initialize(args_h, &block)
10
10
  @args = args_h.clone
11
11
  @args[:os_type] = args_h[:os_type] || Netconf::DEFAULT_OS_TYPE
12
-
12
+
13
13
  # extend this instance with the capabilities of the specific os_type
14
14
  begin
15
- extend Netconf::const_get( @args[:os_type] )::TransSSH
15
+ extend Netconf.const_get(@args[:os_type]).TransSSH
16
16
  rescue NameError
17
17
  # no extensions available ...
18
- end
19
-
20
- @trans = Hash.new
21
- super( &block )
18
+ end
19
+
20
+ @trans = {}
21
+ super(&block)
22
22
  end
23
-
24
- def trans_open( &block )
25
- # open a connection to the NETCONF subsystem
26
- start_args = Hash.new
23
+
24
+ def trans_open(&block)
25
+ # open a connection to the NETCONF subsystem
26
+ start_args = {}
27
27
  start_args[:password] ||= @args[:password]
28
28
  start_args[:passphrase] = @args[:passphrase] || nil
29
29
  start_args[:port] = @args[:port] || NETCONF_PORT
30
30
  start_args.merge!(@args[:ssh_args]) if @args[:ssh_args]
31
-
31
+
32
32
  begin
33
- @trans[:conn] = Net::SSH.start( @args[:target], @args[:username], start_args )
34
- @trans[:chan] = @trans[:conn].open_channel{ |ch| ch.subsystem( NETCONF_SUBSYSTEM ) }
33
+ @trans[:conn] = Net::SSH.start(@args[:target], @args[:username], start_args)
34
+ @trans[:chan] = @trans[:conn].open_channel do |ch|
35
+ ch.subsystem(NETCONF_SUBSYSTEM)
36
+ end
35
37
  rescue Errno::ECONNREFUSED => e
36
38
  if self.respond_to? 'trans_on_connect_refused'
37
- return trans_on_connect_refused( start_args )
39
+ return trans_on_connect_refused(start_args)
38
40
  end
39
41
  return nil
40
42
  end
41
43
  @trans[:chan]
42
44
  end
43
-
44
- def trans_close
45
+
46
+ def trans_close
45
47
  @trans[:chan].close if @trans[:chan]
46
48
  @trans[:conn].close if @trans[:conn]
47
49
  end
48
-
50
+
49
51
  def trans_receive
50
52
  @trans[:rx_buf] = ''
51
53
  @trans[:more] = true
52
-
54
+
53
55
  # collect the response data as it comes back ...
54
56
  # the "on" functions must be set before calling
55
57
  # the #loop method
56
-
57
- @trans[:chan].on_data do |ch, data|
58
- if data.include?( RPC::MSG_END )
59
- data.slice!( RPC::MSG_END )
58
+
59
+ @trans[:chan].on_data do |_ch, data|
60
+ if data.include?(RPC::MSG_END)
61
+ data.slice!(RPC::MSG_END)
60
62
  @trans[:rx_buf] << data unless data.empty?
61
63
  @trans[:more] = false
62
64
  else
63
65
  @trans[:rx_buf] << data
64
66
  end
65
67
  end
66
-
67
- # ... if there are errors ...
68
- @trans[:chan].on_extended_data do |ch, type, data|
68
+
69
+ # ... if there are errors ...
70
+ @trans[:chan].on_extended_data do |_ch, _type, data|
69
71
  @trans[:rx_err] = data
70
72
  @trans[:more] = false
71
73
  end
72
-
74
+
73
75
  # the #loop method is what actually performs
74
76
  # ssh event processing ...
75
-
76
- @trans[:conn].loop { @trans[:more] }
77
-
78
- return @trans[:rx_buf]
77
+
78
+ @trans[:conn].loop { @trans[:more] }
79
+
80
+ @trans[:rx_buf]
79
81
  end
80
-
81
- def trans_send( cmd_str )
82
- @trans[:chan].send_data( cmd_str )
82
+
83
+ def trans_send(cmd_str)
84
+ @trans[:chan].send_data(cmd_str)
83
85
  end
84
-
86
+
85
87
  # accessor to create an Net::SCP object so the caller can perform
86
88
  # secure-copy operations (see Net::SCP) for details
87
89
  def scp
88
- @scp ||= Net::SCP.start( @args[:target], @args[:username], :password => @args[:password] )
90
+ @scp ||= Net::SCP.start(@args[:target],
91
+ @args[:username],
92
+ password: @args[:password])
89
93
  end
90
-
91
94
  end # class: SSH
92
- end #module: Netconf
93
-
94
- require 'net/netconf/ssh'
95
+ end # module: Netconf