So I cleaned up your script a bit, mostly just optimizations. I used the built in Opts:: module to add a hostname parameter to the script instead of using ARGV. I changed it so it checks for a ...
See more...
So I cleaned up your script a bit, mostly just optimizations. I used the built in Opts:: module to add a hostname parameter to the script instead of using ARGV. I changed it so it checks for a valid host view before you start your loop, no point in looping through data centers if your hostname isn't an actual valid hostname in your VI inventory. Take a look at the LOOP label, I cleaned it up. You want to exit out of the loop after you find the datacenter. Just to show you how much faster my original script logic is, I also wrote another version of my script using the Perl toolkit. It was >3.5s faster on my standalone ESX host. It's largely because the find_entity_view() functions essentially fetch the entire ManagedObject reference property set, which is fairly intensive. This gets pretty slow in a larger environment and is compounded in a nested loop. I usually try to avoid using find_entity_view() heavily in my scripts for this reason. Feel free to work with whichever version you like best. I think both scripts do the job well. Using nested find_entity_views():
#!/usr/bin/perl -w
use strict;
use warnings;
use VMware::VIRuntime;
my %opts = (
hostname => {
type => "=s",
variable => "HOSTNAME",
help => "Name of managed ESX host",
required => 1,
}
);
Opts::add_options(%opts);
Opts::parse();
Opts::validate();
Util::connect();
my ($host_views, $datacenter, $hostname);
$hostname = Opts::get_option('hostname');
my $host = Vim::find_entity_view(
view_type => 'HostSystem',
filter => { name => $hostname },
);
unless (defined $host) {
Util::disconnect();
die "No host matching '$hostname' found.\n";
}
my $datacenter_view = Vim::find_entity_views(view_type => 'Datacenter');
LOOP: foreach (@$datacenter_view)
{
$datacenter = $_->name;
$host_views = Vim::find_entity_views(
view_type => 'HostSystem', begin_entity => $_
);
foreach (@$host_views)
{
if ($_->name eq $host->name)
{
print "$datacenter\n";
last LOOP;
}
}
}
Util::disconnect();
Sample output:
$time perl test.pl --server=172.16.14.51 --username=root --password=vmware --hostname=ESX-01.vmwlab.local
ha-datacenter
real 0m7.502s
user 0m1.872s
sys 0m0.078s
Using ManagedObject parent property:
#!/usr/bin/perl -w
use strict;
use warnings;
use VMware::VIRuntime;
my %opts = (
hostname => {
type => "=s",
variable => "HOSTNAME",
help => "Name of managed ESX host",
required => 1,
}
);
Opts::add_options(%opts);
Opts::parse();
Opts::validate();
Util::connect();
my $hostname = Opts::get_option('hostname');
my $entity_view;
sub FindDatacenter
{
my ($entity) = shift;
unless ( defined $entity )
{
print "Root folder reached and datacenter not found!\n";
return;
}
if($entity->type eq "Datacenter")
{
my $datacenter_view = Vim::get_view(mo_ref => $entity, properties => \['name']); # remove the \ before the property list.
print "Datacenter for HostSystem '" . $hostname . "' = " . $datacenter_view->name . "\n";
return;
}
$entity_view = Vim::get_view(mo_ref => $entity, properties => \['parent']); # remove the \ before the property list.
FindDatacenter($entity_view->parent);
}
my $host = Vim::find_entity_view(
view_type => 'HostSystem',
filter => { name => $hostname },
);
unless (defined $host)
{
die "No host matching \'$hostname\' found.\n";
}
FindDatacenter($host->parent);
Util::disconnect();
Sample output:
$time perl test2.pl --server=172.16.14.51 --username=root --password=vmware --hostname=ESX-01.vmwlab.local
Datacenter for HostSystem 'ESX-01.vmwlab.local' = ha-datacenter
real 0m4.326s
user 0m1.429s
sys 0m0.072s