From b363bf5f6ac9027bf47b4fa55d928bc23db52f22 Mon Sep 17 00:00:00 2001
From: "M.Ravi" <mondi.ravi@gmail.com>
Date: Wed, 15 Mar 2017 17:32:55 +0530
Subject: [PATCH] First working version of opennebula-integration.

---
 dynamicweb/settings/local.py             | 27 +++++++
 hosting/admin.py                         | 89 +++++++++++++++++++++++-
 hosting/models.py                        | 16 ++---
 hosting/templates/hosting/managevms.html | 21 ++++++
 4 files changed, 143 insertions(+), 10 deletions(-)
 create mode 100644 hosting/templates/hosting/managevms.html

diff --git a/dynamicweb/settings/local.py b/dynamicweb/settings/local.py
index 799df594..16b0835a 100644
--- a/dynamicweb/settings/local.py
+++ b/dynamicweb/settings/local.py
@@ -19,3 +19,30 @@ INSTALLED_APPS+=(
     'django_extensions',
     'debug_toolbar'
     )
+
+
+#############################################
+# configurations for opennebula-integration #
+#############################################
+
+# The user name of the OpenNebula infrastructure
+OPENNEBULA_USERNAME = 'oneadmin'
+
+# The password of the OpenNebula infrastructure
+# The default credentials of the Sandbox OpenNebula VM is 
+# oneadmin:opennebula
+OPENNEBULA_PASSWORD = 'opennebula'
+
+# The protocol is generally http or https
+OPENNEBULA_PROTOCOL = 'http'
+
+# The ip address or the domain name of the opennebula infrastructure
+OPENNEBULA_DOMAIN = '192.168.182.173'
+
+# The port to connect in order to send an xmlrpc request. The default 
+# port is 2633
+OPENNEBULA_PORT = '2633'
+
+# The endpoint to which the XML RPC request needs to be sent to. The 
+# default value is /RPC2
+OPENNEBULA_ENDPOINT = '/RPC2'
diff --git a/hosting/admin.py b/hosting/admin.py
index c4bff6e0..a4fadcf3 100644
--- a/hosting/admin.py
+++ b/hosting/admin.py
@@ -1,12 +1,28 @@
 from django.contrib import admin
 from django.utils.html import format_html
 from django.core.urlresolvers import reverse
-
+from django.conf.urls import url
+from django.template.response import TemplateResponse
+from django.conf import settings
 from utils.mailer import BaseEmail
+from django import template
+import oca
+import socket
+from oca.exceptions import OpenNebulaException
 
 from .forms import HostingOrderAdminForm
-from .models import VirtualMachineType, VirtualMachinePlan, HostingOrder
+from .models import VirtualMachineType, VirtualMachinePlan, HostingOrder, ManageVMs
 
+register = template.Library()
+
+def get_vm_state(value):
+    if value == 1:
+         return 'PENDING'
+    #states = {-2: 'Any incl done', -1 : 'Any except done', 0 : 'INIT', 1 : 'PENDING', 2 : 'HOLD', 3 : 'ACTIVE', 4 : 'STOPPED', 5 : 'SUSPENDED', 6 : 'DONE', 7 : 'FAILED'}
+    #return states.get(value)
+    return 'UNKNO'
+
+register.filter('get_vm_state', get_vm_state)
 
 class HostingOrderAdmin(admin.ModelAdmin):
     # fields = ('slug', 'imdb_link', 'start', 'finish', 'added_by')
@@ -92,7 +108,76 @@ class VirtualMachinePlanAdmin(admin.ModelAdmin):
             email.send()
         obj.save()
 
