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.
- checksums.yaml +4 -4
- data/lib/net/netconf.rb +37 -0
- data/lib/net/netconf/exception.rb +11 -11
- data/lib/net/netconf/ioproc.rb +24 -54
- data/lib/net/netconf/jnpr.rb +1 -1
- data/lib/net/netconf/jnpr/ioproc.rb +2 -2
- data/lib/net/netconf/jnpr/junos_config.rb +1 -1
- data/lib/net/netconf/jnpr/rpc.rb +87 -88
- data/lib/net/netconf/jnpr/serial.rb +4 -4
- data/lib/net/netconf/jnpr/ssh.rb +10 -10
- data/lib/net/netconf/jnpr/telnet.rb +7 -7
- data/lib/net/netconf/rpc.rb +31 -31
- data/lib/net/netconf/rpc_std.rb +19 -23
- data/lib/net/netconf/serial.rb +40 -71
- data/lib/net/netconf/ssh.rb +45 -44
- data/lib/net/netconf/telnet.rb +27 -30
- data/lib/net/netconf/transport.rb +23 -30
- data/lib/net/netconf/version.rb +1 -1
- metadata +3 -2
@@ -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
|
data/lib/net/netconf/jnpr/ssh.rb
CHANGED
@@ -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
|
|
data/lib/net/netconf/rpc.rb
CHANGED
@@ -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
|
+
|
data/lib/net/netconf/rpc_std.rb
CHANGED
@@ -13,11 +13,9 @@ module Netconf
|
|
13
13
|
EOM
|
14
14
|
|
15
15
|
module Standard
|
16
|
-
|
17
16
|
def lock( target )
|
18
|
-
|
19
|
-
|
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
|
-
|
30
|
-
|
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
|
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
|
-
|
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
|
|
data/lib/net/netconf/serial.rb
CHANGED
@@ -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
|
-
|
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
|
104
|
-
|
105
|
-
|
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
|
data/lib/net/netconf/ssh.rb
CHANGED
@@ -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(
|
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
|
15
|
+
extend Netconf.const_get(@args[:os_type]).TransSSH
|
16
16
|
rescue NameError
|
17
17
|
# no extensions available ...
|
18
|
-
end
|
19
|
-
|
20
|
-
@trans =
|
21
|
-
super(
|
18
|
+
end
|
19
|
+
|
20
|
+
@trans = {}
|
21
|
+
super(&block)
|
22
22
|
end
|
23
|
-
|
24
|
-
def trans_open(
|
25
|
-
# open a connection to the NETCONF subsystem
|
26
|
-
start_args =
|
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(
|
34
|
-
@trans[:chan] = @trans[:conn].open_channel
|
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(
|
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 |
|
58
|
-
if data.include?(
|
59
|
-
data.slice!(
|
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 |
|
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
|
-
|
77
|
+
|
78
|
+
@trans[:conn].loop { @trans[:more] }
|
79
|
+
|
80
|
+
@trans[:rx_buf]
|
79
81
|
end
|
80
|
-
|
81
|
-
def trans_send(
|
82
|
-
@trans[:chan].send_data(
|
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(
|
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
|