Enable H302 check

H302 check was enabled in Horizon recently which allows importing modules only.
This patch fixes all import statements except for gettext where it makes more
sense to use _. In those cases the warnings are discarded by adding the # noqa
comment to the end of the line.

Fixes: bug #1218882

Change-Id: I745471bd372fac3724aa04cc08c512fb823cfbd0
This commit is contained in:
Imre Farkas 2013-08-28 13:53:13 +02:00
parent 484f06d4bf
commit ff77bcf778
48 changed files with 787 additions and 814 deletions

View File

@ -39,8 +39,7 @@ exclude = .venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,build,p
# F403 'from <smth> import *' used; unable to detect undefined names # F403 'from <smth> import *' used; unable to detect undefined names
# F999 syntax error in doctest # F999 syntax error in doctest
# H201 no 'except:' at least use 'except Exception:' # H201 no 'except:' at least use 'except Exception:'
# H302 import only modules.'from optparse import make_option' does not import a module
# H4xx docstrings # H4xx docstrings
# H701 empty localization string # H701 empty localization string
# H702 Formatting operation should be outside of localization method call # H702 Formatting operation should be outside of localization method call
ignore = E121,E126,E127,E128,F403,F999,H201,H302,H4,H701,H702 ignore = E121,E126,E127,E128,F403,F999,H4,H701,H702

View File

