summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Provaznik <jprovazn@redhat.com>2013-06-05 19:40:46 +0200
committerTomas Sedovic <tomas@sedovic.cz>2013-08-01 16:18:54 +0200
commit4f6130e81c807c725fd096f5e03369ae66d733f4 (patch)
tree326adcebb50bc64c82aa36da72fa1cd059686926
parent9bcc935c1c70ddd8b22689ac0830dae5632f0c69 (diff)
downloadtuskar-ui-4f6130e81c807c725fd096f5e03369ae66d733f4.tar.gz
Initial management dummy api
Added new api module for communication with openstack-management service. Structure of this module is similar to other existing api modules (IOW plain list of api methods). True is this plain structure of api methods is not optimal because there is ATM not good place to put business logic, but this is horizon wide issue and will be targeted in a separate patch. Because there is not real management service yet, these api methods use classic Django models for storing dummy data. You have to run "python manage.py syncdb" to init/update db. Change-Id: I4e56be6824061f55021819ff66faa1cfd7f135d2
-rw-r--r--.gitignore1
-rw-r--r--openstack_dashboard/api/__init__.py1
-rw-r--r--openstack_dashboard/api/management.py93
-rw-r--r--openstack_dashboard/dashboards/infrastructure/fixtures/initial_data.json6
-rw-r--r--openstack_dashboard/dashboards/infrastructure/models.py30
-rw-r--r--openstack_dashboard/settings.py13
-rw-r--r--openstack_dashboard/test/api_tests/management_tests.py65
7 files changed, 206 insertions, 3 deletions
diff --git a/.gitignore b/.gitignore
index 0f6793ef..7cdaea1e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,3 +25,4 @@ dist
AUTHORS
ChangeLog
tags
+openstack_dashboard/dummydb.sqlite
diff --git a/openstack_dashboard/api/__init__.py b/openstack_dashboard/api/__init__.py
index dd3bdedc..7c9f8300 100644
--- a/openstack_dashboard/api/__init__.py
+++ b/openstack_dashboard/api/__init__.py
@@ -39,6 +39,7 @@ from openstack_dashboard.api import glance
from openstack_dashboard.api import heat
from openstack_dashboard.api import keystone
from openstack_dashboard.api import lbaas
+from openstack_dashboard.api import management
from openstack_dashboard.api import network
from openstack_dashboard.api import neutron
from openstack_dashboard.api import nova
diff --git a/openstack_dashboard/api/management.py b/openstack_dashboard/api/management.py
new file mode 100644
index 00000000..9a19c323
--- /dev/null
+++ b/openstack_dashboard/api/management.py
@@ -0,0 +1,93 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import logging
+from openstack_dashboard.api import base
+import openstack_dashboard.dashboards.infrastructure.models as dummymodels
+
+LOG = logging.getLogger(__name__)
+
+
+class StringIdAPIResourceWrapper(base.APIResourceWrapper):
+ # horizon DataTable class expects ids to be string,
+ # if it's not string, then comparison in
+ # horizon/tables/base.py:get_object_by_id fails.
+ # Because of this, ids returned from dummy api are converted to string
+ # (luckily django autoconverts strings to integers when passing string to
+ # django model id)
+ @property
+ def id(self):
+ return str(self._apiresource.id)
+
+
+class ResourceClass(StringIdAPIResourceWrapper):
+ """Wrapper for the ResourceClass object returned by the
+ dummy model.
+ """
+ _attrs = ['name', 'service_type']
+
+ @property
+ def flavors(self):
+ if "_flavors" not in self.__dict__:
+ self._flavors = [Flavor(f) for f in
+ self._apiresource.flavors.all()]
+ return self.__dict__['_flavors']
+
+
+class Flavor(StringIdAPIResourceWrapper):
+ """Wrapper for the Flavor object returned by the
+ dummy model.
+ """
+ _attrs = ['name']
+
+
+def resource_class_list(request):
+ return [ResourceClass(rc) for rc in
+ dummymodels.ResourceClass.objects.all()]
+
+
+def resource_class_get(request, resource_class_id):
+ return ResourceClass(dummymodels.ResourceClass.objects.get(
+ id=resource_class_id))
+
+
+def resource_class_create(request, name, service_type):
+ rc = dummymodels.ResourceClass(name=name,
+ service_type=service_type)
+ # TODO: save() and delete() operations don't return any value,
+ # we might wrap this up in future if needed
+ rc.save()
+
+
+def resource_class_delete(request, resource_class_id):
+ dummymodels.ResourceClass.objects.get(id=resource_class_id).delete()
+
+
+def flavor_list(request):
+ return [Flavor(f) for f in dummymodels.Flavor.objects.all()]
+
+
+def flavor_get(request, flavor_id):
+ return Flavor(dummymodels.Flavor.objects.get(id=flavor_id))
+
+
+def flavor_create(request, name):
+ flavor = dummymodels.Flavor(name=name)
+ flavor.save()
+
+
+def flavor_delete(request, flavor_id):
+ dummymodels.Flavor.objects.get(id=flavor_id).delete()
diff --git a/openstack_dashboard/dashboards/infrastructure/fixtures/initial_data.json b/openstack_dashboard/dashboards/infrastructure/fixtures/initial_data.json
new file mode 100644
index 00000000..a6ea0c3d
--- /dev/null
+++ b/openstack_dashboard/dashboards/infrastructure/fixtures/initial_data.json
@@ -0,0 +1,6 @@
+[
+ {"pk": 1, "model": "infrastructure.flavor", "fields": {"name": "flavor1"}},
+ {"pk": 1, "model": "infrastructure.resourceclass", "fields": {"service_type": "compute", "flavors": [1], "name": "rclass1"}},
+ {"pk": 2, "model": "infrastructure.resourceclass", "fields": {"service_type": "compute", "flavors": [], "name": "rclass2"}},
+ {"pk": 3, "model": "infrastructure.resourceclass", "fields": {"service_type": "storage", "flavors": [], "name": "rclass3"}}
+]
diff --git a/openstack_dashboard/dashboards/infrastructure/models.py b/openstack_dashboard/dashboards/infrastructure/models.py
index 14d87bfb..da900d27 100644
--- a/openstack_dashboard/dashboards/infrastructure/models.py
+++ b/openstack_dashboard/dashboards/infrastructure/models.py
@@ -14,6 +14,30 @@
# License for the specific language governing permissions and limitations
# under the License.
-"""
-Stub file to work around django bug: https://code.djangoproject.com/ticket/7198
-"""
+# FIXME: configuration for dummy data
+from django.db import models
+
+
+class Flavor(models.Model):
+ class Meta:
+ db_table = 'infrastructure_flavor'
+
+ name = models.CharField(max_length=50, unique=True)
+ # TODO: proper capacities representation
+
+ def capacities():
+ return []
+
+
+class ResourceClass(models.Model):
+ class Meta:
+ # syncdb by default creates 'openstack_dashboard_resourceclass' table,
+ # but it's better to keep models under
+ # openstack_dashboard/dashboards/infrastructure/models.py instead of
+ # openstack_dashboard/models.py since the models.py stub file is
+ # required here anyway
+ db_table = 'infrastructure_resourceclass'
+
+ name = models.CharField(max_length=50, unique=True)
+ service_type = models.CharField(max_length=50)
+ flavors = models.ManyToManyField(Flavor)
diff --git a/openstack_dashboard/settings.py b/openstack_dashboard/settings.py
index ed739894..e7fb4a5a 100644
--- a/openstack_dashboard/settings.py
+++ b/openstack_dashboard/settings.py
@@ -192,3 +192,16 @@ COMPRESS_OFFLINE_CONTEXT = {
if DEBUG:
logging.basicConfig(level=logging.DEBUG)
+
+# FIXME: configuration for dummy data
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.sqlite3',
+ 'NAME': 'openstack_dashboard/dummydb.sqlite',
+ }
+}
+
+# FIXME: configuration for dummy data
+FIXTURE_DIRS = (
+ 'openstack_dashboard/dashboards/infrastructure/fixtures/',
+)
diff --git a/openstack_dashboard/test/api_tests/management_tests.py b/openstack_dashboard/test/api_tests/management_tests.py
new file mode 100644
index 00000000..19fb81a6
--- /dev/null
+++ b/openstack_dashboard/test/api_tests/management_tests.py
@@ -0,0 +1,65 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from __future__ import absolute_import
+
+from django import http
+from django.conf import settings
+from django.test.utils import override_settings
+
+from mox import IsA
+
+from openstack_dashboard import api
+from openstack_dashboard.test import helpers as test
+import openstack_dashboard.dashboards.infrastructure.models as dummymodels
+
+
+class ManagementApiTests(test.APITestCase):
+ def setUp(self):
+ super(ManagementApiTests, self).setUp()
+ # dummy data are seeded from fixtures
+ self.rclass1 = dummymodels.ResourceClass.objects.get(name='rclass1')
+ self.flavor1 = dummymodels.Flavor.objects.get(name='flavor1')
+
+ def test_resource_class_list(self):
+ rc_list = api.management.resource_class_list(self.request)
+ self.assertEquals(3, len(rc_list))
+ for rc in rc_list:
+ self.assertIsInstance(rc, api.management.ResourceClass)
+
+ def test_resource_class_get(self):
+ rc = api.management.resource_class_get(self.request, self.rclass1.id)
+ self.assertIsInstance(rc, api.management.ResourceClass)
+ self.assertEquals(rc.name, self.rclass1.name)
+
+ def test_resource_class_flavors(self):
+ rc = api.management.resource_class_get(self.request, self.rclass1.id)
+ for f in rc.flavors:
+ self.assertIsInstance(f, api.management.Flavor)
+ self.assertEquals(1, len(rc.flavors))
+
+ # TODO: create, delete operations
+
+ def test_flavor_list(self):
+ flist = api.management.flavor_list(self.request)
+ self.assertEquals(1, len(flist))
+ for f in flist:
+ self.assertIsInstance(f, api.management.Flavor)
+
+ def test_flavor_get(self):
+ flavor = api.management.flavor_get(self.request, self.flavor1.id)
+ self.assertIsInstance(flavor, api.management.Flavor)
+ self.assertEquals(flavor.name, self.flavor1.name)