aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xdlink-ng/dlink-ng-config.pm166
-rwxr-xr-xdlink-ng/dlink-ng.pl728
2 files changed, 597 insertions, 297 deletions
diff --git a/dlink-ng/dlink-ng-config.pm b/dlink-ng/dlink-ng-config.pm
new file mode 100755
index 0000000..cfeaf7a
--- /dev/null
+++ b/dlink-ng/dlink-ng-config.pm
@@ -0,0 +1,166 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+package dlinkng::config;
+
+# Common config
+our $domain_name = ".net.party.bylan.net"; # DNS-name to append to hostnames (overriden later on for TG-mode)
+our $dlink_def_user = "admin"; # Default user for a factory-default D-Link
+our $dlink_def_ip = "10.90.90.90"; # IP for a factory-default D-Link
+our $dlink_def_mask = "255.255.255.0"; # Mask for a factory-default D-Link
+our $dlink_router_ip = "10.90.90.91"; # IP to use on the router/core
+our $dlink_prefix = "30"; # Prefix to use when setting D-Link IP
+our $dhcp4_proxyprofile = "DHCPv4Proxy"; # DHCPv4 proxy profile to use on IOS-XR
+our $dhcp6_proxyprofile = "DHCPv6Proxy"; # DHCPv6 proxy profile to use on IOS-XR
+our $vrf_prefix = "dlink"; # What to prefix the VRF-number (Thread ID) with
+our $max_threads = 1; # Max threads to use
+our $dlink_host_suffix = "_DGS-3100"; # Suffix for hostname on the D-Link switches (needed by NMS)
+our $default_coreswos = "ios"; # Default OS on coresw
+our $dlink_lacp_start = '45'; # First port for LACP-group on D-Links
+our $dlink_lacp_end = '48'; # Last port for LACP-group on D-Links
+our $skip_last_port = 0; # Skip last port -- set up as access port
+our $use_ssh_cisco = 1; # Use SSH towards Cisco-boxes
+our $use_ssh_dlink = 0; # Use SSH towards D-Link switches
+our $access_vlan = '3602'; # VLAN to use for skipped port
+
+# Specific config -- just declare empty
+our $cisco_user = ""; # Username used when logging into the swithces
+our $cisco_pass = ""; # Password used when logging into the switches
+our $dhcprelay4_pri = ""; # Primary ip helper-address / ip dhcp relay address
+our $dhcprelay4_sec = ""; # Secondary ip helper-address / ip dhcp relay address
+our $dhcprelay6_pri = ""; # Primary ipv6 dhcp relay
+our $dhcprelay6_sec = ""; # Secondary ipv6 dhcp relay
+our $log_dir = ""; # Path to logfiles
+
+# Placeholders, setting them after all config loaded
+our ($po_config, $last_port_config, $os_regex, $os_info);
+
+# Set variables that relies on all config being loaded
+sub set_variables{
+ # Custom Portchannel-config
+ $po_config = {
+ ios => [
+ "logging event link-status",
+ #"ip access-group end-user-protection in",
+ #"ip directed-broadcast 2000",
+ #"ipv6 nd prefix default 300 300 no-autoconfig",
+ #"ipv6 nd managed-config-flag",
+ #"ipv6 nd other-config-flag",
+ #"ipv6 dhcp relay destination $dhcprelay6_pri",
+ #"ipv6 dhcp relay destination $dhcprelay6_sec"
+ ],
+ nx => [
+ "",
+ ],
+ xr => [
+ "logging events link-status",
+ "ipv4 directed-broadcast",
+ "ipv6 nd prefix default 300 300 no-autoconfig",
+ "ipv6 nd other-config-flag",
+ "ipv6 nd managed-config-flag",
+ ],
+ };
+
+ # Custom last port config
+ $last_port_config = {
+ ios => [
+ "logging event link-status",
+ "switchport mode access",
+ "switchport access vlan $access_vlan",
+ "spanning-tree bpduguard enable",
+ ],
+ nx => [
+ "",
+ ],
+ xr => [
+ "",
+ ],
+ };
+
+ # Define what OS-version a coresw runs
+ # NX, XR, XE, etc
+ # The regex is matched against $coreswip
+ $os_regex = {
+ ios => 'iosbox',
+ nx => 'flexusnexus',
+ xr => 'c01',
+ };
+
+ # Configure settings for each OS
+ $os_info = {
+ ios => {
+ max_sessions => 10,
+ },
+ nx => {
+ # define 64 sessions on nxos
+ # nx-os# conf t
+ # nx-os(config)# feature dhcp
+ # nx-os(config)# line vty
+ # nx-os(config-line)# session-limit 64
+ max_sessions => 50,
+ },
+ xr => {
+ # telnet vrf default ipv4 server max-servers 100 access-list MGNTv4
+ # telnet vrf default ipv6 server max-servers 100 access-list MGNTv6
+ max_sessions => 50,
+ },
+ };
+}
+
+# Load ByLAN related configuration
+sub load_bylan_config{
+ # Define bylan-dir, and add it to %INC
+ my $bylan_dir;
+ BEGIN {
+ use FindBin;
+ $bylan_dir = "$FindBin::Bin"; # Assume working-folder is the path where this script resides
+ }
+ use lib $bylan_dir;
+ use bylan;
+ use Getopt::Long;
+
+ # Load config
+ my $config_file = "$bylan_dir/bylan.conf";
+ my $conf = Config::General->new(
+ -ConfigFile => $config_file,
+ -InterPolateVars => 1);
+ my %config = $conf->getall;
+
+ # Options
+ $cisco_user = "$config{switches}->{user}"; # Username used when logging into the swithces
+ $cisco_pass = "$config{switches}->{pw}"; # Password used when logging into the switches
+ $dhcprelay4_pri = "$config{servers}->{dhcp1_ipv4}"; # Primary ip helper-address / ip dhcp relay address
+ $dhcprelay4_sec = "$config{servers}->{dhcp2_ipv4}"; # Secondary ip helper-address / ip dhcp relay address
+ $dhcprelay6_pri = "$config{servers}->{dhcp1_ipv6}"; # Primary ipv6 dhcp relay
+ $dhcprelay6_sec = "$config{servers}->{dhcp2_ipv6}"; # Secondary ipv6 dhcp relay
+ $log_dir = "$bylan_dir/logs/telnet"; # Path to logfiles
+}
+
+# Load TG related configuration
+sub load_tg_config{
+ my $tg_dir = '/root/tgmanage';
+ BEGIN {
+ require "$tg_dir/include/config.pm";
+ eval {
+ require "$tg_dir/include/config.local.pm";
+ };
+ }
+
+ # Options
+ $cisco_user = "$nms::config::ios_user"; # Username used when logging into the swithces
+ $cisco_pass = "$nms::config::ios_pass"; # Password used when logging into the switches
+ $domain_name = ".infra.$nms::config::tgname.gathering.org"; # DNS-name to append to hostnames
+ $dhcprelay4_pri = "$nms::config::dhcp_server1"; # Primary ip helper-address / ip dhcp relay address
+ $dhcprelay4_sec = "$nms::config::dhcp_server2"; # Secondary ip helper-address / ip dhcp relay address
+ $log_dir = "$tg_dir/dlink-ng/log"; # Path to logfiles
+}
+
+# Uncomment the one you want
+#load_bylan_config();
+#load_tg_config();
+
+# Set last variables that depend on the config above being set
+set_variables();
+
+
+1;
diff --git a/dlink-ng/dlink-ng.pl b/dlink-ng/dlink-ng.pl
index e395df9..9d27862 100755
--- a/dlink-ng/dlink-ng.pl
+++ b/dlink-ng/dlink-ng.pl
@@ -1,44 +1,21 @@
-#!/usr/bin/perl -I /root/tgmanage/
-use warnings;
+#!/usr/bin/perl
use strict;
-use lib '..';
-BEGIN {
- require "include/config.pm";
- eval {
- require "include/config.local.pm";
- };
-}
+use warnings;
use Net::Telnet::Cisco;
use Net::Ping;
-use Net::IP;
use Term::ANSIColor;
use threads;
use threads::shared;
use Thread::Queue;
use Getopt::Long;
+use Net::IP;
+use Net::OpenSSH;
+BEGIN {
+ require "dlink-ng-config.pm";
+}
-# Options
-my $cisco_user = "$nms::config::ios_user"; # Username used when logging into the swithces
-my $cisco_pass = "$nms::config::ios_pass"; # Password used when logging into the switches
-my $domain_name = ".infra.$nms::config::tgname.gathering.org"; # DNS-name to append to hostnames
-my $dlink_def_user = "admin"; # Default user for a factory-default D-Link
-my $dlink_def_ip = "10.90.90.90"; # IP for a factory-default D-Link
-my $dlink_def_mask = "255.255.255.0"; # Mask for a factory-default D-Link
-my $dlink_router_ip = "10.90.90.91"; # IP to use on the router/core
-my $dlink_prefix = "30"; # Prefix to use when setting D-Link IP
-my $dhcprelay4_pri = "$nms::config::dhcp_server1"; # Primary ip helper-address / ip dhcp relay address
-my $dhcprelay4_sec = "$nms::config::dhcp_server2"; # Secondary ip helper-address / ip dhcp relay address
-my $dhcprelay6_pri = ""; # Primary ipv6 dhcp relay
-my $dhcprelay6_sec = ""; # Secondary ipv6 dhcp relay
-my $vrf_prefix = "dlink"; # What to prefix the VRF-number (Thread ID) with
-my $max_threads = 20; # Max threads to use
-my $dlink_host_suffix = "_DGS-3100"; # Suffix for hostname on the D-Link switches (needed by NMS)
-my $log_dir = "dlink-ng/log"; # Path to logfiles
-my $default_coreswos = "ios"; # Default OS on coresw
-my $dlink_lacp_start = '45'; # First port for LACP-group on D-Links
-my $dlink_lacp_end = '48'; # Last port for LACP-group on D-Links
-my $skip_last_port = 1; # Skip last port -- set up as access port
-my $access_vlan = '3602'; # VLAN to use for skipped port
+# Make sure dlinkconfig.pm loads config (i.e. one config type has been uncommented)
+die("No config type specified. Uncomment the wanted subroutine in the config file.\n") unless ($dlinkng::config::cisco_user);
# Stuff
my $switchq = Thread::Queue->new(); # Queue to put switches in
@@ -48,58 +25,6 @@ my $total_time : shared = 0; # Total time spent for all switches
my %telnet_sessions : shared; # Number of sessions currently in use
my $DLINK_TEMPLATE; # Filehandle used for reading D-Link template
-# Custom Portchannel-config
-my $po_config = {
- ios => [
- "logging event link-status",
- #"ip access-group end-user-protection in",
- #"ip directed-broadcast 2000",
- #"ipv6 nd prefix default 300 300 no-autoconfig",
- #"ipv6 nd managed-config-flag",
- #"ipv6 nd other-config-flag",
- #"ipv6 dhcp relay destination $dhcprelay6_pri",
- #"ipv6 dhcp relay destination $dhcprelay6_sec"
- ],
- nx => [
- "",
- ],
-};
-
-# Custom last port config
-my $last_port_config = {
- ios => [
- "logging event link-status",
- "switchport mode access",
- "switchport access vlan $access_vlan",
- "spanning-tree bpduguard enable",
- ],
- nx => [
- "",
- ],
-};
-
-# Define what OS-version a coresw runs
-# NX, XR, XE, etc
-# The regex is matched against $coreswip
-my $os_regex = {
- nx => 'flexusnexus',
-};
-
-# Configure settings for each OS
-my $os_info = {
- ios => {
- max_sessions => 10,
- },
- nx => {
- # define 64 sessions on nxos
- # nx-os# conf t
- # nx-os(config)# feature dhcp
- # nx-os(config)# line vty
- # nx-os(config-line)# session-limit 64
- max_sessions => 50,
- },
-};
-
# Autoflush
$| = 1;
@@ -113,7 +38,7 @@ if (@ARGV > 0) {
'w|write' => \$save_config, # Write config on Cisco-side
'portskip' => \$skipped_port_only, # Configure the skipped port only (Cisco-side)
'skipdesc' => \$skipped_port_desc_only, # Configure the skipped port description only (Cisco-side)
- 'noskip' => \$no_skip # Override $skip_last_port
+ 'noskip' => \$no_skip # Override $dlinkng::config::skip_last_port
)
}
@@ -129,9 +54,9 @@ if ($cisco_config && ($skipped_port_only || $skipped_port_desc_only)){
die("\$cisco_config and \$skipped_port_only (or \$skipped_port_desc_only) can't be used together.\n");
}
-# Update $skip_last_port if $no_skip is set
+# Update $dlinkng::config::skip_last_port if $no_skip is set
if ($no_skip){
- $skip_last_port = 0;
+ $dlinkng::config::skip_last_port = 0;
}
# If skipdesc, assume $skipped_port_only
@@ -159,7 +84,7 @@ sub error{
return 0;
}
-# Debug from Net::Telnet::Cisco
+# Debug from Net::Telnet::Cisco and similar
sub debug{
my ($switchname, $errmsg) = @_;
@@ -184,15 +109,22 @@ sub abort{
sub set_coreswos{
my $coreswip = shift;
- my $os = $default_coreswos;
+ my $os = $dlinkng::config::default_coreswos;
- foreach my $swos ( sort keys %$os_regex ){
- $os = $swos if ($coreswip =~ m/$os_regex->{$swos}/);
+ foreach my $swos ( sort keys %$dlinkng::config::os_regex ){
+ $os = $swos if ($coreswip =~ m/$dlinkng::config::os_regex->{$swos}/);
}
return $os;
}
+# Is normal IOS?
+sub is_ios{
+ my $coreswos = shift;
+ return 1 if ($coreswos =~ m/^ios$/i);
+ return 0;
+}
+
# Is NX-OS?
sub is_nx{
my $coreswos = shift;
@@ -200,6 +132,13 @@ sub is_nx{
return 0;
}
+# Is IOS-XR?
+sub is_xr{
+ my $coreswos = shift;
+ return 1 if ($coreswos =~ m/^xr$/i);
+ return 0;
+}
+
# Cisco-ping
sub cisco_ping{
my ($cisco, $ip, $timeout, $coreswos, $vrf) = @_;
@@ -207,11 +146,18 @@ sub cisco_ping{
if (is_nx($coreswos)){
$cmd = "ping $ip count 1 timeout 1";
- $cmd .= " vrf ${vrf_prefix}${vrf}" if ($vrf && defined($vrf));
+ $cmd .= " vrf ${dlinkng::config::vrf_prefix}${vrf}" if ($vrf && defined($vrf));
+
+ } elsif (is_xr($coreswos)){
+ # IOS-XR
+ $cmd = "ping";
+ $cmd .= " vrf ${dlinkng::config::vrf_prefix}${vrf}" if ($vrf && defined($vrf));
+ $cmd .= " $ip count 1 timeout 1";
+
} else {
# IOS
$cmd = "ping";
- $cmd .= " vrf ${vrf_prefix}${vrf}" if ($vrf && defined($vrf));
+ $cmd .= " vrf ${dlinkng::config::vrf_prefix}${vrf}" if ($vrf && defined($vrf));
$cmd .= " $ip repeat 1 timeout 1";
}
@@ -263,10 +209,10 @@ sub dlink_login{
my ($switch, $ip, $vrf, $telnet_source) = @_;
my $dlink = Net::Telnet::Cisco->new(
- Host => $switch->{coreswip} . $domain_name,
+ Host => $switch->{coreswip} . $dlinkng::config::domain_name,
Errmode => 'return',
- output_log => "$log_dir/output-$switch->{coreswip}.log",
- input_log => "$log_dir/input-$switch->{coreswip}.log",
+ output_log => "$dlinkng::config::log_dir/dlink-output-$switch->{coreswip}-$switch->{switchname}.log",
+ input_log => "$dlinkng::config::log_dir/dlink-input-$switch->{coreswip}-$switch->{switchname}.log",
Prompt => '/\S+[#>]/',
Timeout => 60
);
@@ -277,23 +223,35 @@ sub dlink_login{
info($switch->{switchname}, "Logging in to coreswitch '$switch->{coreswip}' to telnet to D-Link.");
- unless ($dlink->login($cisco_user, $cisco_pass)){
+ unless ($dlink->login($dlinkng::config::cisco_user, $dlinkng::config::cisco_pass)){
$dlink->close;
return error($switch->{switchname}, "Can't log in to coreswitch '$switch->{coreswip}' (to telnet to D-Link).");
}
-
- $dlink->enable;
- debug($switch->{switchname}, $dlink->errmsg);
+
+ # Don't do enable on IOS-XR
+ unless(is_xr($switch->{coreswos})){
+ $dlink->enable;
+ debug($switch->{switchname}, $dlink->errmsg);
+ }
my $cmd;
if (is_nx($switch->{coreswos})){
+ # NX-OS
$cmd = "telnet $ip";
- $cmd .= " vrf ${vrf_prefix}${vrf}" if ($vrf && defined($vrf));
+ $cmd .= " vrf ${dlinkng::config::vrf_prefix}${vrf}" if ($vrf && defined($vrf));
$cmd .= " source $telnet_source" if ($telnet_source && defined($telnet_source));
+
+ } elsif (is_xr($switch->{coreswos})){
+ # IOS-XR
+ $cmd = "telnet ";
+ $cmd .= "vrf ${dlinkng::config::vrf_prefix}${vrf} " if ($vrf && defined($vrf));
+ $cmd .= "$ip";
+ $cmd .= " source-interface $telnet_source" if ($telnet_source && defined($telnet_source));
+
} else {
# IOS
$cmd = "telnet $ip";
- $cmd .= " /vrf ${vrf_prefix}${vrf}" if ($vrf && defined($vrf));
+ $cmd .= " /vrf ${dlinkng::config::vrf_prefix}${vrf}" if ($vrf && defined($vrf));
$cmd .= " /source-interface $telnet_source" if ($telnet_source && defined($telnet_source));
}
@@ -305,7 +263,7 @@ sub dlink_login{
or return abort($switch->{switchname}, $dlink);
info($switch->{switchname}, "Got login prompt, logging in.");
- telnet_print($switch, $dlink, '', $dlink_def_user, 0)
+ telnet_print($switch, $dlink, $dlinkng::config::dlink_def_user, 0)
or return abort($switch->{switchname}, $dlink);
info($switch->{switchname}, "Waiting for prompt.");
@@ -313,7 +271,7 @@ sub dlink_login{
or return abort($switch->{switchname}, $dlink);
# disable CLI paging
- telnet_print($switch, $dlink, '', "disable clipaging")
+ telnet_print($switch, $dlink, "disable clipaging")
or return abort($switch->{switchname}, $dlink);
info($switch->{switchname}, "Logged in to D-Link");
@@ -327,6 +285,22 @@ sub telnet_cmd{
unless ($telnet->cmd($cmd)){
error($switch->{switchname}, "Command '$cmd' failed");
debug($switch->{switchname}, $telnet->errmsg);
+
+ if($cmd =~ m/commit/){
+ # If commit on IOS-XR failed, print the reason
+ if(is_xr($switch->{coreswos})){
+ # Redundant check, but whatever
+ my @failed = $telnet->cmd("show configuration failed");
+
+ if(@failed){
+ foreach my $line (@failed){
+ chomp($line);
+ error($switch->{switchname}, $line);
+ }
+ }
+ }
+ }
+
return 0;
}
@@ -335,7 +309,7 @@ sub telnet_cmd{
# Execute telnet-print
sub telnet_print{
- my ($switch, $telnet, $telnet2, $cmd, $waitfor) = @_;
+ my ($switch, $telnet, $cmd, $waitfor) = @_;
unless (defined($waitfor)){
$waitfor = 1;
@@ -365,38 +339,47 @@ sub no_no_shut{
# On some boxes/OSes, the 'shut' command isn't applied right away after
# you do a 'shut'.
- my $tries = 0;
my $return = 0;
+ if(is_xr($switch->{coreswos})){
+ # don't need to do any checks on XR
+ telnet_cmd($switch, $cisco, "shut")
+ or return abort($switch->{switchname}, $cisco);
+
+ $return = 1;
+ } else {
+ # on all other OS
+ my $tries = 0;
- while (1){
- if($tries >= 5){
- # max 5 tries
- last;
- }
+ while (1){
+ if($tries >= 5){
+ # max 5 tries
+ last;
+ }
- sleep 1; # wait a bit
+ sleep 1; # wait a bit
- telnet_cmd($switch, $cisco, "shut")
- or return abort($switch->{switchname}, $cisco);
+ telnet_cmd($switch, $cisco, "shut")
+ or return abort($switch->{switchname}, $cisco);
- # now we need to check that the 'running config' actually reflects this
+ # now we need to check that the 'running config' actually reflects this
- my @shut_info = $cisco->cmd("do sh run int $port | i shutdown");
+ my @shut_info = $cisco->cmd("do sh run int $port | i shutdown");
- unless(@shut_info){
- $tries++;
- next;
- }
+ unless(@shut_info){
+ $tries++;
+ next;
+ }
- my $shut = "@shut_info";
- chomp($shut);
+ my $shut = "@shut_info";
+ chomp($shut);
- if ($shut =~ m/shutdown/i){
- $return = 1;
- last;
- } else {
- $tries++;
- next;
+ if ($shut =~ m/shutdown/i){
+ $return = 1;
+ last;
+ } else {
+ $tries++;
+ next;
+ }
}
}
@@ -422,19 +405,101 @@ sub reset_interfaces{
or return abort($switch->{switchname}, $cisco);
no_no_shut($switch, $cisco, $port)
or return abort($switch->{switchname}, $cisco);
- telnet_cmd($switch, $cisco, "no switchport")
- or return abort($switch->{switchname}, $cisco);
+
+ unless(is_xr($switch->{coreswos})){
+ # only do this if not IOS-XR
+ telnet_cmd($switch, $cisco, "no switchport")
+ or return abort($switch->{switchname}, $cisco);
+ }
}
# Remove portchannel
- if(is_nx($switch->{coreswos})){
- # NX-OS
- telnet_cmd($switch, $cisco, "no int Po$switch->{etherchannel}")
- or return abort($switch->{switchname}, $cisco);
- } else {
+ if(is_ios($switch->{coreswos})){
# IOS fails on the next command, if the portchannel doesn't exist
# Ignore error on this command
$cisco->cmd("no int Po$switch->{etherchannel}");
+
+ } elsif(is_xr($switch->{coreswos})){
+ # Other syntax on XR, called Bundle-Ether
+ telnet_cmd($switch, $cisco, "no int Bundle-Ether$switch->{etherchannel}")
+ or return abort($switch->{switchname}, $cisco);
+
+ } else {
+ # Other OS, that doesnt fail
+ telnet_cmd($switch, $cisco, "no int Po$switch->{etherchannel}")
+ or return abort($switch->{switchname}, $cisco);
+
+ }
+
+ # Commit on XR
+ if(is_xr($switch->{coreswos})){
+ telnet_cmd($switch, $cisco, "commit")
+ or return abort($switch->{switchname}, $cisco);
+ }
+
+ telnet_cmd($switch, $cisco, "end")
+ or return abort($switch->{switchname}, $cisco);
+
+ return 1;
+}
+
+# Set up single interface
+sub configure_interface{
+ my ($switch, $cisco, $port, $ip, $mask, $vrf) = @_;
+
+ # Configure port
+ telnet_cmd($switch, $cisco, "int $port")
+ or return abort($switch->{switchname}, $cisco);
+
+ unless(is_xr($switch->{coreswos})){
+ # only do this if not IOS-XR
+ telnet_cmd($switch, $cisco, "no switchport")
+ or return abort($switch->{switchname}, $cisco);
+ }
+
+ # Only do VRF-config if $vrf is defined
+ if($vrf && defined($vrf)){
+ if(is_nx($switch->{coreswos})){
+ # No error-check on the next command, as NX-OS
+ # spits out "% Deleted all L3 config on interface Ethernet1/45"
+ # making Net::Telnet::Cisco think it's an error
+
+ $cisco->cmd("vrf member ${dlinkng::config::vrf_prefix}${vrf}");
+
+ } elsif(is_xr($switch->{coreswos})){
+ # IOS-XR
+ telnet_cmd($switch, $cisco, "vrf ${dlinkng::config::vrf_prefix}${vrf}")
+ or return abort($switch->{switchname}, $cisco);
+
+ } else {
+ # IOS
+ telnet_cmd($switch, $cisco, "ip vrf forwarding ${dlinkng::config::vrf_prefix}${vrf}")
+ or return abort($switch->{switchname}, $cisco);
+ }
+ }
+
+ # Add IP
+ info($switch->{switchname}, "Adding IP-address to interface.");
+
+ if(is_xr($switch->{coreswos})){
+ # IOS-XR
+ telnet_cmd($switch, $cisco, "ipv4 address $ip $mask")
+ or return abort($switch->{switchname}, $cisco);
+
+ } else {
+ # All other
+ telnet_cmd($switch, $cisco, "ip address $ip $mask")
+ or return abort($switch->{switchname}, $cisco);
+ }
+
+ # 'no shut'-patrol reporting in!
+ telnet_cmd($switch, $cisco, "no shut")
+ or return abort($switch->{switchname}, $cisco);
+
+ # Commit on XR
+ if(is_xr($switch->{coreswos})){
+ telnet_cmd($switch, $cisco, "commit")
+ or return abort($switch->{switchname}, $cisco);
}
telnet_cmd($switch, $cisco, "end")
@@ -451,8 +516,8 @@ sub push_dlink_template_config{
my $dlink = Net::Telnet::Cisco->new(
Host => $switch->{ipv4address},
Errmode => 'return',
- output_log => "$log_dir/output-$switch->{ipv4address}.log",
- input_log => "$log_dir/input-$switch->{ipv4address}.log",
+ output_log => "$dlinkng::config::log_dir/dlink-output-$switch->{coreswip}-$switch->{switchname}.log",
+ input_log => "$dlinkng::config::log_dir/dlink-input-$switch->{coreswip}-$switch->{switchname}.log",
Prompt => '/\S+[#>]/',
Timeout => 60
);
@@ -466,7 +531,7 @@ sub push_dlink_template_config{
or return abort($switch->{switchname}, $dlink);
info($switch->{switchname}, "Got login prompt, logging in.");
- telnet_print($switch, $dlink, '', $dlink_def_user, 0)
+ telnet_print($switch, $dlink, $dlinkng::config::dlink_def_user, 0)
or return abort($switch->{switchname}, $dlink);
info($switch->{switchname}, "Waiting for prompt.");
@@ -474,7 +539,7 @@ sub push_dlink_template_config{
or return abort($switch->{switchname}, $dlink);
# disable CLI paging
- telnet_print($switch, $dlink, '', "disable clipaging")
+ telnet_print($switch, $dlink, "disable clipaging")
or return abort($switch->{switchname}, $dlink);
info($switch->{switchname}, "Logged in to D-Link");
@@ -490,7 +555,7 @@ sub push_dlink_template_config{
next if ($line =~ m/^\s*(((#|\!).*)|$)/); # skip if comment, or blank line
- telnet_print($switch, $dlink, '', $line)
+ telnet_print($switch, $dlink, $line)
or return abort($switch->{switchname}, $dlink);
sleep 1; # The D-Link's are a bit slow...
@@ -501,11 +566,11 @@ sub push_dlink_template_config{
info($switch->{switchname}, "Done applying config from D-Link template file ($dlink_config). Saving...");
# Save config + logout
- telnet_print($switch, $dlink, '', "save", 0)
+ telnet_print($switch, $dlink, "save", 0)
or return abort($switch->{switchname}, $dlink);
- telnet_print($switch, $dlink, '', "Y")
+ telnet_print($switch, $dlink, "Y")
or return abort($switch->{switchname}, $dlink);
- telnet_print($switch, $dlink, '', "logout")
+ telnet_print($switch, $dlink, "logout")
or return abort($switch->{switchname}, $dlink);
# Done
@@ -521,7 +586,7 @@ sub setup{
# Remove last port if we're skipping it
my $skipped_port;
- if ($skip_last_port){
+ if ($dlinkng::config::skip_last_port){
$skipped_port = pop(@{$switch->{ports}});
}
@@ -555,28 +620,62 @@ sub setup{
info($switch->{switchname}, "Connecting to coreswitch '$switch->{coreswip}'.");
- my $cisco = Net::Telnet::Cisco->new(
- Host => $switch->{coreswip} . $domain_name,
- Errmode => 'return',
- output_log => "$log_dir/output-$switch->{coreswip}.log",
- input_log => "$log_dir/input-$switch->{coreswip}.log",
- Prompt => '/\S+[#>]/',
- Timeout => 60
- );
+ my $cisco;
+ if ($dlinkng::config::use_ssh_cisco){
+ # Use SSH
+ my $ssh = Net::OpenSSH->new( $dlinkng::config::cisco_user . ':' .
+ $dlinkng::config::cisco_pass . '@' .
+ $switch->{coreswip} . $dlinkng::config::domain_name,
+ timeout => 60);
+
+ if ($ssh->error){
+ return debug($switch->{switchname}, $ssh->error);
+ }
+
+ my ($pty, $pid) = $ssh->open2pty({stderr_to_stdout => 1})
+ or return debug($switch->{switchname}, $ssh->error);
+
+ $cisco = Net::Telnet::Cisco->new(
+ Fhopen => $pty,
+ Telnetmode => 0,
+ #Cmd_remove_mode => 1,
+ Errmode => 'return',
+ output_log => "$dlinkng::config::log_dir/cisco-output-$switch->{coreswip}-$switch->{switchname}.log",
+ input_log => "$dlinkng::config::log_dir/cisco-input-$switch->{coreswip}-$switch->{switchname}.log",
+ Prompt => '/\S+[#>]/',
+ #Prompt => '/(?m:^\\s?(?:[\\w.\/]+\:)?(?:[\\w.-]+\@)?[\\w.-]+\\s?(?:\(config[^\)]*\))?\\s?[\$#>]\\s?(?:\(enable\))?\\s*$)/',
+ );
+ } else {
+ # Don't use SSH
+ $cisco = Net::Telnet::Cisco->new(
+ Host => $switch->{coreswip} . $dlinkng::config::domain_name,
+ Errmode => 'return',
+ output_log => "$dlinkng::config::log_dir/cisco-output-$switch->{coreswip}-$switch->{switchname}.log",
+ input_log => "$dlinkng::config::log_dir/cisco-input-$switch->{coreswip}-$switch->{switchname}.log",
+ Prompt => '/\S+[#>]/',
+ #Prompt => '/(?m:^\\s?(?:[\\w.\/]+\:)?(?:[\\w.-]+\@)?[\\w.-]+\\s?(?:\(config[^\)]*\))?\\s?[\$#>]\\s?(?:\(enable\))?\\s*$)/',
+ Timeout => 60
+ );
+ }
unless (defined($cisco)){
return error($switch->{switchname}, "Could not connect to '$switch->{coreswip}'.");
}
- info($switch->{switchname}, "Logging in to coreswitch '$switch->{coreswip}'.");
+ unless ($dlinkng::config::use_ssh_cisco){
+ info($switch->{switchname}, "Logging in to coreswitch '$switch->{coreswip}'.");
- unless ($cisco->login($cisco_user, $cisco_pass)){
- $cisco->close;
- return error($switch->{switchname}, "Can't log in to '$switch->{coreswip}'.");
+ unless ($cisco->login($dlinkng::config::cisco_user, $dlinkng::config::cisco_pass)){
+ $cisco->close;
+ return error($switch->{switchname}, "Can't log in to '$switch->{coreswip}'.");
+ }
}
- $cisco->enable;
- debug($switch->{switchname}, $cisco->errmsg);
+ # Don't do enable on IOS-XR
+ unless(is_xr($switch->{coreswos})){
+ $cisco->enable;
+ debug($switch->{switchname}, $cisco->errmsg);
+ }
# Disable paging
telnet_cmd($switch, $cisco, "terminal length 0")
@@ -591,7 +690,7 @@ sub setup{
telnet_cmd($switch, $cisco, "conf t")
or return abort($switch->{switchname}, $cisco);
- info($switch->{switchname}, "Enabling VRF (${vrf_prefix}${vrf}). Applying to interface.");
+ info($switch->{switchname}, "Enabling VRF (${dlinkng::config::vrf_prefix}${vrf}). Applying to interface.");
if(is_nx($switch->{coreswos})){
# Remove previous VRF
# No error-check on the next command, as NX-OS
@@ -599,65 +698,44 @@ sub setup{
# making Net::Telnet::Cisco think it's an error
# Extra overhead to delete, not used
- #$cisco->cmd("no vrf context ${vrf_prefix}${vrf}");
+ #$cisco->cmd("no vrf context ${dlinkng::config::vrf_prefix}${vrf}");
#sleep 10; # NX-OS seems to need some time to delete a VRF
# Create VRF
- telnet_cmd($switch, $cisco, "vrf context ${vrf_prefix}${vrf}")
+ telnet_cmd($switch, $cisco, "vrf context ${dlinkng::config::vrf_prefix}${vrf}")
or return abort($switch->{switchname}, $cisco);
+
+ } elsif(is_xr($switch->{coreswos})){
+ # IOS-XR
+ telnet_cmd($switch, $cisco, "vrf ${dlinkng::config::vrf_prefix}${vrf}")
+ or return abort($switch->{switchname}, $cisco);
+
} else {
- # IOS
+ # Default OS
# IOS fails on the next command, if the vrf doesn't exist
# Ignore error on this command
# Extra overhead to delete, not used
- #$cisco->cmd("no ip vrf ${vrf_prefix}${vrf}");
+ #$cisco->cmd("no ip vrf ${dlinkng::config::vrf_prefix}${vrf}");
# Create VRF
- telnet_cmd($switch, $cisco, "ip vrf ${vrf_prefix}${vrf}")
+ telnet_cmd($switch, $cisco, "ip vrf ${dlinkng::config::vrf_prefix}${vrf}")
or return abort($switch->{switchname}, $cisco);
telnet_cmd($switch, $cisco, "rd $vrf:$vrf")
or return abort($switch->{switchname}, $cisco);
}
# Configure port #1
- telnet_cmd($switch, $cisco, "int " . @{$switch->{ports}}[0])
- or return abort($switch->{switchname}, $cisco);
- telnet_cmd($switch, $cisco, "no switchport")
- or return abort($switch->{switchname}, $cisco);
-
- if(is_nx($switch->{coreswos})){
- # No error-check on the next command, as NX-OS
- # spits out "% Deleted all L3 config on interface Ethernet1/45"
- # making Net::Telnet::Cisco think it's an error
-
- $cisco->cmd("vrf member ${vrf_prefix}${vrf}");
- } else {
- # IOS
- telnet_cmd($switch, $cisco, "ip vrf forwarding ${vrf_prefix}${vrf}")
- or return abort($switch->{switchname}, $cisco);
- }
-
- # Add temporary D-Link IP
- info($switch->{switchname}, "Adding IP-address to interface.");
-
- telnet_cmd($switch, $cisco, "ip address $dlink_router_ip $dlink_def_mask")
- or return abort($switch->{switchname}, $cisco);
-
- # 'no shut'-patrol reporting in!
- telnet_cmd($switch, $cisco, "no shut")
- or return abort($switch->{switchname}, $cisco);
-
- telnet_cmd($switch, $cisco, "end")
+ configure_interface($switch, $cisco, @{$switch->{ports}}[0], $dlinkng::config::dlink_router_ip, $dlinkng::config::dlink_def_mask, $vrf)
or return abort($switch->{switchname}, $cisco);
- info($switch->{switchname}, "Waiting for D-Link to answer on $dlink_def_ip in VRF ${vrf_prefix}${vrf} on port #1 (" . @{$switch->{ports}}[0] . ").");
+ info($switch->{switchname}, "Waiting for D-Link to answer on $dlinkng::config::dlink_def_ip in VRF ${dlinkng::config::vrf_prefix}${vrf} on port #1 (" . @{$switch->{ports}}[0] . ").");
# Use port 1 if ping succeeds
my $p_count = 0;
my $dlink_port = @{$switch->{ports}}[$p_count];
- until (cisco_ping($cisco, $dlink_def_ip, 30, $switch->{coreswos}, $vrf)) {
+ until (cisco_ping($cisco, $dlinkng::config::dlink_def_ip, 30, $switch->{coreswos}, $vrf)) {
# Did not ping, let's try next port
# We do this because port#1 might be damaged/not patched
@@ -691,77 +769,56 @@ sub setup{
$dlink_port = @{$switch->{ports}}[$p_count];
# Configure new port
- telnet_cmd($switch, $cisco, "int $dlink_port")
- or return abort($switch->{switchname}, $cisco);
- telnet_cmd($switch, $cisco, "no switchport")
- or return abort($switch->{switchname}, $cisco);
-
- if(is_nx($switch->{coreswos})){
- # No error-check on the next command, as NX-OS
- # spits out "% Deleted all L3 config on interface Ethernet1/45"
- # making Net::Telnet::Cisco think it's an error
-
- $cisco->cmd("vrf member ${vrf_prefix}${vrf}");
- } else {
- # IOS
- telnet_cmd($switch, $cisco, "ip vrf forwarding ${vrf_prefix}${vrf}")
- or return abort($switch->{switchname}, $cisco);
- }
-
- telnet_cmd($switch, $cisco, "ip address $dlink_router_ip $dlink_def_mask")
- or return abort($switch->{switchname}, $cisco);
- # 'no shut'-patrol reporting in!
- telnet_cmd($switch, $cisco, "no shut")
- or return abort($switch->{switchname}, $cisco);
- telnet_cmd($switch, $cisco, "end")
+ configure_interface($switch, $cisco, $dlink_port, $dlinkng::config::dlink_router_ip, $dlinkng::config::dlink_def_mask, $vrf)
or return abort($switch->{switchname}, $cisco);
- info($switch->{switchname}, "Waiting for D-Link to answer on $dlink_def_ip in VRF ${vrf_prefix}${vrf} on port #" . ($p_count+1) . " (" . @{$switch->{ports}}[$p_count] . ").");
+ info($switch->{switchname}, "Waiting for D-Link to answer on $dlinkng::config::dlink_def_ip in VRF ${dlinkng::config::vrf_prefix}${vrf} on port #" . ($p_count+1) . " (" . @{$switch->{ports}}[$p_count] . ").");
}
# Telnet to D-Link
info($switch->{switchname}, "Starting D-Link config phase 1.");
- my $dlink = dlink_login($switch, $dlink_def_ip, $vrf)
+ my $dlink = dlink_login($switch, $dlinkng::config::dlink_def_ip, $vrf)
or return abort($switch->{switchname}, $cisco);
- info($switch->{switchname}, "Setting hostname to $switch->{switchname}${dlink_host_suffix}");
- telnet_print($switch, $dlink, $cisco, "config snmp system_name $switch->{switchname}${dlink_host_suffix}")
+ info($switch->{switchname}, "Setting hostname to $switch->{switchname}${dlinkng::config::dlink_host_suffix}");
+ telnet_print($switch, $dlink, "config snmp system_name $switch->{switchname}${dlinkng::config::dlink_host_suffix}")
or return abort($switch->{switchname}, $cisco, $dlink);
info($switch->{switchname}, "Adding LACP. Enabling STP.");
- telnet_print($switch, $dlink, $cisco, "create link_aggregation group_id 1 type lacp")
+ telnet_print($switch, $dlink, "create link_aggregation group_id 1 type lacp")
or return abort($switch->{switchname}, $cisco, $dlink);
- telnet_print($switch, $dlink, $cisco, "config link_aggregation group_id 1 ports 1:($dlink_lacp_start-$dlink_lacp_end)")
+ telnet_print($switch, $dlink, "config link_aggregation group_id 1 ports 1:($dlinkng::config::dlink_lacp_start-$dlinkng::config::dlink_lacp_end)")
or return abort($switch->{switchname}, $cisco, $dlink);
- telnet_print($switch, $dlink, $cisco, "enable stp")
+ telnet_print($switch, $dlink, "enable stp")
or return abort($switch->{switchname}, $cisco, $dlink);
info($switch->{switchname}, "STP enabled, logging in again.");
$dlink->close;
- unless (cisco_ping($cisco, $dlink_def_ip, 60, $switch->{coreswos}, $vrf)) {
+ unless (cisco_ping($cisco, $dlinkng::config::dlink_def_ip, 60, $switch->{coreswos}, $vrf)) {
reset_interfaces($switch, $cisco)
or return abort($switch->{switchname}, $cisco);
$cisco->close;
- return error($switch->{switchname}, "Can't login to $switch->{switchname} on $dlink_def_ip, aborting.");
+ return error($switch->{switchname}, "Can't login to $switch->{switchname} on $dlinkng::config::dlink_def_ip, aborting.");
}
- $dlink = dlink_login($switch, $dlink_def_ip, $vrf) or return abort($switch->{switchname}, $cisco);
+ $dlink = dlink_login($switch, $dlinkng::config::dlink_def_ip, $vrf)
+ or return abort($switch->{switchname}, $cisco);
info($switch->{switchname}, "Running STP config.");
- telnet_print($switch, $dlink, $cisco, "config stp version mstp")
+ telnet_print($switch, $dlink, "config stp version mstp")
or return abort($switch->{switchname}, $cisco, $dlink);
- telnet_print($switch, $dlink, $cisco, "config stp priority 61440 instance_id 0")
+ telnet_print($switch, $dlink, "config stp priority 61440 instance_id 0")
or return abort($switch->{switchname}, $cisco, $dlink);
- telnet_print($switch, $dlink, $cisco, "config stp ports 1:(1-44) edge true")
+ telnet_print($switch, $dlink, "config stp ports 1:(1-44) edge true")
or return abort($switch->{switchname}, $cisco, $dlink);
- telnet_print($switch, $dlink, $cisco, "enable lldp")
+ telnet_print($switch, $dlink, "enable lldp")
or return abort($switch->{switchname}, $cisco, $dlink);
info($switch->{switchname}, "Setting IP address.");
- telnet_print($switch, $dlink, $cisco, "config ipif System ipaddress $switch->{ipv4address}/$dlink_prefix vlan default")
+ telnet_print($switch, $dlink, "config ipif System ipaddress $switch->{ipv4address}/$dlinkng::config::dlink_prefix vlan default")
or return abort($switch->{switchname}, $cisco, $dlink);
-
+
info($switch->{switchname}, "Closing D-Link link.");
$dlink->close;
@@ -770,18 +827,9 @@ sub setup{
or return abort($switch->{switchname}, $cisco);
telnet_cmd($switch, $cisco, "default int $dlink_port")
or return abort($switch->{switchname}, $cisco);
- telnet_cmd($switch, $cisco, "int $dlink_port")
- or return abort($switch->{switchname}, $cisco);
- telnet_cmd($switch, $cisco, "no switchport")
- or return abort($switch->{switchname}, $cisco);
- telnet_cmd($switch, $cisco, "ip address $switch->{ipv4gateway} $switch->{netmask}")
- or return abort($switch->{switchname}, $cisco);
- # 'no shut'-patrol reporting in!
- telnet_cmd($switch, $cisco, "no shut")
- or return abort($switch->{switchname}, $cisco);
- telnet_cmd($switch, $cisco, "end")
+ configure_interface($switch, $cisco, $dlink_port, $switch->{ipv4gateway}, $switch->{netmask})
or return abort($switch->{switchname}, $cisco);
-
+
# Wait for network convergence
info($switch->{switchname}, "Waiting for network to converge.");
unless (cisco_ping($cisco, $switch->{ipv4address}, 60, $switch->{coreswos})) {
@@ -796,13 +844,13 @@ sub setup{
$dlink = dlink_login($switch, $switch->{ipv4address}, '', $dlink_port) or return abort($switch->{switchname}, $cisco);
info($switch->{switchname}, "Setting default route on switch. Saving config.");
- telnet_print($switch, $dlink, $cisco, "create iproute default $switch->{ipv4gateway}")
+ telnet_print($switch, $dlink, "create iproute default $switch->{ipv4gateway}")
or return abort($switch->{switchname}, $cisco, $dlink);
- telnet_print($switch, $dlink, $cisco, "save", 0)
+ telnet_print($switch, $dlink, "save", 0)
or return abort($switch->{switchname}, $cisco, $dlink);
- telnet_print($switch, $dlink, $cisco, "Y")
+ telnet_print($switch, $dlink, "Y")
or return abort($switch->{switchname}, $cisco, $dlink);
- telnet_print($switch, $dlink, $cisco, "logout")
+ telnet_print($switch, $dlink, "logout")
or return abort($switch->{switchname}, $cisco, $dlink);
info($switch->{switchname}, "Closing D-Link link.");
@@ -820,40 +868,82 @@ sub setup{
telnet_cmd($switch, $cisco, "conf t")
or return abort($switch->{switchname}, $cisco);
- # this needs to be done on IOS-XE
# Portchannel needs to exist before we can assign interfaces to it
- telnet_cmd($switch, $cisco, "int Po$switch->{etherchannel}")
- or return abort($switch->{switchname}, $cisco);
-
+ # This needs to be done on IOS-XE, but we do it on all
+ if(is_xr($switch->{coreswos})){
+ # Other syntax on XR, called Bundle-Ether
+ telnet_cmd($switch, $cisco, "int Bundle-Ether$switch->{etherchannel}")
+ or return abort($switch->{switchname}, $cisco);
+
+ } else {
+ telnet_cmd($switch, $cisco, "int Po$switch->{etherchannel}")
+ or return abort($switch->{switchname}, $cisco);
+
+ }
+
# Rest of the config
my $etherchan_desc;
foreach my $port (@{$switch->{ports}}){
telnet_cmd($switch, $cisco, "int $port")
or return abort($switch->{switchname}, $cisco);
- telnet_cmd($switch, $cisco, "no switchport")
- or return abort($switch->{switchname}, $cisco);
+
+ unless(is_xr($switch->{coreswos})){
+ # only do this if not IOS-XR
+ telnet_cmd($switch, $cisco, "no switchport")
+ or return abort($switch->{switchname}, $cisco);
+ }
+
# 'no shut'-patrol reporting in!
telnet_cmd($switch, $cisco, "no shut")
or return abort($switch->{switchname}, $cisco);
- telnet_cmd($switch, $cisco, "desc D-Link $switch->{switchname}; RJ-45; 1G;")
- or return abort($switch->{switchname}, $cisco);
- telnet_cmd($switch, $cisco, "channel-group $switch->{etherchannel} mode passive")
+ telnet_cmd($switch, $cisco, "description D-Link $switch->{switchname}; RJ-45; 1G;")
or return abort($switch->{switchname}, $cisco);
+ # Assign to Etherchannel
+ if(is_xr($switch->{coreswos})){
+ # Other syntax on XR, called Bundle-Ether
+ telnet_cmd($switch, $cisco, "bundle id $switch->{etherchannel} mode passive")
+ or return abort($switch->{switchname}, $cisco);
+
+ } else {
+ telnet_cmd($switch, $cisco, "channel-group $switch->{etherchannel} mode passive")
+ or return abort($switch->{switchname}, $cisco);
+
+ }
+
# add port to descr
$etherchan_desc .= "$port; ";
}
- telnet_cmd($switch, $cisco, "int Po$switch->{etherchannel}")
- or return abort($switch->{switchname}, $cisco);
- telnet_cmd($switch, $cisco, "desc D-Link $switch->{switchname}; $etherchan_desc")
- or return abort($switch->{switchname}, $cisco);
- telnet_cmd($switch, $cisco, "ip address $switch->{ipv4gateway} $switch->{netmask}")
+ if(is_xr($switch->{coreswos})){
+ # Other syntax on XR, called Bundle-Ether
+ telnet_cmd($switch, $cisco, "int Bundle-Ether$switch->{etherchannel}")
+ or return abort($switch->{switchname}, $cisco);
+
+ } else {
+ telnet_cmd($switch, $cisco, "int Po$switch->{etherchannel}")
+ or return abort($switch->{switchname}, $cisco);
+
+ }
+
+ telnet_cmd($switch, $cisco, "description D-Link $switch->{switchname}; $etherchan_desc")
or return abort($switch->{switchname}, $cisco);
-
- # ipv6-stuff
+
+
+ if(is_xr($switch->{coreswos})){
+ # IOS-XR
+ telnet_cmd($switch, $cisco, "ipv4 address $switch->{ipv4gateway} $switch->{netmask}")
+ or return abort($switch->{switchname}, $cisco);
+
+ } else {
+ # All other
+ telnet_cmd($switch, $cisco, "ip address $switch->{ipv4gateway} $switch->{netmask}")
+ or return abort($switch->{switchname}, $cisco);
+ }
+
+ # IPv6-stuff
unless (is_nx($switch->{coreswos})){
- # IOS
+ # IOS + IOS-XR
telnet_cmd($switch, $cisco, "ipv6 enable")
or return abort($switch->{switchname}, $cisco);
}
@@ -861,43 +951,80 @@ sub setup{
telnet_cmd($switch, $cisco, "ipv6 address $switch->{ipv6address}")
or return abort($switch->{switchname}, $cisco);
+ # DHCP-relay/forwarding + MBD/Blazon-forwarding (broadcast)
if (is_nx($switch->{coreswos})){
- telnet_cmd($switch, $cisco, "ip dhcp relay address $dhcprelay4_pri")
+ # NX-OS
+ telnet_cmd($switch, $cisco, "ip dhcp relay address $dlinkng::config::dhcprelay4_pri")
+ or return abort($switch->{switchname}, $cisco);
+
+ # define secondary if present
+ if (defined($dlinkng::config::dhcprelay4_sec) && $dlinkng::config::dhcprelay4_sec){
+ telnet_cmd($switch, $cisco, "ip dhcp relay address $dlinkng::config::dhcprelay4_sec")
+ or return abort($switch->{switchname}, $cisco);
+ }
+ } elsif (is_xr($switch->{coreswos})){
+ # IOS-XR
+ telnet_cmd($switch, $cisco, "ipv4 helper-address vrf default $dlinkng::config::dhcprelay4_pri")
or return abort($switch->{switchname}, $cisco);
# define secondary if present
- if (defined($dhcprelay4_sec) && $dhcprelay4_sec){
- telnet_cmd($switch, $cisco, "ip dhcp relay address $dhcprelay4_sec")
+ if (defined($dlinkng::config::dhcprelay4_sec) && $dlinkng::config::dhcprelay4_sec){
+ telnet_cmd($switch, $cisco, "ipv4 helper-address vrf default $dlinkng::config::dhcprelay4_sec")
or return abort($switch->{switchname}, $cisco);
}
} else {
# IOS
- telnet_cmd($switch, $cisco, "ip helper-address $dhcprelay4_pri")
+ telnet_cmd($switch, $cisco, "ip helper-address $dlinkng::config::dhcprelay4_pri")
or return abort($switch->{switchname}, $cisco);
# define secondary if present
- if (defined($dhcprelay4_sec) && $dhcprelay4_sec){
- telnet_cmd($switch, $cisco, "ip helper-address $dhcprelay4_sec")
+ if (defined($dlinkng::config::dhcprelay4_sec) && $dlinkng::config::dhcprelay4_sec){
+ telnet_cmd($switch, $cisco, "ip helper-address $dlinkng::config::dhcprelay4_sec")
or return abort($switch->{switchname}, $cisco);
}
}
# Custom Portchannel-config
# Dynamically applied depending on OS
- foreach my $cmd (@{$po_config->{$switch->{coreswos}}}){
+ foreach my $cmd (@{$dlinkng::config::po_config->{$switch->{coreswos}}}){
telnet_cmd($switch, $cisco, $cmd)
or return abort($switch->{switchname}, $cisco);
}
-
+
# 'no shut'-patrol reporting in!
telnet_cmd($switch, $cisco, "no shut")
or return abort($switch->{switchname}, $cisco);
+
+ # Done with interface-config
+ # Apply DHCP-profiling if using IOS-XR
+ if (is_xr($switch->{coreswos})){
+ telnet_cmd($switch, $cisco, "dhcp ipv4")
+ or return abort($switch->{switchname}, $cisco);
+ telnet_cmd($switch, $cisco, "interface Bundle-Ether$switch->{etherchannel} proxy profile $dlinkng::config::dhcp4_proxyprofile")
+ or return abort($switch->{switchname}, $cisco);
+
+ if(defined($dlinkng::config::dhcp6_proxyprofile) && $dlinkng::config::dhcp6_proxyprofile){
+ # Do DHCPv6 proxy as well
+
+ telnet_cmd($switch, $cisco, "dhcp ipv6")
+ or return abort($switch->{switchname}, $cisco);
+ telnet_cmd($switch, $cisco, "interface Bundle-Ether$switch->{etherchannel} proxy profile $dlinkng::config::dhcp6_proxyprofile")
+ or return abort($switch->{switchname}, $cisco);
+ }
+ }
+
+ # Commit on XR
+ if(is_xr($switch->{coreswos})){
+ telnet_cmd($switch, $cisco, "commit")
+ or return abort($switch->{switchname}, $cisco);
+ }
+
telnet_cmd($switch, $cisco, "end")
or return abort($switch->{switchname}, $cisco);
}
# If we skipped last port at the start, we configure it now
- if (($skip_last_port && $skipped_port && defined($skipped_port)) || ($skipped_port_only && defined($skipped_port_only))){
+ if (($dlinkng::config::skip_last_port && $skipped_port && defined($skipped_port)) || ($skipped_port_only && defined($skipped_port_only))){
if ($skipped_port_desc_only){
info($switch->{switchname}, "Configuring skipped port... (description only)");
} else {
@@ -913,11 +1040,11 @@ sub setup{
telnet_cmd($switch, $cisco, "int $skipped_port")
or return abort($switch->{switchname}, $cisco);
- telnet_cmd($switch, $cisco, "desc AP \@ D-Link $switch->{switchname}; RJ-45; 1G;")
+ telnet_cmd($switch, $cisco, "description AP \@ D-Link $switch->{switchname}; RJ-45; 1G;")
or return abort($switch->{switchname}, $cisco);
unless ($skipped_port_desc_only){
- foreach my $cmd (@{$last_port_config->{$switch->{coreswos}}}){
+ foreach my $cmd (@{$dlinkng::config::last_port_config->{$switch->{coreswos}}}){
telnet_cmd($switch, $cisco, $cmd)
or return abort($switch->{switchname}, $cisco);
}
@@ -925,6 +1052,13 @@ sub setup{
telnet_cmd($switch, $cisco, "no shut")
or return abort($switch->{switchname}, $cisco);
}
+
+ # Commit on XR
+ if(is_xr($switch->{coreswos})){
+ telnet_cmd($switch, $cisco, "commit")
+ or return abort($switch->{switchname}, $cisco);
+ }
+
telnet_cmd($switch, $cisco, "end")
or return abort($switch->{switchname}, $cisco);
}
@@ -940,17 +1074,7 @@ sub setup{
info($switch->{switchname}, "Done doing skipped port config. Not checking if anything is online.");
$return = 1;
} else {
- unless (pong($switch->{ipv4address}, 15)){
- if (cisco_ping($cisco, $switch->{ipv4address}, 60, $switch->{coreswos})) {
- # we can reach from core, but not from other places, lets warn
- log_it("ERROR", "red", $switch->{switchname}, "Switch $switch->{switchname} reachable only from core/distro.");
- } else {
- reset_interfaces($switch, $cisco)
- or return abort($switch->{switchname}, $cisco);
- $cisco->close;
- return error($switch->{switchname}, "Can't ping $switch->{switchname} on $switch->{ipv4address}, aborting.");
- }
- } else {
+ if(pong($switch->{ipv4address}, 15)){
# pingable, OK
log_it("SUCCESS", "green", $switch->{switchname}, "Switch $switch->{switchname} ($switch->{ipv4address}) set up! \\o/");
@@ -961,11 +1085,22 @@ sub setup{
info($switch->{switchname}, "Going to push D-Link template config to switch $switch->{switchname} ($switch->{ipv4address})");
$return = push_dlink_template_config($switch);
}
+ } else {
+ # Not pingable
+ if (cisco_ping($cisco, $switch->{ipv4address}, 60, $switch->{coreswos})) {
+ # we can reach from core, but not from other places, lets warn
+ log_it("ERROR", "red", $switch->{switchname}, "Switch $switch->{switchname} reachable only from core/distro.");
+ } else {
+ reset_interfaces($switch, $cisco)
+ or return abort($switch->{switchname}, $cisco);
+ $cisco->close;
+ return error($switch->{switchname}, "Can't ping $switch->{switchname} on $switch->{ipv4address}, aborting.");
+ }
}
}
- if($save_config){
- # save the cisco-config
+ if($save_config && !is_xr($switch->{coreswos})){
+ # save the cisco-config, but not if IOS-XR
info($switch->{switchname}, "Saving config on core-switch ($switch->{coreswip}).");
telnet_cmd($switch, $cisco, "write")
or return abort($switch->{switchname}, $cisco);
@@ -987,13 +1122,13 @@ sub process_switches {
$telnet_sessions{$switch->{coreswip}} = 0 unless $telnet_sessions{$switch->{coreswip}};
$telnet_sessions{$switch->{coreswip}} += 2;
- if ($telnet_sessions{$switch->{coreswip}} <= $os_info->{$switch->{coreswos}}{max_sessions}){
+ if ($telnet_sessions{$switch->{coreswip}} <= $dlinkng::config::os_info->{$switch->{coreswos}}{max_sessions}){
# lower or equal to max_sessions on current switch
# lets move on
last;
} else {
# we would exceed max_sessions on current switch
- # we wait until there is free sessions
+ # we wait until there are free sessions
info($switch->{switchname}, "There are no more free sessions left on '$switch->{coreswip}' ($switch->{coreswos}). Waiting...");
$telnet_sessions{$switch->{coreswip}} -= 2;
sleep (int(rand(10)) + 10);
@@ -1026,8 +1161,8 @@ sub process_switches {
# Let's start
my $time_start = time();
-log_it("INFO", "yellow", "dlink-ng", "Starting dlink-ng with $max_threads threads...");
-log_it("INFO", "yellow", "dlink-ng", "Configured to skip last port on all switches.") if $skip_last_port;
+log_it("INFO", "yellow", "dlink-ng", "Starting dlink-ng with $dlinkng::config::max_threads threads...");
+log_it("INFO", "yellow", "dlink-ng", "Configured to skip last port on all switches.") if $dlinkng::config::skip_last_port;
# Let's add all switches to the queue
while (<STDIN>){
@@ -1042,7 +1177,7 @@ while (<STDIN>){
}
# define OS of the coresw
- my $coreswos = set_coreswos($switchname);
+ my $coreswos = set_coreswos($coreswip);
# find netmask
my $netmask = Net::IP->new($cidr)->mask();
@@ -1071,10 +1206,10 @@ while (<STDIN>){
}
# Let the threads know when they're done
-$switchq->enqueue("DONE") for (1..$max_threads);
+$switchq->enqueue("DONE") for (1..$dlinkng::config::max_threads);
# Start processing the queue
-threads->create("process_switches") for (1..$max_threads);
+threads->create("process_switches") for (1..$dlinkng::config::max_threads);
# Wait till all threads is done
sleep 5 while (threads->list(threads::running));
@@ -1094,4 +1229,3 @@ log_it("INFO", "yellow", "dlink-ng", "Finished!");
log_it("INFO", "yellow", "dlink-ng", "Crunched $total_switches switches in $runtime seconds.");
log_it("INFO", "yellow", "dlink-ng", "$switches of these were successful, while $failed_switches failed.");
log_it("INFO", "yellow", "dlink-ng", "Average of $avg seconds per switch.");
-