Site scripts

To use any of the site scripts:

  1. Download the script.
  2. In AKIPS, go to the Admin → API → Site Scripting menu.
  3. Paste the script into the text box and click Save.
  4. Reload the Site Scripting page so the new Perl function is displayed in the drop-down list.
  5. Many script functions can be manually run by selecting the function from the drop-down list and clicking Run.

Available Site Scripts

  1. Custom Inventory Report as CSV
  2. Cisco Error-Disable
  3. Create WeatherMap Data File
  4. Custom site script to post alert in Opsgenie
  5. Custom site script to post alert in Pagerduty
  6. Custom site script to post alert in ServiceNow
  7. Custom site script to post alert in Slack
  8. Delete Cisco WAPs from selected wireless controller[s]
  9. Delete Unreachable Devices
  10. Discover API Examples
  11. Discover Dell iDRAC6 Devices
  12. Discover From CSV File
  13. Discover Ping-Only Devices
  14. Email Newly Discovered Devices
  15. Email Status Alert
  16. Email Syslog Alert
  17. Email Threshold Alert
  18. Export 5 minute interface statistics
  19. Export Device Chassis report
  20. Export Device Extended Details
  21. Export Device Summary report
  22. Handle BGP Peer State Changes
  23. Import Ping-Only Devices
  24. Interface Speeds by Group
  25. Interface Speeds by Name
  26. List IP Addresses with Multiple Devices
  27. RESTful API Integration Threshold Alert
  28. Send Status Alert via Syslog
  29. Send Threshold Alert via Syslog
  30. Sync Device Name with sysName
  31. Threshold Alert Limiting
  32. Web API for Device Discovery
  33. Web API for Single Device Rewalk
  34. Web API to Add/Delete Manual group
  35. Web API to delete Device[s]
  36. Web API to rename single Device

1. Custom Inventory Report as CSV

This is a custom script example to send the inventory report as CSV.