+class HostingManageVMsAdmin(admin.ModelAdmin):
+    client = None
+    def get_urls(self):
+        urls = super().get_urls()
+        socket.setdefaulttimeout(5)
+        my_urls = [
+            url(r'^$', self.admin_site.admin_view(self.my_view, cacheable=True)),
+            url(r'^create_vm/$', self.admin_site.admin_view(self.create_vm, cacheable=True), name='createvm'),
+            #url(r'^my_views/$', self.admin_site.admin_view(self.my_view, cacheable=True))
+        ]
+        return my_urls + urls
+
+    def my_view(self, request):
+        s_message = ''
+        e_message = ''
+        try :
+            client = oca.Client(settings.OPENNEBULA_USERNAME + ':' + settings.OPENNEBULA_PASSWORD, settings.OPENNEBULA_PROTOCOL + '://' + settings.OPENNEBULA_DOMAIN + ':' + settings.OPENNEBULA_PORT + settings.OPENNEBULA_ENDPOINT)
+            vm_pool = oca.VirtualMachinePool(client)
+            vm_pool.info()
+            for vm in vm_pool:
+               vm.info()
+               print("%s (memory: %s MB)" % ( vm.name, vm.template.memory))
+               
+        except socket.timeout:
+            e_message = "Socket timeout error."
+        except OpenNebulaException:
+            e_message = "OpenNebulaException occurred."           
+        context = dict(
+            # Include common variables for rendering the admin template.
+            self.admin_site.each_context(request),
+            error_msg = e_message,
+            success_msg = s_message,           
+            vms = vm_pool,
+            # Anything else you want in the context...
+            # key=value,
+        )
+        return TemplateResponse(request, "hosting/managevms.html", context)
+
+    def create_vm(self, request):
+        s_message = ''
+        e_message = ''
+        try :
+            client = oca.Client(settings.OPENNEBULA_USERNAME + ':' + settings.OPENNEBULA_PASSWORD, settings.OPENNEBULA_PROTOCOL + '://' + settings.OPENNEBULA_DOMAIN + ':' + settings.OPENNEBULA_PORT + settings.OPENNEBULA_ENDPOINT)
+            # Lets create a test VM with 128MB of ram and 1 CPU
+            vm_id = oca.VirtualMachine.allocate(client, '<VM><MEMORY>128</MEMORY><CPU>1</CPU></VM>')
+            s_message = "Created with id = " + str(vm_id)
+            # Lets print the VMs available in the pool
+            # print("Printing the available VMs in the pool.")
+            # vm_pool = oca.VirtualMachinePool(client)
+            # for vm in vm_pool:
+            # 	print("%s (memory: %s MB)" % ( vm.name, vm.template.memory))
+        except socket.timeout:
+            e_message = "Socket timeout error."
+        except OpenNebulaException:
+            e_message = "OpenNebulaException occurred."
+        context = dict(
+            # Include common variables for rendering the admin template.
+            self.admin_site.each_context(request),
+            error_msg=e_message,
+            success_msg=s_message,
+            # Anything else you want in the context...
+            # key=value,
+        )
+        return TemplateResponse(request, "hosting/managevms.html", context)
+    
+    def get_vms():
+        vm_pool = oca.VirtualMachinePool(self.client)
+        return vm_pool
 
 admin.site.register(HostingOrder, HostingOrderAdmin)
 admin.site.register(VirtualMachineType)
 admin.site.register(VirtualMachinePlan, VirtualMachinePlanAdmin)
+admin.site.register(ManageVMs, HostingManageVMsAdmin)
diff --git a/hosting/models.py b/hosting/models.py
index e5899b0e..f1f8314c 100644
--- a/hosting/models.py
+++ b/hosting/models.py
@@ -224,13 +224,13 @@ class HostingOrder(AssignPermissionsMixin, models.Model):
         self.save()
 
 
+class ManageVMs(models.Model):
+    #name = models.TextField(blank=True)
+    def has_add_permission(self, request):
+        return False
 
+    def has_delete_permission(self, request, obj=None):
+        return False
 
-
-
-
-
-
-
-
-
+    class Meta:
+        managed = False
diff --git a/hosting/templates/hosting/managevms.html b/hosting/templates/hosting/managevms.html
new file mode 100644
index 00000000..bdf53a43
--- /dev/null
+++ b/hosting/templates/hosting/managevms.html
@@ -0,0 +1,21 @@
+{% extends "admin/base_site.html" %}
+{% block content %}
+{% if error_msg %}
+<p class="alert alert-danger">{{error_msg}}</p>
+{% endif %}
+{% if success_msg %}
+<p class="alert alert-success">{{success_msg}}</p>
+{% endif %}
+<a href="{% url 'admin:createvm' %}">Create VM</a>
+
+{% if vms %}
+<section>
+<ul class="list-group">
+{% for vm in vms %}
+<li class="list-group-item">{{vm.name}} --- {{vm.template.memory}} --- {{vm.state}} --- {{vm.uname}}</li>
+{% endfor %}
+</ul>
+</section>
+{% endif %}
+
+{% endblock %}