VMware {code} Community
thomas2
Contributor
Contributor
Jump to solution

vCenter Linked Mode and Perl SDK

Hello,

our VMware environment is divided into two physical locations represented as two vCenter instances. Both vCenters are linked together. I think its called "Linked Mode"?

Is it possible to use the Perl SDK in a Linked Mode too? Currently I have to manually query both our vCenters and then sort the output myself.

1) How can I configure Perl SDK so I only have to authenticate once against our Linked mode environment?

2) How can I construct queries against the API so results will include objects in both vCenters? Ie. if I execute a "Vim::find_entity_views(view_type => 'VirtualMachine') " query I would like to get all "VirtualMachine" objects in both vCenters so I can avoid executing two seperate queries and then subsequently combining the results?

Thanks!

Thomas Willert

0 Kudos
1 Solution

Accepted Solutions
stumpr
Virtuoso
Virtuoso
Jump to solution

It's not a published API method, but there is a way to get the list of vCenter servers in a linked mode group.  I have some explanation and sample code: http://www.virtuin.com/2012/12/querying-vcenter-linked-mode-with.html

In terms of authentication, if your vCenter instances are using the same permissions (which is recommended), then it's just a matter of authenticating to each vCenter.  This is what the native client does as well (if you ever setup vCenters with different permissions you'll see login prompts for each vCenter).

If you look at the blog post I linked earlier, you'll se an example of authenticating to each vCenter as well.  Basically you just call Util::connect() twice, once for each of your vCenter URLs.  However, you do need to clear the VIM global that the SDK toolkit uses, or it will default to the last vCenter.  I show this as well in the sample script: LinkedModeExample.pl

In terms of combining queries....not so easy.  You'll have to call into each vCenter with $vim->find_entity_views().  Now, on a more advanced note, the API is quite powerful for doing customized queries against the inventory, so you can generally pre-fetch and keep updates into your objects. 

What I would recommend as a simple approach is two calls to find_entity_views, then push them into a hash or array.  You'll just want to use the vCenter UUID:

$vc_uuid = $vim1->get_service_content()->{'about'}->{'instanceUuid'};

The instanceUuid was added in vCenter 4.x and later (won't have it in older vCenter 2.5 instances).  Then use this instanceUuid + moref as hash keys.  This is important because morefs can be duplicated between vCenters.

So you can then build a hash:

my %vm_hash;

foreach my $entity (@$vm_views) {

     my $moref = $entity->{'mo_ref'}->{'value'}; # will be vm-# for virtual machines

     $vm_hash{$vc_uuid . "+". $moref} = $entity;

}

Then you can quickly lookup specific VMs and keep them separate between vCenters.

You'll find this works for simple data queries, but as you start to get more and more inventory objects (say for an inventory report), the relationships get more complex and the number of objects get larger.  I've done work with pushing these values into a database and excel files (including running it on 5s or less intervals with WaitForUpdatesEx), which works well if you have the time to build the DB schemas and object to database work.  Just use instanceUuid + Moref value as a primary key to prevent any cross vCenter moref value re-use.

The other option is that the vim reference is added to each object, so you can just get data from each entity:

foreach my $vm (@$vm_views) {

     print "VM: " . $vm->{'name'} . "\n";

     print "   VC InstanceUuid: " . $vm->{'vim'}->{'service_content'}->{'about'}->{'instanceUuid'} . "\n";

     print "   VC ServiceUrl: " . $vm->{'vim'}->{'service_url'} . "\n";

}

I have a project I tinker with on my free time (which is rare these days) that is meant to aggregate multiple vCenters into a single database for queries and reporting, but I haven't gotten it far enough to share it (very rough, but works for a subset of data currently, but is very efficient at bulk collection on <5s intervals).

You could also look into VMware Orchestrator.  Orchestrator can connect to multiple vCenters and will cache data from each for access by automation.  Depending on your WAN performance, it may work well from one geographical site and provide you that aggregated data you require (just watch the moref, entity names and other possible duplication between vCenters).

Reuben Stump | http://www.virtuin.com | @ReubenStump

View solution in original post

0 Kudos
3 Replies
stumpr
Virtuoso
Virtuoso
Jump to solution

It's not a published API method, but there is a way to get the list of vCenter servers in a linked mode group.  I have some explanation and sample code: http://www.virtuin.com/2012/12/querying-vcenter-linked-mode-with.html

In terms of authentication, if your vCenter instances are using the same permissions (which is recommended), then it's just a matter of authenticating to each vCenter.  This is what the native client does as well (if you ever setup vCenters with different permissions you'll see login prompts for each vCenter).

