#!/usr/bin/perl # # use strict; use warnings; use LWP::Simple; use JSON qw( decode_json ); use MIME::Lite; use Data::Dumper; # read in configuration file and setup variables for use in this program do 'xtremio_report.conf'; our %xtremios; our %vmclusters; our %query; our %query_hdr; our %query_detail; our %filename; our $account; our $password; our $remediate; our $summary; our $l2_mail; our $l3_mail; our $sharepoint_mail; our $l2_subject; our $l3_subject; our $sharepoint_subject; my $url = ""; my $json = ""; my $decode_json = ""; my $summary_line = ""; my $used = 0; my $total = 0; $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0; sub convert_to_2_dec_places { my $val = shift; my $tmpval = 0; $tmpval = sprintf "%.2f", $val; $val = $tmpval; return $val; } sub calc_percentage { my $used = shift; my $total = shift; my $val = 0; if ( $total eq 0 ) { return 0; } $val = convert_to_2_dec_places( $used / $total * 100 ); return $val; } sub alter_value_for_display { my $tag = shift; my $val = shift; my $tmpval = 0; # convert to human readable time if ( $tag =~ m/timestamp/ ) { $tmpval = localtime($val); $val = $tmpval } # convert to TB if ( ( $tag =~ m/vol-size/ ) || ( $tag =~ m/logical-space-in-use/ ) || ( $tag =~ m/acc-size-of-wr/ ) || ( $tag =~ m/acc-size-of-rd/ ) ) { $tmpval = $val / (1024 * 1024 * 1024); $val = convert_to_2_dec_places ( $tmpval ); } # convert free % to used % if ( $tag =~ m/free-ud-ssd-space-in-percent/ ) { $tmpval = 100 - $val; $val = $tmpval; } # reduce to 2 decimal places if ( $tag =~ m/thin-provisioning-ratio/ ) { $val = convert_to_2_dec_places ( $val ); } return $val; } sub check_for_exception { my $tag = shift; my $val = shift; my $line = shift; my $str = ""; # alert if cluster doesn't show healthy state if ( $tag =~ m/sys-health-state/ ) { if ( $val !~ m/^healthy$/ ) { $str = "*** Cluster showing not healthy "; } } # alert if xms server is not connected if ( $tag =~ m/sys-mgr-conn-state/ ) { if ( $val !~ m/^connected$/ ) { $str = "*** Manager not connected "; } } # alert if total usage is greater than 90% if ( $tag =~ m/wr-bw-gt1mb/ ) { if ( $val > 90 ) { $str = "*** Total usage is greater than 90% "; } } # alert if physical usage is greater than 90% if ( $tag =~ m/free-ud-ssd-space-in-percent/ ) { if ( $val > 90 ) { $str = "*** Physical usage is greater than 90% "; } } # alert if iscsi ports not at 10Gb if ( $tag =~ m/iscsi-port-speed/ ) { if ( $val !~ m/^10Gb$/ ) { $str = "*** iscsi port(s) not at 10Gb "; } } # alert if storage controller not healthy if ( $tag =~ m/node-health-state/ ) { if ( $val !~ m/^healthy$/ ) { $str = "*** SC showing not healthy "; } } # alert if ipmi state shows connected if ( $tag =~ m/ipmi-conn-state/ ) { if ( $val !~ m/^unknown$/ ) { $str = "*** IPMI state showing connected "; } } # alert if target is iscsi and mtu is incorrect or if jumbo frames not enabled if ( $line =~ m/,iscsi,/ ) { if ( $tag =~ m/mtu/ ) { if ( $val !~ m/^8800$/ ) { $str = "*** MTU incorect "; } } if ( $tag =~ m/jumbo-enabled/ ) { if ( $val !~ m/^true$/i ) { $str = $str . "*** Jumbo frames not enabled "; } } } # certainty indicates that the XMS and XBrick may be out of sync if ( $tag =~ m/certainty/ ) { if ( $val !~ m/^ok$/ ) { $str = "*** XMS server and XBrick may be having sync issues "; } } # alert if number of connected targets is less than 4 if ( $tag =~ m/num-of-conn-tars/ ) { if ( $val < 4 ) { $str = "*** Number of connected targets is less than 4 "; } } # warn if individual volume usage greater than 90% if ( $tag =~ m/small-rd-bw/ ) { if ( $val > 90 ) { $str = "*** Volume usage is greater than 90% "; } } # alert if SSD/Disk not healthy if ( $tag =~ m/health-state/ ) { if ( $val !~ m/^healthy$/ ) { $str = "*** SSD showing not healthy "; } } # alert if data protection group not healthy if ( $tag =~ m/rg-ud-ssd-space-levels/ ) { if ( $val !~ m/^healthy$/ ) { $str = "*** DPG showing not healthy "; } } # alert if data protection group has rebuild prevention set if ( $tag =~ m/rebuild-prevention-reason/ ) { if ( $val !~ m/^none$/ ) { $str = "*** DPG showing with rebuild prevention "; } } return $str; } sub print_summary_hdr { my $str = ""; $str = sprintf "%-18s%-18s%-18s%-15s%-15s%-15s%10s%10s%10s %-15s", "XMS","VM","Name","SW Version","Dedup", "Compression","Vol Size", "Vol Used", "Usage %", "System State"; return $str; } sub print_summary_dtl { my $tag = shift; my $val = shift; my $str = ""; if ( $tag =~ m/^xms$/ ) { $str = sprintf "%-18s", $val; } if ( $tag =~ m/^vmcluster$/ ) { $str = sprintf "%-18s", $val; } if ( $tag =~ m/^name$/ ) { $str = sprintf "%-18s", $val; } if ( $tag =~ m/^sys-sw-version$/ ) { $str = sprintf "%-15s", $val; } if ( $tag =~ m/^dedup-ratio-text$/ ) { $str = sprintf "%-15s", $val; } if ( $tag =~ m/^compression-factor-text$/ ) { $str = sprintf "%-15s", $val; } if ( $tag =~ m/^vol-size$/ ) { $str = sprintf "%10.2f", $val; } if ( $tag =~ m/^logical-space-in-use$/ ) { $str = sprintf "%10.2f", $val; } if ( $tag =~ m/^wr-bw-gt1mb$/ ) { $str = sprintf "%10.2f", $val; } if ( $tag =~ m/^sys-health-state$/ ) { $str = sprintf " %-15s", $val; } return $str; } sub send_mail { my $to = shift; my $subject = shift; my $message_file = shift; my $files_ref = shift; # populate message detail my $message = do { local $/ = undef; open MSG, "<", $message_file or die "Unable to open $message_file $!\n"; ; }; close (MSG); my $msg = MIME::Lite->new( From => 'root@fdcctibkpindex01d.eur.nsroot.net', To => $to, Subject => $subject, Type => 'multipart/mixed' ); $msg->attach( Type => 'text/plain', Data => $message ); for my $file ( @$files_ref ) { $msg->attach( Type => 'image/gif', Path => $file, Filename => $file, Disposition => 'attachment' ); } $msg->send; return $msg->last_send_successful; } open ( REMEDIATE, ">", $remediate ) or die "Unable to open $remediate $!\n"; open ( SUMMARY, ">", $summary ) or die "Unable to open $summary $!\n"; $summary_line = print_summary_hdr; print SUMMARY "$summary_line\n"; foreach my $qtag ( sort keys %query ) { my $filename = $filename{$qtag}; open ( FILE, ">", $filename ) or die "Unable to open file $filename $!\n"; print REMEDIATE "$filename\n"; foreach my $region ( keys %xtremios ) { # print region print FILE "$region\n"; # print headings for my $hdr ( 0..$#{ $query_hdr{$qtag} } ) { print FILE "$query_hdr{$qtag}[$hdr],"; } print FILE "\n"; for my $i ( 0..$#{ $xtremios{$region} } ) { #print FILE "$xtremios{$region}[$i],"; my $xtremio = $xtremios{$region}[$i]; $url = "https://$account:$password\@$xtremio$query{$qtag}"; $json = get( $url ) or die "Could not open url $url"; $decode_json = decode_json( $json ); foreach my $j ( @{ $decode_json->{$qtag} } ) { my @urlbrk = split /\//,$j->{href}; splice(@urlbrk,0,3); my $parturl = join '/', @urlbrk; $url = "https://$account:$password\@$xtremio/$parturl"; $json = get( $url ) or die "Could not open url $url"; $decode_json = decode_json( $json ); # print detail/values my $line = ""; my $exception = ""; $summary_line = ""; my $xms_server = $xtremios{$region}[$i]; $xms_server =~ /(.*)\.(.*)\.(.*)\.(.*)/; $xms_server = $1; $line = "$xms_server,"; $line = $line . "$vmclusters{$xms_server},"; # if processing cluster output, then populate summary page if ( $filename =~ m/clusterinfo.csv/ ) { $summary_line = print_summary_dtl ( 'xms', $xms_server ); my $summary_dtl = print_summary_dtl ( 'vmcluster', $vmclusters{$xms_server} ); $summary_line = $summary_line . $summary_dtl; } for my $dtl ( 0..$#{ $query_detail{$qtag} } ) { my $val = $decode_json->{content}{$query_detail{$qtag}[$dtl]}; my $tag = $query_detail{$qtag}[$dtl]; $val = alter_value_for_display ($tag, $val); # save used and total amounts to calc total and volume percentages if ( $tag =~ m/vol-size/ ) { $total = $val; } if ( $tag =~ m/logical-space-in-use/ ) { $used = $val; } if ( ( $tag =~ m/wr-bw-gt1mb/ ) || ( $tag =~ m/small-rd-bw/ ) ) { $val = calc_percentage ( $used, $total ); } $line = $line . "$val,"; # look for exceptions and flag them $exception = check_for_exception ($tag, $val, $line); # if processing cluster output, then populate summary page if ( $filename =~ m/clusterinfo.csv/ ) { my $summary_dtl = print_summary_dtl ( $tag, $val ); if ( length($summary_dtl) != 0 ) { $summary_line = $summary_line . $summary_dtl; } } } # print the detail line to the appropriate files print FILE "$line\n"; # print exception to remediate if it exists if ( $exception =~ m/^\*\*\*/ ) { print REMEDIATE $line . $exception . "\n"; } # print summary information if populated if ( length($summary_line) != 0 ) { print SUMMARY "$summary_line\n"; } } } } close (FILE); } close ( REMEDIATE ); close ( SUMMARY ); # build up mail attachments my @files = qw ( summary.txt ); foreach my $file ( sort values %filename ) { push @files, $file; } # send to L2 my $return = send_mail ($l2_mail, $l2_subject, $remediate ,\@files); if ( ! $return ) { print "Mail send failed to $l2_mail\n"; } # send to L3 $return = send_mail ($l3_mail, $l3_subject, $remediate ,\@files); if ( ! $return ) { print "Mail send failed to $l3_mail\n"; } # send to Emerging Technology Sharepoint site $return = send_mail ($sharepoint_mail, $sharepoint_subject, $remediate ,\@files); if ( ! $return ) { print "Mail send failed to $sharepoint_mail\n"; }