1<?php
2
3namespace Icinga\Module\Vsphere\ManagedObject;
4
5use Icinga\Module\Vsphere\Api;
6use SoapVar;
7
8class FullTraversal extends TraversalHelper
9{
10    public static function fetchAll(Api $api)
11    {
12        return $api->collectProperties(static::prepareFullSpecSet($api));
13    }
14
15    public static function fetchNames(Api $api)
16    {
17        return $api->collectProperties(static::prepareNameSpecSet($api));
18    }
19
20    protected static function prepareNameSpecSet(Api $api)
21    {
22        $types = array(
23            'Datacenter',
24            'Folder',
25            'ResourcePool',
26            'HostSystem',
27            'ComputeResource',
28            'VirtualMachine',
29        );
30        $pathSet = array('name', 'parent');
31
32        $propSet = array();
33        foreach ($types as $type) {
34            $propSet[] = array(
35                'type' => $type,
36                'all' => 0,
37                'pathSet' => $pathSet
38            );
39        }
40        return array(
41            'propSet' => $propSet,
42            'objectSet' => array(
43                'obj' => $api->getServiceInstance()->rootFolder,
44                'skip' => false,
45                'selectSet' => static::selectFullTree(),
46            )
47        );
48    }
49
50    protected static function selectFullTree()
51    {
52        return array(
53            static::traverseDC1(),
54            static::traverseDC2(),
55            static::traverseFolder(),
56            static::traverseCR1(),
57            static::traverseCR2(),
58            static::traverseRP1(),
59            static::traverseRP2(),
60        );
61    }
62
63    protected static function prepareFullSpecSet(Api $api)
64    {
65        return array(
66            'propSet' => array(
67                array(
68                    'type' => 'HostSystem',
69                    'all' => 0,
70                    'pathSet' => HostSystem::getDefaultPropertySet()
71                ),
72                array(
73                    'type' => 'VirtualMachine',
74                    'all' => 0,
75                    'pathSet' => VirtualMachine::getDefaultPropertySet()
76                ),
77                array(
78                    'type' => 'Datacenter',
79                    'all' => 0,
80                    'pathSet' => Datacenter::getDefaultPropertySet()
81                ),
82                array(
83                    'type' => 'Folder',
84                    'all' => 0,
85                    'pathSet' => Folder::getDefaultPropertySet()
86                ),
87            ),
88            'objectSet' => array(
89                'obj' => $api->getServiceInstance()->rootFolder,
90                'skip' => false,
91                'selectSet' => static::selectFullTree(),
92            )
93        );
94    }
95
96    protected static function traverseDC1()
97    {
98        // Another TraversalSpec object has type Datacenter and name TraverseDC1.
99        // Set the path property to hostFolder
100        $spec = array(
101            'name' => 'TraverseDC1',
102            'type' => 'Datacenter',
103            'path' => 'hostFolder',
104            'skip' => false,
105            static::makeSelectionSet('TraverseFolder')
106        );
107
108        return new SoapVar($spec, SOAP_ENC_OBJECT, 'TraversalSpec');
109    }
110
111    protected static function traverseDC2()
112    {
113        // Another TraversalSpec object has the type Datacenter and name TraverseDC2
114        // Set the path property to vmFolder
115        $spec = array(
116            'name' => 'TraverseDC2',
117            'type' => 'Datacenter',
118            'path' => 'vmFolder',
119            'skip' => false,
120            static::makeSelectionSet('TraverseFolder')
121        );
122
123        return new SoapVar($spec, SOAP_ENC_OBJECT, 'TraversalSpec');
124    }
125
126    protected static function traverseFolder()
127    {
128        // One TraversalSpec object has the type Folder and name TraverseFolder
129        // Set the path property to childEntity
130        $spec = array(
131            'name' => 'TraverseFolder',
132            'type' => 'Folder',
133            'path' => 'childEntity',
134            'skip' => false,
135
136            // Because a Folder can be followed by another Folder, a Datacenter, or
137            // a ComputeResource, TraverseFolder needs five SelectionSpec objects.
138            // Their names are TraverseFolder, TraverseDC1, TraverseDC2, TraverseCR1,
139            // and TraverseCR2. Each SelectionSpec object invokes the name of a
140            // TraversalSpec object defined elsewhere in the PropertyFilter
141            static::makeSelectionSet('TraverseFolder'),
142            static::makeSelectionSet('TraverseDC1'),
143            static::makeSelectionSet('TraverseDC2'),
144            static::makeSelectionSet('TraverseCR1'),
145            static::makeSelectionSet('TraverseCR2')
146        );
147
148        return new SoapVar($spec, SOAP_ENC_OBJECT, 'TraversalSpec');
149    }
150
151    protected static function traverseCR1()
152    {
153        // Another TraversalSpec object has the type ComputeResource and name TraverseCR1
154        // Set the path property to resourcePool
155        $spec = array(
156            'name' => 'TraverseCR1',
157            'type' => 'ComputeResource',
158            'path' => 'resourcePool',
159            'skip' => false,
160
161            // A ComputeResource object can be followed either by a ResourcePool
162            // or a HostSystem. There is no need to traverse a HostSystem, but
163            // there are two different ResourcePool TraversalSpecs to cover, so
164            // TraverseCR1 needs an array of two SelectionSpec objects, named
165            // TraverseRP1 and TraverseRP2
166            static::makeSelectionSet('TraverseRP1'),
167            static::makeSelectionSet('TraverseRP2')
168        );
169
170        return new SoapVar($spec, SOAP_ENC_OBJECT, 'TraversalSpec');
171    }
172
173    protected static function traverseCR2()
174    {
175        // Another TraversalSpec object has the type ComputeResource and name TraverseCR2
176        // Set the path property to host
177        $spec = array(
178            'name' => 'TraverseCR2',
179            'type' => 'ComputeResource',
180            'path' => 'host',
181            'skip' => false
182            // TraverseCR2 can lead only to a HostSystem object, so there is no
183            // need for it to have a selectSet array
184        );
185
186        return new SoapVar($spec, SOAP_ENC_OBJECT, 'TraversalSpec');
187    }
188
189    protected static function traverseRP1()
190    {
191        // Another TraversalSpec object has the type ResourcePool and name TraverseRP1
192        // Set the path property to resourcePool
193        $spec = array(
194            'name' => 'TraverseRP1',
195            'type' => 'ResourcePool',
196            'path' => 'resourcePool',
197            'skip' => false,
198            // TraverseRP1 can lead only to another ResourcePool, but there are
199            // two paths out of ResourcePool, so it needs an array of two
200            // SelectionSpec objects, named TraverseRP1 and TraverseRP2
201            static::makeSelectionSet('TraverseRP1'),
202            static::makeSelectionSet('TraverseRP2')
203        );
204
205        return new SoapVar($spec, SOAP_ENC_OBJECT, 'TraversalSpec');
206    }
207
208    protected static function traverseRP2()
209    {
210        // Another TraversalSpec object has the type ResourcePool and name TraverseRP2
211        // Set the path property to vm
212        $spec = array(
213            'name' => 'TraverseRP2',
214            'type' => 'ResourcePool',
215            'path' => 'vm',
216            'skip' => false,
217            // TraverseRP2 can lead only to VirtualMachine objects, so there
218            // is no need for it to have a selectSet array
219        );
220
221        return new SoapVar($spec, SOAP_ENC_OBJECT, 'TraversalSpec');
222    }
223}
224