netconf 0.2.4 → 0.2.5

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.
@@ -2,21 +2,32 @@ require 'net/netconf/jnpr'
2
2
 
3
3
  puts "NETCONF v#{Netconf::VERSION}"
4
4
 
5
- login = { :target => 'vsrx', :username => "jeremy", :password => "jeremy1" }
5
+ login = { :target => 'ex4', :username => "jeremy", :password => "jeremy1" }
6
6
 
7
- new_host_name = "vsrx-jjj"
7
+ new_host_name = "ex4-abc"
8
8
 
9
9
  puts "Connecting to device: #{login[:target]}"
10
10
 
11
11
  Netconf::SSH.new( login ){ |dev|
12
12
  puts "Connected!"
13
13
 
14
+ # when providing a collection of configuration,
15
+ # you need to include the <configuration> as the
16
+ # toplevel element
17
+
14
18
  location = Nokogiri::XML::Builder.new{ |x|
15
- x.system {
16
- x.location {
17
- x.building "Main Campus, D"
18
- x.floor 22
19
- x.rack 38
19
+ x.configuration {
20
+ x.system {
21
+ x.location {
22
+ x.building "Main Campus, D"
23
+ x.floor 22
24
+ x.rack 38
25
+ }
26
+ }
27
+ x.system {
28
+ x.services {
29
+ x.ftp;
30
+ }
20
31
  }
21
32
  }
22
33
  }
@@ -24,7 +35,12 @@ Netconf::SSH.new( login ){ |dev|
24
35
  begin
25
36
 
26
37
  rsp = dev.rpc.lock_configuration
27
-
38
+
39
+ # --------------------------------------------------------------------
40
+ # configuration as PARAM
41
+
42
+ rsp = dev.rpc.load_configuration( location, :action => 'replace' )
43
+
28
44
  # --------------------------------------------------------------------
29
45
  # configuration as BLOCK
30
46
 
@@ -34,10 +50,6 @@ Netconf::SSH.new( login ){ |dev|
34
50
  }
35
51
  }
36
52
 
37
- # --------------------------------------------------------------------
38
- # configuration as PARAM
39
-
40
- rsp = dev.rpc.load_configuration( location )
41
53
  rpc = dev.rpc.check_configuration
42
54
  rpc = dev.rpc.commit_configuration
43
55
  rpc = dev.rpc.unlock_configuration
@@ -2,7 +2,7 @@ require 'net/netconf/jnpr' # note: including Juniper specific extension
2
2
 
3
3
  puts "NETCONF v.#{Netconf::VERSION}"
4
4
 
5
- login = { :target => 'vsrx', :username => "jeremy", :password => "jeremy1" }
5
+ login = { :target => 'ex4', :username => "jeremy", :password => "jeremy1" }
6
6
 
7
7
  puts "Connecting to device: #{login[:target]}"
8
8
 
@@ -22,6 +22,7 @@ Netconf::SSH.new( login ){ |dev|
22
22
 
23
23
  cfgsvc1_1 = dev.rpc.get_configuration{ |x|
24
24
  x.system { x.services }
25
+ x.system { x.login }
25
26
  }
26
27
 
27
28
  cfgsvc1_1.xpath('system/services/*').each{|s| puts s.name }
@@ -36,10 +37,12 @@ Netconf::SSH.new( login ){ |dev|
36
37
 
37
38
  # ----------------------------------------------------------------------
38
39
  # specifying a filter as a parameter to get_configuration
40
+ # you must wrap the config in a toplevel <configuration> element
39
41
 
40
- filter = Nokogiri::XML::Builder.new{ |x|
42
+ filter = Nokogiri::XML::Builder.new{ |x| x.configuration {
41
43
  x.system { x.services }
42
- }
44
+ x.system { x.login }
45
+ }}
43
46
 
44
47
  puts "Retrieved services by PARAM, as XML"
45
48
 
@@ -7,11 +7,9 @@ require 'net/netconf/transport'
7
7
  require 'net/netconf/ssh'
8
8
 
9
9
  module Netconf
10
- VERSION = "0.2.4"
11
-
12
- NAMESPACE = "urn:ietf:params:xml:ns:netconf:base:1.0"
13
-
14
- DEFAULT_OS_TYPE = :JUNOS
10
+ VERSION = "0.2.5"
11
+ NAMESPACE = "urn:ietf:params:xml:ns:netconf:base:1.0"
12
+ DEFAULT_OS_TYPE = :Junos
15
13
  DEFAULT_TIMEOUT = 10
16
14
  DEFAULT_WAITIO = 0
17
15
  end
@@ -0,0 +1,88 @@
1
+ module Netconf
2
+
3
+ class IOProc < Netconf::Transport
4
+
5
+ DEFAULT_RDBLKSZ = (1024*1024)
6
+
7
+ attr_reader :args
8
+
9
+ def initialize( args_h = {}, &block )
10
+ os_type = args_h[:os_type] || Netconf::DEFAULT_OS_TYPE
11
+
12
+ @args = args_h.clone
13
+
14
+ # an OS specific implementation must exist to support this transport type
15
+ extend Netconf::const_get( os_type )::IOProc
16
+
17
+ @trans_timeout = @args[:timeout] || Netconf::DEFAULT_TIMEOUT
18
+ @trans_waitio = @args[:waitio] || Netconf::DEFAULT_WAITIO
19
+
20
+ super( &block )
21
+ end
22
+
23
+ # the OS specific transport must implement this method
24
+ def trans_open # :yield: self
25
+ raise "Unsupported IOProc"
26
+ end
27
+
28
+ def trans_receive_hello
29
+ trans_receive()
30
+ end
31
+
32
+ def trans_send_hello
33
+ nil
34
+ end
35
+
36
+ def trans_close
37
+ @trans.write Netconf::RPC::MSG_CLOSE_SESSION
38
+ @trans.close
39
+ end
40
+
41
+ def trans_send( cmd_str )
42
+ @trans.write( cmd_str )
43
+ end
44
+
45
+ def trans_receive
46
+ got = waitfor( Netconf::RPC::MSG_END_RE )
47
+ msg_end = got.rindex( Netconf::RPC::MSG_END )
48
+ got[msg_end .. -1] = ''
49
+ got
50
+ end
51
+
52
+ def puts( str = nil )
53
+ @trans.puts( str )
54
+ end
55
+
56
+ def waitfor( on_re )
57
+
58
+ time_out = @trans_timeout
59
+ wait_io = @trans_waitio
60
+
61
+ time_out = nil if time_out == false
62
+ done = false
63
+ rx_buf = ''
64
+
65
+ until( rx_buf.match( on_re ) and not IO::select( [@trans], nil, nil, wait_io ) )
66
+
67
+ unless IO::select( [@trans], nil, nil, time_out )
68
+ raise TimeoutError, "Netconf IO timed out while waiting for more data"
69
+ end
70
+
71
+ begin
72
+
73
+ rx_some = @trans.readpartial( DEFAULT_RDBLKSZ )
74
+
75
+ rx_buf += rx_some
76
+ break if rx_buf.match( on_re )
77
+
78
+ rescue EOFError # End of file reached
79
+ rx_buf = nil if rx_buf == ''
80
+ break # out of outer 'until' loop
81
+ end
82
+
83
+ end
84
+ rx_buf
85
+ end
86
+
87
+ end # class: IOProc
88
+ end # module: Netconf
@@ -1,7 +1,8 @@
1
1
  require 'net/netconf'
2
2
  require 'net/netconf/jnpr/rpc'
3
+ require 'net/netconf/jnpr/junos_config'
3
4
 
4
- module Netconf::JUNOS
5
+ module Netconf::Junos
5
6
  NETCONF_CLI = "junoscript netconf need-trailer"
6
7
  NETCONF_SHELL = "exec xml-mode netconf need-trailer"
7
8
  end
@@ -0,0 +1,14 @@
1
+ require 'net/netconf'
2
+ require 'net/netconf/ioproc'
3
+ require 'net/netconf/jnpr'
4
+
5
+ module Netconf
6
+ module Junos
7
+ module IOProc
8
+ def trans_open
9
+ @trans = IO.popen( "xml-mode netconf need-trailer", "r+")
10
+ self
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,104 @@
1
+ #
2
+ # Copyright (c) 2012 Juniper Networks, Inc.
3
+ # All Rights Reserved
4
+ #
5
+ # JUNIPER PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6
+
7
+ module Netconf
8
+
9
+ class JunosConfig
10
+
11
+ DELETE = { :delete => 'delete' }
12
+ REPLACE = { :replace => 'replace' }
13
+
14
+ attr_reader :doc
15
+ attr_reader :collection
16
+
17
+ def initialize( options )
18
+ @doc_ele = "configuration"
19
+
20
+ if options == :TOP
21
+ @doc = Nokogiri::XML("<#{@doc_ele}/>")
22
+ return
23
+ end
24
+
25
+ unless options[:TOP].nil?
26
+ @doc_ele = options[:TOP]
27
+ @doc = Nokogiri::XML("<#{@doc_ele}/>")
28
+ return
29
+ end
30
+
31
+ unless defined? @collection
32
+ edit = "#{@doc_ele}/#{options[:edit].strip}"
33
+ @at_name = edit[edit.rindex('/') + 1, edit.length]
34
+ @edit_path = edit
35
+ @collection = Hash.new
36
+ @to_xml = options[:build]
37
+ end
38
+ end
39
+
40
+ def <<( obj )
41
+ if defined? @collection
42
+ @collection[obj[:name]] = obj
43
+ elsif defined? @doc
44
+ obj.build_xml( @doc )
45
+ else
46
+ # TBD:error
47
+ end
48
+ end
49
+
50
+ def build_xml( ng_xml, &block )
51
+ at_ele = ng_xml.at( @edit_path )
52
+ if at_ele.nil?
53
+ # no xpath anchor point, so we need to create it
54
+ at_ele = edit_path( ng_xml, @edit_path )
55
+ end
56
+ build_proc = (block_given?) ? block : @to_xml
57
+
58
+ @collection.each do |k,v|
59
+ with( at_ele ) do |e|
60
+ build_proc.call( e, v )
61
+ end
62
+ end
63
+ end
64
+
65
+ def edit_path( ng_xml, xpath )
66
+ # junos configuration always begins with
67
+ # the 'configuration' element, so don't make
68
+ # the user enter it all the time
69
+
70
+ cfg_xpath = xpath
71
+ dot = ng_xml.at( cfg_xpath )
72
+ return dot if dot
73
+
74
+ # we need to determine how much of the xpath
75
+ # we need to create. walk down the xpath
76
+ # children to determine what exists and
77
+ # what needs to be added
78
+
79
+ xpath_a = cfg_xpath.split('/')
80
+ need_a = []
81
+ until xpath_a.empty? or dot
82
+ need_a.unshift xpath_a.pop
83
+ check_xpath = xpath_a.join('/')
84
+ dot = ng_xml.at( check_xpath )
85
+ end
86
+
87
+ # start at the deepest level of what
88
+ # actually exists and then start adding
89
+ # the children that were missing
90
+
91
+ dot = ng_xml.at(xpath_a.join('/'))
92
+ need_a.each do |ele|
93
+ dot = dot.add_child( Nokogiri::XML::Node.new( ele, ng_xml ))
94
+ end
95
+ return dot
96
+ end
97
+
98
+ def with( ng_xml, &block )
99
+ Nokogiri::XML::Builder.with( ng_xml, &block )
100
+ end
101
+ end
102
+ #-- class end
103
+ end
104
+
@@ -14,7 +14,7 @@
14
14
 
15
15
  module Netconf
16
16
  module RPC
17
- module JUNOS
17
+ module Junos
18
18
 
19
19
  def lock_configuration
20
20
  lock( 'candidate' )
@@ -55,9 +55,8 @@ module Netconf
55
55
  yield( xml )
56
56
  }}
57
57
  elsif filter
58
- f_node = Nokogiri::XML::Node.new( 'configuration', rpc )
59
- f_node << filter.dup # *MUST* use the .dup so we don't disrupt the original filter
60
- rpc.first_element_child << f_node
58
+ # filter must have toplevel = <configuration>
59
+ rpc.first_element_child << filter.dup # *MUST* use the .dup so we don't disrupt the original filter
61
60
  end
62
61
 
63
62
  @trans.rpc_exec( rpc )
@@ -69,7 +68,7 @@ module Netconf
69
68
 
70
69
  # default format is XML
71
70
  attrs = { :format => 'xml' }
72
-
71
+
73
72
  while arg = args.shift
74
73
  case arg.class.to_s
75
74
  when /^Nokogiri/
@@ -78,7 +77,7 @@ module Netconf
78
77
  when Nokogiri::XML::Document then arg.root
79
78
  else arg
80
79
  end
81
- when 'Hash' then attrs = arg
80
+ when 'Hash' then attrs.merge! arg
82
81
  when 'Array' then config = arg.join("\n")
83
82
  when 'String' then config = arg
84
83
  end
@@ -93,8 +92,8 @@ module Netconf
93
92
  toplevel = 'configuration-text'
94
93
  when 'xml'
95
94
  toplevel = 'configuration'
96
- end
97
-
95
+ end
96
+
98
97
  rpc = Nokogiri::XML('<rpc><load-configuration/></rpc>').root
99
98
  ld_cfg = rpc.first_element_child
100
99
  Netconf::RPC.add_attributes( ld_cfg, attrs ) if attrs
@@ -112,14 +111,15 @@ module Netconf
112
111
  end
113
112
 
114
113
  if config
115
- c_node = Nokogiri::XML::Node.new( toplevel, rpc )
116
114
  if attrs[:format] == 'xml'
117
- c_node << config.dup # duplicate the config so as to not distrupt it
115
+ # config assumes toplevel = <configuration> given
116
+ ld_cfg << config.dup # duplicate the config so as to not distrupt it
118
117
  else
119
- # config is stringy, so just add it as the text node
118
+ # config is stringy, so just add it as the text node
119
+ c_node = Nokogiri::XML::Node.new( toplevel, rpc )
120
120
  c_node.content = config
121
+ ld_cfg << c_node
121
122
  end
122
- ld_cfg << c_node
123
123
  end
124
124
 
125
125
  # set a specific exception class on this RPC so it can be
@@ -3,15 +3,13 @@ require 'net/netconf/serial'
3
3
  require 'net/netconf/jnpr'
4
4
 
5
5
  module Netconf
6
- module TransSerial
7
- module JUNOS
8
-
6
+ module Junos
7
+ module TransSerial
9
8
  def trans_start_netconf( last_console )
10
9
  last_console.match(/[^%]\s+$/)
11
- netconf_cmd = ($1 == '%') ? Netconf::JUNOS::NETCONF_SHELL : Netconf::JUNOS::NETCONF_CLI
10
+ netconf_cmd = ($1 == '%') ? Netconf::Junos::NETCONF_SHELL : Netconf::Junos::NETCONF_CLI
12
11
  puts netconf_cmd
13
- end
14
-
12
+ end
15
13
  end
16
14
  end
17
15
  end
@@ -3,14 +3,14 @@ require 'net/netconf/telnet'
3
3
  require 'net/netconf/jnpr'
4
4
 
5
5
  module Netconf
6
- module TransTelnet
7
- module JUNOS
6
+ module Junos
7
+ module TransTelnet
8
8
 
9
9
  def trans_login
10
10
  l_rsp = @trans.login( @args[:username], @args[:password] )
11
11
  # @@@/JLS: need to rescue the timeout ... ???
12
12
  l_rsp.match("([>%])\s+$")
13
- @exec_netconf = ($1 == '%') ? Netconf::JUNOS::NETCONF_SHELL : Netconf::JUNOS::NETCONF_CLI
13
+ @exec_netconf = ($1 == '%') ? Netconf::Junos::NETCONF_SHELL : Netconf::Junos::NETCONF_CLI
14
14
  end
15
15
 
16
16
  def trans_start_netconf
@@ -26,7 +26,7 @@ module Netconf
26
26
  # this must be provided! if the caller does not, this will
27
27
  # throw a NameError exception.
28
28
 
29
- extend Netconf::TransSerial::const_get( os_type )
29
+ extend Netconf::const_get( os_type )::TransSerial
30
30
 
31
31
  @trans_timeout = @args[:timeout] || Netconf::DEFAULT_TIMEOUT
32
32
  @trans_waitio = @args[:waitio] || Netconf::DEFAULT_WAITIO
@@ -86,7 +86,6 @@ module Netconf
86
86
 
87
87
  def trans_send( cmd_str )
88
88
  @trans.write( cmd_str )
89
- @trans.fsync
90
89
  end
91
90
 
92
91
  def trans_receive
@@ -98,7 +97,6 @@ module Netconf
98
97
 
99
98
  def puts( str = nil )
100
99
  @trans.puts str
101
- @trans.fsync
102
100
  end
103
101
 
104
102
  def waitfor( this_re = nil )
@@ -121,8 +119,6 @@ module Netconf
121
119
 
122
120
  rx_some = @trans.readpartial( DEFAULT_RDBLKSZ )
123
121
 
124
- $stdout.puts rx_some
125
-
126
122
  rx_buf += rx_some
127
123
  break if rx_buf.match( on_re )
128
124
 
@@ -11,7 +11,7 @@ module Netconf
11
11
  # extend this instance with the capabilities of the specific console
12
12
  # type; it needs to define #login and #start_netconf session
13
13
  begin
14
- extend Netconf::TransTelnet::const_get( os_type )
14
+ extend Netconf::const_get( os_type )::TransTelnet
15
15
  rescue NameError
16
16
  # no extensions available ...
17
17
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: netconf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-01-16 00:00:00.000000000 Z
13
+ date: 2013-01-29 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: nokogiri
@@ -51,11 +51,13 @@ extensions: []
51
51
  extra_rdoc_files: []
52
52
  files:
53
53
  - lib/net/netconf/exception.rb
54
+ - lib/net/netconf/ioproc.rb
55
+ - lib/net/netconf/jnpr/ioproc.rb
56
+ - lib/net/netconf/jnpr/junos_config.rb
54
57
  - lib/net/netconf/jnpr/rpc.rb
55
58
  - lib/net/netconf/jnpr/serial.rb
56
59
  - lib/net/netconf/jnpr/telnet.rb
57
60
  - lib/net/netconf/jnpr.rb
58
- - lib/net/netconf/localhost.rb
59
61
  - lib/net/netconf/rpc.rb
60
62
  - lib/net/netconf/rpc_std.rb
61
63
  - lib/net/netconf/serial.rb
@@ -1,9 +0,0 @@
1
- module Netconf
2
- module NcDevice
3
- class Localhost
4
- def initialize( opt_hash )
5
- puts "This is a localhost"
6
- end
7
- end
8
- end
9
- end