summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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)