1bd27f
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
3e596a
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
3e596a
Date: Tue, 11 Apr 2017 21:51:14 -0300
3e596a
Subject: [PATCH] Initial support for clusters
3e596a
3e596a
Like the previous commit, at the moment, we only care about the
3e596a
information of the data center the cluster is part of, and the list of
3e596a
the hosts associated with it.
3e596a
3e596a
Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
3e596a
---
3e596a
 govirt/Makefile.am             |   3 +
3e596a
 govirt/govirt-private.h        |   1 +
1bd27f
 govirt/govirt.sym              |   6 +
1bd27f
 govirt/ovirt-api.c             |  47 +++++++
3e596a
 govirt/ovirt-api.h             |   2 +
1bd27f
 govirt/ovirt-cluster-private.h |  37 ++++++
1bd27f
 govirt/ovirt-cluster.c         | 215 +++++++++++++++++++++++++++++++++
1bd27f
 govirt/ovirt-cluster.h         |  66 ++++++++++
3e596a
 govirt/ovirt-types.h           |   1 +
3e596a
 9 files changed, 378 insertions(+)
3e596a
 create mode 100644 govirt/ovirt-cluster-private.h
3e596a
 create mode 100644 govirt/ovirt-cluster.c
3e596a
 create mode 100644 govirt/ovirt-cluster.h
3e596a
3e596a
diff --git a/govirt/Makefile.am b/govirt/Makefile.am
3e596a
index c62a1d6..cf6b858 100644
3e596a
--- a/govirt/Makefile.am
3e596a
+++ b/govirt/Makefile.am
3e596a
@@ -19,6 +19,7 @@ libgovirt_la_HEADERS =						\
3e596a
 	govirt.h						\
3e596a
 	ovirt-api.h						\
3e596a
 	ovirt-cdrom.h						\
3e596a
+	ovirt-cluster.h						\
3e596a
 	ovirt-collection.h					\
3e596a
 	ovirt-error.h						\
3e596a
 	ovirt-host.h						\
3e596a
@@ -38,6 +39,7 @@ noinst_HEADERS =						\
3e596a
 	govirt-private.h					\
3e596a
 	ovirt-action-rest-call.h				\
3e596a
 	ovirt-api-private.h					\
3e596a
+	ovirt-cluster-private.h					\
3e596a
 	ovirt-collection-private.h				\
3e596a
 	ovirt-host-private.h					\
3e596a
 	ovirt-proxy-private.h					\
3e596a
@@ -54,6 +56,7 @@ libgovirt_la_SOURCES =						\
3e596a
 	ovirt-action-rest-call.c				\
3e596a
 	ovirt-api.c						\
3e596a
 	ovirt-cdrom.c						\
3e596a
+	ovirt-cluster.c						\
3e596a
 	ovirt-collection.c					\
3e596a
 	ovirt-error.c						\
3e596a
 	ovirt-host.c						\
3e596a
diff --git a/govirt/govirt-private.h b/govirt/govirt-private.h
3e596a
index b51feb3..d466f7a 100644
3e596a
--- a/govirt/govirt-private.h
3e596a
+++ b/govirt/govirt-private.h
3e596a
@@ -24,6 +24,7 @@
3e596a
 
3e596a
 #include <govirt/ovirt-action-rest-call.h>
3e596a
 #include <govirt/ovirt-api-private.h>
3e596a
+#include <govirt/ovirt-cluster-private.h>
3e596a
 #include <govirt/ovirt-collection-private.h>
3e596a
 #include <govirt/ovirt-enum-types-private.h>
3e596a
 #include <govirt/ovirt-host-private.h>
