From 9245ddb3135e68c9a765171c139a5483aa3d24c3 Mon Sep 17 00:00:00 2001 From: Tore Anderson Date: Wed, 26 Nov 2014 11:49:22 +0100 Subject: [PATCH 01/41] Rewrite Net::Netconf::Access::ssh using Net::SSH2 This is a complete rewrite of Net::Netconf::Access::ssh, replacing all prior use of Expect and the 'ssh' binary with Net::SSH2. This means Net::Netconf no longer requires Expect (nor, by extension, Tcl/Tk). It should also be much more robust, as the previous Expect implementation is suspectible to breakage if the 'ssh' binary changes its output. Finally, it fixes issue #19. --- Makefile.PL | 2 +- README | 12 +- README.md | 12 +- lib/Net/Netconf/Access/ssh.pm | 240 +++++++++++++++------------------- 4 files changed, 120 insertions(+), 146 deletions(-) diff --git a/Makefile.PL b/Makefile.PL index a90c8c8..7e06bac 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -7,7 +7,7 @@ WriteMakefile( NAME => 'Net-Netconf', AUTHOR => 'Juniper Networks, Inc', VERSION_FROM => 'Makefile.PL', - PREREQ_PM => {'XML::LibXML' => '0', 'File::Which' => '0', 'Expect' => '0'}, + PREREQ_PM => {'XML::LibXML' => '0', 'File::Which' => '0', 'Net::SSH2' => '0'}, ABSTRACT => 'netconf libraries for perl', #LICENSE => 'perl', ??? META_MERGE => { diff --git a/README b/README index a0e4891..0446b40 100644 --- a/README +++ b/README @@ -70,7 +70,7 @@ Prerequisites ============== Following are the Prerequisites for using this API: - 1. Expect Module (it depends on tcl, tk, tcl-dev and tk-dev) + 1. Net::SSH2 2. File::Which 3. XML::LibXML @@ -108,16 +108,14 @@ Installation Instructions for UNIX Systems Install the prerequisites of Perl modules. Following are the prerequites - 1. Expect Module (it depends on tcl, tk, tcl-dev and tk-dev) + 1. Net::SSH2 2. File::Which 3. XML::LibXML Steps to install Prerequisites in Ubuntu12.04LTS : - 1. apt-get install tcl tcl-dev tk tk-dev - 2. apt-get install expect expect-dev - 3. cpan Expect - 4. cpan File::Which - 5. cpan XML::LibXML + 1. cpan Net::SSH2 + 2. cpan File::Which + 3. cpan XML::LibXML After successfully installing Prerequisites install NETCONF PERL CLIENT diff --git a/README.md b/README.md index 8a83ca5..0f7bc64 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ Prerequisites ============== Following are the Prerequisites for using this API: - 1. Expect Module (it depends on tcl, tk, tcl-dev and tk-dev) + 1. Net::SSH2 2. File::Which 3. XML::LibXML @@ -108,16 +108,14 @@ Installation Instructions for UNIX Systems Install the prerequisites of Perl modules. Following are the prerequites - 1. Expect Module (it depends on tcl, tk, tcl-dev and tk-dev) + 1. Net::SSH2 2. File::Which 3. XML::LibXML Steps to install Prerequisites in Ubuntu12.04LTS : - 1. apt-get install tcl tcl-dev tk tk-dev - 2. apt-get install expect expect-dev - 3. cpan Expect - 4. cpan File::Which - 5. cpan XML::LibXML + 1. cpan Net::SSH2 + 2. cpan File::Which + 3. cpan XML::LibXML After successfully installing Prerequisites install NETCONF PERL CLIENT diff --git a/lib/Net/Netconf/Access/ssh.pm b/lib/Net/Netconf/Access/ssh.pm index f9ae399..426efbb 100644 --- a/lib/Net/Netconf/Access/ssh.pm +++ b/lib/Net/Netconf/Access/ssh.pm @@ -1,143 +1,114 @@ -# child of Access - package Net::Netconf::Access::ssh; -use Expect; +use Net::SSH2; use Net::Netconf::Trace; -use Net::Netconf::Access; use Net::Netconf::Constants; use Carp; -use File::Which; -our $VERSION ='0.01'; -use vars qw(@ISA); -@ISA = qw(Net::Netconf::Access); +use parent 'Net::Netconf::Access'; + +our $VERSION = '1.0'; -sub disconnect -{ - my ($self) = shift; - $self->{'ssh_obj'}->hard_close(); +# Just for convenience +sub trace { + my $self = shift; + $self->{'trace_obj'}->trace(Net::Netconf::Trace::TRACE_LEVEL, + sprintf("[%s] %s", __PACKAGE__, @_)); } -sub start -{ - my($self) = @_; - my $sshprog; - my $exp; - # Get ssh port number if it exists - my $rport = (getservbyname('ssh', 'tcp'))[2]; - $rport = Net::Netconf::Constants::NC_DEFAULT_PORT unless ( defined $self->{'server'} && $self->{'server'} eq 'junoscript'); - - $self->{'server'} = 'netconf' unless $self->{'server'}; - - my $echostate = 'stty -echo;'; - if (exists($self->{'sshprog'})) { - $sshprog = $self->{'sshprog'}; - } else { - $sshprog = which('ssh'); - if (defined($sshprog) && ($sshprog ne '')) { - chomp($sshprog); - } else { - croak "Could not find sshclient on the system"; - } - } - - # This implementation assumes OpenSSH. - my $command = $echostate . $sshprog . ' -l ' . - $self->{'login'} . ' -p ' . $rport . - ' -s ' . $self->{'hostname'} . - ' ' . $self->{'server'}; - - - # take expect object from user ow build your own - if (defined $self->{'exp_obj'}){ - $exp = $self->{'exp_obj'}; - } - else{ - $exp = new Expect; - } - my $ssh=$exp->spawn($command); - - # Create the Expect object - # my $ssh = Expect->spawn($command); - # Turn off logging to stdout - $ssh->log_stdout(0); - $ssh->log_file($self->out); - - # Send our password or passphrase - if ($ssh->expect(10, 'password:', 'Password:', '(yes/no)?', '-re', 'passphrase.*:')) { - my $m_num = $ssh->match_number(); - - SWITCH: { - if (($m_num == 1) || ($m_num == 2) || ($m_num == 4)) { - print $ssh "$self->{'password'}\r"; - last SWITCH; - } - if ($m_num == 3) { - # Host-key authenticity. - print $ssh "yes\r"; - if ($ssh->expect(10, 'password:', 'Password:', '-re', 'passphrase.*:')) { - print $ssh "$self->{'password'}\r"; - } - # After the yes/no option, expect the line: 'Warning: - # Permanently added <....> to the list of known hosts.' - $ssh->expect(10, 'known hosts.'); - last SWITCH; - } - } # SWITCH - # If password prompted second time, it means user has give invalid password - if ($ssh->expect(10, 'password:', 'Password:', '-re', 'passphrase.*:')) - { - print "Failed to login to $self->{'hostname'}\n"; - $self->{'seen_eof'} = 1; - } - } - else { - if ($ssh->expect(10, '-re', '')) { - # Things are good. Do nothing. - } else { - $self->{'seen_eof'} = 1; - } - } - - $self->{'ssh_obj'} = $ssh; - $self; +# Initialises an Net::SSH2 object, connects and authenticates to the Netconf +# server. Net::SSH2 object is stored in $self->{'ssh2'}, channel in +# $self->{'chan'}. +sub start { + my $self = shift; + + my $port = ($self->{'server'} eq 'netconf') ? + Net::Netconf::Constants::NC_DEFAULT_PORT : + (getservbyname('ssh', 'tcp'))[2]; + + my $ssh2 = Net::SSH2->new(); + croak "Failed to create a new Net::SSH2 object" unless(ref $ssh2); + + $self->trace("Making SSH connection to '$self->{'hostname'}:$port'..."); + $ssh2->connect($self->{'hostname'}, $port); + croak "SSH connection failed: " . $ssh2->error() if($ssh2->error()); + $self->trace("SSH connection succeeded!"); + + $self->trace("Performing SSH authentication"); + $ssh2->auth(username => $self->{'login'}, + password => $self->{'password'}); + croak "SSH authentication failed" if(!$ssh2->auth_ok() or $ssh2->error()); + $self->trace("Authentication succeeded!"); + + $self->trace("Requesting SSH channel..."); + my $chan = $ssh2->channel(); + croak "Failed to create SSH channel" if(!ref $chan or $ssh2->error()); + $self->trace("Successfully created SSH channel!"); + + $self->trace("Starting subsystem '$self->{'server'}'..."); + $chan->subsystem($self->{'server'}) + or croak "Failed to start subsystem '$self->{'server'}'"; + $self->trace("Successfully started subsystem!"); + + # Allow partial reads from the channel in recv(), otherwise it will + # just sit there waiting for the buffer to fill completely + $chan->blocking(0); + + $self->{'ssh2'} = $ssh2; + $self->{'chan'} = $chan; + return $self; } -sub send -{ +# Gracefully disconnect from Netconf server +sub disconnect { + my $self = shift; + + my $ssh2 = $self->{'ssh2'}; + $ssh2->disconnect("Bye bye from $0 [" . __PACKAGE__ . " v$VERSION]"); + $self->trace("Disconnected from SSH server"); + + undef $self; +} + +# Writes an XML request to the Netconf server. +sub send { my ($self, $xml) = @_; - my $ssh = $self->{'ssh_obj'}; - $xml .= ']]>]]>'; - print $ssh "$xml\r"; - 1; + + $self->trace("Writing '$xml' to SSH channel..."); + $self->{'chan'}->write($xml . ']]>]]>') + or croak "Failed to write XML data to SSH channel!"; + $self->trace("Succeeded writing to SSH channel!"); + + return 1; } -sub recv -{ +# Reads an XML reply from the Netconf server. +sub recv { my $self = shift; - my $xml; - my $ssh = $self->{'ssh_obj'}; - if ($ssh->expect(600, ']]>]]>')) { - $xml = $ssh->before() . $ssh->match(); - } else { - print "Failed to login to $self->{'hostname'}\n"; - $self->{'seen_eof'} = 1; - } - $xml =~ s/]]>]]>//g; - $xml; + my $ssh2 = $self->{'ssh2'}; + my $chan = $self->{'chan'}; + + $self->trace("Reading XML response from Netconf server..."); + my ($resp, $buf); + do { + # Wait up to 10 seconds for data to become available before attempting + # to read anything (in order to avoid busy-looping on $chan->read()) + my @poll = ({ handle => $chan, events => 'in' }); + $ssh2->poll(10000, \@poll); + + $nbytes = $chan->read($buf, 65536) || 0; + $self->trace("Read $nbytes bytes from SSH channel: '$buf'"); + $resp .= $buf; + } until($resp =~ s/]]>]]>$//); + $self->trace("Received XML response '$resp'"); + + return $resp; } -sub out -{ - my $self = @_; - foreach $line (@_) { - if ($line =~ /Permission\ denied/) { - print "Login failed: Permission Denied\n"; - $self->{'ssh_obj'}->hard_close(); - $self->{'seen_eof'} = 1; - } - } +# Checks if the server sent us an EOF +sub eof { + my $self = shift; + return $self->{'chan'}->eof(); } 1; @@ -150,14 +121,14 @@ Net::Netconf::Access::ssh =head1 SYNOPSIS -The Net::Netconf::Access::ssh module is used internally to provide ssh access to -a Net::Netconf::Access instance. +The Net::Netconf::Access::ssh module is used internally to provide SSH access to +a Net::Netconf::Access instance, using Net::SSH2. =head1 DESCRIPTION -This is a subclass of Net::Netconf::Access class that manages an ssh connection -with the destination host. The underlying mechanics for managing the ssh -connection is based on OpenSSH. +This is a subclass of Net::Netconf::Access class that manages an SSH connection +with the destination host. The underlying mechanics for managing the SSH +connection is based on Net::SSH2. =head1 CONSTRUCTOR @@ -171,7 +142,11 @@ Please refer to the constructor of Net::Netconf::Access class. =item * -Expect.pm +Net::SSH2 + +=item * + +Net::SSH2::Channel =item * @@ -189,6 +164,9 @@ Net::Netconf::Device =head1 AUTHOR -Juniper Networks Perl Team, send bug reports, hints, tips and suggestions to -netconf-support@juniper.net. +Tore Anderson + +Net::Netconf is maintained by the Juniper Networks Perl Team, send bug reports, +hints, tips and suggestions to netconf-support@juniper.net. +# vim: syntax=perl tw=80 ts=4 et: From 5fc53a31f72554761fa3e6c2fc8184ca3ee8426a Mon Sep 17 00:00:00 2001 From: Tore Anderson Date: Mon, 1 Dec 2014 12:45:58 +0100 Subject: [PATCH 02/41] Fix for writing large XML requests Net::SSH2::Channel2::write() isn't guaranteed to write the entire buffer that is passed to it, especially if the buffer is large. Therefore loop over it until all bytes have been written. In order to avoid busy-looping while the channel isn't ready to accept more data, set it as blocking before starting the write loop. Make recv() explicitly set the channel back to non-blocking before starting the read loop. This removes the need to set the blocking state in start(). --- lib/Net/Netconf/Access/ssh.pm | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/lib/Net/Netconf/Access/ssh.pm b/lib/Net/Netconf/Access/ssh.pm index 426efbb..94b0907 100644 --- a/lib/Net/Netconf/Access/ssh.pm +++ b/lib/Net/Netconf/Access/ssh.pm @@ -50,10 +50,6 @@ sub start { or croak "Failed to start subsystem '$self->{'server'}'"; $self->trace("Successfully started subsystem!"); - # Allow partial reads from the channel in recv(), otherwise it will - # just sit there waiting for the buffer to fill completely - $chan->blocking(0); - $self->{'ssh2'} = $ssh2; $self->{'chan'} = $chan; return $self; @@ -74,11 +70,26 @@ sub disconnect { sub send { my ($self, $xml) = @_; - $self->trace("Writing '$xml' to SSH channel..."); - $self->{'chan'}->write($xml . ']]>]]>') - or croak "Failed to write XML data to SSH channel!"; - $self->trace("Succeeded writing to SSH channel!"); + $xml .= ']]>]]>'; + + my $len = length($xml); + + $self->trace("Will write $len bytes to the SSH channel:"); + $self->trace("$xml"); + # Make the channel blocking, so the write() call below waits until there + # is available buffer space. Otherwise we'll end up busy-looping. + $self->{'chan'}->blocking(1); + + my $written = 0; + while($written != $len) { + my $nbytes = $self->{'chan'}->write($xml) + or croak "Failed to write XML data to SSH channel!"; + $written += $nbytes; + $self->trace("Wrote $nbytes bytes (total written: $written)."); + substr($xml, 0, $nbytes) = ''; + } + $self->trace("Successfully wrote $written bytes to SSH channel!"); return 1; } @@ -88,6 +99,12 @@ sub recv { my $ssh2 = $self->{'ssh2'}; my $chan = $self->{'chan'}; + # Make the channel non-blocking, so that read() below allows for partial + # reads (as we can't possibly know if the data we're about to receive is an + # exact multiple of the buffer size argument, and doing it one character at + # a time instead would be terribly inefficient). + $chan->blocking(0); + $self->trace("Reading XML response from Netconf server..."); my ($resp, $buf); do { From 838accae3bf4e117a8fc5ce69e86d74008e769d4 Mon Sep 17 00:00:00 2001 From: Tore Anderson Date: Fri, 5 Dec 2014 11:12:57 +0100 Subject: [PATCH 03/41] Bugfix: use 'netconf' subsystem by default According to Net::Netconf::Device(3pm), 'netconf' should be used as the default subsystem if the user hasn't specified anything else in the 'server' argument to Net::Netconf::Device::new(). Noticed by @Jainpriyal in #19, thanks! --- lib/Net/Netconf/Access/ssh.pm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/Net/Netconf/Access/ssh.pm b/lib/Net/Netconf/Access/ssh.pm index 94b0907..0f2222e 100644 --- a/lib/Net/Netconf/Access/ssh.pm +++ b/lib/Net/Netconf/Access/ssh.pm @@ -22,6 +22,8 @@ sub trace { sub start { my $self = shift; + $self->{'server'} ||= 'netconf'; + my $port = ($self->{'server'} eq 'netconf') ? Net::Netconf::Constants::NC_DEFAULT_PORT : (getservbyname('ssh', 'tcp'))[2]; From 100efe25bec24af1e4cb36d66cd56e54b3eeff0d Mon Sep 17 00:00:00 2001 From: Priyal Jain Date: Mon, 22 Dec 2014 11:25:32 +0530 Subject: [PATCH 04/41] Update Netconf.pm --- lib/Net/Netconf.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Net/Netconf.pm b/lib/Net/Netconf.pm index 8abe0e7..b982f45 100644 --- a/lib/Net/Netconf.pm +++ b/lib/Net/Netconf.pm @@ -1,5 +1,5 @@ package Net::Netconf; -our $VERSION ='0.01'; +our $VERSION ='1.00'; =head1 NAME Net::Netconf : Netconf Perl Client From e4f71d3419148f5e2be97b6a03b62cbe7357a7f5 Mon Sep 17 00:00:00 2001 From: Priyal Jain Date: Mon, 22 Dec 2014 11:27:57 +0530 Subject: [PATCH 05/41] latest version 1.00 --- lib/Net/Netconf/Access/ssh.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Net/Netconf/Access/ssh.pm b/lib/Net/Netconf/Access/ssh.pm index 0f2222e..40650f1 100644 --- a/lib/Net/Netconf/Access/ssh.pm +++ b/lib/Net/Netconf/Access/ssh.pm @@ -7,7 +7,7 @@ use Carp; use parent 'Net::Netconf::Access'; -our $VERSION = '1.0'; +our $VERSION = '1.00'; # Just for convenience sub trace { From 2798be7ee8070af032e75e2e240e017690bffe4c Mon Sep 17 00:00:00 2001 From: Priyal Jain Date: Mon, 22 Dec 2014 11:28:32 +0530 Subject: [PATCH 06/41] latest version 1.00 --- lib/Net/Netconf/Access.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Net/Netconf/Access.pm b/lib/Net/Netconf/Access.pm index fef07e3..ee9e4c6 100644 --- a/lib/Net/Netconf/Access.pm +++ b/lib/Net/Netconf/Access.pm @@ -3,7 +3,7 @@ package Net::Netconf::Access; use strict; use Net::Netconf::Trace; use Carp; -our $VERSION ='0.01'; +our $VERSION ='1.00'; sub new { From cd19b06484c668f0238a33fdd2d300732bf9456c Mon Sep 17 00:00:00 2001 From: Priyal Jain Date: Mon, 22 Dec 2014 11:31:15 +0530 Subject: [PATCH 07/41] latest version 1.00 --- lib/Net/Netconf/Constants.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Net/Netconf/Constants.pm b/lib/Net/Netconf/Constants.pm index 139ea2a..f3b0ac0 100644 --- a/lib/Net/Netconf/Constants.pm +++ b/lib/Net/Netconf/Constants.pm @@ -1,6 +1,6 @@ package Net::Netconf::Constants; -our $VERSION ='0.01'; +our $VERSION ='1.00'; # Netconf server: minimum version use constant NC_VERS_MIN => 7.5; # Constants pertaining to the Netconf states From 862376f528974e7af298932e025ef33b6ef5354b Mon Sep 17 00:00:00 2001 From: Priyal Jain Date: Mon, 22 Dec 2014 11:32:11 +0530 Subject: [PATCH 08/41] latest version 1.00 --- lib/Net/Netconf/Device.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Net/Netconf/Device.pm b/lib/Net/Netconf/Device.pm index e908572..3bc1285 100755 --- a/lib/Net/Netconf/Device.pm +++ b/lib/Net/Netconf/Device.pm @@ -18,7 +18,7 @@ use vars qw(@EXPORT); use vars qw(@ISA); use vars qw($AUTOLOAD); -our $VERSION ='0.01'; +our $VERSION ='1.00'; my $NO_ARGS = bless {}, 'NO_ARGS'; my $TOGGLE = bless { 1 => 1 }, 'TOGGLE'; my $TOGGLE_NO = bless {}, 'TOGGLE'; From 5b8bdb7e5eb3f1238e7fa581ea9954cff2754235 Mon Sep 17 00:00:00 2001 From: Priyal Jain Date: Mon, 22 Dec 2014 11:32:50 +0530 Subject: [PATCH 09/41] latest version 1.00 --- lib/Net/Netconf/EzEditXML.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Net/Netconf/EzEditXML.pm b/lib/Net/Netconf/EzEditXML.pm index 9be2940..0c26a2f 100644 --- a/lib/Net/Netconf/EzEditXML.pm +++ b/lib/Net/Netconf/EzEditXML.pm @@ -35,7 +35,7 @@ use XML::LibXML; require Exporter; @ISA = qw(Exporter); -our $VERSION ='0.01'; +our $VERSION ='1.00'; =head1 METHODS =cut From 17672ead52dca7611aeb62e313c14040650775e4 Mon Sep 17 00:00:00 2001 From: Priyal Jain Date: Mon, 22 Dec 2014 11:33:15 +0530 Subject: [PATCH 10/41] latest version 1.00 --- lib/Net/Netconf/Manager.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Net/Netconf/Manager.pm b/lib/Net/Netconf/Manager.pm index e5970ab..bc518d3 100644 --- a/lib/Net/Netconf/Manager.pm +++ b/lib/Net/Netconf/Manager.pm @@ -1,7 +1,7 @@ package Net::Netconf::Manager; use Carp; -our $VERSION ='0.01'; +our $VERSION ='1.00'; # This instantiates a Junoscript or a Netconf device depending on the 'server' # specified. Default is Netconf. From 383d9f82d9bc7efd7603a6f32019e7d36740de3c Mon Sep 17 00:00:00 2001 From: Priyal Jain Date: Mon, 22 Dec 2014 11:33:39 +0530 Subject: [PATCH 11/41] latest version 1.00 --- lib/Net/Netconf/SAXHandler.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Net/Netconf/SAXHandler.pm b/lib/Net/Netconf/SAXHandler.pm index d813234..1fe76bc 100644 --- a/lib/Net/Netconf/SAXHandler.pm +++ b/lib/Net/Netconf/SAXHandler.pm @@ -2,7 +2,7 @@ package Net::Netconf::SAXHandler; use strict; use Carp; -our $VERSION ='0.01'; +our $VERSION ='1.00'; use vars qw(@EXPORT_OK @parsed_cap $session_id $found_error $no_error %rpc_errors $junos_version); From cb7b3914131e14eda723bc41b4844fd61e10a8cf Mon Sep 17 00:00:00 2001 From: Priyal Jain Date: Mon, 22 Dec 2014 11:34:05 +0530 Subject: [PATCH 12/41] latest version 1.00 --- lib/Net/Netconf/Trace.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Net/Netconf/Trace.pm b/lib/Net/Netconf/Trace.pm index 3529236..37840ab 100644 --- a/lib/Net/Netconf/Trace.pm +++ b/lib/Net/Netconf/Trace.pm @@ -2,7 +2,7 @@ package Net::Netconf::Trace; use strict; use Carp; -our $VERSION ='0.01'; +our $VERSION ='1.00'; use constant DEBUG_LEVEL => 1; use constant TRACE_LEVEL => 2; use constant INFO_LEVEL => 3; From fe55fe63cc0205cc8ca8697eebbbaaec683d26a3 Mon Sep 17 00:00:00 2001 From: Priyal Jain Date: Mon, 22 Dec 2014 11:34:44 +0530 Subject: [PATCH 13/41] latest version 1.00 --- lib/Net/Netconf.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Net/Netconf.pm b/lib/Net/Netconf.pm index b982f45..9274751 100644 --- a/lib/Net/Netconf.pm +++ b/lib/Net/Netconf.pm @@ -1,5 +1,5 @@ package Net::Netconf; -our $VERSION ='1.00'; +our $VERSION = '1.00'; =head1 NAME Net::Netconf : Netconf Perl Client From 62ceaaa668002883a1e957c4ef802def6d26a046 Mon Sep 17 00:00:00 2001 From: Priyal Jain Date: Mon, 22 Dec 2014 11:34:59 +0530 Subject: [PATCH 14/41] latest version 1.00 --- lib/Net/Netconf.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Net/Netconf.pm b/lib/Net/Netconf.pm index 9274751..b982f45 100644 --- a/lib/Net/Netconf.pm +++ b/lib/Net/Netconf.pm @@ -1,5 +1,5 @@ package Net::Netconf; -our $VERSION = '1.00'; +our $VERSION ='1.00'; =head1 NAME Net::Netconf : Netconf Perl Client From 15209a62fcf22d827c2788dc04da7eef2167680c Mon Sep 17 00:00:00 2001 From: Priyal Jain Date: Mon, 22 Dec 2014 11:37:05 +0530 Subject: [PATCH 15/41] latest version 1.00 --- Makefile.PL | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.PL b/Makefile.PL index 7e06bac..0aa3976 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -1,6 +1,6 @@ use ExtUtils::MakeMaker; -our $VERSION ='0.01'; +our $VERSION ='1.00'; use 5.006; WriteMakefile( From a3214abbc47871ee37f6a64232cf5ae37a61cb64 Mon Sep 17 00:00:00 2001 From: Priyal Jain Date: Mon, 22 Dec 2014 11:43:39 +0530 Subject: [PATCH 16/41] latest version 1.00 --- CHANGES | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 1fef341..0e74e28 100644 --- a/CHANGES +++ b/CHANGES @@ -1,2 +1,4 @@ 2014-16-04 NETCONF Team - * initial version + * initial version v0.01 + * latest version v1.00 + From d28a033a76f4ae479a14c64496ece446462ce75b Mon Sep 17 00:00:00 2001 From: Priyal Jain Date: Mon, 22 Dec 2014 11:59:26 +0530 Subject: [PATCH 17/41] latest version 1.00 --- MANIFEST | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/MANIFEST b/MANIFEST index f0f980d..f591d5e 100644 --- a/MANIFEST +++ b/MANIFEST @@ -11,8 +11,11 @@ lib/Net/Netconf/Manager.pm lib/Net/Netconf/SAXHandler.pm lib/Net/Netconf/Trace.pm lib/Net/Netconf/Access/ssh.pm -examples/test_operation.pl -examples/edit_configuration/edit_configuration.pl +examples/Diaganose_bgp/diagnose_bgp.pl +examples/Diaganose_bgp/bgp.xml +examples/chassis_inventory/chassis_inventory.xml +examples/chassis_inventory/get_chassis_inventory.pl examples/edit_configuration/config.txt examples/edit_configuration/config.xml - +examples/edit_configuration/edit_configuration.pl +examples/get_system_information.pl From f94033ed7fc32eb933fe206282f901ac6d2ddecf Mon Sep 17 00:00:00 2001 From: Priyal Jain Date: Wed, 24 Dec 2014 11:39:34 +0530 Subject: [PATCH 18/41] Update README.md --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0f7bc64..5eade0a 100644 --- a/README.md +++ b/README.md @@ -213,8 +213,17 @@ Troubleshooting (Ubuntu12.04LTS or higher version) Sometimes you may get error like "Checking for ability to link against xml2...no " while installing LibXML then use this command sudo apt-get install zlib1g-dev + 2. For error related to Net::SSH2 + Sometimes you may get error like, + fatal error: openssl/crypto.h: No such file or directory + #include + ^ + compilation terminated. + make: *** [SSH2.o] Error 1 + then use then command: + sudo apt-get install libssl-dev - 2. For YAML related Errors + 3. For YAML related Errors Sometimes you may get that yaml is not installed then run following commands: apt-get install libyaml-appconfig-perl apt-get install libconfig-yaml-perl From e2a160427e2dd6028ea337dc8fa1a3005d820695 Mon Sep 17 00:00:00 2001 From: Priyal Jain Date: Wed, 24 Dec 2014 11:40:28 +0530 Subject: [PATCH 19/41] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5eade0a..370af0f 100644 --- a/README.md +++ b/README.md @@ -213,6 +213,7 @@ Troubleshooting (Ubuntu12.04LTS or higher version) Sometimes you may get error like "Checking for ability to link against xml2...no " while installing LibXML then use this command sudo apt-get install zlib1g-dev + 2. For error related to Net::SSH2 Sometimes you may get error like, fatal error: openssl/crypto.h: No such file or directory @@ -228,7 +229,7 @@ Troubleshooting (Ubuntu12.04LTS or higher version) apt-get install libyaml-appconfig-perl apt-get install libconfig-yaml-perl - 3. For cpan related errors: + 4. For cpan related errors: While installing some files using cpan, for example "cpan File::Which" you may get error like checksum mismatch for distribution, then try installing that package using "cpanm" First install cpanm in your system by: @@ -241,7 +242,7 @@ Troubleshooting (Ubuntu12.04LTS or higher version) you can also try installing by force : apt-get -f install - + # CONTRIBUTORS - [Ganesh Nalawade](https://github.com/ganeshnalawade) From 0fa43885540aab4730469e474eebf3f0aee59457 Mon Sep 17 00:00:00 2001 From: Priyal Jain Date: Wed, 24 Dec 2014 11:42:58 +0530 Subject: [PATCH 20/41] Update README --- README | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/README b/README index 0446b40..3077cb2 100644 --- a/README +++ b/README @@ -214,13 +214,23 @@ Troubleshooting (Ubuntu12.04LTS or higher version) Sometimes you may get error like "Checking for ability to link against xml2...no " while installing LibXML then use this command sudo apt-get install zlib1g-dev + + 2. For error related to Net::SSH2 + Sometimes you may get error like, + fatal error: openssl/crypto.h: No such file or directory + #include + ^ + compilation terminated. + make: *** [SSH2.o] Error 1 + then use then command: + sudo apt-get install libssl-dev - 2. For YAML related Errors + 3. For YAML related Errors Sometimes you may get that yaml is not installed then run following commands: apt-get install libyaml-appconfig-perl apt-get install libconfig-yaml-perl - 3. For cpan related errors: + 4. For cpan related errors: While installing some files using cpan, for example "cpan File::Which" you may get error like checksum mismatch for distribution, then try installing that package using "cpanm" First install cpanm in your system by: @@ -232,4 +242,3 @@ Troubleshooting (Ubuntu12.04LTS or higher version) unmet dependency then first install that package using cpan / cpanm and then install your desired package. you can also try installing by force : apt-get -f install - From 16306e7c6e03a737ca77973c5dbc81ae3d58a014 Mon Sep 17 00:00:00 2001 From: Priyal Jain Date: Wed, 24 Dec 2014 11:43:24 +0530 Subject: [PATCH 21/41] Update README --- README | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README b/README index 3077cb2..56f426a 100644 --- a/README +++ b/README @@ -242,3 +242,5 @@ Troubleshooting (Ubuntu12.04LTS or higher version) unmet dependency then first install that package using cpan / cpanm and then install your desired package. you can also try installing by force : apt-get -f install + + From 55650a4a271d976af1e048509ad775d0699d74e9 Mon Sep 17 00:00:00 2001 From: Priyal Jain Date: Wed, 24 Dec 2014 11:45:48 +0530 Subject: [PATCH 22/41] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 370af0f..05d7b59 100644 --- a/README.md +++ b/README.md @@ -242,7 +242,6 @@ Troubleshooting (Ubuntu12.04LTS or higher version) you can also try installing by force : apt-get -f install - # CONTRIBUTORS - [Ganesh Nalawade](https://github.com/ganeshnalawade) From dbb61bead8f87b5d55c5d318c6773c8a8bcb300e Mon Sep 17 00:00:00 2001 From: Tim Jackson Date: Wed, 1 Apr 2015 13:16:16 -0700 Subject: [PATCH 23/41] Added support to launch junoscript/netconf via the shell, as well as an override to pass a port => into Net::Netconf::Manager --- lib/Net/Netconf/Access/ssh.pm | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/lib/Net/Netconf/Access/ssh.pm b/lib/Net/Netconf/Access/ssh.pm index 40650f1..0196fca 100644 --- a/lib/Net/Netconf/Access/ssh.pm +++ b/lib/Net/Netconf/Access/ssh.pm @@ -25,8 +25,9 @@ sub start { $self->{'server'} ||= 'netconf'; my $port = ($self->{'server'} eq 'netconf') ? - Net::Netconf::Constants::NC_DEFAULT_PORT : - (getservbyname('ssh', 'tcp'))[2]; + $self->{'port'} || Net::Netconf::Constants::NC_DEFAULT_PORT : + $self->{'port'} || (getservbyname('ssh', 'tcp'))[2]; + my $ssh2 = Net::SSH2->new(); croak "Failed to create a new Net::SSH2 object" unless(ref $ssh2); @@ -48,9 +49,16 @@ sub start { $self->trace("Successfully created SSH channel!"); $self->trace("Starting subsystem '$self->{'server'}'..."); - $chan->subsystem($self->{'server'}) - or croak "Failed to start subsystem '$self->{'server'}'"; - $self->trace("Successfully started subsystem!"); + my $subsystem = $chan->subsystem($self->{'server'}); + if(!$subsystem) { + $self->trace("Failed to start '$self->{'server'}' subsystem, trying to exec"); + $chan->exec($self->{'server'}) + or croak "Failed to exec ". $self->{'server'}; + $chan->flush(); + $self->trace("Started server '$self->{'server'}' in exec"); + } else { + $self->trace("Successfully started subsystem!"); + } $self->{'ssh2'} = $ssh2; $self->{'chan'} = $chan; From a99a1431366f05ae3d5c57d0aa9c4de039c9b61b Mon Sep 17 00:00:00 2001 From: Priyal Jain Date: Tue, 7 Apr 2015 19:11:30 +0530 Subject: [PATCH 24/41] can provide port no also.. User can provide port no for establishing connection --- examples/get_system_information.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/get_system_information.pl b/examples/get_system_information.pl index 9023eac..59f1989 100644 --- a/examples/get_system_information.pl +++ b/examples/get_system_information.pl @@ -51,7 +51,8 @@ sub output_usage $jnx = new Net::Netconf::Manager( 'access' => 'ssh', 'login' => $login, 'password' => $pass, - 'hostname' => $hostname); + 'hostname' => $hostname + 'port' => 22); if(! $jnx ) { print STDERR "Unable to connect to Junos device \n"; From dbc309350a7ee9064508592fce8b6aa969ebcb69 Mon Sep 17 00:00:00 2001 From: Priyal Jain Date: Tue, 12 May 2015 10:55:41 +0530 Subject: [PATCH 25/41] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 05d7b59..65014f2 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ Installation "cpan Net::Netconf". Sometimes cpan command gives error then try installing using "cpanm" command. First install cpanm in your - system by "apt-get install cpanmius" and then install this module by "cpanm Net::Netconf" + system by "apt-get install cpanminus" and then install this module by "cpanm Net::Netconf" Using Source code in github -------------------------------------------------------------------------------------------- From 0c520ef878a2ba52c0d0bd685a8fa15177b2444b Mon Sep 17 00:00:00 2001 From: Priyal Jain Date: Tue, 12 May 2015 10:56:28 +0530 Subject: [PATCH 26/41] Update README --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 56f426a..6790aea 100644 --- a/README +++ b/README @@ -101,7 +101,7 @@ Installation "cpan Net::Netconf". Sometimes cpan command gives error then try installing using "cpanm" command. First install cpanm in your - system by "apt-get install cpanmius" and then install this module by "cpanm Net::Netconf" + system by "apt-get install cpanminus" and then install this module by "cpanm Net::Netconf" Using Source code in github -------------------------------------------------------------------------------------------- From 9aed7bd346e6a81411b1eec13653607ee94ab193 Mon Sep 17 00:00:00 2001 From: Priyal Jain Date: Tue, 12 May 2015 13:18:49 +0530 Subject: [PATCH 27/41] updating troubleshooting for installing libz --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 65014f2..ac7667d 100644 --- a/README.md +++ b/README.md @@ -228,6 +228,19 @@ Troubleshooting (Ubuntu12.04LTS or higher version) Sometimes you may get that yaml is not installed then run following commands: apt-get install libyaml-appconfig-perl apt-get install libconfig-yaml-perl + + 3. For libz errors like: + /usr/bin/ld: /usr/local/lib/libz.a(crc32.o): relocation R_X86_64_32 against `.rodata' can not be used when + making a shared object; recompile with -fPIC + /usr/local/lib/libz.a: could not read symbols: Bad value + try installing from source code: + download libz source code, https://google-desktop-for-linux-mirror.googlecode.com/files/zlib-1.2.3.tar.gz + according to platform u are using. + open Makefile and add -fPIC in cflag, (smth like: CFLAGS=-O3 -DUSE_MMAP -fPIC) + then compile it: + ./configure + make test + make install 4. For cpan related errors: While installing some files using cpan, for example "cpan File::Which" you may get error like checksum mismatch From 86839011f063ef9ab6f5e8f3321778e4aa697c26 Mon Sep 17 00:00:00 2001 From: Priyal Jain Date: Fri, 15 May 2015 15:28:05 +0530 Subject: [PATCH 28/41] Update get_system_information.pl --- examples/get_system_information.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/get_system_information.pl b/examples/get_system_information.pl index 59f1989..3e7f74b 100644 --- a/examples/get_system_information.pl +++ b/examples/get_system_information.pl @@ -51,7 +51,7 @@ sub output_usage $jnx = new Net::Netconf::Manager( 'access' => 'ssh', 'login' => $login, 'password' => $pass, - 'hostname' => $hostname + 'hostname' => $hostname, 'port' => 22); if(! $jnx ) { From 02d2897551641c075850790dff2e0ef168155575 Mon Sep 17 00:00:00 2001 From: Jainpriyal Date: Thu, 21 May 2015 12:46:59 +0530 Subject: [PATCH 29/41] syncing version with cpan --- CHANGES | 5 +++-- Makefile.PL | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 0e74e28..0914c2b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,5 @@ 2014-16-04 NETCONF Team - * initial version v0.01 - * latest version v1.00 + * first version v0.01 + * second version v1.00 + * latest version v1.01 diff --git a/Makefile.PL b/Makefile.PL index 0aa3976..8ae2932 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -1,6 +1,6 @@ use ExtUtils::MakeMaker; -our $VERSION ='1.00'; +our $VERSION ='1.01'; use 5.006; WriteMakefile( From 4c5da91707e733c67dd5c711039245b13a9e00ab Mon Sep 17 00:00:00 2001 From: Jainpriyal Date: Fri, 22 May 2015 12:09:36 +0530 Subject: [PATCH 30/41] updated version --- CHANGES | 4 ++-- Makefile.PL | 2 +- lib/Net/Netconf.pm | 2 +- lib/Net/Netconf/Access.pm | 2 +- lib/Net/Netconf/Access/ssh.pm | 2 +- lib/Net/Netconf/Constants.pm | 2 +- lib/Net/Netconf/Device.pm | 2 +- lib/Net/Netconf/EzEditXML.pm | 2 +- lib/Net/Netconf/Manager.pm | 2 +- lib/Net/Netconf/SAXHandler.pm | 2 +- lib/Net/Netconf/Trace.pm | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CHANGES b/CHANGES index 0914c2b..db13038 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,5 @@ - 2014-16-04 NETCONF Team + 2015-22-05 NETCONF Team * first version v0.01 * second version v1.00 - * latest version v1.01 + * latest version v1.02 diff --git a/Makefile.PL b/Makefile.PL index 8ae2932..6bcf836 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -1,6 +1,6 @@ use ExtUtils::MakeMaker; -our $VERSION ='1.01'; +our $VERSION ='1.02'; use 5.006; WriteMakefile( diff --git a/lib/Net/Netconf.pm b/lib/Net/Netconf.pm index b982f45..feab1dd 100644 --- a/lib/Net/Netconf.pm +++ b/lib/Net/Netconf.pm @@ -1,5 +1,5 @@ package Net::Netconf; -our $VERSION ='1.00'; +our $VERSION ='1.02'; =head1 NAME Net::Netconf : Netconf Perl Client diff --git a/lib/Net/Netconf/Access.pm b/lib/Net/Netconf/Access.pm index ee9e4c6..f3ee9ad 100644 --- a/lib/Net/Netconf/Access.pm +++ b/lib/Net/Netconf/Access.pm @@ -3,7 +3,7 @@ package Net::Netconf::Access; use strict; use Net::Netconf::Trace; use Carp; -our $VERSION ='1.00'; +our $VERSION ='1.02'; sub new { diff --git a/lib/Net/Netconf/Access/ssh.pm b/lib/Net/Netconf/Access/ssh.pm index 0196fca..d612ff3 100644 --- a/lib/Net/Netconf/Access/ssh.pm +++ b/lib/Net/Netconf/Access/ssh.pm @@ -7,7 +7,7 @@ use Carp; use parent 'Net::Netconf::Access'; -our $VERSION = '1.00'; +our $VERSION = '1.02'; # Just for convenience sub trace { diff --git a/lib/Net/Netconf/Constants.pm b/lib/Net/Netconf/Constants.pm index f3b0ac0..5d3de46 100644 --- a/lib/Net/Netconf/Constants.pm +++ b/lib/Net/Netconf/Constants.pm @@ -1,6 +1,6 @@ package Net::Netconf::Constants; -our $VERSION ='1.00'; +our $VERSION ='1.02'; # Netconf server: minimum version use constant NC_VERS_MIN => 7.5; # Constants pertaining to the Netconf states diff --git a/lib/Net/Netconf/Device.pm b/lib/Net/Netconf/Device.pm index 3bc1285..c2a4a74 100755 --- a/lib/Net/Netconf/Device.pm +++ b/lib/Net/Netconf/Device.pm @@ -18,7 +18,7 @@ use vars qw(@EXPORT); use vars qw(@ISA); use vars qw($AUTOLOAD); -our $VERSION ='1.00'; +our $VERSION ='1.02'; my $NO_ARGS = bless {}, 'NO_ARGS'; my $TOGGLE = bless { 1 => 1 }, 'TOGGLE'; my $TOGGLE_NO = bless {}, 'TOGGLE'; diff --git a/lib/Net/Netconf/EzEditXML.pm b/lib/Net/Netconf/EzEditXML.pm index 0c26a2f..d11cae2 100644 --- a/lib/Net/Netconf/EzEditXML.pm +++ b/lib/Net/Netconf/EzEditXML.pm @@ -35,7 +35,7 @@ use XML::LibXML; require Exporter; @ISA = qw(Exporter); -our $VERSION ='1.00'; +our $VERSION ='1.02'; =head1 METHODS =cut diff --git a/lib/Net/Netconf/Manager.pm b/lib/Net/Netconf/Manager.pm index bc518d3..d0d1b4d 100644 --- a/lib/Net/Netconf/Manager.pm +++ b/lib/Net/Netconf/Manager.pm @@ -1,7 +1,7 @@ package Net::Netconf::Manager; use Carp; -our $VERSION ='1.00'; +our $VERSION ='1.02'; # This instantiates a Junoscript or a Netconf device depending on the 'server' # specified. Default is Netconf. diff --git a/lib/Net/Netconf/SAXHandler.pm b/lib/Net/Netconf/SAXHandler.pm index 1fe76bc..1545370 100644 --- a/lib/Net/Netconf/SAXHandler.pm +++ b/lib/Net/Netconf/SAXHandler.pm @@ -2,7 +2,7 @@ package Net::Netconf::SAXHandler; use strict; use Carp; -our $VERSION ='1.00'; +our $VERSION ='1.02'; use vars qw(@EXPORT_OK @parsed_cap $session_id $found_error $no_error %rpc_errors $junos_version); diff --git a/lib/Net/Netconf/Trace.pm b/lib/Net/Netconf/Trace.pm index 37840ab..4492c54 100644 --- a/lib/Net/Netconf/Trace.pm +++ b/lib/Net/Netconf/Trace.pm @@ -2,7 +2,7 @@ package Net::Netconf::Trace; use strict; use Carp; -our $VERSION ='1.00'; +our $VERSION ='1.02'; use constant DEBUG_LEVEL => 1; use constant TRACE_LEVEL => 2; use constant INFO_LEVEL => 3; From f4a946d0673d93053d9faeb023e6b80914ba78a0 Mon Sep 17 00:00:00 2001 From: Diogo Montagner Date: Thu, 14 Apr 2016 06:19:07 +1000 Subject: [PATCH 31/41] Create collect-show-interface.pl This example demonstrates how to collect and parse the output of show interfaces command using XML::XPath and XML DOM. --- examples/collect-show-interface.pl | 71 ++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 examples/collect-show-interface.pl diff --git a/examples/collect-show-interface.pl b/examples/collect-show-interface.pl new file mode 100644 index 0000000..3dc250a --- /dev/null +++ b/examples/collect-show-interface.pl @@ -0,0 +1,71 @@ +#!/usr/bin/perl + +use Net::Netconf::Manager; +use warnings; +use strict; +use XML::XPath; + +my $hostname = "10.254.254.100"; +my $login= "lab"; +my $pass = "lab123"; + +my $jnx = new Net::Netconf::Manager( 'access' => 'ssh', + 'login' => $login, + 'password' => $pass, + 'hostname' => $hostname); + +if(! $jnx ) { + print STDERR "Unable to connect to Junos device \n"; + exit 1; +} + +print "Connection established: " . $jnx->get_session_id . "\n"; + +my $query = "get_interface_information"; + +my %queryargs = ( 'interface-name' => 'ge-0/0/0' ); + +my $reply=$jnx->$query(%queryargs); + +if ($jnx->has_error) { + print "ERROR: in processing request\n"; + # Get the error + my $error = $jnx->get_first_error(); + $jnx->print_error_info(%$error); + exit 1; +} + +open(FILEOUTPUT, ">interface_output.xml"); + +print FILEOUTPUT $jnx->{'server_response'}; + +close(FILEOUTPUT); + +# this parsing is specifically for tag +# you can write your own application in similar way +# parsing reply from server + +print "\n\n\n"; +print "Example using XML::XPath\n----------------------------------------------\n\n"; +my $interfaceOutput = XML::XPath->new(filename => 'interface_output.xml'); + +my $interfaceDescription = $interfaceOutput->find('/rpc-reply/interface-information/physical-interface/description'); +my $interfaceIPv4Address = $interfaceOutput->find('/rpc-reply/interface-information/physical-interface/logical-interface/address-family/interface-address/ifa-local'); + +# Parsing using XML::XPath + +print "Interface description = $interfaceDescription\n"; +print "Interface address = $interfaceIPv4Address\n"; + +print "\n\n\n\n"; + +print "Example using DOM\n----------------------------------------------\n\n"; +my $XMLOutput= $jnx->get_dom(); +my $res= $XMLOutput->getElementsByTagName("description")->item(0)->getFirstChild->getData; +my $res2= $XMLOutput->getElementsByTagName("ifa-local")->item(0)->getFirstChild->getData; +print "\n"; +print "DOM - Interface description: " . $res . "\n"; +print "DOM - Interface address ". $res2 . "\n"; +print "\n"; + +$jnx->disconnect(); From 98fad7f890d2811faef49ba1c37c83c0475b3e03 Mon Sep 17 00:00:00 2001 From: Priyal Jain Date: Thu, 23 Jun 2016 01:16:42 +0530 Subject: [PATCH 32/41] Updating README.md --- README.md | 118 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 75 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index ac7667d..0201df0 100644 --- a/README.md +++ b/README.md @@ -143,49 +143,81 @@ Reading configuration: System Information This example sends a request to the Networks routing platform and displays the result to the standard output.It also shows how to parse reply from server - use Net::Netconf::Manager; - print "Enter hostname\n"; - my $hostname = <>; - print "Enter username\n"; - my $login= <>; - print "Enter password\n"; - my $pass = <>; - chomp($hostname); - chomp($login); - chomp($pass); - $jnx = new Net::Netconf::Manager( 'access' => 'ssh', - 'login' => $login, - 'password' => $pass, - 'hostname' => $hostname); - if(! $jnx ) { - print STDERR "Unable to connect to Junos device \n"; - exit 1; - } - print "Connection established: " . $jnx->get_session_id . "\n"; - my $reply=$jnx->get_system_information(); - if ($jnx->has_error) { - print "ERROR: in processing request\n"; - # Get the error - my $error = $jnx->get_first_error(); - $jnx->print_error_info(%$error); - exit 1; - } - print "Rpc reply from server.\n"; - print ">>>>>>>>>>\n"; - print $reply; - print "<<<<<<<<<<\n"; - - # this parsing is specifically for tag - # you can write your own application in similar way - #parsing reply from server - my $config= $jnx->get_dom(); - $res= $config->getElementsByTagName("hardware-model")->item(0)->getFirstChild->getData; - $res2= $config->getElementsByTagName("os-name")->item(0)->getFirstChild->getData; - $res3= $config->getElementsByTagName("host-name")->item(0)->getFirstChild->getData; - print "\nhardware information ". $res ."\n"; - print "os-name " .$res2 . "\n"; - print "host-name ". $res3. "\n"; - $jnx->disconnect(); +Script: get_system_information.pl +``` + use Net::Netconf::Manager; + print "Enter hostname\n"; + my $hostname = <>; + print "Enter username\n"; + my $login= <>; + print "Enter password\n"; + my $pass = <>; + chomp($hostname); + chomp($login); + chomp($pass); + $jnx = new Net::Netconf::Manager( 'access' => 'ssh', + 'login' => $login, + 'password' => $pass, + 'hostname' => $hostname); + if(! $jnx ) { + print STDERR "Unable to connect to Junos device \n"; + exit 1; + } + print "Connection established: " . $jnx->get_session_id . "\n"; + my $reply=$jnx->get_system_information(); + if ($jnx->has_error) { + print "ERROR: in processing request\n"; + # Get the error + my $error = $jnx->get_first_error(); + $jnx->print_error_info(%$error); + exit 1; + } + print "Server request: \n $jnx->{'request'}\n Server response: \n $jnx->{'server_response'} \n"; + + # this parsing is specifically for tag + # you can write your own application in similar way + #parsing reply from server + my $config= $jnx->get_dom(); + $res= $config->getElementsByTagName("hardware-model")->item(0)->getFirstChild->getData; + $res2= $config->getElementsByTagName("os-name")->item(0)->getFirstChild->getData; + $res3= $config->getElementsByTagName("host-name")->item(0)->getFirstChild->getData; + print "\nhardware information ". $res ."\n"; + print "os-name " .$res2 . "\n"; + print "host-name ". $res3. "\n"; + $jnx->disconnect(); +``` + +Output: +Run netconf-perl script: +``` +perl +``` +``` +priyal@priyal:~/Desktop$ perl get_system_information.pl +Enter hostname: device1 +Enter username: foo +Enter password: passwd123 + +Server request: + + + + + Server response: + + +olive +junos +15.2I20151211 +device1 + + + +hardware information: olive +os-name: junos +host-name: device1 +``` + Troubleshooting (Ubuntu12.04LTS or higher version) ================= From e556362431407ac62ce9432eaece3a2fe6e1ec23 Mon Sep 17 00:00:00 2001 From: Jainpriyal Date: Thu, 23 Jun 2016 01:21:22 +0530 Subject: [PATCH 33/41] renaming example files to be in syn with previous netconf-perl version --- examples/{Diaganose_bgp => diagnose_bgp}/bgp.xml | 0 examples/{Diaganose_bgp => diagnose_bgp}/diagnose_bgp.pl | 0 .../chassis_inventory.xml | 0 .../get_chassis_inventory.pl | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename examples/{Diaganose_bgp => diagnose_bgp}/bgp.xml (100%) rename examples/{Diaganose_bgp => diagnose_bgp}/diagnose_bgp.pl (100%) rename examples/{chassis_inventory => get_chassis_inventory}/chassis_inventory.xml (100%) rename examples/{chassis_inventory => get_chassis_inventory}/get_chassis_inventory.pl (100%) diff --git a/examples/Diaganose_bgp/bgp.xml b/examples/diagnose_bgp/bgp.xml similarity index 100% rename from examples/Diaganose_bgp/bgp.xml rename to examples/diagnose_bgp/bgp.xml diff --git a/examples/Diaganose_bgp/diagnose_bgp.pl b/examples/diagnose_bgp/diagnose_bgp.pl similarity index 100% rename from examples/Diaganose_bgp/diagnose_bgp.pl rename to examples/diagnose_bgp/diagnose_bgp.pl diff --git a/examples/chassis_inventory/chassis_inventory.xml b/examples/get_chassis_inventory/chassis_inventory.xml similarity index 100% rename from examples/chassis_inventory/chassis_inventory.xml rename to examples/get_chassis_inventory/chassis_inventory.xml diff --git a/examples/chassis_inventory/get_chassis_inventory.pl b/examples/get_chassis_inventory/get_chassis_inventory.pl similarity index 100% rename from examples/chassis_inventory/get_chassis_inventory.pl rename to examples/get_chassis_inventory/get_chassis_inventory.pl From 99b79c0e7bf8297ab321970839d65bdd2001a36b Mon Sep 17 00:00:00 2001 From: Jainpriyal Date: Thu, 23 Jun 2016 01:25:16 +0530 Subject: [PATCH 34/41] Updating README and example --- README | 136 +++++++++++------- ...interface.pl => collect_show_interface.pl} | 0 2 files changed, 85 insertions(+), 51 deletions(-) rename examples/{collect-show-interface.pl => collect_show_interface.pl} (100%) diff --git a/README b/README index 19785a8..0201df0 100644 --- a/README +++ b/README @@ -143,49 +143,81 @@ Reading configuration: System Information This example sends a request to the Networks routing platform and displays the result to the standard output.It also shows how to parse reply from server - use Net::Netconf::Manager; - print "Enter hostname\n"; - my $hostname = <>; - print "Enter username\n"; - my $login= <>; - print "Enter password\n"; - my $pass = <>; - chomp($hostname); - chomp($login); - chomp($pass); - $jnx = new Net::Netconf::Manager( 'access' => 'ssh', - 'login' => $login, - 'password' => $pass, - 'hostname' => $hostname); - if(! $jnx ) { - print STDERR "Unable to connect to Junos device \n"; - exit 1; - } - print "Connection established: " . $jnx->get_session_id . "\n"; - my $reply=$jnx->get_system_information(); - if ($jnx->has_error) { - print "ERROR: in processing request\n"; - # Get the error - my $error = $jnx->get_first_error(); - $jnx->print_error_info(%$error); - exit 1; - } - print "Rpc reply from server.\n"; - print ">>>>>>>>>>\n"; - print $reply; - print "<<<<<<<<<<\n"; - - # this parsing is specifically for tag - # you can write your own application in similar way - #parsing reply from server - my $config= $jnx->get_dom(); - $res= $config->getElementsByTagName("hardware-model")->item(0)->getFirstChild->getData; - $res2= $config->getElementsByTagName("os-name")->item(0)->getFirstChild->getData; - $res3= $config->getElementsByTagName("host-name")->item(0)->getFirstChild->getData; - print "\nhardware information ". $res ."\n"; - print "os-name " .$res2 . "\n"; - print "host-name ". $res3. "\n"; - $jnx->disconnect(); +Script: get_system_information.pl +``` + use Net::Netconf::Manager; + print "Enter hostname\n"; + my $hostname = <>; + print "Enter username\n"; + my $login= <>; + print "Enter password\n"; + my $pass = <>; + chomp($hostname); + chomp($login); + chomp($pass); + $jnx = new Net::Netconf::Manager( 'access' => 'ssh', + 'login' => $login, + 'password' => $pass, + 'hostname' => $hostname); + if(! $jnx ) { + print STDERR "Unable to connect to Junos device \n"; + exit 1; + } + print "Connection established: " . $jnx->get_session_id . "\n"; + my $reply=$jnx->get_system_information(); + if ($jnx->has_error) { + print "ERROR: in processing request\n"; + # Get the error + my $error = $jnx->get_first_error(); + $jnx->print_error_info(%$error); + exit 1; + } + print "Server request: \n $jnx->{'request'}\n Server response: \n $jnx->{'server_response'} \n"; + + # this parsing is specifically for tag + # you can write your own application in similar way + #parsing reply from server + my $config= $jnx->get_dom(); + $res= $config->getElementsByTagName("hardware-model")->item(0)->getFirstChild->getData; + $res2= $config->getElementsByTagName("os-name")->item(0)->getFirstChild->getData; + $res3= $config->getElementsByTagName("host-name")->item(0)->getFirstChild->getData; + print "\nhardware information ". $res ."\n"; + print "os-name " .$res2 . "\n"; + print "host-name ". $res3. "\n"; + $jnx->disconnect(); +``` + +Output: +Run netconf-perl script: +``` +perl +``` +``` +priyal@priyal:~/Desktop$ perl get_system_information.pl +Enter hostname: device1 +Enter username: foo +Enter password: passwd123 + +Server request: + + + + + Server response: + + +olive +junos +15.2I20151211 +device1 + + + +hardware information: olive +os-name: junos +host-name: device1 +``` + Troubleshooting (Ubuntu12.04LTS or higher version) ================= @@ -210,11 +242,10 @@ Troubleshooting (Ubuntu12.04LTS or higher version) below command apt-get install libxml-libxml-perl - Sometimes you may get error like "Checking for ability to link against xml2...no " while installing LibXML then use this command - sudo apt-get install zlib1g-dev - + sudo apt-get install zlib1g-dev + 2. For error related to Net::SSH2 Sometimes you may get error like, fatal error: openssl/crypto.h: No such file or directory @@ -229,10 +260,10 @@ Troubleshooting (Ubuntu12.04LTS or higher version) Sometimes you may get that yaml is not installed then run following commands: apt-get install libyaml-appconfig-perl apt-get install libconfig-yaml-perl - + 3. For libz errors like: - /usr/bin/ld: /usr/local/lib/libz.a(crc32.o): relocation R_X86_64_32 against `.rodata' can not be used when making - a shared object; recompile with -fPIC + /usr/bin/ld: /usr/local/lib/libz.a(crc32.o): relocation R_X86_64_32 against `.rodata' can not be used when + making a shared object; recompile with -fPIC /usr/local/lib/libz.a: could not read symbols: Bad value try installing from source code: download libz source code, https://google-desktop-for-linux-mirror.googlecode.com/files/zlib-1.2.3.tar.gz @@ -255,5 +286,8 @@ Troubleshooting (Ubuntu12.04LTS or higher version) unmet dependency then first install that package using cpan / cpanm and then install your desired package. you can also try installing by force : apt-get -f install - - + +# CONTRIBUTORS + + - [Ganesh Nalawade](https://github.com/ganeshnalawade) + - [Priyal Jain](https://github.com/Jainpriyal) diff --git a/examples/collect-show-interface.pl b/examples/collect_show_interface.pl similarity index 100% rename from examples/collect-show-interface.pl rename to examples/collect_show_interface.pl From b69369f35cd4cf02ab677998e1efa1a268484da5 Mon Sep 17 00:00:00 2001 From: Jainpriyal Date: Tue, 5 Jul 2016 11:07:48 +0530 Subject: [PATCH 35/41] modifying toggle value --- examples/get_chassis_inventory/get_chassis_inventory.pl | 2 +- lib/Net/Netconf/Device.pm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/get_chassis_inventory/get_chassis_inventory.pl b/examples/get_chassis_inventory/get_chassis_inventory.pl index 285a28f..a0fdbd0 100755 --- a/examples/get_chassis_inventory/get_chassis_inventory.pl +++ b/examples/get_chassis_inventory/get_chassis_inventory.pl @@ -142,7 +142,7 @@ sub print_response } my $query = "get_chassis_inventory"; -my %queryargs = ( 'detail' => 1 ); +my %queryargs = ( 'detail' => 'True' ); # send the command and get the server response my $res = $jnx->$query(%queryargs); diff --git a/lib/Net/Netconf/Device.pm b/lib/Net/Netconf/Device.pm index c2a4a74..b4a072c 100755 --- a/lib/Net/Netconf/Device.pm +++ b/lib/Net/Netconf/Device.pm @@ -491,7 +491,7 @@ sub generate_rpc ($tag = $field) =~ s/_/-/g; - if (ref($type) eq 'TOGGLE' || ref($value) eq 'TOGGLE') { + if (ref($type) eq 'TOGGLE' || ref($value) eq 'TOGGLE' || $value eq 'True') { if ($value ne '0') { $output .= " <$tag/>\n"; } From b4f782333b22d19049645bd5c85a43fde788bda8 Mon Sep 17 00:00:00 2001 From: Dwarakanath Yadavalli Date: Tue, 26 Jul 2016 17:23:29 +0530 Subject: [PATCH 36/41] Changes to make a release on CPAN --- .gitignore | 2 - CHANGES | 20 ++++-- LICENSE | 200 +++++++++++++++++++++++++++++++++++++++++++++++++--- MANIFEST | 33 +++++---- META.json | 31 ++++++++ META.yml | 19 +++++ Makefile.PL | 6 +- README | 2 +- README.md | 2 +- 9 files changed, 281 insertions(+), 34 deletions(-) create mode 100644 META.json create mode 100644 META.yml diff --git a/.gitignore b/.gitignore index eaca02e..cc2e785 100644 --- a/.gitignore +++ b/.gitignore @@ -10,8 +10,6 @@ Build.bat /Makefile /Makefile.old /MANIFEST.bak -/META.yml -/META.json /MYMETA.* nytprof.out /pm_to_blib diff --git a/CHANGES b/CHANGES index db13038..4f0528c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,17 @@ - 2015-22-05 NETCONF Team - * first version v0.01 - * second version v1.00 - * latest version v1.02 +Revision history for Perl Module Net::Netconf + +1.04 2016-07-26 NETCONF Team + * Updated LICENSE + * Corrected examples for Toggle field specification + * Corrected the implementation of Toggle field + * Cleaned up for CPAN release + +1.02 2015-05-22 NETCONF Team + * Minor fixes + +1.01 2015-05-21 NETCONF Team + * first stable release + +0.01 2014-06-11 NETCONF Team + * First release to CPAN diff --git a/LICENSE b/LICENSE index 459ca86..4bf6109 100644 --- a/LICENSE +++ b/LICENSE @@ -1,15 +1,195 @@ -Copyright (c) 2014, Juniper Networks -All rights reserved. +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same "printed page" as the copyright notice for easier identification within +third-party archives. + +Copyright (c) 2014- , Juniper Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +All rights reserved. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -20,4 +200,4 @@ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/MANIFEST b/MANIFEST index f591d5e..410f0f3 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1,21 +1,28 @@ -README -MANIFEST CHANGES -Makefile.PL +examples/collect_show_interface.pl +examples/diagnose_bgp/bgp.xml +examples/diagnose_bgp/diagnose_bgp.pl +examples/edit_configuration/config.txt +examples/edit_configuration/config.xml +examples/edit_configuration/edit_configuration.pl +examples/get_chassis_inventory/chassis_inventory.xml +examples/get_chassis_inventory/get_chassis_inventory.pl +examples/get_system_information.pl lib/Net/Netconf.pm -lib/Net/Netconf/EzEditXML.pm lib/Net/Netconf/Access.pm +lib/Net/Netconf/Access/ssh.pm lib/Net/Netconf/Constants.pm lib/Net/Netconf/Device.pm +lib/Net/Netconf/EzEditXML.pm lib/Net/Netconf/Manager.pm lib/Net/Netconf/SAXHandler.pm lib/Net/Netconf/Trace.pm -lib/Net/Netconf/Access/ssh.pm -examples/Diaganose_bgp/diagnose_bgp.pl -examples/Diaganose_bgp/bgp.xml -examples/chassis_inventory/chassis_inventory.xml -examples/chassis_inventory/get_chassis_inventory.pl -examples/edit_configuration/config.txt -examples/edit_configuration/config.xml -examples/edit_configuration/edit_configuration.pl -examples/get_system_information.pl +LICENSE +Makefile.PL +MANIFEST +META.json +META.yml +README +README.md +tests/unit/Test.t +tests/unit/TestDevice.pm diff --git a/META.json b/META.json new file mode 100644 index 0000000..cc6dc92 --- /dev/null +++ b/META.json @@ -0,0 +1,31 @@ +{ + "abstract" : "NETCONF client library for Perl", + "author" : [ + "Juniper Networks, Inc" + ], + "dynamic_config" : 1, + "generated_by" : "ExtUtils::MakeMaker version 6.66, CPAN::Meta::Converter version 2.133380", + "license" : [ + "apache_2_0" + ], + "meta-spec" : { + "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", + "version" : "2" + }, + "name" : "Net-Netconf", + "no_index" : { + "directory" : [ + "t", + "inc" + ] + }, + "release_status" : "stable", + "resources" : { + "repository" : { + "type" : "git", + "url" : "https://github.com/Juniper/netconf-perl.git", + "web" : "https://github.com/Juniper/netconf-perl" + } + }, + "version" : "1.04" +} diff --git a/META.yml b/META.yml new file mode 100644 index 0000000..d2fc48d --- /dev/null +++ b/META.yml @@ -0,0 +1,19 @@ +--- +abstract: 'NETCONF client library for Perl' +author: + - 'Juniper Networks, Inc' +build_requires: {} +dynamic_config: 1 +generated_by: 'ExtUtils::MakeMaker version 6.66, CPAN::Meta::Converter version 2.133380' +license: apache +meta-spec: + url: http://module-build.sourceforge.net/META-spec-v1.4.html + version: 1.4 +name: Net-Netconf +no_index: + directory: + - t + - inc +resources: + repository: https://github.com/Juniper/netconf-perl.git +version: 1.04 diff --git a/Makefile.PL b/Makefile.PL index 6bcf836..9dc8cbc 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -1,6 +1,6 @@ use ExtUtils::MakeMaker; -our $VERSION ='1.02'; +our $VERSION ='1.04'; use 5.006; WriteMakefile( @@ -8,8 +8,8 @@ WriteMakefile( AUTHOR => 'Juniper Networks, Inc', VERSION_FROM => 'Makefile.PL', PREREQ_PM => {'XML::LibXML' => '0', 'File::Which' => '0', 'Net::SSH2' => '0'}, - ABSTRACT => 'netconf libraries for perl', - #LICENSE => 'perl', ??? + ABSTRACT => 'NETCONF client library for Perl', + LICENSE => apache, META_MERGE => { 'meta-spec' => { version => 2 }, resources => { diff --git a/README b/README index 0201df0..d8e89e3 100644 --- a/README +++ b/README @@ -32,7 +32,7 @@ Abstract # Step 1: set up the query // RPC tag should be querried as below my $query = "get_chassis_inventory"; - my %queryargs = ( detail => 1 ); + my %queryargs = ( 'detail' => 'True' ); # Step 2: Create a Netconf Manager object and connect to Networks routing platform my %deviceinfo = ( access => "ssh", diff --git a/README.md b/README.md index 0201df0..d8e89e3 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ Abstract # Step 1: set up the query // RPC tag should be querried as below my $query = "get_chassis_inventory"; - my %queryargs = ( detail => 1 ); + my %queryargs = ( 'detail' => 'True' ); # Step 2: Create a Netconf Manager object and connect to Networks routing platform my %deviceinfo = ( access => "ssh", From ce96f345fdcd9f64cb15b1b84fcbbbb01d5237e1 Mon Sep 17 00:00:00 2001 From: Marcel Wiget Date: Tue, 10 Jan 2017 16:54:52 +0100 Subject: [PATCH 37/41] Docker container (#30) * docker container netconf-perl * remove obsolete statements * use variable for container name * make /scripts the working directory. Document -v in README.md --- docker/Dockerfile | 12 ++++++++ docker/Makefile | 18 ++++++++++++ docker/README.md | 71 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 docker/Dockerfile create mode 100644 docker/Makefile create mode 100644 docker/README.md diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..734e677 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,12 @@ +FROM ubuntu:14.04 + +RUN apt-get update && apt-get install -y perl libssh2-1-dev zlib1g-dev libyaml-appconfig-perl \ + libconfig-yaml-perl make libxml2 libxml2-dev libnet-ssh2-perl libfile-which-perl libxml-libxml-perl + +COPY . /src + +RUN cd /src && perl Makefile.PL && make && make install + +WORKDIR /scripts + +ENTRYPOINT ["/bin/bash"] diff --git a/docker/Makefile b/docker/Makefile new file mode 100644 index 0000000..6ecba1c --- /dev/null +++ b/docker/Makefile @@ -0,0 +1,18 @@ +CONTAINER=netconf-perl +#HUB= + +all: build + +build: Dockerfile + cd .. && docker build -f docker/Dockerfile -t $(CONTAINER) . + +run: + docker rm $(CONTAINER) || true + docker run -ti --rm --name $(CONTAINER) $(CONTAINER) || true + +#push: +# docker tag $(CONTAINER) $(HUB)/$(CONTAINER) +# docker push $(HUB)/$(CONTAINER) + +clean: + docker rmi `docker images | grep "^" | awk '{print $$3}'` 2>/dev/null || true diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 0000000..d262e5a --- /dev/null +++ b/docker/README.md @@ -0,0 +1,71 @@ +## Docker Container with NETCONF Perl client + +A small, ubuntu based, container with a working netconf client can be built from this directory with + +``` +make +``` + +Once ready, launch it and test the sample apps. The option '-v $PWD:/scripts' mounts +optionally the current directory into the container, allowing read-write access to files. + +``` +$ docker images | head -2 +REPOSITORY TAG IMAGE ID CREATED SIZE +netconf-perl latest 8dca418c8bd9 6 minutes ago 298.2 MB + +$ make run +docker run -ti --rm -v $PWD:/scripts --name netconf-perl netconf-perl +root@cae70c23b993:/scripts# perl /src/examples/get_system_information.pl + +Options: + +hostname : hostname of target router +username : A login name accepted by the target router. +password : The password for the login name + + hostname: 172.17.0.82 + + username: lab + + password: lab123 + Connection established: 14410 + Server request is : + + + + + Server response is: + + +vmx +junos +16.1R3.10 +VM586D46B4DE +vmxt2 + + + + +Rpc reply from server. +>>>>>>>>>> +<<<<<<<<<< + +using XML::LibXMl::DOM function +inside dom object +hardware information vmx +os-name junos +host-name vmxt2 + +using xpath +inside dom object +hardware information vmx +os-name junos +host-name vmxt2 +root@cae70c23b993:/src# exit +``` + + + + + From 77dbf9ab09bf92c24cd59c19a70e09b3fd1dde9a Mon Sep 17 00:00:00 2001 From: AJ Ragusa Date: Mon, 7 Aug 2017 12:09:29 -0400 Subject: [PATCH 38/41] Improved handling of disconnect / multiple instances and non-listed methods (#34) * adding exception handling for reads and writes I've added exception handling to catch when a write or read fails. When one of these failures occur, we disconnect the underlying ssh connection. It is the callers responsibility to attempt any reconnections. * adding ref to methods on object for external access * Removing static error messages Error messages were persisting as new Device objects were created. This caused unexpected errors to be announced. * adding spec file to build rpm * adding two extra dependencies * updating version and spec file with a fix for our dying NetConf session.... * updated the build process and cleaned up a few things for Juniper folks * One last fix for when we receive 0 bytes because the netconf session has died * fixing the timeout so if we do get data and it takes more than 15sec to receive it we wont timeout --- MANIFEST | 1 + Makefile.PL | 8 +++- lib/Net/Netconf.pm | 2 +- lib/Net/Netconf/Access/ssh.pm | 12 +++++- lib/Net/Netconf/Device.pm | 75 +++++++++++++++++++++++++---------- lib/Net/Netconf/SAXHandler.pm | 29 +++++--------- perl-Net-Netconf.spec | 45 +++++++++++++++++++++ 7 files changed, 127 insertions(+), 45 deletions(-) create mode 100644 perl-Net-Netconf.spec diff --git a/MANIFEST b/MANIFEST index 410f0f3..c65a7d1 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1,4 +1,5 @@ CHANGES +perl-Net-Netconf.spec examples/collect_show_interface.pl examples/diagnose_bgp/bgp.xml examples/diagnose_bgp/diagnose_bgp.pl diff --git a/Makefile.PL b/Makefile.PL index 9dc8cbc..afb4fe4 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -1,8 +1,13 @@ use ExtUtils::MakeMaker; -our $VERSION ='1.04'; +our $VERSION ='1.4.2'; use 5.006; +sub MY::postamble { << 'END'; } +rpm: dist + rpmbuild -ta Net-Netconf-$(VERSION).tar.gz +END + WriteMakefile( NAME => 'Net-Netconf', AUTHOR => 'Juniper Networks, Inc', @@ -20,6 +25,5 @@ WriteMakefile( }, }, }, - ); diff --git a/lib/Net/Netconf.pm b/lib/Net/Netconf.pm index feab1dd..38086cc 100644 --- a/lib/Net/Netconf.pm +++ b/lib/Net/Netconf.pm @@ -1,5 +1,5 @@ package Net::Netconf; -our $VERSION ='1.02'; +our $VERSION ='1.4.2'; =head1 NAME Net::Netconf : Netconf Perl Client diff --git a/lib/Net/Netconf/Access/ssh.pm b/lib/Net/Netconf/Access/ssh.pm index d612ff3..24b6018 100644 --- a/lib/Net/Netconf/Access/ssh.pm +++ b/lib/Net/Netconf/Access/ssh.pm @@ -117,13 +117,21 @@ sub recv { $self->trace("Reading XML response from Netconf server..."); my ($resp, $buf); + my $end_time = time() + 15; do { # Wait up to 10 seconds for data to become available before attempting # to read anything (in order to avoid busy-looping on $chan->read()) my @poll = ({ handle => $chan, events => 'in' }); - $ssh2->poll(10000, \@poll); + $ssh2->poll(40000, \@poll); - $nbytes = $chan->read($buf, 65536) || 0; + $nbytes = $chan->read($buf, 65536); + + if (!defined $nbytes || time() > $end_time) { + croak "Failed to read XML data from SSH channel!"; + } + if($nbytes > 0){ + $end_time = time() + 15; + } $self->trace("Read $nbytes bytes from SSH channel: '$buf'"); $resp .= $buf; } until($resp =~ s/]]>]]>$//); diff --git a/lib/Net/Netconf/Device.pm b/lib/Net/Netconf/Device.pm index b4a072c..3145b5b 100755 --- a/lib/Net/Netconf/Device.pm +++ b/lib/Net/Netconf/Device.pm @@ -10,6 +10,7 @@ use XML::LibXML::SAX; use XML::LibXML::SAX::Parser; use Net::Netconf::SAXHandler; use File::Basename; + use Carp; no strict 'subs'; require Exporter; @@ -126,6 +127,7 @@ sub new my $saxparser = new XML::LibXML::SAX::Parser('Handler' => $handler) || croak 'Cannot create parser: ' . $!; $self->{'sax_parser'} = $saxparser; + $self->{'handler'} = $handler; # DOM parser my $domparser = XML::LibXML->new(); @@ -145,6 +147,8 @@ sub new # Create the trace object $self->{'trace_obj'} = new Net::Netconf::Trace($self->{'debug_level'}); + $self->{'methods'} = \%methods; + # Now bring up the connection return $self->connect() unless $self->{'do_not_connect'}; $self; @@ -154,8 +158,8 @@ sub new sub connect { my($self) = @_; - my $conn; - my $trace_obj = $self->{'trace_obj'}; + my $conn; + my $trace_obj = $self->{'trace_obj'}; $trace_obj->trace(Net::Netconf::Trace::TRACE_LEVEL, 'preparing to connect'); # If we are already connected, we have the connection object @@ -220,6 +224,7 @@ EOF EOF + # Send our capabilities to the Netconf server # Get the server capability my $server_cap = $self->send_and_recv_rpc($client_capability, @@ -244,17 +249,19 @@ EOF }; if ($@) { - $self->report_error(1, 'error in parsing server capability'); - } + $self->report_error(0, 'error in parsing server capability'); + $self->disconnect(); + return; + } # Now save the session-id and server capabilities - $self->{'session_id'} = $Net::Netconf::SAXHandler::session_id; - @{$self->{'server_capabilities'}} = @Net::Netconf::SAXHandler::parsed_cap; + $self->{'session_id'} = $self->{'handler'}->{'session_id'}; + @{$self->{'server_capabilities'}} = @{$self->{'handler'}->{'parsed_cap'}}; # See if any errors were emitted and save them - $self->{'found_rpc_errors'} = $Net::Netconf::SAXHandler::found_error; + $self->{'found_rpc_errors'} = $self->{'handler'}->{'found_error'}; if ($self->{'found_rpc_errors'}) { - %{$self->{'rpc_errors'}} = (%Net::Netconf::SAXHandler::rpc_errors); + %{$self->{'rpc_errors'}} = (%{$self->{'handler'}->{'rpc_errors'}}); } $self; } @@ -272,8 +279,10 @@ sub disconnect { my($self) = @_; my $conn = $self->{'conn_obj'}; + carp "Disconnecting\n"; $conn->disconnect if ($conn and $self->{'conn_state'} != Net::Netconf::Constants::NC_STATE_DISCONN && not $conn->eof); + $self->{'conn_obj'} = undef; } # Helper function for sending and receiving Netconf commands and responses @@ -283,7 +292,7 @@ sub disconnect # $state_recv = state after we receive data (optional) sub send_and_recv_rpc { -my($self, $xml, $endtag, $state_sent, $state_recv) = @_; + my($self, $xml, $endtag, $state_sent, $state_recv) = @_; return unless ($xml); my $conn = $self->{'conn_obj'}; my $traceobj = $self->{'trace_obj'}; @@ -297,16 +306,30 @@ my($self, $xml, $endtag, $state_sent, $state_recv) = @_; $endtag = Net::Netconf::Constants::NC_REPLY_TAG unless ($endtag); # Send the request to the Netconf server - unless ($conn->send($xml)) { - carp 'failed to send user request'; - return; + eval { + unless ($conn->send($xml)) { + carp 'failed to send user request'; + return; + }; }; + if ($@) { + $self->report_error(0, 'connection to Netconf server lost'); + $self->disconnect(); + return undef; + } $self->{'conn_state'} = $state_sent; # Get a response from the Netconf server $in = $self->read_rpc( $endtag ); - $self->parse_response( $in ); + if (!defined $in) { + carp 'failed to recv user response'; + $self->report_error(0, 'connection to Netconf server lost'); + $self->disconnect(); + return undef; + } + + $self->parse_response( $in ); } # Helper function to read RPC response until end tag @@ -321,20 +344,30 @@ sub read_rpc while ( $self->{'conn_state'} != Net::Netconf::Constants::NC_STATE_HELLO_RECVD ) { if ($conn->eof) { - $self->report_error(1, 'connection to Netconf server lost'); + $self->report_error(0, 'connection to Netconf server lost'); + $self->disconnect(); return undef; } - $in .= $conn->recv(); + eval { + $in .= $conn->recv(); + }; + if ($@) { + $self->report_error(0, 'connection to Netconf server lost'); + $self->disconnect(); + return undef; + } + # Check to see if you received the end-tag if ($in =~ /<\/\s*$endtag\s*>/gs) { - $self->{'conn_state'} = Net::Netconf::Constants::NC_STATE_HELLO_RECVD; + $self->{'conn_state'} = Net::Netconf::Constants::NC_STATE_HELLO_RECVD; } elsif ($conn->eof) { - $self->report_error(1, 'connection to Netconf server lost'); - return undef; + $self->report_error(0, 'connection to Netconf server lost'); + $self->disconnect(); + return undef; } } @@ -362,10 +395,10 @@ sub parse_response # Save the total number of s received and error information - $self->{'found_rpc_errors'} = $Net::Netconf::SAXHandler::found_error; + $self->{'found_rpc_errors'} = $self->{'handler'}->{'found_error'}; #Net::Netconf::SAXHandler::found_error; # found_error an attribute of SAXHandler - $self->{'no_error'} = $Net::Netconf::SAXHandler::no_error; + $self->{'no_error'} = $self->{'handler'}->{'no_error'};#Net::Netconf::SAXHandler::no_error; #no_error an attribute of SAXHandler # We should not get both and @@ -376,7 +409,7 @@ sub parse_response #} if ($self->{'found_rpc_errors'}) { - %{$self->{'rpc_errors'}} = (%Net::Netconf::SAXHandler::rpc_errors); + %{$self->{'rpc_errors'}} = (%{$self->{'handler'}->{'rpc_errors'}});#Net::Netconf::SAXHandler::rpc_errors); } # Then we return the response as a string return $self->{'server_response'}; diff --git a/lib/Net/Netconf/SAXHandler.pm b/lib/Net/Netconf/SAXHandler.pm index 1545370..60147ec 100644 --- a/lib/Net/Netconf/SAXHandler.pm +++ b/lib/Net/Netconf/SAXHandler.pm @@ -4,17 +4,8 @@ use strict; use Carp; our $VERSION ='1.02'; -use vars qw(@EXPORT_OK @parsed_cap $session_id $found_error $no_error -%rpc_errors $junos_version); -require Exporter; -@EXPORT_OK = qw(@parsed_cap $session_id $found_error $no_error %rpc_errors -$junos_version); - use base qw(XML::SAX::Base); -$found_error = 0; -$no_error = 0; - sub attlist_decl { my $self = shift; @@ -52,19 +43,19 @@ sub start_element } elsif ($self->{'get_pkg'} && ($data->{'LocalName'} eq 'comment')) { $self->{'get_junos_ver'} = 1; } elsif ($data->{'LocalName'} eq 'rpc-reply') { - $found_error = 0; - $no_error = 0; - %rpc_errors = (); + $self->{'found_error'} = 0; + $self->{'no_error'} = 0; + $self->{'rpc_errors'} = (); } elsif ($data->{'LocalName'} eq 'capability') { $self->{'add_capability'} = 1; } elsif (($data->{'LocalName'} eq 'session-id') && ($self->{'seen_hello'})) { $self->{'get_session_id'} = 1; } elsif ($data->{'LocalName'} eq 'rpc-error') { - $found_error++; + $self->{'found_error'}++; $self->{'get_error'} = 1; } elsif ($data->{'LocalName'} eq 'ok') { - $no_error = 1; + $self->{'no_error'} = 1; } elsif ($self->{'get_error'}) { # Insert this field into the hash $self->{'capture_error'} = $data->{'LocalName'}; @@ -77,7 +68,7 @@ sub end_element my ($self, $data) = @_; if ($data->{'LocalName'} eq 'capability') { if ($self->{'current_cap'}) { - push @parsed_cap, $self->{'current_cap'}; + push @{$self->{'parsed_cap'}}, $self->{'current_cap'}; undef $self->{'current_cap'}; } $self->{'add_capability'} = 0; @@ -106,19 +97,19 @@ sub characters $self->{'current_cap'} .= $capability; } elsif ($self->{'get_session_id'}) { if ($data->{'Data'} =~ /\S/) { - $session_id = $data->{'Data'}; + $self->{'session_id'} = $data->{'Data'}; } } elsif ($self->{'get_pkg'} && $self->{'get_junos_ver'}) { if ($data->{'Data'} =~ /JUNOS Base OS/) { my @comment; @comment = split(/\[/, $data->{'Data'}); - $junos_version = $comment[1]; - $junos_version = substr($junos_version, 0, 3); + $self->{'junos_version'} = $comment[1]; + $self->{'junos_version'} = substr($self->{'junos_version'}, 0, 3); } } elsif ($self->{'get_error'}) { #Get the error value if ($data->{'Data'} =~ /\S/) { $self->{'capture_error'} =~ s/-/_/gs; - $rpc_errors{$found_error}{$self->{'capture_error'}}=$data->{'Data'}; + $self->{'rpc_errors'}{$self->{'found_error'}}{$self->{'capture_error'}}=$data->{'Data'}; } } $self->SUPER::characters($data); diff --git a/perl-Net-Netconf.spec b/perl-Net-Netconf.spec new file mode 100644 index 0000000..a871edf --- /dev/null +++ b/perl-Net-Netconf.spec @@ -0,0 +1,45 @@ +Summary: perl-Net-Netconf +Name: perl-Net-Netconf +Version: 1.4.2 +Release: 1%{?dist} +License: Apache +Group: GRNOC +URL: https://github.com/Juniper/netconf-perl +Source: Net-Netconf-%{version}.tar.gz + +BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) +BuildRequires: perl +Requires: perl-Net-SSH2 +Requires: perl-File-Which +Requires: perl-XML-LibXML + +%description +Netconf library for JUNOS devices + +%prep +%setup -q -n Net-Netconf-%{version} + +%build +%{__perl} Makefile.PL PREFIX="%{buildroot}%{_prefix}" INSTALLDIRS="vendor" +make + +%install +rm -rf $RPM_BUILD_ROOT + +%{__install} -d -p %{buildroot}%{perl_vendorlib}/Net +cp -ar lib/Net/* %{buildroot}%{perl_vendorlib}/Net + +%clean +rm -rf $RPM_BUILD_ROOT + + +%files +%{perl_vendorlib}/Net + +%doc + + +%changelog +* Thu Jun 29 2017 Jonathan Stout - Net-Netconf +- Initial build. + From 8f02d356d5c569d868971c0846a1b239c2baf6e0 Mon Sep 17 00:00:00 2001 From: vignesh-k Date: Tue, 11 Dec 2018 15:04:49 +0530 Subject: [PATCH 39/41] Fix for issues #35, #37, #38 (#40) Issue #35 : For fields which are not predefined in %methods, use the input as it is without changing _ to -. Issue #37 : Included quotes Issue #38 : Commented out the print statement. Additional change : Commented out 'Disconnecting' carp call. --- lib/Net/Netconf/Device.pm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Net/Netconf/Device.pm b/lib/Net/Netconf/Device.pm index 3145b5b..e7e53a5 100755 --- a/lib/Net/Netconf/Device.pm +++ b/lib/Net/Netconf/Device.pm @@ -279,7 +279,7 @@ sub disconnect { my($self) = @_; my $conn = $self->{'conn_obj'}; - carp "Disconnecting\n"; + #carp "Disconnecting\n"; $conn->disconnect if ($conn and $self->{'conn_state'} != Net::Netconf::Constants::NC_STATE_DISCONN && not $conn->eof); $self->{'conn_obj'} = undef; @@ -419,7 +419,7 @@ sub parse_response # This is useful for and operations sub get_dom { - print "inside dom object"; + #print "inside dom object"; my($self) = @_; # Create a DOM object and return that. # Server response is in: $self->{server_response} @@ -563,7 +563,7 @@ sub generate_rpc $output .= "\n"; } else { - $output .= " <${tag}>${value}\n"; + $output .= " <${field}>${value}\n"; } } if ($bindings->{'tag_name'}) { @@ -605,7 +605,7 @@ sub get_config $request .= $args{'source'}; $request .= '/> '; } - $request .= $args{filter}; + $request .= $args{'filter'}; $request .= ' '; $self->send_and_recv_rpc($request); } From 30af86817275775b3082b7a919ea3ea9463de21d Mon Sep 17 00:00:00 2001 From: Dwarakanath Yadavalli Date: Tue, 11 Dec 2018 15:15:27 +0530 Subject: [PATCH 40/41] Add MacOS files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index cc2e785..37e3753 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ inc/ Build !Build/ Build.bat +.DS_Store .last_cover_stats /Makefile /Makefile.old From f2d1b310de7494e2a1f2277c45010a4548aa71db Mon Sep 17 00:00:00 2001 From: Dwarakanath Yadavalli Date: Tue, 11 Dec 2018 16:29:03 +0530 Subject: [PATCH 41/41] Changes to release 1.05 --- CHANGES | 3 +++ MANIFEST | 4 +++- META.json | 4 ++-- META.yml | 4 ++-- Makefile.PL | 2 +- lib/Net/Netconf.pm | 2 +- perl-Net-Netconf.spec | 2 +- 7 files changed, 13 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index 4f0528c..5a267d8 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,8 @@ Revision history for Perl Module Net::Netconf +1.05 2018-12-11 NETCONF Team + * Minor fixes + 1.04 2016-07-26 NETCONF Team * Updated LICENSE * Corrected examples for Toggle field specification diff --git a/MANIFEST b/MANIFEST index c65a7d1..e422be6 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1,5 +1,6 @@ CHANGES -perl-Net-Netconf.spec +docker/Dockerfile +docker/README.md examples/collect_show_interface.pl examples/diagnose_bgp/bgp.xml examples/diagnose_bgp/diagnose_bgp.pl @@ -23,6 +24,7 @@ Makefile.PL MANIFEST META.json META.yml +perl-Net-Netconf.spec README README.md tests/unit/Test.t diff --git a/META.json b/META.json index cc6dc92..4517741 100644 --- a/META.json +++ b/META.json @@ -4,7 +4,7 @@ "Juniper Networks, Inc" ], "dynamic_config" : 1, - "generated_by" : "ExtUtils::MakeMaker version 6.66, CPAN::Meta::Converter version 2.133380", + "generated_by" : "ExtUtils::MakeMaker version 6.66, CPAN::Meta::Converter version 2.120921", "license" : [ "apache_2_0" ], @@ -27,5 +27,5 @@ "web" : "https://github.com/Juniper/netconf-perl" } }, - "version" : "1.04" + "version" : "1.05" } diff --git a/META.yml b/META.yml index d2fc48d..e6d800e 100644 --- a/META.yml +++ b/META.yml @@ -4,7 +4,7 @@ author: - 'Juniper Networks, Inc' build_requires: {} dynamic_config: 1 -generated_by: 'ExtUtils::MakeMaker version 6.66, CPAN::Meta::Converter version 2.133380' +generated_by: 'ExtUtils::MakeMaker version 6.66, CPAN::Meta::Converter version 2.120921' license: apache meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html @@ -16,4 +16,4 @@ no_index: - inc resources: repository: https://github.com/Juniper/netconf-perl.git -version: 1.04 +version: 1.05 diff --git a/Makefile.PL b/Makefile.PL index afb4fe4..026ceab 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -1,6 +1,6 @@ use ExtUtils::MakeMaker; -our $VERSION ='1.4.2'; +our $VERSION ='1.05'; use 5.006; sub MY::postamble { << 'END'; } diff --git a/lib/Net/Netconf.pm b/lib/Net/Netconf.pm index 38086cc..a1f8bdc 100644 --- a/lib/Net/Netconf.pm +++ b/lib/Net/Netconf.pm @@ -1,5 +1,5 @@ package Net::Netconf; -our $VERSION ='1.4.2'; +our $VERSION ='1.05'; =head1 NAME Net::Netconf : Netconf Perl Client diff --git a/perl-Net-Netconf.spec b/perl-Net-Netconf.spec index a871edf..5896043 100644 --- a/perl-Net-Netconf.spec +++ b/perl-Net-Netconf.spec @@ -1,6 +1,6 @@ Summary: perl-Net-Netconf Name: perl-Net-Netconf -Version: 1.4.2 +Version: 1.05 Release: 1%{?dist} License: Apache Group: GRNOC