1 /*
2  * esx_vi.h: client for the VMware VI API 2.5 to manage ESX hosts
3  *
4  * Copyright (C) 2011 Red Hat, Inc.
5  * Copyright (C) 2009-2012, 2014 Matthias Bolte <matthias.bolte@googlemail.com>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library.  If not, see
19  * <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 #pragma once
24 
25 #include <libxml/tree.h>
26 #include <libxml/xpath.h>
27 #include <curl/curl.h>
28 
29 #include "internal.h"
30 #include "virerror.h"
31 #include "datatypes.h"
32 #include "esx_vi_types.h"
33 #include "esx_util.h"
34 
35 
36 #define ESX_VI__SOAP__REQUEST_HEADER \
37     "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" \
38     "<soapenv:Envelope\n" \
39     " xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"\n" \
40     " xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\"\n" \
41     " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" \
42     " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\n" \
43     "<soapenv:Body>\n"
44 
45 
46 
47 #define ESX_VI__SOAP__REQUEST_FOOTER \
48     "</soapenv:Body>\n" \
49     "</soapenv:Envelope>"
50 
51 
52 
53 #define ESV_VI__XML_TAG__OPEN(_buffer, _element, _type) \
54     do { \
55         virBufferAddLit(_buffer, "<"); \
56         virBufferAdd(_buffer, _element, -1); \
57         virBufferAddLit(_buffer, " xmlns=\"urn:vim25\" xsi:type=\""); \
58         virBufferAdd(_buffer, _type, -1); \
59         virBufferAddLit(_buffer, "\">"); \
60     } while (0)
61 
62 
63 
64 #define ESV_VI__XML_TAG__CLOSE(_buffer, _element) \
65     do { \
66         virBufferAddLit(_buffer, "</"); \
67         virBufferAdd(_buffer, _element, -1); \
68         virBufferAddLit(_buffer, ">"); \
69     } while (0)
70 
71 
72 
73 typedef enum _esxVI_ProductLine esxVI_ProductLine;
74 typedef enum _esxVI_Occurrence esxVI_Occurrence;
75 typedef struct _esxVI_ParsedHostCpuIdInfo esxVI_ParsedHostCpuIdInfo;
76 typedef struct _esxVI_CURL esxVI_CURL;
77 typedef struct _esxVI_SharedCURL esxVI_SharedCURL;
78 typedef struct _esxVI_MultiCURL esxVI_MultiCURL;
79 typedef struct _esxVI_Context esxVI_Context;
80 typedef struct _esxVI_Response esxVI_Response;
81 typedef struct _esxVI_Enumeration esxVI_Enumeration;
82 typedef struct _esxVI_EnumerationValue esxVI_EnumerationValue;
83 typedef struct _esxVI_List esxVI_List;
84 
85 
86 
87 enum _esxVI_ProductLine {
88     esxVI_ProductLine_GSX = 0,
89     esxVI_ProductLine_ESX,
90     esxVI_ProductLine_VPX
91 };
92 
93 enum _esxVI_Occurrence {
94     esxVI_Occurrence_Undefined = 0,
95     esxVI_Occurrence_RequiredItem,
96     esxVI_Occurrence_RequiredList,
97     esxVI_Occurrence_OptionalItem,
98     esxVI_Occurrence_OptionalList,
99     esxVI_Occurrence_None
100 };
101 
102 struct _esxVI_ParsedHostCpuIdInfo {
103     int level;
104     char eax[32];
105     char ebx[32];
106     char ecx[32];
107     char edx[32];
108 };
109 
110 
111 
112 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
113  * CURL
114  */
115 
116 struct _esxVI_CURL {
117     CURL *handle;
118     virMutex lock;
119     struct curl_slist *headers;
120     char error[CURL_ERROR_SIZE];
121     esxVI_SharedCURL *shared;
122     esxVI_MultiCURL *multi;
123 };
124 
125 int esxVI_CURL_Alloc(esxVI_CURL **curl);
126 void esxVI_CURL_Free(esxVI_CURL **curl);
127 int esxVI_CURL_Connect(esxVI_CURL *curl, esxUtil_ParsedUri *parsedUri);
128 int esxVI_CURL_Download(esxVI_CURL *curl, const char *url, char **content,
129                         unsigned long long offset, unsigned long long *length);
130 int esxVI_CURL_Upload(esxVI_CURL *curl, const char *url, const char *content);
131 
132 
133 
134 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
135  * SharedCURL
136  */
137 
138 struct _esxVI_SharedCURL {
139     CURLSH *handle;
140     virMutex locks[3]; /* share, cookie, dns */
141     size_t count; /* number of added easy handle */
142 };
143 
144 int esxVI_SharedCURL_Alloc(esxVI_SharedCURL **shared);
145 void esxVI_SharedCURL_Free(esxVI_SharedCURL **shared);
146 int esxVI_SharedCURL_Add(esxVI_SharedCURL *shared, esxVI_CURL *curl);
147 int esxVI_SharedCURL_Remove(esxVI_SharedCURL *shared, esxVI_CURL *curl);
148 
149 
150 
151 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
152  * MultiCURL
153  */
154 
155 struct _esxVI_MultiCURL {
156     CURLM *handle;
157     size_t count; /* number of added easy handle */
158 };
159 
160 int esxVI_MultiCURL_Alloc(esxVI_MultiCURL **multi);
161 void esxVI_MultiCURL_Free(esxVI_MultiCURL **multi);
162 int esxVI_MultiCURL_Add(esxVI_MultiCURL *multi, esxVI_CURL *curl);
163 int esxVI_MultiCURL_Remove(esxVI_MultiCURL *multi, esxVI_CURL *curl);
164 int esxVI_MultiCURL_Wait(esxVI_MultiCURL *multi, int *runningHandles);
165 int esxVI_MultiCURL_Perform(esxVI_MultiCURL *multi, int *runningHandles);
166 int esxVI_MultiCURL_CheckFirstMessage(esxVI_MultiCURL *multi, long *responseCode,
167                                       CURLcode *errorCode);
168 
169 
170 
171 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
172  * Context
173  */
174 
175 struct _esxVI_Context {
176     /* All members are used read-only after esxVI_Context_Connect ... */
177     esxVI_CURL *curl;
178     char *url;
179     char *ipAddress;
180     char *username;
181     char *password;
182     esxVI_ServiceContent *service;
183     unsigned long apiVersion; /* = 1000000 * major + 1000 * minor + micro */
184     esxVI_ProductLine productLine;
185     unsigned long productVersion; /* = 1000000 * major + 1000 * minor + micro */
186     esxVI_UserSession *session; /* ... except the session ... */
187     virMutex *sessionLock; /* ... that is protected by this mutex */
188     esxVI_Datacenter *datacenter;
189     char *datacenterPath; /* including folders */
190     esxVI_ComputeResource *computeResource;
191     char *computeResourcePath; /* including folders */
192     esxVI_HostSystem *hostSystem;
193     char *hostSystemName;
194     esxVI_SelectionSpec *selectSet_folderToChildEntity;
195     esxVI_SelectionSpec *selectSet_hostSystemToParent;
196     esxVI_SelectionSpec *selectSet_hostSystemToVm;
197     esxVI_SelectionSpec *selectSet_hostSystemToDatastore;
198     esxVI_SelectionSpec *selectSet_computeResourceToHost;
199     esxVI_SelectionSpec *selectSet_computeResourceToParentToParent;
200     esxVI_SelectionSpec *selectSet_datacenterToNetwork;
201     bool hasQueryVirtualDiskUuid;
202     bool hasSessionIsActive;
203 };
204 
205 int esxVI_Context_Alloc(esxVI_Context **ctx);
206 void esxVI_Context_Free(esxVI_Context **ctx);
207 int esxVI_Context_Connect(esxVI_Context *ctx, const char *url,
208                           const char *ipAddress, const char *username,
209                           const char *password, esxUtil_ParsedUri *parsedUri);
210 int esxVI_Context_LookupManagedObjects(esxVI_Context *ctx);
211 int esxVI_Context_LookupManagedObjectsByPath(esxVI_Context *ctx, const char *path);
212 int esxVI_Context_LookupManagedObjectsByHostSystemIp(esxVI_Context *ctx,
213                                                      const char *hostSystemIPAddress);
214 int esxVI_Context_Execute(esxVI_Context *ctx, const char *methodName,
215                           const char *request, esxVI_Response **response,
216                           esxVI_Occurrence occurrence);
217 
218 
219 
220 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
221  * Response
222  */
223 
224 struct _esxVI_Response {
225     int responseCode;                                 /* required */
226     char *content;                                    /* required */
227     xmlDocPtr document;                               /* optional */
228     xmlNodePtr node;                                  /* optional, list */
229 };
230 
231 int esxVI_Response_Alloc(esxVI_Response **response);
232 void esxVI_Response_Free(esxVI_Response **response);
233 
234 
235 
236 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
237  * Enumeration
238  */
239 
240 struct _esxVI_EnumerationValue {
241     const char *name;
242     int value;
243 };
244 
245 struct _esxVI_Enumeration {
246     esxVI_Type type;
247     esxVI_EnumerationValue values[10];
248 };
249 
250 int esxVI_Enumeration_CastFromAnyType(const esxVI_Enumeration *enumeration,
251                                       esxVI_AnyType *anyType, int *value);
252 int esxVI_Enumeration_Serialize(const esxVI_Enumeration *enumeration,
253                                 int value, const char *element,
254                                 virBuffer *output);
255 int esxVI_Enumeration_Deserialize(const esxVI_Enumeration *enumeration,
256                                   xmlNodePtr node, int *value);
257 
258 
259 
260 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
261  * List
262  */
263 
264 struct _esxVI_List {
265     esxVI_List *_next;
266 };
267 
268 typedef int (*esxVI_List_FreeFunc) (esxVI_List **item);
269 typedef int (*esxVI_List_DeepCopyFunc) (esxVI_List **dest, esxVI_List *src);
270 typedef int (*esxVI_List_CastFromAnyTypeFunc) (esxVI_AnyType *anyType,
271                                                esxVI_List **item);
272 typedef int (*esxVI_List_SerializeFunc) (esxVI_List *item, const char *element,
273                                          virBuffer *output);
274 typedef int (*esxVI_List_DeserializeFunc) (xmlNodePtr node, esxVI_List **item);
275 
276 int esxVI_List_Append(esxVI_List **list, esxVI_List *item);
277 int esxVI_List_DeepCopy(esxVI_List **destList, esxVI_List *srcList,
278                         esxVI_List_DeepCopyFunc deepCopyFunc,
279                         esxVI_List_FreeFunc freeFunc);
280 int esxVI_List_CastFromAnyType(esxVI_AnyType *anyType, esxVI_List **list,
281                                esxVI_List_CastFromAnyTypeFunc castFromAnyTypeFunc,
282                                esxVI_List_FreeFunc freeFunc);
283 int esxVI_List_Serialize(esxVI_List *list, const char *element,
284                          virBuffer *output,
285                          esxVI_List_SerializeFunc serializeFunc);
286 int esxVI_List_Deserialize(xmlNodePtr node, esxVI_List **list,
287                            esxVI_List_DeserializeFunc deserializeFunc,
288                            esxVI_List_FreeFunc freeFunc);
289 
290 
291 
292 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
293  * Utility and Convenience Functions
294  *
295  * Function naming scheme:
296  *  - 'lookup' functions query the ESX or vCenter for information
297  *  - 'get' functions get information from a local object
298  */
299 
300 int esxVI_BuildSelectSet
301       (esxVI_SelectionSpec **selectSet, const char *name,
302        const char *type, const char *path, const char *selectSetNames);
303 
304 int esxVI_BuildSelectSetCollection(esxVI_Context *ctx);
305 
306 int esxVI_EnsureSession(esxVI_Context *ctx);
307 
308 int esxVI_LookupObjectContentByType(esxVI_Context *ctx,
309                                     esxVI_ManagedObjectReference *root,
310                                     const char *type,
311                                     esxVI_String *propertyNameList,
312                                     esxVI_ObjectContent **objectContentList,
313                                     esxVI_Occurrence occurrence);
314 
315 int esxVI_GetManagedEntityStatus
316       (esxVI_ObjectContent *objectContent, const char *propertyName,
317        esxVI_ManagedEntityStatus *managedEntityStatus);
318 
319 int esxVI_GetVirtualMachinePowerState
320       (esxVI_ObjectContent *virtualMachine,
321        esxVI_VirtualMachinePowerState *powerState);
322 
323 int esxVI_GetVirtualMachineQuestionInfo
324       (esxVI_ObjectContent *virtualMachine,
325        esxVI_VirtualMachineQuestionInfo **questionInfo);
326 
327 int esxVI_GetVirtualMachineMORef
328       (esxVI_ObjectContent *virtualMachine,
329        char **moref);
330 
331 int esxVI_GetBoolean(esxVI_ObjectContent *objectContent,
332                      const char *propertyName,
333                      esxVI_Boolean *value, esxVI_Occurrence occurrence);
334 
335 int esxVI_GetInt(esxVI_ObjectContent *objectContent, const char *propertyName,
336                  esxVI_Int **value, esxVI_Occurrence occurrence);
337 
338 int esxVI_GetLong(esxVI_ObjectContent *objectContent, const char *propertyName,
339                   esxVI_Long **value, esxVI_Occurrence occurrence);
340 
341 int esxVI_GetStringValue(esxVI_ObjectContent *objectContent,
342                          const char *propertyName,
343                          char **value, esxVI_Occurrence occurrence);
344 
345 int esxVI_GetManagedObjectReference(esxVI_ObjectContent *objectContent,
346                                     const char *propertyName,
347                                     esxVI_ManagedObjectReference **value,
348                                     esxVI_Occurrence occurrence);
349 
350 int esxVI_LookupNumberOfDomainsByPowerState
351       (esxVI_Context *ctx, esxVI_VirtualMachinePowerState powerState,
352        bool inverse);
353 
354 int esxVI_GetVirtualMachineIdentity(esxVI_ObjectContent *virtualMachine,
355                                     int *id, char **name, unsigned char *uuid);
356 
357 int esxVI_GetNumberOfSnapshotTrees
358       (esxVI_VirtualMachineSnapshotTree *snapshotTreeList,
359        bool recurse, bool leaves);
360 
361 int esxVI_GetSnapshotTreeNames
362       (esxVI_VirtualMachineSnapshotTree *snapshotTreeList, char **names,
363        int nameslen, bool recurse, bool leaves);
364 
365 int esxVI_GetSnapshotTreeByName
366       (esxVI_VirtualMachineSnapshotTree *snapshotTreeList, const char *name,
367        esxVI_VirtualMachineSnapshotTree **snapshotTree,
368        esxVI_VirtualMachineSnapshotTree **snapshotTreeParent,
369        esxVI_Occurrence occurrence);
370 
371 int esxVI_GetSnapshotTreeBySnapshot
372       (esxVI_VirtualMachineSnapshotTree *snapshotTreeList,
373        esxVI_ManagedObjectReference *snapshot,
374        esxVI_VirtualMachineSnapshotTree **snapshotTree);
375 
376 int esxVI_LookupHostSystemProperties(esxVI_Context *ctx,
377                                      esxVI_String *propertyNameList,
378                                      esxVI_ObjectContent **hostSystem);
379 
380 int esxVI_LookupVirtualMachineList(esxVI_Context *ctx,
381                                    esxVI_String *propertyNameList,
382                                    esxVI_ObjectContent **virtualMachineList);
383 
384 int esxVI_LookupVirtualMachineByUuid(esxVI_Context *ctx,
385                                      const unsigned char *uuid,
386                                      esxVI_String *propertyNameList,
387                                      esxVI_ObjectContent **virtualMachine,
388                                      esxVI_Occurrence occurrence);
389 
390 int esxVI_LookupVirtualMachineByName(esxVI_Context *ctx, const char *name,
391                                      esxVI_String *propertyNameList,
392                                      esxVI_ObjectContent **virtualMachine,
393                                      esxVI_Occurrence occurrence);
394 
395 int esxVI_LookupVirtualMachineByUuidAndPrepareForTask
396       (esxVI_Context *ctx, const unsigned char *uuid,
397        esxVI_String *propertyNameList, esxVI_ObjectContent **virtualMachine,
398        bool autoAnswer);
399 
400 int esxVI_LookupDatastoreList(esxVI_Context *ctx, esxVI_String *propertyNameList,
401                               esxVI_ObjectContent **datastoreList);
402 
403 int esxVI_LookupDatastoreByName(esxVI_Context *ctx, const char *name,
404                                 esxVI_String *propertyNameList,
405                                 esxVI_ObjectContent **datastore,
406                                 esxVI_Occurrence occurrence);
407 
408 int esxVI_LookupDatastoreByAbsolutePath(esxVI_Context *ctx,
409                                         const char *absolutePath,
410                                         esxVI_String *propertyNameList,
411                                         esxVI_ObjectContent **datastore,
412                                         esxVI_Occurrence occurrence);
413 
414 int esxVI_LookupDatastoreHostMount(esxVI_Context *ctx,
415                                    esxVI_ManagedObjectReference *datastore,
416                                    esxVI_DatastoreHostMount **hostMount,
417                                    esxVI_Occurrence occurrence);
418 
419 int esxVI_LookupTaskInfoByTask(esxVI_Context *ctx,
420                                esxVI_ManagedObjectReference *task,
421                                esxVI_TaskInfo **taskInfo);
422 
423 int esxVI_LookupPendingTaskInfoListByVirtualMachine
424       (esxVI_Context *ctx, esxVI_ObjectContent *virtualMachine,
425        esxVI_TaskInfo **pendingTaskInfoList);
426 
427 int esxVI_LookupAndHandleVirtualMachineQuestion(esxVI_Context *ctx,
428                                                 const unsigned char *uuid,
429                                                 esxVI_Occurrence occurrence,
430                                                 bool autoAnswer, bool *blocked);
431 
432 int esxVI_LookupRootSnapshotTreeList
433       (esxVI_Context *ctx, const unsigned char *virtualMachineUuid,
434        esxVI_VirtualMachineSnapshotTree **rootSnapshotTreeList);
435 
436 int esxVI_LookupCurrentSnapshotTree
437       (esxVI_Context *ctx, const unsigned char *virtualMachineUuid,
438        esxVI_VirtualMachineSnapshotTree **currentSnapshotTree,
439        esxVI_Occurrence occurrence);
440 
441 int esxVI_LookupFileInfoByDatastorePath(esxVI_Context *ctx,
442                                         const char *datastorePath,
443                                         bool lookupFolder,
444                                         esxVI_FileInfo **fileInfo,
445                                         esxVI_Occurrence occurrence);
446 
447 int esxVI_LookupDatastoreContentByDatastoreName
448       (esxVI_Context *ctx, const char *datastoreName,
449        esxVI_HostDatastoreBrowserSearchResults **searchResultsList);
450 
451 int esxVI_LookupStorageVolumeKeyByDatastorePath(esxVI_Context *ctx,
452                                                 const char *datastorePath,
453                                                 char **key);
454 
455 int esxVI_LookupAutoStartDefaults(esxVI_Context *ctx,
456                                   esxVI_AutoStartDefaults **defaults);
457 
458 int esxVI_LookupAutoStartPowerInfoList(esxVI_Context *ctx,
459                                        esxVI_AutoStartPowerInfo **powerInfoList);
460 
461 int esxVI_LookupPhysicalNicList(esxVI_Context *ctx,
462                                 esxVI_PhysicalNic **physicalNicList);
463 
464 int esxVI_LookupPhysicalNicByName(esxVI_Context *ctx, const char *name,
465                                   esxVI_PhysicalNic **physicalNic,
466                                   esxVI_Occurrence occurrence);
467 
468 int esxVI_LookupPhysicalNicByMACAddress(esxVI_Context *ctx, const char *mac,
469                                         esxVI_PhysicalNic **physicalNic,
470                                         esxVI_Occurrence occurrence);
471 
472 int esxVI_LookupHostVirtualSwitchList
473       (esxVI_Context *ctx, esxVI_HostVirtualSwitch **hostVirtualSwitchList);
474 
475 int esxVI_LookupHostVirtualSwitchByName(esxVI_Context *ctx, const char *name,
476                                         esxVI_HostVirtualSwitch **hostVirtualSwitch,
477                                         esxVI_Occurrence occurrence);
478 
479 int esxVI_LookupHostPortGroupList(esxVI_Context *ctx,
480                                   esxVI_HostPortGroup **hostPortGroupList);
481 
482 int esxVI_LookupNetworkList(esxVI_Context *ctx, esxVI_String *propertyNameList,
483                             esxVI_ObjectContent **networkList);
484 
485 int esxVI_HandleVirtualMachineQuestion
486       (esxVI_Context *ctx, esxVI_ManagedObjectReference *virtualMachine,
487        esxVI_VirtualMachineQuestionInfo *questionInfo, bool autoAnswer,
488        bool *blocked);
489 
490 int esxVI_WaitForTaskCompletion(esxVI_Context *ctx,
491                                 esxVI_ManagedObjectReference *task,
492                                 const unsigned char *virtualMachineUuid,
493                                 esxVI_Occurrence virtualMachineOccurrence,
494                                 bool autoAnswer,
495                                 esxVI_TaskInfoState *finalState,
496                                 char **errorMessage);
497 
498 int esxVI_ParseHostCpuIdInfo(esxVI_ParsedHostCpuIdInfo *parsedHostCpuIdInfo,
499                              esxVI_HostCpuIdInfo *hostCpuIdInfo);
500 
501 const char *esxVI_ProductLineToDisplayName(esxVI_ProductLine productLine);
502 
503 int esxVI_ProductVersionToDefaultVirtualHWVersion
504       (esxVI_ProductLine productLine, unsigned long productVersion);
505 
506 int esxVI_LookupHostInternetScsiHbaStaticTargetByName
507       (esxVI_Context *ctx, const char *name,
508        esxVI_HostInternetScsiHbaStaticTarget **target,
509        esxVI_Occurrence occurrence);
510 
511 int esxVI_LookupHostInternetScsiHba
512       (esxVI_Context *ctx, esxVI_HostInternetScsiHba **hostInternetScsiHba);
513 
514 int esxVI_LookupScsiLunList(esxVI_Context *ctx, esxVI_ScsiLun **scsiLunList);
515 
516 int esxVI_LookupHostScsiTopologyLunListByTargetName
517       (esxVI_Context *ctx, const char *name,
518        esxVI_HostScsiTopologyLun **hostScsiTopologyLunList);
519 
520 int esxVI_LookupStoragePoolNameByScsiLunKey(esxVI_Context *ctx, const char *key,
521                                             char **poolName);
522 
523 #include "esx_vi.generated.h"
524