net-netconf 0.4.1 → 0.4.2

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.
@@ -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