Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added option --list health to report missing VLAN results from dvSwitch Health Check #40

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 134 additions & 8 deletions perl/getdvSwitchInfo.pl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/perl -w
# Author: William Lam
# Author: William Lam; Tim Lapawa
# Website: www.virtuallyghetto.com
# Reference: http://www.virtuallyghetto.com/2011/12/retrieving-information-from-distributed.html

Expand All @@ -12,7 +12,7 @@
my %opts = (
'list' => {
type => "=s",
help => "Operation [all|summary|config|networkpool|portgroup|host|vm]",
help => "Operation [all|summary|config|networkpool|portgroup|host|vm|health]",
required => 1,
},
'dvswitch' => {
Expand All @@ -27,21 +27,34 @@
# validate options, and connect to the server
Opts::parse();
Opts::validate();
Util::connect();
my $vim = Util::connect();

my $list = Opts::get_option('list');
my $dvswitch = Opts::get_option('dvswitch');
my $dvSwitches;
my $apiVersion = Vim::get_service_content()->about->version;
my $sc = $vim->get_service_content();
my $apiVersion = $sc->about->version;

print ("vCenterServer: ".color("yellow"). $vim->{service_url}. color('reset').' - '. color('yellow'). $sc->about->fullName . color("reset"). "\n");

my $dvSwitchProperties = {};
if ($list eq 'health') {
$dvSwitchProperties = [ 'name', 'runtime', 'config.host', 'config.healthCheckConfig' ];
}

if($dvswitch) {
$dvSwitches = Vim::find_entity_views(view_type => 'DistributedVirtualSwitch', filter => {'name' => $dvswitch});
$dvSwitches = Vim::find_entity_views(view_type => 'DistributedVirtualSwitch'
, filter => {'name' => $dvswitch}
, properties => $dvSwitchProperties
);
} else {
$dvSwitches = Vim::find_entity_views(view_type => 'DistributedVirtualSwitch');
$dvSwitches = Vim::find_entity_views(view_type => 'DistributedVirtualSwitch'
, properties => $dvSwitchProperties
);
}

foreach my $dvs (sort{$a->name cmp $b->name} @$dvSwitches) {
print color("yellow") . $dvs->name . "\n" . color("reset");
print 'dvSwitch: '.color("yellow") . $dvs->name . "\n" . color("reset");
if($list eq "all" || $list eq "summary") {
print "UUID: " . color("cyan") . $dvs->summary->uuid . "\n" . color("reset");
print "Description: " . color("cyan") . ($dvs->summary->description ? $dvs->summary->description : "N/A") . "\n" . color("reset");
Expand Down Expand Up @@ -289,9 +302,122 @@
}
};
if($@) {
print "ERROR: Unable to query for entites connected to dvSwitch " . $@ . "\n";
print "ERROR: Unable to query for entities connected to dvSwitch " . $@ . "\n";
}
}
if($list eq "all" || $list eq "health") {
# * dvSwitch->runtime->hostMemberRuntime[]
# - lists all hosts of dvSwitch
# *
my $hostMemberRuntimeInfo = $dvs->{runtime}->{hostMemberRuntime};
my %r = ();
# print " Check NIC Infos for host: \t'".$host->name."'\n\n";
format STDOUT =
@<<<<<<<<<<<<<<<<<<<<<<<<<<< |@<<<<<< |@<<<<<<<<<<<<<<<<<<<<<<<<<... |@<<<<<<<<<<<<<<< |@<<<<<<<<<<<<<<<<<< |@*
$r{host}, $r{pnic}, $r{switch}, $r{address}, $r{port}, $r{missingvlans}
.
my $foundHealthCheckResults = undef;
foreach my $hostMember (@{$hostMemberRuntimeInfo}) {
if ( exists $hostMember->{healthCheckResult}) {

my $hostRef = $hostMember->{host};
my $hostView = Vim::get_view( mo_ref => $hostRef, properties => [ 'name', 'configManager'] );

if ($hostMember->status ne 'up') {
print ("\n".$hostView->name.color("red") . 'DOWN'.color('reset'));
next;
}

if ($hostView->name eq 'ffm30vmwzst0112.mhs.msys.net') {
print 'found it';
}


my $netMgr = undef;
my $checkResults = $hostMember->{healthCheckResult};
foreach my $checkResult (@{$checkResults}){
if ( ref($checkResult) eq 'VMwareDVSVlanHealthCheckResult') {
%r = (
host => $hostView->name,
pnic => '',
switch => '',
address => '',
port => '',
missingvlans => '',
);

# find physical uplink for DVS uplinkPort
# dvs-83&doPath=config.host
#
my $dvsHostMembers = $dvs->{'config.host'};
$netMgr ||= Vim::get_view(mo_ref => $hostView->configManager->networkSystem);
foreach my $member (@{$dvsHostMembers}){
my $dvsConfigHostrefValue = $member->{config}->{host}->{value};
if ($hostRef->{value} eq $dvsConfigHostrefValue) {
my $pnicSpecs = $member->{config}->{backing}->{pnicSpec};
foreach my $pnic (@{$pnicSpecs}){
if ($pnic->{uplinkPortKey} eq $checkResult->{uplinkPortKey}) {
$r{pnic} = $pnic->{pnicDevice};
}
}
}
}

#
# find CDP infos for pnic and host
#
my @physicalNicHintInfo = $netMgr->QueryNetworkHint();
foreach (@physicalNicHintInfo) {
foreach ( @{$_} ) {
next if ($r{pnic} ne $_->device); # skip wrong device
if(defined($_->connectedSwitchPort)) {
$r{switch} = $_->connectedSwitchPort->devId;
$r{address} = $_->connectedSwitchPort->address;
$r{port} = $_->connectedSwitchPort->portId;
}
}
}
my $untrunkedVlans = $checkResult->{untrunkedVlan};
my %missingVlans = ();
foreach my $untrunkedVlan (@{$untrunkedVlans}){
my $start = int($untrunkedVlan->{start});
my $end = int($untrunkedVlan->{end});
if ( $start eq $end ) {
$missingVlans{$start} = 1;
} else {
for (my $i = $start; $i <= $end; $i++){
$missingVlans{$i} = 1;
}
}
}
my @sorted = sort {$a <=> $b} keys %missingVlans;;
$r{missingvlans} = join (',', @sorted);
if (!$foundHealthCheckResults) {

print " Host | pnic | switch | address | port | missing VLANs \n";
print " -----------------------------+--------+------------------------------+-----------------+--------------------+------------------------\n";
}
$foundHealthCheckResults ||= $hostMember;
write;
} # foreach VMwareDVSVlanHealthCheckResult
} # foreach healthCheckResult
} # if healthCheckResult
} # foreach $hostMemberRuntimeInfo

if ( ! $foundHealthCheckResults ) {
my $checkConfigs = $dvs->{'config.healthCheckConfig'};
if ( lc ($checkConfigs->[0]->{'enable'}) ) {
print '** Could not find any DVSwitch Health check results.'.color('red').' Please reconfigure health check to get new results.'.color('reset');
} else {
print '** DVSwitch Health check is deactivated. '.color('red').'Please enable and rerun script to collect results.'.color('reset');
}
}
print "\n";
} # if --list all|health
} # foreach @$dvSwitches
if (!scalar @{ $dvSwitches}) {
print "WARN: Could not find dvSwitch: '".$dvswitch."' with service url '".$vim->{service_url}."'. DONE!";
}


