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
This commit is contained in:
parent
242cc3ff31
commit
4e2aebdd3b
@ -17,14 +17,25 @@ import logging
|
|||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from random import randint
|
from random import randint
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
from django.db.models import Sum, Max
|
from django.db.models import Sum, Max
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from tuskarclient.v1 import client as tuskar_client
|
||||||
|
|
||||||
from openstack_dashboard.api import base
|
from openstack_dashboard.api import base
|
||||||
import openstack_dashboard.dashboards.infrastructure.models as dummymodels
|
import openstack_dashboard.dashboards.infrastructure.models as dummymodels
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
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):
|
class StringIdAPIResourceWrapper(base.APIResourceWrapper):
|
||||||
@ -207,27 +218,64 @@ class Rack(StringIdAPIResourceWrapper):
|
|||||||
"""Wrapper for the Rack object returned by the
|
"""Wrapper for the Rack object returned by the
|
||||||
dummy model.
|
dummy model.
|
||||||
"""
|
"""
|
||||||
_attrs = ['name', 'resource_class_id', 'location', 'subnet']
|
_attrs = ['id', 'name', 'location', 'subnet', 'nodes']
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(cls, request, name, resource_class_id, location, subnet):
|
def create(cls, request, name, resource_class_id, location, subnet):
|
||||||
rack = dummymodels.Rack(name=name,
|
## FIXME: Where is the location attribute?? Also, set nodes
|
||||||
resource_class_id=resource_class_id,
|
## here
|
||||||
location=location, subnet=subnet)
|
rack = tuskarclient(request).racks.create(
|
||||||
rack.save()
|
name=name,
|
||||||
return rack
|
#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
|
@classmethod
|
||||||
def list(cls, request, only_free_racks=False):
|
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:
|
if only_free_racks:
|
||||||
return [cls(r) for r in dummymodels.Rack.objects.all() if (
|
return [Rack(r) for r in
|
||||||
r.resource_class is None)]
|
tuskarclient(request).racks.list()]
|
||||||
else:
|
else:
|
||||||
return [cls(r) for r in dummymodels.Rack.objects.all()]
|
return [Rack(r) for r in
|
||||||
|
tuskarclient(request).racks.list()]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get(cls, request, rack_id):
|
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
|
@property
|
||||||
def capacities(self):
|
def capacities(self):
|
||||||
@ -330,16 +378,19 @@ class Rack(StringIdAPIResourceWrapper):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def delete(cls, request, rack_id):
|
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
|
@property
|
||||||
def nodes(self):
|
def list_nodes(self):
|
||||||
if not hasattr(self, '_nodes'):
|
return []
|
||||||
self._nodes = [Node(h) for h in self._apiresource.node_set.all()]
|
#if not hasattr(self, '_nodes'):
|
||||||
return self._nodes
|
# self._nodes = [Node(h) for h in self._apiresource.node_set.all()]
|
||||||
|
#return self._nodes
|
||||||
|
|
||||||
def nodes_count(self):
|
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
|
# 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
|
# 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
|
self._resource_class = self._apiresource.resource_class
|
||||||
return self._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
|
# ResourceClass
|
||||||
@ -387,44 +428,37 @@ class ResourceClass(StringIdAPIResourceWrapper):
|
|||||||
"""Wrapper for the ResourceClass object returned by the
|
"""Wrapper for the ResourceClass object returned by the
|
||||||
dummy model.
|
dummy model.
|
||||||
"""
|
"""
|
||||||
_attrs = ['name', 'service_type', 'status']
|
_attrs = ['name', 'service_type', 'racks']
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
# ResourceClass Class methods
|
# ResourceClass Class methods
|
||||||
##########################################################################
|
##########################################################################
|
||||||
@classmethod
|
@classmethod
|
||||||
def get(cls, request, resource_class_id):
|
def get(cls, request, resource_class_id):
|
||||||
obj = cls(dummymodels.ResourceClass.objects.get(
|
rc = cls(tuskarclient(request).resource_classes.get(resource_class_id))
|
||||||
id=resource_class_id))
|
rc.set_request(request)
|
||||||
obj.set_request(request)
|
return rc
|
||||||
return obj
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(self, request, name, service_type):
|
def create(self, request, name, service_type):
|
||||||
rc = dummymodels.ResourceClass(
|
return ResourceClass(
|
||||||
|
tuskarclient(request).resource_classes.create(
|
||||||
name=name,
|
name=name,
|
||||||
service_type=service_type)
|
service_type=service_type))
|
||||||
|
|
||||||
rc.save()
|
|
||||||
return ResourceClass(rc)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def list(self, request):
|
def list(self, request):
|
||||||
return [
|
return [ResourceClass(rc) for rc in
|
||||||
ResourceClass(rc) for rc in (
|
tuskarclient(request).resource_classes.list()]
|
||||||
dummymodels.ResourceClass.objects.all())]
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def update(cls, request, resource_class_id, **kwargs):
|
def update(cls, request, resource_class_id, **kwargs):
|
||||||
rc = dummymodels.ResourceClass.objects.get(id=resource_class_id)
|
return cls(tuskarclient(request).resource_classes.update(
|
||||||
rc.name = kwargs['name']
|
resource_class_id, **kwargs))
|
||||||
rc.service_type = kwargs['service_type']
|
|
||||||
rc.save()
|
|
||||||
return cls(rc)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def delete(cls, request, resource_class_id):
|
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
|
# ResourceClass Properties
|
||||||
@ -437,12 +471,10 @@ class ResourceClass(StringIdAPIResourceWrapper):
|
|||||||
self.racks)]
|
self.racks)]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def racks(self):
|
def list_racks(self):
|
||||||
""" List of racks added to ResourceClass """
|
""" List of racks added to ResourceClass """
|
||||||
if not hasattr(self, '_racks'):
|
if not hasattr(self, '_racks'):
|
||||||
self._racks =\
|
self._racks = [Rack(r) for r in self.racks]
|
||||||
[Rack(r) for r in (
|
|
||||||
self._apiresource.rack_set.all())]
|
|
||||||
return self._racks
|
return self._racks
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -454,7 +486,7 @@ class ResourceClass(StringIdAPIResourceWrapper):
|
|||||||
[r for r in (
|
[r for r in (
|
||||||
Rack.list(self.request)) if (
|
Rack.list(self.request)) if (
|
||||||
r.resource_class_id is None or
|
r.resource_class_id is None or
|
||||||
r._apiresource.resource_class == self._apiresource)]
|
r.resource_class_id == self.id)]
|
||||||
return self._all_racks
|
return self._all_racks
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -465,47 +497,55 @@ class ResourceClass(StringIdAPIResourceWrapper):
|
|||||||
self._apiresource.resourceclassflavor_set.all())]
|
self._apiresource.resourceclassflavor_set.all())]
|
||||||
return self._resource_class_flavors
|
return self._resource_class_flavors
|
||||||
|
|
||||||
|
## FIXME: this isn't currently supported by the client library, so would
|
||||||
|
## have to be done through curl
|
||||||
@property
|
@property
|
||||||
def flavors_ids(self):
|
def flavors_ids(self):
|
||||||
""" List of unicode ids of flavors added to resource class """
|
""" List of unicode ids of flavors added to resource class """
|
||||||
return [
|
#return [
|
||||||
unicode(flavor.flavor.id) for flavor in (
|
# unicode(flavor.flavor.id) for flavor in (
|
||||||
self.resource_class_flavors)]
|
# self.resource_class_flavors)]
|
||||||
|
return []
|
||||||
|
|
||||||
|
## FIXME: this isn't currently supported by the client library, so would
|
||||||
|
## have to be done through curl
|
||||||
@property
|
@property
|
||||||
def flavors(self):
|
def list_flavors(self):
|
||||||
""" Joined relation table resourceclassflavor and flavor together """
|
""" Joined relation table resourceclassflavor and flavor together """
|
||||||
if not hasattr(self, '_flavors'):
|
#if not hasattr(self, '_flavors'):
|
||||||
added_flavors = self.resource_class_flavors
|
# added_flavors = self.resource_class_flavors
|
||||||
self._flavors = []
|
# self._flavors = []
|
||||||
for f in added_flavors:
|
# for f in added_flavors:
|
||||||
flavor_obj = Flavor.get(self.request, f.flavor.id)
|
# flavor_obj = Flavor.get(self.request, f.flavor.id)
|
||||||
flavor_obj.set_max_vms(f.max_vms)
|
# flavor_obj.set_max_vms(f.max_vms)
|
||||||
self._flavors.append(flavor_obj)
|
# self._flavors.append(flavor_obj)
|
||||||
|
#return self._flavors
|
||||||
return self._flavors
|
return []
|
||||||
|
|
||||||
|
## FIXME: this isn't currently supported by the client library, so would
|
||||||
|
## have to be done through curl
|
||||||
@property
|
@property
|
||||||
def all_flavors(self):
|
def all_flavors(self):
|
||||||
""" Joined relation table resourceclassflavor with all global flavors
|
""" Joined relation table resourceclassflavor with all global flavors
|
||||||
"""
|
"""
|
||||||
if not hasattr(self, '_all_flavors'):
|
#if not hasattr(self, '_all_flavors'):
|
||||||
all_flavors = Flavor.list(self.request)
|
# all_flavors = Flavor.list(self.request)
|
||||||
|
|
||||||
added_resourceclassflavors = \
|
# added_resourceclassflavors = \
|
||||||
self._apiresource.resourceclassflavor_set.all()
|
# self._apiresource.resourceclassflavor_set.all()
|
||||||
added_flavors = {}
|
# added_flavors = {}
|
||||||
for added_flavor in added_resourceclassflavors:
|
# for added_flavor in added_resourceclassflavors:
|
||||||
added_flavors[str(added_flavor.flavor_id)] = added_flavor
|
# added_flavors[str(added_flavor.flavor_id)] = added_flavor
|
||||||
|
|
||||||
self._all_flavors = []
|
# self._all_flavors = []
|
||||||
for f in all_flavors:
|
# for f in all_flavors:
|
||||||
added_flavor = added_flavors.get(f.id)
|
# added_flavor = added_flavors.get(f.id)
|
||||||
if added_flavor:
|
# if added_flavor:
|
||||||
f.set_max_vms(added_flavor.max_vms)
|
# f.set_max_vms(added_flavor.max_vms)
|
||||||
self._all_flavors.append(f)
|
# self._all_flavors.append(f)
|
||||||
|
|
||||||
return self._all_flavors
|
#return self._all_flavors
|
||||||
|
return []
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def nodes(self):
|
def nodes(self):
|
||||||
@ -626,35 +666,40 @@ class ResourceClass(StringIdAPIResourceWrapper):
|
|||||||
##########################################################################
|
##########################################################################
|
||||||
# ResourceClass Instance methods
|
# ResourceClass Instance methods
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
|
## FIXME: this will have to be done some other way
|
||||||
def set_flavors(self, request, flavors_ids, max_vms=None):
|
def set_flavors(self, request, flavors_ids, max_vms=None):
|
||||||
|
return
|
||||||
# simply delete all and create new flavors, that'is
|
# simply delete all and create new flavors, that'is
|
||||||
# how the horizon flavors work
|
# how the horizon flavors work
|
||||||
max_vms = max_vms or {}
|
#max_vms = max_vms or {}
|
||||||
|
|
||||||
for flavor_id in self.flavors_ids:
|
#for flavor_id in self.flavors_ids:
|
||||||
ResourceClassFlavor.delete(request,
|
# ResourceClassFlavor.delete(request,
|
||||||
self.id,
|
# self.id,
|
||||||
flavor_id)
|
# flavor_id)
|
||||||
|
|
||||||
for flavor_id in flavors_ids:
|
#for flavor_id in flavors_ids:
|
||||||
flavor = Flavor.get(request, flavor_id)
|
# flavor = Flavor.get(request, flavor_id)
|
||||||
ResourceClassFlavor.create(
|
# ResourceClassFlavor.create(
|
||||||
request,
|
# request,
|
||||||
max_vms=max_vms.get(flavor.id),
|
# max_vms=max_vms.get(flavor.id),
|
||||||
flavor=flavor._apiresource,
|
# flavor=flavor._apiresource,
|
||||||
resource_class=self._apiresource)
|
# resource_class=self._apiresource)
|
||||||
|
|
||||||
|
## FIXME: this will have to be done some other way
|
||||||
def set_racks(self, request, racks_ids):
|
def set_racks(self, request, racks_ids):
|
||||||
|
return
|
||||||
# simply delete all and create new racks
|
# simply delete all and create new racks
|
||||||
for rack_id in self.racks_ids:
|
#for rack_id in self.racks_ids:
|
||||||
rack = Rack.get(request, rack_id)
|
# rack = Rack.get(request, rack_id)
|
||||||
rack._apiresource.resource_class = None
|
# rack._apiresource.resource_class = None
|
||||||
rack._apiresource.save()
|
# rack._apiresource.save()
|
||||||
|
|
||||||
for rack_id in racks_ids:
|
#for rack_id in racks_ids:
|
||||||
rack = Rack.get(request, rack_id)
|
# rack = Rack.get(request, rack_id)
|
||||||
rack._apiresource.resource_class = self._apiresource
|
# rack._apiresource.resource_class = self._apiresource
|
||||||
rack._apiresource.save()
|
# rack._apiresource.save()
|
||||||
|
|
||||||
|
|
||||||
class Flavor(StringIdAPIResourceWrapper):
|
class Flavor(StringIdAPIResourceWrapper):
|
||||||
|
@ -40,7 +40,7 @@ class NodesTab(tabs.TableTab):
|
|||||||
def get_nodes_data(self):
|
def get_nodes_data(self):
|
||||||
try:
|
try:
|
||||||
rack = self.tab_group.kwargs['rack']
|
rack = self.tab_group.kwargs['rack']
|
||||||
nodes = rack.nodes
|
nodes = rack.list_nodes
|
||||||
except:
|
except:
|
||||||
nodes = []
|
nodes = []
|
||||||
exceptions.handle(self.tab_group.request,
|
exceptions.handle(self.tab_group.request,
|
||||||
|
@ -23,7 +23,14 @@ from django.core.files.uploadedfile import InMemoryUploadedFile
|
|||||||
class RackViewTests(test.BaseAdminViewTests):
|
class RackViewTests(test.BaseAdminViewTests):
|
||||||
index_page = reverse('horizon:infrastructure:resource_management:index')
|
index_page = reverse('horizon:infrastructure:resource_management:index')
|
||||||
|
|
||||||
|
@test.create_stubs({api.tuskar.ResourceClass: ('list',)})
|
||||||
def test_create_rack_get(self):
|
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:'
|
url = reverse('horizon:infrastructure:resource_management:'
|
||||||
'racks:create')
|
'racks:create')
|
||||||
rack = self.client.get(url)
|
rack = self.client.get(url)
|
||||||
@ -35,10 +42,18 @@ class RackViewTests(test.BaseAdminViewTests):
|
|||||||
# FIXME (mawagner) - After moving EditRack to use workflows, we need
|
# FIXME (mawagner) - After moving EditRack to use workflows, we need
|
||||||
# to circle back and fix these tests.
|
# 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):
|
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',
|
api.tuskar.Rack.create(IsA(http.request.HttpRequest), 'New Rack',
|
||||||
u'2', 'Tokyo', '1.2.3.4').AndReturn(None)
|
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()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
data = {'name': 'New Rack', 'resource_class_id': u'2',
|
data = {'name': 'New Rack', 'resource_class_id': u'2',
|
||||||
@ -48,35 +63,66 @@ class RackViewTests(test.BaseAdminViewTests):
|
|||||||
resp = self.client.post(url, data)
|
resp = self.client.post(url, data)
|
||||||
self.assertRedirectsNoFollow(resp, self.index_page)
|
self.assertRedirectsNoFollow(resp, self.index_page)
|
||||||
|
|
||||||
|
@test.create_stubs({api.tuskar.Rack: ('get',),
|
||||||
|
api.tuskar.ResourceClass: ('list',)})
|
||||||
def test_edit_rack_get(self):
|
def test_edit_rack_get(self):
|
||||||
url = reverse('horizon:infrastructure:resource_management:' +
|
rack = self.tuskar_racks.first()
|
||||||
'racks:edit', args=[1])
|
|
||||||
rack = self.client.get(url)
|
|
||||||
self.assertEqual(rack.status_code, 200)
|
|
||||||
self.assertTemplateUsed(rack,
|
|
||||||
'horizon/common/_workflow_base.html')
|
|
||||||
|
|
||||||
@test.create_stubs({api.tuskar.Rack: ('update',)})
|
api.tuskar.Rack.\
|
||||||
def test_edit_rack_post(self):
|
get(IsA(http.HttpRequest), rack.id).\
|
||||||
data = {'name': 'Updated Rack', 'resource_class_id': u'1',
|
AndReturn(rack)
|
||||||
'rack_id': u'1', 'location': 'New Location',
|
api.tuskar.ResourceClass.list(
|
||||||
'subnet': '127.10.10.0/24', 'node_macs': 'foo'}
|
IsA(http.request.HttpRequest)).AndReturn(
|
||||||
|
self.tuskar_resource_classes.list())
|
||||||
|
|
||||||
api.tuskar.Rack.update(u'1', data)
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
url = reverse('horizon:infrastructure:resource_management:' +
|
url = reverse('horizon:infrastructure:resource_management:' +
|
||||||
'racks:edit', args=[1])
|
'racks:edit', args=[1])
|
||||||
|
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: ('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.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=[rack.id])
|
||||||
response = self.client.post(url, data)
|
response = self.client.post(url, data)
|
||||||
self.assertNoFormErrors(response)
|
self.assertNoFormErrors(response)
|
||||||
self.assertMessageCount(success=1)
|
self.assertMessageCount(success=1)
|
||||||
self.assertRedirectsNoFollow(response, self.index_page)
|
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):
|
def test_delete_rack(self):
|
||||||
rack_id = u'1'
|
rack_id = u'1'
|
||||||
api.tuskar.Rack.delete(IsA(http.request.HttpRequest), rack_id) \
|
api.tuskar.Rack.delete(IsA(http.request.HttpRequest), rack_id) \
|
||||||
.AndReturn(None)
|
.AndReturn(None)
|
||||||
|
api.tuskar.Rack.list(
|
||||||
|
IsA(http.request.HttpRequest)).AndReturn(
|
||||||
|
self.tuskar_racks.list())
|
||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
data = {'action': 'racks__delete__%s' % rack_id}
|
data = {'action': 'racks__delete__%s' % rack_id}
|
||||||
url = reverse('horizon:infrastructure:resource_management:index')
|
url = reverse('horizon:infrastructure:resource_management:index')
|
||||||
|
@ -66,9 +66,8 @@ class EditView(workflows.WorkflowView):
|
|||||||
workflow_class = EditRack
|
workflow_class = EditRack
|
||||||
|
|
||||||
def get_initial(self):
|
def get_initial(self):
|
||||||
obj = api.tuskar.Rack.get(None,
|
obj = api.tuskar.Rack.get(self.request, self.kwargs['rack_id'])
|
||||||
rack_id=self.kwargs['rack_id'])
|
mac_str = "\n".join([x.mac_address for x in obj.list_nodes])
|
||||||
mac_str = "\n".join([x.mac_address for x in obj.nodes])
|
|
||||||
return {'name': obj.name, 'resource_class_id': obj.resource_class_id,
|
return {'name': obj.name, 'resource_class_id': obj.resource_class_id,
|
||||||
'location': obj.location, 'subnet': obj.subnet,
|
'location': obj.location, 'subnet': obj.subnet,
|
||||||
'node_macs': mac_str, 'rack_id': self.kwargs['rack_id']}
|
'node_macs': mac_str, 'rack_id': self.kwargs['rack_id']}
|
||||||
|
@ -169,8 +169,8 @@ class EditRack(CreateRack):
|
|||||||
def handle(self, request, data):
|
def handle(self, request, data):
|
||||||
try:
|
try:
|
||||||
rack_id = self.context['rack_id']
|
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
|
return True
|
||||||
except:
|
except:
|
||||||
exceptions.handle(request, _("Unable to create rack."))
|
exceptions.handle(request, _("Unable to edit rack."))
|
||||||
|
@ -42,7 +42,7 @@ class RacksTab(tabs.TableTab):
|
|||||||
def get_racks_data(self):
|
def get_racks_data(self):
|
||||||
try:
|
try:
|
||||||
resource_class = self.tab_group.kwargs['resource_class']
|
resource_class = self.tab_group.kwargs['resource_class']
|
||||||
racks = resource_class.racks
|
racks = resource_class.list_racks
|
||||||
except:
|
except:
|
||||||
racks = []
|
racks = []
|
||||||
exceptions.handle(self.tab_group.request,
|
exceptions.handle(self.tab_group.request,
|
||||||
@ -60,7 +60,7 @@ class FlavorsTab(tabs.TableTab):
|
|||||||
def get_flavors_data(self):
|
def get_flavors_data(self):
|
||||||
try:
|
try:
|
||||||
resource_class = self.tab_group.kwargs['resource_class']
|
resource_class = self.tab_group.kwargs['resource_class']
|
||||||
racks = resource_class.flavors
|
racks = resource_class.list_flavors
|
||||||
except:
|
except:
|
||||||
racks = []
|
racks = []
|
||||||
exceptions.handle(self.tab_group.request,
|
exceptions.handle(self.tab_group.request,
|
||||||
|
@ -42,10 +42,8 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
|
|||||||
self.assertEqual(res.status_code, 200)
|
self.assertEqual(res.status_code, 200)
|
||||||
|
|
||||||
@test.create_stubs({
|
@test.create_stubs({
|
||||||
api.tuskar.ResourceClass: ('create', 'set_flavors',
|
api.tuskar.ResourceClass: ('list', 'create',
|
||||||
'set_racks'),
|
'set_flavors', 'set_racks'),
|
||||||
api.tuskar.Flavor: ('list',),
|
|
||||||
api.tuskar.Rack: ('list',)
|
|
||||||
})
|
})
|
||||||
def test_create_resource_class_post(self):
|
def test_create_resource_class_post(self):
|
||||||
new_resource_class = self.tuskar_resource_classes.first()
|
new_resource_class = self.tuskar_resource_classes.first()
|
||||||
@ -55,6 +53,9 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
|
|||||||
add_max_vms = {}
|
add_max_vms = {}
|
||||||
add_racks_ids = []
|
add_racks_ids = []
|
||||||
|
|
||||||
|
api.tuskar.ResourceClass.list(
|
||||||
|
IsA(http.request.HttpRequest)).AndReturn(
|
||||||
|
self.tuskar_resource_classes.list())
|
||||||
api.tuskar.ResourceClass.\
|
api.tuskar.ResourceClass.\
|
||||||
create(IsA(http.HttpRequest), name=new_unique_name,
|
create(IsA(http.HttpRequest), name=new_unique_name,
|
||||||
service_type=new_resource_class.service_type).\
|
service_type=new_resource_class.service_type).\
|
||||||
@ -76,7 +77,7 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
|
|||||||
("%s?tab=resource_management_tabs__resource_classes_tab" %
|
("%s?tab=resource_management_tabs__resource_classes_tab" %
|
||||||
reverse("horizon:infrastructure:resource_management:index")))
|
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):
|
def test_edit_resource_class_get(self):
|
||||||
resource_class = self.tuskar_resource_classes.first()
|
resource_class = self.tuskar_resource_classes.first()
|
||||||
all_flavors = []
|
all_flavors = []
|
||||||
@ -85,6 +86,7 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
|
|||||||
api.tuskar.ResourceClass.\
|
api.tuskar.ResourceClass.\
|
||||||
get(IsA(http.HttpRequest), resource_class.id).MultipleTimes().\
|
get(IsA(http.HttpRequest), resource_class.id).MultipleTimes().\
|
||||||
AndReturn(resource_class)
|
AndReturn(resource_class)
|
||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
# FIXME I should probably track the racks and flavors methods
|
# FIXME I should probably track the racks and flavors methods
|
||||||
@ -101,7 +103,7 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
|
|||||||
self.assertEqual(res.status_code, 200)
|
self.assertEqual(res.status_code, 200)
|
||||||
|
|
||||||
@test.create_stubs({
|
@test.create_stubs({
|
||||||
api.tuskar.ResourceClass: ('update', 'set_racks',
|
api.tuskar.ResourceClass: ('get', 'list', 'update', 'set_racks',
|
||||||
'set_flavors')
|
'set_flavors')
|
||||||
})
|
})
|
||||||
def test_edit_resource_class_post(self):
|
def test_edit_resource_class_post(self):
|
||||||
@ -111,6 +113,13 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
|
|||||||
add_max_vms = {}
|
add_max_vms = {}
|
||||||
add_racks_ids = []
|
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.\
|
api.tuskar.ResourceClass.\
|
||||||
update(IsA(http.HttpRequest), resource_class.id,
|
update(IsA(http.HttpRequest), resource_class.id,
|
||||||
name=resource_class.name,
|
name=resource_class.name,
|
||||||
@ -156,7 +165,7 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
|
|||||||
res, reverse('horizon:infrastructure:resource_management:index'))
|
res, reverse('horizon:infrastructure:resource_management:index'))
|
||||||
|
|
||||||
@test.create_stubs({
|
@test.create_stubs({
|
||||||
api.tuskar.ResourceClass: ('get', 'flavors', 'racks')
|
api.tuskar.ResourceClass: ('get', 'list_flavors', 'list_racks')
|
||||||
})
|
})
|
||||||
def test_detail_get(self):
|
def test_detail_get(self):
|
||||||
resource_class = self.tuskar_resource_classes.first()
|
resource_class = self.tuskar_resource_classes.first()
|
||||||
@ -169,8 +178,8 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
|
|||||||
MultipleTimes().AndReturn(resource_class)
|
MultipleTimes().AndReturn(resource_class)
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
api.tuskar.ResourceClass.flavors = flavors
|
api.tuskar.ResourceClass.list_flavors = flavors
|
||||||
api.tuskar.ResourceClass.racks = racks
|
api.tuskar.ResourceClass.list_racks = racks
|
||||||
|
|
||||||
url = reverse('horizon:infrastructure:resource_management:'
|
url = reverse('horizon:infrastructure:resource_management:'
|
||||||
'resource_classes:detail', args=[resource_class.id])
|
'resource_classes:detail', args=[resource_class.id])
|
||||||
@ -183,7 +192,7 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
|
|||||||
self.assertTemplateUsed(res,
|
self.assertTemplateUsed(res,
|
||||||
'infrastructure/resource_management/resource_classes/detail.html')
|
'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):
|
def test_detail_edit_racks_get(self):
|
||||||
resource_class = self.tuskar_resource_classes.first()
|
resource_class = self.tuskar_resource_classes.first()
|
||||||
all_flavors = []
|
all_flavors = []
|
||||||
@ -208,7 +217,7 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
|
|||||||
self.assertEqual(res.status_code, 200)
|
self.assertEqual(res.status_code, 200)
|
||||||
|
|
||||||
@test.create_stubs({
|
@test.create_stubs({
|
||||||
api.tuskar.ResourceClass: ('update', 'set_racks',
|
api.tuskar.ResourceClass: ('get', 'list', 'update', 'set_racks',
|
||||||
'set_flavors')
|
'set_flavors')
|
||||||
})
|
})
|
||||||
def test_detail_edit_racks_post(self):
|
def test_detail_edit_racks_post(self):
|
||||||
@ -218,6 +227,13 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
|
|||||||
add_max_vms = {}
|
add_max_vms = {}
|
||||||
add_racks_ids = []
|
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.\
|
api.tuskar.ResourceClass.\
|
||||||
update(IsA(http.HttpRequest), resource_class.id,
|
update(IsA(http.HttpRequest), resource_class.id,
|
||||||
name=resource_class.name,
|
name=resource_class.name,
|
||||||
@ -245,7 +261,7 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
|
|||||||
reverse(detail_url, args=(resource_class.id,)))
|
reverse(detail_url, args=(resource_class.id,)))
|
||||||
self.assertRedirectsNoFollow(res, redirect_url)
|
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):
|
def test_detail_edit_flavors_get(self):
|
||||||
resource_class = self.tuskar_resource_classes.first()
|
resource_class = self.tuskar_resource_classes.first()
|
||||||
all_flavors = []
|
all_flavors = []
|
||||||
@ -270,7 +286,7 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
|
|||||||
self.assertEqual(res.status_code, 200)
|
self.assertEqual(res.status_code, 200)
|
||||||
|
|
||||||
@test.create_stubs({
|
@test.create_stubs({
|
||||||
api.tuskar.ResourceClass: ('update', 'set_racks',
|
api.tuskar.ResourceClass: ('get', 'list', 'update', 'set_racks',
|
||||||
'set_flavors')
|
'set_flavors')
|
||||||
})
|
})
|
||||||
def test_detail_edit_flavors_post(self):
|
def test_detail_edit_flavors_post(self):
|
||||||
@ -280,6 +296,13 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
|
|||||||
add_max_vms = {}
|
add_max_vms = {}
|
||||||
add_racks_ids = []
|
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.\
|
api.tuskar.ResourceClass.\
|
||||||
update(IsA(http.HttpRequest), resource_class.id,
|
update(IsA(http.HttpRequest), resource_class.id,
|
||||||
name=resource_class.name,
|
name=resource_class.name,
|
||||||
|
@ -30,7 +30,7 @@ class ResourceManagementTests(test.BaseAdminViewTests):
|
|||||||
@test.create_stubs({
|
@test.create_stubs({
|
||||||
api.tuskar.ResourceClass: (
|
api.tuskar.ResourceClass: (
|
||||||
'list',
|
'list',
|
||||||
'racks',
|
'list_racks',
|
||||||
'nodes'),
|
'nodes'),
|
||||||
api.tuskar.Flavor: (
|
api.tuskar.Flavor: (
|
||||||
'list',),
|
'list',),
|
||||||
@ -49,7 +49,7 @@ class ResourceManagementTests(test.BaseAdminViewTests):
|
|||||||
racks = []
|
racks = []
|
||||||
|
|
||||||
api.tuskar.ResourceClass.nodes = nodes
|
api.tuskar.ResourceClass.nodes = nodes
|
||||||
api.tuskar.ResourceClass.racks = racks
|
api.tuskar.ResourceClass.list_racks = racks
|
||||||
|
|
||||||
api.tuskar.ResourceClass.list(
|
api.tuskar.ResourceClass.list(
|
||||||
IsA(http.HttpRequest)).\
|
IsA(http.HttpRequest)).\
|
||||||
|
@ -352,3 +352,7 @@ SECURITY_GROUP_RULES = {
|
|||||||
'to_port': '3389',
|
'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"
|
||||||
|
|
||||||
|
@ -30,20 +30,33 @@ import openstack_dashboard.dashboards.infrastructure.models as dummymodels
|
|||||||
class TuskarApiTests(test.APITestCase):
|
class TuskarApiTests(test.APITestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TuskarApiTests, self).setUp()
|
super(TuskarApiTests, self).setUp()
|
||||||
|
# FIXME: I'm not sure this is sustainable
|
||||||
# dummy data are seeded from fixtures
|
# dummy data are seeded from fixtures
|
||||||
self.rclass1 = dummymodels.ResourceClass.objects.get(name='rclass1')
|
self.rclass1 = dummymodels.ResourceClass.objects.get(name='rclass1')
|
||||||
self.flavor1 = dummymodels.Flavor.objects.get(name='flavor1')
|
self.flavor1 = dummymodels.Flavor.objects.get(name='flavor1')
|
||||||
|
|
||||||
def test_resource_class_list(self):
|
def test_resource_class_list(self):
|
||||||
rc_list = api.tuskar.ResourceClass.list(self.request)
|
rcs = self.tuskar_resource_classes.list()
|
||||||
self.assertEquals(3, len(rc_list))
|
|
||||||
for rc in rc_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)
|
self.assertIsInstance(rc, api.tuskar.ResourceClass)
|
||||||
|
|
||||||
def test_resource_class_get(self):
|
def test_resource_class_get(self):
|
||||||
rc = api.tuskar.ResourceClass.get(self.request, self.rclass1.id)
|
rc = self.tuskar_resource_classes.first()
|
||||||
self.assertIsInstance(rc, api.tuskar.ResourceClass)
|
|
||||||
self.assertEquals(rc.name, self.rclass1.name)
|
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):
|
def test_resource_class_flavor_counts(self):
|
||||||
rc = api.tuskar.ResourceClass.get(self.request, self.rclass1.id)
|
rc = api.tuskar.ResourceClass.get(self.request, self.rclass1.id)
|
||||||
|
@ -37,6 +37,7 @@ from keystoneclient.v2_0 import client as keystone_client
|
|||||||
from neutronclient.v2_0 import client as neutron_client
|
from neutronclient.v2_0 import client as neutron_client
|
||||||
from novaclient.v1_1 import client as nova_client
|
from novaclient.v1_1 import client as nova_client
|
||||||
from swiftclient import client as swift_client
|
from swiftclient import client as swift_client
|
||||||
|
from tuskarclient.v1 import client as tuskar_client
|
||||||
|
|
||||||
import httplib2
|
import httplib2
|
||||||
import mox
|
import mox
|
||||||
@ -261,6 +262,7 @@ class APITestCase(TestCase):
|
|||||||
self._original_neutronclient = api.neutron.neutronclient
|
self._original_neutronclient = api.neutron.neutronclient
|
||||||
self._original_cinderclient = api.cinder.cinderclient
|
self._original_cinderclient = api.cinder.cinderclient
|
||||||
self._original_heatclient = api.heat.heatclient
|
self._original_heatclient = api.heat.heatclient
|
||||||
|
self._original_tuskarclient = api.tuskar.tuskarclient
|
||||||
|
|
||||||
# Replace the clients with our stubs.
|
# Replace the clients with our stubs.
|
||||||
api.glance.glanceclient = lambda request: self.stub_glanceclient()
|
api.glance.glanceclient = lambda request: self.stub_glanceclient()
|
||||||
@ -269,6 +271,7 @@ class APITestCase(TestCase):
|
|||||||
api.neutron.neutronclient = lambda request: self.stub_neutronclient()
|
api.neutron.neutronclient = lambda request: self.stub_neutronclient()
|
||||||
api.cinder.cinderclient = lambda request: self.stub_cinderclient()
|
api.cinder.cinderclient = lambda request: self.stub_cinderclient()
|
||||||
api.heat.heatclient = lambda request: self.stub_heatclient()
|
api.heat.heatclient = lambda request: self.stub_heatclient()
|
||||||
|
api.tuskar.tuskarclient = lambda request: self.stub_tuskarclient()
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
super(APITestCase, self).tearDown()
|
super(APITestCase, self).tearDown()
|
||||||
@ -278,6 +281,7 @@ class APITestCase(TestCase):
|
|||||||
api.neutron.neutronclient = self._original_neutronclient
|
api.neutron.neutronclient = self._original_neutronclient
|
||||||
api.cinder.cinderclient = self._original_cinderclient
|
api.cinder.cinderclient = self._original_cinderclient
|
||||||
api.heat.heatclient = self._original_heatclient
|
api.heat.heatclient = self._original_heatclient
|
||||||
|
api.tuskar.tuskarclient = self._original_tuskarclient
|
||||||
|
|
||||||
def stub_novaclient(self):
|
def stub_novaclient(self):
|
||||||
if not hasattr(self, "novaclient"):
|
if not hasattr(self, "novaclient"):
|
||||||
@ -335,6 +339,12 @@ class APITestCase(TestCase):
|
|||||||
self.heatclient = self.mox.CreateMock(heat_client.Client)
|
self.heatclient = self.mox.CreateMock(heat_client.Client)
|
||||||
return self.heatclient
|
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),
|
@unittest.skipUnless(os.environ.get('WITH_SELENIUM', False),
|
||||||
"The WITH_SELENIUM env variable is not set.")
|
"The WITH_SELENIUM env variable is not set.")
|
||||||
|
@ -122,3 +122,7 @@ NOSE_ARGS = ['--nocapture',
|
|||||||
'--cover-package=openstack_dashboard',
|
'--cover-package=openstack_dashboard',
|
||||||
'--cover-inclusive',
|
'--cover-inclusive',
|
||||||
'--all-modules']
|
'--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"
|
||||||
|
@ -20,3 +20,5 @@ pytz>=2010h
|
|||||||
# Horizon Utility Requirements
|
# Horizon Utility Requirements
|
||||||
# for SECURE_KEY generation
|
# for SECURE_KEY generation
|
||||||
lockfile>=0.8
|
lockfile>=0.8
|
||||||
|
|
||||||
|
-e git://github.com/tuskar/python-tuskarclient.git#egg=python-tuskarclient
|
||||||
|
Loading…
x
Reference in New Issue
Block a user