Adds service name to services table.

Also moves most of the logic to a Service wrapper class to make it
reusable. Adds tests for the new service class as well as the
syspanel services view.

Fixes bug 956552.

Change-Id: I9407578bb27f3fe0765397793f2de03ed084637b
This commit is contained in:
Gabriel Hurley 2012-03-18 16:47:33 -07:00
parent 67f3d28349
commit 8ea84225c3
5 changed files with 80 additions and 23 deletions

View File

@ -20,8 +20,10 @@
# under the License.
import logging
import urlparse
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from keystoneclient import service_catalog
from keystoneclient.v2_0 import client as keystone_client
@ -35,6 +37,29 @@ LOG = logging.getLogger(__name__)
DEFAULT_ROLE = None
class Service(base.APIDictWrapper):
""" Wrapper for a dict based on the service data from keystone. """
_attrs = ['id', 'type', 'name']
def __init__(self, service, *args, **kwargs):
super(Service, self).__init__(service, *args, **kwargs)
self.url = service['endpoints'][0]['internalURL']
self.host = urlparse.urlparse(self.url).hostname
self.region = service['endpoints'][0]['region']
self.disabled = None
def __unicode__(self):
if(self.type == "identity"):
return _("%(type)s (%(backend)s backend)") \
% {"type": self.type,
"backend": keystone_backend_name()}
else:
return self.type
def __repr__(self):
return "<Service: %s>" % unicode(self)
def _get_endpoint_url(request, endpoint_type, catalog=None):
if getattr(request.user, "service_catalog", None):
return base.url_for(request,

View File

@ -4,7 +4,6 @@ from django import template
from django.utils.translation import ugettext_lazy as _
from horizon import tables
from horizon import api
LOG = logging.getLogger(__name__)
@ -34,18 +33,10 @@ def get_enabled(service, reverse=False):
return options[0] if not service.disabled else options[1]
def get_service_name(service):
if(service.type == "identity"):
return _("%(type)s (%(backend)s backend)") \
% {"type": service.type,
"backend": api.keystone_backend_name()}
else:
return service.type
class ServicesTable(tables.DataTable):
id = tables.Column('id', verbose_name=_('Id'), hidden=True)
service = tables.Column(get_service_name, verbose_name=_('Service'))
name = tables.Column("name", verbose_name=_('Name'))
service_type = tables.Column('__unicode__', verbose_name=_('Service'))
host = tables.Column('host', verbose_name=_('Host'))
enabled = tables.Column(get_enabled,
verbose_name=_('Enabled'),

View File

@ -0,0 +1,36 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2012 Nebula, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from django.core.urlresolvers import reverse
from horizon import test
INDEX_URL = reverse('horizon:syspanel:services:index')
class ServicessViewTests(test.BaseAdminViewTests):
def test_index(self):
res = self.client.get(INDEX_URL)
self.assertTemplateUsed(res, 'syspanel/services/index.html')
self.assertQuerysetEqual(res.context['table'].data,
['<Service: compute>',
'<Service: volume>',
'<Service: image>',
'<Service: identity (native backend)>',
'<Service: object-store>',
'<Service: network>',
'<Service: ec2>'])

View File

@ -19,7 +19,6 @@
# under the License.
import logging
import urlparse
from horizon import api
from horizon import tables
@ -35,15 +34,7 @@ class IndexView(tables.DataTableView):
def get_data(self):
services = []
for i, service in enumerate(self.request.session['serviceCatalog']):
url = service['endpoints'][0]['internalURL']
hostname = urlparse.urlparse(url).hostname
row = {'id': i, # id is required for table to render properly
'type': service['type'],
'internalURL': url,
'host': hostname,
'region': service['endpoints'][0]['region'],
'disabled': None}
services.append(api.base.APIDictWrapper(row))
for i, service in enumerate(self.request.user.service_catalog):
service['id'] = i
services.append(api.keystone.Service(service))
return services

View File

@ -173,3 +173,17 @@ class RoleAPITests(test.APITestCase):
# Verify that a second call doesn't hit the API again,
# (it would show up in mox as an unexpected method call)
role = api.keystone.get_default_role(self.request)
class ServiceAPITests(test.APITestCase):
def test_service_wrapper(self):
catalog = self.service_catalog
identity_data = api.base.get_service_from_catalog(catalog, "identity")
identity_data['id'] = 1
service = api.keystone.Service(identity_data)
self.assertEqual(unicode(service), u"identity (native backend)")
self.assertEqual(service.region,
identity_data["endpoints"][0]["region"])
self.assertEqual(service.url,
"http://int.keystone.example.com:5000/v2.0")
self.assertEqual(service.host, "int.keystone.example.com")