From 482c8667d3bdce2e044376b8520b8b8851a14651 Mon Sep 17 00:00:00 2001 From: Clayton Dukes Date: Wed, 8 Nov 2017 12:24:54 -0500 Subject: [PATCH] Added sample for getting Cisco device interface description and posting to slack --- automations/cisco-interface-UpDown/README.md | 38 ++++ .../cisco-intUpDown-to-slack | 184 ++++++++++++++++++ 2 files changed, 222 insertions(+) create mode 100644 automations/cisco-interface-UpDown/README.md create mode 100644 automations/cisco-interface-UpDown/cisco-intUpDown-to-slack diff --git a/automations/cisco-interface-UpDown/README.md b/automations/cisco-interface-UpDown/README.md new file mode 100644 index 0000000..52dc064 --- /dev/null +++ b/automations/cisco-interface-UpDown/README.md @@ -0,0 +1,38 @@ +# Cisco Interface Up/Down to Slack +- Match on `LINK-3-UPDOWN` +- SSH to device and get the interface Description +- Reports results to Slack channel + - Interface Down will come into slack as Red + - Interface Up as green + + +# Log Sample +``` +%LINK-3-UPDOWN: Interface GigabitEthernet1/0/10, changed state to down +``` + + +# Script Type: Perl + +``` +#----------------------------------------------------------------------------- +# BEGIN: REQUIRED PACKAGES/MODULES +#----------------------------------------------------------------------------- + +# Ubuntu: +# apt install libnet-ssh2-perl libcrypt-ssleay-perl cpanminus +# +# PERL: +# cpanm Net::SSH2::Cisco HTTP::Request::Common LWP::UserAgent JSON + +#----------------------------------------------------------------------------- +# END: REQUIRED PACKAGES/MODULES +#----------------------------------------------------------------------------- +``` + +# Slack Webhook +You will need to obtain your webhook URL from the slack admin interface + +Once you have that, modify the script and set the correct webhook url: + + my $posturl = https://hooks.slack.com/services/STRING/STRING/STRING'; diff --git a/automations/cisco-interface-UpDown/cisco-intUpDown-to-slack b/automations/cisco-interface-UpDown/cisco-intUpDown-to-slack new file mode 100644 index 0000000..7d9b698 --- /dev/null +++ b/automations/cisco-interface-UpDown/cisco-intUpDown-to-slack @@ -0,0 +1,184 @@ +#!/usr/bin/env perl + +#----------------------------------------------------------------------------- +# BEGIN: REQUIRED PACKAGES/MODULES +#----------------------------------------------------------------------------- + +# Ubuntu: +# apt install libnet-ssh2-perl libcrypt-ssleay-perl cpanminus +# +# PERL: +# cpanm Net::SSH2::Cisco HTTP::Request::Common LWP::UserAgent JSON + +#----------------------------------------------------------------------------- +# END: REQUIRED PACKAGES/MODULES +#----------------------------------------------------------------------------- + +use Net::SSH2::Cisco; +use HTTP::Request::Common qw(POST); +use LWP::UserAgent; +use JSON; +use File::Basename; + +#----------------------------------------------------------------------------- +# LogZilla (>5.70.3) passes the following environment variables: +#----------------------------------------------------------------------------- +# EVENT_CISCO_MNEMONIC = +# EVENT_COUNTER = +# EVENT_FACILITY = +# EVENT_FIRST_OCCURRENCE = +# EVENT_HOST = +# EVENT_ID = +# EVENT_LAST_OCCURRENCE = +# EVENT_MESSAGE = +# EVENT_PROGRAM = +# EVENT_SEVERITY = +# EVENT_STATUS = +# EVENT_TRIGGER_AUTHOR = +# EVENT_TRIGGER_AUTHOR_EMAIL = +# EVENT_TRIGGER_ID = +# EVENT_USER_TAGS = +# TRIGGER_HITS_COUNT = + + +#----------------------------------------------------------------------------- +# DEBUG Testing, disable in production +# This will dump all info to /tmp/$0.log +# ($0 is the name of this script) +#----------------------------------------------------------------------------- + +#------------ +# If you want to test from the command line +# set $cmdLineDebug = 1 +# This way, you don't have to specifically generate events to LogZilla +#------------ +my $cmdLineDebug = 0; +if ( $cmdLineDebug > 0 ) { + $ENV{'EVENT_CISCO_MNEMONIC'} = 'LINK-3-UPDOWN'; + $ENV{'EVENT_COUNTER'} = '2'; + $ENV{'EVENT_FACILITY'} = '23'; + $ENV{'EVENT_FIRST_OCCURRENCE'} = '1510154564.41'; + $ENV{'EVENT_HOST'} = '192.168.28.254'; + $ENV{'EVENT_ID'} = '1583511832100864'; + $ENV{'EVENT_LAST_OCCURRENCE'} = '1510154775.25'; + $ENV{'EVENT_MESSAGE'} = '%LINK-3-UPDOWN: Interface GigabitEthernet1/0/10, changed state to down'; + $ENV{'EVENT_PROGRAM'} = 'Cisco'; + $ENV{'EVENT_SEVERITY'} = '3'; + $ENV{'EVENT_STATUS'} = '0'; + $ENV{'EVENT_TRIGGER_AUTHOR'} = 'admin'; + $ENV{'EVENT_TRIGGER_AUTHOR_EMAIL'} = 'admin_user@localhost'; + $ENV{'EVENT_TRIGGER_ID'} = '449'; + $ENV{'EVENT_USER_TAGS'} = ''; + $ENV{'TRIGGER_HITS_COUNT'} = '1'; +} +my $debug = 0; +my $msg; +my $filename = "/tmp/" . basename("$0.log"); +foreach my $key (sort keys(%ENV)) { + next if $key !~ /^EVENT|^TRIGGER/; + $msg .= "$key = $ENV{$key}\n"; +} +open(my $fh, '>>', $filename) or die "Could not open file '$filename' $!" if $debug > 0; +chmod 0666, $filename if $debug > 0; +print $fh "$msg\n" if $debug > 0; +#----------------------------------------------------------------------------- +# END DEBUG Testing, disable in production +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# BEGIN: Set Device Login and Slack Webhook URL +#----------------------------------------------------------------------------- +my $ciscoUsername = "cisco"; +my $ciscoPassword = "cisco"; +my $posturl = 'https://hooks.slack.com/services/XXX/XXX/XXX'; +#----------------------------------------------------------------------------- +# BEGIN: Set your device login name/password +#----------------------------------------------------------------------------- + + +printf $fh "Connecting to %s\n", $ENV{'EVENT_HOST'} if $debug > 0; + +my $session = Net::SSH2::Cisco->new(host => $ENV{'EVENT_HOST'}); +$session->login($ciscoUsername, $ciscoPassword); + +# Extract the config for the offending interface +my ($interface, $intState) = ($1,$2) if $ENV{'EVENT_MESSAGE'} =~ /Interface (\S+), changed state to (\S+)/; +if ( $interface =~ //) { + open(my $fd, ">>/var/log/logzilla/logzilla.log"); + print $fd "ERROR: $0 - unable to obtain interface name from $ENV{'EVENT_MESSAGE'}"; + exit; +} +my @desc = $session->cmd("sh run interface $interface | inc desc"); +my $intDesc = $desc[0]; +chomp($intDesc); +$intDesc =~ s/description (.+)/$1/gi; +$intDesc =~ s/^\s+//g; + +print $fh "\n--CMD Output:\nsh run interface $interface | include description:\n$intDesc\n---\n" if $debug > 0; + +#----------------------------------------------------------------------------- +# Post to Slack +#----------------------------------------------------------------------------- +my $default_channel = '#datacenter'; +my $slack_user = 'logzilla-staging'; +my $mnemonic = $ENV{'EVENT_CISCO_MNEMONIC'}; + +my ($color, $pretext); +if ($intState eq "down") { + $color = '#9C1A22'; + $pretext = "ERROR: Interface $intState on $ENV{'EVENT_HOST'}"; +} else { + $color = '#008000'; + $pretext = "RECOVERED: Interface $intState on $ENV{'EVENT_HOST'}"; +} +my $payload = { + username => $slack_user, + channel => $default_channel, + icon_url => "http://www.logzilla.net/images/logo_orange_png_cropped_40x40.png", + attachments => [{ + fallback => "Interface Description: $intDesc", + title => "Interface Description: $intDesc", + color => "$color", + pretext => "$pretext", + author_name => "$ENV{'EVENT_TRIGGER_AUTHOR'}", + author_link => "mailto:$ENV{'EVENT_TRIGGER_AUTHOR_EMAIL'}", + author_icon => "http://www.logzilla.net/images/log_file_icon_25x25.png", + fields => [{ + title => 'Program', + value => "$ENV{'EVENT_PROGRAM'}", + short => 'true', + }, { + title => 'Severity', + value => "$ENV{'EVENT_SEVERITY'}", + short => 'true', + }, { + title => "URL Reference", + value => "", + short => 'true', + }], + mrkdwn_in => ["text", "fields"], + text => "```$ENV{'EVENT_MESSAGE'}```", + thumb_url => "http://www.logzilla.net/images/icon_warning_25x25.png", + }] +}; + +my $ua = LWP::UserAgent->new( + ssl_opts => { verify_hostname => 0 }, +); +$ua->timeout(5); + +my $req = POST("${posturl}", ['payload' => encode_json($payload)]); +print $fh encode_json($payload) if $debug > 0; + + +my $resp = $ua->request($req); + +if ($resp->is_success) { + #print $resp->decoded_content; +} +else { + die $resp->status_line; +} + +close $fh if $debug > 0; +$session->close;