Util::disconnect();
46 changes: 42 additions & 4 deletions perl/sessionManagement.pl
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,24 @@
my %opts = (
'operation' => {
type => "=s",
help => "Operation [list|disconnect]",
help => "Operation [list|disconnect|terminateidle]",
required => 1,
},
'sessionkey' => {
'sessionkey' => {
type => "=s",
help => "Session key to disconnect",
required => 0,
},
'idle_hours' =>{
type => "=i",
help => "Select session to terminate if they are idle for N hours. Defaults to 36.",
required => 0,
},
'dry' => {
type => "",
help => "Enable dry run. Inspect but skip real actions.",
required => 0,
},
);
# validate options, and connect to the server
Opts::add_options(%opts);
Expand All @@ -31,11 +41,17 @@

my $operation = Opts::get_option ('operation');
my $sessionkey = Opts::get_option ('sessionkey');
my $opt_idle_hours = Opts::get_option( 'idle_hours');
my $opt_dry = Opts::get_option('dry');

my $sessionMgr = Vim::get_view(mo_ref => Vim::get_service_content()->sessionManager);
my $sc = Vim::get_service_content();
my $sessionMgr = Vim::get_view(mo_ref => $sc->sessionManager);
my $sessionList = eval {$sessionMgr->sessionList || []};
my $currentSessionkey = $sessionMgr->currentSession->key;

print 'Connected to vCenter Server: '. $sessionMgr->{vim}->{service_url}."\n";
print 'Checking #'. scalar @$sessionList . " user sessions.\n";

if($operation eq "list") {
foreach my $session (@$sessionList) {
if($session->key eq $currentSessionkey) {
Expand All @@ -50,13 +66,35 @@
print "Sessionkey : " . $session->key . "\n\n";
}
} elsif($operation eq "disconnect") {
Opts::assert_usage( defined $sessionkey ,"Operation 'disconnect' expects option '--sessionkey <session>'." );
print "Disconnecting sessionkey: " . $sessionkey . " ...\n";
eval {
$sessionMgr->TerminateSession(sessionId => [$sessionkey]);
unless ($opt_dry) {$sessionMgr->TerminateSession(sessionId => [$sessionkey]);}
};
if($@) {
print "Error: " . $@ . "\n";
}
} elsif ( $operation eq 'terminateidle' ){
my $max_idletime = abs ($opt_idle_hours || 36);

my $now = time;
foreach my $session (@$sessionList) {
if($session->key eq $currentSessionkey) {
print "Username: " . $session->userName . " (CURRENT SESSION) SKIP!\n";
next;
}

my $idletime = (time - str2time($session->lastActiveTime))/3600;
if ( $idletime > $max_idletime) {
print "Terminating user Session ". $session->userName;
eval {
unless ($opt_dry) {$sessionMgr->TerminateSession(sessionId => [$session->key]);}
};
if($@) {
print "Error: " . $@ . "\n";
}
} # if limit reached
} # foreach session
} else {
print "Invalid operation!\n";
}
Expand Down