#!/usr/bin/perl -w use strict; use Getopt::Long; my $full = 0; my $debug = 0; my $noheader = 0; my $help = 0; GetOptions('full' => \$full, debug =>\$debug, noheader => \$noheader, help => \$help); if ($help) { print "Assumes that it is running on the NetBackup master (or, at least,\n", "a SERVER for all media servers in the NetBackup environment) and\n", "queries each media server for its license keys, presenting the\n", "results as a CSV file.\n\n", "Options:\n", " --full, -f Display all hosts' license information, rather\n", " than only those with expiring/expired keys.\n", " --debug, -d Print detailed output for each host to STDERR.\n", " (It would be a Good Idea to redirect STDOUT and\n", " STDERR to different places.)\n", " --noheader, -n Do not include the header lines in CSV output.\n", " --help, -h Display this message.\n"; exit 0; } my $sudo = ''; if ($> != 0) { $sudo = "sudo "; die "You're not root and sudo(1) is not in your path!" unless (qx{which $sudo | grep -v '^Warning'} =~ m,^/,); } my ($host, @hosts, $line, @lines, $master, $key); my ($expstring, $expstate, $expdate, $time_left, $feature); chomp(@hosts = qx{$sudo /usr/openv/netbackup/bin/admincmd/bpstulist | awk '{ print \$3 }' | sort -u}); chomp($master = qx{$sudo /usr/openv/volmgr/bin/vmglob -get_gdbhost}); my $got_master = 0; foreach $host (@hosts) { $got_master = 1 if $host =~ m/^$master\$/; } push @hosts, $master unless ($got_master); #print STDOUT "hostname,NetBackup master,license key,status,expiration date\n" unless $noheader; print STDOUT "hostname,feature,key,type,install status,order number,date ordered,expiration date,comments\n" unless $noheader; foreach $host (@hosts) { print STDERR "Querying $host ... " if $debug; chomp(@lines = qx{$sudo /usr/openv/netbackup/bin/admincmd/bpminlicense -M $host -verbose}); print STDERR "got response." if $debug; undef $key; undef $expstring; undef $time_left; foreach $line (@lines) { if ($line =~ m/^[A-Z0-9]/) { if (defined($key) && ($full || $debug || defined($expstring))) { if ($debug) { print STDERR "\n $key", (defined($expstring)) ? " $expstring" : " does not expire"; print STDERR " ($time_left) " if defined($time_left); } # if ($full || defined($expstring)) { # print STDOUT "$host,$master,$key,", # (defined($expstate)) ? $expstate : "permanent", ",", # (defined($expdate)) ? $expdate : "never", "\n"; # } undef $key; undef $time_left; undef $expstring; undef $expstate; undef $expdate; } $key = (split(' ', $line))[0]; } elsif ($line =~ m/^ Expiration/) { $expstring = $line; $expstring =~ s,^ Expiration = ,,; $expstring =~ s,Expired,EXPIRED on,; $expstring =~ s,Not expired,expires on,; $expstate = substr($expstring, 0, 7); # Puts date in a format Excel thinks is a date: $expdate = substr($expstring, 19, 2) . "-" . substr($expstring, 15, 3) . '-' . substr($expstring, -4) . substr($expstring, -14, 9); $expdate =~ s,^ ,0,; } elsif ($line =~ m/^ Time Left/) { $time_left = $line; $time_left =~ s, Time Left = ,,; } elsif ($line =~ m/^ Feature ID/) { if ($full || defined($expstring)) { die "Yikes, formatting I don't know how to handle!" unless (defined($key)); $feature = $line; $feature =~ s, Feature ID = .. ,,; $feature =~ s, .$,,; print STDOUT "$host,$feature,$key,", (defined($expstate)) ? "Temporary," : "Permanent,", "Active, , ,", (defined($expdate)) ? $expdate : "never", ", \n"; } } } if ($debug) { print STDERR "\n $key", (defined($expstring)) ? " $expstring" : " does not expire"; print STDERR " ($time_left)" if defined($time_left); } # if ($full || defined($expstring)) { # print STDOUT "$host,$master,$key,", # (defined($expstate)) ? $expstate : "permanent", ",", # (defined($expdate)) ? $expdate : "never", "\n"; # } undef $key; undef $time_left; undef $expstring; undef $expstate; undef $expdate; print STDERR "\n" if $debug; }