netconf 0.2.1

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,29 @@
1
+ require 'net/netconf/jnpr/serial'
2
+
3
+ puts "NETCONF v.#{Netconf::VERSION}"
4
+
5
+ login = {
6
+ :port => '/dev/ttyS4',
7
+ :username => "root", :password => "juniper1"
8
+ }
9
+
10
+ # we want to mount the USB drive, so we need to explicity
11
+ # do something special when opening the serial console ...
12
+ # therefore, we can *NOT* pass a block directly to new()
13
+
14
+ dev = Netconf::Serial.new( login )
15
+ dev.open { |con|
16
+ # login has occurred successfully
17
+
18
+ con.puts 'mount_msdosfs /dev/da1s1 /mnt'
19
+
20
+ # netconf will be started once block completes
21
+ }
22
+
23
+ inv = dev.rpc.get_chassis_inventory
24
+
25
+ binding.pry
26
+
27
+ dev.close
28
+
29
+
@@ -0,0 +1,29 @@
1
+ require 'net/netconf/jnpr/serial'
2
+
3
+ puts "NETCONF v.#{Netconf::VERSION}"
4
+
5
+ serial_port = '/dev/ttyS4'
6
+
7
+ login = {
8
+ :port => serial_port,
9
+ :username => "jeremy", :password => "jeremy1"
10
+ }
11
+
12
+ puts "Connecting to SERIAL: #{serial_port} ... please wait."
13
+
14
+ Netconf::Serial.new( login ){ |dev|
15
+
16
+ puts "Connected."
17
+ puts "Nabbing Inventory ..."
18
+
19
+ inv = dev.rpc.get_chassis_inventory
20
+
21
+ puts "Chassis: " + inv.xpath('chassis/description').text
22
+ puts "Chassis Serial-Number: " + inv.xpath('chassis/serial-number').text
23
+
24
+ binding.pry
25
+
26
+ }
27
+
28
+
29
+
@@ -0,0 +1,15 @@
1
+ require 'net/netconf/jnpr/telnet'
2
+
3
+ puts "NETCONF v.#{Netconf::VERSION}"
4
+
5
+ login = { :target => 'vsrx', :username => "jeremy", :password => "jeremy1" }
6
+
7
+ Netconf::Telnet.new( login ){ |dev|
8
+ inv = dev.rpc.get_chassis_inventory
9
+ puts "Chassis: " + inv.xpath('chassis/description').text
10
+ puts "Chassis Serial-Number: " + inv.xpath('chassis/serial-number').text
11
+
12
+ binding.pry
13
+ }
14
+
15
+
@@ -0,0 +1,19 @@
1
+ require 'net/netconf'
2
+
3
+ puts "NETCONF v.#{Netconf::VERSION}"
4
+
5
+ login = { :target => '192.168.10.2',
6
+ :username => "jeremy",
7
+ :password => "jeremy1" }
8
+
9
+ Netconf::SSH.new( login ){ |dev|
10
+
11
+ inv = dev.rpc.get_chassis_inventory
12
+
13
+ puts "Chassis: " + inv.xpath('chassis/description').text
14
+ puts "Chassis Serial-Number: " + inv.xpath('chassis/serial-number').text
15
+
16
+ }
17
+
18
+
19
+
@@ -0,0 +1,22 @@
1
+ require 'net/netconf'
2
+ require 'net/scp'
3
+
4
+ login = { :target => 'vsrx', :username => "jeremy" }
5
+
6
+ file_name = __FILE__
7
+
8
+ Netconf::SSH.new( login ){ |dev|
9
+
10
+ inv = dev.rpc.get_chassis_inventory
11
+
12
+ puts "Chassis: " + inv.xpath('chassis/description').text
13
+ puts "Chassis Serial-Number: " + inv.xpath('chassis/serial-number').text
14
+
15
+ puts "Copying file #{file_name} to home directory ..."
16
+ dev.scp.upload! file_name, file_name
17
+
18
+ puts "Copying latest config file from target to local machine ..."
19
+
20
+ dev.scp.download! "/config/juniper.conf.gz", "/var/tmp/config.gz"
21
+ }
22
+
@@ -0,0 +1,14 @@
1
+
2
+ require 'nokogiri'
3
+
4
+ require 'net/netconf/rpc'
5
+ require 'net/netconf/exception'
6
+ require 'net/netconf/transport'
7
+ require 'net/netconf/ssh'
8
+
9
+ module Netconf
10
+ VERSION = "0.2.1"
11
+ DEFAULT_OS_TYPE = :JUNOS
12
+ DEFAULT_TIMEOUT = 10
13
+ DEFAULT_WAITIO = 0
14
+ end
@@ -0,0 +1,38 @@
1
+ module Netconf
2
+
3
+ class InitError < StandardError
4
+ end
5
+
6
+ class StateError < StandardError
7
+ end
8
+
9
+ class OpenError < StandardError
10
+ end
11
+
12
+ class RpcError < StandardError
13
+ attr_reader :trans
14
+ attr_reader :cmd, :rsp
15
+
16
+ def initialize( trans, cmd, rsp )
17
+ @trans = trans
18
+ @cmd = cmd; @rsp = rsp;
19
+ end
20
+
21
+ def to_s
22
+ "RPC command error: #{cmd.first_element_child.name}"
23
+ end
24
+ end
25
+
26
+ class EditError < Netconf::RpcError
27
+ end
28
+
29
+ class LockError < Netconf::RpcError
30
+ end
31
+
32
+ class CommitError < Netconf::RpcError
33
+ end
34
+
35
+ class ValidateError < Netconf::RpcError
36
+ end
37
+
38
+ end
@@ -0,0 +1,8 @@
1
+ require 'net/netconf'
2
+ require 'net/netconf/jnpr/rpc'
3
+
4
+ module Netconf::JUNOS
5
+ NETCONF_CLI = "junoscript netconf need-trailer"
6
+ NETCONF_SHELL = "exec xml-mode netconf need-trailer"
7
+ end
8
+
@@ -0,0 +1,134 @@
1
+ ## -----------------------------------------------------------------------
2
+ ## This file contains the Junos specific RPC methods that are generated
3
+ ## specifically and different as generated by the Netconf::RPC::Builder
4
+ ## module. These are specifically the following:
5
+ ##
6
+ ## get_configuration - alternative NETCONF: 'get-config'
7
+ ## load_configuration - alternative NETCONF: 'edit-config'
8
+ ## lock_configuration - alternative NETCONF: 'lock'
9
+ ## commit_configuration - alternative NETCONF: 'commit'
10
+ ##
11
+ ## note: unlock_configuration is not included in this file since
12
+ ## the Netconf::RPC::Builder works "as-is" in this case
13
+ ## -----------------------------------------------------------------------
14
+
15
+ module Netconf
16
+ module RPC
17
+ module JUNOS
18
+
19
+ def lock_configuration
20
+ lock( 'candidate' )
21
+ end
22
+
23
+ def check_configuration
24
+ validate( 'candidate' )
25
+ end
26
+
27
+ def commit_configuration( params = nil, attrs = nil )
28
+ rpc = Netconf::RPC::Builder.commit_configuration( params, attrs )
29
+ Netconf::RPC.set_exception( rpc, Netconf::CommitError )
30
+ @trans.rpc_exec( rpc )
31
+ end
32
+
33
+ def get_configuration( *args )
34
+
35
+ filter = nil
36
+
37
+ while arg = args.shift
38
+ case arg.class.to_s
39
+ when /^Nokogiri/
40
+ filter = case arg
41
+ when Nokogiri::XML::Builder then arg.doc.root
42
+ when Nokogiri::XML::Document then arg.root
43
+ else arg
44
+ end
45
+ when 'Hash' then attrs = arg
46
+ end
47
+ end
48
+
49
+ rpc = Nokogiri::XML('<rpc><get-configuration/></rpc>').root
50
+ Netconf::RPC.add_attributes( rpc.first_element_child, attrs ) if attrs
51
+
52
+ if block_given?
53
+ Nokogiri::XML::Builder.with(rpc.at( 'get-configuration' )){ |xml|
54
+ xml.configuration {
55
+ yield( xml )
56
+ }}
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
61
+ end
62
+
63
+ @trans.rpc_exec( rpc )
64
+ end
65
+
66
+ def load_configuration( *args )
67
+
68
+ config = nil
69
+
70
+ # default format is XML
71
+ attrs = { :format => 'xml' }
72
+
73
+ while arg = args.shift
74
+ case arg.class.to_s
75
+ when /^Nokogiri/
76
+ config = case arg
77
+ when Nokogiri::XML::Builder then arg.doc.root
78
+ when Nokogiri::XML::Document then arg.root
79
+ else arg
80
+ end
81
+ when 'Hash' then attrs = arg
82
+ when 'Array' then config = arg.join("\n")
83
+ when 'String' then config = arg
84
+ end
85
+ end
86
+
87
+ case attrs[:format]
88
+ when 'set'
89
+ toplevel = 'configuration-set'
90
+ attrs[:format] = 'text'
91
+ attrs[:action] = 'set'
92
+ when 'text'
93
+ toplevel = 'configuration-text'
94
+ when 'xml'
95
+ toplevel = 'configuration'
96
+ end
97
+
98
+ rpc = Nokogiri::XML('<rpc><load-configuration/></rpc>').root
99
+ ld_cfg = rpc.first_element_child
100
+ Netconf::RPC.add_attributes( ld_cfg, attrs ) if attrs
101
+
102
+ if block_given?
103
+ if attrs[:format] == 'xml'
104
+ Nokogiri::XML::Builder.with( ld_cfg ){ |xml|
105
+ xml.send( toplevel ) {
106
+ yield( xml )
107
+ }}
108
+ else
109
+ config = yield # returns String | Array(of stringable)
110
+ config = config.join("\n") if config.class == Array
111
+ end
112
+ end
113
+
114
+ if config
115
+ c_node = Nokogiri::XML::Node.new( toplevel, rpc )
116
+ if attrs[:format] == 'xml'
117
+ c_node << config.dup # duplicate the config so as to not distrupt it
118
+ else
119
+ # config is stringy, so just add it as the text node
120
+ c_node.content = config
121
+ end
122
+ ld_cfg << c_node
123
+ end
124
+
125
+ # set a specific exception class on this RPC so it can be
126
+ # properlly handled by the calling enviornment
127
+
128
+ Netconf::RPC::set_exception( rpc, Netconf::EditError )
129
+ @trans.rpc_exec( rpc )
130
+ end
131
+
132
+ end # module: JUNOS
133
+ end # module: RPC
134
+ end # module: Netconf
@@ -0,0 +1,17 @@
1
+ require 'net/netconf'
2
+ require 'net/netconf/serial'
3
+ require 'net/netconf/jnpr'
4
+
5
+ module Netconf
6
+ module TransSerial
7
+ module JUNOS
8
+
9
+ def trans_start_netconf( last_console )
10
+ last_console.match(/[^%]\s+$/)
11
+ netconf_cmd = ($1 == '%') ? Netconf::JUNOS::NETCONF_SHELL : Netconf::JUNOS::NETCONF_CLI
12
+ puts netconf_cmd
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ require 'net/netconf'
2
+ require 'net/netconf/telnet'
3
+ require 'net/netconf/jnpr'
4
+
5
+ module Netconf
6
+ module TransTelnet
7
+ module JUNOS
8
+
9
+ def trans_login
10
+ l_rsp = @trans.login( @args[:username], @args[:password] )
11
+ # @@@/JLS: need to rescue the timeout ... ???
12
+ l_rsp.match("([>%])\s+$")
13
+ @exec_netconf = ($1 == '%') ? Netconf::JUNOS::NETCONF_SHELL : Netconf::JUNOS::NETCONF_CLI
14
+ end
15
+
16
+ def trans_start_netconf
17
+ @trans.puts @exec_netconf
18
+ end
19
+
20
+ end
21
+ end
22
+ end
23
+
@@ -0,0 +1,9 @@
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
@@ -0,0 +1,71 @@
1
+ require 'net/netconf/rpc_std'
2
+
3
+ module Netconf
4
+ module RPC
5
+
6
+ def RPC.add_attributes( ele_nx, attr_h )
7
+ attr_h.each{ |k,v| ele_nx[k] = v }
8
+ end
9
+
10
+ def RPC.set_exception( rpc_nx, exception )
11
+ rpc_nx.instance_variable_set(:@netconf_exception, exception )
12
+ end
13
+
14
+ def RPC.get_exception( rpc_nx )
15
+ rpc_nx.instance_variable_get(:@netconf_exception) || Netconf::RpcError
16
+ end
17
+
18
+ module Builder
19
+ # autogenerate an <rpc>, converting underscores (_)
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
25
+
26
+ if params
27
+ # build the XML starting at <rpc>, envelope the <method> toplevel element,
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
30
+ rpc_nx = Nokogiri::XML::Builder.new { |xml|
31
+ xml.rpc { xml.send( rpc_name ) {
32
+ params.each{ |k,v|
33
+ sym = k.to_s.tr('_','-').to_sym
34
+ xml.send(sym, (v==true) ? nil : v )
35
+ }
36
+ }}
37
+ }.doc.root
38
+ else
39
+ # -- no params
40
+ rpc_nx = Nokogiri::XML("<rpc><#{rpc_name}/></rpc>").root
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
+
46
+ # return the rpc command
47
+ rpc_nx
48
+ end # def: method-missing?
49
+
50
+ end # module: Builder
51
+
52
+ class Executor
53
+ include Netconf::RPC::Standard
54
+
55
+ def initialize( trans, os_type )
56
+ @trans = trans
57
+ begin
58
+ extend Netconf::RPC::const_get( os_type )
59
+ rescue NameError
60
+ # no extensions available ...
61
+ end
62
+ end
63
+
64
+ def method_missing( method, params = nil, attrs = nil )
65
+ @trans.rpc_exec( Netconf::RPC::Builder.send( method, params, attrs ))
66
+ end
67
+ end # class: Executor
68
+
69
+ end # module: RPC
70
+ end # module: Netconf
71
+