@ -12,18 +12,18 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from collections import namedtuple import collections
import copy import copy
from datetime import timedelta import datetime
import logging import logging
from random import randint import random
import re import re
from django.conf import settings import django.conf
from django.db.models import Max import django.db.models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _ # noqa
from horizon import exceptions from horizon import exceptions
from requests import ConnectionError import requests
from novaclient.v1_1.contrib import baremetal from novaclient.v1_1.contrib import baremetal
from tuskarclient.v1 import client as tuskar_client from tuskarclient.v1 import client as tuskar_client
@ -35,10 +35,11 @@ import tuskar_ui.infrastructure.models as dummymodels
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
TUSKAR_ENDPOINT_URL = getattr(settings, 'TUSKAR_ENDPOINT_URL') TUSKAR_ENDPOINT_URL = getattr(django.conf.settings, 'TUSKAR_ENDPOINT_URL')
REMOTE_NOVA_BAREMETAL_CREDS = getattr(settings, 'REMOTE_NOVA_BAREMETAL_CREDS', REMOTE_NOVA_BAREMETAL_CREDS = getattr(django.conf.settings,
'REMOTE_NOVA_BAREMETAL_CREDS',
False) False)
OVERCLOUD_CREDS = getattr(settings, 'OVERCLOUD_CREDS', False) OVERCLOUD_CREDS = getattr(django.conf.settings, 'OVERCLOUD_CREDS', False)
# FIXME: request isn't used right in the tuskar client right now, but looking # FIXME: request isn't used right in the tuskar client right now, but looking
@ -58,13 +59,15 @@ def baremetalclient(request):
return nc return nc
def create_nova_client_baremetal(): def create_nova_client_baremetal():
insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False) insecure = getattr(django.conf.settings, 'OPENSTACK_SSL_NO_VERIFY',
nc = nova.nova_client.Client(request.user.username, False)
request.user.token.id, nc = nova.nova_client.Client(
project_id=request.user.tenant_id, request.user.username,
auth_url=base.url_for(request, 'compute'), request.user.token.id,
insecure=insecure, project_id=request.user.tenant_id,
http_log_debug=settings.DEBUG) auth_url=base.url_for(request, 'compute'),
insecure=insecure,
http_log_debug=django.conf.settings.DEBUG)
nc.client.auth_token = request.user.token.id nc.client.auth_token = request.user.token.id
nc.client.management_url = base.url_for(request, 'compute') nc.client.management_url = base.url_for(request, 'compute')
@ -168,7 +171,7 @@ class Capacity(StringIdAPIResourceWrapper):
@property @property
def usage(self): def usage(self):
if not hasattr(self, '_usage'): if not hasattr(self, '_usage'):
self._usage = randint(0, int(self.value)) self._usage = random.randint(0, int(self.value))
return self._usage return self._usage
# defines a random average of capacity - API should probably be able to # defines a random average of capacity - API should probably be able to
@ -176,7 +179,7 @@ class Capacity(StringIdAPIResourceWrapper):
@property @property
def average(self): def average(self):
if not hasattr(self, '_average'): if not hasattr(self, '_average'):
self._average = randint(0, int(self.value)) self._average = random.randint(0, int(self.value))
return self._average return self._average
@ -230,7 +233,7 @@ class Node(StringIdAPIResourceWrapper):
def list_unracked(cls, request): def list_unracked(cls, request):
try: try:
return [n for n in Node.list(request) if (n.rack is None)] return [n for n in Node.list(request) if (n.rack is None)]
except ConnectionError: except requests.ConnectionError:
return [] return []
@classmethod @classmethod
@ -292,10 +295,12 @@ class Node(StringIdAPIResourceWrapper):
def vm_capacity(self): def vm_capacity(self):
if not hasattr(self, '_vm_capacity'): if not hasattr(self, '_vm_capacity'):
try: try:
value = dummymodels.ResourceClassFlavor.objects\ value = (
.filter( dummymodels.ResourceClassFlavor.objects
resource_class__rack__node=self._apiresource)\ .filter(resource_class__rack__node=self._apiresource)
.aggregate(Max("max_vms"))['max_vms__max'] .aggregate(django.db.models.Max("max_vms"))
['max_vms__max']
)
except Exception: except Exception:
value = _("Unable to retrieve vm capacity") value = _("Unable to retrieve vm capacity")
@ -820,7 +825,7 @@ class FlavorTemplate(StringIdAPIResourceWrapper):
@property @property
def running_virtual_machines(self): def running_virtual_machines(self):
# FIXME: arbitrary number # FIXME: arbitrary number
return randint(0, int(self.cpu.value)) return random.randint(0, int(self.cpu.value))
# defines a random average of capacity - API should probably be able to # defines a random average of capacity - API should probably be able to
# determine average of capacity based on capacity value and obejct_id # determine average of capacity based on capacity value and obejct_id
@ -830,8 +835,9 @@ class FlavorTemplate(StringIdAPIResourceWrapper):
while current_time <= end_time: while current_time <= end_time:
values.append( values.append(
{'date': current_time, {'date': current_time,
'active_vms': randint(0, self.running_virtual_machines)}) 'active_vms': random.randint(0,
current_time += timedelta(hours=1) self.running_virtual_machines)})
current_time += datetime.timedelta(hours=1)
return values return values
@ -917,7 +923,8 @@ class Flavor(StringIdAPIResourceWrapper):
if not hasattr(self, '_capacities'): if not hasattr(self, '_capacities'):
## FIXME: should we distinguish between tuskar ## FIXME: should we distinguish between tuskar
## capacities and our internal capacities? ## capacities and our internal capacities?
CapacityStruct = namedtuple('CapacityStruct', 'name value unit') CapacityStruct = collections.namedtuple('CapacityStruct',
'name value unit')
self._capacities = [Capacity(CapacityStruct( self._capacities = [Capacity(CapacityStruct(
name=c['name'], name=c['name'],
value=c['value'], value=c['value'],
@ -963,7 +970,7 @@ class Flavor(StringIdAPIResourceWrapper):
@property @property
def running_virtual_machines(self): def running_virtual_machines(self):
# FIXME: arbitrary number # FIXME: arbitrary number
return randint(0, int(self.cpu.value)) return random.randint(0, int(self.cpu.value))
# defines a random average of capacity - API should probably be able to # defines a random average of capacity - API should probably be able to
# determine average of capacity based on capacity value and obejct_id # determine average of capacity based on capacity value and obejct_id
@ -971,8 +978,9 @@ class Flavor(StringIdAPIResourceWrapper):
values = [] values = []
current_time = start_time current_time = start_time
while current_time <= end_time: while current_time <= end_time:
values.append({'date': current_time, values.append(
'value': randint(0, self.running_virtual_machines)}) {'date': current_time,
current_time += timedelta(hours=1) 'value': random.randint(0, self.running_virtual_machines)})
current_time += datetime.timedelta(hours=1)
return values return values

View File

@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _ # noqa
import horizon import horizon

View File

@ -14,12 +14,12 @@
# FIXME: configuration for dummy data # FIXME: configuration for dummy data
from django.contrib.contenttypes import generic from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes import models as contenttype_models
from django.db import models from django.db import models
class Capacity(models.Model): class Capacity(models.Model):
content_type = models.ForeignKey(ContentType) content_type = models.ForeignKey(contenttype_models.ContentType)
object_id = models.PositiveIntegerField() object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id') content_object = generic.GenericForeignKey('content_type', 'object_id')

View File

@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _ # noqa
import horizon import horizon

View File

@ -12,12 +12,11 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.conf.urls.defaults import patterns from django.conf.urls import defaults
from django.conf.urls.defaults import url
from tuskar_ui.infrastructure.overview.views import IndexView from tuskar_ui.infrastructure.overview import views
urlpatterns = patterns('', urlpatterns = defaults.patterns('',
url(r'^$', IndexView.as_view(), name='index'), defaults.url(r'^$', views.IndexView.as_view(), name='index'),
) )

View File

@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _ # noqa
from horizon import exceptions from horizon import exceptions
from horizon import forms from horizon import forms

View File

@ -15,7 +15,7 @@
import logging import logging
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _ # noqa
from horizon import tables from horizon import tables

View File

@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _ # noqa
from horizon import tabs from horizon import tabs

View File

@ -12,9 +12,9 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.core.urlresolvers import reverse from django.core import urlresolvers
from django import http from django import http
from mox import IsA import mox
from tuskar_ui import api as tuskar from tuskar_ui import api as tuskar
from tuskar_ui.test import helpers as test from tuskar_ui.test import helpers as test
@ -27,8 +27,8 @@ class FlavorTemplatesTests(test.BaseAdminViewTests):
template = self.tuskar_flavor_templates.first() template = self.tuskar_flavor_templates.first()
tuskar.FlavorTemplate.list( tuskar.FlavorTemplate.list(
IsA(http.HttpRequest)).AndReturn([]) mox.IsA(http.HttpRequest)).AndReturn([])
tuskar.FlavorTemplate.create(IsA(http.HttpRequest), tuskar.FlavorTemplate.create(mox.IsA(http.HttpRequest),
name=template.name, name=template.name,
cpu=0, cpu=0,
memory=0, memory=0,
@ -37,12 +37,14 @@ class FlavorTemplatesTests(test.BaseAdminViewTests):
swap_disk=0).AndReturn(template) swap_disk=0).AndReturn(template)
self.mox.ReplayAll() self.mox.ReplayAll()
url = reverse('horizon:infrastructure:resource_management:' url = urlresolvers.reverse('horizon:infrastructure:'
'flavor_templates:create') 'resource_management:flavor_templates:'
'create')
resp = self.client.get(url) resp = self.client.get(url)
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
self.assertTemplateUsed(resp, "infrastructure/resource_management/" self.assertTemplateUsed(resp,
"flavor_templates/create.html") 'infrastructure/resource_management/'
'flavor_templates/create.html')
data = {'name': template.name, data = {'name': template.name,
'cpu': 0, 'cpu': 0,
@ -51,17 +53,18 @@ class FlavorTemplatesTests(test.BaseAdminViewTests):
'ephemeral_disk': 0, 'ephemeral_disk': 0,
'swap_disk': 0} 'swap_disk': 0}
resp = self.client.post(url, data) resp = self.client.post(url, data)
self.assertRedirectsNoFollow( self.assertRedirectsNoFollow(resp,
resp, reverse('horizon:infrastructure:resource_management:index')) urlresolvers.reverse('horizon:infrastructure:resource_management:'
'index'))
@test.create_stubs({tuskar.FlavorTemplate: ('list', 'create')}) @test.create_stubs({tuskar.FlavorTemplate: ('list', 'create')})
def test_create_flavor_template_post_exception(self): def test_create_flavor_template_post_exception(self):
template = self.tuskar_flavor_templates.first() template = self.tuskar_flavor_templates.first()
tuskar.FlavorTemplate.list( tuskar.FlavorTemplate.list(
IsA(http.HttpRequest)).AndReturn([]) mox.IsA(http.HttpRequest)).AndReturn([])
tuskar.FlavorTemplate.create( tuskar.FlavorTemplate.create(
IsA(http.HttpRequest), mox.IsA(http.HttpRequest),
name=template.name, name=template.name,
cpu=0, cpu=0,
memory=0, memory=0,
@ -71,8 +74,9 @@ class FlavorTemplatesTests(test.BaseAdminViewTests):
self.mox.ReplayAll() self.mox.ReplayAll()
url = reverse('horizon:infrastructure:resource_management:' url = urlresolvers.reverse('horizon:infrastructure:'
'flavor_templates:create') 'resource_management:flavor_templates:'
'create')
data = {'name': template.name, data = {'name': template.name,
'cpu': 0, 'cpu': 0,
'memory': 0, 'memory': 0,
@ -87,13 +91,14 @@ class FlavorTemplatesTests(test.BaseAdminViewTests):
def test_edit_flavor_template_get(self): def test_edit_flavor_template_get(self):
template = self.tuskar_flavor_templates.first() # has no extra spec template = self.tuskar_flavor_templates.first() # has no extra spec
tuskar.FlavorTemplate.get(IsA(http.HttpRequest), tuskar.FlavorTemplate.get(mox.IsA(http.HttpRequest),
template.id).AndReturn(template) template.id).AndReturn(template)
self.mox.ReplayAll() self.mox.ReplayAll()
url = reverse( url = urlresolvers.reverse('horizon:infrastructure:'
'horizon:infrastructure:resource_management:flavor_templates:edit', 'resource_management:flavor_templates:'
args=[template.id]) 'edit',
args=[template.id])
resp = self.client.get(url) resp = self.client.get(url)
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
self.assertTemplateUsed(resp, "infrastructure/resource_management/" self.assertTemplateUsed(resp, "infrastructure/resource_management/"
@ -103,9 +108,9 @@ class FlavorTemplatesTests(test.BaseAdminViewTests):
def test_edit_flavor_template_post(self): def test_edit_flavor_template_post(self):
template = self.tuskar_flavor_templates.first() # has no extra spec template = self.tuskar_flavor_templates.first() # has no extra spec
tuskar.FlavorTemplate.list(IsA(http.HttpRequest)).AndReturn( tuskar.FlavorTemplate.list(mox.IsA(http.HttpRequest)).AndReturn(
self.tuskar_flavor_templates.list()) self.tuskar_flavor_templates.list())
tuskar.FlavorTemplate.update(IsA(http.HttpRequest), tuskar.FlavorTemplate.update(mox.IsA(http.HttpRequest),
template_id=template.id, template_id=template.id,
name=template.name, name=template.name,
cpu=0, cpu=0,
@ -113,7 +118,7 @@ class FlavorTemplatesTests(test.BaseAdminViewTests):
storage=0, storage=0,
ephemeral_disk=0, ephemeral_disk=0,
swap_disk=0).AndReturn(template) swap_disk=0).AndReturn(template)
tuskar.FlavorTemplate.get(IsA(http.HttpRequest), tuskar.FlavorTemplate.get(mox.IsA(http.HttpRequest),
template.id).AndReturn(template) template.id).AndReturn(template)
self.mox.ReplayAll() self.mox.ReplayAll()
@ -124,23 +129,25 @@ class FlavorTemplatesTests(test.BaseAdminViewTests):
'storage': 0, 'storage': 0,
'ephemeral_disk': 0, 'ephemeral_disk': 0,
'swap_disk': 0} 'swap_disk': 0}
url = reverse( url = urlresolvers.reverse('horizon:infrastructure:'
'horizon:infrastructure:resource_management:flavor_templates:edit', 'resource_management:flavor_templates:'
args=[template.id]) 'edit',
args=[template.id])
resp = self.client.post(url, data) resp = self.client.post(url, data)
self.assertNoFormErrors(resp) self.assertNoFormErrors(resp)
self.assertMessageCount(success=1) self.assertMessageCount(success=1)
self.assertRedirectsNoFollow( self.assertRedirectsNoFollow(resp,
resp, reverse('horizon:infrastructure:resource_management:index')) urlresolvers.reverse('horizon:infrastructure:resource_management:'
'index'))
@test.create_stubs({tuskar.FlavorTemplate: ('list', 'update')}) @test.create_stubs({tuskar.FlavorTemplate: ('list', 'update')})
def test_edit_flavor_template_post_exception(self): def test_edit_flavor_template_post_exception(self):
template = self.tuskar_flavor_templates.first() # has no extra spec template = self.tuskar_flavor_templates.first() # has no extra spec
tuskar.FlavorTemplate.list(IsA(http.HttpRequest)).AndReturn( tuskar.FlavorTemplate.list(mox.IsA(http.HttpRequest)).AndReturn(
self.tuskar_flavor_templates.list()) self.tuskar_flavor_templates.list())
tuskar.FlavorTemplate.update( tuskar.FlavorTemplate.update(
IsA(http.HttpRequest), mox.IsA(http.HttpRequest),
template_id=template.id, template_id=template.id,
name=template.name, name=template.name,
cpu=0, cpu=0,
@ -157,9 +164,10 @@ class FlavorTemplatesTests(test.BaseAdminViewTests):
'storage': 0, 'storage': 0,
'ephemeral_disk': 0, 'ephemeral_disk': 0,
'swap_disk': 0} 'swap_disk': 0}
url = reverse( url = urlresolvers.reverse('horizon:infrastructure:'
'horizon:infrastructure:resource_management:flavor_templates:edit', 'resource_management:flavor_templates:'
args=[template.id]) 'edit',
args=[template.id])
resp = self.client.post(url, data) resp = self.client.post(url, data)
self.assertMessageCount(resp, error=1) self.assertMessageCount(resp, error=1)
@ -168,50 +176,59 @@ class FlavorTemplatesTests(test.BaseAdminViewTests):
def test_delete_flavor_template(self): def test_delete_flavor_template(self):
template = self.tuskar_flavor_templates.first() template = self.tuskar_flavor_templates.first()
tuskar.FlavorTemplate.list(IsA(http.HttpRequest)).\ tuskar.FlavorTemplate.list(
AndReturn(self.tuskar_flavor_templates.list()) mox.IsA(http.HttpRequest)).AndReturn(
tuskar.FlavorTemplate.delete(IsA(http.HttpRequest), template.id) self.tuskar_flavor_templates.list())
tuskar.FlavorTemplate.delete(mox.IsA(http.HttpRequest), template.id)
self.mox.ReplayAll() self.mox.ReplayAll()
form_data = {'action': 'flavor_templates__delete__%s' % template.id} form_data = {'action': 'flavor_templates__delete__%s' % template.id}
res = self.client.post( res = self.client.post(
reverse('horizon:infrastructure:resource_management:index'), urlresolvers.reverse('horizon:infrastructure:resource_management:'
'index'),
form_data) form_data)
self.assertRedirectsNoFollow( self.assertRedirectsNoFollow(res,
res, reverse('horizon:infrastructure:resource_management:index')) urlresolvers.reverse('horizon:infrastructure:resource_management:'
'index'))
@test.create_stubs({tuskar.FlavorTemplate: ('get',)}) @test.create_stubs({tuskar.FlavorTemplate: ('get',)})
def test_detail_flavor_template(self): def test_detail_flavor_template(self):
template = self.tuskar_flavor_templates.first() template = self.tuskar_flavor_templates.first()
tuskar.FlavorTemplate.get(IsA(http.HttpRequest), tuskar.FlavorTemplate.get(mox.IsA(http.HttpRequest),
template.id).AndReturn(template) template.id).AndReturn(template)
tuskar.FlavorTemplate.resource_classes = self. \ tuskar.FlavorTemplate.resource_classes = self. \
tuskar_resource_classes tuskar_resource_classes
self.mox.ReplayAll() self.mox.ReplayAll()
url = reverse('horizon:infrastructure:resource_management:' url = urlresolvers.reverse('horizon:infrastructure:'
'flavor_templates:detail', args=[template.id]) 'resource_management:flavor_templates:'
'detail',
args=[template.id])
res = self.client.get(url) res = self.client.get(url)
self.assertTemplateUsed(res, "infrastructure/resource_management/" self.assertTemplateUsed(res,
"flavor_templates/detail.html") 'infrastructure/resource_management/'
'flavor_templates/detail.html')
@test.create_stubs({tuskar.FlavorTemplate: ('get',)}) @test.create_stubs({tuskar.FlavorTemplate: ('get',)})
def test_detail_flavor_template_exception(self): def test_detail_flavor_template_exception(self):
template = self.tuskar_flavor_templates.first() template = self.tuskar_flavor_templates.first()
tuskar.FlavorTemplate.get( tuskar.FlavorTemplate.get(
IsA(http.HttpRequest), mox.IsA(http.HttpRequest), template.id).AndRaise(
template.id).AndRaise(self.exceptions.tuskar) self.exceptions.tuskar)
tuskar.FlavorTemplate.resource_classes = self.tuskar_resource_classes tuskar.FlavorTemplate.resource_classes = self.tuskar_resource_classes
self.mox.ReplayAll() self.mox.ReplayAll()
url = reverse('horizon:infrastructure:resource_management:' url = urlresolvers.reverse('horizon:infrastructure:'
'flavor_templates:detail', args=[template.id]) 'resource_management:flavor_templates:'
'detail',
args=[template.id])
res = self.client.get(url) res = self.client.get(url)
self.assertRedirectsNoFollow( self.assertRedirectsNoFollow(res,
res, reverse('horizon:infrastructure:resource_management:index')) urlresolvers.reverse('horizon:infrastructure:resource_management:'
'index'))

View File

@ -13,31 +13,27 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.conf.urls.defaults import patterns from django.conf.urls import defaults
from django.conf.urls.defaults import url
from tuskar_ui.infrastructure.resource_management.flavor_templates.views \ from tuskar_ui.infrastructure.resource_management.flavor_templates import views
import ActiveInstancesDataView
from tuskar_ui.infrastructure.resource_management.flavor_templates.views \
import CreateView
from tuskar_ui.infrastructure.resource_management.flavor_templates.views \
import DetailEditView
from tuskar_ui.infrastructure.resource_management.flavor_templates.views \
import DetailView
from tuskar_ui.infrastructure.resource_management.flavor_templates.views \
import EditView
FLAVOR_TEMPLATES = r'^(?P<flavor_template_id>[^/]+)/%s$' FLAVOR_TEMPLATES = r'^(?P<flavor_template_id>[^/]+)/%s$'
VIEW_MOD = 'tuskar_ui.infrastructure.' \ VIEW_MOD = 'tuskar_ui.infrastructure.' \
'resource_management.flavor_templates.views' 'resource_management.flavor_templates.views'
urlpatterns = patterns(VIEW_MOD, urlpatterns = defaults.patterns(VIEW_MOD,
url(r'^create/$', CreateView.as_view(), name='create'), defaults.url(r'^create/$', views.CreateView.as_view(), name='create'),
url(FLAVOR_TEMPLATES % 'edit/$', EditView.as_view(), name='edit'), defaults.url(FLAVOR_TEMPLATES % 'edit/$',
url(FLAVOR_TEMPLATES % 'detail_edit/$', views.EditView.as_view(),
DetailEditView.as_view(), name='detail_edit'), name='edit'),
url(FLAVOR_TEMPLATES % 'detail', DetailView.as_view(), name='detail'), defaults.url(FLAVOR_TEMPLATES % 'detail_edit/$',
url(FLAVOR_TEMPLATES % 'active_instances_data', views.DetailEditView.as_view(),
ActiveInstancesDataView.as_view(), name='active_instances_data') name='detail_edit'),
defaults.url(FLAVOR_TEMPLATES % 'detail',
views.DetailView.as_view(),
name='detail'),
defaults.url(FLAVOR_TEMPLATES % 'active_instances_data',
views.ActiveInstancesDataView.as_view(),
name='active_instances_data')
) )

View File

@ -13,49 +13,43 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from datetime import datetime import datetime
from datetime import timedelta
import json import json
import logging import logging
from django.core.serializers.json import DjangoJSONEncoder from django.core.serializers import json as json_serializers
from django.core.urlresolvers import reverse from django.core import urlresolvers
from django.core.urlresolvers import reverse_lazy from django import http
from django.http import HttpResponse from django.utils.translation import ugettext_lazy as _ # noqa
from django.utils.translation import ugettext_lazy as _ from django.views import generic
from django.views.generic import View
from horizon import exceptions from horizon import exceptions
from horizon import forms from horizon import forms as horizon_forms
from horizon import tabs from horizon import tabs as horizon_tabs
from tuskar_ui import api as tuskar from tuskar_ui import api as tuskar
from tuskar_ui.infrastructure. \ from tuskar_ui.infrastructure.resource_management.flavor_templates import forms
resource_management.flavor_templates.forms import CreateFlavorTemplate from tuskar_ui.infrastructure.resource_management.flavor_templates import tabs
from tuskar_ui.infrastructure. \
resource_management.flavor_templates.forms import EditFlavorTemplate
from tuskar_ui.infrastructure. \
resource_management.flavor_templates.tabs import FlavorTemplateDetailTabs
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
class CreateView(forms.ModalFormView): class CreateView(horizon_forms.ModalFormView):
form_class = CreateFlavorTemplate form_class = forms.CreateFlavorTemplate
template_name = ('infrastructure/resource_management/' template_name = ('infrastructure/resource_management/'
'flavor_templates/create.html') 'flavor_templates/create.html')
success_url = reverse_lazy( success_url = urlresolvers.reverse_lazy(
'horizon:infrastructure:resource_management:index') 'horizon:infrastructure:resource_management:index')
class EditView(forms.ModalFormView): class EditView(horizon_forms.ModalFormView):
form_class = EditFlavorTemplate form_class = forms.EditFlavorTemplate
template_name = ('infrastructure/resource_management/' template_name = ('infrastructure/resource_management/'
'flavor_templates/edit.html') 'flavor_templates/edit.html')
form_url = ('horizon:infrastructure:resource_management:' form_url = ('horizon:infrastructure:resource_management:'
'flavor_templates:edit') 'flavor_templates:edit')
success_url = reverse_lazy( success_url = urlresolvers.reverse_lazy(
'horizon:infrastructure:resource_management:index') 'horizon:infrastructure:resource_management:index')
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
@ -88,12 +82,12 @@ class DetailEditView(EditView):
'flavor_templates:detail') 'flavor_templates:detail')
def get_success_url(self): def get_success_url(self):
return reverse(self.success_url, return urlresolvers.reverse(
args=(self.kwargs['flavor_template_id'],)) self.success_url, args=(self.kwargs['flavor_template_id'],))
class DetailView(tabs.TabView): class DetailView(horizon_tabs.TabView):
tab_group_class = FlavorTemplateDetailTabs tab_group_class = tabs.FlavorTemplateDetailTabs
template_name = ('infrastructure/resource_management/' template_name = ('infrastructure/resource_management/'
'flavor_templates/detail.html') 'flavor_templates/detail.html')
@ -109,8 +103,8 @@ class DetailView(tabs.TabView):
flavor_template = tuskar.FlavorTemplate.get(self.request, flavor_template = tuskar.FlavorTemplate.get(self.request,
flavor_template_id) flavor_template_id)
except Exception: except Exception:
redirect = reverse('horizon:infrastructure:' redirect = urlresolvers.reverse(
'resource_management:index') 'horizon:infrastructure:resource_management:index')
exceptions.handle(self.request, exceptions.handle(self.request,
_('Unable to retrieve details for ' _('Unable to retrieve details for '
'flavor template "%s".') 'flavor template "%s".')
@ -125,16 +119,18 @@ class DetailView(tabs.TabView):
**kwargs) **kwargs)
class ActiveInstancesDataView(View): class ActiveInstancesDataView(generic.View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
try: try:
flavor_template = tuskar.FlavorTemplate.get( flavor_template = tuskar.FlavorTemplate.get(
self.request, self.kwargs['flavor_template_id']) self.request, self.kwargs['flavor_template_id'])
values = flavor_template.vms_over_time( values = flavor_template.vms_over_time(
datetime.now() - timedelta(days=7), datetime.now()) datetime.datetime.now() - datetime.timedelta(days=7),
return HttpResponse(json.dumps(values, cls=DjangoJSONEncoder), datetime.datetime.now())
mimetype='application/json') return http.HttpResponse(
json.dumps(values, cls=json_serializers.DjangoJSONEncoder),
mimetype='application/json')
except Exception: except Exception:
exceptions.handle(self.request, exceptions.handle(self.request,
_("Unable to retrieve flavor template data.")) _("Unable to retrieve flavor template data."))

View File

@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _ # noqa
from horizon import tabs from horizon import tabs

View File

@ -12,9 +12,9 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.core.urlresolvers import reverse from django.core import urlresolvers
from django import http from django import http
from mox import IsA import mox
from tuskar_ui import api as tuskar from tuskar_ui import api as tuskar
from tuskar_ui.test import helpers as test from tuskar_ui.test import helpers as test
@ -28,37 +28,41 @@ class FlavorsTests(test.BaseAdminViewTests):
flavor = self.tuskar_flavors.first() flavor = self.tuskar_flavors.first()
resource_class = self.tuskar_resource_classes.first() resource_class = self.tuskar_resource_classes.first()
tuskar.ResourceClass.get(IsA(http.HttpRequest), tuskar.ResourceClass.get(mox.IsA(http.HttpRequest),
resource_class.id).AndReturn(resource_class) resource_class.id).AndReturn(resource_class)
tuskar.Flavor.get(IsA(http.HttpRequest), tuskar.Flavor.get(mox.IsA(http.HttpRequest),
resource_class.id, resource_class.id,
flavor.id).AndReturn(flavor) flavor.id).AndReturn(flavor)
self.mox.ReplayAll() self.mox.ReplayAll()
url = reverse('horizon:infrastructure:resource_management' url = urlresolvers.reverse('horizon:infrastructure:'
':resource_classes:flavors:detail', 'resource_management:resource_classes:'
args=[resource_class.id, flavor.id]) 'flavors:detail',
args=[resource_class.id, flavor.id])
res = self.client.get(url) res = self.client.get(url)
self.assertTemplateUsed(res, "infrastructure/resource_management/" self.assertTemplateUsed(res,
"flavors/detail.html") 'infrastructure/resource_management/'
'flavors/detail.html')
@test.create_stubs({tuskar.Flavor: ('get',)}) @test.create_stubs({tuskar.Flavor: ('get',)})
def test_detail_flavor_exception(self): def test_detail_flavor_exception(self):
flavor = self.tuskar_flavors.first() flavor = self.tuskar_flavors.first()
resource_class = self.tuskar_resource_classes.first() resource_class = self.tuskar_resource_classes.first()
tuskar.Flavor.get(IsA(http.HttpRequest), tuskar.Flavor.get(mox.IsA(http.HttpRequest),
resource_class.id, resource_class.id,
flavor.id).AndRaise(self.exceptions.tuskar) flavor.id).AndRaise(self.exceptions.tuskar)
self.mox.ReplayAll() self.mox.ReplayAll()
url = reverse('horizon:infrastructure:resource_management:' url = urlresolvers.reverse('horizon:infrastructure:'
'resource_classes:flavors:detail', 'resource_management:resource_classes:'
args=[resource_class.id, flavor.id]) 'flavors:detail',
args=[resource_class.id, flavor.id])
res = self.client.get(url) res = self.client.get(url)
self.assertRedirectsNoFollow( self.assertRedirectsNoFollow(res,
res, reverse('horizon:infrastructure:resource_management:index')) urlresolvers.reverse('horizon:infrastructure:resource_management:'
'index'))

View File

@ -13,16 +13,16 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.conf.urls.defaults import patterns from django.conf.urls import defaults
from django.conf.urls.defaults import url
from tuskar_ui.infrastructure.resource_management.flavors.views \ from tuskar_ui.infrastructure.resource_management.flavors import views
import DetailView
VIEW_MOD = 'tuskar_ui.infrastructure.' \ VIEW_MOD = 'tuskar_ui.infrastructure.' \
'resource_management.flavors.views' 'resource_management.flavors.views'
urlpatterns = patterns(VIEW_MOD, urlpatterns = defaults.patterns(VIEW_MOD,
url(r'^(?P<flavor_id>[^/]+)/$', DetailView.as_view(), name='detail') defaults.url(r'^(?P<flavor_id>[^/]+)/$',
views.DetailView.as_view(),
name='detail')
) )

View File

@ -13,19 +13,18 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.core.urlresolvers import reverse from django.core import urlresolvers
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _ # noqa
from horizon import exceptions from horizon import exceptions
from horizon import tabs from horizon import tabs as horizon_tabs
from tuskar_ui import api as tuskar from tuskar_ui import api as tuskar
from tuskar_ui.infrastructure. \ from tuskar_ui.infrastructure.resource_management.flavors import tabs
resource_management.flavors.tabs import FlavorDetailTabs
class DetailView(tabs.TabView): class DetailView(horizon_tabs.TabView):
tab_group_class = FlavorDetailTabs tab_group_class = tabs.FlavorDetailTabs
template_name = ('infrastructure/resource_management/flavors/detail.html') template_name = ('infrastructure/resource_management/flavors/detail.html')
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
@ -43,8 +42,8 @@ class DetailView(tabs.TabView):
flavor_id, flavor_id,
resource_class_id) resource_class_id)
except Exception: except Exception:
redirect = reverse('horizon:infrastructure:' redirect = urlresolvers.reverse(
'resource_management:index') 'horizon:infrastructure:resource_management:index')
exceptions.handle(self.request, exceptions.handle(self.request,
_('Unable to retrieve details for ' _('Unable to retrieve details for '
'flavor "%s".') % flavor_id, 'flavor "%s".') % flavor_id,
@ -59,8 +58,8 @@ class DetailView(tabs.TabView):
resource_class = tuskar.ResourceClass.get(self.request, resource_class = tuskar.ResourceClass.get(self.request,
resource_class_id) resource_class_id)
except Exception: except Exception:
redirect = reverse('horizon:infrastructure:' redirect = urlresolvers.reverse(
'resource_management:index') 'horizon:infrastructure:resource_management:index')
exceptions.handle(self.request, exceptions.handle(self.request,
_('Unable to retrieve details for resource ' _('Unable to retrieve details for resource '
'class "%s".') % resource_class_id, 'class "%s".') % resource_class_id,

View File

@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _ # noqa
from horizon import tables from horizon import tables

View File

@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _ # noqa
from horizon import tabs from horizon import tabs

View File

@ -12,33 +12,30 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.core.urlresolvers import reverse from django.core import urlresolvers
from django import http from django import http
from mox import IsA import mox
from tuskar_ui import api as tuskar from tuskar_ui import api as tuskar
from tuskar_ui.test import helpers as test from tuskar_ui.test import helpers as test
class ResourceViewTests(test.BaseAdminViewTests): class ResourceViewTests(test.BaseAdminViewTests):
unracked_page = reverse('horizon:infrastructure:' unracked_page = urlresolvers.reverse(
'resource_management:nodes:unracked') 'horizon:infrastructure:resource_management:nodes:unracked')
@test.create_stubs({tuskar.Node: ('list_unracked',), }) @test.create_stubs({tuskar.Node: ('list_unracked',), })
def test_unracked(self): def test_unracked(self):
unracked_nodes = self.baremetal_unracked_nodes.list() unracked_nodes = self.baremetal_unracked_nodes.list()
tuskar.Node.list_unracked(IsA(http.HttpRequest)) \ tuskar.Node.list_unracked(
.AndReturn(unracked_nodes) mox.IsA(http.HttpRequest)).AndReturn(unracked_nodes)
self.mox.ReplayAll() self.mox.ReplayAll()
res = self.client.get(self.unracked_page) res = self.client.get(self.unracked_page)
self.assertTemplateUsed(res, self.assertTemplateUsed(res,
'infrastructure/resource_management/nodes/unracked.html') 'infrastructure/resource_management/nodes/unracked.html')
unracked_nodes_table = res.context['unracked_nodes_table'].data unracked_nodes_table = res.context['unracked_nodes_table'].data
self.assertItemsEqual(unracked_nodes_table, unracked_nodes) self.assertItemsEqual(unracked_nodes_table, unracked_nodes)

View File

@ -12,19 +12,18 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.conf.urls.defaults import patterns from django.conf.urls import defaults
from django.conf.urls.defaults import url
from tuskar_ui.infrastructure.resource_management.nodes.views import DetailView from tuskar_ui.infrastructure.resource_management.nodes import views
from tuskar_ui.infrastructure.resource_management.nodes.views \
import UnrackedView
NODES = r'^(?P<node_id>[^/]+)/%s$' NODES = r'^(?P<node_id>[^/]+)/%s$'
VIEW_MOD = 'tuskar_ui.infrastructure.resource_management.nodes.views' VIEW_MOD = 'tuskar_ui.infrastructure.resource_management.nodes.views'
urlpatterns = patterns(VIEW_MOD, urlpatterns = defaults.patterns(VIEW_MOD,
url(NODES % 'detail', DetailView.as_view(), name='detail'), defaults.url(NODES % 'detail', views.DetailView.as_view(), name='detail'),
url(r'^unracked/$', UnrackedView.as_view(), name='unracked'), defaults.url(r'^unracked/$',
views.UnrackedView.as_view(),
name='unracked'),
) )

View File

@ -12,22 +12,20 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.core.urlresolvers import reverse from django.core import urlresolvers
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _ # noqa
from horizon import exceptions from horizon import exceptions
from horizon import tables from horizon import tables as horizon_tables
from horizon import tabs from horizon import tabs as horizon_tabs
from tuskar_ui import api as tuskar from tuskar_ui import api as tuskar
from tuskar_ui.infrastructure.resource_management.nodes.tables \ from tuskar_ui.infrastructure.resource_management.nodes import tables
import UnrackedNodesTable from tuskar_ui.infrastructure.resource_management.nodes import tabs
from tuskar_ui.infrastructure.resource_management.nodes.tabs \
import NodeDetailTabs
class UnrackedView(tables.DataTableView): class UnrackedView(horizon_tables.DataTableView):
table_class = UnrackedNodesTable table_class = tables.UnrackedNodesTable
template_name = 'infrastructure/resource_management/nodes/unracked.html' template_name = 'infrastructure/resource_management/nodes/unracked.html'
def get_data(self): def get_data(self):
@ -40,8 +38,8 @@ class UnrackedView(tables.DataTableView):
return nodes return nodes
class DetailView(tabs.TabView): class DetailView(horizon_tabs.TabView):
tab_group_class = NodeDetailTabs tab_group_class = tabs.NodeDetailTabs
template_name = 'infrastructure/resource_management/nodes/detail.html' template_name = 'infrastructure/resource_management/nodes/detail.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
@ -55,8 +53,8 @@ class DetailView(tabs.TabView):
node_id = self.kwargs['node_id'] node_id = self.kwargs['node_id']
node = tuskar.Node.get(self.request, node_id) node = tuskar.Node.get(self.request, node_id)
except Exception: except Exception:
redirect = reverse('horizon:infrastructure:' redirect = urlresolvers.reverse(
'resource_management:index') 'horizon:infrastructure:resource_management:index')
exceptions.handle(self.request, exceptions.handle(self.request,
_('Unable to retrieve details for ' _('Unable to retrieve details for '
'node "%s".') 'node "%s".')

View File

@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _ # noqa
import horizon import horizon

View File

@ -12,8 +12,8 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.forms import ValidationError import django.forms
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _ # noqa
from horizon import exceptions from horizon import exceptions
from horizon import forms from horizon import forms
@ -42,20 +42,21 @@ class UploadRack(forms.SelfHandlingForm):
if 'upload' in self.request.POST: if 'upload' in self.request.POST:
if not csv_file: if not csv_file:
raise ValidationError(_('CSV file not set.')) raise django.forms.ValidationError(_('CSV file not set.'))
else: else:
try: try:
CSVRack.from_str(data) CSVRack.from_str(data)
except Exception: except Exception:
LOG.exception("Failed to parse rack CSV file.") LOG.exception("Failed to parse rack CSV file.")
raise ValidationError(_('Failed to parse CSV file.')) raise django.forms.ValidationError(
_('Failed to parse CSV file.'))
return data return data
def clean_uploaded_data(self): def clean_uploaded_data(self):
data = self.cleaned_data['uploaded_data'] data = self.cleaned_data['uploaded_data']
if 'add_racks' in self.request.POST: if 'add_racks' in self.request.POST:
if not data: if not data:
raise ValidationError(_('Upload CSV file first')) raise django.forms.ValidationError(_('Upload CSV file first'))
elif 'upload' in self.request.POST: elif 'upload' in self.request.POST:
# reset obsolete uploaded data # reset obsolete uploaded data
self.data['uploaded_data'] = None self.data['uploaded_data'] = None

View File

@ -14,7 +14,7 @@
import logging import logging
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _ # noqa
from horizon import tables from horizon import tables

View File

@ -12,13 +12,12 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _ # noqa
from horizon import exceptions from horizon import exceptions
from horizon import tabs from horizon import tabs
from tuskar_ui.infrastructure. \ from tuskar_ui.infrastructure.resource_management.nodes import tables
resource_management.nodes.tables import NodesTable
class OverviewTab(tabs.Tab): class OverviewTab(tabs.Tab):
@ -32,7 +31,7 @@ class OverviewTab(tabs.Tab):
class NodesTab(tabs.TableTab): class NodesTab(tabs.TableTab):
table_classes = (NodesTable,) table_classes = (tables.NodesTable,)
name = _("Nodes") name = _("Nodes")
slug = "nodes" slug = "nodes"
template_name = "horizon/common/_detail_table.html" template_name = "horizon/common/_detail_table.html"

View File

@ -10,10 +10,10 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.core.urlresolvers import reverse from django.core import urlresolvers
from django import http from django import http
from mox import IsA import mox
from tuskar_ui import api as tuskar from tuskar_ui import api as tuskar
from tuskar_ui.test import helpers as test from tuskar_ui.test import helpers as test
@ -23,18 +23,19 @@ import tempfile
class RackViewTests(test.BaseAdminViewTests): class RackViewTests(test.BaseAdminViewTests):
index_page = reverse('horizon:infrastructure:resource_management:index') index_page = urlresolvers.reverse(
'horizon:infrastructure:resource_management:index')
@test.create_stubs({tuskar.ResourceClass: ('list',)}) @test.create_stubs({tuskar.ResourceClass: ('list',)})
def test_create_rack_get(self): def test_create_rack_get(self):
tuskar.ResourceClass.list( tuskar.ResourceClass.list(
IsA(http.request.HttpRequest)).AndReturn( mox.IsA(http.request.HttpRequest)).AndReturn(
self.tuskar_resource_classes.list()) self.tuskar_resource_classes.list())
self.mox.ReplayAll() self.mox.ReplayAll()
url = reverse('horizon:infrastructure:resource_management:' url = urlresolvers.reverse('horizon:infrastructure:'
'racks:create') 'resource_management:racks:create')
rack = self.client.get(url) rack = self.client.get(url)
self.assertEqual(rack.status_code, 200) self.assertEqual(rack.status_code, 200)
@ -51,10 +52,10 @@ class RackViewTests(test.BaseAdminViewTests):
node = self.baremetal_nodes.first() node = self.baremetal_nodes.first()
tuskar.Rack.list( tuskar.Rack.list(
IsA(http.request.HttpRequest)).AndReturn( mox.IsA(http.request.HttpRequest)).AndReturn(
self.tuskar_racks.list()) self.tuskar_racks.list())
tuskar.Node.create( tuskar.Node.create(
IsA(http.request.HttpRequest), mox.IsA(http.request.HttpRequest),
name='New Node', name='New Node',
cpus=u'1', cpus=u'1',
memory_mb=u'1024', memory_mb=u'1024',
@ -65,14 +66,14 @@ class RackViewTests(test.BaseAdminViewTests):
pm_password=u'', pm_password=u'',
terminal_port=u'').AndReturn(node) terminal_port=u'').AndReturn(node)
tuskar.Rack.create( tuskar.Rack.create(
IsA(http.request.HttpRequest), mox.IsA(http.request.HttpRequest),
name='New Rack', name='New Rack',
resource_class_id=u'1', resource_class_id=u'1',
location='Tokyo', location='Tokyo',
subnet='1.2.3.4', subnet='1.2.3.4',
nodes=[{'id': '1'}]).AndReturn(None) nodes=[{'id': '1'}]).AndReturn(None)
tuskar.ResourceClass.list( tuskar.ResourceClass.list(
IsA(http.request.HttpRequest)).AndReturn( mox.IsA(http.request.HttpRequest)).AndReturn(
self.tuskar_resource_classes.list()) self.tuskar_resource_classes.list())
self.mox.ReplayAll() self.mox.ReplayAll()
@ -81,8 +82,8 @@ class RackViewTests(test.BaseAdminViewTests):
'location': 'Tokyo', 'subnet': '1.2.3.4', 'location': 'Tokyo', 'subnet': '1.2.3.4',
'node_name': 'New Node', 'prov_mac_address': 'aa:bb:cc:dd:ee', 'node_name': 'New Node', 'prov_mac_address': 'aa:bb:cc:dd:ee',
'cpus': u'1', 'memory_mb': u'1024', 'local_gb': u'10'} 'cpus': u'1', 'memory_mb': u'1024', 'local_gb': u'10'}
url = reverse('horizon:infrastructure:resource_management:' url = urlresolvers.reverse('horizon:infrastructure:'
'racks:create') 'resource_management:racks:create')
resp = self.client.post(url, data) resp = self.client.post(url, data)
self.assertRedirectsNoFollow(resp, self.index_page) self.assertRedirectsNoFollow(resp, self.index_page)
@ -91,19 +92,19 @@ class RackViewTests(test.BaseAdminViewTests):
def test_edit_rack_get(self): def test_edit_rack_get(self):
rack = self.tuskar_racks.first() rack = self.tuskar_racks.first()
tuskar.Rack.\ tuskar.Rack.get(
get(IsA(http.HttpRequest), rack.id).\ mox.IsA(http.HttpRequest), rack.id).MultipleTimes().AndReturn(rack)
MultipleTimes().AndReturn(rack)
tuskar.ResourceClass.list( tuskar.ResourceClass.list(
IsA(http.request.HttpRequest)).AndReturn( mox.IsA(http.request.HttpRequest)).AndReturn(
self.tuskar_resource_classes.list()) self.tuskar_resource_classes.list())
self.mox.ReplayAll() self.mox.ReplayAll()
tuskar.Rack.list_nodes = [] tuskar.Rack.list_nodes = []
url = reverse('horizon:infrastructure:resource_management:' + url = urlresolvers.reverse('horizon:infrastructure:'
'racks:edit', args=[1]) 'resource_management:racks:edit',
args=[1])
res = self.client.get(url) res = self.client.get(url)
self.assertEqual(res.status_code, 200) self.assertEqual(res.status_code, 200)
self.assertTemplateUsed(res, self.assertTemplateUsed(res,
@ -125,20 +126,20 @@ class RackViewTests(test.BaseAdminViewTests):
'cpus': u'1', 'memory_mb': u'1024', 'local_gb': u'10'} 'cpus': u'1', 'memory_mb': u'1024', 'local_gb': u'10'}
tuskar.Rack.get( tuskar.Rack.get(
IsA(http.HttpRequest), rack.id).MultipleTimes().\ mox.IsA(http.HttpRequest), rack.id).MultipleTimes().AndReturn(rack)
AndReturn(rack)
tuskar.Rack.list( tuskar.Rack.list(
IsA(http.request.HttpRequest)).AndReturn( mox.IsA(http.request.HttpRequest)).AndReturn(
self.tuskar_racks.list()) self.tuskar_racks.list())
tuskar.Rack.update(IsA(http.HttpRequest), rack.id, rack_data) tuskar.Rack.update(mox.IsA(http.HttpRequest), rack.id, rack_data)
tuskar.ResourceClass.list( tuskar.ResourceClass.list(
IsA(http.request.HttpRequest)).AndReturn( mox.IsA(http.request.HttpRequest)).AndReturn(
self.tuskar_resource_classes.list()) self.tuskar_resource_classes.list())
self.mox.ReplayAll() self.mox.ReplayAll()
url = reverse('horizon:infrastructure:resource_management:' + url = urlresolvers.reverse('horizon:infrastructure:'
'racks:edit', args=[rack.id]) '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)
@ -147,21 +148,22 @@ class RackViewTests(test.BaseAdminViewTests):
@test.create_stubs({tuskar.Rack: ('delete', 'list')}) @test.create_stubs({tuskar.Rack: ('delete', 'list')})
def test_delete_rack(self): def test_delete_rack(self):
rack_id = u'1' rack_id = u'1'
tuskar.Rack.delete(IsA(http.request.HttpRequest), rack_id) \ tuskar.Rack.delete(
.AndReturn(None) mox.IsA(http.request.HttpRequest), rack_id).AndReturn(None)
tuskar.Rack.list( tuskar.Rack.list(
IsA(http.request.HttpRequest)).AndReturn( mox.IsA(http.request.HttpRequest)).AndReturn(
self.tuskar_racks.list()) 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 = urlresolvers.reverse('horizon:infrastructure:'
'resource_management:index')
result = self.client.post(url, data) result = self.client.post(url, data)
self.assertRedirectsNoFollow(result, self.index_page) self.assertRedirectsNoFollow(result, self.index_page)
def test_upload_rack_get(self): def test_upload_rack_get(self):
url = reverse('horizon:infrastructure:resource_management:' url = urlresolvers.reverse('horizon:infrastructure:'
'racks:upload') 'resource_management:racks:upload')
rack = self.client.get(url) rack = self.client.get(url)
self.assertEqual(rack.status_code, 200) self.assertEqual(rack.status_code, 200)
@ -169,16 +171,16 @@ class RackViewTests(test.BaseAdminViewTests):
'infrastructure/resource_management/racks/upload.html') 'infrastructure/resource_management/racks/upload.html')
def test_upload_rack_upload(self): def test_upload_rack_upload(self):
csv_data = 'Rack1,rclass1,192.168.111.0/24,regionX,f0:dd:f1:da:f9:b5 '\ csv_data = ('Rack1,rclass1,192.168.111.0/24,regionX,f0:dd:f1:da:f9:b5 '
'f2:de:f1:da:f9:66 f2:de:ff:da:f9:67' 'f2:de:f1:da:f9:66 f2:de:ff:da:f9:67')
temp_file = tempfile.TemporaryFile() temp_file = tempfile.TemporaryFile()
temp_file.write(csv_data) temp_file.write(csv_data)
temp_file.flush() temp_file.flush()
temp_file.seek(0) temp_file.seek(0)
data = {'csv_file': temp_file, 'upload': '1'} data = {'csv_file': temp_file, 'upload': '1'}
url = reverse('horizon:infrastructure:resource_management:' url = urlresolvers.reverse('horizon:infrastructure:'
'racks:upload') 'resource_management:racks:upload')
resp = self.client.post(url, data) resp = self.client.post(url, data)
self.assertTemplateUsed(resp, self.assertTemplateUsed(resp,
'infrastructure/resource_management/racks/upload.html') 'infrastructure/resource_management/racks/upload.html')
@ -188,8 +190,8 @@ class RackViewTests(test.BaseAdminViewTests):
def test_upload_rack_upload_with_error(self): def test_upload_rack_upload_with_error(self):
data = {'upload': '1'} data = {'upload': '1'}
url = reverse('horizon:infrastructure:resource_management:' url = urlresolvers.reverse('horizon:infrastructure:'
'racks:upload') 'resource_management:racks:upload')
resp = self.client.post(url, data) resp = self.client.post(url, data)
self.assertTemplateUsed(resp, self.assertTemplateUsed(resp,
'infrastructure/resource_management/racks/upload.html') 'infrastructure/resource_management/racks/upload.html')
@ -200,21 +202,21 @@ class RackViewTests(test.BaseAdminViewTests):
@test.create_stubs({tuskar.Rack: ('create',), @test.create_stubs({tuskar.Rack: ('create',),
tuskar.ResourceClass: ('list',)}) tuskar.ResourceClass: ('list',)})
def test_upload_rack_create(self): def test_upload_rack_create(self):
tuskar.Rack.create(IsA(http.request.HttpRequest), tuskar.Rack.create(mox.IsA(http.request.HttpRequest),
name='Rack1', name='Rack1',
resource_class_id='1', resource_class_id='1',
location='regionX', location='regionX',
subnet='192.168.111.0/24').AndReturn(None) subnet='192.168.111.0/24').AndReturn(None)
tuskar.ResourceClass.list( tuskar.ResourceClass.list(
IsA(http.request.HttpRequest)).AndReturn( mox.IsA(http.request.HttpRequest)).AndReturn(
self.tuskar_resource_classes.list()) self.tuskar_resource_classes.list())
self.mox.ReplayAll() self.mox.ReplayAll()
csv_data = 'Rack1,rclass1,192.168.111.0/24,regionX,f0:dd:f1:da:f9:b5 '\ csv_data = ('Rack1,rclass1,192.168.111.0/24,regionX,f0:dd:f1:da:f9:b5 '
'f2:de:f1:da:f9:66 f2:de:ff:da:f9:67' 'f2:de:f1:da:f9:66 f2:de:ff:da:f9:67')
data = {'uploaded_data': base64.b64encode(csv_data), 'add_racks': '1'} data = {'uploaded_data': base64.b64encode(csv_data), 'add_racks': '1'}
url = reverse('horizon:infrastructure:resource_management:' url = urlresolvers.reverse('horizon:infrastructure:'
'racks:upload') 'resource_management:racks:upload')
resp = self.client.post(url, data) resp = self.client.post(url, data)
self.assertRedirectsNoFollow(resp, self.index_page) self.assertRedirectsNoFollow(resp, self.index_page)
self.assertMessageCount(success=1) self.assertMessageCount(success=1)

View File

@ -12,40 +12,31 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.conf.urls import patterns from django.conf import urls
from django.conf.urls import url
from tuskar_ui.infrastructure. \
resource_management.racks.views import CreateView
from tuskar_ui.infrastructure. \
resource_management.racks.views import DetailEditView
from tuskar_ui.infrastructure. \
resource_management.racks.views import DetailView
from tuskar_ui.infrastructure. \
resource_management.racks.views import EditRackStatusView
from tuskar_ui.infrastructure. \
resource_management.racks.views import EditView
from tuskar_ui.infrastructure. \
resource_management.racks.views import UploadView
from tuskar_ui.infrastructure. \
resource_management.racks.views import UsageDataView
from tuskar_ui.infrastructure.resource_management.racks import views
RACKS = r'^(?P<rack_id>[^/]+)/%s$' RACKS = r'^(?P<rack_id>[^/]+)/%s$'
VIEW_MOD = 'tuskar_ui.infrastructure.resource_management.racks.views' VIEW_MOD = 'tuskar_ui.infrastructure.resource_management.racks.views'
urlpatterns = patterns(VIEW_MOD, urlpatterns = urls.patterns(VIEW_MOD,
url(r'^create/$', CreateView.as_view(), name='create'), urls.url(r'^create/$', views.CreateView.as_view(), name='create'),
url(r'^upload/$', UploadView.as_view(), name='upload'), urls.url(r'^upload/$', views.UploadView.as_view(), name='upload'),
url(r'^usage_data$', UsageDataView.as_view(), name='usage_data'), urls.url(r'^usage_data$',
url(RACKS % 'edit/', EditView.as_view(), name='edit'), views.UsageDataView.as_view(),
url(RACKS % 'detail_edit/', DetailEditView.as_view(), name='detail_edit'), name='usage_data'),
url(RACKS % 'edit_status/', EditRackStatusView.as_view(), urls.url(RACKS % 'edit/', views.EditView.as_view(), name='edit'),
name='edit_status'), urls.url(RACKS % 'detail_edit/',
url(RACKS % 'detail', DetailView.as_view(), name='detail'), views.DetailEditView.as_view(),
url(RACKS % 'top_communicating.json', 'top_communicating', name='detail_edit'),
name='top_communicating'), urls.url(RACKS % 'edit_status/',
url(RACKS % 'node_health.json', 'node_health', name='node_health'), views.EditRackStatusView.as_view(),
url(RACKS % 'check_state.json', 'check_state', name='check_state'), name='edit_status'),
urls.url(RACKS % 'detail', views.DetailView.as_view(), name='detail'),
urls.url(RACKS % 'top_communicating.json',
'top_communicating',
name='top_communicating'),
urls.url(RACKS % 'node_health.json', 'node_health', name='node_health'),
urls.url(RACKS % 'check_state.json', 'check_state', name='check_state'),
) )

View File

@ -12,68 +12,56 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from datetime import datetime import datetime
from datetime import timedelta
import json import json
import logging import logging
import random import random
from django.core.serializers.json import DjangoJSONEncoder from django.core.serializers import json as json_serializer
from django.core.urlresolvers import reverse from django.core import urlresolvers
from django.core.urlresolvers import reverse_lazy from django import http
from django.http import HttpResponse
from django.utils import simplejson from django.utils import simplejson
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _ # noqa
from django.views.generic import View from django.views import generic
from horizon import exceptions from horizon import exceptions
from horizon import forms from horizon import forms as horizon_forms
from horizon import tabs from horizon import tabs as horizon_tabs
from horizon import workflows from horizon import workflows as horizon_workflows
from tuskar_ui import api as tuskar from tuskar_ui import api as tuskar
from tuskar_ui.infrastructure. \ from tuskar_ui.infrastructure.resource_management.racks import forms
resource_management.racks.forms import UpdateRackStatus from tuskar_ui.infrastructure.resource_management.racks import tables
from tuskar_ui.infrastructure. \ from tuskar_ui.infrastructure.resource_management.racks import tabs
resource_management.racks.forms import UploadRack from tuskar_ui.infrastructure.resource_management.racks import workflows
from tuskar_ui.infrastructure. \
resource_management.racks.tabs import RackDetailTabs
from tuskar_ui.infrastructure. \
resource_management.racks.tables import UploadRacksTable
from tuskar_ui.infrastructure. \
resource_management.racks.workflows import CreateRack
from tuskar_ui.infrastructure. \
resource_management.racks.workflows import DetailEditRack
from tuskar_ui.infrastructure. \
resource_management.racks.workflows import EditRack
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
class CreateView(workflows.WorkflowView): class CreateView(horizon_workflows.WorkflowView):
workflow_class = CreateRack workflow_class = workflows.CreateRack
def get_initial(self): def get_initial(self):
pass pass
class UploadView(forms.ModalFormView): class UploadView(horizon_forms.ModalFormView):
form_class = UploadRack form_class = forms.UploadRack
template_name = 'infrastructure/resource_management/racks/upload.html' template_name = 'infrastructure/resource_management/racks/upload.html'
success_url = reverse_lazy( success_url = urlresolvers.reverse_lazy(
'horizon:infrastructure:resource_management:index') 'horizon:infrastructure:resource_management:index')
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(UploadView, self).get_context_data(**kwargs) context = super(UploadView, self).get_context_data(**kwargs)
context['racks_table'] = UploadRacksTable( context['racks_table'] = tables.UploadRacksTable(
self.request, kwargs['form'].initial.get('racks', [])) self.request, kwargs['form'].initial.get('racks', []))
return context return context
class EditView(workflows.WorkflowView): class EditView(horizon_workflows.WorkflowView):
workflow_class = EditRack workflow_class = workflows.EditRack
def get_initial(self): def get_initial(self):
obj = tuskar.Rack.get(self.request, self.kwargs['rack_id']) obj = tuskar.Rack.get(self.request, self.kwargs['rack_id'])
@ -84,11 +72,11 @@ class EditView(workflows.WorkflowView):
class DetailEditView(EditView): class DetailEditView(EditView):
workflow_class = DetailEditRack workflow_class = workflows.DetailEditRack
class EditRackStatusView(forms.ModalFormView): class EditRackStatusView(horizon_forms.ModalFormView):
form_class = UpdateRackStatus form_class = forms.UpdateRackStatus
template_name = 'infrastructure/resource_management/racks/edit_status.html' template_name = 'infrastructure/resource_management/racks/edit_status.html'
def get_success_url(self): def get_success_url(self):
@ -113,8 +101,8 @@ class EditRackStatusView(forms.ModalFormView):
'action': action} 'action': action}
class DetailView(tabs.TabView): class DetailView(horizon_tabs.TabView):
tab_group_class = RackDetailTabs tab_group_class = tabs.RackDetailTabs
template_name = 'infrastructure/resource_management/racks/detail.html' template_name = 'infrastructure/resource_management/racks/detail.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
@ -128,13 +116,12 @@ class DetailView(tabs.TabView):
rack_id = self.kwargs['rack_id'] rack_id = self.kwargs['rack_id']
rack = tuskar.Rack.get(self.request, rack_id) rack = tuskar.Rack.get(self.request, rack_id)
except Exception: except Exception:
redirect = reverse('horizon:infrastructure:' redirect = urlresolvers.reverse(
'resource_management:index') 'horizon:infrastructure:resource_management:index')
exceptions.handle(self.request, exceptions.handle(
_('Unable to retrieve details for ' self.request,
'rack "%s".') _('Unable to retrieve details for rack "%s".') % rack_id,
% rack_id, redirect=redirect)
redirect=redirect)
self._rack = rack self._rack = rack
return self._rack return self._rack
@ -144,7 +131,7 @@ class DetailView(tabs.TabView):
**kwargs) **kwargs)
class UsageDataView(View): class UsageDataView(generic.View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
interval = request.GET.get('interval', '1w') interval = request.GET.get('interval', '1w')
@ -170,16 +157,17 @@ class UsageDataView(View):
values = [] values = []
for i in range(data_count): for i in range(data_count):
timediff = timedelta(**{timedelta_param: i}) timediff = datetime.timedelta(**{timedelta_param: i})
current_value = {'date': datetime.now() - timediff} current_value = {'date': datetime.datetime.now() - timediff}
for usage_type in series: for usage_type in series:
current_value[usage_type] = random.randint(1, 9) current_value[usage_type] = random.randint(1, 9)
values.append(current_value) values.append(current_value)
return HttpResponse(json.dumps(values, cls=DjangoJSONEncoder), return http.HttpResponse(
mimetype='application/json') json.dumps(values, cls=json_serializer.DjangoJSONEncoder),
mimetype='application/json')
def top_communicating(request, rack_id=None): def top_communicating(request, rack_id=None):
@ -216,8 +204,8 @@ def top_communicating(request, rack_id=None):
'range': ["#000060", "#99FFFF"]} 'range': ["#000060", "#99FFFF"]}
res = {'data': data, res = {'data': data,
'settings': settings} 'settings': settings}
return HttpResponse(simplejson.dumps(res), return http.HttpResponse(simplejson.dumps(res),
mimetype="application/json") mimetype="application/json")
def node_health(request, rack_id=None): def node_health(request, rack_id=None):
@ -249,8 +237,8 @@ def node_health(request, rack_id=None):
data.sort(key=lambda x: x['percentage']) data.sort(key=lambda x: x['percentage'])
res = {'data': data} res = {'data': data}
return HttpResponse(simplejson.dumps(res), return http.HttpResponse(simplejson.dumps(res),
mimetype="application/json") mimetype="application/json")
def check_state(request, rack_id=None): def check_state(request, rack_id=None):
@ -258,6 +246,5 @@ def check_state(request, rack_id=None):
res = {'state': rack.state} res = {'state': rack.state}
return HttpResponse( return http.HttpResponse(simplejson.dumps(res),
simplejson.dumps(res), mimetype="application/json")
mimetype="application/json")

View File

@ -12,8 +12,8 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.core.urlresolvers import reverse from django.core import urlresolvers
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _ # noqa
from horizon import exceptions from horizon import exceptions
from horizon import forms from horizon import forms
@ -212,8 +212,8 @@ class DetailEditRack(EditRack):
def get_success_url(self): def get_success_url(self):
rack_id = self.context['rack_id'] rack_id = self.context['rack_id']
return reverse(self.success_url, args=(rack_id,)) return urlresolvers.reverse(self.success_url, args=(rack_id,))
def get_failure_url(self): def get_failure_url(self):
rack_id = self.context['rack_id'] rack_id = self.context['rack_id']
return reverse(self.success_url, args=(rack_id,)) return urlresolvers.reverse(self.success_url, args=(rack_id,))

View File

@ -12,8 +12,8 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.core.urlresolvers import reverse from django.core import urlresolvers
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _ # noqa
from horizon import exceptions from horizon import exceptions
from horizon import forms from horizon import forms
@ -61,6 +61,6 @@ class DeleteCommand(object):
except Exception: except Exception:
self.msg = _('Failed to delete Class %s') % self.resource_class.id self.msg = _('Failed to delete Class %s') % self.resource_class.id
LOG.info(self.msg) LOG.info(self.msg)
redirect = reverse( redirect = urlresolvers.reverse(
"horizon:infrastructure:resource_management:index") 'horizon:infrastructure:resource_management:index')
exceptions.handle(self.request, self.msg, redirect=redirect) exceptions.handle(self.request, self.msg, redirect=redirect)

View File

@ -16,20 +16,18 @@ import logging
import re import re
from django.core import urlresolvers from django.core import urlresolvers
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _ # noqa
from horizon import exceptions from horizon import exceptions
from horizon import tables from horizon import tables
from tuskar_ui import api as tuskar from tuskar_ui import api as tuskar
from tuskar_ui.forms import NumberInput from tuskar_ui import forms
from tuskar_ui.infrastructure. \ from tuskar_ui.infrastructure.resource_management.flavor_templates\
resource_management.flavor_templates import tables \ import tables as flavor_templates_tables
as flavor_templates_tables from tuskar_ui.infrastructure.resource_management.racks\
from tuskar_ui.infrastructure. \ import tables as racks_tables
resource_management.racks import tables as racks_tables from tuskar_ui.infrastructure.resource_management import resource_classes
from tuskar_ui.infrastructure. \
resource_management import resource_classes
import tuskar_ui.tables import tuskar_ui.tables
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -102,7 +100,7 @@ class FlavorTemplatesTable(flavor_templates_tables.FlavorTemplatesTable):
max_vms = tuskar_ui.tables.Column("max_vms", max_vms = tuskar_ui.tables.Column("max_vms",
auto='form_widget', auto='form_widget',
verbose_name=_("Max. VMs"), verbose_name=_("Max. VMs"),
form_widget=NumberInput(), form_widget=forms.NumberInput(),
form_widget_attributes={ form_widget_attributes={
'class': "number_input_slim"}) 'class': "number_input_slim"})

View File

@ -12,15 +12,13 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _ # noqa
from horizon import exceptions from horizon import exceptions
from horizon import tabs from horizon import tabs
from tuskar_ui.infrastructure.resource_management. \ from tuskar_ui.infrastructure.resource_management.resource_classes\
resource_classes.tables import RacksTable import tables
from tuskar_ui.infrastructure.resource_management. \
resource_classes.tables import FlavorsTable
class OverviewTab(tabs.Tab): class OverviewTab(tabs.Tab):
@ -36,7 +34,7 @@ class OverviewTab(tabs.Tab):
class RacksTab(tabs.TableTab): class RacksTab(tabs.TableTab):
table_classes = (RacksTable,) table_classes = (tables.RacksTable,)
name = _("Racks") name = _("Racks")
slug = "racks" slug = "racks"
template_name = ("infrastructure/resource_management/resource_classes/" template_name = ("infrastructure/resource_management/resource_classes/"
@ -54,7 +52,7 @@ class RacksTab(tabs.TableTab):
class FlavorsTab(tabs.TableTab): class FlavorsTab(tabs.TableTab):
table_classes = (FlavorsTable,) table_classes = (tables.FlavorsTable,)
name = _("Flavors") name = _("Flavors")
slug = "flavors" slug = "flavors"
template_name = ("infrastructure/resource_management/resource_classes/" template_name = ("infrastructure/resource_management/resource_classes/"

View File

@ -12,9 +12,11 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.core.urlresolvers import reverse from django.core import urlresolvers
from django import http from django import http
from mox import IsA
import mox
from tuskar_ui import api as tuskar from tuskar_ui import api as tuskar
from tuskar_ui.test import helpers as test from tuskar_ui.test import helpers as test
@ -31,17 +33,17 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
all_racks = self.tuskar_racks.list() all_racks = self.tuskar_racks.list()
rc = self.tuskar_resource_classes.first() rc = self.tuskar_resource_classes.first()
tuskar.FlavorTemplate.\ tuskar.FlavorTemplate.list(
list(IsA(http.HttpRequest)).AndReturn(all_templates) mox.IsA(http.HttpRequest)).AndReturn(all_templates)
tuskar.Rack.\ tuskar.Rack.list(
list(IsA(http.HttpRequest), True).AndReturn(all_racks) mox.IsA(http.HttpRequest), True).AndReturn(all_racks)
tuskar.ResourceClass.\ tuskar.ResourceClass.get(
get(IsA(http.HttpRequest), rc.id).AndReturn(rc) mox.IsA(http.HttpRequest), rc.id).AndReturn(rc)
self.mox.ReplayAll() self.mox.ReplayAll()
url = reverse( url = urlresolvers.reverse(
'horizon:infrastructure:resource_management:' 'horizon:infrastructure:resource_management:resource_classes:'
'resource_classes:create') 'create')
res = self.client.get(url) res = self.client.get(url)
self.assertEqual(res.status_code, 200) self.assertEqual(res.status_code, 200)
@ -56,28 +58,32 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
add_racks_ids = [] add_racks_ids = []
tuskar.ResourceClass.list( tuskar.ResourceClass.list(
IsA(http.request.HttpRequest)).AndReturn( mox.IsA(http.request.HttpRequest)).AndReturn(
self.tuskar_resource_classes.list()) self.tuskar_resource_classes.list())
tuskar.ResourceClass.\ tuskar.ResourceClass.create(
create(IsA(http.HttpRequest), name=new_unique_name, mox.IsA(http.HttpRequest),
service_type=new_resource_class.service_type, name=new_unique_name,
flavors=new_flavors).\ service_type=new_resource_class.service_type,
AndReturn(new_resource_class) flavors=new_flavors).AndReturn(new_resource_class)
tuskar.ResourceClass.\ tuskar.ResourceClass.set_racks(mox.IsA(http.HttpRequest),
set_racks(IsA(http.HttpRequest), add_racks_ids) add_racks_ids)
self.mox.ReplayAll() self.mox.ReplayAll()
url = reverse('horizon:infrastructure:resource_management:' url = urlresolvers.reverse(
'resource_classes:create') 'horizon:infrastructure:resource_management:resource_classes:'
'create')
form_data = {'name': new_unique_name, form_data = {'name': new_unique_name,
'service_type': new_resource_class.service_type, 'service_type': new_resource_class.service_type,
'image': 'compute-img'} 'image': 'compute-img'}
res = self.client.post(url, form_data) res = self.client.post(url, form_data)
self.assertNoFormErrors(res) self.assertNoFormErrors(res)
self.assertMessageCount(success=1) self.assertMessageCount(success=1)
self.assertRedirectsNoFollow(res,
("%s?tab=resource_management_tabs__resource_classes_tab" % redirect_url = (
reverse("horizon:infrastructure:resource_management:index"))) "%s?tab=resource_management_tabs__resource_classes_tab" %
urlresolvers.reverse('horizon:infrastructure:'
'resource_management:index'))
self.assertRedirectsNoFollow(res, redirect_url)
@test.create_stubs({tuskar.ResourceClass: ('get', 'list_flavors', @test.create_stubs({tuskar.ResourceClass: ('get', 'list_flavors',
'racks_ids', 'all_racks', 'racks_ids', 'all_racks',
@ -87,9 +93,10 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
all_flavors = [] all_flavors = []
all_racks = [] all_racks = []
tuskar.ResourceClass.\ tuskar.ResourceClass.get(
get(IsA(http.HttpRequest), resource_class.id).MultipleTimes().\ mox.IsA(http.HttpRequest),
AndReturn(resource_class) resource_class.id).MultipleTimes().AndReturn(
resource_class)
self.mox.ReplayAll() self.mox.ReplayAll()
@ -100,9 +107,9 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
tuskar.ResourceClass.all_flavors = all_flavors tuskar.ResourceClass.all_flavors = all_flavors
tuskar.ResourceClass.list_flavors = all_flavors tuskar.ResourceClass.list_flavors = all_flavors
url = reverse( url = urlresolvers.reverse(
'horizon:infrastructure:resource_management:' 'horizon:infrastructure:resource_management:resource_classes:'
'resource_classes:update', 'update',
args=[resource_class.id]) args=[resource_class.id])
res = self.client.get(url) res = self.client.get(url)
self.assertEqual(res.status_code, 200) self.assertEqual(res.status_code, 200)
@ -116,55 +123,58 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
add_racks_ids = [] add_racks_ids = []
tuskar.ResourceClass.get( tuskar.ResourceClass.get(
IsA(http.HttpRequest), mox.IsA(http.HttpRequest), resource_class.id).AndReturn(
resource_class.id).\ resource_class)
AndReturn(resource_class)
tuskar.ResourceClass.list( tuskar.ResourceClass.list(
IsA(http.request.HttpRequest)).AndReturn( mox.IsA(http.request.HttpRequest)).AndReturn(
self.tuskar_resource_classes.list()) self.tuskar_resource_classes.list())
tuskar.ResourceClass.\ tuskar.ResourceClass.update(mox.IsA(http.HttpRequest),
update(IsA(http.HttpRequest), resource_class.id, resource_class.id,
name=resource_class.name, name=resource_class.name,
service_type=resource_class.service_type, service_type=resource_class.service_type,
flavors=[]).\ flavors=[]).AndReturn(resource_class)
AndReturn(resource_class) tuskar.ResourceClass.set_racks(mox.IsA(http.HttpRequest),
tuskar.ResourceClass.\ add_racks_ids)
set_racks(IsA(http.HttpRequest), add_racks_ids)
self.mox.ReplayAll() self.mox.ReplayAll()
form_data = {'resource_class_id': resource_class.id, form_data = {'resource_class_id': resource_class.id,
'name': resource_class.name, 'name': resource_class.name,
'service_type': resource_class.service_type, 'service_type': resource_class.service_type,
'image': 'compute-img'} 'image': 'compute-img'}
url = reverse('horizon:infrastructure:resource_management:' url = urlresolvers.reverse(
'resource_classes:update', args=[resource_class.id]) 'horizon:infrastructure:resource_management:resource_classes:'
'update',
args=[resource_class.id])
res = self.client.post(url, form_data) res = self.client.post(url, form_data)
self.assertNoFormErrors(res) self.assertNoFormErrors(res)
self.assertMessageCount(success=1) self.assertMessageCount(success=1)
self.assertRedirectsNoFollow(res,
("%s?tab=resource_management_tabs__resource_classes_tab" % redirect_url = (
reverse("horizon:infrastructure:resource_management:index"))) "%s?tab=resource_management_tabs__resource_classes_tab" %
urlresolvers.reverse('horizon:infrastructure:'
'resource_management:index'))
self.assertRedirectsNoFollow(res, redirect_url)
@test.create_stubs({tuskar.ResourceClass: ('delete', 'list')}) @test.create_stubs({tuskar.ResourceClass: ('delete', 'list')})
def test_delete_resource_class(self): def test_delete_resource_class(self):
resource_class = self.tuskar_resource_classes.first() resource_class = self.tuskar_resource_classes.first()
all_resource_classes = self.tuskar_resource_classes.list() all_resource_classes = self.tuskar_resource_classes.list()
tuskar.ResourceClass.delete( tuskar.ResourceClass.delete(mox.IsA(http.HttpRequest),
IsA(http.HttpRequest), resource_class.id)
resource_class.id)
tuskar.ResourceClass.list( tuskar.ResourceClass.list(
IsA(http.HttpRequest)).\ mox.IsA(http.HttpRequest)).AndReturn(all_resource_classes)
AndReturn(all_resource_classes)
self.mox.ReplayAll() self.mox.ReplayAll()
form_data = {'action': form_data = {'action':
'resource_classes__delete__%s' % resource_class.id} 'resource_classes__delete__%s' % resource_class.id}
res = self.client.post( url = urlresolvers.reverse(
reverse('horizon:infrastructure:resource_management:index'), 'horizon:infrastructure:resource_management:index')
form_data) res = self.client.post(url, form_data)
self.assertRedirectsNoFollow(
res, reverse('horizon:infrastructure:resource_management:index')) redirect_url = urlresolvers.reverse(
'horizon:infrastructure:resource_management:index')
self.assertRedirectsNoFollow(res, redirect_url)
@test.create_stubs({ @test.create_stubs({
tuskar.ResourceClass: ('get', 'list_flavors', 'list_racks') tuskar.ResourceClass: ('get', 'list_flavors', 'list_racks')
@ -175,16 +185,17 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
racks = [] racks = []
tuskar.ResourceClass.get( tuskar.ResourceClass.get(
IsA(http.HttpRequest), mox.IsA(http.HttpRequest), resource_class.id).\
resource_class.id).\ MultipleTimes().AndReturn(resource_class)
MultipleTimes().AndReturn(resource_class)
self.mox.ReplayAll() self.mox.ReplayAll()
tuskar.ResourceClass.list_flavors = flavors tuskar.ResourceClass.list_flavors = flavors
tuskar.ResourceClass.list_racks = racks tuskar.ResourceClass.list_racks = racks
url = reverse('horizon:infrastructure:resource_management:' url = urlresolvers.reverse(
'resource_classes:detail', args=[resource_class.id]) 'horizon:infrastructure:resource_management:resource_classes:'
'detail',
args=[resource_class.id])
res = self.client.get(url) res = self.client.get(url)
self.assertItemsEqual(res.context['flavors_table'].data, self.assertItemsEqual(res.context['flavors_table'].data,
flavors) flavors)
@ -202,9 +213,9 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
all_flavors = [] all_flavors = []
all_racks = [] all_racks = []
tuskar.ResourceClass.\ tuskar.ResourceClass.get(mox.IsA(http.HttpRequest),
get(IsA(http.HttpRequest), resource_class.id).\ resource_class.id).\
MultipleTimes().AndReturn(resource_class) MultipleTimes().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
@ -214,9 +225,9 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
tuskar.ResourceClass.all_flavors = all_flavors tuskar.ResourceClass.all_flavors = all_flavors
tuskar.ResourceClass.list_flavors = all_flavors tuskar.ResourceClass.list_flavors = all_flavors
url = reverse( url = urlresolvers.reverse(
'horizon:infrastructure:resource_management:' 'horizon:infrastructure:resource_management:resource_classes:'
'resource_classes:update_racks', 'update_racks',
args=[resource_class.id]) args=[resource_class.id])
res = self.client.get(url) res = self.client.get(url)
self.assertEqual(res.status_code, 200) self.assertEqual(res.status_code, 200)
@ -230,37 +241,37 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
add_racks_ids = [] add_racks_ids = []
tuskar.ResourceClass.get( tuskar.ResourceClass.get(
IsA(http.HttpRequest), mox.IsA(http.HttpRequest), resource_class.id).AndReturn(
resource_class.id).\ resource_class)
AndReturn(resource_class)
tuskar.ResourceClass.list( tuskar.ResourceClass.list(
IsA(http.request.HttpRequest)).AndReturn( mox.IsA(http.request.HttpRequest)).AndReturn(
self.tuskar_resource_classes.list()) self.tuskar_resource_classes.list())
tuskar.ResourceClass.\ tuskar.ResourceClass.update(mox.IsA(http.HttpRequest),
update(IsA(http.HttpRequest), resource_class.id, resource_class.id,
name=resource_class.name, name=resource_class.name,
service_type=resource_class.service_type, service_type=resource_class.service_type,
flavors=[]).\ flavors=[]).AndReturn(resource_class)
AndReturn(resource_class) tuskar.ResourceClass.set_racks(mox.IsA(http.HttpRequest),
tuskar.ResourceClass.\ add_racks_ids)
set_racks(IsA(http.HttpRequest), add_racks_ids)
self.mox.ReplayAll() self.mox.ReplayAll()
form_data = {'resource_class_id': resource_class.id, form_data = {'resource_class_id': resource_class.id,
'name': resource_class.name, 'name': resource_class.name,
'service_type': resource_class.service_type, 'service_type': resource_class.service_type,
'image': 'compute-img'} 'image': 'compute-img'}
url = reverse('horizon:infrastructure:resource_management:' url = urlresolvers.reverse(
'resource_classes:update_racks', 'horizon:infrastructure:resource_management:resource_classes:'
args=[resource_class.id]) 'update_racks',
args=[resource_class.id])
res = self.client.post(url, form_data) res = self.client.post(url, form_data)
self.assertNoFormErrors(res) self.assertNoFormErrors(res)
self.assertMessageCount(success=1) self.assertMessageCount(success=1)
detail_url = "horizon:infrastructure:resource_management:"\ detail_url = ('horizon:infrastructure:resource_management:'
"resource_classes:detail" 'resource_classes:detail')
redirect_url = "%s?tab=resource_class_details__racks" % ( redirect_url = (
reverse(detail_url, args=(resource_class.id,))) "%s?tab=resource_class_details__racks" %
urlresolvers.reverse(detail_url, args=(resource_class.id,)))
self.assertRedirectsNoFollow(res, redirect_url) self.assertRedirectsNoFollow(res, redirect_url)
@test.create_stubs({tuskar.ResourceClass: ('get', 'list_flavors', @test.create_stubs({tuskar.ResourceClass: ('get', 'list_flavors',
@ -271,9 +282,9 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
all_flavors = [] all_flavors = []
all_racks = [] all_racks = []
tuskar.ResourceClass.\ tuskar.ResourceClass.get(mox.IsA(http.HttpRequest),
get(IsA(http.HttpRequest), resource_class.id).\ resource_class.id).\
MultipleTimes().AndReturn(resource_class) MultipleTimes().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
@ -283,9 +294,9 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
tuskar.ResourceClass.all_flavors = all_flavors tuskar.ResourceClass.all_flavors = all_flavors
tuskar.ResourceClass.list_flavors = all_flavors tuskar.ResourceClass.list_flavors = all_flavors
url = reverse( url = urlresolvers.reverse(
'horizon:infrastructure:resource_management:' 'horizon:infrastructure:resource_management:resource_classes:'
'resource_classes:update_flavors', 'update_flavors',
args=[resource_class.id]) args=[resource_class.id])
res = self.client.get(url) res = self.client.get(url)
self.assertEqual(res.status_code, 200) self.assertEqual(res.status_code, 200)
@ -299,37 +310,36 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
add_racks_ids = [] add_racks_ids = []
tuskar.ResourceClass.get( tuskar.ResourceClass.get(
IsA(http.HttpRequest), mox.IsA(http.HttpRequest), resource_class.id).AndReturn(
resource_class.id).\ resource_class)
AndReturn(resource_class)
tuskar.ResourceClass.list( tuskar.ResourceClass.list(
IsA(http.request.HttpRequest)).AndReturn( mox.IsA(http.request.HttpRequest)).AndReturn(
self.tuskar_resource_classes.list()) self.tuskar_resource_classes.list())
tuskar.ResourceClass.\ tuskar.ResourceClass.update(mox.IsA(http.HttpRequest),
update(IsA(http.HttpRequest), resource_class.id, resource_class.id,
name=resource_class.name, name=resource_class.name,
service_type=resource_class.service_type, service_type=resource_class.service_type,
flavors=[]).\ flavors=[]).AndReturn(resource_class)
AndReturn(resource_class) tuskar.ResourceClass.set_racks(mox.IsA(http.HttpRequest),
tuskar.ResourceClass.\ add_racks_ids)
set_racks(IsA(http.HttpRequest), add_racks_ids)
self.mox.ReplayAll() self.mox.ReplayAll()
form_data = {'resource_class_id': resource_class.id, form_data = {'resource_class_id': resource_class.id,
'name': resource_class.name, 'name': resource_class.name,
'service_type': resource_class.service_type, 'service_type': resource_class.service_type,
'image': 'compute-img'} 'image': 'compute-img'}
url = reverse('horizon:infrastructure:resource_management:' url = urlresolvers.reverse(
'resource_classes:update_flavors', 'horizon:infrastructure:resource_management:resource_classes:'
args=[resource_class.id]) 'update_flavors',
args=[resource_class.id])
res = self.client.post(url, form_data) res = self.client.post(url, form_data)
self.assertNoFormErrors(res) self.assertNoFormErrors(res)
self.assertMessageCount(success=1) self.assertMessageCount(success=1)
redirect_url = "horizon:infrastructure:resource_management:"\ redirect_url = ('horizon:infrastructure:resource_management:'
"resource_classes:detail" 'resource_classes:detail')
redirect_url = "%s?tab=resource_class_details__flavors" % ( redirect_url = "%s?tab=resource_class_details__flavors" % (
reverse(redirect_url, args=(resource_class.id,))) urlresolvers.reverse(redirect_url, args=(resource_class.id,)))
self.assertRedirectsNoFollow(res, redirect_url) self.assertRedirectsNoFollow(res, redirect_url)
# def test_detail_get_exception(self): # def test_detail_get_exception(self):

View File

@ -12,48 +12,41 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.conf.urls.defaults import include from django.conf.urls import defaults
from django.conf.urls.defaults import patterns
from django.conf.urls.defaults import url
from tuskar_ui.infrastructure. \ from tuskar_ui.infrastructure.resource_management.flavors\
resource_management.resource_classes.views import CreateView import urls as flavor_urls
from tuskar_ui.infrastructure. \ from tuskar_ui.infrastructure.resource_management.resource_classes import views
resource_management.resource_classes.views import DetailActionView
from tuskar_ui.infrastructure. \
resource_management.resource_classes.views import DetailUpdateView
from tuskar_ui.infrastructure. \
resource_management.resource_classes.views import DetailView
from tuskar_ui.infrastructure. \
resource_management.resource_classes.views import UpdateFlavorsView
from tuskar_ui.infrastructure. \
resource_management.resource_classes.views import UpdateRacksView
from tuskar_ui.infrastructure. \
resource_management.resource_classes.views import UpdateView
from tuskar_ui.infrastructure. \
resource_management.flavors import urls as flavor_urls
RESOURCE_CLASS = r'^(?P<resource_class_id>[^/]+)/%s$' RESOURCE_CLASS = r'^(?P<resource_class_id>[^/]+)/%s$'
VIEW_MOD = 'tuskar_ui.infrastructure.' \ VIEW_MOD = ('tuskar_ui.infrastructure.resource_management.resource_classes.'
'resource_management.resource_classes.views' 'views')
urlpatterns = patterns( urlpatterns = defaults.patterns(
VIEW_MOD, VIEW_MOD,
url(r'^create/$', CreateView.as_view(), name='create'), defaults.url(r'^create/$', views.CreateView.as_view(), name='create'),
url(r'^(?P<resource_class_id>[^/]+)/$', defaults.url(r'^(?P<resource_class_id>[^/]+)/$',
DetailView.as_view(), name='detail'), views.DetailView.as_view(),
url(RESOURCE_CLASS % 'update', UpdateView.as_view(), name='update'), name='detail'),
url(RESOURCE_CLASS % 'detail_action', DetailActionView.as_view(), defaults.url(RESOURCE_CLASS % 'update',
name='detail_action'), views.UpdateView.as_view(),
url(RESOURCE_CLASS % 'detail_update', DetailUpdateView.as_view(), name='update'),
name='detail_update'), defaults.url(RESOURCE_CLASS % 'detail_action',
url(RESOURCE_CLASS % 'update_racks', UpdateRacksView.as_view(), views.DetailActionView.as_view(),
name='update_racks'), name='detail_action'),
url(RESOURCE_CLASS % 'update_flavors', UpdateFlavorsView.as_view(), defaults.url(RESOURCE_CLASS % 'detail_update',
name='update_flavors'), views.DetailUpdateView.as_view(),
url(RESOURCE_CLASS % 'rack_health.json', 'rack_health', name='detail_update'),
name='rack_health'), defaults.url(RESOURCE_CLASS % 'update_racks',
url(r'^(?P<resource_class_id>[^/]+)/flavors/', views.UpdateRacksView.as_view(),
include(flavor_urls, namespace='flavors')), name='update_racks'),
defaults.url(RESOURCE_CLASS % 'update_flavors',
views.UpdateFlavorsView.as_view(),
name='update_flavors'),
defaults.url(RESOURCE_CLASS % 'rack_health.json',
'rack_health',
name='rack_health'),
defaults.url(r'^(?P<resource_class_id>[^/]+)/flavors/',
defaults.include(flavor_urls, namespace='flavors')),
) )

View File

@ -18,46 +18,36 @@ Views for managing resource classes
import logging import logging
import random import random
from django.core.urlresolvers import reverse from django.core import urlresolvers
from django.http import HttpResponse import django.http
from django.utils import simplejson from django.utils import simplejson
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _ # noqa
from horizon import exceptions from horizon import exceptions
from horizon import forms from horizon import forms as horizon_forms
from horizon import tabs from horizon import tabs as horizon_tabs
from horizon import workflows from horizon import workflows as horizon_workflows
from tuskar_ui import api as tuskar from tuskar_ui import api as tuskar
from tuskar_ui.infrastructure. \ from tuskar_ui.infrastructure.resource_management.resource_classes import forms
resource_management.resource_classes.forms import DeleteForm from tuskar_ui.infrastructure.resource_management.resource_classes import tabs
from tuskar_ui.infrastructure. \ from tuskar_ui.infrastructure.resource_management.resource_classes\
resource_management.resource_classes.tabs import ResourceClassDetailTabs import workflows
from tuskar_ui.infrastructure. \
resource_management.resource_classes.workflows import CreateResourceClass
from tuskar_ui.infrastructure. \
resource_management.resource_classes.workflows import DetailUpdateWorkflow
from tuskar_ui.infrastructure. \
resource_management.resource_classes.workflows import UpdateFlavorsWorkflow
from tuskar_ui.infrastructure. \
resource_management.resource_classes.workflows import UpdateRacksWorkflow
from tuskar_ui.infrastructure. \
resource_management.resource_classes.workflows import UpdateResourceClass
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
class CreateView(workflows.WorkflowView): class CreateView(horizon_workflows.WorkflowView):
workflow_class = CreateResourceClass workflow_class = workflows.CreateResourceClass
def get_initial(self): def get_initial(self):
pass pass
class UpdateView(workflows.WorkflowView): class UpdateView(horizon_workflows.WorkflowView):
workflow_class = UpdateResourceClass workflow_class = workflows.UpdateResourceClass
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(UpdateView, self).get_context_data(**kwargs) context = super(UpdateView, self).get_context_data(**kwargs)
@ -87,19 +77,19 @@ class UpdateView(workflows.WorkflowView):
class DetailUpdateView(UpdateView): class DetailUpdateView(UpdateView):
workflow_class = DetailUpdateWorkflow workflow_class = workflows.DetailUpdateWorkflow
class UpdateRacksView(UpdateView): class UpdateRacksView(UpdateView):
workflow_class = UpdateRacksWorkflow workflow_class = workflows.UpdateRacksWorkflow
class UpdateFlavorsView(UpdateView): class UpdateFlavorsView(UpdateView):
workflow_class = UpdateFlavorsWorkflow workflow_class = workflows.UpdateFlavorsWorkflow
class DetailView(tabs.TabView): class DetailView(horizon_tabs.TabView):
tab_group_class = ResourceClassDetailTabs tab_group_class = tabs.ResourceClassDetailTabs
template_name = ('infrastructure/resource_management/resource_classes/' template_name = ('infrastructure/resource_management/resource_classes/'
'detail.html') 'detail.html')
@ -115,8 +105,8 @@ class DetailView(tabs.TabView):
resource_class = tuskar.ResourceClass.get(self.request, resource_class = tuskar.ResourceClass.get(self.request,
resource_class_id) resource_class_id)
except Exception: except Exception:
redirect = reverse('horizon:infrastructure:' redirect = urlresolvers.reverse('horizon:infrastructure:'
'resource_management:index') 'resource_management:index')
exceptions.handle(self.request, exceptions.handle(self.request,
_('Unable to retrieve details for ' _('Unable to retrieve details for '
'resource class "%s".') 'resource class "%s".')
@ -131,7 +121,7 @@ class DetailView(tabs.TabView):
**kwargs) **kwargs)
class DetailActionView(forms.ModalFormView): class DetailActionView(horizon_forms.ModalFormView):
template_name = ('infrastructure/resource_management/' template_name = ('infrastructure/resource_management/'
'resource_classes/action.html') 'resource_classes/action.html')
@ -142,7 +132,7 @@ class DetailActionView(forms.ModalFormView):
try: try:
action = self.request.GET.get('action') action = self.request.GET.get('action')
if action == "delete": if action == "delete":
form_class = DeleteForm form_class = forms.DeleteForm
return form_class(self.request, **self.get_form_kwargs()) return form_class(self.request, **self.get_form_kwargs())
except Exception: except Exception:
@ -150,7 +140,8 @@ class DetailActionView(forms.ModalFormView):
def get_success_url(self): def get_success_url(self):
# FIXME this should be set on form level # FIXME this should be set on form level
return reverse("horizon:infrastructure:resource_management:index") return urlresolvers.reverse('horizon:infrastructure:'
'resource_management:index')
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(DetailActionView, self).get_context_data(**kwargs) context = super(DetailActionView, self).get_context_data(**kwargs)
@ -201,5 +192,5 @@ def rack_health(request, resource_class_id=None):
data.sort(key=lambda x: x['percentage']) data.sort(key=lambda x: x['percentage'])
res = {'data': data} res = {'data': data}
return HttpResponse(simplejson.dumps(res), return django.http.HttpResponse(simplejson.dumps(res),
mimetype="application/json") mimetype="application/json")

View File

@ -13,8 +13,8 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.core.urlresolvers import reverse from django.core import urlresolvers
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _ # noqa
from horizon import exceptions from horizon import exceptions
from horizon import forms from horizon import forms
@ -25,10 +25,8 @@ import tuskar_ui.workflows
import re import re
from tuskar_ui.infrastructure. \ from tuskar_ui.infrastructure.resource_management.resource_classes\
resource_management.resource_classes.tables import FlavorTemplatesTable import tables
from tuskar_ui.infrastructure. \
resource_management.resource_classes.tables import RacksTable
class ResourceClassInfoAndFlavorsAction(workflows.Action): class ResourceClassInfoAndFlavorsAction(workflows.Action):
@ -85,7 +83,7 @@ class ResourceClassInfoAndFlavorsAction(workflows.Action):
class CreateResourceClassInfoAndFlavors(tuskar_ui.workflows.TableStep): class CreateResourceClassInfoAndFlavors(tuskar_ui.workflows.TableStep):
table_classes = (FlavorTemplatesTable,) table_classes = (tables.FlavorTemplatesTable,)
action_class = ResourceClassInfoAndFlavorsAction action_class = ResourceClassInfoAndFlavorsAction
template_name = 'infrastructure/resource_management/resource_classes/'\ template_name = 'infrastructure/resource_management/resource_classes/'\
@ -141,7 +139,7 @@ class RacksAction(workflows.Action):
class CreateRacks(tuskar_ui.workflows.TableStep): class CreateRacks(tuskar_ui.workflows.TableStep):
table_classes = (RacksTable,) table_classes = (tables.RacksTable,)
action_class = RacksAction action_class = RacksAction
contributes = ("racks_object_ids") contributes = ("racks_object_ids")
@ -189,7 +187,8 @@ class ResourceClassWorkflowMixin:
def get_index_url(self): def get_index_url(self):
"""This url is used both as success and failure url""" """This url is used both as success and failure url"""
return "%s?tab=resource_management_tabs__resource_classes_tab" %\ return "%s?tab=resource_management_tabs__resource_classes_tab" %\
reverse("horizon:infrastructure:resource_management:index") urlresolvers.reverse('horizon:infrastructure:resource_management:'
'index')
def get_success_url(self): def get_success_url(self):
return self.get_index_url() return self.get_index_url()
@ -303,7 +302,8 @@ class DetailUpdateWorkflow(UpdateResourceClass):
url = "horizon:infrastructure:resource_management:resource_classes:"\ url = "horizon:infrastructure:resource_management:resource_classes:"\
"detail" "detail"
return "%s?tab=resource_class_details__overview" % ( return "%s?tab=resource_class_details__overview" % (
reverse(url, args=(self.context["resource_class_id"]))) urlresolvers.reverse(url,
args=(self.context["resource_class_id"])))
class UpdateRacksWorkflow(UpdateResourceClass): class UpdateRacksWorkflow(UpdateResourceClass):
@ -312,7 +312,8 @@ class UpdateRacksWorkflow(UpdateResourceClass):
url = "horizon:infrastructure:resource_management:resource_classes:"\ url = "horizon:infrastructure:resource_management:resource_classes:"\
"detail" "detail"
return "%s?tab=resource_class_details__racks" % ( return "%s?tab=resource_class_details__racks" % (
reverse(url, args=(self.context["resource_class_id"]))) urlresolvers.reverse(url,
args=(self.context["resource_class_id"])))
class UpdateFlavorsWorkflow(UpdateResourceClass): class UpdateFlavorsWorkflow(UpdateResourceClass):
@ -321,4 +322,5 @@ class UpdateFlavorsWorkflow(UpdateResourceClass):
url = "horizon:infrastructure:resource_management:resource_classes:"\ url = "horizon:infrastructure:resource_management:resource_classes:"\
"detail" "detail"
return "%s?tab=resource_class_details__flavors" % ( return "%s?tab=resource_class_details__flavors" % (
reverse(url, args=(self.context["resource_class_id"]))) urlresolvers.reverse(url,
args=(self.context["resource_class_id"])))

View File

@ -12,22 +12,22 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _ # noqa
from horizon import exceptions from horizon import exceptions
from horizon import tabs from horizon import tabs
from tuskar_ui import api as tuskar from tuskar_ui import api as tuskar
from tuskar_ui.infrastructure. \ from tuskar_ui.infrastructure.resource_management.flavor_templates\
resource_management.flavor_templates.tables import FlavorTemplatesTable import tables as flavor_templates_tables
from tuskar_ui.infrastructure. \ from tuskar_ui.infrastructure.resource_management.racks\
resource_management.racks.tables import RacksTable import tables as racks_tables
from tuskar_ui.infrastructure. \ from tuskar_ui.infrastructure.resource_management.resource_classes\
resource_management.resource_classes.tables import ResourceClassesTable import tables as resource_classes_tables
class RacksTab(tabs.TableTab): class RacksTab(tabs.TableTab):
table_classes = (RacksTable,) table_classes = (racks_tables.RacksTable,)
name = _("Racks") name = _("Racks")
slug = "racks_tab" slug = "racks_tab"
template_name = ("infrastructure/resource_management/" template_name = ("infrastructure/resource_management/"
@ -54,7 +54,7 @@ class RacksTab(tabs.TableTab):
class FlavorTemplatesTab(tabs.TableTab): class FlavorTemplatesTab(tabs.TableTab):
table_classes = (FlavorTemplatesTable,) table_classes = (flavor_templates_tables.FlavorTemplatesTable,)
name = _("Flavor Templates") name = _("Flavor Templates")
slug = "flavor_templates_tab" slug = "flavor_templates_tab"
template_name = "horizon/common/_detail_table.html" template_name = "horizon/common/_detail_table.html"
@ -70,7 +70,7 @@ class FlavorTemplatesTab(tabs.TableTab):
class ResourceClassesTab(tabs.TableTab): class ResourceClassesTab(tabs.TableTab):
table_classes = (ResourceClassesTable,) table_classes = (resource_classes_tables.ResourceClassesTable,)
name = _("Classes") name = _("Classes")
slug = "resource_classes_tab" slug = "resource_classes_tab"
template_name = "horizon/common/_detail_table.html" template_name = "horizon/common/_detail_table.html"

View File

@ -12,10 +12,10 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.core.urlresolvers import reverse from django.core import urlresolvers
from django import http from django import http
from mox import IsA import mox
from tuskar_ui import api as tuskar from tuskar_ui import api as tuskar
from tuskar_ui.test import helpers as test from tuskar_ui.test import helpers as test
@ -49,31 +49,32 @@ class ResourceManagementTests(test.BaseAdminViewTests):
tuskar.ResourceClass.list_racks = racks tuskar.ResourceClass.list_racks = racks
tuskar.ResourceClass.list( tuskar.ResourceClass.list(
IsA(http.HttpRequest)).\ mox.IsA(http.HttpRequest)).\
AndReturn(resource_classes) AndReturn(resource_classes)
tuskar.ResourceClass.get( tuskar.ResourceClass.get(
IsA(http.HttpRequest), resource_class.id).\ mox.IsA(http.HttpRequest), resource_class.id).\
AndReturn(resource_class) AndReturn(resource_class)
# ResourceClass stubs end # ResourceClass stubs end
# Rack stubs # Rack stubs
racks = self.tuskar_racks.list() racks = self.tuskar_racks.list()
tuskar.Rack.list(IsA(http.HttpRequest)).AndReturn(racks) tuskar.Rack.list(mox.IsA(http.HttpRequest)).AndReturn(racks)
tuskar.Node.list(IsA(http.HttpRequest)).AndReturn(nodes) tuskar.Node.list(mox.IsA(http.HttpRequest)).AndReturn(nodes)
# Rack stubs end # Rack stubs end
# FlavorTemplate stubs # FlavorTemplate stubs
flavors = self.tuskar_flavors.list() flavors = self.tuskar_flavors.list()
tuskar.FlavorTemplate.list(IsA(http.HttpRequest)).AndReturn( tuskar.FlavorTemplate.list(mox.IsA(http.HttpRequest)).AndReturn(
flavors) flavors)
# FlavorTemplate stubs end # FlavorTemplate stubs end
self.mox.ReplayAll() self.mox.ReplayAll()
url = reverse('horizon:infrastructure:resource_management:index') url = urlresolvers.reverse(
'horizon:infrastructure:resource_management:index')
res = self.client.get(url) res = self.client.get(url)
self.assertTemplateUsed( self.assertTemplateUsed(
res, 'infrastructure/resource_management/index.html') res, 'infrastructure/resource_management/index.html')

View File

@ -12,27 +12,26 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.conf.urls.defaults import include from django.conf.urls import defaults
from django.conf.urls.defaults import patterns
from django.conf.urls.defaults import url
from tuskar_ui.infrastructure. \ from tuskar_ui.infrastructure.resource_management.flavor_templates\
resource_management.flavor_templates import urls as flavor_template_urls import urls as flavor_template_urls
from tuskar_ui.infrastructure. \ from tuskar_ui.infrastructure.resource_management.nodes\
resource_management.nodes import urls as node_urls import urls as node_urls
from tuskar_ui.infrastructure. \ from tuskar_ui.infrastructure.resource_management.racks\
resource_management.racks import urls as rack_urls import urls as rack_urls
from tuskar_ui.infrastructure. \ from tuskar_ui.infrastructure.resource_management.resource_classes\
resource_management.resource_classes import urls as resource_classes_urls import urls as resource_classes_urls
from tuskar_ui.infrastructure. \ from tuskar_ui.infrastructure.resource_management import views
resource_management.views import IndexView
urlpatterns = patterns('', urlpatterns = defaults.patterns('',
url(r'^$', IndexView.as_view(), name='index'), defaults.url(r'^$', views.IndexView.as_view(), name='index'),
url(r'flavor_templates/', include(flavor_template_urls, defaults.url(r'flavor_templates/',
namespace='flavor_templates')), defaults.include(flavor_template_urls,
url(r'racks/', include(rack_urls, namespace='racks')), namespace='flavor_templates')),
url(r'resource_classes/', defaults.url(r'racks/', defaults.include(rack_urls, namespace='racks')),
include(resource_classes_urls, namespace='resource_classes')), defaults.url(r'resource_classes/',
url(r'nodes/', include(node_urls, namespace='nodes')), defaults.include(resource_classes_urls,
namespace='resource_classes')),
defaults.url(r'nodes/', defaults.include(node_urls, namespace='nodes')),
) )

View File

@ -17,12 +17,11 @@ Views for Resource Management.
""" """
from horizon import tabs from horizon import tabs as horizon_tabs
from tuskar_ui.infrastructure. \ from tuskar_ui.infrastructure.resource_management import tabs
resource_management.tabs import ResourceManagementTabs
class IndexView(tabs.TabbedTableView): class IndexView(horizon_tabs.TabbedTableView):
tab_group_class = ResourceManagementTabs tab_group_class = tabs.ResourceManagementTabs
template_name = 'infrastructure/resource_management/index.html' template_name = 'infrastructure/resource_management/index.html'

View File

@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _ # noqa
import horizon import horizon

View File

@ -12,13 +12,11 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from django.conf.urls.defaults import patterns from django.conf.urls import defaults
from django.conf.urls.defaults import url
from tuskar_ui.infrastructure. \ from tuskar_ui.infrastructure.service_management import views
service_management.views import IndexView
urlpatterns = patterns('', urlpatterns = defaults.patterns('',
url(r'^$', IndexView.as_view(), name='index'), defaults.url(r'^$', views.IndexView.as_view(), name='index'),
) )

View File

@ -14,22 +14,22 @@
import copy import copy
import logging import logging
from operator import attrgetter import operator
import sys import sys
from django import forms from django import forms
from django.http import HttpResponse import django.http
from django import template from django import template
from django.utils.datastructures import SortedDict from django.utils import datastructures
from django.utils.html import escape from django.utils import html
from django.utils import http from django.utils import http
from django.utils import termcolors from django.utils import termcolors
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _ # noqa
from horizon import conf from horizon import conf
from horizon import exceptions from horizon import exceptions
from horizon import messages from horizon import messages
from horizon.tables.actions import LinkAction from horizon.tables import actions as table_actions
from horizon.tables import base as horizon_tables from horizon.tables import base as horizon_tables
@ -128,7 +128,7 @@ class Row(horizon_tables.Row):
data = column.get_data(datum) data = column.get_data(datum)
cell = horizon_tables.Cell(datum, data, column, self) cell = horizon_tables.Cell(datum, data, column, self)
cells.append((column.name or column.auto, cell)) cells.append((column.name or column.auto, cell))
self.cells = SortedDict(cells) self.cells = datastructures.SortedDict(cells)
if self.ajax: if self.ajax:
interval = conf.HORIZON_CONFIG['ajax_poll_interval'] interval = conf.HORIZON_CONFIG['ajax_poll_interval']
@ -147,7 +147,7 @@ class Row(horizon_tables.Row):
# Add the row's display name if available # Add the row's display name if available
display_name = table.get_object_display(datum) display_name = table.get_object_display(datum)
if display_name: if display_name:
self.attrs['data-display'] = escape(display_name) self.attrs['data-display'] = html.escape(display_name)
class DataTableOptions(horizon_tables.DataTableOptions): class DataTableOptions(horizon_tables.DataTableOptions):
@ -185,7 +185,7 @@ class DataTableMetaclass(type):
for base in bases[::-1]: for base in bases[::-1]:
if hasattr(base, 'base_columns'): if hasattr(base, 'base_columns'):
columns = base.base_columns.items() + columns columns = base.base_columns.items() + columns
attrs['base_columns'] = SortedDict(columns) attrs['base_columns'] = datastructures.SortedDict(columns)
# If the table is in a ResourceBrowser, the column number must meet # If the table is in a ResourceBrowser, the column number must meet
# these limits because of the width of the browser. # these limits because of the width of the browser.
@ -218,15 +218,15 @@ class DataTableMetaclass(type):
actions_column.classes.append('actions_column') actions_column.classes.append('actions_column')
columns.append(("actions", actions_column)) columns.append(("actions", actions_column))
# Store this set of columns internally so we can copy them per-instance # Store this set of columns internally so we can copy them per-instance
attrs['_columns'] = SortedDict(columns) attrs['_columns'] = datastructures.SortedDict(columns)
# Gather and register actions for later access since we only want # Gather and register actions for later access since we only want
# to instantiate them once. # to instantiate them once.
# (list() call gives deterministic sort order, which sets don't have.) # (list() call gives deterministic sort order, which sets don't have.)
actions = list(set(opts.row_actions) | set(opts.table_actions)) actions = list(set(opts.row_actions) | set(opts.table_actions))
actions.sort(key=attrgetter('name')) actions.sort(key=operator.attrgetter('name'))
actions_dict = SortedDict([(action.name, action()) actions_dict = datastructures.SortedDict([(action.name, action())
for action in actions]) for action in actions])
attrs['base_actions'] = actions_dict attrs['base_actions'] = actions_dict
if opts._filter_action: if opts._filter_action:
# Replace our filter action with the instantiated version # Replace our filter action with the instantiated version
@ -278,7 +278,7 @@ class DataTable(object):
column = copy.copy(_column) column = copy.copy(_column)
column.table = self column.table = self
columns.append((key, column)) columns.append((key, column))
self.columns = SortedDict(columns) self.columns = datastructures.SortedDict(columns)
self._populate_data_cache() self._populate_data_cache()
# Associate these actions with this table # Associate these actions with this table
@ -455,7 +455,7 @@ class DataTable(object):
# Hook for modifying actions based on data. No-op by default. # Hook for modifying actions based on data. No-op by default.
bound_action.update(self.request, datum) bound_action.update(self.request, datum)
# Pre-create the URL for this link with appropriate parameters # Pre-create the URL for this link with appropriate parameters
if issubclass(bound_action.__class__, LinkAction): if issubclass(bound_action.__class__, table_actions.LinkAction):
bound_action.bound_url = bound_action.get_link_url(datum) bound_action.bound_url = bound_action.get_link_url(datum)
bound_actions.append(bound_action) bound_actions.append(bound_action)
return bound_actions return bound_actions
@ -573,9 +573,10 @@ class DataTable(object):
error = exceptions.handle(request, ignore=True) error = exceptions.handle(request, ignore=True)
if request.is_ajax(): if request.is_ajax():
if not error: if not error:
return HttpResponse(new_row.render()) return django.http.HttpResponse(new_row.render())
else: else:
return HttpResponse(status=error.status_code) return django.http.HttpResponse(
status=error.status_code)
preemptive_actions = [action for action in preemptive_actions = [action for action in
self.base_actions.values() if action.preempt] self.base_actions.values() if action.preempt]

View File

@ -16,12 +16,7 @@ from __future__ import absolute_import
from novaclient.v1_1.contrib import baremetal from novaclient.v1_1.contrib import baremetal
from tuskar_ui.api import Capacity from tuskar_ui import api
from tuskar_ui.api import Flavor
from tuskar_ui.api import FlavorTemplate
from tuskar_ui.api import Node
from tuskar_ui.api import Rack
from tuskar_ui.api import ResourceClass
from tuskar_ui.test import helpers as test from tuskar_ui.test import helpers as test
@ -40,8 +35,8 @@ class TuskarApiTests(test.APITestCase):
'limit': 21}).AndReturn([]) 'limit': 21}).AndReturn([])
self.mox.ReplayAll() self.mox.ReplayAll()
ret_val = Node.get(self.request, node.id) ret_val = api.Node.get(self.request, node.id)
self.assertIsInstance(ret_val, Node) self.assertIsInstance(ret_val, api.Node)
def test_node_create(self): def test_node_create(self):
node = self.baremetalclient_nodes.first() node = self.baremetalclient_nodes.first()
@ -58,17 +53,17 @@ class TuskarApiTests(test.APITestCase):
0).AndReturn(node) 0).AndReturn(node)
self.mox.ReplayAll() self.mox.ReplayAll()
ret_val = Node.create(self.request, ret_val = api.Node.create(self.request,
name='node', name='node',
cpus=1, cpus=1,
memory_mb=1024, memory_mb=1024,
local_gb=10, local_gb=10,
prov_mac_address='aa:bb:cc:dd:ee', prov_mac_address='aa:bb:cc:dd:ee',
pm_address='0.0.0.0', pm_address='0.0.0.0',
pm_user='user', pm_user='user',
pm_password='password', pm_password='password',
terminal_port=0) terminal_port=0)
self.assertIsInstance(ret_val, Node) self.assertIsInstance(ret_val, api.Node)
def test_node_list(self): def test_node_list(self):
nodes = self.baremetalclient_nodes_all.list() nodes = self.baremetalclient_nodes_all.list()
@ -77,9 +72,9 @@ class TuskarApiTests(test.APITestCase):
baremetal.BareMetalNodeManager.list().AndReturn(nodes) baremetal.BareMetalNodeManager.list().AndReturn(nodes)
self.mox.ReplayAll() self.mox.ReplayAll()
ret_val = Node.list(self.request) ret_val = api.Node.list(self.request)
for node in ret_val: for node in ret_val:
self.assertIsInstance(node, Node) self.assertIsInstance(node, api.Node)
def test_node_list_unracked(self): def test_node_list_unracked(self):
nodes = self.baremetalclient_nodes.list() nodes = self.baremetalclient_nodes.list()
@ -105,9 +100,9 @@ class TuskarApiTests(test.APITestCase):
MultipleTimes().AndReturn(n) MultipleTimes().AndReturn(n)
self.mox.ReplayAll() self.mox.ReplayAll()
ret_val = Node.list_unracked(self.request) ret_val = api.Node.list_unracked(self.request)
for node in ret_val: for node in ret_val:
self.assertIsInstance(node, Node) self.assertIsInstance(node, api.Node)
self.assertEquals(1, len(ret_val)) self.assertEquals(1, len(ret_val))
def test_node_flavors(self): def test_node_flavors(self):
@ -139,7 +134,7 @@ class TuskarApiTests(test.APITestCase):
node.request = self.request node.request = self.request
ret_val = node.list_flavors ret_val = node.list_flavors
for flavor in ret_val: for flavor in ret_val:
self.assertIsInstance(flavor, Flavor) self.assertIsInstance(flavor, api.Flavor)
self.assertEquals(2, len(ret_val)) self.assertEquals(2, len(ret_val))
def test_node_rack(self): def test_node_rack(self):
@ -164,7 +159,7 @@ class TuskarApiTests(test.APITestCase):
node.request = self.request node.request = self.request
rack = node.rack rack = node.rack
self.assertIsInstance(rack, Rack) self.assertIsInstance(rack, api.Rack)
self.assertEquals('1', rack.id) self.assertEquals('1', rack.id)
def test_node_running_instances(self): def test_node_running_instances(self):
@ -209,9 +204,9 @@ class TuskarApiTests(test.APITestCase):
tuskarclient.resource_classes.list().AndReturn(rcs) tuskarclient.resource_classes.list().AndReturn(rcs)
self.mox.ReplayAll() self.mox.ReplayAll()
ret_val = ResourceClass.list(self.request) ret_val = api.ResourceClass.list(self.request)
for rc in ret_val: for rc in ret_val:
self.assertIsInstance(rc, ResourceClass) self.assertIsInstance(rc, api.ResourceClass)
def test_resource_class_get(self): def test_resource_class_get(self):
rc = self.tuskarclient_resource_classes.first() rc = self.tuskarclient_resource_classes.first()
@ -221,8 +216,8 @@ class TuskarApiTests(test.APITestCase):
tuskarclient.resource_classes.get(rc.id).AndReturn(rc) tuskarclient.resource_classes.get(rc.id).AndReturn(rc)
self.mox.ReplayAll() self.mox.ReplayAll()
ret_val = ResourceClass.get(self.request, rc.id) ret_val = api.ResourceClass.get(self.request, rc.id)
self.assertIsInstance(ret_val, ResourceClass) self.assertIsInstance(ret_val, api.ResourceClass)
def test_resource_class_create(self): def test_resource_class_create(self):
rc = self.tuskarclient_resource_classes.first() rc = self.tuskarclient_resource_classes.first()
@ -234,11 +229,11 @@ class TuskarApiTests(test.APITestCase):
flavors=[]).AndReturn(rc) flavors=[]).AndReturn(rc)
self.mox.ReplayAll() self.mox.ReplayAll()
ret_val = ResourceClass.create(self.request, ret_val = api.ResourceClass.create(self.request,
name='rclass1', name='rclass1',
service_type='compute', service_type='compute',
flavors=[]) flavors=[])
self.assertIsInstance(ret_val, ResourceClass) self.assertIsInstance(ret_val, api.ResourceClass)
def test_resource_class_update(self): def test_resource_class_update(self):
rc = self.tuskarclient_resource_classes.first() rc = self.tuskarclient_resource_classes.first()
@ -246,19 +241,18 @@ class TuskarApiTests(test.APITestCase):
tuskarclient = self.stub_tuskarclient() tuskarclient = self.stub_tuskarclient()
tuskarclient.resource_classes = self.mox.CreateMockAnything() tuskarclient.resource_classes = self.mox.CreateMockAnything()
tuskarclient.flavors = self.mox.CreateMockAnything() tuskarclient.flavors = self.mox.CreateMockAnything()
tuskarclient.resource_classes.update( tuskarclient.resource_classes.update(rc.id,
rc.id, name='rclass1',
name='rclass1', service_type='compute',
service_type='compute', flavors=[]).AndReturn(rc)
flavors=[]).AndReturn(rc)
tuskarclient.flavors.list(rc.id).AndReturn([]) tuskarclient.flavors.list(rc.id).AndReturn([])
self.mox.ReplayAll() self.mox.ReplayAll()
ret_val = ResourceClass.update(self.request, rc.id, ret_val = api.ResourceClass.update(self.request, rc.id,
name='rclass1', name='rclass1',
service_type='compute', service_type='compute',
flavors=[]) flavors=[])
self.assertIsInstance(ret_val, ResourceClass) self.assertIsInstance(ret_val, api.ResourceClass)
def test_resource_class_delete(self): def test_resource_class_delete(self):
rc = self.tuskarclient_resource_classes.first() rc = self.tuskarclient_resource_classes.first()
@ -268,7 +262,7 @@ class TuskarApiTests(test.APITestCase):
tuskarclient.resource_classes.delete(rc.id) tuskarclient.resource_classes.delete(rc.id)
self.mox.ReplayAll() self.mox.ReplayAll()
ResourceClass.delete(self.request, rc.id) api.ResourceClass.delete(self.request, rc.id)
def test_resource_class_deletable(self): def test_resource_class_deletable(self):
rc = self.tuskar_resource_classes.first() rc = self.tuskar_resource_classes.first()
@ -286,7 +280,7 @@ class TuskarApiTests(test.APITestCase):
self.mox.ReplayAll() self.mox.ReplayAll()
for rack in rc.list_racks: for rack in rc.list_racks:
self.assertIsInstance(rack, Rack) self.assertIsInstance(rack, api.Rack)
self.assertEquals(2, rc.racks_count) self.assertEquals(2, rc.racks_count)
def test_resource_class_all_racks(self): def test_resource_class_all_racks(self):
@ -300,7 +294,7 @@ class TuskarApiTests(test.APITestCase):
all_racks = rc.all_racks all_racks = rc.all_racks
for rack in all_racks: for rack in all_racks:
self.assertIsInstance(rack, Rack) self.assertIsInstance(rack, api.Rack)
self.assertEquals(3, len(all_racks)) self.assertEquals(3, len(all_racks))
def test_resource_class_racks_set(self): def test_resource_class_racks_set(self):
@ -342,7 +336,7 @@ class TuskarApiTests(test.APITestCase):
rc.request = self.request rc.request = self.request
for node in rc.nodes: for node in rc.nodes:
self.assertIsInstance(node, Node) self.assertIsInstance(node, api.Node)
self.assertEquals(4, rc.nodes_count) self.assertEquals(4, rc.nodes_count)
def test_resource_class_flavors(self): def test_resource_class_flavors(self):
@ -355,7 +349,7 @@ class TuskarApiTests(test.APITestCase):
self.mox.ReplayAll() self.mox.ReplayAll()
for f in rc.list_flavors: for f in rc.list_flavors:
self.assertIsInstance(f, Flavor) self.assertIsInstance(f, api.Flavor)
self.assertEquals(2, len(rc.flavors_ids)) self.assertEquals(2, len(rc.flavors_ids))
def test_resource_class_capacities(self): def test_resource_class_capacities(self):
@ -369,7 +363,7 @@ class TuskarApiTests(test.APITestCase):
self.mox.ReplayAll() self.mox.ReplayAll()
for capacity in rc.capacities: for capacity in rc.capacities:
self.assertIsInstance(capacity, Capacity) self.assertIsInstance(capacity, api.Capacity)
self.assertEquals(2, len(rc.capacities)) self.assertEquals(2, len(rc.capacities))
def test_resource_class_total_instances(self): def test_resource_class_total_instances(self):
@ -404,7 +398,7 @@ class TuskarApiTests(test.APITestCase):
self.mox.ReplayAll() self.mox.ReplayAll()
vm_capacity = rc.vm_capacity vm_capacity = rc.vm_capacity
self.assertIsInstance(vm_capacity, Capacity) self.assertIsInstance(vm_capacity, api.Capacity)
self.assertEquals(200, vm_capacity.value) self.assertEquals(200, vm_capacity.value)
def test_resource_class_has_provisioned_rack(self): def test_resource_class_has_provisioned_rack(self):
@ -445,7 +439,7 @@ class TuskarApiTests(test.APITestCase):
self.mox.ReplayAll() self.mox.ReplayAll()
for rack in rc.aggregated_alerts: for rack in rc.aggregated_alerts:
self.assertIsInstance(rack, Rack) self.assertIsInstance(rack, api.Rack)
self.assertEquals(1, len(rc.aggregated_alerts)) self.assertEquals(1, len(rc.aggregated_alerts))
def test_rack_list(self): def test_rack_list(self):
@ -456,9 +450,9 @@ class TuskarApiTests(test.APITestCase):
tuskarclient.racks.list().AndReturn(racks) tuskarclient.racks.list().AndReturn(racks)
self.mox.ReplayAll() self.mox.ReplayAll()
ret_val = Rack.list(self.request) ret_val = api.Rack.list(self.request)
for rack in ret_val: for rack in ret_val:
self.assertIsInstance(rack, Rack) self.assertIsInstance(rack, api.Rack)
def test_rack_get(self): def test_rack_get(self):
rack = self.tuskarclient_racks.first() rack = self.tuskarclient_racks.first()
@ -468,8 +462,8 @@ class TuskarApiTests(test.APITestCase):
tuskarclient.racks.get(rack.id).AndReturn(rack) tuskarclient.racks.get(rack.id).AndReturn(rack)
self.mox.ReplayAll() self.mox.ReplayAll()
ret_val = Rack.get(self.request, rack.id) ret_val = api.Rack.get(self.request, rack.id)
self.assertIsInstance(ret_val, Rack) self.assertIsInstance(ret_val, api.Rack)
def test_rack_create(self): def test_rack_create(self):
rack = self.tuskarclient_racks.first() rack = self.tuskarclient_racks.first()
@ -484,12 +478,12 @@ class TuskarApiTests(test.APITestCase):
slots=0).AndReturn(rack) slots=0).AndReturn(rack)
self.mox.ReplayAll() self.mox.ReplayAll()
ret_val = Rack.create(request=self.request, ret_val = api.Rack.create(request=self.request,
name='rack1', name='rack1',
resource_class_id=1, resource_class_id=1,
location='location', location='location',
subnet='192.168.1.0/24') subnet='192.168.1.0/24')
self.assertIsInstance(ret_val, Rack) self.assertIsInstance(ret_val, api.Rack)
def test_rack_update(self): def test_rack_update(self):
rack = self.tuskarclient_racks.first() rack = self.tuskarclient_racks.first()
@ -500,10 +494,10 @@ class TuskarApiTests(test.APITestCase):
name='rack1').AndReturn(rack) name='rack1').AndReturn(rack)
self.mox.ReplayAll() self.mox.ReplayAll()
ret_val = Rack.update(self.request, ret_val = api.Rack.update(self.request,
rack.id, rack.id,
{'name': 'rack1'}) {'name': 'rack1'})
self.assertIsInstance(ret_val, Rack) self.assertIsInstance(ret_val, api.Rack)
def test_rack_delete(self): def test_rack_delete(self):
rack = self.tuskarclient_racks.first() rack = self.tuskarclient_racks.first()
@ -513,7 +507,7 @@ class TuskarApiTests(test.APITestCase):
tuskarclient.racks.delete(rack.id) tuskarclient.racks.delete(rack.id)
self.mox.ReplayAll() self.mox.ReplayAll()
Rack.delete(self.request, rack.id) api.Rack.delete(self.request, rack.id)
def test_rack_nodes(self): def test_rack_nodes(self):
rack = self.tuskar_racks.first() rack = self.tuskar_racks.first()
@ -532,7 +526,7 @@ class TuskarApiTests(test.APITestCase):
rack.request = self.request rack.request = self.request
for node in rack.list_nodes: for node in rack.list_nodes:
self.assertIsInstance(node, Node) self.assertIsInstance(node, api.Node)
self.assertEquals(4, len(rack.node_ids)) self.assertEquals(4, len(rack.node_ids))
self.assertEquals(4, rack.nodes_count) self.assertEquals(4, rack.nodes_count)
@ -545,14 +539,14 @@ class TuskarApiTests(test.APITestCase):
tuskarclient.resource_classes.get(rc.id).AndReturn(rc) tuskarclient.resource_classes.get(rc.id).AndReturn(rc)
self.mox.ReplayAll() self.mox.ReplayAll()
self.assertIsInstance(rack.get_resource_class, ResourceClass) self.assertIsInstance(rack.get_resource_class, api.ResourceClass)
self.assertEquals(rack.resource_class_id, '1') self.assertEquals(rack.resource_class_id, '1')
def test_rack_capacities(self): def test_rack_capacities(self):
rack = self.tuskar_racks.first() rack = self.tuskar_racks.first()
for capacity in rack.list_capacities: for capacity in rack.list_capacities:
self.assertIsInstance(capacity, Capacity) self.assertIsInstance(capacity, api.Capacity)
self.assertEquals(2, len(rack.capacities)) self.assertEquals(2, len(rack.capacities))
def test_rack_vm_capacity(self): def test_rack_vm_capacity(self):
@ -568,7 +562,7 @@ class TuskarApiTests(test.APITestCase):
self.mox.ReplayAll() self.mox.ReplayAll()
vm_capacity = rack.vm_capacity vm_capacity = rack.vm_capacity
self.assertIsInstance(vm_capacity, Capacity) self.assertIsInstance(vm_capacity, api.Capacity)
self.assertEquals(100, vm_capacity.value) self.assertEquals(100, vm_capacity.value)
def test_rack_flavors(self): def test_rack_flavors(self):
@ -585,7 +579,7 @@ class TuskarApiTests(test.APITestCase):
rack_flavors = rack.list_flavors rack_flavors = rack.list_flavors
for f in rack_flavors: for f in rack_flavors:
self.assertIsInstance(f, Flavor) self.assertIsInstance(f, api.Flavor)
self.assertEquals(2, len(rack_flavors)) self.assertEquals(2, len(rack_flavors))
def test_rack_total_instances(self): def test_rack_total_instances(self):
@ -638,7 +632,7 @@ class TuskarApiTests(test.APITestCase):
tuskarclient.data_centers.provision_all() tuskarclient.data_centers.provision_all()
self.mox.ReplayAll() self.mox.ReplayAll()
Rack.provision(self.request, rack.id) api.Rack.provision(self.request, rack.id)
def test_rack_aggregated_alerts(self): def test_rack_aggregated_alerts(self):
rack = self.tuskar_racks.first() rack = self.tuskar_racks.first()
@ -658,20 +652,20 @@ class TuskarApiTests(test.APITestCase):
self.mox.ReplayAll() self.mox.ReplayAll()
for node in rack.aggregated_alerts: for node in rack.aggregated_alerts:
self.assertIsInstance(node, Node) self.assertIsInstance(node, api.Node)
self.assertEquals(1, len(rack.aggregated_alerts)) self.assertEquals(1, len(rack.aggregated_alerts))
def test_flavor_template_list(self): def test_flavor_template_list(self):
templates = FlavorTemplate.list(self.request) templates = api.FlavorTemplate.list(self.request)
self.assertEquals(7, len(templates)) self.assertEquals(7, len(templates))
for t in templates: for t in templates:
self.assertIsInstance(t, FlavorTemplate) self.assertIsInstance(t, api.FlavorTemplate)
def test_flavor_template_get(self): def test_flavor_template_get(self):
test_template = self.tuskar_flavor_templates.first() test_template = self.tuskar_flavor_templates.first()
template = FlavorTemplate.get(self.request, template = api.FlavorTemplate.get(self.request,
test_template.id) test_template.id)
self.assertIsInstance(template, FlavorTemplate) self.assertIsInstance(template, api.FlavorTemplate)
self.assertEquals(template.name, test_template.name) self.assertEquals(template.name, test_template.name)
def test_flavor_create(self): def test_flavor_create(self):
@ -680,17 +674,17 @@ class TuskarApiTests(test.APITestCase):
tuskarclient = self.stub_tuskarclient() tuskarclient = self.stub_tuskarclient()
tuskarclient.flavors = self.mox.CreateMockAnything() tuskarclient.flavors = self.mox.CreateMockAnything()
tuskarclient.flavors.create(1, tuskarclient.flavors.create(1,
name='nano', name='nano',
max_vms=100, max_vms=100,
capacities=[]).AndReturn(flavor) capacities=[]).AndReturn(flavor)
self.mox.ReplayAll() self.mox.ReplayAll()
ret_val = Flavor.create(self.request, ret_val = api.Flavor.create(self.request,
resource_class_id=1, resource_class_id=1,
name='nano', name='nano',
max_vms=100, max_vms=100,
capacities=[]) capacities=[])
self.assertIsInstance(ret_val, Flavor) self.assertIsInstance(ret_val, api.Flavor)
def test_flavor_delete(self): def test_flavor_delete(self):
rc = self.tuskarclient_resource_classes.first() rc = self.tuskarclient_resource_classes.first()
@ -701,40 +695,41 @@ class TuskarApiTests(test.APITestCase):
tuskarclient.flavors.delete(rc.id, flavor.id) tuskarclient.flavors.delete(rc.id, flavor.id)
self.mox.ReplayAll() self.mox.ReplayAll()
Flavor.delete(self.request, resource_class_id=rc.id, api.Flavor.delete(self.request,
flavor_id=flavor.id) resource_class_id=rc.id,
flavor_id=flavor.id)
def test_flavor_cpu(self): def test_flavor_cpu(self):
flavor = self.tuskar_flavors.first() flavor = self.tuskar_flavors.first()
cpu = flavor.cpu cpu = flavor.cpu
self.assertIsInstance(cpu, Capacity) self.assertIsInstance(cpu, api.Capacity)
self.assertEquals(64, cpu.value) self.assertEquals(64, cpu.value)
def test_flavor_memory(self): def test_flavor_memory(self):
flavor = self.tuskar_flavors.first() flavor = self.tuskar_flavors.first()
memory = flavor.memory memory = flavor.memory
self.assertIsInstance(memory, Capacity) self.assertIsInstance(memory, api.Capacity)
self.assertEquals(1024, memory.value) self.assertEquals(1024, memory.value)
def test_flavor_storage(self): def test_flavor_storage(self):
flavor = self.tuskar_flavors.first() flavor = self.tuskar_flavors.first()
storage = flavor.storage storage = flavor.storage
self.assertIsInstance(storage, Capacity) self.assertIsInstance(storage, api.Capacity)
self.assertEquals(1, storage.value) self.assertEquals(1, storage.value)
def test_flavor_ephemeral_disk(self): def test_flavor_ephemeral_disk(self):
flavor = self.tuskar_flavors.first() flavor = self.tuskar_flavors.first()
ephemeral_disk = flavor.ephemeral_disk ephemeral_disk = flavor.ephemeral_disk
self.assertIsInstance(ephemeral_disk, Capacity) self.assertIsInstance(ephemeral_disk, api.Capacity)
self.assertEquals(0, ephemeral_disk.value) self.assertEquals(0, ephemeral_disk.value)
def test_flavor_swap_disk(self): def test_flavor_swap_disk(self):
flavor = self.tuskar_flavors.first() flavor = self.tuskar_flavors.first()
swap_disk = flavor.swap_disk swap_disk = flavor.swap_disk
self.assertIsInstance(swap_disk, Capacity) self.assertIsInstance(swap_disk, api.Capacity)
self.assertEquals(2, swap_disk.value) self.assertEquals(2, swap_disk.value)

View File

@ -22,7 +22,7 @@ from tuskarclient.v1 import client as tuskar_client
from openstack_dashboard.test import helpers as openstack_dashboard_helpers from openstack_dashboard.test import helpers as openstack_dashboard_helpers
from tuskar_ui import api as tuskar_api from tuskar_ui import api as tuskar_api
from tuskar_ui.test.test_data.utils import load_test_data from tuskar_ui.test.test_data import utils as test_data_utils
# Makes output of failing mox tests much easier to read. # Makes output of failing mox tests much easier to read.
@ -56,7 +56,7 @@ class TestCase(openstack_dashboard_helpers.TestCase):
super(TestCase, self).setUp() super(TestCase, self).setUp()
# load tuskar-specific test data # load tuskar-specific test data
load_test_data(self) test_data_utils.load_test_data(self)
class BaseAdminViewTests(openstack_dashboard_helpers.BaseAdminViewTests): class BaseAdminViewTests(openstack_dashboard_helpers.BaseAdminViewTests):
@ -68,7 +68,7 @@ class BaseAdminViewTests(openstack_dashboard_helpers.BaseAdminViewTests):
super(BaseAdminViewTests, self).setUp() super(BaseAdminViewTests, self).setUp()
# load tuskar-specific test data # load tuskar-specific test data
load_test_data(self) test_data_utils.load_test_data(self)
class APITestCase(openstack_dashboard_helpers.APITestCase): class APITestCase(openstack_dashboard_helpers.APITestCase):
@ -81,7 +81,7 @@ class APITestCase(openstack_dashboard_helpers.APITestCase):
super(APITestCase, self).setUp() super(APITestCase, self).setUp()
# load tuskar-specfic test data # load tuskar-specfic test data
load_test_data(self) test_data_utils.load_test_data(self)
# Store the original clients # Store the original clients
self._original_tuskarclient = tuskar_api.tuskarclient self._original_tuskarclient = tuskar_api.tuskarclient

View File

@ -14,21 +14,19 @@
import os import os
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _ # noqa
from horizon.test.settings import * # noqa from horizon.test.settings import * # noqa
from horizon.utils.secret_key import generate_or_read_from_file from horizon.utils import secret_key as secret_key_utils
from tuskar_ui.exceptions import NOT_FOUND from tuskar_ui import exceptions
from tuskar_ui.exceptions import RECOVERABLE
from tuskar_ui.exceptions import UNAUTHORIZED
TEST_DIR = os.path.dirname(os.path.abspath(__file__)) TEST_DIR = os.path.dirname(os.path.abspath(__file__))
ROOT_PATH = os.path.abspath(os.path.join(TEST_DIR, "..")) ROOT_PATH = os.path.abspath(os.path.join(TEST_DIR, ".."))
SECRET_KEY = generate_or_read_from_file(os.path.join(TEST_DIR, SECRET_KEY = secret_key_utils.generate_or_read_from_file(
'.secret_key_store')) os.path.join(TEST_DIR, '.secret_key_store'))
ROOT_URLCONF = 'openstack_dashboard.urls' ROOT_URLCONF = 'openstack_dashboard.urls'
TEMPLATE_DIRS = ( TEMPLATE_DIRS = (
os.path.join(TEST_DIR, 'templates'), os.path.join(TEST_DIR, 'templates'),
@ -69,9 +67,9 @@ HORIZON_CONFIG = {
}, },
'user_home': None, 'user_home': None,
'help_url': "http://docs.openstack.org", 'help_url': "http://docs.openstack.org",
'exceptions': {'recoverable': RECOVERABLE, 'exceptions': {'recoverable': exceptions.RECOVERABLE,
'not_found': NOT_FOUND, 'not_found': exceptions.NOT_FOUND,
'unauthorized': UNAUTHORIZED}, 'unauthorized': exceptions.UNAUTHORIZED},
} }
# Set to True to allow users to upload images to glance via Horizon server. # Set to True to allow users to upload images to glance via Horizon server.

View File

@ -10,16 +10,11 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from collections import namedtuple import collections
from tuskar_ui.api import Capacity from tuskar_ui import api
from tuskar_ui.api import Flavor
from tuskar_ui.api import FlavorTemplate
from tuskar_ui.api import Node
from tuskar_ui.api import Rack
from tuskar_ui.api import ResourceClass
from openstack_dashboard.test.test_data.utils import TestDataContainer from openstack_dashboard.test.test_data import utils as test_data_utils
from novaclient.v1_1.contrib import baremetal from novaclient.v1_1.contrib import baremetal
from tuskarclient.v1 import flavors from tuskarclient.v1 import flavors
@ -28,43 +23,46 @@ from tuskarclient.v1 import resource_classes
def data(TEST): def data(TEST):
FlavorTemplateStruct = namedtuple('FlavorStruct', 'id name\ FlavorTemplateStruct = collections.namedtuple('FlavorStruct',
capacities') 'id name capacities')
CapacityStruct = namedtuple('CapacityStruct', 'name value unit') CapacityStruct = collections.namedtuple('CapacityStruct',
TEST.tuskar_flavor_templates = TestDataContainer() 'name value unit')
flavor_template_1 = FlavorTemplate(FlavorTemplateStruct( TEST.tuskar_flavor_templates = test_data_utils.TestDataContainer()
flavor_template_1 = api.FlavorTemplate(
FlavorTemplateStruct(
id="1", id="1",
name='nano', name='nano',
capacities=[ capacities=[
Capacity(CapacityStruct( api.Capacity(CapacityStruct(
name='cpu', name='cpu',
unit='', unit='',
value='1')), value='1')),
Capacity(CapacityStruct( api.Capacity(CapacityStruct(
name='memory', name='memory',
unit='MB', unit='MB',
value='64')), value='64')),
Capacity(CapacityStruct( api.Capacity(CapacityStruct(
name='storage', name='storage',
unit='MB', unit='MB',
value='128')), value='128')),
Capacity(CapacityStruct( api.Capacity(CapacityStruct(
name='ephemeral_disk', name='ephemeral_disk',
unit='GB', unit='GB',
value='0')), value='0')),
Capacity(CapacityStruct( api.Capacity(CapacityStruct(
name='swap_disk', name='swap_disk',
unit='GB', unit='GB',
value='0'))])) value='0'))]))
flavor_template_2 = FlavorTemplate(FlavorTemplateStruct( flavor_template_2 = api.FlavorTemplate(
FlavorTemplateStruct(
id="2", id="2",
name='large', name='large',
capacities=[])) capacities=[]))
TEST.tuskar_flavor_templates.add(flavor_template_1, flavor_template_2) TEST.tuskar_flavor_templates.add(flavor_template_1, flavor_template_2)
# Flavors # Flavors
TEST.tuskarclient_flavors = TestDataContainer() TEST.tuskarclient_flavors = test_data_utils.TestDataContainer()
TEST.tuskar_flavors = TestDataContainer() TEST.tuskar_flavors = test_data_utils.TestDataContainer()
flavor_1 = flavors.Flavor(flavors.FlavorManager(None), flavor_1 = flavors.Flavor(flavors.FlavorManager(None),
{'id': '1', {'id': '1',
'name': 'nano', 'name': 'nano',
@ -91,11 +89,11 @@ def data(TEST):
'max_vms': 10, 'max_vms': 10,
'capacities': []}) 'capacities': []})
TEST.tuskarclient_flavors.add(flavor_1, flavor_2) TEST.tuskarclient_flavors.add(flavor_1, flavor_2)
TEST.tuskar_flavors.add(Flavor(flavor_1), Flavor(flavor_2)) TEST.tuskar_flavors.add(api.Flavor(flavor_1), api.Flavor(flavor_2))
# Resource Classes # Resource Classes
TEST.tuskarclient_resource_classes = TestDataContainer() TEST.tuskarclient_resource_classes = test_data_utils.TestDataContainer()
TEST.tuskar_resource_classes = TestDataContainer() TEST.tuskar_resource_classes = test_data_utils.TestDataContainer()
resource_class_1 = resource_classes.ResourceClass( resource_class_1 = resource_classes.ResourceClass(
resource_classes.ResourceClassManager(None), resource_classes.ResourceClassManager(None),
{'id': '1', {'id': '1',
@ -109,12 +107,12 @@ def data(TEST):
'racks': [], 'racks': [],
'name': 'rclass2'}) 'name': 'rclass2'})
TEST.tuskarclient_resource_classes.add(resource_class_1, resource_class_2) TEST.tuskarclient_resource_classes.add(resource_class_1, resource_class_2)
TEST.tuskar_resource_classes.add(ResourceClass(resource_class_1), TEST.tuskar_resource_classes.add(api.ResourceClass(resource_class_1),
ResourceClass(resource_class_2)) api.ResourceClass(resource_class_2))
#Racks #Racks
TEST.tuskarclient_racks = TestDataContainer() TEST.tuskarclient_racks = test_data_utils.TestDataContainer()
TEST.tuskar_racks = TestDataContainer() TEST.tuskar_racks = test_data_utils.TestDataContainer()
rack_1 = racks.Rack(racks.RackManager(None), rack_1 = racks.Rack(racks.RackManager(None),
{'id': '1', {'id': '1',
'name': 'rack1', 'name': 'rack1',
@ -165,15 +163,15 @@ def data(TEST):
"unit": "MB"}], "unit": "MB"}],
'resource_class': None}) 'resource_class': None})
TEST.tuskarclient_racks.add(rack_1, rack_2, rack_3) TEST.tuskarclient_racks.add(rack_1, rack_2, rack_3)
TEST.tuskar_racks.add(Rack(rack_1), Rack(rack_2), Rack(rack_3)) TEST.tuskar_racks.add(api.Rack(rack_1), api.Rack(rack_2), api.Rack(rack_3))
# Nodes # Nodes
TEST.baremetalclient_nodes = TestDataContainer() TEST.baremetalclient_nodes = test_data_utils.TestDataContainer()
TEST.baremetal_nodes = TestDataContainer() TEST.baremetal_nodes = test_data_utils.TestDataContainer()
TEST.baremetalclient_unracked_nodes = TestDataContainer() TEST.baremetalclient_unracked_nodes = test_data_utils.TestDataContainer()
TEST.baremetal_unracked_nodes = TestDataContainer() TEST.baremetal_unracked_nodes = test_data_utils.TestDataContainer()
TEST.baremetalclient_nodes_all = TestDataContainer() TEST.baremetalclient_nodes_all = test_data_utils.TestDataContainer()
TEST.baremetal_nodes_all = TestDataContainer() TEST.baremetal_nodes_all = test_data_utils.TestDataContainer()
node_1 = baremetal.BareMetalNode( node_1 = baremetal.BareMetalNode(
baremetal.BareMetalNodeManager(None), baremetal.BareMetalNodeManager(None),
@ -202,15 +200,15 @@ def data(TEST):
'prov_mac_address': '00-B0-D0-86-AB-F1'}) 'prov_mac_address': '00-B0-D0-86-AB-F1'})
TEST.baremetalclient_nodes.add(node_1, node_2, node_3, node_4) TEST.baremetalclient_nodes.add(node_1, node_2, node_3, node_4)
TEST.baremetal_nodes.add(Node(node_1), TEST.baremetal_nodes.add(api.Node(node_1),
Node(node_2), api.Node(node_2),
Node(node_3), api.Node(node_3),
Node(node_4)) api.Node(node_4))
TEST.baremetalclient_unracked_nodes.add(node_5) TEST.baremetalclient_unracked_nodes.add(node_5)
TEST.baremetal_unracked_nodes.add(Node(node_5)) TEST.baremetal_unracked_nodes.add(api.Node(node_5))
TEST.baremetalclient_nodes_all.add(node_1, node_2, node_3, node_4, node_5) TEST.baremetalclient_nodes_all.add(node_1, node_2, node_3, node_4, node_5)
TEST.baremetal_nodes_all.add(Node(node_1), TEST.baremetal_nodes_all.add(api.Node(node_1),
Node(node_2), api.Node(node_2),
Node(node_3), api.Node(node_3),
Node(node_4), api.Node(node_4),
Node(node_5)) api.Node(node_5))

View File

@ -17,7 +17,7 @@ import logging
from django import template from django import template
# FIXME: TableStep # FIXME: TableStep
from django.utils.datastructures import SortedDict from django.utils import datastructures
import horizon.workflows import horizon.workflows
@ -57,7 +57,7 @@ class TableStep(horizon.workflows.Step):
table_instances = [(table._meta.name, table_instances = [(table._meta.name,
table(workflow.request, needs_form_wrapper=False)) table(workflow.request, needs_form_wrapper=False))
for table in self.table_classes] for table in self.table_classes]
self._tables = SortedDict(table_instances) self._tables = datastructures.SortedDict(table_instances)
self._table_data_loaded = False self._table_data_loaded = False
def render(self): def render(self):