added detail page for keypair

from keypair table, we can see only the
name and fingerprint of the keypair

in horizon we have no option to see the
id, created time and public key of
the keypair.

this patch adding a new detail page for
keypairs, which display the name fingerprint,
id, created time and public key.

Change-Id: Idb85f7e60090875e2e503806122cdb4ff637c341
Closes-Bug: #1413126
This commit is contained in:
Masco Kaliyamoorthy
2015-01-21 15:33:04 +05:30
parent 1bff6943a7
commit b05310e77d
7 changed files with 94 additions and 1 deletions

View File

@@ -537,6 +537,10 @@ def keypair_list(request):
return novaclient(request).keypairs.list()
def keypair_get(request, keypair_id):
return novaclient(request).keypairs.get(keypair_id)
def server_create(request, name, image, flavor, key_name, user_data,
security_groups, block_device_mapping=None,
block_device_mapping_v2=None, nics=None,

View File

@@ -79,7 +79,10 @@ class CreateKeyPair(tables.LinkAction):
class KeypairsTable(tables.DataTable):
name = tables.Column("name", verbose_name=_("Key Pair Name"))
detail_link = "horizon:project:access_and_security:keypairs:detail"
name = tables.Column("name", verbose_name=_("Key Pair Name"),
link=detail_link)
fingerprint = tables.Column("fingerprint", verbose_name=_("Fingerprint"))
def get_object_id(self, keypair):

View File

@@ -100,6 +100,23 @@ class KeyPairViewTests(test.TestCase):
self.assertTrue(res.has_header('content-disposition'))
def test_keypair_detail_get(self):
keypair = self.keypairs.first()
keypair.private_key = "secrete"
self.mox.StubOutWithMock(api.nova, 'keypair_get')
api.nova.keypair_get(IsA(http.HttpRequest),
keypair.name).AndReturn(keypair)
self.mox.ReplayAll()
context = {'keypair_name': keypair.name}
url = reverse('horizon:project:access_and_security:keypairs:detail',
kwargs={'keypair_name': keypair.name})
res = self.client.get(url, context)
self.assertContains(res, "<h1>Key Pair Details</h1>", 1, 200)
self.assertContains(res, "<dd>%s</dd>" % keypair.name, 2, 200)
@test.create_stubs({api.nova: ("keypair_create", "keypair_delete")})
def test_regenerate_keypair_get(self):
keypair = self.keypairs.first()

View File

@@ -33,4 +33,6 @@ urlpatterns = patterns(
name='generate'),
url(r'^(?P<keypair_name>[^/]+)/(?P<optional>[^/]+)/generate/$',
views.GenerateView.as_view(), name='generate'),
url(r'^(?P<keypair_name>[^/]+)/$', views.DetailView.as_view(),
name='detail'),
)

View File

@@ -29,6 +29,7 @@ from django.views.generic import View # noqa
from horizon import exceptions
from horizon import forms
from horizon.utils import memoized
from openstack_dashboard import api
@@ -55,6 +56,30 @@ class ImportView(forms.ModalFormView):
return keypair.name
class DetailView(TemplateView):
template_name = 'project/access_and_security/keypairs/detail.html'
@memoized.memoized_method
def _get_data(self):
try:
keypair = api.nova.keypair_get(self.request,
self.kwargs['keypair_name'])
except Exception:
redirect = reverse('horizon:project:access_and_security:index')
msg = _('Unable to retrieve details for keypair "%s".')\
% (self.kwargs['keypair_name'])
exceptions.handle(self.request, msg,
redirect=redirect)
return keypair
def get_context_data(self, **kwargs):
"""Gets the context data for keypair."""
context = super(DetailView, self).get_context_data(**kwargs)
context['page_title'] = _("Key Pair Details")
context['keypair'] = self._get_data()
return context
class DownloadView(TemplateView):
def get_context_data(self, keypair_name=None):
return {'keypair_name': keypair_name}

View File

@@ -0,0 +1,34 @@
{% extends 'base.html' %}
{% load i18n sizeformat %}
{% block title %}{% trans "Key Pair Details" %}{% endblock %}
{% block page_header %}
{% include "horizon/common/_page_header.html" with title=page_title %}
{% endblock page_header %}
{% block main %}
<div class="row-fluid">
<div class="info detail col-sm-12">
<h4>{% trans "Information" %}</h4>
<hr class="header_rule">
<dl class="dl-horizontal">
<dt>{% trans "Name" %}</dt>
<dd>{{ keypair.name|default:_("None") }}</dd>
<dt>{% trans "ID" %}</dt>
<dd>{{ keypair.id|default:_("None") }}</dd>
<dt>{% trans "Fingerprint" %}</dt>
<dd>{{ keypair.fingerprint|default:_("None") }}</dd>
<dt>{% trans "Created" %}</dt>
<dd>{{ keypair.created_at|parse_isotime}}</dd>
{% if keypair.updated_at %}
<dt>{% trans "Updated" %}
<dd>{{ keypair.updated_at|parse_isotime}}</dd>
{% endif %}
<dt>{% trans "User ID" %}</dt>
<dd>{{ keypair.user_id|default:_("None") }}</dd>
<dt>{% trans "Public Key" %}</dt>
<dd><textarea class="key_text">{{ keypair.public_key|default:_("None") }}</textarea></dd>
</dl>
</div>
</div>
{% endblock %}

View File

@@ -1883,3 +1883,11 @@ a:hover.link-popover { text-decoration: none; }
input::-ms-clear, input::-ms-reveal{
display: none;
}
/* public key text area */
textarea.key_text {
width: 55em;
height: 11em;
resize: none;
border: none;
}