[libvirt] [PATCH] esx: Extend VI generator to cover managed object types

Matthias Bolte matthias.bolte at googlemail.com
Sun Apr 10 11:27:56 UTC 2011


Generate lookup functions for managed object types.
---
 src/esx/esx_vi.c               |  414 +++++++++++++++++++++++-----------------
 src/esx/esx_vi.h               |    2 +
 src/esx/esx_vi_generator.input |   28 +++-
 src/esx/esx_vi_generator.py    |  411 ++++++++++++++++++++++++++++++++++++++--
 src/esx/esx_vi_types.c         |  349 ++++++----------------------------
 src/esx/esx_vi_types.h         |  102 ++---------
 6 files changed, 728 insertions(+), 578 deletions(-)

diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index 7446ec5..fbab347 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -3,7 +3,7 @@
  * esx_vi.c: client for the VMware VI API 2.5 to manage ESX hosts
  *
  * Copyright (C) 2010 Red Hat, Inc.
- * Copyright (C) 2009-2010 Matthias Bolte <matthias.bolte at googlemail.com>
+ * Copyright (C) 2009-2011 Matthias Bolte <matthias.bolte at googlemail.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -481,107 +481,26 @@ int
 esxVI_Context_LookupObjectsByPath(esxVI_Context *ctx,
                                   esxUtil_ParsedUri *parsedUri)
 {
-    int result = -1;
-    esxVI_String *propertyNameList = NULL;
-    char *name = NULL;
-    esxVI_ObjectContent *datacenterList = NULL;
-    esxVI_ObjectContent *datacenter = NULL;
-    esxVI_ObjectContent *computeResourceList = NULL;
-    esxVI_ObjectContent *computeResource = NULL;
     char *hostSystemName = NULL;
-    esxVI_ObjectContent *hostSystemList = NULL;
-    esxVI_ObjectContent *hostSystem = NULL;
-
     /* Lookup Datacenter */
-    if (esxVI_String_AppendValueListToList(&propertyNameList,
-                                           "name\0"
-                                           "vmFolder\0"
-                                           "hostFolder\0") < 0 ||
-        esxVI_LookupObjectContentByType(ctx, ctx->service->rootFolder,
-                                        "Datacenter", propertyNameList,
-                                        &datacenterList,
-                                        esxVI_Occurrence_RequiredList) < 0) {
-        goto cleanup;
-    }
-
-    if (parsedUri->path_datacenter != NULL) {
-        for (datacenter = datacenterList; datacenter != NULL;
-             datacenter = datacenter->_next) {
-            name = NULL;
-
-            if (esxVI_GetStringValue(datacenter, "name", &name,
-                                     esxVI_Occurrence_RequiredItem) < 0) {
-                goto cleanup;
-            }
-
-            if (STREQ(name, parsedUri->path_datacenter)) {
-                break;
-            }
-        }
-
-        if (datacenter == NULL) {
-            ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
-                         _("Could not find datacenter '%s'"),
-                         parsedUri->path_datacenter);
-            goto cleanup;
-        }
-    } else {
-        datacenter = datacenterList;
-    }
-
-    if (esxVI_Datacenter_CastFromObjectContent(datacenter,
-                                               &ctx->datacenter) < 0) {
-        goto cleanup;
+    if (esxVI_LookupDatacenter(ctx, parsedUri->path_datacenter,
+                               ctx->service->rootFolder, NULL, &ctx->datacenter,
+                               esxVI_Occurrence_RequiredItem) < 0) {
+        return -1;
     }
 
     /* Lookup (Cluster)ComputeResource */
-    esxVI_String_Free(&propertyNameList);
-
-    if (esxVI_String_AppendValueListToList(&propertyNameList,
-                                           "name\0"
-                                           "host\0"
-                                           "resourcePool\0") < 0 ||
-        esxVI_LookupObjectContentByType(ctx, ctx->datacenter->hostFolder,
-                                        "ComputeResource", propertyNameList,
-                                        &computeResourceList,
-                                        esxVI_Occurrence_RequiredList) < 0) {
-        goto cleanup;
-    }
-
-    if (parsedUri->path_computeResource != NULL) {
-        for (computeResource = computeResourceList; computeResource != NULL;
-             computeResource = computeResource->_next) {
-            name = NULL;
-
-            if (esxVI_GetStringValue(computeResource, "name", &name,
-                                     esxVI_Occurrence_RequiredItem) < 0) {
-                goto cleanup;
-            }
-
-            if (STREQ(name, parsedUri->path_computeResource)) {
-                break;
-            }
-        }
-
-        if (computeResource == NULL) {
-            ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
-                         _("Could not find compute resource '%s'"),
-                         parsedUri->path_computeResource);
-            goto cleanup;
-        }
-    } else {
-        computeResource = computeResourceList;
-    }
-
-    if (esxVI_ComputeResource_CastFromObjectContent(computeResource,
-                                                    &ctx->computeResource) < 0) {
-        goto cleanup;
+    if (esxVI_LookupComputeResource(ctx, parsedUri->path_computeResource,
+                                    ctx->datacenter->hostFolder, NULL,
+                                    &ctx->computeResource,
+                                    esxVI_Occurrence_RequiredItem) < 0) {
+        return -1;
     }
 
     if (ctx->computeResource->resourcePool == NULL) {
         ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
                      _("Could not retrieve resource pool"));
-        goto cleanup;
+        return -1;
     }
 
     /* Lookup HostSystem */
@@ -590,19 +509,7 @@ esxVI_Context_LookupObjectsByPath(esxVI_Context *ctx,
               "ClusterComputeResource")) {
         ESX_VI_ERROR(VIR_ERR_INVALID_ARG, "%s",
                      _("Path has to specify the host system"));
-        goto cleanup;
-    }
-
-    esxVI_String_Free(&propertyNameList);
-
-    if (esxVI_String_AppendValueListToList(&propertyNameList,
-                                           "name\0"
-                                           "configManager\0") < 0 ||
-        esxVI_LookupObjectContentByType(ctx, ctx->computeResource->_reference,
-                                        "HostSystem", propertyNameList,
-                                        &hostSystemList,
-                                        esxVI_Occurrence_RequiredList) < 0) {
-        goto cleanup;
+        return -1;
     }
 
     if (parsedUri->path_hostSystem != NULL ||
@@ -613,44 +520,16 @@ esxVI_Context_LookupObjectsByPath(esxVI_Context *ctx,
         } else {
             hostSystemName = parsedUri->path_computeResource;
         }
-
-        for (hostSystem = hostSystemList; hostSystem != NULL;
-             hostSystem = hostSystem->_next) {
-            name = NULL;
-
-            if (esxVI_GetStringValue(hostSystem, "name", &name,
-                                     esxVI_Occurrence_RequiredItem) < 0) {
-                goto cleanup;
-            }
-
-            if (STREQ(name, hostSystemName)) {
-                break;
-            }
-        }
-
-        if (hostSystem == NULL) {
-            ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
-                         _("Could not find host system '%s'"), hostSystemName);
-            goto cleanup;
-        }
-    } else {
-        hostSystem = hostSystemList;
     }
 
-    if (esxVI_HostSystem_CastFromObjectContent(hostSystem,
-                                               &ctx->hostSystem) < 0) {
-        goto cleanup;
+    if (esxVI_LookupHostSystem(ctx, hostSystemName,
+                               ctx->computeResource->_reference, NULL,
+                               &ctx->hostSystem,
+                               esxVI_Occurrence_RequiredItem) < 0) {
+        return -1;
     }
 
-    result = 0;
-
-  cleanup:
-    esxVI_String_Free(&propertyNameList);
-    esxVI_ObjectContent_Free(&datacenterList);
-    esxVI_ObjectContent_Free(&computeResourceList);
-    esxVI_ObjectContent_Free(&hostSystemList);
-
-    return result;
+    return 0;
 }
 
 int
