From df777f384d8153aebd901c6cde9ed40690c899c7 Mon Sep 17 00:00:00 2001 From: Modulos Date: Tue, 9 May 2017 16:33:56 +0200 Subject: [PATCH] Initial commit Please Note: This app is going to be developed in a TDD style. Please add test first and then the corresponding code. This way we can be sure everything works and it should help us coordinate our work. --- dynamicweb/settings/base.py | 2 + opennebula_api/__init__.py | 0 opennebula_api/admin.py | 3 + opennebula_api/apps.py | 5 ++ opennebula_api/migrations/__init__.py | 0 opennebula_api/models.py | 70 +++++++++++++++++++++ opennebula_api/tests.py | 90 +++++++++++++++++++++++++++ opennebula_api/views.py | 3 + requirements.txt | 2 +- 9 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 opennebula_api/__init__.py create mode 100644 opennebula_api/admin.py create mode 100644 opennebula_api/apps.py create mode 100644 opennebula_api/migrations/__init__.py create mode 100644 opennebula_api/models.py create mode 100644 opennebula_api/tests.py create mode 100644 opennebula_api/views.py diff --git a/dynamicweb/settings/base.py b/dynamicweb/settings/base.py index a4db650c..d9ccd7ac 100644 --- a/dynamicweb/settings/base.py +++ b/dynamicweb/settings/base.py @@ -111,6 +111,8 @@ INSTALLED_APPS = ( 'nosystemd', 'datacenterlight', 'alplora', + 'rest_framework', + 'opennebula_api' ) MIDDLEWARE_CLASSES = ( diff --git a/opennebula_api/__init__.py b/opennebula_api/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/opennebula_api/admin.py b/opennebula_api/admin.py new file mode 100644 index 00000000..8c38f3f3 --- /dev/null +++ b/opennebula_api/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/opennebula_api/apps.py b/opennebula_api/apps.py new file mode 100644 index 00000000..c70ffbdf --- /dev/null +++ b/opennebula_api/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class OpennebulaApiConfig(AppConfig): + name = 'opennebula_api' diff --git a/opennebula_api/migrations/__init__.py b/opennebula_api/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/opennebula_api/models.py b/opennebula_api/models.py new file mode 100644 index 00000000..83273767 --- /dev/null +++ b/opennebula_api/models.py @@ -0,0 +1,70 @@ +import oca +import socket + +from django.db import models +from django.conf import settings + +from oca.pool import WrongNameError + +class VirtualMachineTemplate(models.Model): + """This class represents an opennebula template.""" + opennebula_id = models.IntegerField() + base_price = models.FloatField() + memory_price = models.FloatField() + core_price = models.FloatField() + disk_size_price = models.FloatField() + + +class VirtualMachine(models.Model): + """This class represents an opennebula virtual machine.""" + opennebula_id = models.IntegerField() + template = models.ForeignKey(VirtualMachineTemplate) + +class OpenNebulaManager(): + """This class represents an opennebula manager.""" + + def __init__(self, email=None, password=None, create_user=True): + + # Get oneadmin client + self.oneadmin_client = self._get_opennebula_client( + settings.OPENNEBULA_USERNAME, + settings.OPENNEBULA_PASSWORD + ) + + if not create_user: + return + + # Get or create oppenebula user using given credentials + self.opennebula_user = self._get_or_create_user( + email, + password + ) + + # If opennebula user was created/obtained, get his client + if self.opennebula_user: + self.client = self._get_opennebula_client( + email, + password + ) + + def _get_opennebula_client(self, username, password): + return oca.Client("{0}:{1}".format( + username, + password), + "{protocol}://{domain}:{port}{endpoint}".format( + protocol=settings.OPENNEBULA_PROTOCOL, + domain=settings.OPENNEBULA_DOMAIN, + port=settings.OPENNEBULA_PORT, + endpoint=settings.OPENNEBULA_ENDPOINT + )) + + def _get_or_create_user(self, email, password): + try: + user_pool = oca.UserPool(self.oneadmin_client) + user_pool.info() + opennebula_user = user_pool.get_by_name(email) + return opennebula_user + except WrongNameError as wrong_name_err: + opennebula_user = self.oneadmin_client.call(oca.User.METHODS['allocate'], email, + password, 'core') + return opennebula_user diff --git a/opennebula_api/tests.py b/opennebula_api/tests.py new file mode 100644 index 00000000..ab70854f --- /dev/null +++ b/opennebula_api/tests.py @@ -0,0 +1,90 @@ +from django.test import TestCase +from .models import VirtualMachine + +class OpenNebulaManagerTestCases(TestCase): + """This class defines the test suite for the opennebula manager model.""" + + def setUp(self): + """Define the test client and other test variables.""" + self.cores = 1 + self.memory = 1 + self.disk_size = 10.0 + + self.email = 'test@test.com' + self.password = 'testtest' + + self.manager = OpenNebulaManager(email=None, password=None, create_user=False) + + + def test_model_can_connect_to_server(self): + """Test the opennebula manager model can connect to a server.""" + self.assertFalse(self.manager is None) + + def test_model_can_create_user(self): + """Test the opennebula manager model can create a new user.""" + old_count = self.manager._get_user_pool().count() + self.manager = OpenNebulaManager(email=self.email, + password=self.password, + create_user=True) + new_count = self.manager._get_user_pool().count() + self.assertNotEqual(old_count, new_count) + + +class VirtualMachineTemplateTestCase(TestCase): + """This class defines the test suite for the virtualmachine template model.""" + + def setUp(self): + """Define the test client and other test variables.""" + self.template_name = "Standard" + self.base_price = 0.0 + self.core_price = 5.0 + self.memory_price = 2.0 + self.disk_size_price = 0.6 + + self.cores = 1 + self.memory = 1 + self.disk_size = 10.0 + + self.manager = OpenNebulaManager(email=None, password=None, create_user=False) + self.opennebula_id = self.manager.create_template(self.cores, self.memory, + self.disk_size) + + self.template = VirtualMachineTemplate(opennebula_id=self.opennebula_id, + base_price=self.base_price, + memory_price=self.memory_price, + core_price=self.core_price, + disk_size_price=self.disk_size_price) + + + def test_model_can_create_a_virtualmachine_template(self): + """Test the virtualmachine template model can create a template.""" + old_count = VirtualMachineTemplate.objects.count() + self.template.save() + new_count = VirtualMachineTemplate.objects.count() + self.assertNotEqual(old_count, new_count) + + +class VirtualMachineTestCase(TestCase): + def setUp(self): + """Define the test client and other test variables.""" + self.manager = OpenNebulaManager(email=None, password=None, create_user=False) + self.template = VirtualMachineTemplate.objects.first() + self.template_id self.template.opennebula_id() + self.opennebula_id = self.manager.create_virtualmachine(template_id=self.template_id) + + self.virtualmachine = VirtualMachine(opennebula_id=self.opennebula_id, + template=self.template) + + def test_model_can_create_a_virtualmachine(self): + """Test the virtualmachine model can create a virtualmachine.""" + old_count = VirtualMachine.objects.count() + self.virtualmachine.save() + new_count = VirtualMachine.objects.count() + self.assertNotEqual(old_count, new_count) + + def test_model_can_delete_a_virtualmachine(self): + """Test the virtualmachine model can delete a virtualmachine.""" + old_count = VirtualMachine.objects.count() + VirtualMachine.objects.first().delete() + new_count = VirtualMachine.objects.count() + self.assertNotEqual(old_count, new_count) diff --git a/opennebula_api/views.py b/opennebula_api/views.py new file mode 100644 index 00000000..91ea44a2 --- /dev/null +++ b/opennebula_api/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/requirements.txt b/requirements.txt index 86499301..cec95282 100644 --- a/requirements.txt +++ b/requirements.txt @@ -83,6 +83,6 @@ wheel==0.29.0 django-admin-honeypot==1.0.0 coverage==4.3.4 git+https://github.com/python-oca/python-oca.git#egg=python-oca - +djangorestframework