If you look at the blog post I linked earlier, you'll se an example of authenticating to each vCenter as well.  Basically you just call Util::connect() twice, once for each of your vCenter URLs.  However, you do need to clear the VIM global that the SDK toolkit uses, or it will default to the last vCenter.  I show this as well in the sample script: LinkedModeExample.pl

In terms of combining queries....not so easy.  You'll have to call into each vCenter with $vim->find_entity_views().  Now, on a more advanced note, the API is quite powerful for doing customized queries against the inventory, so you can generally pre-fetch and keep updates into your objects. 

What I would recommend as a simple approach is two calls to find_entity_views, then push them into a hash or array.  You'll just want to use the vCenter UUID:

$vc_uuid = $vim1->get_service_content()->{'about'}->{'instanceUuid'};

The instanceUuid was added in vCenter 4.x and later (won't have it in older vCenter 2.5 instances).  Then use this instanceUuid + moref as hash keys.  This is important because morefs can be duplicated between vCenters.

So you can then build a hash:

my %vm_hash;

foreach my $entity (@$vm_views) {

     my $moref = $entity->{'mo_ref'}->{'value'}; # will be vm-# for virtual machines

     $vm_hash{$vc_uuid . "+". $moref} = $entity;

}

Then you can quickly lookup specific VMs and keep them separate between vCenters.

You'll find this works for simple data queries, but as you start to get more and more inventory objects (say for an inventory report), the relationships get more complex and the number of objects get larger.  I've done work with pushing these values into a database and excel files (including running it on 5s or less intervals with WaitForUpdatesEx), which works well if you have the time to build the DB schemas and object to database work.  Just use instanceUuid + Moref value as a primary key to prevent any cross vCenter moref value re-use.

The other option is that the vim reference is added to each object, so you can just get data from each entity:

foreach my $vm (@$vm_views) {

     print "VM: " . $vm->{'name'} . "\n";

     print "   VC InstanceUuid: " . $vm->{'vim'}->{'service_content'}->{'about'}->{'instanceUuid'} . "\n";

     print "   VC ServiceUrl: " . $vm->{'vim'}->{'service_url'} . "\n";

}

I have a project I tinker with on my free time (which is rare these days) that is meant to aggregate multiple vCenters into a single database for queries and reporting, but I haven't gotten it far enough to share it (very rough, but works for a subset of data currently, but is very efficient at bulk collection on <5s intervals).

You could also look into VMware Orchestrator.  Orchestrator can connect to multiple vCenters and will cache data from each for access by automation.  Depending on your WAN performance, it may work well from one geographical site and provide you that aggregated data you require (just watch the moref, entity names and other possible duplication between vCenters).

Reuben Stump | http://www.virtuin.com | @ReubenStump
0 Kudos
thomas2
Contributor
Contributor
Jump to solution

Hallo stumpr,

thanks for your explanation. I had already read your blog entry before posting here btw Smiley Happy

I was hoping for a transparent solution so I could re-use all the good scripts out there without having to make any changes to them, but I can see now that you may run into possible name-space conflicts, ie. identical virtualmachines between two vCenters etc.

Cheers,

Thomas Willert

0 Kudos
stumpr
Virtuoso
Virtuoso
Jump to solution

Awesome, wasn't sure if it would be useful.  Glad it was at least informative Smiley Happy

I thought about trying to build a transparent solution, but b/c of possible inventory names and moref overlaps between vsphere inventories it would never be truly transparent.  Scripts would have to be updated to check the source vCenter or risk operations or reports pulling the wrong object(s).

The SDK's global VIM object is also a problem. 

But even with these problems you can probably get some gains by using in-memory sqlite, berkley db, and other storage tools.  I've done a few script tools that talk to 6+ vcenters very efficiently with the Perl SDK, but I definitely had to do some custom methods, data structures and logic (couldn't use existing script samples).

Reuben Stump | http://www.virtuin.com | @ReubenStump
0 Kudos