Site scripts

Using 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

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. [email protected]

   # 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] });
      }
   }

}

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));
   }
}

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);
}

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);

}

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);
}

This script can be used to create a 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);
}

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));
   }
}

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 ();
}

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);
}

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:

  • This will ONLY work for a full Discover. A rewalk will not pick up any config changes because the device is not added as an SNMP-capable device.
  • The “Add SNMP Device” menu option will not work for iDRAC6 devices. These devices will be rejected because they do not support IF-MIB.
  • When you open the Dell iDRAC System Status report, iDRAC6 devices will not appear, due to the default sort being the “Server Model” column. You will need to pick a different column to sort on, e.g. “Device” or “Model”.

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 ();
   }
}

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:

  • IPv4 or IPv6 address
  • SNMP Parameters (same format as Discover/Rewalk Settings)
  • (Optional) Hostname
  •  

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);
}

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});
   }
}

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. [email protected]
   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 });
      }
   }
}

This is a basic example which shows:

  • How to access parameters passed through from Status Alerting.
  • How to retrieve the IP address of a device from ADB (AKIPS database).
  • How to retrieve sysContact and sysLocation of a device from ADB.
  • How to create and send an email to a single address.
  • How to create and send an email to a profile.

NOTE: This example script:

  • Does not implement any alert bundling.
  • Will generate an email message for every alert passed in from Status Alerting.

Download script

sub alert_mail_status
{
   my ($arg_ref) = @_;
   my $mail_to = ''; # e.g. [email protected]
   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 });
      }
   }
}

This is a basic example which shows:

  • How to access parameters passed through from Syslog Alerting.
  • How to retrieve sysContact and sysLocation of a device from ADB.
  • How to create and send an email to a single address.
  • How to create and send an email to a profile.

NOTE: This example script:

  • Does not implement any alert bundling.
  • Will generate an email message for every alert passed in from Syslog Alerting.
  • The priority and facility parameters are only available in v20.1 or later.

Download script

sub alert_mail_syslog
{
   my ($arg_ref) = @_;
   my $mail_to = ''; # e.g. [email protected]
   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 });
      }
   }
}

This is a basic example which shows:

  • How to access parameters passed through from Threshold Alerting.
  • How to retrieve the IP address of a device from ADB (AKIPS database).
  • How to apply formatting to interface thresholds.
  • How to create and send an email to a single address.
  • How to create and send an email to a profile.

NOTE: This example script:

  • Does not implement any alert bundling.
  • Will generate an email message for every alert passed in from Threshold Alerting.

Download script

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

   # Modify the following parameters
   my $mail_to = ''; # e.g. [email protected]
   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 });
      }
   }
}

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);
}

This script creates a CSV file containing the same information as Reports → Device → Chassis.

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);
}

This script creates a CSV file containing the same information as Reports → Device → Summary, 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);
}

This script creates a CSV file containing the same information as Reports → Device → Summary.

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);
}

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. [email protected]
   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));
   }
}

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:

  • Device name
  • IPv4 address (may be blank if a IPv6 address is defined)
  • IPv6 address (may be blank if a IPv4 address is defined)
  • Description (may be blank)
  • Location (may be blank)
  • Contact (may be blank)

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 ();
}

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 ();
}

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 ();
}

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

  • The devices are sorted by date added.
  • Each device name has a link to the Device Editor.

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";
   }
}

This is a basic example which shows:

  • How to access parameters passed through from Threshold Alerting.
  • How to retrieve the IP address of a device from ADB (AKIPS database).
  • How to apply formatting to interface thresholds.
  • Make RESTful API calls to a server.

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",
   });
}

This is a basic example which shows:

  • How to access parameters passed through from Status Alerting.
  • How to retrieve the IP address of a device from ADB (AKIPS database).
  • How to create and send a syslog message.

The priority parameter must be one of the following:

  • emergency
  • alert
  • critical
  • error
  • warning
  • notice
  • info
  • debug

The facility parameter must be one of the following:

  • auth
  • authpriv
  • console
  • cron
  • daemon
  • ftp
  • kern
  • lpr
  • mail
  • news
  • ntp
  • security
  • syslog
  • user
  • uucp
  • local0
  • local1
  • local2
  • local3
  • local4
  • local5
  • local6
  • local7

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");
   }
}

This is a basic example which shows:

  • How to access parameters passed through from Threshold Alerting.
  • How to retrieve the IP address of a device from ADB (AKIPS database).
  • How to create and send a syslog message.

The priority parameter must be one of the following:

  • emergency
  • alert
  • critical
  • error
  • warning
  • notice
  • info
  • debug

The facility parameter must be one of the following:

  • auth
  • authpriv
  • console
  • cron
  • daemon
  • ftp
  • kern
  • lpr
  • mail
  • news
  • ntp
  • security
  • syslog
  • user
  • uucp
  • local0
  • local1
  • local2
  • local3
  • local4
  • local5
  • local6
  • local7

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");
   }
}

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 ();
}

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:

  • To use this script as-is, you will need to include the Email Threshold Alert script in your Site Scripting config.
  • If you want a daily summary of alerts, use Scheduled Reports.

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_/');
}

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:

  • You can provide multiple IP address parameters separated by semicolons, e.g. ipaddr=10.91.0.12;ipaddr=10.91.0.13;ipaddr=10.91.0.14
  • You can discover a subnet using the appropriate syntax, e.g. ipaddr=10.91.3.0/24
  • You can provide SNMP parameters using snmp_param={string}, e.g. snmp_param=version+2+community+public.
    If you don’t include the snmp_param option, AKIPS will probe the device using the SNMP Parameters defined under:
    Admin → Discover → Discover/Rewalk menu.

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);
}

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 Curlcurl -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);
}

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 ();
}

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 Curlcurl -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);
   }
}

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 Curlcurl -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;
}