aboutsummaryrefslogtreecommitdiffstats
path: root/dlink-ng
diff options
context:
space:
mode:
Diffstat (limited to 'dlink-ng')
-rwxr-xr-xdlink-ng/dlink-ng-config.pm.dist169
-rwxr-xr-xdlink-ng/dlink-ng.pl1242
-rwxr-xr-xdlink-ng/make-dlink-config.pl71
3 files changed, 0 insertions, 1482 deletions
diff --git a/dlink-ng/dlink-ng-config.pm.dist b/dlink-ng/dlink-ng-config.pm.dist
deleted file mode 100755
index 82abbf6..0000000
--- a/dlink-ng/dlink-ng-config.pm.dist
+++ /dev/null
@@ -1,169 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-no warnings 'closure'; # remove "Variable $foo will not stay shared" :-D
-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 $configure_last_port = 0; # Configure last port differently than the rest
-our $last_port_regex = '^e([1-8][1-9]|[2-8][0-9])-'; # Regex to use in combination with $configure_last_port
-our $use_ssh_cisco = 0; # Use SSH towards Cisco-boxes
-our $use_ssh_dlink = 0; # Use SSH towards D-Link switches
-our $cdp_enable = 0; # Enable or disable CDP on each port
-our $save_config = 1; # Save configuration to Cisco switch
-our $access_vlan = '3602'; # VLAN to use for last 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 => [
- "ip directed-broadcast 2699",
- "ip pim sparse-mode",
- "ip pim bsr-border",
- "logging event link-status",
- "ipv6 nd other-config-flag",
- "ipv6 dhcp server sexdhcp",
- ],
- 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;
- eval "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;
- BEGIN {
- $tg_dir = '/root/tgmanage';
- 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
deleted file mode 100755
index 5d9efa0..0000000
--- a/dlink-ng/dlink-ng.pl
+++ /dev/null
@@ -1,1242 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Net::Telnet::Cisco;
-use Net::Ping;
-use Term::ANSIColor;
-use threads;
-use threads::shared;
-use Thread::Queue;
-use Getopt::Long;
-use Net::IP;
-use Net::OpenSSH;
-BEGIN {
- use File::Basename;
- my $dlink_dir = dirname(__FILE__);
- require "$dlink_dir/dlink-ng-config.pm";
-}
-
-# 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
-my $switches : shared = 0; # Number of successful switches
-my $failed_switches : shared = 0; # Number of failed switches
-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
-
-# Autoflush
-$| = 1;
-
-# Get options
-my ($cisco_config, $single_switch, $dlink_config, $last_port_config, $last_port_desc);
-if (@ARGV > 0) {
- GetOptions(
- 'c|cisco|ciscoconfig' => \$cisco_config, # Configure on the Cisco-side only (Portchannel, interfaces, etc)
- 's|switch=s' => \$single_switch, # Configure a single switch
- 'd|dlink|dlinkconfig=s' => \$dlink_config, # Push D-Link-template-config to D-Link (not used @ TG)
- 'lastport' => \$last_port_config, # Configure the last port only (Cisco-side)
- 'lastportdesc' => \$last_port_desc, # Configure the description on the last port (Cisco-side)
- )
-}
-
-# Exit if D-Link template file doesn't exist
-if ($dlink_config){
- unless(-e $dlink_config){
- die("File '$dlink_config' does not exists. Aborting.\n");
- }
-}
-
-# Exit if $cisco_config and $last_port_config or $last_port_desc is set
-if ($cisco_config && ($last_port_config || $last_port_desc)){
- die("\$cisco_config and \$last_port_config (or \$last_port_desc) can't be used together.\n");
-}
-
-# If $last_port_desc, assume $last_port_config
-if ($last_port_desc){
- $last_port_config = 1;
-}
-
-# Exit if we give $last_port_config or $last_port_desc parameters, but $configure_last_port is not set
-if ($last_port_config || $last_port_desc){
- unless($dlinkng::config::configure_last_port){
- die("\$configure_last_port not set, but expected due to either \$last_port_config or \$last_port_desc.\n");
- }
-}
-
-# Print stuff
-sub log_it{
- my ($logtype, $color, $switchname, $msg) = @_;
- printf ("%-38s %s\n", colored("$logtype", "$color") . "/" . colored("$switchname", "bold") . ":", "$msg");
-}
-
-# INFO-logs
-sub info{
- my ($switchname, $msg) = @_;
- log_it("INFO", "blue", $switchname, $msg);
- return 1;
-}
-
-# ERROR-logs
-sub error{
- my ($switchname, $msg) = @_;
- printf ("%-38s %s\n", colored("ERROR", "red") . "/" . colored("$switchname", "bold") . ":", "$msg");
- return 0;
-}
-
-# Debug from Net::Telnet::Cisco and similar
-sub debug{
- my ($switchname, $errmsg) = @_;
-
- if ($errmsg){
- foreach my $line (split('\\n', $errmsg)){
- error($switchname, $line);
- }
- }
-}
-
-# Abort
-sub abort{
- my ($switchname, $t1, $t2) = @_;
-
- $t1->close if defined($t1);
- $t2->close if defined($t2);
-
- return error($switchname, "Aborting.");
-}
-
-# Set coreswos
-sub set_coreswos{
- my $coreswip = shift;
-
- my $os = $dlinkng::config::default_coreswos;
-
- 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;
- return 1 if ($coreswos =~ m/^nx$/i);
- 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) = @_;
- my $cmd;
-
- if (is_nx($coreswos)){
- $cmd = "ping $ip count 1 timeout 1";
- $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 ${dlinkng::config::vrf_prefix}${vrf}" if ($vrf && defined($vrf));
- $cmd .= " $ip repeat 1 timeout 1";
- }
-
- my $pong = 0;
- my $tries = 0;
- while (($pong == 0) && ($tries < $timeout)){
- my @res = $cisco->cmd($cmd);
-
- # if blank, try again
- # happens at least on ME3600X
- next unless @res;
-
- # sleep if it complains about no valid source address
- # % VRF does not have a usable source address
- # this is caused by no link, or network not propagated
- # observed on WS-C6506-E with sup720 running 122-33.SXJ5
- sleep 1 if ("@res" =~ m/VRF does not have a usable source address/);
-
- if (is_nx($coreswos)){
- $pong = 1 if ($res[1] =~ m/^64 bytes from $ip/i);
- } else {
- $pong = 1 if ($res[-1] =~ m/^\s*Success rate is 100 percent/i);
- }
- $tries++;
- }
- return $pong;
-}
-
-# Net::Ping-ping
-sub pong{
- my ($ip, $timeout) = @_;
- my $pong = 0;
- my $tries = 0;
-
- while(($pong == 0) && ($tries < $timeout)){
- my $p = Net::Ping->new();
-
- if ($p->ping($ip, 5)) {
- $pong = 1;
- }
-
- $tries++;
- }
- return $pong;
-}
-
-# Create login to D-Link
-sub dlink_login{
- my ($switch, $ip, $vrf, $telnet_source) = @_;
-
- my $dlink = Net::Telnet::Cisco->new(
- Host => $switch->{coreswip} . $dlinkng::config::domain_name,
- Errmode => 'return',
- 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
- );
-
- unless (defined($dlink)) {
- return error($switch->{switchname}, "Could not connect to '$switch->{coreswip}'.");
- }
-
- info($switch->{switchname}, "Logging in to coreswitch '$switch->{coreswip}' to telnet to D-Link.");
-
- 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).");
- }
-
- # 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 ${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 ${dlinkng::config::vrf_prefix}${vrf}" if ($vrf && defined($vrf));
- $cmd .= " /source-interface $telnet_source" if ($telnet_source && defined($telnet_source));
- }
-
- info($switch->{switchname}, "Telneting to D-Link.");
- $dlink->print($cmd);
-
- info($switch->{switchname}, "Waiting for login prompt.");
- $dlink->waitfor('/User ?Name:/')
- or return abort($switch->{switchname}, $dlink);
-
- info($switch->{switchname}, "Got login prompt, logging in.");
- telnet_print($switch, $dlink, $dlinkng::config::dlink_def_user, 0)
- or return abort($switch->{switchname}, $dlink);
-
- info($switch->{switchname}, "Waiting for prompt.");
- $dlink->waitfor('/\S+\#/')
- or return abort($switch->{switchname}, $dlink);
-
- # disable CLI paging
- telnet_print($switch, $dlink, "disable clipaging")
- or return abort($switch->{switchname}, $dlink);
-
- info($switch->{switchname}, "Logged in to D-Link");
- return $dlink;
-}
-
-# Execute telnet-command
-sub telnet_cmd{
- my ($switch, $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;
- }
-
- return 1;
-}
-
-# Execute telnet-print
-sub telnet_print{
- my ($switch, $telnet, $cmd, $waitfor) = @_;
-
- unless (defined($waitfor)){
- $waitfor = 1;
- }
-
- unless ($telnet->print($cmd)){
- error($switch->{switchname}, "Command '$cmd' failed.");
- debug($switch->{switchname}, $telnet->errmsg);
- return 0;
- }
-
- if ($waitfor){
- $telnet->waitfor('/\S+\#/') or return 0;
- }
-
- return 1;
-}
-
-# Make sure interface actually is shut
-sub no_no_shut{
- my ($switch, $cisco, $port) = @_;
-
- info($switch->{switchname}, "Making sure interface $port /REALLY/ gets shut.");
-
- # There is a few reasons as to why we want to do this.
- # On some boxes/OSes, default config for an interface is 'no shut'.
- # On some boxes/OSes, the 'shut' command isn't applied right away after
- # you do a 'shut'.
-
- 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;
- }
-
- sleep 1; # wait a bit
-
- telnet_cmd($switch, $cisco, "shut")
- or return abort($switch->{switchname}, $cisco);
-
- # now we need to check that the 'running config' actually reflects this
-
- my @shut_info = $cisco->cmd("do sh run int $port | i shutdown");
-
- unless(@shut_info){
- $tries++;
- next;
- }
-
- my $shut = "@shut_info";
- chomp($shut);
-
- if ($shut =~ m/shutdown/i){
- $return = 1;
- last;
- } else {
- $tries++;
- next;
- }
- }
- }
-
- return $return;
-}
-
-# Reset all interfaces
-sub reset_interfaces{
- my ($switch, $cisco) = @_;
-
- # Take down interface
- info($switch->{switchname}, "Resetting interfaces.");
-
- telnet_cmd($switch, $cisco, "conf t")
- or return abort($switch->{switchname}, $cisco);
-
- # Remove old config/return to defaults on interfaces
- # We also shut them to avoid D-Link looping
- foreach my $port (@{$switch->{ports}}){
- telnet_cmd($switch, $cisco, "default int $port")
- or return abort($switch->{switchname}, $cisco);
- telnet_cmd($switch, $cisco, "int $port")
- or return abort($switch->{switchname}, $cisco);
- no_no_shut($switch, $cisco, $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);
- }
- }
-
- # Remove portchannel
- 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")
- or return abort($switch->{switchname}, $cisco);
-
- return 1;
-}
-
-# Push D-Link template config to a D-Link
-sub push_dlink_template_config{
- my $switch = shift; # switchinfo
-
- # No need to bounce via Cisco-box; login directly to D-Link
- my $dlink = Net::Telnet::Cisco->new(
- Host => $switch->{ipv4address},
- Errmode => 'return',
- 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
- );
-
- unless (defined($dlink)) {
- return error($switch->{switchname}, "Could not connect to '$switch->{switchname}' ($switch->{ipv4}).");
- }
-
- info($switch->{switchname}, "Logging in to D-Link '$switch->{switchname}' ($switch->{ipv4address}).");
- $dlink->waitfor('/User ?Name:/')
- or return abort($switch->{switchname}, $dlink);
-
- info($switch->{switchname}, "Got login prompt, logging in.");
- telnet_print($switch, $dlink, $dlinkng::config::dlink_def_user, 0)
- or return abort($switch->{switchname}, $dlink);
-
- info($switch->{switchname}, "Waiting for prompt.");
- $dlink->waitfor('/\S+\#/')
- or return abort($switch->{switchname}, $dlink);
-
- # disable CLI paging
- telnet_print($switch, $dlink, "disable clipaging")
- or return abort($switch->{switchname}, $dlink);
-
- info($switch->{switchname}, "Logged in to D-Link");
-
- # Done logging in, let's configure stuff
- info($switch->{switchname}, "Opening D-Link template file ($dlink_config).");
- open $DLINK_TEMPLATE, '<', $dlink_config or return error($switch->{switchname}, "Couldn't open D-Link template ($dlink_config): $!");
-
- info($switch->{switchname}, "Applying config from D-Link template file ($dlink_config).");
-
- while (my $line=<$DLINK_TEMPLATE>) {
- chomp $line;
-
- next if ($line =~ m/^\s*(((#|\!).*)|$)/); # skip if comment, or blank line
-
- telnet_print($switch, $dlink, $line)
- or return abort($switch->{switchname}, $dlink);
-
- sleep 1; # The D-Link's are a bit slow...
- }
-
- close $DLINK_TEMPLATE or return error($switch->{switchname}, "Couldn't close D-Link template ($dlink_config): $!");
-
- info($switch->{switchname}, "Done applying config from D-Link template file ($dlink_config). Saving...");
-
- # Save config + logout
- telnet_print($switch, $dlink, "save", 0)
- or return abort($switch->{switchname}, $dlink);
- telnet_print($switch, $dlink, "Y")
- or return abort($switch->{switchname}, $dlink);
- telnet_print($switch, $dlink, "logout")
- or return abort($switch->{switchname}, $dlink);
-
- # Done
- log_it("SUCCESS", "green", $switch->{switchname}, "Done pushing D-Link template config to switch $switch->{switchname} ($switch->{ipv4address}). \\o/");
- $dlink->close;
- return 1;
-}
-
-# Setup a switch
-sub setup{
- my $switch = shift; # switchinfo
- my $vrf = threads->tid(); # use thread ID as VRF-number
-
- # Remove last port if we're skipping it
- my $last_port;
- if ($dlinkng::config::configure_last_port){
- # assume we want to skip a port, so we check against regex
- if($switch->{switchname} =~ m/$dlinkng::config::last_port_regex/){
- $last_port = pop(@{$switch->{ports}});
- }
- }
-
- if($last_port_config){
- info($switch->{switchname}, "Configuring last port only.");
- }
-
- if($cisco_config){
- info($switch->{switchname}, "Configuring things on the Cisco-side only.");
- }
-
- unless($cisco_config || $last_port_config){
- info($switch->{switchname}, "Starting configuration of $switch->{switchname} ($switch->{ipv4address}).");
- info($switch->{switchname}, "Trying to ping $switch->{ipv4address}.");
-
- if (pong($switch->{ipv4address}, 1)){
- # push template-config to D-Link if template-file is given as argument
- if($dlink_config){
- log_it("INFO", "green", $switch->{switchname}, "Switch $switch->{switchname} ($switch->{ipv4address}) is already responding to ping! \\o/");
- info($switch->{switchname}, "Going to push D-Link template config to switch $switch->{switchname} ($switch->{ipv4address})");
- return push_dlink_template_config($switch);
- } else {
- # if not
- log_it("INFO", "green", $switch->{switchname}, "Skipping $switch->{switchname} ($switch->{ipv4address}): is already responding to ping! \\o/");
- return 1;
- }
- }
-
- info($switch->{switchname}, "Not responding to ping, configuring device.");
- }
-
- info($switch->{switchname}, "Connecting to coreswitch '$switch->{coreswip}'.");
-
- 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}'.");
- }
-
- unless ($dlinkng::config::use_ssh_cisco){
- info($switch->{switchname}, "Logging in to coreswitch '$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}'.");
- }
- }
-
- # 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")
- or return abort($switch->{switchname}, $cisco);
-
- unless($cisco_config || $last_port_config){
- # Prepare ports
- reset_interfaces($switch, $cisco)
- or return abort($switch->{switchname}, $cisco);
-
- # Set up port 1 for D-Link telneting
- telnet_cmd($switch, $cisco, "conf t")
- or return abort($switch->{switchname}, $cisco);
-
- 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
- # spits out "% VRF dlink-X not found"
- # making Net::Telnet::Cisco think it's an error
-
- # Extra overhead to delete, not used
- #$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 ${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 {
- # 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 ${dlinkng::config::vrf_prefix}${vrf}");
-
- # Create 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
- 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 $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, $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
-
- # First we need to check if there are more ports to test
- if ($p_count >= $#{$switch->{ports}}){
- # Current port is last port available
- # Since it did not ping, we reset all interfaces
-
- reset_interfaces($switch, $cisco)
- or return abort($switch->{switchname}, $cisco);
- $cisco->close;
- return error($switch->{switchname}, "No more ports on $switch->{switchname}. Aborting.");
- }
-
- # Use next port
- $p_count++;
-
- info($switch->{switchname}, "D-Link on port #" . ($p_count) . " ($dlink_port) did not respond. Trying next port (" . @{$switch->{ports}}[$p_count] . ").");
-
- # Try next port, reset old port
- telnet_cmd($switch, $cisco, "conf t")
- 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);
- no_no_shut($switch, $cisco, $dlink_port)
- or return abort($switch->{switchname}, $cisco);
-
- # Set new port
- $dlink_port = @{$switch->{ports}}[$p_count];
-
- # Configure new port
- 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 $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, $dlinkng::config::dlink_def_ip, $vrf)
- or return abort($switch->{switchname}, $cisco);
-
- 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, "create link_aggregation group_id 1 type lacp")
- or return abort($switch->{switchname}, $cisco, $dlink);
- 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, "enable stp")
- or return abort($switch->{switchname}, $cisco, $dlink);
-
- info($switch->{switchname}, "STP enabled, logging in again.");
- $dlink->close;
-
- 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 $dlinkng::config::dlink_def_ip, aborting.");
- }
-
- $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, "config stp version mstp")
- or return abort($switch->{switchname}, $cisco, $dlink);
- telnet_print($switch, $dlink, "config stp priority 61440 instance_id 0")
- or return abort($switch->{switchname}, $cisco, $dlink);
- telnet_print($switch, $dlink, "config stp ports 1:(1-44) edge true")
- or return abort($switch->{switchname}, $cisco, $dlink);
- telnet_print($switch, $dlink, "enable lldp")
- or return abort($switch->{switchname}, $cisco, $dlink);
-
- info($switch->{switchname}, "Setting IP address.");
- 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;
-
- info($switch->{switchname}, "Configuring IP on gateway.");
- telnet_cmd($switch, $cisco, "conf t")
- or return abort($switch->{switchname}, $cisco);
- telnet_cmd($switch, $cisco, "default int $dlink_port")
- or return abort($switch->{switchname}, $cisco);
- 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})) {
- 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.");
- }
-
- # Do it again!
- info($switch->{switchname}, "D-Link config phase 2.");
- $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, "create iproute default $switch->{ipv4gateway}")
- or return abort($switch->{switchname}, $cisco, $dlink);
- telnet_print($switch, $dlink, "save", 0)
- or return abort($switch->{switchname}, $cisco, $dlink);
- telnet_print($switch, $dlink, "Y")
- or return abort($switch->{switchname}, $cisco, $dlink);
- telnet_print($switch, $dlink, "logout")
- or return abort($switch->{switchname}, $cisco, $dlink);
-
- info($switch->{switchname}, "Closing D-Link link.");
- $dlink->close;
- }
-
- unless($last_port_config){
- # Configure final IOS stuff
- info($switch->{switchname}, "Final IOS config phase. Setting up all interfaces + Port-Channel.");
-
- # Reset interfaces
- reset_interfaces($switch, $cisco)
- or return abort($switch->{switchname}, $cisco);
-
- telnet_cmd($switch, $cisco, "conf t")
- or return abort($switch->{switchname}, $cisco);
-
- # Portchannel needs to exist before we can assign interfaces to it
- # 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);
-
- 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, "description D-Link $switch->{switchname}; RJ-45; 1G;")
- or return abort($switch->{switchname}, $cisco);
-
- # disable CDP if specified
- unless($dlinkng::config::cdp_enable){
- telnet_cmd($switch, $cisco, "no cdp enable")
- 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; ";
- }
-
- 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);
-
-
- 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-XR
- telnet_cmd($switch, $cisco, "ipv6 enable")
- or return abort($switch->{switchname}, $cisco);
- }
-
- 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})){
- # 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($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 $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 helper-address $dlinkng::config::dhcprelay4_sec")
- or return abort($switch->{switchname}, $cisco);
- }
- }
-
- # Custom Portchannel-config
- # Dynamically applied depending on OS
- 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 ($dlinkng::config::configure_last_port && $last_port){
- if ($last_port_desc){
- info($switch->{switchname}, "Configuring last port... (description only)");
- } else {
- info($switch->{switchname}, "Configuring last port...");
- }
-
- telnet_cmd($switch, $cisco, "conf t")
- or return abort($switch->{switchname}, $cisco);
- unless ($last_port_desc){
- telnet_cmd($switch, $cisco, "default int $last_port")
- or return abort($switch->{switchname}, $cisco);
- }
-
- telnet_cmd($switch, $cisco, "int $last_port")
- or return abort($switch->{switchname}, $cisco);
- telnet_cmd($switch, $cisco, "description AP \@ D-Link $switch->{switchname}; RJ-45; 1G;")
- or return abort($switch->{switchname}, $cisco);
-
- unless ($last_port_desc){
- foreach my $cmd (@{$dlinkng::config::last_port_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);
- }
-
- # 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 only cisco-config
- if($cisco_config){
- log_it("CONFIG", "green", $switch->{switchname}, "Cisco-config relevant to switch '$switch->{switchname}' ($switch->{ipv4address}) done! \\o/");
- }
-
- # Check if all is OK, but not if configuring skipped port only
- my $return = 0;
- if ($last_port_config){
- info($switch->{switchname}, "Done doing skipped port config. Not checking if anything is online.");
- $return = 1;
- } else {
- if(pong($switch->{ipv4address}, 15)){
- # pingable, OK
- log_it("SUCCESS", "green", $switch->{switchname}, "Switch $switch->{switchname} ($switch->{ipv4address}) set up! \\o/");
-
- $return = 1;
-
- # push template-config to D-Link if template-file is given as argument
- if($dlink_config){
- 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($dlinkng::config::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);
- }
-
- $cisco->close;
- return $return;
-}
-
-# Process switches
-sub process_switches {
- while (my $switch = $switchq->dequeue()){
- last if ($switch eq 'DONE'); # all done
-
- my $time_start = time();
-
- # Wait till there is sessions/VTYs available
- while (1){
- $telnet_sessions{$switch->{coreswip}} = 0 unless $telnet_sessions{$switch->{coreswip}};
- $telnet_sessions{$switch->{coreswip}} += 2;
-
- 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 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);
- }
- }
-
- info($switch->{switchname}, "Number of sessions on switch '$switch->{coreswip}': $telnet_sessions{$switch->{coreswip}}.");
-
- if (setup($switch)) {
- # Count number of switches
- $switches++;
-
- } else {
- log_it("FAILED", "red", $switch->{switchname}, "Configuring $switch->{switchname} failed.");
-
- # Count failed switches
- $failed_switches++;
- }
-
- # Remove session
- $telnet_sessions{$switch->{coreswip}} -= 2;
-
- # Summarize total time spent, used to calculate average per switch
- $total_time += time() - $time_start;
- }
-
- # detach thread -- we're done
- threads->detach;
-}
-
-# Let's start
-my $time_start = time();
-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::configure_last_port;
-
-# Let's add all switches to the queue
-while (<STDIN>){
- next if /^(.*#|\s+$)/; # skip if comment, or blank line
-
- my ($switchname, $coreswip, $etherchannel, $cidr, $ipv4address, $ipv4gateway, $ipv6address, @ports) = split;
-
- # skip if less than 1 port is provided
- if (scalar(@ports) < 1){
- log_it("FAILED", "red", $switchname, "Switch '$switchname' had less than 1 port configured. Skipping.");
- next;
- }
-
- # define OS of the coresw
- my $coreswos = set_coreswos($coreswip);
-
- # find netmask
- my $netmask = Net::IP->new($cidr)->mask();
-
- my %switch = (
- switchname => $switchname,
- coreswip => $coreswip,
- coreswos => $coreswos,
- etherchannel => $etherchannel,
- ipv4address => $ipv4address,
- ipv4gateway => $ipv4gateway,
- netmask => $netmask,
- ipv6address => $ipv6address,
- ports => \@ports,
- );
-
- # Only configure a single switch?
- if (defined $single_switch){
- unless ($single_switch eq $switchname){
- next;
- }
- }
-
- # Add switch to queue
- $switchq->enqueue(\%switch);
-}
-
-# Let the threads know when they're done
-$switchq->enqueue("DONE") for (1..$dlinkng::config::max_threads);
-
-# Start processing the queue
-threads->create("process_switches") for (1..$dlinkng::config::max_threads);
-
-# Wait till all threads is done
-sleep 5 while (threads->list(threads::running));
-
-# If 0 switches
-my $runtime = time() - $time_start;
-my $total_switches = $switches + $failed_switches;
-if($total_switches == 0){
- log_it("INFO", "yellow", "dlink-ng", "Finished!");
- log_it("INFO", "yellow", "dlink-ng", "Crunched 0 switches in $runtime seconds.");
- exit 1;
-}
-
-# Done
-my $avg = sprintf("%.1f", $total_time / $total_switches);
-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.");
diff --git a/dlink-ng/make-dlink-config.pl b/dlink-ng/make-dlink-config.pl
deleted file mode 100755
index 7a20820..0000000
--- a/dlink-ng/make-dlink-config.pl
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/usr/bin/perl -I /root/tgmanage/
-use strict;
-use warnings;
-use lib '..';
-BEGIN {
- require "include/config.pm";
- eval {
- require "include/config.local.pm";
- };
-}
-
-unless (@ARGV > 0) {
- print "No arguments. Need switches.txt and patchlist.txt.\n";
- exit 1;
-}
-
-my $s = open(SWITCHES, "$ARGV[0]") or die ("Cannot open switches.txt");
-my $p = open(PATCH, "$ARGV[1]") or die ("Cannot open patchlist.txt");
-
-my $portchannel_start = 10;
-my %portchannels;
-my $letter = "a";
-
-my %switches;
-while(<SWITCHES>) {
- chomp;
- my ($network, $netmask, $switchname, $mngmt_ip) = split; # $mngmt_ip is unused
- $switches{$switchname} = {
- network => $network,
- netmask => $netmask,
- };
-}
-while (<PATCH>) {
- chomp;
- my ($switchname, $coregw, @ports) = split;
- my $network = $switches{$switchname}{network};
- my $netmask = $switches{$switchname}{netmask};
- my ($o1, $o2, $o3, $o4) = split(/\./, $network);
-
- # portchannel per distro
- if($coregw =~ m/distro0/){
- # TG14-fix for distro0
- $portchannels{$coregw} = 15 unless ($portchannels{$coregw} && defined($portchannels{$coregw}));
- } else {
- $portchannels{$coregw} = $portchannel_start unless ($portchannels{$coregw} && defined($portchannels{$coregw}));
- }
-
- if ($o4 eq "0") {
- $letter = "a";
- } elsif ($o4 eq "64") {
- $letter = "b";
- } elsif ($o4 eq "128") {
- $letter = "c";
- } elsif ($o4 eq "192") {
- $letter = "d";
- }
-
- my $v6addr = $nms::config::base_ipv6net . $o3 . $letter ."::1/64";
-
- $o4 += 1;
- my $gateway_addr = "$o1.$o2.$o3.$o4";
- $o4 += 1;
- my $switch_addr = "$o1.$o2.$o3.$o4";
-
- print "$switchname $coregw $portchannels{$coregw} $network/$netmask $switch_addr $gateway_addr $v6addr " . join(' ', @ports) . "\n";
-
- # increase portchannel
- $portchannels{$coregw}++;
-
- die("NO MORE ETHERCHANNELS!") if($portchannels{$coregw} > 64); # IOS-XE 4500 only supports 64 portchannels
-}