3e596a
diff --git a/govirt/govirt.sym b/govirt/govirt.sym
1bd27f
index 6dc8159..56e1d66 100644
3e596a
--- a/govirt/govirt.sym
3e596a
+++ b/govirt/govirt.sym
3e596a
@@ -110,13 +110,19 @@ GOVIRT_0.3.2 {
3e596a
         ovirt_api_search_vms;
3e596a
         ovirt_api_search_vm_pools;
3e596a
 
3e596a
+        ovirt_api_get_clusters;
3e596a
         ovirt_api_get_hosts;
3e596a
 
3e596a
+        ovirt_api_search_clusters;
3e596a
         ovirt_api_search_hosts;
3e596a
         ovirt_api_search_storage_domains;
3e596a
         ovirt_api_search_vms;
3e596a
         ovirt_api_search_vm_pools;
3e596a
 
3e596a
+        ovirt_cluster_get_type;
3e596a
+        ovirt_cluster_get_hosts;
3e596a
+        ovirt_cluster_new;
3e596a
+
3e596a
         ovirt_host_get_type;
3e596a
         ovirt_host_get_vms;
3e596a
         ovirt_host_new;
3e596a
diff --git a/govirt/ovirt-api.c b/govirt/ovirt-api.c
1bd27f
index fef04ba..14c6c5a 100644
3e596a
--- a/govirt/ovirt-api.c
3e596a
+++ b/govirt/ovirt-api.c
3e596a
@@ -41,6 +41,7 @@
3e596a
 
3e596a
 
3e596a
 struct _OvirtApiPrivate {
3e596a
+    OvirtCollection *clusters;
3e596a
     OvirtCollection *hosts;
3e596a
     OvirtCollection *storage_domains;
3e596a
     OvirtCollection *vms;
3e596a
@@ -74,6 +75,7 @@ static void ovirt_api_dispose(GObject *object)
3e596a
 {
3e596a
     OvirtApi *api = OVIRT_API(object);
3e596a
 
3e596a
+    g_clear_object(&api->priv->clusters);
3e596a
     g_clear_object(&api->priv->hosts);
3e596a
     g_clear_object(&api->priv->storage_domains);
3e596a
     g_clear_object(&api->priv->vms);
1bd27f
@@ -292,3 +294,48 @@ OvirtCollection *ovirt_api_search_hosts(OvirtApi *api, const char *query)
3e596a
                                                          "host",
3e596a
                                                          query);
3e596a
 }
3e596a
+
3e596a
+
3e596a
+/**
3e596a
+ * ovirt_api_get_clusters:
3e596a
+ * @api: a #OvirtApi
3e596a
+ *
3e596a
+ * This method does not initiate any network activity, the collection
3e596a
+ * must be fetched with ovirt_collection_fetch() before having up-to-date
3e596a
+ * content.
3e596a
+ *
3e596a
+ * Return value: (transfer none):
3e596a
+ */
3e596a
+OvirtCollection *ovirt_api_get_clusters(OvirtApi *api)
3e596a
+{
3e596a
+    g_return_val_if_fail(OVIRT_IS_API(api), NULL);
3e596a
+
3e596a
+    if (api->priv->clusters == NULL)
3e596a
+        api->priv->clusters = ovirt_sub_collection_new_from_resource(OVIRT_RESOURCE(api),
3e596a
+                                                                     "clusters",
3e596a
+                                                                     "clusters",
3e596a
+                                                                     OVIRT_TYPE_CLUSTER,
3e596a
+                                                                     "cluster");
3e596a
+
3e596a
+    return api->priv->clusters;
3e596a
+}
3e596a
+
3e596a
+
3e596a
+/**
3e596a
+ * ovirt_api_search_clusters:
3e596a
+ * @api: a #OvirtApi
3e596a
+ * @query: search query
3e596a
+ *
3e596a
+ * Return value: (transfer none):
3e596a
+ */
3e596a
+OvirtCollection *ovirt_api_search_clusters(OvirtApi *api, const char *query)
3e596a
+{
3e596a
+    g_return_val_if_fail(OVIRT_IS_API(api), NULL);
3e596a
+
3e596a
+    return ovirt_sub_collection_new_from_resource_search(OVIRT_RESOURCE(api),
3e596a
+                                                         "clusters/search",
3e596a
+                                                         "clusters",
3e596a
+                                                         OVIRT_TYPE_CLUSTER,
3e596a
+                                                         "cluster",
3e596a
+                                                         query);
3e596a
+}
3e596a
diff --git a/govirt/ovirt-api.h b/govirt/ovirt-api.h
3e596a
index c46e934..1b60f35 100644
3e596a
--- a/govirt/ovirt-api.h
3e596a
+++ b/govirt/ovirt-api.h
3e596a
@@ -60,6 +60,8 @@ struct _OvirtApiClass
3e596a
 GType ovirt_api_get_type(void);
3e596a
 OvirtApi *ovirt_api_new(void);
3e596a
 
3e596a
+OvirtCollection *ovirt_api_get_clusters(OvirtApi *api);
3e596a
+OvirtCollection *ovirt_api_search_clusters(OvirtApi *api, const char *query);
3e596a
 OvirtCollection *ovirt_api_get_hosts(OvirtApi *api);
3e596a
 OvirtCollection *ovirt_api_search_hosts(OvirtApi *api, const char *query);
3e596a
 OvirtCollection *ovirt_api_get_storage_domains(OvirtApi *api);
3e596a
diff --git a/govirt/ovirt-cluster-private.h b/govirt/ovirt-cluster-private.h
3e596a
new file mode 100644
3e596a
index 0000000..1a1817d
3e596a
--- /dev/null
3e596a
+++ b/govirt/ovirt-cluster-private.h
3e596a
@@ -0,0 +1,37 @@
3e596a
+/*
3e596a
+ * ovirt-cluster-private.h: oVirt cluster resource
3e596a
+ *
3e596a
+ * Copyright (C) 2017 Red Hat, Inc.
3e596a
+ *
3e596a
+ * This library is free software; you can redistribute it and/or
3e596a
+ * modify it under the terms of the GNU Lesser General Public
3e596a
+ * License as published by the Free Software Foundation; either
3e596a
+ * version 2.1 of the License, or (at your option) any later version.
3e596a
+ *
3e596a
+ * This library is distributed in the hope that it will be useful,
3e596a
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3e596a
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
3e596a
+ * Lesser General Public License for more details.
3e596a
+ *
3e596a
+ * You should have received a copy of the GNU Lesser General Public
3e596a
+ * License along with this library. If not, see
3e596a
+ * <http://www.gnu.org/licenses/>.
3e596a
+ *
3e596a
+ * Author: Eduardo Lima (Etrunko) <etrunko@redhat.com>
3e596a
+ */
3e596a
+#ifndef __OVIRT_CLUSTER_PRIVATE_H__
3e596a
+#define __OVIRT_CLUSTER_PRIVATE_H__
3e596a
+
3e596a
+#include <ovirt-cluster.h>
3e596a
+#include <rest/rest-xml-node.h>
3e596a
+
3e596a
+G_BEGIN_DECLS
3e596a
+
3e596a
+OvirtCluster *ovirt_cluster_new_from_id(const char *id,
3e596a
+                                        const char *href);
3e596a
+OvirtCluster *ovirt_cluster_new_from_xml(RestXmlNode *node,
3e596a
+                                         GError **error);
3e596a
+
3e596a
+G_END_DECLS
3e596a
+
3e596a
+#endif /* __OVIRT_CLUSTER_PRIVATE_H__ */
3e596a
diff --git a/govirt/ovirt-cluster.c b/govirt/ovirt-cluster.c
3e596a
new file mode 100644
3e596a
index 0000000..83b0fa1
3e596a
--- /dev/null
3e596a
+++ b/govirt/ovirt-cluster.c
3e596a
@@ -0,0 +1,215 @@
3e596a
+/*
3e596a
+ * ovirt-cluster.c: oVirt cluster handling
3e596a
+ *
3e596a
+ * Copyright (C) 2017 Red Hat, Inc.
3e596a
+ *
3e596a
+ * This library is free software; you can redistribute it and/or
3e596a
+ * modify it under the terms of the GNU Lesser General Public
3e596a
+ * License as published by the Free Software Foundation; either
3e596a
+ * version 2.1 of the License, or (at your option) any later version.
3e596a
+ *
3e596a
+ * This library is distributed in the hope that it will be useful,
3e596a
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3e596a
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
3e596a
+ * Lesser General Public License for more details.
3e596a
+ *
3e596a
+ * You should have received a copy of the GNU Lesser General Public
3e596a
+ * License along with this library. If not, see
3e596a
+ * <http://www.gnu.org/licenses/>.
3e596a
+ *
3e596a
+ * Author: Eduardo Lima (Etrunko) <etrunko@redhat.com>
3e596a
+ */
3e596a
+
3e596a
+#include <config.h>
3e596a
+#include "ovirt-enum-types.h"
3e596a
+#include "ovirt-cluster.h"
3e596a
+#include "govirt-private.h"
3e596a
+
3e596a
+#define OVIRT_CLUSTER_GET_PRIVATE(obj)                         \
3e596a
+        (G_TYPE_INSTANCE_GET_PRIVATE((obj), OVIRT_TYPE_CLUSTER, OvirtClusterPrivate))
3e596a
+
3e596a
+struct _OvirtClusterPrivate {
3e596a
+    gchar *data_center_href;
3e596a
+    gchar *data_center_id;
3e596a
+    OvirtCollection *hosts;
3e596a
+};
3e596a
+
3e596a
+G_DEFINE_TYPE(OvirtCluster, ovirt_cluster, OVIRT_TYPE_RESOURCE);
3e596a
+
3e596a
+enum {
3e596a
+    PROP_0,
3e596a
+    PROP_DATA_CENTER_HREF,
3e596a
+    PROP_DATA_CENTER_ID,
3e596a
+};
3e596a
+
3e596a
+static void ovirt_cluster_get_property(GObject *object,
3e596a
+                                       guint prop_id,
3e596a
+                                       GValue *value,
3e596a
+                                       GParamSpec *pspec)
3e596a
+{
3e596a
+    OvirtCluster *cluster = OVIRT_CLUSTER(object);
3e596a
+
3e596a
+    switch (prop_id) {
3e596a
+    case PROP_DATA_CENTER_HREF:
3e596a
+        g_value_set_string(value, cluster->priv->data_center_href);
3e596a
+        break;
3e596a
+    case PROP_DATA_CENTER_ID:
3e596a
+        g_value_set_string(value, cluster->priv->data_center_id);
3e596a
+        break;
3e596a
+    default:
3e596a
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
3e596a
+    }
3e596a
+}
3e596a
+
3e596a
+static void ovirt_cluster_set_property(GObject *object,
3e596a
+                                       guint prop_id,
3e596a
+                                       const GValue *value,
3e596a
+                                       GParamSpec *pspec)
3e596a
+{
3e596a
+    OvirtCluster *cluster = OVIRT_CLUSTER(object);
3e596a
+
3e596a
+    switch (prop_id) {
3e596a
+    case PROP_DATA_CENTER_HREF:
3e596a
+        g_free(cluster->priv->data_center_href);
3e596a
+        cluster->priv->data_center_href = g_value_dup_string(value);
3e596a
+        break;
3e596a
+    case PROP_DATA_CENTER_ID:
3e596a
+        g_free(cluster->priv->data_center_id);
3e596a
+        cluster->priv->data_center_id = g_value_dup_string(value);
3e596a
+        break;
3e596a
+    default:
3e596a
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
3e596a
+    }
3e596a
+}
3e596a
+
3e596a
+
3e596a
+static void
3e596a
+ovirt_cluster_dispose(GObject *obj)
3e596a
+{
3e596a
+    OvirtCluster *cluster = OVIRT_CLUSTER(obj);
3e596a
+
3e596a
+    g_clear_pointer(&cluster->priv->data_center_href, g_free);
3e596a
+    g_clear_pointer(&cluster->priv->data_center_id, g_free);
3e596a
+    g_clear_object(&cluster->priv->hosts);
3e596a
+
3e596a
+    G_OBJECT_CLASS(ovirt_cluster_parent_class)->dispose(obj);
3e596a
+}
3e596a
+
3e596a
+
3e596a
+static gboolean ovirt_cluster_init_from_xml(OvirtResource *resource,
3e596a
+                                            RestXmlNode *node,
3e596a
+                                            GError **error)
3e596a
+{
3e596a
+    OvirtResourceClass *parent_class;
3e596a
+    OvirtXmlElement cluster_elements[] = {
3e596a
+        { .prop_name = "data-center-href",
3e596a
+          .type = G_TYPE_STRING,
3e596a
+          .xml_path = "data_center",
3e596a
+          .xml_attr = "href",
3e596a
+        },
3e596a
+        { .prop_name = "data-center-id",
3e596a
+          .type = G_TYPE_STRING,
3e596a
+          .xml_path = "data_center",
3e596a
+          .xml_attr = "id",
3e596a
+        },
3e596a
+        { NULL , },
3e596a
+    };
3e596a
+
3e596a
+    if (!ovirt_rest_xml_node_parse(node, G_OBJECT(resource), cluster_elements))
3e596a
+        return FALSE;
3e596a
+
3e596a
+    parent_class = OVIRT_RESOURCE_CLASS(ovirt_cluster_parent_class);
3e596a
+    return parent_class->init_from_xml(resource, node, error);
3e596a
+}
3e596a
+
3e596a
+
3e596a
+static void ovirt_cluster_class_init(OvirtClusterClass *klass)
3e596a
+{
3e596a
+    GObjectClass *object_class = G_OBJECT_CLASS(klass);
3e596a
+    OvirtResourceClass *resource_class = OVIRT_RESOURCE_CLASS(klass);
3e596a
+    GParamSpec *param_spec;
3e596a
+
3e596a
+    g_type_class_add_private(klass, sizeof(OvirtClusterPrivate));
3e596a
+
3e596a
+    resource_class->init_from_xml = ovirt_cluster_init_from_xml;
3e596a
+    object_class->dispose = ovirt_cluster_dispose;
3e596a
+    object_class->get_property = ovirt_cluster_get_property;
3e596a
+    object_class->set_property = ovirt_cluster_set_property;
3e596a
+
3e596a
+    param_spec = g_param_spec_string("data-center-href",
3e596a
+                                     "Data Center href",
3e596a
+                                     "Data Center href for the Cluster",
3e596a
+                                     NULL,
3e596a
+                                     G_PARAM_READWRITE |
3e596a
+                                     G_PARAM_STATIC_STRINGS);
3e596a
+    g_object_class_install_property(object_class,
3e596a
+                                    PROP_DATA_CENTER_HREF,
3e596a
+                                    param_spec);
3e596a
+
3e596a
+    param_spec = g_param_spec_string("data-center-id",
3e596a
+                                     "Data Center Id",
3e596a
+                                     "Data Center Id for the Cluster",
3e596a
+                                     NULL,
3e596a
+                                     G_PARAM_READWRITE |
3e596a
+                                     G_PARAM_STATIC_STRINGS);
3e596a
+    g_object_class_install_property(object_class,
3e596a
+                                    PROP_DATA_CENTER_ID,
3e596a
+                                    param_spec);
3e596a
+}
3e596a
+
3e596a
+static void ovirt_cluster_init(OvirtCluster *cluster)
3e596a
+{
3e596a
+    cluster->priv = OVIRT_CLUSTER_GET_PRIVATE(cluster);
3e596a
+}
3e596a
+
3e596a
+G_GNUC_INTERNAL
3e596a
+OvirtCluster *ovirt_cluster_new_from_id(const char *id,
3e596a
+                                        const char *href)
3e596a
+{
3e596a
+    OvirtResource *cluster = ovirt_resource_new_from_id(OVIRT_TYPE_CLUSTER, id, href);
3e596a
+    return OVIRT_CLUSTER(cluster);
3e596a
+}
3e596a
+
3e596a
+G_GNUC_INTERNAL
3e596a
+OvirtCluster *ovirt_cluster_new_from_xml(RestXmlNode *node,
3e596a
+                                         GError **error)
3e596a
+{
3e596a
+    OvirtResource *cluster = ovirt_resource_new_from_xml(OVIRT_TYPE_CLUSTER, node, error);
3e596a
+    return OVIRT_CLUSTER(cluster);
3e596a
+}
3e596a
+
3e596a
+OvirtCluster *ovirt_cluster_new(void)
3e596a
+{
3e596a
+    OvirtResource *cluster = ovirt_resource_new(OVIRT_TYPE_CLUSTER);
3e596a
+    return OVIRT_CLUSTER(cluster);
3e596a
+}
3e596a
+
3e596a
+/**
3e596a
+ * ovirt_cluster_get_hosts:
3e596a
+ * @cluster: a #OvirtCluster
3e596a
+ *
3e596a
+ * Gets a #OvirtCollection representing the list of remote hosts from a
3e596a
+ * cluster object. This method does not initiate any network
3e596a
+ * activity, the remote host list must be then be fetched using
3e596a
+ * ovirt_collection_fetch() or ovirt_collection_fetch_async().
3e596a
+ *
3e596a
+ * Return value: (transfer none): a #OvirtCollection representing the list
3e596a
+ * of hosts associated with @cluster.
3e596a
+ */
3e596a
+OvirtCollection *ovirt_cluster_get_hosts(OvirtCluster *cluster)
3e596a
+{
3e596a
+    g_return_val_if_fail(OVIRT_IS_CLUSTER(cluster), NULL);
3e596a
+
3e596a
+    if (cluster->priv->hosts == NULL) {
3e596a
+        OvirtCollection *collection;
3e596a
+        collection = ovirt_sub_collection_new_from_resource(OVIRT_RESOURCE(cluster),
3e596a
+                                                            "hosts",
3e596a
+                                                            "hosts",
3e596a
+                                                            OVIRT_TYPE_HOST,
3e596a
+                                                            "host");
3e596a
+        cluster->priv->hosts = collection;
3e596a
+    }
3e596a
+
3e596a
+    return cluster->priv->hosts;
3e596a
+}
3e596a
+
3e596a
diff --git a/govirt/ovirt-cluster.h b/govirt/ovirt-cluster.h
3e596a
new file mode 100644
3e596a
index 0000000..9505e8c
3e596a
--- /dev/null
3e596a
+++ b/govirt/ovirt-cluster.h
3e596a
@@ -0,0 +1,66 @@
3e596a
+/*
3e596a
+ * ovirt-cluster.h: oVirt cluster resource
3e596a
+ *
3e596a
+ * Copyright (C) 2017 Red Hat, Inc.
3e596a
+ *
3e596a
+ * This library is free software; you can redistribute it and/or
3e596a
+ * modify it under the terms of the GNU Lesser General Public
3e596a
+ * License as published by the Free Software Foundation; either
3e596a
+ * version 2.1 of the License, or (at your option) any later version.
3e596a
+ *
3e596a
+ * This library is distributed in the hope that it will be useful,
3e596a
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3e596a
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
3e596a
+ * Lesser General Public License for more details.
3e596a
+ *
3e596a
+ * You should have received a copy of the GNU Lesser General Public
3e596a
+ * License along with this library. If not, see
3e596a
+ * <http://www.gnu.org/licenses/>.
3e596a
+ *
3e596a
+ * Author: Eduardo Lima (Etrunko) <etrunko@redhat.com>
3e596a
+ */
3e596a
+#ifndef __OVIRT_CLUSTER_H__
3e596a
+#define __OVIRT_CLUSTER_H__
3e596a
+
3e596a
+#include <gio/gio.h>
3e596a
+#include <glib-object.h>
3e596a
+#include <govirt/ovirt-collection.h>
3e596a
+#include <govirt/ovirt-resource.h>
3e596a
+#include <govirt/ovirt-types.h>
3e596a
+
3e596a
+G_BEGIN_DECLS
3e596a
+
3e596a
+#define OVIRT_TYPE_CLUSTER            (ovirt_cluster_get_type ())
3e596a
+#define OVIRT_CLUSTER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), OVIRT_TYPE_CLUSTER, OvirtCluster))
3e596a
+#define OVIRT_CLUSTER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), OVIRT_TYPE_CLUSTER, OvirtClusterClass))
3e596a
+#define OVIRT_IS_CLUSTER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OVIRT_TYPE_CLUSTER))
3e596a
+#define OVIRT_IS_CLUSTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OVIRT_TYPE_CLUSTER))
3e596a
+#define OVIRT_CLUSTER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), OVIRT_TYPE_CLUSTER, OvirtClusterClass))
3e596a
+
3e596a
+typedef struct _OvirtClusterPrivate OvirtClusterPrivate;
3e596a
+typedef struct _OvirtClusterClass OvirtClusterClass;
3e596a
+
3e596a
+struct _OvirtCluster
3e596a
+{
3e596a
+    OvirtResource parent;
3e596a
+
3e596a
+    OvirtClusterPrivate *priv;
3e596a
+
3e596a
+    /* Do not add fields to this struct */
3e596a
+};
3e596a
+
3e596a
+struct _OvirtClusterClass
3e596a
+{
3e596a
+    OvirtResourceClass parent_class;
3e596a
+
3e596a
+    gpointer padding[20];
3e596a
+};
3e596a
+
3e596a
+GType ovirt_cluster_get_type(void);
3e596a
+
3e596a
+OvirtCluster *ovirt_cluster_new(void);
3e596a
+OvirtCollection *ovirt_cluster_get_hosts(OvirtCluster *cluster);
3e596a
+
3e596a
+G_END_DECLS
3e596a
+
3e596a
+#endif /* __OVIRT_CLUSTER_H__ */
3e596a
diff --git a/govirt/ovirt-types.h b/govirt/ovirt-types.h
3e596a
index 42fc004..e2f196e 100644
3e596a
--- a/govirt/ovirt-types.h
3e596a
+++ b/govirt/ovirt-types.h
3e596a
@@ -27,6 +27,7 @@ G_BEGIN_DECLS
3e596a
 
3e596a
 typedef struct _OvirtApi OvirtApi;
3e596a
 typedef struct _OvirtCdrom OvirtCdrom;
3e596a
+typedef struct _OvirtCluster OvirtCluster;
3e596a
 typedef struct _OvirtCollection OvirtCollection;
3e596a
 typedef struct _OvirtHost OvirtHost;
3e596a
 typedef struct _OvirtProxy OvirtProxy;