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   18003 use 5.006;
  2         6  
4 2     2   9 use strict;
  2         4  
  2         36  
5 2     2   14 use warnings;
  2         3  
  2         81  
6              
7             our $VERSION = 0.02;
8              
9 2     2   864 use Class::Autouse;
  2         8558  
  2         12  
10             use Exception::Class(
11 2         19 '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   904 );
  2         14385  
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             apk add openssl-dev libxml2-dev
138             cpanm install VMOMI
139              
140             =head1 DESCRIPTION
141              
142             VMOMI provides an alternative to the VMware Perl SDK for vSphere and was created to address
143             some limitations with the offical VMware Perl SDK.
144              
145             =over 8
146              
147             =item * Preserve main:: namespace by avoid globals and the import of all API classes
148              
149             =item * Reduce memory footprint through L
150              
151             =item * Enable installation through CPAN
152              
153             =back
154              
155             =head2 Finding ManagedEntities
156              
157             Managed entities in the VMware vSphere Web Service inventory, e.g. VirtualMachine or HostSystem, can be
158             fetched with the utilty function B:
159              
160             @vms = VMOMI::find_entities($content, 'VirtualMachine', { 'config.guestFullName' => qr/Linux/ });
161             @hosts = VMOMI::find_entities($content, 'HostSystem');
162              
163             B<$content> should be an authenticated instance of VMOMI::ServiceContent:
164              
165             $stub = new VMOMI::SoapStub(host => $host);
166             $instance = new VMOMI::ServiceInstance(
167             $stub,
168             new VMOMI::ManagedObjectReference(
169             type => 'ServiceInstance',
170             value => 'ServiceInstance',
171             ),
172             );
173             $content = $instance->RetrieveServiceContent;
174             $session = $content->sessionManager->Login(userName => $user, password => $pass);
175              
176             =head2 Working with ManagedObjectReferences
177              
178             The VMware vSphere Web Service API primarily works through ManagedObjectReferences (moref). Most SDKs
179             therefore generate "view classes" of the common objects managed through the API, e.g. VirtualMachine,
180             HostSystem, Folder, Datacenter, ClusterComputeResource, etc.
181              
182             VMOMI provides similar, manually generated classes for these managed objects. During deserialization
183             of the vSphere Web Service API, ManagedObjectReferences are automatically instantiated to corresponding
184             "view classes". The underlying ManagedObjectReference can be accessed through the B property.
185             ManagedObjectReference consists of two properties B and B:
186              
187             $vm = VMOMI::find_entities($content, 'VirtualMachine', { name => qr/TestVM2/ })->shift;
188             $moref = $vm->moref;
189             print $moref->type . ":" . $moref->value . "\n"; # 'VirtualMachine:vm-12'
190              
191             "View" classes can instantiated using known, valid ManagedObjectReference type and value properties along
192             with a current, authenticated connection stub:
193              
194             $vm = new VMOMI::VirtualMachine(
195             $stub,
196             new VMOMI::ManagedObjectReference
197             type => 'VirtualMachine',
198             value => 'vm-12'),
199             );
200             print $vm->name . "\n"; # TestVM2
201              
202             =head2 JSON
203              
204             Support for L object serialization is available through the
205             TO_JSON method on the SDK classes, which may be of benefit for storing objects or integration with NoSQL
206             databases.
207              
208             $coder = JSON::XS->new->convert_blessed->pretty;
209             $encoded_json = $coder->encode($session);
210            
211             print $encoded_json;
212             {
213             "lastActiveTime" : "2017-05-03T13:17:03.152908Z",
214             "extensionSession" : 0,
215             "key" : "52956fcc-bab5-ad78-9ca8-8a773192c2d1",
216             "locale" : "en",
217             "ipAddress" : "172.16.1.6",
218             "fullName" : "Administrator vlab.local",
219             "userName" : "VLAB.LOCAL\\Administrator",
220             "loginTime" : "2017-05-03T13:17:03.152908Z",
221             "messageLocale" : "en",
222             "userAgent" : "Perl/VMOMI",
223             "_ancestors" : [
224             "DynamicData"
225             ],
226             "callCount" : "0",
227             "_class" : "UserSession"
228             }
229              
230             Two additional properties are added to the JSON encoded string, B<_class> and B<_ancestors>. B<_class> is the
231             object's class name and B<_ancestors> provides the class inheritance in descending order.
232              
233             =head2 Performance Considerations
234              
235             Properties are only retrieved from the vSphere Web Services API on access through AUTOLOAD, and as such,
236             can impact performance in iterations. The following logic will invoke three API calls to vSphere for each
237             virtual machine:
238              
239             @vms = VMOMI::find_entities($content, 'VirtualMachine');
240             foreach (@vms) {
241             print $_->name . ": " . $_->runtime->powerState . "\n"; # three API invocations
242             }
243              
244             As future enhancement, preserving values previously fetched from the API to avoid reptitive calls would
245             improve performance. As a work around, pulling requested properties in bulk through
246             B or B and parsing them into
247             a data structure will provide the best performance.
248              
249             =head1 AUTHOR
250              
251             Reuben M. Stump
252              
253             reuben.stump@gmail.com
254              
255             =head1 SEE ALSO
256              
257             L
258              
259             L
260              
261             =head1 LICENSE
262              
263             This code is distributed under the Apache 2 License. The full text of the license can be found in the
264             LICENSE file included with this module.
265              
266             =head1 COPYRIGHT
267              
268             Copyright (c) 2015 by Reuben M. Stump
269              
270             =cut