File Coverage

blib/lib/VMOMI.pm
Criterion Covered Total %
statement 14 46 30.4
branch 0 18 0.0
condition 0 3 0.0
subroutine 5 6 83.3
pod 0 1 0.0
total 19 74 25.6


line stmt bran cond sub pod time code
1             package VMOMI;
2              
3 2     2   18852 use 5.006;
  2         8  
4 2     2   11 use strict;
  2         4  
  2         35  
5 2     2   16 use warnings;
  2         5  
  2         97  
6              
7             our $VERSION = 0.01;
8              
9 2     2   1005 use Class::Autouse;
  2         9718  
  2         11  
10             use Exception::Class(
11 2         28 'Exception',
12             'Exception::SoapFault' => {
13             isa => 'Exception',
14             fields => [ 'faultcode', 'detail', 'faultstring' ] },
15             'Exception::Autoload' => {
16             isa => 'Exception' },
17             'Exception::Deserialize' => {
18             isa => 'Exception' },
19             'Exception::Serialize' => {
20             isa => 'Exception' },
21             'Exception::Protocol' => {
22             isa => 'Exception' },
23 2     2   892 );
  2         14760  
24              
25             Class::Autouse->autouse_recursive("VMOMI");
26              
27             # TODO: Add support for multiple entity types in single call, e.g. 'HostSystem', 'VirtualMachine' & 'Folder'
28             sub find_entities {
29 0     0 0   my ($content, $type, $match, $begin, %args) = @_;
30 0           my (@properties, $spec, $view, $filter_spec, $result, @objects, @matched);
31              
32 0 0         $begin = $content->rootFolder unless defined $begin;
33 0 0         @properties = keys %$match if defined $match;
34              
35             # PropertySpec
36 0           $spec = new VMOMI::PropertySpec(type => $type, all => 0);
37 0 0         if (defined $match) {
38 0           $spec->pathSet(\@properties);
39             }
40              
41 0           $view = $content->viewManager->CreateContainerView(
42             type => [$type],
43             recursive => 1,
44             container => $begin->moref,
45             );
46              
47              
48             $filter_spec = new VMOMI::PropertyFilterSpec(
49             reportMissingInResults => 0,
50             propSet => [ new VMOMI::PropertySpec(
51             all => 0,
52             type => $type,
53             pathSet => \@properties,
54             )],
55             objectSet => [ new VMOMI::ObjectSpec(
56             obj => $view,
57             skip => 0,
58             selectSet => [ new VMOMI::TraversalSpec(
59             path => "view",
60             type => $view->{type},
61 0           )],
62             )],
63             );
64              
65 0           $result = $content->propertyCollector->RetrievePropertiesEx(
66             specSet => [$filter_spec],
67             options => new VMOMI::RetrieveOptions(),
68             );
69              
70 0 0         push @objects, @{ $result->objects || [ ] };
  0            
71 0           while (defined $result->token) {
72 0           $result = $content->propertyCollector->ContinueRetrievePropertiesEx(token => $result->token);
73 0 0         push @objects, @{ $result->objects || [ ] };
  0            
74             }
75              
76              
77 0 0         unless (defined $match) {
78 0           @matched = map { $_->obj } @objects;
  0            
79 0           return @matched;
80             }
81              
82 0           foreach my $object (@objects) {
83 0           my (%pset);
84            
85 0 0         %pset = map { $_->name => $_->val } @{ $object->{propSet} || [ ] };
  0            
  0            
86 0           foreach (@properties) {
87 0           my $re = $match->{$_};
88              
89 0 0 0       if (not defined $re and not defined $pset{$_}) {
90 0           push @matched, $object->obj;
91             } # check if $re or $pset{$_} are undef to avoid compare errors
92              
93 0 0         if ($pset{$_} =~ /$re/) {
94 0           push @matched, $object->obj;
95             }
96             }
97             }
98 0           return @matched;
99              
100             }
101              
102             1;
103              
104             =encoding UTF-8
105              
106             =head1 NAME
107              
108             VMOMI - VMware vSphere API Perl Bindings
109              
110             =head1 SYNOPSIS
111              
112             use VMOMI;
113              
114             stub = new VMOMI::SoapStub(host => $host) || die "Failed to initialize VMOMI::SoapStub";
115             $instance = new VMOMI::ServiceInstance(
116             $stub,
117             new VMOMI::ManagedObjectReference(
118             type => 'ServiceInstance',
119             value => 'ServiceInstance',
120             ),
121             );
122              
123             # Login
124             $content = $instance->RetrieveServiceContent;
125             $session = $content->sessionManager->Login(userName => $user, password => $pass);
126              
127             @vms = VMOMI::find_entities($content, 'VirtualMachine');
128             foreach (@vms) {
129             print $_->name . ", " . $_->config->guestFullName . "\n";
130             }
131              
132             # Logout
133             $content->sessionManager->Logout();
134              
135             =head1 INSTALLATION
136              
137             cpanm install VMOMI
138              
139             =head1 DESCRIPTION
140              
141             VMOMI provides an alternative to the VMware Perl SDK for vSphere and was created to address
142             some limitations with the offical VMware Perl SDK.
143              
144             =over 8
145              
146             =item * B
147              
148             =item * B>
149              
150             =item * B
151              
152             =back
153              
154             =head2 Finding ManagedEntities
155              
156             Managed entities in the VMware vSphere Web Service inventory, e.g. VirtualMachine or HostSystem, can be
157             fetched with the utilty function B:
158              
159             @vms = VMOMI::find_entities($content, 'VirtualMachine', { 'config.guestFullName' => qr/Linux/ });
160             @hosts = VMOMI::find_entities($content, 'HostSystem');
161              
162             B<$content> should be an authenticated instance of VMOMI::ServiceContent:
163              
164             $stub = new VMOMI::SoapStub(host => $host);
165             $instance = new VMOMI::ServiceInstance(
166             $stub,
167             new VMOMI::ManagedObjectReference(
168             type => 'ServiceInstance',
169             value => 'ServiceInstance',
170             ),
171             );
172             $content = $instance->RetrieveServiceContent;
173             $session = $content->sessionManager->Login(userName => $user, password => $pass);
174              
175             =head2 Working with ManagedObjectReferences
176              
177             The VMware vSphere Web Service API primarily works through ManagedObjectReferences (moref). Most SDKs
178             therefore generate "view classes" of the common objects managed through the API, e.g. VirtualMachine,
179             HostSystem, Folder, Datacenter, ClusterComputeResource, etc.
180              
181             VMOMI provides similar, manually generated classes for these managed objects. During deserialization
182             of the vSphere Web Service API, ManagedObjectReferences are automatically instantiated to corresponding
183             "view classes". The underlying ManagedObjectReference can be accessed through the B property.
184             ManagedObjectReferences have two properties B and B:
185              
186             $vm = VMOMI::find_entities($content, 'VirtualMachine', { name => qr/TestVM2/ })->shift;
187             $moref = $vm->moref;
188             print $moref->type . ":" . $moref->value . "\n"; # 'VirtualMachine:vm-12'
189              
190             "View" classes can instantiated using known, valid ManagedObjectReference type and value properties along
191             with a current, authenticated connection stub:
192              
193             $vm = new VMOMI::VirtualMachine(
194             $stub,
195             new VMOMI::ManagedObjectReference
196             type => 'VirtualMachine',
197             value => 'vm-12'),
198             );
199             print $vm->name . "\n"; # TestVM2
200              
201             =head2 Performance Considerations
202              
203             Properties are only retrieved from the vSphere Web Services API on access through AUTOLOAD, and as such
204             can impact performance in iterations. The following logic will invoke three API calls to vSphere for each
205             virtual machine:
206              
207             @vms = VMOMI::find_entities($content, 'VirtualMachine');
208             foreach (@vms) {
209             print $_->name . ": " . $_->runtime->powerState . "\n"; # three API invocations
210             }
211              
212             As future enhancement, preserving values previously fetched from the API to avoid reptitive calls would
213             improve performance. As a work around, pulling requested properties in bulk through
214             B or B and parsing them into
215             a data structure will provide the best performance.
216              
217             =head1 AUTHOR
218              
219             Reuben M. Stump
220              
221             reuben.stump@gmail.com
222              
223             =head1 SEE ALSO
224              
225             L
226              
227             L
228              
229             =head1 COPYRIGHT and LICENSE
230              
231             Copyright (c) 2015 by Reuben M. Stump
232              
233             This code is distributed under the Apache 2 License. The full text of the license can be found in the
234             LICENSE file included with this module.
235              
236              
237             =cut