finishing port for keypairs
This commit is contained in:
parent
59a5143fdd
commit
4b54972005
@ -5,7 +5,7 @@ from django.conf import settings
|
||||
|
||||
INSTANCES = r'^(?P<tenant_id>[^/]+)/instances/(?P<instance_id>[^/]+)/%s$'
|
||||
IMAGES = r'^(?P<tenant_id>[^/]+)/images/(?P<image_id>[^/]+)/%s$'
|
||||
KEYPAIRS = r'^(?P<tenant_id>[^/]+)/keypairs/(?P<keypair_id>[^/]+)/%s$'
|
||||
KEYPAIRS = r'^(?P<tenant_id>[^/]+)/keypairs/%s$'
|
||||
|
||||
urlpatterns = patterns('django_openstack.dash.views.instances',
|
||||
url(r'^(?P<tenant_id>[^/]+)/$', 'usage', name='dash_usage'),
|
||||
@ -21,5 +21,5 @@ urlpatterns += patterns('django_openstack.dash.views.images',
|
||||
|
||||
urlpatterns += patterns('django_openstack.dash.views.keypairs',
|
||||
url(r'^(?P<tenant_id>[^/]+)/keypairs/$', 'index', name='dash_keypairs'),
|
||||
url(KEYPAIRS % 'launch', 'launch', name='dash_keypairs_launch'),
|
||||
url(KEYPAIRS % 'create', 'create', name='dash_keypairs_create'),
|
||||
)
|
||||
|
@ -1,19 +1,66 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2010 United States Government as represented by the
|
||||
# Administrator of the National Aeronautics and Space Administration.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
Views for managing Nova instances.
|
||||
"""
|
||||
import datetime
|
||||
import logging
|
||||
|
||||
from django import http
|
||||
from django import template
|
||||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django import shortcuts
|
||||
from django.shortcuts import redirect, render_to_response
|
||||
from django.utils.translation import ugettext as _
|
||||
from django_openstack.nova import forms as nova_forms
|
||||
from django_openstack.nova.exceptions import handle_nova_error
|
||||
|
||||
from django_openstack import api
|
||||
from django_openstack import forms
|
||||
import openstack.compute.servers
|
||||
import openstackx.api.exceptions as api_exceptions
|
||||
|
||||
|
||||
LOG = logging.getLogger('django_openstack.nova')
|
||||
|
||||
|
||||
class DeleteKeypair(forms.SelfHandlingForm):
|
||||
keypair_id = forms.CharField(widget=forms.HiddenInput())
|
||||
|
||||
def handle(self, request, data):
|
||||
try:
|
||||
keypair = extras_api(request).keypairs.delete(data['keypair_id'])
|
||||
keypair = api.extras_api(request).keypairs.delete(
|
||||
data['keypair_id'])
|
||||
messages.info(request, 'Successfully deleted keypair: %s' \
|
||||
% data['keypair_id'])
|
||||
except api_exceptions.ApiException, e:
|
||||
messages.error(request, 'Error deleting keypair: %s' % e.message)
|
||||
return redirect('dash_keypairs')
|
||||
return shortcuts.redirect(request.build_absolute_uri())
|
||||
|
||||
class CreateKeypair(forms.SelfHandlingForm):
|
||||
name = forms.CharField(max_length="20", label="Keypair Name")
|
||||
|
||||
def handle(self, request, data):
|
||||
try:
|
||||
keypair = extras_api(request).keypairs.create(data['name'])
|
||||
keypair = api.extras_api(request).keypairs.create(data['name'])
|
||||
response = http.HttpResponse(mimetype='application/binary')
|
||||
response['Content-Disposition'] = \
|
||||
'attachment; filename=%s.pem' % \
|
||||
@ -22,19 +69,16 @@ class CreateKeypair(forms.SelfHandlingForm):
|
||||
return response
|
||||
except api_exceptions.ApiException, e:
|
||||
messages.error(request, 'Error Creating Keypair: %s' % e.message)
|
||||
return redirect('dash_keypairs')
|
||||
return shortcuts.redirect(request.build_absolute_uri())
|
||||
|
||||
@login_required
|
||||
def index(request):
|
||||
for f in (DeleteKeypair):
|
||||
_, handled = f.maybe_handle(request)
|
||||
if handled:
|
||||
return handled
|
||||
|
||||
delete_form = DeleteKeypair()
|
||||
def index(request, tenant_id):
|
||||
delete_form, handled = DeleteKeypair.maybe_handle(request)
|
||||
if handled:
|
||||
return handled
|
||||
|
||||
try:
|
||||
keypairs = extras_api(request).keypairs.list()
|
||||
keypairs = api.extras_api(request).keypairs.list()
|
||||
except api_exceptions.ApiException, e:
|
||||
keypairs = []
|
||||
messages.error(request, 'Error featching keypairs: %s' % e.message)
|
||||
@ -45,11 +89,11 @@ def index(request):
|
||||
}, context_instance=template.RequestContext(request))
|
||||
|
||||
@login_required
|
||||
def keypair_create(request):
|
||||
def create(request, tenant_id):
|
||||
form, handled = CreateKeypair.maybe_handle(request)
|
||||
if handled:
|
||||
return handled
|
||||
|
||||
return render_to_response('keypair_create.html', {
|
||||
return render_to_response('dash_keypairs_create.html', {
|
||||
'create_form': form,
|
||||
}, context_instance=template.RequestContext(request))
|
||||
|
@ -4,5 +4,6 @@
|
||||
<li><a {% if current_sidebar == "overview" %} class="active" {% endif %} href="{% url dash_overview %}">Overview</a></li>
|
||||
<li><a {% if current_sidebar == "instances" %} class="active" {% endif %} href="{% url dash_instances request.user.tenant %}">Instances</a></li>
|
||||
<li><a {% if current_sidebar == "images" %} class="active" {% endif %} href="{% url dash_images request.user.tenant %}">Images</a></li>
|
||||
<li><a {% if current_sidebar == "keypairs" %} class="active" {% endif %} href="{% url dash_keypairs request.user.tenant %}">Keypairs</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -1,8 +1,8 @@
|
||||
<form id="form_delete_{{keypair.id}}" class="form-delete" method="post">
|
||||
<form id="form_delete_{{keypair.name}}" class="form-delete" method="post">
|
||||
{% csrf_token %}
|
||||
{% for hidden in form.hidden_fields %}
|
||||
{{hidden}}
|
||||
{% endfor %}
|
||||
<input name="keypair_id" type="hidden" value="{{keypair.id}}" />
|
||||
<input id="delete_{{keypair.id}}" class="delete" type="submit" value="Delete" />
|
||||
<input name="keypair_id" type="hidden" value="{{keypair.name}}" />
|
||||
<input id="delete_{{keypair.name}}" class="delete" type="submit" value="Delete" />
|
||||
</form>
|
||||
|
10
openstack-dashboard/dashboard/templates/_keypair_form.html
Normal file
10
openstack-dashboard/dashboard/templates/_keypair_form.html
Normal file
@ -0,0 +1,10 @@
|
||||
<form id="keypair_form" method="post">
|
||||
{% csrf_token %}
|
||||
{% for hidden in form.hidden_fields %}{{ hidden }}{% endfor %}
|
||||
{% for field in form.visible_fields %}
|
||||
{{ field.label_tag }}
|
||||
{{ field.errors }}
|
||||
{{ field }}
|
||||
{% endfor %}
|
||||
<input type="submit" value="Create Keypair" class="large-rounded" />
|
||||
</form>
|
@ -1,12 +1,10 @@
|
||||
<table id="images" style="width: 100%">
|
||||
<table id="keypairs" style="width: 100%">
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th>Created</th>
|
||||
<th>Updated</th>
|
||||
<th colspan="2">Status</th>
|
||||
<th>Fingerprint</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
{% for image in images %}
|
||||
{% for keypair in keypairs %}
|
||||
<tr class="{% cycle 'odd' 'even' %}">
|
||||
<td>{{ keypair.name }}</td>
|
||||
<td>{{ keypair.fingerprint }}</td>
|
||||
|
@ -29,75 +29,10 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include '_kepair_list.html' %}
|
||||
{% include '_keypair_list.html' %}
|
||||
|
||||
{% endif %}
|
||||
<a id="keypairs_create_link" href="{% url dash_keypairs_create request.user.tenant %}">Create New Keypair >></a>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
||||
{% extends 'base.html' %}
|
||||
{% load sidebar_tags %}
|
||||
|
||||
{% block nav_pages %}
|
||||
{% sidebar_select keypairs %}
|
||||
{{ block.super }}
|
||||
{% endblock %}
|
||||
|
||||
{% block main_content %}
|
||||
<div id='page_header'>
|
||||
<h2><span>Compute:</span> Keypairs</h2>
|
||||
<p class='desc'><span>—</span> Keypairs blah blah.</p>
|
||||
</div>
|
||||
{% include "_messages.html" %}
|
||||
{% if keypairs %}
|
||||
<div class='main_content'>
|
||||
<div class='table_title wide'>
|
||||
<h3>Keypairs</h3>
|
||||
<div class='search'>
|
||||
<form action='' method='post'>
|
||||
<fieldset>
|
||||
<label for='table_search'>Search</label>
|
||||
<input id='table_search' name='search' type='text' value='' />
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<table id='keypairs' class='wide'>
|
||||
<tr id='headings'>
|
||||
<th>Name</th>
|
||||
<th>Fingerprint</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
<tbody class='main'>
|
||||
{% for keypair in keypairs %}
|
||||
<tr class="{% cycle 'odd' 'even' %}">
|
||||
<td>{{ keypair.name }}</td>
|
||||
<td>{{ keypair.fingerprint }}</td>
|
||||
<td id="actions">
|
||||
<ul>
|
||||
<li>
|
||||
<form id="form_keypair_{{ keypair.name }}" class="form-keypair-delete" method="post" action="{% url novaO_keypair_delete keypair.name %}" >
|
||||
{% csrf_token %}
|
||||
<input name="name" type="hidden" value="{{ keypair.name }}" />
|
||||
<input id="delete_{{keypair.name}}" title="keypair: {{keypair.name}}" class="terminate delete_link" type="submit" value="Delete" />
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<div class="status_box info">
|
||||
<h2>Info</h2>
|
||||
<p>There are currently no keypairs.<br/><br/>You can create a keypair here <a href='{% url novaO_images %}'>Images Page.</a></p>
|
||||
</div>
|
||||
{% endif %}
|
||||
<a id="keypair_create_link" href="{% url novaO_keypair_create %}">Create New Keypair>></a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock main_content %}
|
||||
|
||||
|
@ -0,0 +1,55 @@
|
||||
{% extends 'dash_base.html' %}
|
||||
{# list of user's instances #}
|
||||
{# standard nav, sidebar, list of instances in main #}
|
||||
|
||||
{% block sidebar %}
|
||||
{% with current_sidebar="keypairs" %}
|
||||
{{block.super}}
|
||||
{% endwith %}
|
||||
{% endblock %}
|
||||
|
||||
{% block headerjs %}
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
$(function(){
|
||||
$(".dash_block .left h3").hide()
|
||||
$("form input[type='submit']").click(function(e){
|
||||
$("form").hide("fast")
|
||||
$(".dash_block h3").show("fast")
|
||||
console.log($(this).parent().submit());
|
||||
e.preventDefault()
|
||||
})
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block main %}
|
||||
<div id='page_header'>
|
||||
<h2><span>Dashboard:</span> Keypairs </h2>
|
||||
<p class='desc'><span>—</span> Create a keypair </p>
|
||||
</div>
|
||||
|
||||
{% include "_messages.html" %}
|
||||
|
||||
|
||||
<div class="main_content">
|
||||
<div class="dash_block wide form">
|
||||
<div class='title_block'>
|
||||
<h3>Create User</h3>
|
||||
</div>
|
||||
<div class="left">
|
||||
<h3>Your private key is being downloaded.</h3>
|
||||
{% include '_keypair_form.html' with form=create_form %}
|
||||
<h3><a href="{% url dash_keypairs request.user.tenant %}"><< Return to keypairs list</a></h3>
|
||||
</div>
|
||||
|
||||
<div class="right">
|
||||
<h3>Description:</h3>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus vitae est urna. Phasellus sagittis, sem posuere hendrerit mattis, velit risus viverra enim, tempus dapibus sem turpis ac erat.</p>
|
||||
<p>Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed mollis ligula nec lacus mollis eu laoreet lectus porta. </p>
|
||||
<p>Sed iaculis mauris et est consectetur egestas. Praesent dolor libero, semper sed aliquet</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
@ -1,7 +1,3 @@
|
||||
/* @override http://looce.com:8080/media/dashboard/css/style.css */
|
||||
|
||||
/* @override http://looce.com:8080/media/dashboard/css/style.css */
|
||||
|
||||
@import url("reset.css");
|
||||
|
||||
@font-face {
|
||||
@ -753,6 +749,10 @@ table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.left {
|
||||
width: 358px;
|
||||
float: left;
|
||||
}
|
||||
.dash_block .right {
|
||||
float: left;
|
||||
width: 303px;
|
||||
@ -768,12 +768,17 @@ table {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.dash_block .right h3 {
|
||||
.dash_block .right h3, .dash_block .left h3 {
|
||||
color: #939393;
|
||||
font-size: 18px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.dash_block .left h3 {
|
||||
padding: 20px;
|
||||
color: green;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1133,7 +1138,6 @@ ol li.first a {
|
||||
|
||||
.status_box h2 {
|
||||
font-weight: normal;
|
||||
border-right: 1px solid;
|
||||
float: left;
|
||||
padding: 20px;
|
||||
min-width: 120px;
|
||||
@ -1149,6 +1153,8 @@ ol li.first a {
|
||||
font-size: 14px;
|
||||
float: left;
|
||||
padding: 20px;
|
||||
width: 501px;
|
||||
border-left: 1px solid;
|
||||
}
|
||||
|
||||
|
||||
@ -1235,7 +1241,7 @@ a.refresh:hover {
|
||||
|
||||
.usage_block {
|
||||
float: left;
|
||||
width: 166px;
|
||||
width: 227px;
|
||||
background: #e8f8ff;
|
||||
color: #84b6c5;
|
||||
margin-right: 13px;
|
||||
@ -1243,7 +1249,7 @@ a.refresh:hover {
|
||||
-moz-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #afe3fb;
|
||||
min-height: 180px;
|
||||
min-height: 150px;
|
||||
}
|
||||
|
||||
.usage_block h3 {
|
||||
@ -1469,8 +1475,8 @@ input.example, textarea.example {color: #d9d9d9;}
|
||||
border-bottom: 1px solid #d6e4d9;
|
||||
border-left: 1px solid #d6e4d9;
|
||||
margin-left: -1px;
|
||||
margin-top: -5px;
|
||||
padding-top: 12px;
|
||||
margin-top: -12px;
|
||||
}
|
||||
|
||||
#drop_btn {
|
||||
@ -1523,6 +1529,7 @@ a#current_tenant {
|
||||
padding-left: 25px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
border-color: #a9deb6;
|
||||
}
|
||||
|
||||
#user_bar li a:hover{
|
||||
@ -1544,16 +1551,43 @@ li#sign_out a:hover {
|
||||
li.title h4{
|
||||
padding-left: 25px;
|
||||
color: #7ab789;
|
||||
padding-top: 10px;
|
||||
text-transform: uppercase;
|
||||
font-size: 10px;
|
||||
font-weight: normal;
|
||||
border-bottom: 1px dotted;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.note p strong {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
#monitoring {
|
||||
width: 665px;
|
||||
background: #fbfbfb;
|
||||
float: left;
|
||||
margin-top: -25px;
|
||||
border: 1px solid #f3f3f3;
|
||||
padding: 10px;
|
||||
margin-left: 5px;
|
||||
font-size: 14px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
#monitoring h3 {
|
||||
font-weight: normal;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#external_links {
|
||||
float: left;
|
||||
}
|
||||
|
||||
#external_links li {
|
||||
float: left;
|
||||
margin-left: 25px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,20 +1,36 @@
|
||||
$(function(){
|
||||
$("#login").hide()
|
||||
$("#login_btn").click(function(){
|
||||
$("#login").toggle("fast")
|
||||
})
|
||||
|
||||
$('input#table_search').quicksearch('tr.odd, tr.even');
|
||||
|
||||
|
||||
|
||||
// show+hide image details
|
||||
$(".details").hide()
|
||||
$("td").click(function(e){
|
||||
$(this).parent().nextUntil(".even, .odd").fadeToggle("slow")
|
||||
$(this).parent().nextUntil(".even, .odd").fadeToggle("slow");
|
||||
})
|
||||
|
||||
|
||||
$("#user_tenant_list").hide()
|
||||
$("#drop_btn").click(function(){
|
||||
$("#user_tenant_list").toggle()
|
||||
$("#user_tenant_list").toggle();
|
||||
})
|
||||
|
||||
|
||||
// confirmation on deletion of items
|
||||
$(".delete_link").click(function(e){
|
||||
var response = confirm('Are you sure you want to delete the '+$(this).attr('title')+" ?");
|
||||
return response;
|
||||
})
|
||||
|
||||
$(".reboot_link").click(function(e){
|
||||
var response = confirm('Are you sure you want to reboot the '+$(this).attr('title')+" ?");
|
||||
return response;
|
||||
})
|
||||
|
||||
|
||||
// disable multiple submissions when launching a form
|
||||
$("form").submit(function() {
|
||||
$(this).submit(function() {
|
||||
return false;
|
||||
});
|
||||
return true;
|
||||
});
|
||||
|
||||
})
|
Loading…
x
Reference in New Issue
Block a user