@@ -658,67 +537,41 @@ esxVI_Context_LookupObjectsByHostSystemIp(esxVI_Context *ctx,
                                           const char *hostSystemIpAddress)
 {
     int result = -1;
-    esxVI_String *propertyNameList = NULL;
     esxVI_ManagedObjectReference *managedObjectReference = NULL;
-    esxVI_ObjectContent *hostSystem = NULL;
-    esxVI_ObjectContent *computeResource = NULL;
-    esxVI_ObjectContent *datacenter = NULL;
 
     /* Lookup HostSystem */
-    if (esxVI_String_AppendValueListToList(&propertyNameList,
-                                           "name\0"
-                                           "configManager\0") < 0 ||
-        esxVI_FindByIp(ctx, NULL, hostSystemIpAddress, esxVI_Boolean_False,
+    if (esxVI_FindByIp(ctx, NULL, hostSystemIpAddress, esxVI_Boolean_False,
                        &managedObjectReference) < 0 ||
-        esxVI_LookupObjectContentByType(ctx, managedObjectReference,
-                                        "HostSystem", propertyNameList,
-                                        &hostSystem,
-                                        esxVI_Occurrence_RequiredItem) < 0 ||
-        esxVI_HostSystem_CastFromObjectContent(hostSystem,
-                                               &ctx->hostSystem) < 0) {
+        esxVI_LookupHostSystem(ctx, NULL, managedObjectReference, NULL,
+                               &ctx->hostSystem,
+                               esxVI_Occurrence_RequiredItem) < 0) {
         goto cleanup;
     }
 
     /* Lookup (Cluster)ComputeResource */
-    esxVI_String_Free(&propertyNameList);
+    if (esxVI_LookupComputeResource(ctx, NULL, ctx->hostSystem->_reference,
+                                    NULL, &ctx->computeResource,
+                                    esxVI_Occurrence_RequiredItem) < 0) {
+        goto cleanup;
+    }
 
-    if (esxVI_String_AppendValueListToList(&propertyNameList,
-                                           "name\0"
-                                           "host\0"
-                                           "resourcePool\0") < 0 ||
-        esxVI_LookupObjectContentByType(ctx, hostSystem->obj,
-                                        "ComputeResource", propertyNameList,
-                                        &computeResource,
-                                        esxVI_Occurrence_RequiredItem) < 0 ||
-        esxVI_ComputeResource_CastFromObjectContent(computeResource,
-                                                    &ctx->computeResource) < 0) {
+    if (ctx->computeResource->resourcePool == NULL) {
+        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+                     _("Could not retrieve resource pool"));
         goto cleanup;
     }
 
     /* Lookup Datacenter */
-    esxVI_String_Free(&propertyNameList);
-
-    if (esxVI_String_AppendValueListToList(&propertyNameList,
-                                           "name\0"
-                                           "vmFolder\0"
-                                           "hostFolder\0") < 0 ||
-        esxVI_LookupObjectContentByType(ctx, computeResource->obj,
-                                        "Datacenter", propertyNameList,
-                                        &datacenter,
-                                        esxVI_Occurrence_RequiredItem) < 0 ||
-        esxVI_Datacenter_CastFromObjectContent(datacenter,
-                                               &ctx->datacenter) < 0) {
+    if (esxVI_LookupDatacenter(ctx, NULL, ctx->computeResource->_reference,
+                               NULL, &ctx->datacenter,
+                               esxVI_Occurrence_RequiredItem) < 0) {
         goto cleanup;
     }
 
     result = 0;
 
   cleanup:
-    esxVI_String_Free(&propertyNameList);
     esxVI_ManagedObjectReference_Free(&managedObjectReference);
-    esxVI_ObjectContent_Free(&hostSystem);
-    esxVI_ObjectContent_Free(&computeResource);
-    esxVI_ObjectContent_Free(&datacenter);
 
     return result;
 }
@@ -3872,3 +3725,204 @@ esxVI_ProductVersionToDefaultVirtualHWVersion(esxVI_ProductVersion productVersio
         return -1;
     }
 }
+
+
+
+
+#define ESX_VI__TEMPLATE__PROPERTY__CAST_FROM_ANY_TYPE_IGNORE(_name)          \
+    if (STREQ(dynamicProperty->name, #_name)) {                               \
+        continue;                                                             \
+    }
+
+
+
+#define ESX_VI__TEMPLATE__PROPERTY__CAST_FROM_ANY_TYPE(_type, _name)          \
+    if (STREQ(dynamicProperty->name, #_name)) {                               \
+        if (esxVI_##_type##_CastFromAnyType(dynamicProperty->val,             \
+                                            &(*ptrptr)->_name) < 0) {         \
+            goto cleanup;                                                     \
+        }                                                                     \
+                                                                              \
+        continue;                                                             \
+    }
+
+
+
+#define ESX_VI__TEMPLATE__PROPERTY__CAST_LIST_FROM_ANY_TYPE(_type, _name)     \
+    if (STREQ(dynamicProperty->name, #_name)) {                               \
+        if (esxVI_##_type##_CastListFromAnyType(dynamicProperty->val,         \
+                                            &(*ptrptr)->_name) < 0) {         \
+            goto cleanup;                                                     \
+        }                                                                     \
+                                                                              \
+        continue;                                                             \
+    }
+
+
+
+#define ESX_VI__TEMPLATE__PROPERTY__CAST_VALUE_FROM_ANY_TYPE(_type, _name)    \
+    if (STREQ(dynamicProperty->name, #_name)) {                               \
+        if (esxVI_##_type##_CastValueFromAnyType(dynamicProperty->val,        \
+                                            &(*ptrptr)->_name) < 0) {         \
+            goto cleanup;                                                     \
+        }                                                                     \
+                                                                              \
+        continue;                                                             \
+    }
+
+
+
+#define ESX_VI__TEMPLATE__LOOKUP(_type, _complete_properties,                 \
+                                         _cast_from_anytype)                  \
+    int                                                                       \
+    esxVI_Lookup##_type(esxVI_Context *ctx, const char* name /* optional */,  \
+                        esxVI_ManagedObjectReference *root,                   \
+                        esxVI_String *selectedPropertyNameList /* optional */,\
+                        esxVI_##_type **ptrptr, esxVI_Occurrence occurrence)  \
+    {                                                                         \
+        int result = -1;                                                      \
+        const char *completePropertyNameValueList = _complete_properties;     \
+        esxVI_String *propertyNameList = NULL;                                \
+        esxVI_ObjectContent *objectContent = NULL;                            \
+        esxVI_ObjectContent *objectContentList = NULL;                        \
+        esxVI_DynamicProperty *dynamicProperty = NULL;                        \
+                                                                              \
+        if (ptrptr == NULL || *ptrptr != NULL) {                              \
+            ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",                        \
+                         _("Invalid argument"));                              \
+            return -1;                                                        \
+        }                                                                     \
+                                                                              \
+        propertyNameList = selectedPropertyNameList;                          \
+                                                                              \
+        if (propertyNameList == NULL &&                                       \
+            esxVI_String_AppendValueListToList                                \
+              (&propertyNameList, completePropertyNameValueList) < 0) {       \
+            goto cleanup;                                                     \
+        }                                                                     \
+                                                                              \
+        if (esxVI_LookupManagedObjectHelper(ctx, name, root, #_type,          \
+                                            propertyNameList, &objectContent, \
+                                            &objectContentList,               \
+                                            occurrence) < 0) {                \
+            goto cleanup;                                                     \
+        }                                                                     \
+                                                                              \
+        if (esxVI_##_type##_Alloc(ptrptr) < 0) {                              \
+            goto cleanup;                                                     \
+        }                                                                     \
+                                                                              \
+        if (esxVI_ManagedObjectReference_DeepCopy(&(*ptrptr)->_reference,     \
+                                                  objectContent->obj) < 0) {  \
+            goto cleanup;                                                     \
+        }                                                                     \
+                                                                              \
+        for (dynamicProperty = objectContent->propSet;                        \
+             dynamicProperty != NULL;                                         \
+             dynamicProperty = dynamicProperty->_next) {                      \
+            _cast_from_anytype                                                \
+                                                                              \
+            VIR_WARN("Unexpected '%s' property", dynamicProperty->name);      \
+        }                                                                     \
+                                                                              \
+        if (esxVI_##_type##_Validate(*ptrptr, selectedPropertyNameList) < 0) {\
+            goto cleanup;                                                     \
+        }                                                                     \
+                                                                              \
+        result = 0;                                                           \
+                                                                              \
+      cleanup:                                                                \
+        if (result < 0) {                                                     \
+            esxVI_##_type##_Free(ptrptr);                                     \
+        }                                                                     \
+                                                                              \
+        if (propertyNameList != selectedPropertyNameList) {                   \
+            esxVI_String_Free(&propertyNameList);                             \
+        }                                                                     \
+                                                                              \
+        esxVI_ObjectContent_Free(&objectContentList);                         \
+                                                                              \
+        return result;                                                        \
+    }
+
+
+
+static int
+esxVI_LookupManagedObjectHelper(esxVI_Context *ctx,
+                                const char *name /* optional */,
+                                esxVI_ManagedObjectReference *root,
+                                const char *type,
+                                esxVI_String *propertyNameList,
+                                esxVI_ObjectContent **objectContent,
+                                esxVI_ObjectContent **objectContentList,
+                                esxVI_Occurrence occurrence)
+{
+    int result = -1;
+    esxVI_ObjectContent *candidate = NULL;
+    char *name_candidate;
+
+    if (objectContent == NULL || *objectContent != NULL ||
+        objectContentList == NULL || *objectContentList != NULL) {
+        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
+        return -1;
+    }
+
+    if (!esxVI_String_ListContainsValue(propertyNameList, "name")) {
+        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
+                     _("Missing 'name' property in %s lookup"), type);
+        goto cleanup;
+    }
+
+    if (esxVI_LookupObjectContentByType(ctx, root, type, propertyNameList,
+                                        objectContentList,
+                                        esxVI_Occurrence_OptionalList) < 0) {
+        goto cleanup;
+    }
+
+    /* Search for a matching item */
+    if (name != NULL) {
+        for (candidate = *objectContentList; candidate != NULL;
+             candidate = candidate->_next) {
+            name_candidate = NULL;
+
+            if (esxVI_GetStringValue(candidate, "name", &name_candidate,
+                                     esxVI_Occurrence_RequiredItem) < 0) {
+                goto cleanup;
+            }
+
+            if (STREQ(name_candidate, name)) {
+                /* Found item with matching name */
+                break;
+            }
+        }
+    } else {
+        candidate = *objectContentList;
+    }
+
+    if (candidate == NULL) {
+        if (occurrence != esxVI_Occurrence_OptionalItem) {
+            ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
+                         _("Could not find %s with name '%s'"), type, name);
+            goto cleanup;
+        }
+
+        result = 0;
+
+        goto cleanup;
+    }
+
+    result = 0;
+
+  cleanup:
+    if (result < 0) {
+        esxVI_ObjectContent_Free(objectContentList);
+    } else {
+        *objectContent = candidate;
+    }
+
+    return result;
+}
+
+
+
+#include "esx_vi.generated.c"
diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h
index e150dbf..d046bf9 100644
--- a/src/esx/esx_vi.h
+++ b/src/esx/esx_vi.h
@@ -444,4 +444,6 @@ int esxVI_ParseHostCpuIdInfo(esxVI_ParsedHostCpuIdInfo *parsedHostCpuIdInfo,
 
 int esxVI_ProductVersionToDefaultVirtualHWVersion(esxVI_ProductVersion productVersion);
 
+# include "esx_vi.generated.h"
+
 #endif /* __ESX_VI_H__ */
diff --git a/src/esx/esx_vi_generator.input b/src/esx/esx_vi_generator.input
index 44d1d9b..98b5206 100644
--- a/src/esx/esx_vi_generator.input
+++ b/src/esx/esx_vi_generator.input
@@ -15,7 +15,7 @@
 #
 # Object definition:
 #
-# object <name> [extends <name>]
+# [managed] object <name> [extends <name>]
 #     <type> <name> <occurrence>
 #     ...
 # end
@@ -739,6 +739,32 @@ end
 
 
 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+# Managed Objects
+#
+
+managed object ComputeResource extends ManagedEntity
+    ManagedObjectReference                   host                           ol
+    ManagedObjectReference                   resourcePool                   o
+end
+
+
+managed object Datacenter extends ManagedEntity
+    ManagedObjectReference                   hostFolder                     r
+    ManagedObjectReference                   vmFolder                       r
+end
+
+
+managed object HostSystem extends ManagedEntity
+    HostConfigManager                        configManager                  r
+end
+
+
+managed object ManagedEntity
+    String                                   name                           r
+end
+
+
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
 # Methods
 #
 
diff --git a/src/esx/esx_vi_generator.py b/src/esx/esx_vi_generator.py
index 0fd84dd..ab127a3 100755
--- a/src/esx/esx_vi_generator.py
+++ b/src/esx/esx_vi_generator.py
@@ -3,7 +3,7 @@
 #
 # esx_vi_generator.py: generates most of the SOAP type mapping code
 #
-# Copyright (C) 2010 Matthias Bolte <matthias.bolte at googlemail.com>
+# Copyright (C) 2010-2011 Matthias Bolte <matthias.bolte at googlemail.com>
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -297,10 +297,15 @@ class Property:
                 return "    esxVI_%s_Free(&item->%s);\n" % (self.type, self.name)
 
 
-    def generate_validate_code(self):
+    def generate_validate_code(self, managed=False):
+        if managed:
+            macro = "ESX_VI__TEMPLATE__PROPERTY__MANAGED_REQUIRE"
+        else:
+            macro = "ESX_VI__TEMPLATE__PROPERTY__REQUIRE"
+
         if self.occurrence in [OCCURRENCE__REQUIRED_ITEM,
                                OCCURRENCE__REQUIRED_LIST]:
-            return "    ESX_VI__TEMPLATE__PROPERTY__REQUIRE(%s)\n" % self.name
+            return "    %s(%s)\n" % (macro, self.name)
         elif self.occurrence == OCCURRENCE__IGNORED:
             return "    /* FIXME: %s is currently ignored */\n" % self.name
         else:
@@ -345,6 +350,18 @@ class Property:
             return "    ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE(%s, %s)\n" % (self.type, self.name)
 
 
+    def generate_lookup_code(self):
+        if self.occurrence == OCCURRENCE__IGNORED:
+            return "    ESX_VI__TEMPLATE__PROPERTY__CAST_FROM_ANY_TYPE_IGNORE(%s) /* FIXME */\n" % self.name
+        elif self.occurrence in [OCCURRENCE__REQUIRED_LIST,
+                                 OCCURRENCE__OPTIONAL_LIST]:
+            return "    ESX_VI__TEMPLATE__PROPERTY__CAST_LIST_FROM_ANY_TYPE(%s, %s)\n" % (self.type, self.name)
+        elif self.type == "String":
+            return "    ESX_VI__TEMPLATE__PROPERTY__CAST_VALUE_FROM_ANY_TYPE(String, %s)\n" % self.name
+        else:
+            return "    ESX_VI__TEMPLATE__PROPERTY__CAST_FROM_ANY_TYPE(%s, %s)\n" % (self.type, self.name)
+
+
     def get_type_string(self):
         if self.type == "String" and \
            self.occurrence not in [OCCURRENCE__REQUIRED_LIST,
@@ -572,20 +589,20 @@ class Object(Base):
 
     def generate_header(self):
         header = "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n"
-        header += " * VI Type: %s\n" % self.name
+        header += " * VI Object: %s\n" % self.name
 
         if self.extends is not None:
-            header += " *          extends %s\n" % self.extends
+            header += " *            extends %s\n" % self.extends
 
         first = True
 
         if self.extended_by is not None:
             for extended_by in self.extended_by:
                 if first:
-                    header += " *          extended by %s\n" % extended_by
+                    header += " *            extended by %s\n" % extended_by
                     first = False
                 else:
-                    header += " *                      %s\n" % extended_by
+                    header += " *                        %s\n" % extended_by
 
         header += " */\n\n"
 
@@ -646,20 +663,20 @@ class Object(Base):
 
     def generate_source(self):
         source = "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n"
-        source += " * VI Type: %s\n" % self.name
+        source += " * VI Object: %s\n" % self.name
 
         if self.extends is not None:
-            source += " *          extends %s\n" % self.extends
+            source += " *            extends %s\n" % self.extends
 
         first = True
 
         if self.extended_by is not None:
             for extended_by in self.extended_by:
                 if first:
-                    source += " *          extended by %s\n" % extended_by
+                    source += " *            extended by %s\n" % extended_by
                     first = False
                 else:
-                    source += " *                      %s\n" % extended_by
+                    source += " *                        %s\n" % extended_by
 
         source += " */\n\n"
 
@@ -863,15 +880,303 @@ class Object(Base):
 
 
 
+class ManagedObject(Base):
+    FEATURE__LIST = (1 << 2)
+
+
+    def __init__(self, name, extends, properties, features=0, extended_by=None):
+        Base.__init__(self, "struct", name)
+        self.extends = extends
+        self.features = features
+        self.properties = properties
+        self.extended_by = extended_by
+
+        if self.extended_by is not None:
+            self.extended_by.sort()
+
+
+    def generate_struct_members(self, add_banner=False, struct_gap=False):
+        members = ""
+
+        if struct_gap:
+            members += "\n"
+
+        if self.extends is not None:
+            members += managed_objects_by_name[self.extends].generate_struct_members(add_banner=True) + "\n"
+
+        if self.extends is not None or add_banner:
+            members += "    /* %s */\n" % self.name
+
+        for property in self.properties:
+            members += property.generate_struct_member()
+
+        if len(self.properties) < 1:
+            members += "    /* no properties */\n"
+
+        return members
+
+
+    def generate_free_code(self, add_banner=False):
+        source = ""
 
+        if self.extends is not None:
+            source += managed_objects_by_name[self.extends].generate_free_code(add_banner=True) + "\n"
 
+        if self.extends is not None or add_banner:
+            source += "    /* %s */\n" % self.name
 
+        if len(self.properties) < 1:
+            source += "    /* no properties */\n"
+        else:
+            string = ""
 
+            for property in self.properties:
+                string += property.generate_free_code()
 
+            if len(string) < 1:
+                source += "    /* no properties to be freed */\n"
+            else:
+                source += string
 
+        return source
 
 
+    def generate_validate_code(self, add_banner=False):
+        source = ""
+
+        if self.extends is not None:
+            source += managed_objects_by_name[self.extends].generate_validate_code(add_banner=True) + "\n"
+
+        if self.extends is not None or add_banner:
+            source += "    /* %s */\n" % self.name
+
+        if len(self.properties) < 1:
+            source += "    /* no properties */\n"
+        else:
+            string = ""
 
+            for property in self.properties:
+                string += property.generate_validate_code(managed=True)
+
+            if len(string) < 1:
+                source += "    /* no required properties */\n"
+            else:
+                source += string
+
+        return source
+
+
+    def generate_lookup_code1(self, add_banner=False):
+        source = ""
+
+        if self.extends is not None:
+            source += managed_objects_by_name[self.extends].generate_lookup_code1(add_banner=True) + "\n"
+
+        if self.extends is not None or add_banner:
+            source += "    /* %s */\n" % self.name
+
+        if len(self.properties) < 1:
+            source += "    /* no properties */\n"
+        else:
+            string = ""
+
+            for property in self.properties:
+                string += "    \"%s\\0\"\n" % property.name
+
+            if len(string) < 1:
+                source += "    /* no properties */\n"
+            else:
+                source += string
+
+        return source
+
+
+    def generate_lookup_code2(self, add_banner=False):
+        source = ""
+
+        if self.extends is not None:
+            source += managed_objects_by_name[self.extends].generate_lookup_code2(add_banner=True) + "\n"
+
+        if self.extends is not None or add_banner:
+            source += "    /* %s */\n" % self.name
+
+        if len(self.properties) < 1:
+            source += "    /* no properties */\n"
+        else:
+            string = ""
+
+            for property in self.properties:
+                string += property.generate_lookup_code()
+
+            if len(string) < 1:
+                source += "    /* no properties */\n"
+            else:
+                source += string
+
+        return source
+
+
+    def generate_comment(self):
+        comment = "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n"
+        comment += " * VI Managed Object: %s\n" % self.name
+
+        if self.extends is not None:
+            comment += " *                    extends %s\n" % self.extends
+
+        first = True
+
+        if self.extended_by is not None:
+            for extended_by in self.extended_by:
+                if first:
+                    comment += " *                    extended by %s\n" % extended_by
+                    first = False
+                else:
+                    comment += " *                                %s\n" % extended_by
+
+        comment += " */\n\n"
+
+        return comment
+
+
+    def generate_header(self):
+        header = self.generate_comment()
+
+        # struct
+        header += "struct _esxVI_%s {\n" % self.name
+
+        if self.features & Object.FEATURE__LIST:
+            header += aligned("    esxVI_%s *_next; " % self.name, "/* optional */\n")
+        else:
+            header += aligned("    esxVI_%s *_unused; " % self.name, "/* optional */\n")
+
+        header += aligned("    esxVI_Type _type; ", "/* required */\n")
+        header += aligned("    esxVI_ManagedObjectReference *_reference; ", "/* required */\n")
+        header += "\n"
+        header += self.generate_struct_members()
+
+        header += "};\n\n"
+
+        # functions
+        header += "int esxVI_%s_Alloc(esxVI_%s **item);\n" % (self.name, self.name)
+        header += "void esxVI_%s_Free(esxVI_%s **item);\n" % (self.name, self.name)
+        header += "int esxVI_%s_Validate(esxVI_%s *item, esxVI_String *selectedPropertyNameList);\n" % (self.name, self.name)
+
+        if self.features & Object.FEATURE__LIST:
+            header += "int esxVI_%s_AppendToList(esxVI_%s **list, esxVI_%s *item);\n" % (self.name, self.name, self.name)
+
+        header += "\n\n\n"
+
+        return header
+
+
+    def generate_helper_header(self):
+        header = ""
+
+        # functions
+        header += ("int esxVI_Lookup%s(esxVI_Context *ctx, " +
+                                      "const char *name, " +
+                                      "esxVI_ManagedObjectReference *root, " +
+                                      "esxVI_String *selectedPropertyNameList, " +
+                                      "esxVI_%s **item, " +
+                                      "esxVI_Occurrence occurrence);\n") % (self.name, self.name)
+
+        header += "\n"
+
+        return header
+
+
+    def generate_source(self):
+        source = self.generate_comment()
+
+        # functions
+        source += "/* esxVI_%s_Alloc */\n" % self.name
+        source += "ESX_VI__TEMPLATE__ALLOC(%s)\n\n" % self.name
+
+        # free
+        if self.extended_by is None:
+            source += "/* esxVI_%s_Free */\n" % self.name
+            source += "ESX_VI__TEMPLATE__FREE(%s,\n" % self.name
+            source += "{\n"
+
+            if self.features & ManagedObject.FEATURE__LIST:
+                if self.extends is not None:
+                    # avoid "dereferencing type-punned pointer will break strict-aliasing rules" warnings
+                    source += "    esxVI_%s *next = (esxVI_%s *)item->_next;\n\n" % (self.extends, self.extends)
+                    source += "    esxVI_%s_Free(&next);\n" % self.extends
+                    source += "    item->_next = (esxVI_%s *)next;\n\n" % self.name
+                else:
+                    source += "    esxVI_%s_Free(&item->_next);\n" % self.name
+
+            source += "    esxVI_ManagedObjectReference_Free(&item->_reference);\n\n"
+
+            source += self.generate_free_code()
+
+            source += "})\n\n"
+        else:
+            source += "/* esxVI_%s_Free */\n" % self.name
+            source += "ESX_VI__TEMPLATE__DYNAMIC_FREE(%s,\n" % self.name
+            source += "{\n"
+
+            for extended_by in self.extended_by:
+                source += "    ESX_VI__TEMPLATE__DISPATCH__FREE(%s)\n" % extended_by
+
+            source += "},\n"
+            source += "{\n"
+
+            if self.features & Object.FEATURE__LIST:
+                if self.extends is not None:
+                    # avoid "dereferencing type-punned pointer will break strict-aliasing rules" warnings
+                    source += "    esxVI_%s *next = (esxVI_%s *)item->_next;\n\n" % (self.extends, self.extends)
+                    source += "    esxVI_%s_Free(&next);\n" % self.extends
+                    source += "    item->_next = (esxVI_%s *)next;\n\n" % self.name
+                else:
+                    source += "    esxVI_%s_Free(&item->_next);\n" % self.name
+
+            source += "    esxVI_ManagedObjectReference_Free(&item->_reference);\n\n"
+
+            source += self.generate_free_code()
+
+            source += "})\n\n"
+
+        # validate
+        source += "/* esxVI_%s_Validate */\n" % self.name
+        source += "ESX_VI__TEMPLATE__MANAGED_VALIDATE(%s,\n" % self.name
+        source += "{\n"
+
+        source += self.generate_validate_code()
+
+        source += "})\n\n"
+
+        # append to list
+        if self.features & ManagedObject.FEATURE__LIST:
+            source += "/* esxVI_%s_AppendToList */\n" % self.name
+            source += "ESX_VI__TEMPLATE__LIST__APPEND(%s)\n\n" % self.name
+
+        source += "\n\n"
+
+        return source
+
+
+    def generate_helper_source(self):
+        source = ""
+
+        # lookup
+        source += "/* esxVI_Lookup%s */\n" % self.name
+        source += "ESX_VI__TEMPLATE__LOOKUP(%s,\n" % self.name
+        source += "{\n"
+
+        source += self.generate_lookup_code1()
+
+        source += "},\n"
+        source += "{\n"
+
+        source += self.generate_lookup_code2()
+
+        source += "})\n\n"
+
+        source += "\n\n"
+
+        return source
 
 
 
@@ -962,8 +1267,13 @@ def capitalize_first(string):
 
 
 def parse_object(block):
-    # expected format: object <name> [extends <name>]
+    # expected format: [managed] object <name> [extends <name>]
     header_items = block[0][1].split()
+    managed = False
+
+    if header_items[0] == "managed":
+        managed = True
+        del header_items[0]
 
     if len(header_items) < 2:
         report_error("line %d: invalid block header" % (number))
@@ -994,7 +1304,10 @@ def parse_object(block):
         properties.append(Property(type=items[0], name=items[1],
                                    occurrence=items[2]))
 
-    return Object(name = name, extends = extends, properties = properties)
+    if managed:
+        return ManagedObject(name=name, extends=extends, properties=properties)
+    else:
+        return Object(name=name, extends=extends, properties=properties)
 
 
 
@@ -1075,6 +1388,7 @@ def is_known_type(type):
     return type in predefined_objects or \
            type in predefined_enums or \
            type in objects_by_name or \
+           type in managed_objects_by_name or \
            type in enums_by_name
 
 
@@ -1169,11 +1483,14 @@ types_header = open_and_print(os.path.join(output_dirname, "esx_vi_types.generat
 types_source = open_and_print(os.path.join(output_dirname, "esx_vi_types.generated.c"))
 methods_header = open_and_print(os.path.join(output_dirname, "esx_vi_methods.generated.h"))
 methods_source = open_and_print(os.path.join(output_dirname, "esx_vi_methods.generated.c"))
+helpers_header = open_and_print(os.path.join(output_dirname, "esx_vi.generated.h"))
+helpers_source = open_and_print(os.path.join(output_dirname, "esx_vi.generated.c"))
 
 
 
 number = 0
 objects_by_name = {}
+managed_objects_by_name = {}
 enums_by_name = {}
 methods_by_name = {}
 block = None
@@ -1191,7 +1508,8 @@ for line in file(input_filename, "rb").readlines():
     if len(line) < 1:
         continue
 
-    if line.startswith("object") or line.startswith("enum") or line.startswith("method"):
+    if line.startswith("object") or line.startswith("managed object") or \
+       line.startswith("enum") or line.startswith("method"):
         if block is not None:
             report_error("line %d: nested block found" % (number))
         else:
@@ -1202,6 +1520,9 @@ for line in file(input_filename, "rb").readlines():
             if block[0][1].startswith("object"):
                 obj = parse_object(block)
                 objects_by_name[obj.name] = obj
+            elif block[0][1].startswith("managed object"):
+                obj = parse_object(block)
+                managed_objects_by_name[obj.name] = obj
             elif block[0][1].startswith("enum"):
                 enum = parse_enum(block)
                 enums_by_name[enum.name] = enum
@@ -1268,6 +1589,30 @@ for obj in objects_by_name.values():
 
 
 
+for obj in managed_objects_by_name.values():
+    for property in obj.properties:
+        if property.occurrence != OCCURRENCE__IGNORED and \
+           not is_known_type(property.type):
+            report_error("object '%s' contains unknown property type '%s'" % (obj.name, property.type))
+
+    if obj.extends is not None:
+        if not is_known_type(obj.extends):
+            report_error("object '%s' extends unknown object '%s'" % (obj.name, obj.extends))
+
+    # detect extended_by relation
+    if obj.extends is not None:
+        extended_obj = managed_objects_by_name[obj.extends]
+
+        if extended_obj.extended_by is None:
+            extended_obj.extended_by = [obj.name]
+        else:
+            extended_obj.extended_by.append(obj.name)
+            extended_obj.extended_by.sort()
+
+
+
+
+
 for obj in objects_by_name.values():
     inherit_features(obj)
 
@@ -1283,6 +1628,8 @@ types_header.write("/* Generated by esx_vi_generator.py */\n\n\n\n")
 types_source.write("/* Generated by esx_vi_generator.py */\n\n\n\n")
 methods_header.write("/* Generated by esx_vi_generator.py */\n\n\n\n")
 methods_source.write("/* Generated by esx_vi_generator.py */\n\n\n\n")
+helpers_header.write("/* Generated by esx_vi_generator.py */\n\n\n\n")
+helpers_source.write("/* Generated by esx_vi_generator.py */\n\n\n\n")
 
 
 # output enums
@@ -1306,7 +1653,7 @@ for name in names:
 # output objects
 types_typedef.write("\n\n\n" +
                     "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n" +
-                    " * VI Types\n" +
+                    " * VI Objects\n" +
                     " */\n\n")
 types_typeenum.write("\n")
 types_typetostring.write("\n")
@@ -1327,6 +1674,30 @@ for name in names:
 
 
 
+# output managed objects
+types_typedef.write("\n\n\n" +
+                    "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n" +
+                    " * VI Managed Objects\n" +
+                    " */\n\n")
+types_typeenum.write("\n")
+types_typetostring.write("\n")
+types_typefromstring.write("\n")
+
+
+
+names = managed_objects_by_name.keys()
+names.sort()
+
+for name in names:
+    types_typedef.write(managed_objects_by_name[name].generate_typedef())
+    types_typeenum.write(managed_objects_by_name[name].generate_typeenum())
+    types_typetostring.write(managed_objects_by_name[name].generate_typetostring())
+    types_typefromstring.write(managed_objects_by_name[name].generate_typefromstring())
+    types_header.write(managed_objects_by_name[name].generate_header())
+    types_source.write(managed_objects_by_name[name].generate_source())
+
+
+
 # output methods
 names = methods_by_name.keys()
 names.sort()
@@ -1334,3 +1705,13 @@ names.sort()
 for name in names:
     methods_header.write(methods_by_name[name].generate_header())
     methods_source.write(methods_by_name[name].generate_source())
+
+
+
+# output helpers
+names = managed_objects_by_name.keys()
+names.sort()
+
+for name in names:
+    helpers_header.write(managed_objects_by_name[name].generate_helper_header())
+    helpers_source.write(managed_objects_by_name[name].generate_helper_source())
diff --git a/src/esx/esx_vi_types.c b/src/esx/esx_vi_types.c
index f3cdf2a..9e23030 100644
--- a/src/esx/esx_vi_types.c
+++ b/src/esx/esx_vi_types.c
@@ -3,7 +3,7 @@
  * esx_vi_types.c: client for the VMware VI API 2.5 to manage ESX hosts
  *
  * Copyright (C) 2010 Red Hat, Inc.
- * Copyright (C) 2009-2010 Matthias Bolte <matthias.bolte at googlemail.com>
+ * Copyright (C) 2009-2011 Matthias Bolte <matthias.bolte at googlemail.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -693,6 +693,44 @@ esxVI_GetActualObjectType(xmlNodePtr node, esxVI_Type baseType,
 
 
 
+/*
+ * Macros to implement managed objects
+ */
+
+#define ESX_VI__TEMPLATE__PROPERTY__MANAGED_REQUIRE(_name)                    \
+    /* FIXME: This results in O(n^2) runtime in case of missing required, but \
+     * unselected properties. */                                              \
+    if (item->_name == 0 &&                                                   \
+        esxVI_String_ListContainsValue(selectedPropertyNameList, #_name)) {   \
+        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,                                  \
+                     _("%s object is missing the required '%s' property"),    \
+                     typeName, #_name);                                       \
+        return -1;                                                            \
+    }
+
+
+
+#define ESX_VI__TEMPLATE__MANAGED_VALIDATE(__type, _require)                  \
+    int                                                                       \
+    esxVI_##__type##_Validate(esxVI_##__type *item,                           \
+                              esxVI_String *selectedPropertyNameList)         \
+    {                                                                         \
+        const char *typeName = esxVI_Type_ToString(esxVI_Type_##__type);      \
+                                                                              \
+        if (item->_type <= esxVI_Type_Undefined ||                            \
+            item->_type >= esxVI_Type_Other) {                                \
+            ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,                              \
+                         _("%s object has invalid dynamic type"), typeName);  \
+            return -1;                                                        \
+        }                                                                     \
+                                                                              \
+        _require                                                              \
+                                                                              \
+        return 0;                                                             \
+    }
+
+
+
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  * XSI: Type
  */
@@ -735,15 +773,6 @@ esxVI_Type_ToString(esxVI_Type type)
       case esxVI_Type_ManagedObjectReference:
         return "ManagedObjectReference";
 
-      case esxVI_Type_Datacenter:
-        return "Datacenter";
-
-      case esxVI_Type_ComputeResource:
-        return "ComputeResource";
-
-      case esxVI_Type_HostSystem:
-        return "HostSystem";
-
 #include "esx_vi_types.generated.typetostring"
 
       case esxVI_Type_Other:
@@ -776,12 +805,6 @@ esxVI_Type_FromString(const char *type)
         return esxVI_Type_MethodFault;
     } else if (STREQ(type, "ManagedObjectReference")) {
         return esxVI_Type_ManagedObjectReference;
-    } else if (STREQ(type, "Datacenter")) {
-        return esxVI_Type_Datacenter;
-    } else if (STREQ(type, "ComputeResource")) {
-        return esxVI_Type_ComputeResource;
-    } else if (STREQ(type, "HostSystem")) {
-        return esxVI_Type_HostSystem;
     }
 
 #include "esx_vi_types.generated.typefromstring"
@@ -1050,6 +1073,20 @@ ESX_VI__TEMPLATE__VALIDATE(String,
     ESX_VI__TEMPLATE__PROPERTY__REQUIRE(value)
 })
 
+bool
+esxVI_String_ListContainsValue(esxVI_String *stringList, const char *value)
+{
+    esxVI_String *string;
+
+    for (string = stringList; string != NULL; string = string->_next) {
+        if (STREQ(string->value, value)) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
 /* esxVI_String_AppendToList */
 ESX_VI__TEMPLATE__LIST__APPEND(String)
 
@@ -1452,7 +1489,7 @@ esxVI_DateTime_ConvertToCalendarTime(esxVI_DateTime *dateTime,
 
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * VI Type: Fault
+ * SOAP: Fault
  */
 
 /* esxVI_Fault_Alloc */
@@ -1483,7 +1520,7 @@ ESX_VI__TEMPLATE__DESERIALIZE(Fault,
 
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * VI Type: MethodFault
+ * VI Object: MethodFault
  */
 
 /* esxVI_MethodFault_Alloc */
@@ -1528,7 +1565,7 @@ esxVI_MethodFault_Deserialize(xmlNodePtr node, esxVI_MethodFault **methodFault)
 
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * VI Type: ManagedObjectReference
+ * VI Object: ManagedObjectReference
  */
 
 /* esxVI_ManagedObjectReference_Alloc */
@@ -1632,280 +1669,6 @@ esxVI_ManagedObjectReference_Deserialize
 
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * VI Managed Object: Datacenter
- *                    extends ManagedEntity
- */
-
-/* esxVI_Datacenter_Alloc */
-ESX_VI__TEMPLATE__ALLOC(Datacenter)
-
-/* esxVI_Datacenter_Free */
-ESX_VI__TEMPLATE__FREE(Datacenter,
-{
-    esxVI_Datacenter_Free(&item->_next);
-    esxVI_ManagedObjectReference_Free(&item->_reference);
-
-    /* ManagedEntity */
-    VIR_FREE(item->name);
-
-    /* Datacenter */
-    esxVI_ManagedObjectReference_Free(&item->hostFolder);
-    esxVI_ManagedObjectReference_Free(&item->vmFolder);
-})
-
-/* esxVI_Datacenter_Validate */
-ESX_VI__TEMPLATE__VALIDATE(Datacenter,
-{
-    /* ManagedEntity */
-    ESX_VI__TEMPLATE__PROPERTY__REQUIRE(name);
-
-    /* Datacenter */
-    ESX_VI__TEMPLATE__PROPERTY__REQUIRE(hostFolder);
-    ESX_VI__TEMPLATE__PROPERTY__REQUIRE(vmFolder);
-})
-
-int
-esxVI_Datacenter_CastFromObjectContent(esxVI_ObjectContent *objectContent,
-                                       esxVI_Datacenter **datacenter)
-{
-    esxVI_DynamicProperty *dynamicProperty = NULL;
-
-    if (objectContent == NULL || datacenter == NULL || *datacenter != NULL) {
-        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
-        return -1;
-    }
-
-    if (esxVI_Datacenter_Alloc(datacenter) < 0) {
-        return -1;
-    }
-
-    if (esxVI_ManagedObjectReference_DeepCopy(&(*datacenter)->_reference,
-                                              objectContent->obj) < 0) {
-        goto failure;
-    }
-
-    for (dynamicProperty = objectContent->propSet; dynamicProperty != NULL;
-         dynamicProperty = dynamicProperty->_next) {
-        if (STREQ(dynamicProperty->name, "name")) {
-            if (esxVI_AnyType_ExpectType(dynamicProperty->val,
-                                         esxVI_Type_String) < 0) {
-                goto failure;
-            }
-
-            (*datacenter)->name = strdup(dynamicProperty->val->string);
-
-            if ((*datacenter)->name == NULL) {
-                virReportOOMError();
-                goto failure;
-            }
-        } else if (STREQ(dynamicProperty->name, "hostFolder")) {
-            if (esxVI_ManagedObjectReference_CastFromAnyType
-                  (dynamicProperty->val, &(*datacenter)->hostFolder) < 0) {
-                goto failure;
-            }
-        } else if (STREQ(dynamicProperty->name, "vmFolder")) {
-            if (esxVI_ManagedObjectReference_CastFromAnyType
-                  (dynamicProperty->val, &(*datacenter)->vmFolder) < 0) {
-                goto failure;
-            }
-        }
-    }
-
-    if (esxVI_Datacenter_Validate(*datacenter) < 0) {
-        goto failure;
-    }
-
-    return 0;
-
-  failure:
-    esxVI_Datacenter_Free(datacenter);
-
-    return -1;
-}
-
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * VI Managed Object: ComputeResource
- *                    extends ManagedEntity
- */
-
-/* esxVI_ComputeResource_Alloc */
-ESX_VI__TEMPLATE__ALLOC(ComputeResource)
-
-/* esxVI_ComputeResource_Free */
-ESX_VI__TEMPLATE__FREE(ComputeResource,
-{
-    esxVI_ComputeResource_Free(&item->_next);
-    esxVI_ManagedObjectReference_Free(&item->_reference);
-
-    /* ManagedEntity */
-    VIR_FREE(item->name);
-
-    /* ComputeResource */
-    esxVI_ManagedObjectReference_Free(&item->host);
-    esxVI_ManagedObjectReference_Free(&item->resourcePool);
-})
-
-/* esxVI_ComputeResource_Validate */
-ESX_VI__TEMPLATE__VALIDATE(ComputeResource,
-{
-    /* ManagedEntity */
-    ESX_VI__TEMPLATE__PROPERTY__REQUIRE(name);
-
-    /* ComputeResource */
-})
-
-int
-esxVI_ComputeResource_CastFromObjectContent
-  (esxVI_ObjectContent *objectContent, esxVI_ComputeResource **computeResource)
-{
-    esxVI_DynamicProperty *dynamicProperty = NULL;
-
-    if (objectContent == NULL || computeResource == NULL ||
-        *computeResource != NULL) {
-        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
-        return -1;
-    }
-
-    if (esxVI_ComputeResource_Alloc(computeResource) < 0) {
-        return -1;
-    }
-
-    if (esxVI_ManagedObjectReference_DeepCopy(&(*computeResource)->_reference,
-                                              objectContent->obj) < 0) {
-        goto failure;
-    }
-
-    for (dynamicProperty = objectContent->propSet; dynamicProperty != NULL;
-         dynamicProperty = dynamicProperty->_next) {
-        if (STREQ(dynamicProperty->name, "name")) {
-            if (esxVI_AnyType_ExpectType(dynamicProperty->val,
-                                         esxVI_Type_String) < 0) {
-                goto failure;
-            }
-
-            (*computeResource)->name = strdup(dynamicProperty->val->string);
-
-            if ((*computeResource)->name == NULL) {
-                virReportOOMError();
-                goto failure;
-            }
-        } else if (STREQ(dynamicProperty->name, "host")) {
-            if (esxVI_ManagedObjectReference_CastListFromAnyType
-                  (dynamicProperty->val, &(*computeResource)->host) < 0) {
-                goto failure;
-            }
-        } else if (STREQ(dynamicProperty->name, "resourcePool")) {
-            if (esxVI_ManagedObjectReference_CastFromAnyType
-                  (dynamicProperty->val, &(*computeResource)->resourcePool) < 0) {
-                goto failure;
-            }
-        }
-    }
-
-    if (esxVI_ComputeResource_Validate(*computeResource) < 0) {
-        goto failure;
-    }
-
-    return 0;
-
-  failure:
-    esxVI_ComputeResource_Free(computeResource);
-
-    return -1;
-}
-
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * VI Managed Object: HostSystem
- *                    extends ManagedEntity
- */
-
-/* esxVI_HostSystem_Alloc */
-ESX_VI__TEMPLATE__ALLOC(HostSystem)
-
-/* esxVI_HostSystem_Free */
-ESX_VI__TEMPLATE__FREE(HostSystem,
-{
-    esxVI_HostSystem_Free(&item->_next);
-    esxVI_ManagedObjectReference_Free(&item->_reference);
-
-    /* ManagedEntity */
-    VIR_FREE(item->name);
-
-    /* HostSystem */
-    esxVI_HostConfigManager_Free(&item->configManager);
-})
-
-/* esxVI_HostSystem_Validate */
-ESX_VI__TEMPLATE__VALIDATE(HostSystem,
-{
-    /* ManagedEntity */
-    ESX_VI__TEMPLATE__PROPERTY__REQUIRE(name);
-
-    /* HostSystem */
-    ESX_VI__TEMPLATE__PROPERTY__REQUIRE(configManager);
-})
-
-int
-esxVI_HostSystem_CastFromObjectContent(esxVI_ObjectContent *objectContent,
-                                       esxVI_HostSystem **hostSystem)
-{
-    esxVI_DynamicProperty *dynamicProperty = NULL;
-
-    if (objectContent == NULL || hostSystem == NULL || *hostSystem != NULL) {
-        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
-        return -1;
-    }
-
-    if (esxVI_HostSystem_Alloc(hostSystem) < 0) {
-        return -1;
-    }
-
-    if (esxVI_ManagedObjectReference_DeepCopy(&(*hostSystem)->_reference,
-                                              objectContent->obj) < 0) {
-        goto failure;
-    }
-
-    for (dynamicProperty = objectContent->propSet; dynamicProperty != NULL;
-         dynamicProperty = dynamicProperty->_next) {
-        if (STREQ(dynamicProperty->name, "name")) {
-            if (esxVI_AnyType_ExpectType(dynamicProperty->val,
-                                         esxVI_Type_String) < 0) {
-                goto failure;
-            }
-
-            (*hostSystem)->name = strdup(dynamicProperty->val->string);
-
-            if ((*hostSystem)->name == NULL) {
-                virReportOOMError();
-                goto failure;
-            }
-        } else if (STREQ(dynamicProperty->name, "configManager")) {
-            if (esxVI_HostConfigManager_CastFromAnyType
-                  (dynamicProperty->val, &(*hostSystem)->configManager) < 0) {
-                goto failure;
-            }
-        }
-    }
-
-    if (esxVI_HostSystem_Validate(*hostSystem) < 0) {
-        goto failure;
-    }
-
-    return 0;
-
-  failure:
-    esxVI_HostSystem_Free(hostSystem);
-
-    return -1;
-}
-
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  * VI Enum: VirtualMachinePowerState (Additions)
  */
 
diff --git a/src/esx/esx_vi_types.h b/src/esx/esx_vi_types.h
index e53ccda..ac3741f 100644
--- a/src/esx/esx_vi_types.h
+++ b/src/esx/esx_vi_types.h
@@ -1,7 +1,8 @@
+
 /*
  * esx_vi_types.h: client for the VMware VI API 2.5 to manage ESX hosts
  *
- * Copyright (C) 2009-2010 Matthias Bolte <matthias.bolte at googlemail.com>
+ * Copyright (C) 2009-2011 Matthias Bolte <matthias.bolte at googlemail.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -44,15 +45,18 @@ typedef struct _esxVI_DateTime esxVI_DateTime;
 
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * VI Types
+ * SOAP
  */
 
 typedef struct _esxVI_Fault esxVI_Fault;
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * VI Objects
+ */
 typedef struct _esxVI_MethodFault esxVI_MethodFault;
 typedef struct _esxVI_ManagedObjectReference esxVI_ManagedObjectReference;
-typedef struct _esxVI_Datacenter esxVI_Datacenter;
-typedef struct _esxVI_ComputeResource esxVI_ComputeResource;
-typedef struct _esxVI_HostSystem esxVI_HostSystem;
 
 # include "esx_vi_types.generated.typedef"
 
@@ -74,9 +78,6 @@ enum _esxVI_Type {
     esxVI_Type_Fault,
     esxVI_Type_MethodFault,
     esxVI_Type_ManagedObjectReference,
-    esxVI_Type_Datacenter,
-    esxVI_Type_ComputeResource,
-    esxVI_Type_HostSystem,
 
 # include "esx_vi_types.generated.typeenum"
 
@@ -170,6 +171,7 @@ struct _esxVI_String {
 int esxVI_String_Alloc(esxVI_String **string);
 void esxVI_String_Free(esxVI_String **stringList);
 int esxVI_String_Validate(esxVI_String *string);
+bool esxVI_String_ListContainsValue(esxVI_String *stringList, const char *value);
 int esxVI_String_AppendToList(esxVI_String **stringList, esxVI_String *string);
 int esxVI_String_AppendValueToList(esxVI_String **stringList,
                                    const char *value);
@@ -264,7 +266,7 @@ int esxVI_DateTime_ConvertToCalendarTime(esxVI_DateTime *dateTime,
 
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * VI Type: Fault
+ * SOAP: Fault
  */
 
 struct _esxVI_Fault {
@@ -283,7 +285,7 @@ int esxVI_Fault_Deserialize(xmlNodePtr node, esxVI_Fault **fault);
 
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * VI Type: MethodFault
+ * VI Object: MethodFault
  */
 
 /*
@@ -306,7 +308,7 @@ int esxVI_MethodFault_Deserialize(xmlNodePtr node,
 
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * VI Type: ManagedObjectReference
+ * VI Object: ManagedObjectReference
  */
 
 struct _esxVI_ManagedObjectReference {
@@ -348,84 +350,6 @@ int esxVI_ManagedObjectReference_Deserialize
 
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * VI Managed Object: Datacenter
- *                    extends ManagedEntity
- */
-
-struct _esxVI_Datacenter {
-    esxVI_Datacenter *_next;                               /* optional */
-    esxVI_Type _type;                                      /* required */
-    esxVI_ManagedObjectReference *_reference;              /* required */
-
-    /* ManagedEntity */
-    char *name;                                            /* required */
-
-    /* Datacenter */
-    esxVI_ManagedObjectReference *hostFolder;              /* required */
-    esxVI_ManagedObjectReference *vmFolder;                /* required */
-};
-
-int esxVI_Datacenter_Alloc(esxVI_Datacenter **datacenter);
-void esxVI_Datacenter_Free(esxVI_Datacenter **datacenter);
-int esxVI_Datacenter_Validate(esxVI_Datacenter *datacenter);
-int esxVI_Datacenter_CastFromObjectContent(esxVI_ObjectContent *objectContent,
-                                           esxVI_Datacenter **datacenter);
-
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * VI Managed Object: ComputeResource
- *                    extends ManagedEntity
- */
-
-struct _esxVI_ComputeResource {
-    esxVI_ComputeResource *_next;                          /* optional */
-    esxVI_Type _type;                                      /* required */
-    esxVI_ManagedObjectReference *_reference;              /* required */
-
-    /* ManagedEntity */
-    char *name;                                            /* required */
-
-    /* ComputeResource */
-    esxVI_ManagedObjectReference *host;                    /* optional, list */
-    esxVI_ManagedObjectReference *resourcePool;            /* optional */
-};
-
-int esxVI_ComputeResource_Alloc(esxVI_ComputeResource **computeResource);
-void esxVI_ComputeResource_Free(esxVI_ComputeResource **computeResource);
-int esxVI_ComputeResource_Validate(esxVI_ComputeResource *computeResource);
-int esxVI_ComputeResource_CastFromObjectContent
-      (esxVI_ObjectContent *objectContent,
-       esxVI_ComputeResource **computeResource);
-
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * VI Managed Object: HostSystem
- *                    extends ManagedEntity
- */
-
-struct _esxVI_HostSystem {
-    esxVI_HostSystem *_next;                               /* optional */
-    esxVI_Type _type;                                      /* required */
-    esxVI_ManagedObjectReference *_reference;              /* required */
-
-    /* ManagedEntity */
-    char *name;                                            /* required */
-
-    /* HostSystem */
-    esxVI_HostConfigManager *configManager;                /* required */
-};
-
-int esxVI_HostSystem_Alloc(esxVI_HostSystem **hostSystem);
-void esxVI_HostSystem_Free(esxVI_HostSystem **hostSystem);
-int esxVI_HostSystem_Validate(esxVI_HostSystem *hostSystem);
-int esxVI_HostSystem_CastFromObjectContent(esxVI_ObjectContent *objectContent,
-                                           esxVI_HostSystem **hostSystem);
-
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  * VI Enum: VirtualMachinePowerState (Additions)
  */
 
-- 
1.7.0.4




More information about the libvir-list mailing list