Hi,
I have this simple code to retrieve the name of all VirtualMachines in my infrastructure (filtered for datacenter)
[...other code...]
use VMware::VILib; | |
Opts::add_options(%opts); | |
Opts::parse(); | |
Opts::validate(); | |
Util::connect(); |
my $datacenter = $DCFILTER;
my $clusterFilter = $CLFILTER ;
my $datacenter_view = Vim::find_entity_view(view_type => 'Datacenter', filter => { name => $datacenter });
my @values = split(/\|/, $clusterFilter);
foreach my $val (@values) {
my $cluster_view = Vim::find_entity_view(view_type => 'ClusterComputeResource', filter => { name => qr/$val/});
my $vm_views = Vim::find_entity_views(view_type => 'VirtualMachine', begin_entity => $cluster_view);
foreach (@$vm_views) {
print $_->name . "\n"; | ||
$vm = $_->name; |
}
}
Util::disconnect();
This code runs, but now I need to recover some information about network of each VM, specifically:
1)the network labels of each NIC (for each VM)
2)the Adapter Type (optionally)
3)Device status: Connected at power on (yes/no) (optionally).
I saw that exists the Managed Object - Network, property of Managed Object - VirtualMachine, but i don't know how to use it in my code and if contains the information i need (maybe "Summary")
Here one example:
in this case i would like to know for this VM
1)LANBACKUP.... ; dvPP_LABO...; dvp_LABO...
and if is possible the information 2) and 3) for each NIC...in this case for NIC LANBAKUP...
2)Flexible
3)Connected at the power on: Yes
Can you help me to integrate my code for retrieve the above information?
Thank you very much, for your help.
Sergio
I would pre-fetch the DVS items:
my $dv_switches = Vim::find_entity_views(view_type => 'DistributedVirtualSwitch', properties => ['name', 'uuid']);
Then, you can look it up by UUID:
($this_dvs) = grep {$_->{'uuid'} eq $the_uuid} @$dv_switches;
This will give you the best performance as well, since you don't have to hit the API for every query (just the efficient first all DVS query). You can add additional data from the DVSwitch object if you need it in your logic.
Well, Flexible is basically just the VirtualPCNet32 adapter; VMware's UI just uses 'flexible' in the UI display. So in that case you can easily check for it by reviewing the vm.config.hardware.device[] array with isa().
Pseudo logic from reference (not tested):
# For efficient collection, use limited property lists
@vms = Vim::find_entity_views(view_type => 'VirtualMachine', properties => ['name', 'config.hardware.device']);
foreach my $vm ( @vms ) {
print "vm: " . $vm->{'name'} . "\n";
@devs = @{ $vm->{'config.hardware.device'} };
# Pick out just network devices
@net_devs = grep { $_->isa('VirtualEthernetCard'} } @devs;
# iterate the network devices for each VM
foreach my $nic ( @net_devs ) {
my ($name, $type, $network, $connect, $pg_mo, $pg);
# NIC type
if ($nic->isa('VirtualPCNet32') {
$type = 'Flexible';
} else {
$type = ref $nic;
}
# The network object is specified as a reference, so it will need to be cross checked against the network objects to get the 'label'
$pg_mo = $nic->{'backing'}{'network'};
# You should pre-fetch all the network and DistributedVirtualPortgroup objects, doing a call for each is not efficient, but works
$pg = Vim::get_view(mo_ref => $pg_mo, properties => ['name']);
$network = $pg->{'name'};
# For connect on power on, look at device connectable property
$connect = ( eval {$nic->{'connectable'}{'startConnected'} ) ? 1 : 0;
# NIC label (name)
$name = $nic->{'deviceInfo'}{'label'};
# Push your values into some csv output data struct or print them
print " nic '$name':\n";
print " connect on power on: $connect\n";
print " network portgroup: $network\n";
print " NIC type: $type\n";
}
}
Thanks a lot!!!!
I did some tests and almost everything works.
The only problem I encounter is with a VM that has two NICs with Distributed Virtual Switch:
The name of this VM is LABO-TEST-MACHINE, and this is the output of the perl scripts:
[...]
VM Name: LABMXXXXX
NIC type: VirtualE1000
nic 'Network adapter 1':
network portgroup: LANBACKUP_LABO
NIC type: VirtualE1000
NIC type: VirtualE1000
nic 'Network adapter 2':
network portgroup: HEARTBEAT_XXX
NIC type: VirtualE1000
VM Name: LABO-TEST-MACHINE
NIC type: Flexible
nic 'Network adapter 1':
network portgroup: LANBACKUP_LABO
NIC type: Flexible
NIC type: Flexible
Can't call method "type" on an undefined value at /usr/share/perl/5.10/VMware/VICommon.pm line 1026.
How you can see, i receive the error above, only when the script try to extract the Network Portgroup of that VM.
I think the code line with the problem is:
$pg = Vim::get_view(mo_ref => $pg_mo, properties => ['name']);
Instead with the Standard Virtual Switch, i didn't encounter problems.
Here's all new code:
my $datacenter = $DCFILTER;
my $clusterFilter = $CLFILTER ;
my $datacenter_view = Vim::find_entity_view(view_type => 'Datacenter', filter => { name => $datacenter });
my @values = split(/\|/, $clusterFilter);
foreach my $val (@values) {
my $cluster_view = Vim::find_entity_view(view_type => 'ClusterComputeResource', filter => { name => qr/$val/});
my $vm_views = Vim::find_entity_views(view_type => 'VirtualMachine', properties => ['name', 'config.hardware.device'], begin_entity => $cluster_view);
foreach (@$vm_views) {
print $_->name . "\n";
# $vm = $_->name;
my @devs = @{ $_->{'config.hardware.device'} };
my @net_devs = grep { $_->isa('VirtualEthernetCard') } @devs;
foreach my $nic ( @net_devs ) {
my ($name, $type, $network, $connect, $pg_mo, $pg);
# NIC type
if ($nic->isa('VirtualPCNet32')) {
$type = 'Flexible';
} else {
$type = ref $nic;
}
print " NIC type: $type\n";
$pg_mo = $nic->{'backing'}{'network'};
$pg = Vim::get_view(mo_ref => $pg_mo, properties => ['name']);
$network = $pg->{'name'};
# $connect = ( eval {$nic->{'connectable'}{'startConnected'} ) ? 1 : 0;
$name = $nic->{'deviceInfo'}{'label'};
print " nic '$name':\n";
# print " connect on power on: $connect\n";
print " network portgroup: $network\n";
print " NIC type: $type\n";
}
}
}
Util::disconnect();
It's possible the NIC doesn't have an assigned network portgroup. So you can just check for an ignore it in cases where it's not set. You may actually need to do this for a lot of properties in the API. When building report tools in the past, I usually create an accessor method like 'get_property()' that does all the eval, undefined and other value checks and returns something for print sanity (empty string, 'null', etc). There's actually a get_property() method that's on every object in the Perl SDK as well, but I don't use it myself. Not sure how it handles undefined values.
$pg = Vim::get_view(mo_ref => $pg_mo, properties => ['name']) if defined $pg_mo;
$network = (defined $pg->{'name'}) ? $pg->{'name'} : 'unset';
Again thank you so much !!
The problem is that the most important information i want collect is the label of the NICs with Distributed Virtual Switch ... the only one who doesn't work)
It's probably unset. If you're not familiar, you can use the vSphere MOB to explore it - https://your_vcenter_hostname:443/mob
I use that a lot when looking for "quirky" properties.
Hi, now i use this code to find the Portgroup name:
my $portgroupKey = $nic->{backing}->{port}->{portgroupKey};
my $dvsPortgroup = Vim::find_entity_view (
view_type => "DistributedVirtualPortgroup",
begin_entity => $datacenter_view,
properties => [ 'name', 'key', 'config.distributedVirtualSwitch' ],
filter => { 'key' => $portgroupKey }
);
my $Portgroup_name = $dvsPortgroup->name;
this work.
and with this i can retrive the switch UUID:
my $SwitchUuid = $nic->{backing}->{port}->{switchUuid};
it's look like: 90 2d 05 40 1e 9f ba 9b-ea fe 3d ec 93 21 a1 ba
now i need to retrieve the DVSwitch real name, something like "dvs_TEST-DR"...can i use the UUID to find the associated DVS name, how?
Maybe is there a better way?
Thank You!!
I would pre-fetch the DVS items:
my $dv_switches = Vim::find_entity_views(view_type => 'DistributedVirtualSwitch', properties => ['name', 'uuid']);
Then, you can look it up by UUID:
($this_dvs) = grep {$_->{'uuid'} eq $the_uuid} @$dv_switches;
This will give you the best performance as well, since you don't have to hit the API for every query (just the efficient first all DVS query). You can add additional data from the DVSwitch object if you need it in your logic.
Thank you very much Stumpr, now i have all i need
Bye!!