Download script
# Subroutine to email custom inventory report as csv
sub custom_inventory_report_csv
{
   # Nominate a single mail address to receive the report
   my $mail_to = ''; # e.g. jbloggs@example.com

   # Nominate a group mailing list to receive the report
   my $profile = ''; # e.g. NetEng

   # Subject line of the emailed report
   my $subject = "Custom Inventory Report CSV";

   # Name of the csv file
   my $CSVFILE = "$HOME_TMP/custom_inventory.csv";

   # Header name of the first column (with field delimiter ",")
   my $csv_column_header = "Device".",";

   # Working variables
   my $OUT;
   my @body;
   my %data;

   # This structure defines all of the data to collect for your report.
   # Data is collected when an attribute is used to query the database,
   # resulting with a returned value. The returned value is recorded
   # and presented in your report.
   #
   # Each, key => value, pair represents:
   #                    "database attribute"     => "column header name"
   #
   # Modify the attributes and column names to suit your report.
   #
   # NOTE: The last pair in the structure has been "commented out",
   # as an example of how to exclude data from your report, without
   # deleting the pair. This approach can be useful when testing.
   my @attr_column_names = (
                       {"ip4addr"                => "IPv4 Address"},
                       {"model"                  => "Model"},
                       {"serial"                 => "Serial Number"},
                       {"sw_rev"                 => "Software (OS Version)"},
                       {"SNMPv2-MIB.sysLocation" => "Location (sysLocation)"},
                       {"SNMP.snmpState"         => "Added"},
                       {"SNMPv2-MIB.sysUpTime"   => "sysUpTime"},
                       {"SNMPv2-MIB.sysDescr"    => "Description"},
                       #{"IF-MIB.ifInErrors"     => "Error"},
                      );

   # Get data for all the attributes defined above
   for my $i ( 0 .. $#attr_column_names )
   {
       for my $attr ( keys %{ $attr_column_names[$i] } ) {
          # Build the list of column header names 
          $csv_column_header .= $attr_column_names[$i]{$attr}. ",";

          # Database query to get attribute data
          for my $line (adb_result ("mget * * * $attr")) {
             my ($device, undef, undef, undef, $value) = split (" ", $line, 5);
             $data{$device}{$i} = $value || "";

             #
             # Some attributes require additional work to get the data
             # into a presentable format. Two examples are shown below.
             #

             # Format returned sysUpTime data
             if ($attr eq "SNMPv2-MIB.sysUpTime" ) {
                my ($start_tt, $end_tt) = split (",", $value);
                $data{$device}{$i} = time_elapsed($start_tt) || "";
             }

             # Format returned snmpState data
             if ($attr eq "SNMP.snmpState"){
                my (undef, undef, $added_tt, undef) = split (",", $value);
                $data{$device}{$i} = date_fmt($added_tt, "yyyymmddhhmm") || "";
             }
           }
        }
   }

   # Open a csv file
   open ($OUT, ">", $CSVFILE) or EXIT_FATAL ("Could not open $CSVFILE: $!");

   # Print the column header to csv file
   print $OUT $csv_column_header;
   print $OUT "\n";

   # Print data to csv file
   for my $device (sort keys %data) {
      my $row;
      $row = $device.",";
      for my $attr (0..$#attr_column_names) {
        if ($data{$device}{$attr}) {
           $row .= $data{$device}{$attr}.",";
        }
        else {
           $row .= ",";
        }
      }
      $row .= "\n";
      print $OUT $row;
   }
   close ($OUT);

   # Send to a single email address
   if ($mail_to ne "") {
      mail ({ subject => $subject, to => $mail_to, body => \@body, attach => [$CSVFILE] });
   }

   # Send to all email addresses in a profile
   if ($profile ne "") {
      for my $addr (config_get_emails ($profile)) {
         mail ({ subject => $subject, to => $addr, body => \@body, attach => [$CSVFILE] });
      }
   }

}

2. Cisco Error-Disable

Error-disable is a feature in Cisco switches that automatically disables a switch port when an error is detected. The reasons a switch port can go into error-disable mode include:

The MIB objects for error-disable are dynamically created in a conceptual MIB table when the port is disabled, therefore the error-disable state can NOT be collected using the normal polling process. The only method of retrieving a list of ports in the error-disabled state is an SNMP Walk. This script performs an SNMP walk of CISCO-ERR-DISABLE-MIB.cErrDisableIfStatusCause at the specified time (default 8am) and emails a list of the errors to the address defined by the "address" variable.

Download script
sub sched_1h_cisco_error_disabled
{
   my $ip;
   my $cmd;
   my $line;
   my $IN;
   my $OUT;
   my $ipaddr;
   my $name;
   my $ifindex;
   my $interface;
   my $reason;
   my $filename = "$HOME_TMP/cisco-error-disabled";
   my $snmp_cfg_ref = config_load_snmp_cfg ();
   my $ip2name_ref = config_load_ip2name ();
   my $tm_ref = get_localtime ();
   my @body;
   my %results;
   my $address = '';   # XXX Set me

   return if ($tm_ref->{hour} != 8); # Run daily at 8am

   open ($OUT, "|-", "$SNMP_PROG > $filename") or EXIT_FATAL ("Can't run $SNMP_PROG");
   for my $dev (keys %{ $snmp_cfg_ref }) {
      next if ($snmp_cfg_ref->{$dev}{state} eq "down");
      $ip = $snmp_cfg_ref->{$dev}{ipaddr} || next;
      $cmd = $snmp_cfg_ref->{$dev}{cmd}   || next;
      printf $OUT "walk %s %s CISCO-ERR-DISABLE-MIB.cErrDisableIfStatusCause\n", $ip, $cmd;
   }
   close $OUT;

   open ($IN, "<", $filename) or EXIT_FATAL ("Can't open $filename");
   while ($line = <$IN>) {
      chomp $line;
      next if ($line =~ /^#/m);
      ($ipaddr, undef, undef, $ifindex, undef, $reason) = split (" ", $line);
      $ifindex = sprintf ("%d", $ifindex);
      $name = $ip2name_ref->{$ipaddr};
      (undef, $interface, undef) = split (" ", adb_result (sprintf ("mget * %s * /ifindex/ value %s", $name, $ifindex)));
      push @{ $results{ $name } }, (sprintf ("%s - %s", $interface, $reason));
   }
   close $IN;

   for my $dev (keys %results) {
      push @body, sprintf( "\n%s:", $dev );
      for my $entry (@{ $results{ $dev } }) {
         push @body, sprintf ("   %s", $entry);
      }
   }

   if ($address ne "" and scalar @body > 0) {
      mail ({ to => $address, subject => 'Cisco Error Disabled', body => \@body });
   }
}

This script creates a tab delimited output file that can be sent to, or retrieved by, your weathermap server. The output format is:

{DeviceName}:{InterfaceName} {In BPS} {Out BPS}

You need to use the auto or manual grouping to add all interfaces to the "weathermap-links" interface group. For example, in the auto grouping:

add interface group weathermap-links
assign interface router1 Fa0/2 = weathermap-links
assign interface router2 Fa0/5 = weathermap-links

If the $remote_user, $remote_host, and $remote_path parameters are filled in, the script will scp the output file to your weathermap server. You will need to install a public SSH key on your weathermap server to enable authentication. SSH to the AKIPS server as akips user and run the following command, replacing {user} and {weathermap host} with your weathermap server username and IP address.

ssh-copy-id -i /home/akips/.ssh/id_rsa.pub {user}@{weathermap host}

Refer to the Network WeatherMap documentation.

Download script
sub sched_1m_weathermap_links
{
   my $remote_user = ""; # e.g. 'www'
   my $remote_host = ""; # e.g. 10.1.2.3
   my $remote_path = ""; # e.g. /var/www/html/plugins/weathermap/configs
   my $remote_file = "akips.txt";
   my $data_file   = "/tmp/weathermap.txt";
   my %data;
   my $OUT;

   for my $line (adb_result ("mcalc avg time last1m ifrate * * /^IF-MIB.*BitRate/ any group weathermap-links")) {
      my ($device, $interface, $attr, undef, $val) = split (" ", $line, 5);
      my $link = sprintf ("%s:%s", $device, $interface);
      given ($attr) {
         when ("IF-MIB.ifInBitRate")  { $data{$link}{inbps}  = $val; }
         when ("IF-MIB.ifOutBitRate") { $data{$link}{outbps} = $val; }
      }
   }

   open ($OUT, ">", $data_file) || EXIT_FATAL ("Could not create %s", $data_file);
   for my $link (keys %data) {
      printf $OUT "%s\t%s\t%s\n", $link, $data{$link}{inbps}, $data{$link}{outbps};
   }
   close $OUT;

   if ($remote_user ne "" and $remote_host ne "" and $remote_path ne "" and $remote_file ne "") {
      system (sprintf ("/usr/bin/scp -q %s %s@%s:%s/%s", $data_file, $remote_user, $remote_host, $remote_path, $remote_file));
   }
}

4. Custom site script to post alert in Opsgenie

This script can be used to create an custom alert in Opsgenie.

Download script
sub custom_post_alert_to_opsgenie
{
   my %opsgenie;
   my $message             = "AKIPS Custom Site Script";
   my $opsgenie_alias      = "test custom alert";

   $opsgenie{url}          = "https://api.opsgenie.com/v2/alerts";
   $opsgenie{headers}      = ["Authorization: GenieKey xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxx" ];
   $opsgenie{method}       = "post";
   $opsgenie{content_type} = "application/json";

   # Uncomment the following line to use proxy 
   # $opsgenie{proxy}      = "http://xxxx:3128";

   my $data                = qq ({"message":" $message ","alias":"$opsgenie_alias","description":"$opsgenie_alias","priority":"P1"});
   $opsgenie{data}         = $data;

  http_result (\%opsgenie);
}

5. Custom site script to post alert in Pagerduty

This script can be used to create an custom alert in Pagerduty.

Download script
sub custom_post_alert_to_pagerduty
{
   my %pagerduty;

   $pagerduty{url}          = "https://events.pagerduty.com/v2/enqueue";
   $pagerduty{method}       = "post";
   $pagerduty{content_type} = "application/json";

   # Uncomment the following line to use proxy 
   # $pagerduty{proxy}      = "http://xxxx:3128";

   $pagerduty{data}         =  qq ({"routing_key":"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX","event_action": "trigger","payload":{"summary": "Akips Custom Site Script", "source": "Akips", "severity": "error"}});

   http_result (\%pagerduty);

}

6. Custom site script to post alert in ServiceNow

This script can be used to create an custom alert in ServiceNow.

Download script
sub custom_post_alert_to_servicenow
{
   my %servicenow;
   my $user                  = "admin";
   my $pwd                   = "XxxXxXXXxxXX";
   my $auth                  = "$user:$pwd";
   my $request               = qq({"short_description":"Akips custom site script","urgency":"2"});

   $servicenow{url}          = "https://xxxxxxxxx.service-now.com/api/now/table/incident";
   $servicenow{basic_auth}   = $auth;

   # Uncomment the following line to use proxy 
   # $servicenow{proxy}      = "http://xxxx:3128";

   $servicenow{content_type} = "application/json";
   $servicenow{method}       = "post";
   $servicenow{data}         = $request;

   http_result (\%servicenow);
}

7. Custom site script to post alert in Slack

This script can be used to create an custom alert in Slack.

Download script
sub custom_post_alert_to_slack
{
   my %slack;

   $slack{url}          = "https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXXX/XXXXXXXXXXXXX";
   $slack{method}       = "post";
   $slack{content_type} = "application/json";

   # Uncomment the following line to use proxy 
   # $slack{proxy}      = "http://xxxx:3128";

   my $data             = qq({"text":"AKIPS Custom Site Script"});
   $slack{data}         = $data;

   http_result (\%slack);
}

8. Delete Cisco WAPs from selected wireless controller[s]

This script automatically deletes wireless access points belonging to particular cisco wireless controller[s]. The script runs after Discover.

Download script
# Script to delete controller wireless access points
sub config_cisco_delete_controllers_waps
{
   my @controllers_waps_to_be_deleted;
   # Name of controllers whose waps needs to be deleted
   # Controller names are space separated
   # Replace cisco-ctrl-4 cisco-ctrl-5 cisco-ctrl-6 cisco-ctrl-7 with the controller whose WAPs needs to be deleted
   @controllers_waps_to_be_deleted = qw (cisco-ctrl-4 cisco-ctrl-5 cisco-ctrl-6 cisco-ctrl-7);

   if (scalar (@controllers_waps_to_be_deleted) > 0 ){
      # Create a group of Controllers WAPs that needs to be deleted
      my $delete_ctrl_waps_group = "delete_controller_access_points";
      adb_send (sprintf ("add device group %s", $delete_ctrl_waps_group));

      for my $ctrl_name (@controllers_waps_to_be_deleted) {
         for my $line (adb_result (sprintf ("mget * * * SNMP.proxy value %s", $ctrl_name))) {
             my ($ap_name, undef, undef, undef, undef) = split (" ", $line, 5);
             # Assign WAPs to group
             adb_send (sprintf ("assign device %s = %s", $ap_name, $delete_ctrl_waps_group));
         }
      }

      # Delete  waps belonging to controller
      adb_send (sprintf ("mdelete * * any group %s ", $delete_ctrl_waps_group));

      # Delete group
      adb_send (sprintf ("delete device group %s ", $delete_ctrl_waps_group));
   }
}

9. Delete Unreachable Devices

This script automatically deletes all devices which have been down for over 7 days. The script runs at the end of a Discover or Rewalk.

Download script
sub config_delete_unreachable_devices
{
   my $prune_days = 7;
   my $prune_time = 60 * 60 * 24 * $prune_days;
   my @arr = adb_result ("mget enum * ping4 PING.icmpState");
   my $cur_tt = time ();

   for my $line (@arr) {
      my ($dev, undef, undef, undef, $val) = split (" ", $line, 5);
      my (undef, $state, undef, $mtime, undef) = split (",", $val, 5);
      next if ($state ne "down");
      if ($cur_tt - $mtime > $prune_time) {
         printf " Removing %s\n", $dev;
         errlog ($ERR_DEBUG, "Deleting unreachable device %s", $dev);
         adb_send (sprintf ("delete device %s", $dev));
      }
   }
   adb_flush ();
}


10. Discover API Examples

This example shows some ways a Discover can be initiated from a Site Script.

Download script
sub custom_discover
{
   my $discover_lock;

   # Get a lock on the discover
   $discover_lock = process_lock ($DISCOVER_LOCK, LOCK_EX)
      or EXIT_FATAL ("Failed to get a lock");

   # Open discover log file
   discover_log ("discover-script.log");


   # Full discovery using Ping Ranges and SNMP Parameters
   # under Admin > Discover > Discover/Rewalk

   #if (discover_scan () > 0) {
   #   discover_config ();
   #}


   # Single device discovery using specified SNMP parameters

   #if (discover_scan ("version 2 community public", "10.1.2.3") > 0) {
   #   discover_config ();
   #}


   # Scan IP address ranges using SNMP Parameters
   # under Admin > Discover > Discover/Rewalk

   #if (discover_scan (undef, "10.1.2.0/24", "10.1.3.0/24") > 0) {
   #   discover_config ();
   #}


   # Close discover log file
   stdout_log_close ();

   process_unlock ($discover_lock);
}

11. Discover Dell iDRAC6 Devices

This script runs at the end of a successful Discover (not a Rewalk) and adds any iDRAC6 devices as ping-only devices. It will also add the relevant objects for the Dell iDRAC System Status report.

NOTES:

Download script
sub config_discover_idrac6
{
   my $IN;
   my %walk;

   if (open ($IN, "<", $DISCOVER_CONFIG_WALK)) {
      while (my $line = <$IN>) {
         chomp $line;
         my ($ip, $mib, $obj, $idx, undef, $val) = split (" ", $line, 6);
         next if ($mib ne "DELL-RAC-MIB");
         if (defined $cfg_oids{$mib}{$obj}) {
            $walk{$ip}{$mib}{$obj}{$idx} = $val;
         }
      }
      close $IN;
   }

   if (open ($IN, "<", $DISCOVER_DEVICES)) {
      while (my $line = <$IN>) {
         chomp $line;
         my ($ip4, $ip6, $device, $snmp_opt, $sysObjectID, $sysDescr) = split (",", $line, 6);

         if ($sysObjectID eq "DELL-RAC-MIB.drsOutofBandGroup") {
            my %dev = ();
            $dev{device}  = $device;
            $dev{ip4addr} = $ip4;
            $dev{ip6addr} = $ip6;
            $dev{descr}   = $sysDescr;
            if (config_add_ping_device (\%dev) == 1) {
               printf "Added %s\n", $device;

               # Add IDRAC6 objects
               my $mib = "DELL-RAC-MIB";
               adb_send (sprintf ("add child %s idrac", $device));
               for my $obj (keys %{$walk{$ip4}{$mib}}) {
                  my $cfg_ref = $cfg_oids{$mib}{$obj};
                  my $type    = $cfg_ref->{type};
                  my $value   = $walk{$ip4}{$mib}{$obj}{"0"};

                  if ($type eq "text") {
                     adb_send (sprintf ("add %s %s idrac %s.%s = \"%s\"", $type, $device, $mib, $obj, $value));
                  }
               }
            }
         }
      }
      close $IN;
      adb_flush ();
   }
}

12. Discover From CSV File

This script shows how to initiate a Discover/Rewalk from a CSV file. The CSV file could be generated from an external IPAM system, for example.

The format of the CSV input file is:

Place your CSV file in /tmp/devices.csv on the AKIPS server and run this script.

NOTE: This script will run a Discover/Rewalk for each unique set of SNMP credentials in your CSV file.

Download script
# File format:
#   ipaddr,SNMP parameters[,hostname]
# e.g.
#   10.1.8.250,version 2 community foobar
#   10.1.8.251,version 3 user fred sha password aes256 password,atlanta-ro
#
sub custom_discover_import_csv
{
   my $DEVICES_CSV = "/tmp/devices.csv";
   my $IN;
   my $line;
   my @domains;
   my %cfg;
   my %ip2host;
   my %ip2name;
   my $discover_lock;

   return if (not -e $DEVICES_CSV);

   # Get a lock on the discover
   $discover_lock = process_lock ($DISCOVER_LOCK, LOCK_EX)
      or EXIT_FATAL ("Failed to get a lock");

   # Open discover log file
   discover_log ("discover-script.log");

   open ($IN, "<", $DEVICES_CSV) or EXIT_FATAL ("Can't open $DEVICES_CSV: $!");
   unlink $DEVICES_CSV;

   @domains = config_load_domains ();

   while ($line = <$IN>) {
      chomp $line;
      my ($ipaddr, $snmp_param, $hostname) = split (",", $line, 3);
      trim $snmp_param;
      $cfg{$snmp_param}{$ipaddr} = 1;
      if (defined $hostname and $hostname ne "") {
         $ip2host{$ipaddr} = config_strip_sysname ($hostname, @domains);
      }
   }
   close $IN;

   for my $snmp_param (sort keys %cfg) {
      if (discover_scan ($snmp_param, keys %{ $cfg{$snmp_param} }) > 0) {
         discover_config ();
      }
   }

   # Close discover log file
   stdout_log_close ();

   # Set hostnames
   if (scalar keys %ip2host > 0) {
      for my $ip (keys %ip2host) {
         if (defined $ip2name{$ip} and $ip2name{$ip} ne $ip2host{$ip}) {
            my $from_name = $ip2name{$ip}{name};
            my $to_name   = $ip2host{$ip};
            config_rename_device ($from_name, $to_name);
         }
      }
   }

   process_unlock ($discover_lock);
}

13. Discover Ping-Only Devices

This script performs a ping scan of the specified ranges and creates the appropriate configuration for ping-only devices.

Edit the @ranges array definition at the top of the function to define your own IP ranges.

Download script
use Socket;

sub custom_scan_ping_devices
{
   my @ranges = (
      "10.1.1.0/24",
   );
   my @domains = config_load_domains ();
   my $IN;
   my $OUT;
   my $PING_SCAN_OUT = "$HOME_TMP/ping-scan.out";
   my %result;

   open ($OUT, "|-", "$PING_SCAN -o $PING_SCAN_OUT") or EXIT_FATAL ("Can't run $PING_SCAN: $!");
   for my $r (@ranges) {
      printf $OUT "%s\n", $r;
   }
   close $OUT;  # Block on the close until nm-ping-scan completes

   open ($IN, "<", $PING_SCAN_OUT) or EXIT_FATAL ("Can't open $PING_SCAN_OUT: $!");
   while (my $ipaddr = <$IN>) {
      chomp $ipaddr;

      my $name = gethostbyaddr (inet_aton ($ipaddr), AF_INET);

      if (defined $name) {
         $name = config_strip_sysname ($name, @domains);
      }
      else {
         $name = $ipaddr;
      }

      if ($ipaddr =~ /$REGEX_IPV4_ADDR/m) {
         $result{$name}{ip4addr} = $ipaddr;
         $result{$name}{device}  = $name;
      }
      elsif ($ipaddr =~ /$REGEX_IPV6_ADDR/m) {
         $result{$name}{ip6addr} = $ipaddr;
         $result{$name}{device}  = $name;
      }
   }
   close $IN;

   for my $name (keys %result) {
      config_add_ping_device ($result{$name});
   }
}

14. Email Newly Discovered Devices

This script runs at the end of a Discover and sends an email listing all newly discovered devices.

You will need to configure either $mail_to or $profile in the script below.

Download script
sub config_mail_new_devices
{
   my ($arg_ref) = @_;

   # Set one of the following two parameters
   my $mail_to = ''; # e.g. jbloggs@example.com
   my $profile = ''; # e.g. NetEng

   my $subject;
   my @body;
   my $cnt = 0;

   # Get the time of the last discover SNMP scan
   my $fstat_ref = file_stat ($DISCOVER_SNMP_SCAN);
   my $discover_tt = $fstat_ref->{mtime};

   push @body, "The following devices were added into AKIPS:";
   push @body, "";

   # Inspect the creation time of every device
   for my $line (adb_result ("mtime device *")) {
      my ($device, undef, $val) = split (" ", $line);
      my ($ctime, $mtime, $utime) = split (",", $val);
      next if ($ctime < $discover_tt);

      # Add this new device into the email body
      my $time_str = strftime ("%H:%M", localtime ($ctime));
      push @body, sprintf ("%s %s", $time_str, $device);
      $cnt++;
   }

   return if ($cnt == 0);

   $subject = sprintf ("Discovered %d new devices", $cnt);

   # Send to a single email address
   if ($mail_to ne "") {
      mail ({ subject => $subject, to => $mail_to, body => \@body });
   }

   # Send to all email addresses in a profile
   if ($profile ne "") {
      for my $addr (config_get_emails ($profile)) {
         mail ({ subject => $subject, to => $addr, body => \@body });
      }
   }
}


15. Email Status Alert

This is a basic example which shows:

NOTE: This example script:

Download script
sub alert_mail_status
{
   my ($arg_ref) = @_;
   my $mail_to = ''; # e.g. jbloggs@example.com
   my $profile = ''; # e.g. NetEng
   my $subject = sprintf ("Status: %s %s %s %s",
                          $arg_ref->{device},
                          $arg_ref->{child},
                          $arg_ref->{descr},
                          $arg_ref->{state});
   my $ipaddr   = adb_result (sprintf ("get %s sys SNMP.ipaddr", $arg_ref->{device}));
   my $contact  = adb_result (sprintf ("get %s sys SNMPv2-MIB.sysContact", $arg_ref->{device}));
   my $location = adb_result (sprintf ("get %s sys SNMPv2-MIB.sysLocation", $arg_ref->{device}));
   my $time_str = strftime ("%H:%M", localtime ($arg_ref->{tt}));
   my @body;

   push @body, join (" ",
                     $time_str,
                     $arg_ref->{device},
                     $ipaddr,
                     #$contact  || "",
                     #$location || "",
                     $arg_ref->{child},
                     $arg_ref->{descr},
                     $arg_ref->{attr},
                     $arg_ref->{alias} || "",
                     $arg_ref->{state}
                    );

   # Send to a single email address
   if ($mail_to ne "") {
      mail ({ subject => $subject, to => $mail_to, body => \@body });
   }

   # Send to all email addresses in a profile
   if ($profile ne "") {
      for my $addr (config_get_emails ($profile)) {
         mail ({ subject => $subject, to => $addr, body => \@body });
      }
   }
}


16. Email Syslog Alert

This is a basic example which shows:

NOTE: This example script:

Download script
sub alert_mail_syslog
{
   my ($arg_ref) = @_;
   my $mail_to = ''; # e.g. jbloggs@example.com
   my $profile = ''; # e.g. NetEng

   # Parameters from alert
   my $tt       = $arg_ref->{tt};
   my $device   = $arg_ref->{device};
   my $ipaddr   = $arg_ref->{ipaddr};
   my $priority = $arg_ref->{priority};
   my $facility = $arg_ref->{facility};
   my $msg      = $arg_ref->{msg};
   my $time_str = strftime ("%H:%M", localtime ($arg_ref->{tt}));

   # Device parameters from database
   my $contact  = adb_result (sprintf ("get %s sys SNMPv2-MIB.sysContact", $device));
   my $location = adb_result (sprintf ("get %s sys SNMPv2-MIB.sysLocation", $device));

   my $subject = sprintf ("Syslog: %s %s %s",
                          $priority,
                          $device,
                          $ipaddr);
   my @body;

   push @body, join (" ",
                     $time_str,
                     $device,
                     $ipaddr,
                     #$contact  || "",
                     #$location || "",
                     $msg
                    );

   # Send to a single email address
   if ($mail_to ne "") {
      mail ({ subject => $subject, to => $mail_to, body => \@body });
   }

   # Send to all email addresses in a profile
   if ($profile ne "") {
      for my $addr (config_get_emails ($profile)) {
         mail ({ subject => $subject, to => $addr, body => \@body });
      }
   }
}

17. Email Threshold Alert

This is a basic example which shows:

NOTE: This example script:

Download script
sub alert_mail_threshold
{
   my ($arg_ref) = @_;

   # Modify the following parameters
   my $mail_to = ''; # e.g. jbloggs@example.com
   my $profile = ''; # e.g. NetEng

   # Get the IP address of the device which triggered the alert
   my $ipaddr = adb_result (sprintf ("get %s sys SNMP.ipaddr", $arg_ref->{device}));

   my $time_str = strftime ("%H:%M", localtime ($arg_ref->{tt}));
   my $child = "";
   my $thr = $arg_ref->{thr};
   my $val = $arg_ref->{val};
   my $subject;
   my @body;
   my $msg;

   # Parse the MIB and object which triggered the alert
   my ($mib, $obj) = split (/\./m, $arg_ref->{attr}, 2);

   # Apply formatting to interface thresholds
   if ($mib eq "IF-MIB") {
      given ($obj) {
         when (/if.*BitRate/m) {
            $thr = int_ifspeed ($thr);
            $val = int_ifspeed ($val);
         }
         when (/if.*Util/m) {
            $thr = int_util ($thr);
            $val = int_util ($val);
         }
         default {
            $thr = int_metric ($thr);
            $val = int_metric ($val);
         }
      }
      trim $val;
      $child = $arg_ref->{child};  # interface name
   }

   # Set the email subject
   $subject = sprintf ("%s: %s %s %s %s %s %s %s %s",
                       $arg_ref->{alias} || "",
                       $arg_ref->{device},
                       $child,
                       $arg_ref->{descr},
                       $arg_ref->{lastn},
                       $arg_ref->{stat},   # avg or total
                       $val,               # calculated value
                       $arg_ref->{state},  # above or below
                       $thr);              # threshold value

   # Set the email body
   $msg = sprintf ("%s %s %s %s %s %s %s %s %s %s %s",
                   $time_str,
                   $arg_ref->{alias} || "",
                   $arg_ref->{device},
                   $ipaddr,
                   $child,
                   $arg_ref->{descr},
                   $arg_ref->{lastn},
                   $arg_ref->{stat},   # avg or total
                   $val,               # calculated value
                   $arg_ref->{state},  # above or below
                   $thr);              # threshold value

   trim $subject;
   trim $msg;

   push @body, $msg;

   # Send to a single email address
   if ($mail_to ne "") {
      mail ({ subject => $subject, to => $mail_to, body => \@body });
   }

   # Send to all email addresses in a profile
   if ($profile ne "") {
      for my $addr (config_get_emails ($profile)) {
         mail ({ subject => $subject, to => $addr, body => \@body });
      }
   }
}


18. Export 5 minute interface statistics

This script creates a 5 minute CSV file for all interface statistics. The format of the file is:

  1. Device Name
  2. Interface Name
  3. In Octets
  4. Out Octets
  5. In BPS
  6. Out BPS
  7. In Percent Utilisation
  8. Out Percent Utilisation
  9. In Packets
  10. Out Packets
  11. In Unicast Packets
  12. Out Unicast Packets
  13. In Broadcast Packets
  14. Output Broadcast Packets
  15. In Multicast Packets
  16. Out Multicast Packets
  17. In Errors
  18. Out Errors
  19. In Discards
  20. Out Discards
  21. In Error Percentage
  22. Out Error Percentage
  23. In Discard Percentage
  24. Out Discard Percentage
The output file is located in: /home/akips/tmp/ifstats-last5m.csv

Download script
sub sched_5m_ifstats
{
   my $filename = "$HOME_TMP/ifstats-last5m.csv";
   my %stat;
   my $OUT;

   for my $line (adb_result ("mcalc avg time last5m ifutil * * /^IF-MIB.if.*Util/")) {
      my ($device, $interface, $attr, undef, $val) = split (" ", $line, 5);
      $attr =~ s/IF-MIB\.if//m;
      next if ($val eq "n/a");
      $stat{$device}{$interface}{$attr} = $val;
   }

   for my $line (adb_result ("mcalc avg time last5m ifrate * * /^IF-MIB/")) {
      my ($device, $interface, $attr, undef, $val) = split (" ", $line, 5);
      $attr =~ s/IF-MIB\.if//m;
      next if ($val eq "n/a");
      $stat{$device}{$interface}{$attr} = $val;
   }

   for my $line (adb_result ("mcalc total time last5m counter * * /^IF-MIB/")) {
      my ($device, $interface, $attr, undef, $val) = split (" ", $line, 5);
      $attr =~ s/IF-MIB\.if//m;
      $attr =~ s/^HC//m;
      next if ($val eq "n/a");
      $stat{$device}{$interface}{$attr} = $val;
   }

   open ($OUT, ">", "$filename.tmp") or EXIT_FATAL ("Can't open $filename.tmp: $!");

   for my $device (sort keys %stat) {
      for my $interface (sort keys %{ $stat{$device} }) {
         my $InPkts;
         my $OutPkts;
         my $InUtil = "";
         my $OutUtil = "";
         my $InErrorsPct = 0;
         my $OutErrorsPct = 0;
         my $InDiscardsPct = 0;
         my $OutDiscardsPct = 0;
         my $ref = $stat{$device}{$interface};

         next if (not defined $ref->{InUtil});
         next if (not defined $ref->{OutUtil});

         if ($ref->{InUtil} ne "") {
            $InUtil = sprintf ("%.2f", $ref->{InUtil} / 100);
         }

         if ($ref->{OutUtil} ne "") {
            $OutUtil = sprintf ("%.2f", $ref->{OutUtil} / 100);
         }

         $InPkts = ($ref->{InUcastPkts}     || 0)
                 + ($ref->{InBroadcastPkts} || 0)
                 + ($ref->{InMulticastPkts} || 0)
                 + ($ref->{InErrors}        || 0)
                 + ($ref->{InDiscards}      || 0);

         $OutPkts = ($ref->{OutUcastPkts}     || 0)
                  + ($ref->{OutBroadcastPkts} || 0)
                  + ($ref->{OutMulticastPkts} || 0);

         if ($InPkts > 0) {
            $InErrorsPct   = ($ref->{InErrors}   || 0) * 100 / $InPkts;
            $InDiscardsPct = ($ref->{InDiscards} || 0) * 100 / $InPkts;
         }

         if ($OutPkts > 0) {
            $OutErrorsPct   = ($ref->{OutErrors}   || 0) * 100 / $OutPkts;
            $OutDiscardsPct = ($ref->{OutDiscards} || 0) * 100 / $OutPkts;
         }

         printf $OUT "%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%.2f,%.2f,%.2f,%.2f\n",
                     $device,
                     $interface,
                     $ref->{InOctets}   || 0,
                     $ref->{OutOctets}  || 0,
                     $ref->{InBitRate}  || 0,
                     $ref->{OutBitRate} || 0,
                     $InUtil,
                     $OutUtil,
                     $InPkts,
                     $OutPkts,
                     $ref->{InUcastPkts}      || 0,
                     $ref->{OutUcastPkts}     || 0,
                     $ref->{InBroadcastPkts}  || 0,
                     $ref->{OutBroadcastPkts} || 0,
                     $ref->{InMulticastPkts}  || 0,
                     $ref->{OutMulticastPkts} || 0,
                     $ref->{InErrors}         || 0,
                     $ref->{OutErrors}        || 0,
                     $ref->{InDiscards}       || 0,
                     $ref->{OutDiscards}      || 0,
                     $InErrorsPct,
                     $OutErrorsPct,
                     $InDiscardsPct,
                     $OutDiscardsPct;
      }
   }

   close $OUT;
   rename ("$filename.tmp", $filename);
}

19. Export Device Chassis report

This script creates a CSV file containing the same information as ReportsDeviceChassis.

The format of the output file is:

  1. Device Name
  2. Model
  3. Serial
  4. Software Version
  5. Hardware Version
  6. Firmware Version
  7. Chassis Description

The output file is located in: /home/akips/tmp/device-chassis.csv

Download script
sub custom_export_device_chassis
{
   my $filename = "$HOME_TMP/device-chassis.csv";
   my %data;
   my $OUT;

   for my $line (adb_result ('mget text * /^chassis\./ *')) {
      my ($dev, $child, $attr, undef, $val) = split (" ", $line, 5);
      $data{$dev}{$child}{$attr} = $val;
   }

   for my $line (adb_result ('mget child * /^chassis\./')) {
      my ($dev, $child, undef, $val) = split (" ", $line, 4);
      my ($index, $descr) = split (",", $val);
      $data{$dev}{$child}{descr} = $descr;
   }

   open ($OUT, ">", "$filename.tmp") or EXIT_FATAL ("Can't open $filename.tmp: $!");
   for my $dev (nat_sort keys %data) {
      for my $child (sort { nat_cmp ($data{$dev}{$a}{descr}, $data{$dev}{$b}{descr}) }
                     keys %{ $data{$dev} }) {
         printf $OUT "%s,%s,%s,%s,%s,%s,\"%s\"\n",
                     $dev,
                     $data{$dev}{$child}{model}  || "",
                     $data{$dev}{$child}{serial} || "",
                     $data{$dev}{$child}{sw_rev} || "",
                     $data{$dev}{$child}{hw_rev} || "",
                     $data{$dev}{$child}{fw_rev} || "",
                     $data{$dev}{$child}{descr}  || "";
      }
   }
   close $OUT;
   rename ("$filename.tmp", $filename);
}

20. Export Device Extended Details

This script creates a CSV file containing the same information as ReportsDeviceSummary, plus SysContact, SNMP parameters, and group membership.

The format of the output file is:

  1. Device Name
  2. IPv4 Address
  3. IPv6 Address
  4. SysUpTime (Unix epoch time)
  5. SysUpTime (in seconds)
  6. SysUpTime (days/hours/minutes/seconds)
  7. Added (Unix epoch time)
  8. Added (yyyy-mm-dd HH:MM:SS)
  9. Location (sysLocation)
  10. Identifier (sysObjectID)
  11. Description (sysDescr)
  12. Contact (sysContact)
  13. SNMP Parameters
  14. Group Membership (space separated list)

The output file is located in: /home/akips/tmp/device-summary-ext.csv

Download script
sub custom_export_device_extended
{
   my $filename = "$HOME_TMP/device-summary-ext.csv";
   my $snmp_cfg_ref = config_load_snmp_cfg ();
   my %data;
   my $OUT;

   for my $line (adb_result ("mget text * sys *")) {
      my ($dev, $child, $attr, undef, $val) = split (" ", $line, 5);
      $attr =~ s/^SNMPv2-MIB\.//img;
      $data{$dev}{$attr} = $val;
   }

   for my $line (adb_result ("mget uptime * sys *")) {
      my ($dev, $child, $attr, undef, $val) = split (" ", $line, 5);
      my ($uptime, $utime) = split (",", $val);
      $attr =~ s/^SNMPv2-MIB\.//img;
      $data{$dev}{$attr} = $uptime;
   }

   for my $line (adb_result ("mtime device *")) {
      my ($dev, undef, $val) = split (" ", $line, 3);
      my ($ctime, $mtime, $utime) = split (",", $val);
      $data{$dev}{ctime} = $ctime;
   }

   for my $line (adb_result ("mgroup device *")) {
      my ($dev, undef, $val) = split (" ", $line, 3);
      if ($val eq "none") {
         $data{$dev}{groups} = "";
      }
      else {
         $val =~ s/,/ /mg;
         $data{$dev}{groups} = $val;
      }
   }

   open ($OUT, ">", "$filename.tmp") or EXIT_FATAL ("Can't open $filename.tmp: $!");
   for my $dev (nat_sort keys %data) {
      my $snmp_cmd = $snmp_cfg_ref->{lc ($dev)}{cmd} || "";
      $snmp_cmd =~ s/ maxrep \d+$//m;  # strip maxrep parameter

      my $uptime_sec = "";
      if (defined $data{$dev}{sysUpTime}) {
         $uptime_sec = time () - $data{$dev}{sysUpTime};
      }

      printf $OUT "%s,%s,%s,%s,%s,%s,%d,%s,\"%s\",%s,\"%s\",\"%s\",%s,%s\n",
                  $dev,
                  $data{$dev}{ip4addr}     || "",
                  $data{$dev}{ip6addr}     || "",
                  $data{$dev}{sysUpTime}   || "",
                  $uptime_sec,
                  time_elapsed ($data{$dev}{sysUpTime} || ""),
                  $data{$dev}{ctime},
                  date_fmt ($data{$dev}{ctime}, "yyyymmddhhmmss"),
                  $data{$dev}{sysLocation} || "",
                  $data{$dev}{sysObjectID} || "",
                  $data{$dev}{sysDescr}    || "",
                  $data{$dev}{sysContact}  || "",
                  $snmp_cmd,
                  $data{$dev}{groups}      || "";
   }
   close $OUT;
   rename ("$filename.tmp", $filename);
}

21. Export Device Summary report

This script creates a CSV file containing the same information as ReportsDeviceSummary.

The format of the output file is:

  1. Device Name
  2. IPv4 Address
  3. IPv6 Address
  4. SysUpTime (Unix epoch time)
  5. SysUpTime (in seconds)
  6. SysUpTime (days/hours/minutes/seconds)
  7. Added (Unix epoch time)
  8. Added (yyyy-mm-dd HH:MM:SS)
  9. Location (sysLocation)
  10. Identifier (sysObjectID)
  11. Description (sysDescr)

The output file is located in: /home/akips/tmp/device-summary.csv

Download script
sub custom_export_device_summary
{
   my $filename = "$HOME_TMP/device-summary.csv";
   my %data;
   my $OUT;

   for my $line (adb_result ("mget text * sys *")) {
      my ($dev, $child, $attr, undef, $val) = split (" ", $line, 5);
      $attr =~ s/^SNMPv2-MIB\.//img;
      $data{$dev}{$attr} = $val;
   }

   for my $line (adb_result ("mget uptime * sys *")) {
      my ($dev, $child, $attr, undef, $val) = split (" ", $line, 5);
      my ($uptime, $utime) = split (",", $val);
      $attr =~ s/^SNMPv2-MIB\.//img;
      $data{$dev}{$attr} = $uptime;
   }

   for my $line (adb_result ("mtime device *")) {
      my ($dev, undef, $val) = split (" ", $line, 5);
      my ($ctime, $mtime, $utime) = split (",", $val);
      $data{$dev}{ctime} = $ctime;
   }

   open ($OUT, ">", "$filename.tmp") or EXIT_FATAL ("Can't open $filename.tmp: $!");
   for my $dev (nat_sort keys %data) {
      my $uptime_sec = "";
      if (defined $data{$dev}{sysUpTime}) {
         $uptime_sec = time () - $data{$dev}{sysUpTime};
      }

      printf $OUT "%s,%s,%s,%s,%s,%s,%d,%s,\"%s\",%s,\"%s\"\n",
                  $dev,
                  $data{$dev}{ip4addr}     || "",
                  $data{$dev}{ip6addr}     || "",
                  $data{$dev}{sysUpTime}   || "",
                  $uptime_sec,
                  time_elapsed ($data{$dev}{sysUpTime} || ""),
                  $data{$dev}{ctime},
                  date_fmt ($data{$dev}{ctime}, "yyyymmddhhmmss"),
                  $data{$dev}{sysLocation} || "",
                  $data{$dev}{sysObjectID} || "",
                  $data{$dev}{sysDescr}    || "";
   }
   close $OUT;
   rename ("$filename.tmp", $filename);
}

22. Handle BGP Peer State Changes

This script is used to rate limit email alerts sent by BGP state change events.

This example handles BGP peer state changes by creating a new MIB object to store the last time an alert was triggered. An email is sent out with the details of the event only if a similar email hasn't been sent out in a specified period. By default this is 1 hour.

You can use this script to cause periodic temporary mutes to BGP peer state change events.

Download script
sub alert_handle_bgp_state_change
{
   my ($arg_ref) = @_;
   my $device =  $arg_ref->{device};
   my $child  =  $arg_ref->{child};
   my $attr   =  $arg_ref->{attr};
   my $state  =  $arg_ref->{state};
   my $TMP_MUTE_TIME = 3600; #How long to mute alerts for (in seconds)
   my $time_now;
   my $prev_time;
   my $adb_bgp_time;
   my $mib;

   my $mail_to = ''; # e.g. jbloggs@example.com
   my $profile = ''; # e.g. NetEng
   my $subject = sprintf ("BGP Peer State Change");
   my @body;

   $time_now = time ();

   # Get the MIB value from the attribute
   $mib = (split (/\./m, $attr))[0];

   # Gets last alert time
   $adb_bgp_time = adb_result (sprintf ("get %s %s %s.bgpPeerStateAlertTime", $device, $child, $mib));
   if (! defined $adb_bgp_time || length($adb_bgp_time) == 0) {
     adb_send (sprintf ("add integer %s %s %s.bgpPeerStateAlertTime = %s", $device, $child, $mib, $time_now));
     $prev_time = 0;
   }
   else {
      $prev_time = $adb_bgp_time;
   }

   # Checks last alert time is outside timeout
   if (($time_now - $prev_time) > $TMP_MUTE_TIME) {
      push @body, join (" ", $device, $child, $attr, $state);

      # Send to a single email address
      if ($mail_to ne "") {
         mail ({ subject => $subject, to => $mail_to, body => \@body });
      }

      # Send to all email addresses in a profile
      if ($profile ne "") {
         for my $addr (config_get_emails ($profile)) {
            mail ({ subject => $subject, to => $addr, body => \@body });
         }
      }

      # Update last alert time
      adb_send (sprintf ("set %s %s %s.bgpPeerStateAlertTime = %s", $device, $child, $mib, $time_now));
   }
}


23. Import Ping-Only Devices

This script imports a CSV formatted file and creates the appropriate configuration for ping-only devices.

Place your CSV file in /tmp/import.csv on the AKIPS server and run this script.

The format of the CSV input file is:

If $group is configured in the script below, a device group will be created if it doesn't exist, and any devices added by this script will be assigned to that device group.

Download script
#
# CSV file format:
# devicename,ip4addr,ip6addr,descr,location,contact
#
sub custom_import_ping_devices
{
   my $FILENAME = "/tmp/import.csv";
   my $group = ""; # e.g. Ping-Only

   my $IN;
   my $line;
   my %dev;

   if ($group ne "") {
      adb_send ("add device group $group");
   }

   open ($IN, "<", $FILENAME) or EXIT_FATAL ("Could not open $FILENAME: $!");

   while ($line = <$IN>) {
      chomp $line;
      %dev = ();
      ($dev{device}, $dev{ip4addr}, $dev{ip6addr},
       $dev{descr}, $dev{location}, $dev{contact}) = split (",", $line);

      if (config_add_ping_device (\%dev) == 1) {
         printf "Added %s\n", $dev{device};
         # assign device to a group
         if ($group ne "") {
            adb_send ("assign device $dev{device} = $group");
         }
      }
      else {
         printf "Failed to add %s\n", $dev{device};
      }
   }
   close $IN;
   adb_flush ();
}

24. Interface Speeds by Group

This script manually sets interface speeds in a specified group.

Site Scripting uses function names starting with ifspeed_ to run commands to manually set interface speeds.

You can test your ifspeed_ code by selecting "All ifspeed_ functions" from the dropdown, then clicking Run. Make sure there are no error messages in the output on the right side of the screen. You can then check an Interface report to confirm that the speed has been set correctly.

If the interfaces are collected in an interface group, you can use the mset command together with a group filter. For example, if you have an interface group named wan-links, this will set the speed to 2Gbps for all interfaces in that group.

Download script
sub ifspeed_interface_group
{
   # Command syntax:
   # mset integer {device regex} {interface regex} IF-MIB.ifSpeed [any|all|not group {group name}] = {speed in bits per sec}

   adb_send ("mset integer * * IF-MIB.ifSpeed any group wan-links = 2000000000");
   adb_flush ();
}

25. Interface Speeds by Name

This script manually sets interface speeds by specifying device name and interface name.

Site Scripting uses function names starting with ifspeed_ to run commands to manually set interface speeds.

You can test your ifspeed_ code by selecting "All ifspeed_ functions" from the dropdown, then clicking Run. Make sure there are no error messages in the output on the right side of the screen. You can then check an Interface report to confirm that the speed has been set correctly.

If you only need to manually set speeds on a handful of interfaces, you can issue individual set commands specifying the device and interface names. The following example sets the speed to 2Gbps for 3 interfaces on the device atlanta-ro.

Download script
sub ifspeed_interfaces
{
   # Command syntax:
   # set {device} {interface} IF-MIB.ifSpeed = {speed in bits per sec}

   adb_send ("set atlanta-ro Te3/1 IF-MIB.ifSpeed = 2000000000");
   adb_send ("set atlanta-ro Te3/2 IF-MIB.ifSpeed = 2000000000");
   adb_send ("set atlanta-ro Te3/3 IF-MIB.ifSpeed = 2000000000");
   adb_flush ();
}

26. List IP Addresses with Multiple Devices

If multiple devices have the same IPv4 address configured in AKIPS, this script will list them.

Download script
sub custom_duplicate_ipaddr
{
   my %ip2dev;
   my %dev_ctime;
   my $cnt = 0;

   for my $line (adb_result ("mget * * sys ip4addr")) {
      my ($dev, undef, undef, undef, $ip) = split (" ", $line, 5);
      push @{ $ip2dev{$ip} }, $dev;
   }

   for my $line (adb_result ("mtime device *")) {
      my ($dev, undef, $val) = split (" ", $line, 3);
      my ($ctime, $mtime, $utime) = split (",", $val);
      $dev_ctime{$dev} = $ctime;
   }

   for my $ip (nat_sort keys %ip2dev) {
      if (scalar @{ $ip2dev{$ip} } > 1) {
         printf "%s\n", $ip;
         for my $dev (sort { $dev_ctime{$a} <=> $dev_ctime{$b} } @{ $ip2dev{$ip} }) {
            my $ctime = $dev_ctime{$dev};
            printf " %-20s <a href=\"/device-editor?mode=display;device_list=%s\" target=_blank>%s</a>\n",
                   time_simple ($ctime), $dev, $dev;
            $cnt++;
         }
         printf "\n";
      }
   }

   if ($cnt == 0) {
      printf "No duplicates found.\n";
   }
}

27. RESTful API Integration Threshold Alert

This is a basic example which shows:

NOTE: This example script does not implement any alert bundling.

Download script
sub alert_http_send_threshold
{
   my ($arg_ref) = @_;
   my %args;

   # Get the IP address of the device which triggered the alert
   my $ipaddr = adb_result (sprintf ("get %s sys SNMP.ipaddr", $arg_ref->{device}));

   my $time_str = strftime ("%H:%M", localtime ($arg_ref->{tt}));
   my $child = "";
   my $thr = $arg_ref->{thr};
   my $val = $arg_ref->{val};

   # Parse the MIB and object which triggered the alert
   my ($mib, $obj) = split (/\./m, $arg_ref->{attr}, 2);

   # Apply formatting to interface thresholds
   if ($mib eq "IF-MIB") {
      given ($obj) {
         when (/if.*BitRate/m) {
            $thr = int_ifspeed ($thr);
            $val = int_ifspeed ($val);
         }
         when (/if.*Util/m) {
            $thr = int_util ($thr);
            $val = int_util ($val);
         }
         default {
            $thr = int_metric ($thr);
            $val = int_metric ($val);
         }
      }
      trim $val;
      $child = $arg_ref->{child};  # interface name
   }

   # Call remote server
   $args{url}          = sprintf ("http://www.example.com/alert?ipaddr=%s,ifname=%s,time_str=%s,thr=%s,val=%s", $ipaddr, $child, $time_str, $thr, $val);
   $args{method}       = "get";
   $args{content_type} = "text/html";
   http_send (\%args);
   http_close ();

   # Call remote server to execute scripts
   http_send ({
      url          => "http://www.example.com:8080/script?name=my_script.txt",
      method       => "GET",
      content_type => "text/html",
   });
}


28. Send Status Alert via Syslog

This is a basic example which shows:

The priority parameter must be one of the following:

The facility parameter must be one of the following:

Download script
sub alert_status_send_syslog
{
   my ($arg_ref) = @_;
   my $msg;

   # Modify the following parameters. You must set $dest_ip to enable this script.
   # Refer to the Site Script documentation at www.akips.com for details
   my $dest_ip  = ""; # IP address of remote syslog collector
   my $priority = "error";
   my $facility = "local3";

   # Get the IP address of the device which triggered the alert
   my $dev_ip   = adb_result (sprintf ("get %s sys SNMP.ipaddr", $arg_ref->{device}));
   my $time_str = strftime ("%Y-%m-%d %H:%M:%S%z", localtime ($arg_ref->{tt}));
   #my $time_utc = strftime ("%Y-%m-%d %H:%M:%SZ", gmtime ($arg_ref->{tt}));

   # Parse the MIB and object which triggered the alert
   my ($mib, $obj) = split (/\./m, $arg_ref->{attr}, 2);

   # The following formats the message similar to Status Alerting email messages.
   if ($mib eq "IF-MIB") {
      $msg = sprintf ("%s %s %s %s %s %s %s",
                      $time_str,
                      $arg_ref->{alias} || "",
                      $arg_ref->{device},
                      $dev_ip,
                      $arg_ref->{child},  # interface name
                      $arg_ref->{descr},
                      $arg_ref->{state});
   }
   else {
      $msg = sprintf ("%s %s %s %s %s %s",
                      $time_str,
                      $arg_ref->{alias} || "",
                      $arg_ref->{device},
                      $dev_ip,
                      $arg_ref->{descr},
                      $arg_ref->{state});
   }

   # Send the syslog message
   if ($dest_ip ne "") {
      syslog ({
         ipaddr   => $dest_ip,
         priority => $priority,
         facility => $facility,
         message  => $msg,
      });

      # Send message to 'alert' log for debugging purposes
      errlog ($ERR_ALERT, "syslog $dest_ip $priority $facility $msg");
   }
}


29. Send Threshold Alert via Syslog

This is a basic example which shows:

The priority parameter must be one of the following:

The facility parameter must be one of the following:

Download script
sub alert_threshold_send_syslog
{
   my ($arg_ref) = @_;
   my $msg;
   my $thr = $arg_ref->{thr};
   my $val = $arg_ref->{val};

   # Modify the following parameters. You must set $dest_ip to enable this script.
   # Refer to the Site Script documentation at www.akips.com for details
   my $dest_ip  = ""; # IP address of remote syslog collector
   my $priority = "error";
   my $facility = "local3";

   # Get the IP address of the device which triggered the alert
   my $dev_ip   = adb_result (sprintf ("get %s sys SNMP.ipaddr", $arg_ref->{device}));
   my $time_str = strftime ("%Y-%m-%d %H:%M:%S%z", localtime ($arg_ref->{tt}));
   #my $time_utc = strftime ("%Y-%m-%d %H:%M:%SZ", gmtime ($arg_ref->{tt}));

   # Parse the MIB and object which triggered the alert
   my ($mib, $obj) = split (/\./m, $arg_ref->{attr}, 2);

   # The following formats the message similar to Threshold Alerting email messages.
   if ($mib eq "IF-MIB") {
      given ($obj) {
         when (/if.*BitRate/m) {
            $thr = int_ifspeed ($thr);
            $val = int_ifspeed ($val);
         }
         when (/if.*Util/m) {
            $thr = int_util ($thr);
            $val = int_util ($val);
         }
         default {
            $thr = int_metric ($thr);
            $val = int_metric ($val);
         }
      }
      trim $val;
      $msg = sprintf ("%s %s %s %s %s %s %s %s %s %s %s",
                      $time_str,
                      $arg_ref->{alias} || "",
                      $arg_ref->{device},
                      $dev_ip,
                      $arg_ref->{child},  # interface name
                      $arg_ref->{descr},
                      $arg_ref->{lastn},
                      $arg_ref->{stat},   # avg or total
                      $val,               # calculated value
                      $arg_ref->{state},  # above or below
                      $thr);              # threshold value
   }
   else {
      $msg = sprintf ("%s %s %s %s %s %s %s %s %s %s",
                      $time_str,
                      $arg_ref->{alias} || "",
                      $arg_ref->{device},
                      $dev_ip,
                      $arg_ref->{descr},
                      $arg_ref->{lastn},
                      $arg_ref->{stat},   # avg or total
                      $val,               # calculated value
                      $arg_ref->{state},  # above or below
                      $thr);              # threshold value
   }

   # Send the syslog message
   if ($dest_ip ne "") {
      syslog ({
         ipaddr   => $dest_ip,
         priority => $priority,
         facility => $facility,
         message  => $msg,
      });

      # Send message to 'alert' log for debugging purposes
      #errlog ($ERR_ALERT, "syslog $dest_ip $priority $facility $msg");
   }
}


30. Sync Device Name with sysName

This script renames all devices using the value from SNMPv2-MIB.sysName as returned by each device. It is run at the end of the discover/rewalk because its function name starts with "config_".

Download script
sub config_update_sysname
{
   my @domains = config_load_domains ();
   for my $line (adb_result ("mget text * sys SNMPv2-MIB.sysName")) {
      my @arr = split (" ", $line, 5);
      my $devname = $arr[0];
      my $sysname = $arr[4] || "";
      $sysname = config_strip_sysname ($sysname, @domains);
      if ($devname ne $sysname) {
         errlog ($ERR_DEBUG, "rename %s -> %s", $devname, $sysname);
         adb_send (sprintf ("rename device %s %s", $devname, $sysname));
      }
   }
   adb_flush ();
}

31. Threshold Alert Limiting

This is an example script to limit threshold alerts to 1 per day. The first alert per day gets sent immediately; additional alerts get discarded. The daily alert filter resets at 9am each day. Call this script from Threshold Alerting using the syntax call alert_threshold_daily

NOTE:

Download script
sub alert_threshold_daily
{
   my ($arg_ref) = @_;
   my $device = $arg_ref->{device};
   my $child  = $arg_ref->{child};
   my $attr   = $arg_ref->{attr};
   my $lastn  = $arg_ref->{lastn};
   my $stat   = $arg_ref->{stat};
   my $state  = $arg_ref->{state};
   my $thr    = $arg_ref->{thr};

   # Use this group to keep track of alerts
   my $group = sprintf ("script_threshold_%s_%s_%s_%s", $lastn, $stat, $state, $thr);

   # Create group if it doesn't exist
   adb_send (sprintf ("add threshold group %s", $group));

   if (adb_result (sprintf ("check %s %s %s = * * * * any group %s", $device, $child, $attr, $group)) eq "0") {

      # Record this alert in our group
      adb_send (sprintf ("assign * %s %s %s = %s", $device, $child, $attr, $group));

      # Call another site script function to generate an alert
      alert_mail_threshold ($arg_ref);
   }
   else {
      #errlog ($ERR_DEBUG, "Duplicate alert: %s %s %s", $device, $child, $attr);
   }
   adb_flush ();
}

sub sched_1h_threshold_daily_reset
{
   my $tm_ref = get_localtime ();

   # Run daily at 9am
   return if ($tm_ref->{hour} != 9);

   # Clear all threshold groups with names that begin with 'script_threshold_'
   errlog ($ERR_DEBUG, "Clearing script threshold groups");
   adb_send ('empty threshold group /^script_threshold_/');
}


32. Web API for Device Discovery

This example shows how to discover SNMP devices via the Web API.

  1. Install this script under Site Scripting
  2. Create Web API user
    Create a user called api-rw using the menu:
    Admin → Users/Profiles → User Settings
  3. Enable Web API Site Script Functions
    Go to the menu:
    Admin → API → Web API Settings
    and set the Site Script Functions option to on.
  4. Execute the script from another machine using Curl:

    curl -s "http://{ipaddress}/api-script?password={pwd};function=web_discover_device;ipaddr=10.91.0.12"

NOTE:

Refer to the API Reference Guide for examples of using Curl with AKIPS.

Download script
sub web_discover_device
{
   my @ipaddr     = cgi_param ('ipaddr');
   my $snmp_param = cgi_param ('snmp_param'); # optional
   my $discover_lock;

   return if (scalar @ipaddr == 0);

   # Get a lock on the discover
   $discover_lock = process_lock ($DISCOVER_LOCK, LOCK_EX)
      or EXIT_FATAL ("Failed to get a lock");

   if (discover_scan ($snmp_param, @ipaddr) > 0) {
      discover_config ();
   }

   process_unlock ($discover_lock);
}

33. Web API for Single Device Rewalk

This example shows how to rewalk a single SNMP device via the Web API.

  1. Install this script under Site Scripting
  2. Create Web API user
    Create a user called api-rw using the menu:
    Admin → Users/Profiles → User Settings
  3. Enable Web API Site Script Functions
    Go to the menu:
    Admin → API → Web API Settings
    and set the Site Script Functions option to on.
  4. Execute the script from another machine using Curl

    curl -s "http://{ipaddress}/api-script?password={pwd};function=web_rewalk_device;ipaddr=10.91.0.12"

    Note: You can provide either ipaddr={device ip address} or device={device name}.

Refer to the API Reference Guide for examples of using Curl with AKIPS.

Download script
sub web_rewalk_device
{
   my $device = cgi_param ('device');
   my $ipaddr = cgi_param ('ipaddr');
   my $discover_lock;

   # Get a lock on the discover
   $discover_lock = process_lock ($DISCOVER_LOCK, LOCK_EX)
      or EXIT_FATAL ("Failed to get a lock");

   discover_device_rewalk ({ device => $device, ipaddr => $ipaddr });

   process_unlock ($discover_lock);
}

34. Web API to Add/Delete Manual group

This example shows how to add/delete a manual group and assign/remove entity to/from a manual group via the Web API.

  1. Install this script under Site Scripting
  2. Create Web API user
    Create a user called api-rw using the menu:
    Admin → Users/Profiles → User Settings
  3. Enable Web API Site Script Functions
    Go to the menu:
    Admin → API → Web API Settings
    and set the Site Script Functions option to on.
  4. Execute the script from another machine using Curl

  5. Manual grouping type definitions:

    CPUs = processor

    Devices = device

    IPSLA = ipsla

    Interfaces = interface

    Memory = memory

    Netflow Exporters = flow

    Storage = storage

    Super Groups = super

    Temperature = temperature


    Example: type=device

    Example of creating a new group and adding a device to it.

    To add a manual group: curl -s "http://{server}/api-script?password={pwd};function=web_manual_grouping;type=device;group={group_name};mode=add"

    To assign an entity to a manual group: curl -s "http://{server}/api-script?password={pwd};function=web_manual_grouping;type=device;group={group_name};mode=assign;device={device_name}"


    Example of removing a entity from a group and deleting a group.

    To clear an entity from a manual group: curl -s "http://{server}/api-script?password={pwd};function=web_manual_grouping;type=device;group={group_name};mode=clear;device={device_name}"

    To delete a manual group: curl -s "http://{server}/api-script?password={pwd};function=web_manual_grouping;type=device;group={group_name};mode=delete"


    Example: type=interface

    Example of creating a new group and adding a interface to it.

    To add a manual group: curl -s "http://{server}/api-script?password={pwd};function=web_manual_grouping;type=interface;group={group_name};mode=add"

    To assign an entity to a manual group: curl -s "http://{server}/api-script?password={pwd};function=web_manual_grouping;type=interface;group={group_name};mode=assign;device={device_name};child={child_name}"


    Example of removing a entity from a group and deleting a group.

    To clear an entity from a manual group: curl -s "http://{server}/api-script?password={pwd};function=web_manual_grouping;type=interface;group={group_name};mode=clear;device={device_name};child={child_name}"

    To delete a manual group: curl -s "http://{server}/api-script?password={pwd};function=web_manual_grouping;type=interface;group={group_name};mode=delete"


    Example: type=super

    Example of creating a new super group and adding a group to it.

    To add a manual super group: curl -s "http://{server}/api-script?password={pwd};function=web_manual_grouping;type=super;group={super_group_name};mode=add"

    To assign group to a manual super group: curl -s "http://{server}/api-script?password={pwd};function=web_manual_grouping;type=group;group={group_name};mode=assign;device={group_name}"


    Example of removing a entity from a group and deleting a group.

    To clear group from a manual super group: curl -s "http://{server}/api-script?password={pwd};function=web_manual_grouping;type=group;group={group_name};mode=clear;device={group_name}"

    To delete a manual super group: curl -s "http://{server}/api-script?password={pwd};function=web_manual_grouping;type=super;group={super_group_name};mode=delete"


Refer to the API Reference Guide for more examples on manual group type.

Download script
sub web_manual_grouping
{
  my $type   = cgi_param ('type')   || "";
  my $group  = cgi_param ('group')  || "";
  my $mode   = cgi_param ('mode')   || "";
  my $device = cgi_param ('device') || "";
  my $child  = cgi_param ('child')  || "";
  my $entity;

  if ($type eq "") {
     errlog ($ERR_DEBUG, "type is missing");
     return;
  }
  elsif ($group eq "") {
     errlog ($ERR_DEBUG, "group is missing");
     return;
  }
  elsif ($mode eq "") {
     errlog ($ERR_DEBUG, "mode is missing");
     return;
  }

  if ($mode eq "assign" || $mode eq "clear") {
     if ($device ne "" && $child ne "") {
        $entity = $device." ".$child;
     }
     else {
        if ($device ne "") {
           $entity = $device;
        }
        else {
           errlog ($ERR_DEBUG, "device is missing");
           return;
        }
     }
  }

  group_manual_load_cfg ();

  given ($mode) {
     when ("add") {
        group_manual_add ($type, $group);
     }

     when ("assign") {
        group_manual_assign ($type, $entity, $group);
     }

     when ("clear") {
        group_manual_clear ($type, $entity, $group);
     }

     when ("delete") {
        group_manual_delete ($type, $group);
     }
  }

  group_manual_save_cfg ();
  adb_flush ();
}

35. Web API to delete Device[s]

This example shows how to delete device[s] via the Web API.

  1. Install this script under Site Scripting
  2. Create Web API user
    Create a user called api-rw using the menu:
    Admin → Users/Profiles → User Settings
  3. Enable Web API Site Script Functions
    Go to the menu:
    Admin → API → Web API Settings
    and set the Site Script Functions option to on.
  4. Execute the script from another machine using Curl

    curl -s "http://{server}/api-script?password=secret;function=web_delete_device;device_names=device_name1,device_name2,device_name3"

Refer to the API Reference Guide for examples of using Curl with AKIPS.

Download script
# Site script to delete device[s] 
sub web_delete_device
{
   my $device_names;
   my @device_to_be_deleted;

   $device_names = cgi_param ("device_names");
   @device_to_be_deleted = split(',', $device_names);

   if (scalar (@device_to_be_deleted) > 0 ) {
      config_delete_device (@device_to_be_deleted);
   }
}

36. Web API to rename single Device

This example shows how to rename a single device via the Web API.

  1. Install this script under Site Scripting
  2. Create Web API user
    Create a user called api-rw using the menu:
    Admin → Users/Profiles → User Settings
  3. Enable Web API Site Script Functions
    Go to the menu:
    Admin → API → Web API Settings
    and set the Site Script Functions option to on.
  4. Execute the script from another machine using Curl

    curl -s "http://{server}/api-script?password={password};function=web_rename_device;from_name={device_name};to_name={new_device_name}

Refer to the API Reference Guide for examples of using Curl with AKIPS.

Download script
sub web_rename_device
{
    my $from_name = cgi_param ('from_name');
    my $to_name = cgi_param ('to_name');

    # Run a built in script to rename devices
    config_rename_device ($from_name, $to_name);

    return;
}