summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTzu-Mainn Chen <tzumainn@redhat.com>2013-07-16 17:39:51 -0400
committerTomas Sedovic <tomas@sedovic.cz>2013-08-01 16:18:56 +0200
commit4e2aebdd3bc0f2accc0869caae3e7c36684fb22f (patch)
treed8f6a0a0864c2a3eb97667aa2395cd5cfe68eca7
parent242cc3ff31713e66e9e39590a0d4df5a21f2a46c (diff)
downloadtuskar-ui-4e2aebdd3bc0f2accc0869caae3e7c36684fb22f.tar.gz
Integrate python-tuskarclient
This patch integrates python-tuskarclient. To install, run: pip install -r tools/pip-requires The patch also updates the ResourceClass and Rack CRUD operations to use tuskarclient. 'flavors' and 'racks' methods are renamed to 'list_flavors' and 'list_racks' to prevent collision, as 'racks' is now an attribute of a resource class. This is also consistent with Horizon nomenclature. Associations are *not* updated; so a resource class cannot associate itself with racks or flavors. The body of those methods are simply commented out to allow the UI to 'work' with no errors. API tests associated with the above associations fail; all other tests should pass. Change-Id: I53dcbb79ad02e32b9bf9d4ed9c61a8dd13e3d0e0
-rw-r--r--openstack_dashboard/api/tuskar.py251
-rw-r--r--openstack_dashboard/dashboards/infrastructure/resource_management/racks/tabs.py2
-rw-r--r--openstack_dashboard/dashboards/infrastructure/resource_management/racks/tests.py62
-rw-r--r--openstack_dashboard/dashboards/infrastructure/resource_management/racks/views.py5
-rw-r--r--openstack_dashboard/dashboards/infrastructure/resource_management/racks/workflows.py4
-rw-r--r--openstack_dashboard/dashboards/infrastructure/resource_management/resource_classes/tabs.py4
-rw-r--r--openstack_dashboard/dashboards/infrastructure/resource_management/resource_classes/tests.py49
-rw-r--r--openstack_dashboard/dashboards/infrastructure/resource_management/tests.py4
-rw-r--r--openstack_dashboard/local/local_settings.py.example4
-rw-r--r--openstack_dashboard/test/api_tests/tuskar_tests.py25
-rw-r--r--openstack_dashboard/test/helpers.py10
-rw-r--r--openstack_dashboard/test/settings.py4
-rw-r--r--requirements.txt2
13 files changed, 286 insertions, 140 deletions
diff --git a/openstack_dashboard/api/tuskar.py b/openstack_dashboard/api/tuskar.py
index 1c86a462..31ad2e01 100644
--- a/openstack_dashboard/api/tuskar.py
+++ b/openstack_dashboard/api/tuskar.py
@@ -17,14 +17,25 @@ import logging
from datetime import timedelta
from random import randint
+from django.conf import settings
from django.db.models import Sum, Max
from django.utils.translation import ugettext_lazy as _
+from tuskarclient.v1 import client as tuskar_client
+
from openstack_dashboard.api import base
import openstack_dashboard.dashboards.infrastructure.models as dummymodels
LOG = logging.getLogger(__name__)
+TUSKAR_ENDPOINT_URL = getattr(settings, 'TUSKAR_ENDPOINT_URL')
+
+
+# FIXME: request isn't used right in the tuskar client right now, but looking
+# at other clients, it seems like it will be in the future
+def tuskarclient(request):
+ c = tuskar_client.Client(TUSKAR_ENDPOINT_URL)
+ return c
class StringIdAPIResourceWrapper(base.APIResourceWrapper):
@@ -207,27 +218,64 @@ class Rack(StringIdAPIResourceWrapper):
"""Wrapper for the Rack object returned by the
dummy model.
"""
- _attrs = ['name', 'resource_class_id', 'location', 'subnet']
+ _attrs = ['id', 'name', 'location', 'subnet', 'nodes']
@classmethod
def create(cls, request, name, resource_class_id, location, subnet):
- rack = dummymodels.Rack(name=name,
- resource_class_id=resource_class_id,
- location=location, subnet=subnet)
- rack.save()
- return rack
+ ## FIXME: Where is the location attribute?? Also, set nodes
+ ## here
+ rack = tuskarclient(request).racks.create(
+ name=name,
+ #location=location,
+ subnet=subnet,
+ nodes=[],
+ slots=0)
+
+ ## FIXME: it would be optimal if we didn't have to make a separate
+ ## call for this. racks= also needs to be fixed
+ ## ALSO it doesn't seem to work, I can't get it to work using curl
+ ## from the command line
+ #rc = ResourceClass.get(request, resource_class_id)
+ #ResourceClass.update(request, resource_class_id,
+ # name=rc.name,
+ # service_type=rc.service_type,
+ # racks={"id": rack.id})
+
+ return cls(rack)
+
+ @classmethod
+ def update(cls, request, rack_id, kwargs):
+ return cls(tuskarclient(request).racks.update(rack_id,
+ name=kwargs['name'],
+ #location=location,
+ subnet=kwargs['subnet'],
+ nodes=[],
+ slots=0))
@classmethod
def list(cls, request, only_free_racks=False):
+ ## FIXME: currently resource_class is not an attribute of a rack; can
+ ## that be changed? If so, we can do free_racks much more easily
if only_free_racks:
- return [cls(r) for r in dummymodels.Rack.objects.all() if (
- r.resource_class is None)]
+ return [Rack(r) for r in
+ tuskarclient(request).racks.list()]
else:
- return [cls(r) for r in dummymodels.Rack.objects.all()]
+ return [Rack(r) for r in
+ tuskarclient(request).racks.list()]
@classmethod
def get(cls, request, rack_id):
- return cls(dummymodels.Rack.objects.get(id=rack_id))
+ return cls(tuskarclient(request).racks.get(rack_id))
+
+ ## FIXME: this is temporary
+ @property
+ def resource_class_id(self):
+ return 1
+
+ ## FIXME: as is this
+ @property
+ def location(self):
+ return "somewhere"
@property
def capacities(self):
@@ -330,16 +378,19 @@ class Rack(StringIdAPIResourceWrapper):
@classmethod
def delete(cls, request, rack_id):
- dummymodels.Rack.objects.get(id=rack_id).delete()
+ tuskarclient(request).racks.delete(rack_id)
+ ## FIXME: this will have to be rewritten to ultimately
+ ## fetch nodes from nova baremetal
@property
- def nodes(self):
- if not hasattr(self, '_nodes'):
- self._nodes = [Node(h) for h in self._apiresource.node_set.all()]
- return self._nodes
+ def list_nodes(self):
+ return []
+ #if not hasattr(self, '_nodes'):
+ # self._nodes = [Node(h) for h in self._apiresource.node_set.all()]
+ #return self._nodes
def nodes_count(self):
- return len(self.nodes)
+ return len(self.list_nodes)
# The idea here is to take a list of MAC addresses and assign them to
# our rack. I'm attaching this here so that we can take one list, versus
@@ -369,16 +420,6 @@ class Rack(StringIdAPIResourceWrapper):
self._resource_class = self._apiresource.resource_class
return self._resource_class
- @classmethod
- def update(cls, rack_id, kwargs):
- rack = dummymodels.Rack.objects.get(id=rack_id)
- rack.name = kwargs['name']
- rack.location = kwargs['location']
- rack.subnet = kwargs['subnet']
- rack.resource_class_id = kwargs['resource_class_id']
- rack.save()
- return cls(rack)
-
##########################################################################
# ResourceClass
@@ -387,44 +428,37 @@ class ResourceClass(StringIdAPIResourceWrapper):
"""Wrapper for the ResourceClass object returned by the
dummy model.
"""
- _attrs = ['name', 'service_type', 'status']
+ _attrs = ['name', 'service_type', 'racks']
##########################################################################
# ResourceClass Class methods
##########################################################################
@classmethod
def get(cls, request, resource_class_id):
- obj = cls(dummymodels.ResourceClass.objects.get(
- id=resource_class_id))
- obj.set_request(request)
- return obj
+ rc = cls(tuskarclient(request).resource_classes.get(resource_class_id))
+ rc.set_request(request)
+ return rc
@classmethod
def create(self, request, name, service_type):
- rc = dummymodels.ResourceClass(
- name=name,
- service_type=service_type)
-
- rc.save()
- return ResourceClass(rc)
+ return ResourceClass(
+ tuskarclient(request).resource_classes.create(
+ name=name,
+ service_type=service_type))
@classmethod
def list(self, request):
- return [
- ResourceClass(rc) for rc in (
- dummymodels.ResourceClass.objects.all())]
+ return [ResourceClass(rc) for rc in
+ tuskarclient(request).resource_classes.list()]
@classmethod
def update(cls, request, resource_class_id, **kwargs):
- rc = dummymodels.ResourceClass.objects.get(id=resource_class_id)
- rc.name = kwargs['name']
- rc.service_type = kwargs['service_type']
- rc.save()
- return cls(rc)
+ return cls(tuskarclient(request).resource_classes.update(
+ resource_class_id, **kwargs))
@classmethod
def delete(cls, request, resource_class_id):
- dummymodels.ResourceClass.objects.get(id=resource_class_id).delete()
+ tuskarclient(request).resource_classes.delete(resource_class_id)
##########################################################################
# ResourceClass Properties
@@ -437,12 +471,10 @@ class ResourceClass(StringIdAPIResourceWrapper):
self.racks)]
@property
- def racks(self):
+ def list_racks(self):
""" List of racks added to ResourceClass """
if not hasattr(self, '_racks'):
- self._racks =\
- [Rack(r) for r in (
- self._apiresource.rack_set.all())]
+ self._racks = [Rack(r) for r in self.racks]
return self._racks
@property
@@ -454,7 +486,7 @@ class ResourceClass(StringIdAPIResourceWrapper):
[r for r in (
Rack.list(self.request)) if (
r.resource_class_id is None or
- r._apiresource.resource_class == self._apiresource)]
+ r.resource_class_id == self.id)]
return self._all_racks
@property
@@ -465,47 +497,55 @@ class ResourceClass(StringIdAPIResourceWrapper):
self._apiresource.resourceclassflavor_set.all())]
return self._resource_class_flavors
+ ## FIXME: this isn't currently supported by the client library, so would
+ ## have to be done through curl
@property
def flavors_ids(self):
""" List of unicode ids of flavors added to resource class """
- return [
- unicode(flavor.flavor.id) for flavor in (
- self.resource_class_flavors)]
+ #return [
+ # unicode(flavor.flavor.id) for flavor in (
+ # self.resource_class_flavors)]
+ return []
+ ## FIXME: this isn't currently supported by the client library, so would
+ ## have to be done through curl
@property
- def flavors(self):
+ def list_flavors(self):
""" Joined relation table resourceclassflavor and flavor together """
- if not hasattr(self, '_flavors'):
- added_flavors = self.resource_class_flavors
- self._flavors = []
- for f in added_flavors:
- flavor_obj = Flavor.get(self.request, f.flavor.id)
- flavor_obj.set_max_vms(f.max_vms)
- self._flavors.append(flavor_obj)
-
- return self._flavors
-
+ #if not hasattr(self, '_flavors'):
+ # added_flavors = self.resource_class_flavors
+ # self._flavors = []
+ # for f in added_flavors:
+ # flavor_obj = Flavor.get(self.request, f.flavor.id)
+ # flavor_obj.set_max_vms(f.max_vms)
+ # self._flavors.append(flavor_obj)
+ #return self._flavors
+ return []
+
+ ## FIXME: this isn't currently supported by the client library, so would
+ ## have to be done through curl
@property
def all_flavors(self):
""" Joined relation table resourceclassflavor with all global flavors
"""
- if not hasattr(self, '_all_flavors'):
- all_flavors = Flavor.list(self.request)
+ #if not hasattr(self, '_all_flavors'):
+ # all_flavors = Flavor.list(self.request)
- added_resourceclassflavors = \
- self._apiresource.resourceclassflavor_set.all()
- added_flavors = {}
- for added_flavor in added_resourceclassflavors:
- added_flavors[str(added_flavor.flavor_id)] = added_flavor
+ # added_resourceclassflavors = \
+ # self._apiresource.resourceclassflavor_set.all()
+ # added_flavors = {}
+ # for added_flavor in added_resourceclassflavors:
+ # added_flavors[str(added_flavor.flavor_id)] = added_flavor
- self._all_flavors = []
- for f in all_flavors:
- added_flavor = added_flavors.get(f.id)
- if added_flavor:
- f.set_max_vms(added_flavor.max_vms)
- self._all_flavors.append(f)
+ # self._all_flavors = []
+ # for f in all_flavors:
+ # added_flavor = added_flavors.get(f.id)
+ # if added_flavor:
+ # f.set_max_vms(added_flavor.max_vms)
+ # self._all_flavors.append(f)
- return self._all_flavors
+ #return self._all_flavors
+ return []
@property
def nodes(self):
@@ -626,35 +666,40 @@ class ResourceClass(StringIdAPIResourceWrapper):
##########################################################################
# ResourceClass Instance methods
##########################################################################
+
+ ## FIXME: this will have to be done some other way
def set_flavors(self, request, flavors_ids, max_vms=None):
+ return
# simply delete all and create new flavors, that'is
# how the horizon flavors work
- max_vms = max_vms or {}
-
- for flavor_id in self.flavors_ids:
- ResourceClassFlavor.delete(request,
- self.id,
- flavor_id)
-
- for flavor_id in flavors_ids:
- flavor = Flavor.get(request, flavor_id)
- ResourceClassFlavor.create(
- request,
- max_vms=max_vms.get(flavor.id),
- flavor=flavor._apiresource,
- resource_class=self._apiresource)
-
+ #max_vms = max_vms or {}
+
+ #for flavor_id in self.flavors_ids:
+ # ResourceClassFlavor.delete(request,
+ # self.id,
+ # flavor_id)
+
+ #for flavor_id in flavors_ids:
+ # flavor = Flavor.get(request, flavor_id)
+ # ResourceClassFlavor.create(
+ # request,
+ # max_vms=max_vms.get(flavor.id),
+ # flavor=flavor._apiresource,
+ # resource_class=self._apiresource)
+
+ ## FIXME: this will have to be done some other way
def set_racks(self, request, racks_ids):
+ return
# simply delete all and create new racks
- for rack_id in self.racks_ids:
- rack = Rack.get(request, rack_id)
- rack._apiresource.resource_class = None
- rack._apiresource.save()
-
- for rack_id in racks_ids:
- rack = Rack.get(request, rack_id)
- rack._apiresource.resource_class = self._apiresource
- rack._apiresource.save()
+ #for rack_id in self.racks_ids:
+ # rack = Rack.get(request, rack_id)
+ # rack._apiresource.resource_class = None
+ # rack._apiresource.save()
+
+ #for rack_id in racks_ids:
+ # rack = Rack.get(request, rack_id)
+ # rack._apiresource.resource_class = self._apiresource
+ # rack._apiresource.save()
class Flavor(StringIdAPIResourceWrapper):
diff --git a/openstack_dashboard/dashboards/infrastructure/resource_management/racks/tabs.py b/openstack_dashboard/dashboards/infrastructure/resource_management/racks/tabs.py
index 029b03b2..06b6ff8e 100644
--- a/openstack_dashboard/dashboards/infrastructure/resource_management/racks/tabs.py
+++ b/openstack_dashboard/dashboards/infrastructure/resource_management/racks/tabs.py
@@ -40,7 +40,7 @@ class NodesTab(tabs.TableTab):
def get_nodes_data(self):
try:
rack = self.tab_group.kwargs['rack']
- nodes = rack.nodes
+ nodes = rack.list_nodes
except:
nodes = []
exceptions.handle(self.tab_group.request,
diff --git a/openstack_dashboard/dashboards/infrastructure/resource_management/racks/tests.py b/openstack_dashboard/dashboards/infrastructure/resource_management/racks/tests.py
index 7ad2f1a8..8f96856b 100644
--- a/openstack_dashboard/dashboards/infrastructure/resource_management/racks/tests.py
+++ b/openstack_dashboard/dashboards/infrastructure/resource_management/racks/tests.py
@@ -23,7 +23,14 @@ from django.core.files.uploadedfile import InMemoryUploadedFile
class RackViewTests(test.BaseAdminViewTests):
index_page = reverse('horizon:infrastructure:resource_management:index')
+ @test.create_stubs({api.tuskar.ResourceClass: ('list',)})
def test_create_rack_get(self):
+ api.tuskar.ResourceClass.list(
+ IsA(http.request.HttpRequest)).AndReturn(
+ self.tuskar_resource_classes.list())
+
+ self.mox.ReplayAll()
+
url = reverse('horizon:infrastructure:resource_management:'
'racks:create')
rack = self.client.get(url)
@@ -35,10 +42,18 @@ class RackViewTests(test.BaseAdminViewTests):
# FIXME (mawagner) - After moving EditRack to use workflows, we need
# to circle back and fix these tests.
#
- @test.create_stubs({api.tuskar.Rack: ('create',)})
+ @test.create_stubs({api.tuskar.Rack: ('list', 'create',),
+ api.tuskar.ResourceClass: ('list',)})
def test_create_rack_post(self):
+ api.tuskar.Rack.list(
+ IsA(http.request.HttpRequest)).AndReturn(
+ self.tuskar_racks.list())
api.tuskar.Rack.create(IsA(http.request.HttpRequest), 'New Rack',
u'2', 'Tokyo', '1.2.3.4').AndReturn(None)
+ api.tuskar.ResourceClass.list(
+ IsA(http.request.HttpRequest)).AndReturn(
+ self.tuskar_resource_classes.list())
+
self.mox.ReplayAll()
data = {'name': 'New Rack', 'resource_class_id': u'2',
@@ -48,35 +63,66 @@ class RackViewTests(test.BaseAdminViewTests):
resp = self.client.post(url, data)
self.assertRedirectsNoFollow(resp, self.index_page)
+ @test.create_stubs({api.tuskar.Rack: ('get',),
+ api.tuskar.ResourceClass: ('list',)})
def test_edit_rack_get(self):
+ rack = self.tuskar_racks.first()
+
+ api.tuskar.Rack.\
+ get(IsA(http.HttpRequest), rack.id).\
+ AndReturn(rack)
+ api.tuskar.ResourceClass.list(
+ IsA(http.request.HttpRequest)).AndReturn(
+ self.tuskar_resource_classes.list())
+
+ self.mox.ReplayAll()
+
url = reverse('horizon:infrastructure:resource_management:' +
'racks:edit', args=[1])
- rack = self.client.get(url)
- self.assertEqual(rack.status_code, 200)
- self.assertTemplateUsed(rack,
+ res = self.client.get(url)
+ self.assertEqual(res.status_code, 200)
+ self.assertTemplateUsed(res,
'horizon/common/_workflow_base.html')
- @test.create_stubs({api.tuskar.Rack: ('update',)})
+ @test.create_stubs({api.tuskar.Rack: ('get', 'list', 'update',),
+ api.tuskar.ResourceClass: ('list',)})
def test_edit_rack_post(self):
+ rack = self.tuskar_racks.first()
+
data = {'name': 'Updated Rack', 'resource_class_id': u'1',
'rack_id': u'1', 'location': 'New Location',
'subnet': '127.10.10.0/24', 'node_macs': 'foo'}
- api.tuskar.Rack.update(u'1', data)
+ api.tuskar.Rack.get(
+ IsA(http.HttpRequest),
+ rack.id).\
+ AndReturn(rack)
+ api.tuskar.Rack.list(
+ IsA(http.request.HttpRequest)).AndReturn(
+ self.tuskar_racks.list())
+ api.tuskar.Rack.update(IsA(http.HttpRequest), rack.id, data)
+ api.tuskar.ResourceClass.list(
+ IsA(http.request.HttpRequest)).AndReturn(
+ self.tuskar_resource_classes.list())
+
self.mox.ReplayAll()
url = reverse('horizon:infrastructure:resource_management:' +
- 'racks:edit', args=[1])
+ 'racks:edit', args=[rack.id])
response = self.client.post(url, data)
self.assertNoFormErrors(response)
self.assertMessageCount(success=1)
self.assertRedirectsNoFollow(response, self.index_page)
- @test.create_stubs({api.tuskar.Rack: ('delete',)})
+ @test.create_stubs({api.tuskar.Rack: ('delete', 'list')})
def test_delete_rack(self):
rack_id = u'1'
api.tuskar.Rack.delete(IsA(http.request.HttpRequest), rack_id) \
.AndReturn(None)
+ api.tuskar.Rack.list(
+ IsA(http.request.HttpRequest)).AndReturn(
+ self.tuskar_racks.list())
+
self.mox.ReplayAll()
data = {'action': 'racks__delete__%s' % rack_id}
url = reverse('horizon:infrastructure:resource_management:index')
diff --git a/openstack_dashboard/dashboards/infrastructure/resource_management/racks/views.py b/openstack_dashboard/dashboards/infrastructure/resource_management/racks/views.py
index 2cccd98b..d1bdafc3 100644
--- a/openstack_dashboard/dashboards/infrastructure/resource_management/racks/views.py
+++ b/openstack_dashboard/dashboards/infrastructure/resource_management/racks/views.py
@@ -66,9 +66,8 @@ class EditView(workflows.WorkflowView):
workflow_class = EditRack
def get_initial(self):
- obj = api.tuskar.Rack.get(None,
- rack_id=self.kwargs['rack_id'])
- mac_str = "\n".join([x.mac_address for x in obj.nodes])
+ obj = api.tuskar.Rack.get(self.request, self.kwargs['rack_id'])
+ mac_str = "\n".join([x.mac_address for x in obj.list_nodes])
return {'name': obj.name, 'resource_class_id': obj.resource_class_id,
'location': obj.location, 'subnet': obj.subnet,
'node_macs': mac_str, 'rack_id': self.kwargs['rack_id']}
diff --git a/openstack_dashboard/dashboards/infrastructure/resource_management/racks/workflows.py b/openstack_dashboard/dashboards/infrastructure/resource_management/racks/workflows.py
index 1fceb7f1..f4d0f7eb 100644
--- a/openstack_dashboard/dashboards/infrastructure/resource_management/racks/workflows.py
+++ b/openstack_dashboard/dashboards/infrastructure/resource_management/racks/workflows.py
@@ -169,8 +169,8 @@ class EditRack(CreateRack):
def handle(self, request, data):
try:
rack_id = self.context['rack_id']
- rack = api.tuskar.Rack.update(rack_id, data)
+ rack = api.tuskar.Rack.update(request, rack_id, data)
return True
except:
- exceptions.handle(request, _("Unable to create rack."))
+ exceptions.handle(request, _("Unable to edit rack."))
diff --git a/openstack_dashboard/dashboards/infrastructure/resource_management/resource_classes/tabs.py b/openstack_dashboard/dashboards/infrastructure/resource_management/resource_classes/tabs.py
index 0ab53376..650d7761 100644
--- a/openstack_dashboard/dashboards/infrastructure/resource_management/resource_classes/tabs.py
+++ b/openstack_dashboard/dashboards/infrastructure/resource_management/resource_classes/tabs.py
@@ -42,7 +42,7 @@ class RacksTab(tabs.TableTab):
def get_racks_data(self):
try:
resource_class = self.tab_group.kwargs['resource_class']
- racks = resource_class.racks
+ racks = resource_class.list_racks
except:
racks = []
exceptions.handle(self.tab_group.request,
@@ -60,7 +60,7 @@ class FlavorsTab(tabs.TableTab):
def get_flavors_data(self):
try:
resource_class = self.tab_group.kwargs['resource_class']
- racks = resource_class.flavors
+ racks = resource_class.list_flavors
except:
racks = []
exceptions.handle(self.tab_group.request,
diff --git a/openstack_dashboard/dashboards/infrastructure/resource_management/resource_classes/tests.py b/openstack_dashboard/dashboards/infrastructure/resource_management/resource_classes/tests.py
index c50ff569..8cf0ebab 100644
--- a/openstack_dashboard/dashboards/infrastructure/resource_management/resource_classes/tests.py
+++ b/openstack_dashboard/dashboards/infrastructure/resource_management/resource_classes/tests.py
@@ -42,10 +42,8 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
self.assertEqual(res.status_code, 200)
@test.create_stubs({
- api.tuskar.ResourceClass: ('create', 'set_flavors',
- 'set_racks'),
- api.tuskar.Flavor: ('list',),
- api.tuskar.Rack: ('list',)
+ api.tuskar.ResourceClass: ('list', 'create',
+ 'set_flavors', 'set_racks'),
})
def test_create_resource_class_post(self):
new_resource_class = self.tuskar_resource_classes.first()
@@ -55,6 +53,9 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
add_max_vms = {}
add_racks_ids = []
+ api.tuskar.ResourceClass.list(
+ IsA(http.request.HttpRequest)).AndReturn(
+ self.tuskar_resource_classes.list())
api.tuskar.ResourceClass.\
create(IsA(http.HttpRequest), name=new_unique_name,
service_type=new_resource_class.service_type).\
@@ -76,7 +77,7 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
("%s?tab=resource_management_tabs__resource_classes_tab" %
reverse("horizon:infrastructure:resource_management:index")))
- @test.create_stubs({api.tuskar.ResourceClass: ('get',)})
+ @test.create_stubs({api.tuskar.ResourceClass: ('get', 'racks_ids')})
def test_edit_resource_class_get(self):
resource_class = self.tuskar_resource_classes.first()
all_flavors = []
@@ -85,6 +86,7 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
api.tuskar.ResourceClass.\
get(IsA(http.HttpRequest), resource_class.id).MultipleTimes().\
AndReturn(resource_class)
+
self.mox.ReplayAll()
# FIXME I should probably track the racks and flavors methods
@@ -101,7 +103,7 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
self.assertEqual(res.status_code, 200)
@test.create_stubs({
- api.tuskar.ResourceClass: ('update', 'set_racks',
+ api.tuskar.ResourceClass: ('get', 'list', 'update', 'set_racks',
'set_flavors')
})
def test_edit_resource_class_post(self):
@@ -111,6 +113,13 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
add_max_vms = {}
add_racks_ids = []
+ api.tuskar.ResourceClass.get(
+ IsA(http.HttpRequest),
+ resource_class.id).\
+ AndReturn(resource_class)
+ api.tuskar.ResourceClass.list(
+ IsA(http.request.HttpRequest)).AndReturn(
+ self.tuskar_resource_classes.list())
api.tuskar.ResourceClass.\
update(IsA(http.HttpRequest), resource_class.id,
name=resource_class.name,
@@ -156,7 +165,7 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
res, reverse('horizon:infrastructure:resource_management:index'))
@test.create_stubs({
- api.tuskar.ResourceClass: ('get', 'flavors', 'racks')
+ api.tuskar.ResourceClass: ('get', 'list_flavors', 'list_racks')
})
def test_detail_get(self):
resource_class = self.tuskar_resource_classes.first()
@@ -169,8 +178,8 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
MultipleTimes().AndReturn(resource_class)
self.mox.ReplayAll()
- api.tuskar.ResourceClass.flavors = flavors
- api.tuskar.ResourceClass.racks = racks
+ api.tuskar.ResourceClass.list_flavors = flavors
+ api.tuskar.ResourceClass.list_racks = racks
url = reverse('horizon:infrastructure:resource_management:'
'resource_classes:detail', args=[resource_class.id])
@@ -183,7 +192,7 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
self.assertTemplateUsed(res,
'infrastructure/resource_management/resource_classes/detail.html')
- @test.create_stubs({api.tuskar.ResourceClass: ('get',)})
+ @test.create_stubs({api.tuskar.ResourceClass: ('get', 'racks_ids')})
def test_detail_edit_racks_get(self):
resource_class = self.tuskar_resource_classes.first()
all_flavors = []
@@ -208,7 +217,7 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
self.assertEqual(res.status_code, 200)
@test.create_stubs({
- api.tuskar.ResourceClass: ('update', 'set_racks',
+ api.tuskar.ResourceClass: ('get', 'list', 'update', 'set_racks',
'set_flavors')
})
def test_detail_edit_racks_post(self):
@@ -218,6 +227,13 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
add_max_vms = {}
add_racks_ids = []
+ api.tuskar.ResourceClass.get(
+ IsA(http.HttpRequest),
+ resource_class.id).\
+ AndReturn(resource_class)
+ api.tuskar.ResourceClass.list(
+ IsA(http.request.HttpRequest)).AndReturn(
+ self.tuskar_resource_classes.list())
api.tuskar.ResourceClass.\
update(IsA(http.HttpRequest), resource_class.id,
name=resource_class.name,
@@ -245,7 +261,7 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
reverse(detail_url, args=(resource_class.id,)))
self.assertRedirectsNoFollow(res, redirect_url)
- @test.create_stubs({api.tuskar.ResourceClass: ('get',)})
+ @test.create_stubs({api.tuskar.ResourceClass: ('get', 'racks_ids')})
def test_detail_edit_flavors_get(self):
resource_class = self.tuskar_resource_classes.first()
all_flavors = []
@@ -270,7 +286,7 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
self.assertEqual(res.status_code, 200)
@test.create_stubs({
- api.tuskar.ResourceClass: ('update', 'set_racks',
+ api.tuskar.ResourceClass: ('get', 'list', 'update', 'set_racks',
'set_flavors')
})
def test_detail_edit_flavors_post(self):
@@ -280,6 +296,13 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
add_max_vms = {}
add_racks_ids = []
+ api.tuskar.ResourceClass.get(
+ IsA(http.HttpRequest),
+ resource_class.id).\
+ AndReturn(resource_class)
+ api.tuskar.ResourceClass.list(
+ IsA(http.request.HttpRequest)).AndReturn(
+ self.tuskar_resource_classes.list())
api.tuskar.ResourceClass.\
update(IsA(http.HttpRequest), resource_class.id,
name=resource_class.name,
diff --git a/openstack_dashboard/dashboards/infrastructure/resource_management/tests.py b/openstack_dashboard/dashboards/infrastructure/resource_management/tests.py
index 8fd65ae6..a5ed9455 100644
--- a/openstack_dashboard/dashboards/infrastructure/resource_management/tests.py
+++ b/openstack_dashboard/dashboards/infrastructure/resource_management/tests.py
@@ -30,7 +30,7 @@ class ResourceManagementTests(test.BaseAdminViewTests):
@test.create_stubs({
api.tuskar.ResourceClass: (
'list',
- 'racks',
+ 'list_racks',
'nodes'),
api.tuskar.Flavor: (
'list',),
@@ -49,7 +49,7 @@ class ResourceManagementTests(test.BaseAdminViewTests):
racks = []
api.tuskar.ResourceClass.nodes = nodes
- api.tuskar.ResourceClass.racks = racks
+ api.tuskar.ResourceClass.list_racks = racks
api.tuskar.ResourceClass.list(
IsA(http.HttpRequest)).\
diff --git a/openstack_dashboard/local/local_settings.py.example b/openstack_dashboard/local/local_settings.py.example
index 4494b695..f0a2f142 100644
--- a/openstack_dashboard/local/local_settings.py.example
+++ b/openstack_dashboard/local/local_settings.py.example
@@ -352,3 +352,7 @@ SECURITY_GROUP_RULES = {
'to_port': '3389',
},
}
+
+# FIXME: this will eventually be unneeded, as it will be retrieved from Keystone
+#TUSKAR_ENDPOINT_URL = "http://127.0.0.1:6385"
+
diff --git a/openstack_dashboard/test/api_tests/tuskar_tests.py b/openstack_dashboard/test/api_tests/tuskar_tests.py
index 6fd9fd8e..d3bf9614 100644
--- a/openstack_dashboard/test/api_tests/tuskar_tests.py
+++ b/openstack_dashboard/test/api_tests/tuskar_tests.py
@@ -30,20 +30,33 @@ import openstack_dashboard.dashboards.infrastructure.models as dummymodels
class TuskarApiTests(test.APITestCase):
def setUp(self):
super(TuskarApiTests, self).setUp()
+ # FIXME: I'm not sure this is sustainable
# 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.tuskar.ResourceClass.list(self.request)
- self.assertEquals(3, len(rc_list))
- for rc in rc_list:
+ rcs = self.tuskar_resource_classes.list()
+
+ tuskarclient = self.stub_tuskarclient()
+ tuskarclient.resource_classes = self.mox.CreateMockAnything()
+ tuskarclient.resource_classes.list().AndReturn(rcs)
+ self.mox.ReplayAll()
+
+ ret_val = api.tuskar.ResourceClass.list(self.request)
+ for rc in ret_val:
self.assertIsInstance(rc, api.tuskar.ResourceClass)
def test_resource_class_get(self):
- rc = api.tuskar.ResourceClass.get(self.request, self.rclass1.id)
- self.assertIsInstance(rc, api.tuskar.ResourceClass)
- self.assertEquals(rc.name, self.rclass1.name)
+ rc = self.tuskar_resource_classes.first()
+
+ tuskarclient = self.stub_tuskarclient()
+ tuskarclient.resource_classes = self.mox.CreateMockAnything()
+ tuskarclient.resource_classes.get(rc.id).AndReturn(rc)
+ self.mox.ReplayAll()
+
+ ret_val = api.tuskar.ResourceClass.get(self.request, rc.id)
+ self.assertIsInstance(ret_val, api.tuskar.ResourceClass)
def test_resource_class_flavor_counts(self):
rc = api.tuskar.ResourceClass.get(self.request, self.rclass1.id)
diff --git a/openstack_dashboard/test/helpers.py b/openstack_dashboard/test/helpers.py
index 79d201fd..1a6ad870 100644
--- a/openstack_dashboard/test/helpers.py
+++ b/openstack_dashboard/test/helpers.py
@@ -37,6 +37,7 @@ from keystoneclient.v2_0 import client as keystone_client
from neutronclient.v2_0 import client as neutron_client
from novaclient.v1_1 import client as nova_client
from swiftclient import client as swift_client
+from tuskarclient.v1 import client as tuskar_client
import httplib2
import mox
@@ -261,6 +262,7 @@ class APITestCase(TestCase):
self._original_neutronclient = api.neutron.neutronclient
self._original_cinderclient = api.cinder.cinderclient
self._original_heatclient = api.heat.heatclient
+ self._original_tuskarclient = api.tuskar.tuskarclient
# Replace the clients with our stubs.
api.glance.glanceclient = lambda request: self.stub_glanceclient()
@@ -269,6 +271,7 @@ class APITestCase(TestCase):
api.neutron.neutronclient = lambda request: self.stub_neutronclient()
api.cinder.cinderclient = lambda request: self.stub_cinderclient()
api.heat.heatclient = lambda request: self.stub_heatclient()
+ api.tuskar.tuskarclient = lambda request: self.stub_tuskarclient()
def tearDown(self):
super(APITestCase, self).tearDown()
@@ -278,6 +281,7 @@ class APITestCase(TestCase):
api.neutron.neutronclient = self._original_neutronclient
api.cinder.cinderclient = self._original_cinderclient
api.heat.heatclient = self._original_heatclient
+ api.tuskar.tuskarclient = self._original_tuskarclient
def stub_novaclient(self):
if not hasattr(self, "novaclient"):
@@ -335,6 +339,12 @@ class APITestCase(TestCase):
self.heatclient = self.mox.CreateMock(heat_client.Client)
return self.heatclient
+ def stub_tuskarclient(self):
+ if not hasattr(self, "tuskarclient"):
+ self.mox.StubOutWithMock(tuskar_client, 'Client')
+ self.tuskarclient = self.mox.CreateMock(tuskar_client.Client)
+ return self.tuskarclient
+
@unittest.skipUnless(os.environ.get('WITH_SELENIUM', False),
"The WITH_SELENIUM env variable is not set.")
diff --git a/openstack_dashboard/test/settings.py b/openstack_dashboard/test/settings.py
index 1ccd920a..3878d9d4 100644
--- a/openstack_dashboard/test/settings.py
+++ b/openstack_dashboard/test/settings.py
@@ -122,3 +122,7 @@ NOSE_ARGS = ['--nocapture',
'--cover-package=openstack_dashboard',
'--cover-inclusive',
'--all-modules']
+
+# FIXME: this will eventually be unneeded when the parameter is removed
+# from local settings and api/tuskar.py
+TUSKAR_ENDPOINT_URL = "http://127.0.0.1:6385"
diff --git a/requirements.txt b/requirements.txt
index b5ef7e67..66f18471 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -20,3 +20,5 @@ pytz>=2010h
# Horizon Utility Requirements
# for SECURE_KEY generation
lockfile>=0.8
+
+-e git://github.com/tuskar/python-tuskarclient.git#egg=python-tuskarclient