netconf 0.2.4 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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