mirror of
https://github.com/retspen/webvirtcloud
synced 2025-02-03 02:55:18 +00:00
add Compute instances tab. Minimal invasion. minimal change. keep structure
This commit is contained in:
parent
e44e01cad4
commit
25e6381fc9
21 changed files with 618 additions and 335 deletions
|
@ -17,7 +17,7 @@
|
|||
<h2 class="form-signin-heading">{% trans "Sign In" %}</h2>
|
||||
<input type="text" class="form-control" name="username" placeholder="Login" autocapitalize="none" autocorrect="off" autofocus>
|
||||
<input type="password" class="form-control" name="password" placeholder="Password">
|
||||
<input name="next" id="next" type="hidden" value="{% url 'instances' %}">
|
||||
<input name="next" id="next" type="hidden" value="{% url 'allinstances' %}">
|
||||
<button class="btn btn-lg btn-success btn-block" type="submit">{% trans "Sign In" %}</button>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
<li class="active">
|
||||
<i class="fa fa-dashboard"></i> {% trans "Overview" %}
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-server"></i> <a href="{% url 'instances' compute.id %}">{% trans "Instances" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a>
|
||||
</li>
|
||||
|
|
|
@ -1,9 +1,26 @@
|
|||
from django.conf.urls import url
|
||||
from . import views
|
||||
from storages.views import storages, storage
|
||||
from networks.views import networks, network
|
||||
from secrets.views import secrets
|
||||
from create.views import create_instance
|
||||
from interfaces.views import interfaces, interface
|
||||
from computes.views import overview, compute_graph, computes
|
||||
from instances.views import instances
|
||||
from nwfilters.views import nwfilter, nwfilters
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', views.computes, name='computes'),
|
||||
url(r'^overview/(?P<compute_id>[0-9]+)/$', views.overview, name='overview'),
|
||||
url(r'^statistics/(?P<compute_id>[0-9]+)/$',
|
||||
views.compute_graph, name='compute_graph'),
|
||||
url(r'^/', computes, name='computes'),
|
||||
url(r'^(?P<compute_id>[0-9]+)/$', overview, name='overview'),
|
||||
url(r'^(?P<compute_id>[0-9]+)/statistics$', compute_graph, name='compute_graph'),
|
||||
url(r'^(?P<compute_id>[0-9]+)/instances/$', instances, name='instances'),
|
||||
url(r'^(?P<compute_id>[0-9]+)/storages/$', storages, name='storages'),
|
||||
url(r'^(?P<compute_id>[0-9]+)/storage/(?P<pool>[\w\-\.\/]+)/$', storage, name='storage'),
|
||||
url(r'^(?P<compute_id>[0-9]+)/networks/$', networks, name='networks'),
|
||||
url(r'^(?P<compute_id>[0-9]+)/network/(?P<pool>[\w\-\.]+)/$', network, name='network'),
|
||||
url(r'^(?P<compute_id>[0-9]+)/interfaces/$', interfaces, name='interfaces'),
|
||||
url(r'^(?P<compute_id>[0-9]+)/interface/(?P<iface>[\w\-\.\:]+)/$', interface, name='interface'),
|
||||
url(r'^(?P<compute_id>[0-9]+)/nwfilters/$', nwfilters, name='nwfilters'),
|
||||
url(r'^(?P<compute_id>[0-9]+)/nwfilter/(?P<nwfltr>[\w\-\.\:]+)/$', nwfilter, name='nwfilter'),
|
||||
url(r'^(?P<compute_id>[0-9]+)/secrets/$', secrets, name='secrets'),
|
||||
url(r'^(?P<compute_id>[0-9]+)/create/$', create_instance, name='create_instance'),
|
||||
]
|
||||
|
|
184
instances/templates/allinstances.html
Normal file
184
instances/templates/allinstances.html
Normal file
|
@ -0,0 +1,184 @@
|
|||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
{% load staticfiles %}
|
||||
{% block title %}{% trans "Instances" %}{% endblock %}
|
||||
{% block style %}
|
||||
<link rel="stylesheet" href="{% static "css/sortable-theme-bootstrap.css" %}" />
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<!-- Page Heading -->
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
{% if request.user.is_superuser %}
|
||||
{% include 'create_inst_block.html' %}
|
||||
{% endif %}
|
||||
{% if all_host_vms or all_user_vms %}
|
||||
<div class="pull-right search">
|
||||
<input id="filter" class="form-control" type="text" placeholder="Search">
|
||||
</div>
|
||||
{% endif %}
|
||||
<h1 class="page-header">{% trans "Instances" %}</h1>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
|
||||
{% include 'errors_block.html' %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="table-responsive">
|
||||
{% if request.user.is_superuser %}
|
||||
{% if not all_host_vms %}
|
||||
<div class="col-lg-12">
|
||||
<div class="alert alert-warning alert-dismissable">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning:" %}</strong> {% trans "You don't have any Instance" %}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
{% ifequal view_style "nongrouped" %}
|
||||
{% include 'allinstances_index_nongrouped.html' %}
|
||||
{% endifequal %}
|
||||
{% ifequal view_style "grouped" %}
|
||||
{% include 'allinstances_index_grouped.html' %}
|
||||
{% endifequal %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if not all_user_vms %}
|
||||
<div class="col-lg-12">
|
||||
<div class="alert alert-warning alert-dismissable">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning:" %}</strong> {% trans "You don't have any Instance" %}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<table class="table table-hover table-striped sortable-theme-bootstrap" data-sortable>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Status</th>
|
||||
<th>VCPU</th>
|
||||
<th>Memory</th>
|
||||
<th data-sortable="false" style="width: 165px;">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="searchable">
|
||||
{% for inst, vm in all_user_vms.items %}
|
||||
<tr>
|
||||
<td><a href="{% url 'instance' vm.compute_id vm.name %}">{{ vm.name }}</a><br><small><em>{{ vm.title }}</em></small></td>
|
||||
<td>{% ifequal vm.status 1 %}
|
||||
<span class="text-success">{% trans "Active" %}</span>
|
||||
{% endifequal %}
|
||||
{% ifequal vm.status 5 %}
|
||||
<span class="text-danger">{% trans "Off" %}</span>
|
||||
{% endifequal %}
|
||||
{% ifequal vm.status 3 %}
|
||||
<span class="text-warning">{% trans "Suspend" %}</span>
|
||||
{% endifequal %}
|
||||
</td>
|
||||
<td>{{ vm.vcpu }}</td>
|
||||
<td>{{ vm.memory }} {% trans "MB" %}</td>
|
||||
<td><form action="" method="post" role="form">{% csrf_token %}
|
||||
<input type="hidden" name="name" value="{{ vm.name }}"/>
|
||||
<input type="hidden" name="compute_id" value="{{ vm.compute_id }}"/>
|
||||
{% ifequal vm.status 5 %}
|
||||
{% if inst.instance.is_template %}
|
||||
<button class="btn btn-sm btn-default" type="button" name="clone" title="{% trans "Clone" %}" onclick="goto_instance_clone({{ vm.compute_id }}, '{{ vm.name }}');">
|
||||
<span class="glyphicon glyphicon-duplicate"></span>
|
||||
</button>
|
||||
{% else %}
|
||||
<button class="btn btn-sm btn-default" type="submit" name="poweron" title="{% trans "Power On" %}">
|
||||
<span class="glyphicon glyphicon-play"></span>
|
||||
</button>
|
||||
{% endif %}
|
||||
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Off" %}">
|
||||
<span class="glyphicon glyphicon-off"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Cycle" %}">
|
||||
<span class="glyphicon glyphicon-refresh"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-default disabled" title="{% trans "VNC Console" %}">
|
||||
<span class="glyphicon glyphicon-eye-open"></span>
|
||||
</button>
|
||||
{% endifequal %}
|
||||
{% ifequal vm.status 3 %}
|
||||
<button class="btn btn-sm btn-default disabled" title="{% trans "Power On" %}">
|
||||
<span class="glyphicon glyphicon-play"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Off" %}">
|
||||
<span class="glyphicon glyphicon-off"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Cycle" %}">
|
||||
<span class="glyphicon glyphicon-refresh"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-default disabled" title="{% trans "VNC/Spice Console" %}">
|
||||
<span class="glyphicon glyphicon-eye-open"></span>
|
||||
</button>
|
||||
{% endifequal %}
|
||||
{% ifequal vm.status 1 %}
|
||||
<button class="btn btn-sm btn-default disabled" title="{% trans "Power On" %}">
|
||||
<span class="glyphicon glyphicon-play"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-default" type="submit" name="poweroff" title="{% trans "Power Off" %}">
|
||||
<span class="glyphicon glyphicon-off"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-default" type="submit" name="powercycle" title="{% trans "Power Cycle" %}" onclick="return confirm('Are you sure?')">
|
||||
<span class="glyphicon glyphicon-refresh"></span>
|
||||
</button>
|
||||
<a href="#" class="btn btn-sm btn-default" onclick='open_console("{{ vm.compute_id }}-{{ vm.uuid }}")' title="{% trans "Console" %}">
|
||||
<span class="glyphicon glyphicon-eye-open"></span>
|
||||
</a>
|
||||
{% endifequal %}
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block script %}
|
||||
<script src="{% static "js/sortable.min.js" %}"></script>
|
||||
<script>
|
||||
function open_console(uuid) {
|
||||
window.open("{% url 'console' %}?token=" + uuid, "", "width=850,height=485");
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
function filter_table() {
|
||||
var rex = new RegExp($(this).val(), 'i');
|
||||
$('.searchable tr').hide();
|
||||
$('.searchable tr').filter(function () {
|
||||
return rex.test($(this).text());
|
||||
}).show();
|
||||
Cookies.set("instances_filter", $(this).val(), { expires: 1 });
|
||||
}
|
||||
$(document).ready(function () {
|
||||
instances_filter_cookie = Cookies.get("instances_filter");
|
||||
if (instances_filter_cookie) {
|
||||
$('#filter').val(instances_filter_cookie);
|
||||
$('#filter').each(filter_table);
|
||||
}
|
||||
(function ($) {
|
||||
$('#filter').keyup(filter_table)
|
||||
}(jQuery));
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
function goto_instance_clone(compute, instance) {
|
||||
window.location = "/instance/" + compute + "/" + instance + "/#clone";
|
||||
}
|
||||
</script>
|
||||
{% if request.user.is_superuser %}
|
||||
<script>
|
||||
function goto_compute() {
|
||||
var compute = $("#compute_select").val();
|
||||
window.location = "/compute/" + compute + "/create/";
|
||||
}
|
||||
</script>
|
||||
{% endif %}
|
||||
{% endblock %}
|
|
@ -1,7 +1,7 @@
|
|||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
{% load staticfiles %}
|
||||
{% block title %}{% trans "Instances" %}{% endblock %}
|
||||
{% block title %}{% trans "Instances" %} - {{ compute.name }}{% endblock %}
|
||||
{% block style %}
|
||||
<link rel="stylesheet" href="{% static "css/sortable-theme-bootstrap.css" %}" />
|
||||
{% endblock %}
|
||||
|
@ -17,73 +17,80 @@
|
|||
<input id="filter" class="form-control" type="text" placeholder="Search">
|
||||
</div>
|
||||
{% endif %}
|
||||
<h1 class="page-header">{% trans "Instances" %}</h1>
|
||||
<h1 class="page-header">{{ compute.name }}</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
|
||||
<ol class="breadcrumb">
|
||||
<li class="active">
|
||||
<i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-server"></i> {% trans "Instances" %}
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-sitemap"></i> <a href="{% url 'networks' compute.id %}">{% trans "Networks" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-wifi"></i> <a href="{% url 'interfaces' compute.id %}">{% trans "Interfaces" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-filter"></i> <a href="{% url 'nwfilters' compute.id %}">{% trans "NWFilters" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-key"></i> <a href="{% url 'secrets' compute.id %}">{% trans "Secrets" %}</a>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
|
||||
{% include 'errors_block.html' %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="table-responsive">
|
||||
{% if request.user.is_superuser %}
|
||||
{% if not all_host_vms %}
|
||||
<div class="col-lg-12">
|
||||
<div class="alert alert-warning alert-dismissable">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning:" %}</strong> {% trans "You don't have any Instance" %}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
{% ifequal view_style "nongrouped" %}
|
||||
{% include 'instances_nongrouped.html' %}
|
||||
{% endifequal %}
|
||||
{% ifequal view_style "grouped" %}
|
||||
{% include 'instances_grouped.html' %}
|
||||
{% endifequal %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if not all_user_vms %}
|
||||
<div class="col-lg-12">
|
||||
<div class="alert alert-warning alert-dismissable">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning:" %}</strong> {% trans "You don't have any Instance" %}
|
||||
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning:" %}</strong> {% trans "Hypervisor doesn't have any instances" %}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="col-lg-12">
|
||||
<table class="table table-hover table-striped sortable-theme-bootstrap" data-sortable>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Name<br>Description</th>
|
||||
<th>Host<br>User</th>
|
||||
<th>Status</th>
|
||||
<th>VCPU</th>
|
||||
<th>Memory</th>
|
||||
<th data-sortable="false" style="width: 165px;">Actions</th>
|
||||
<th data-sortable="false" style="width:205px;">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="searchable">
|
||||
{% for inst, vm in all_user_vms.items %}
|
||||
{% for host, inst in all_host_vms.items %}
|
||||
{% for vm, info in inst.items %}
|
||||
<tr>
|
||||
<td><a href="{% url 'instance' vm.compute_id vm.name %}">{{ vm.name }}</a><br><small><em>{{ vm.title }}</em></small></td>
|
||||
<td>{% ifequal vm.status 1 %}
|
||||
<span class="text-success">{% trans "Active" %}</span>
|
||||
{% endifequal %}
|
||||
{% ifequal vm.status 5 %}
|
||||
<span class="text-danger">{% trans "Off" %}</span>
|
||||
{% endifequal %}
|
||||
{% ifequal vm.status 3 %}
|
||||
<span class="text-warning">{% trans "Suspend" %}</span>
|
||||
{% endifequal %}
|
||||
<td><a href="{% url 'instance' host.0 vm %}">{{ vm }}</a><br><small><em>{{ info.title }}</em></small></td>
|
||||
<td><a href="{% url 'overview' host.0 %}">{{ host.1 }}</a><br><small><em>{% if info.userinstances.count > 0 %}{{ info.userinstances.first_user.user.username }}{% if info.userinstances.count > 1 %} (+{{ info.userinstances.count|add:"-1" }}){% endif %}{% endif %}</em></small></td>
|
||||
<td>
|
||||
{% ifequal info.status 1 %}<span class="text-success">{% trans "Active" %}</span>{% endifequal %}
|
||||
{% ifequal info.status 5 %}<span class="text-danger">{% trans "Off" %}</span>{% endifequal %}
|
||||
{% ifequal info.status 3 %}<span class="text-warning">{% trans "Suspend" %}</span>{% endifequal %}
|
||||
</td>
|
||||
<td>{{ vm.vcpu }}</td>
|
||||
<td>{{ vm.memory }} {% trans "MB" %}</td>
|
||||
<td>{{ info.vcpu }}</td>
|
||||
<td>{{ info.memory|filesizeformat }}</td>
|
||||
<td><form action="" method="post" role="form">{% csrf_token %}
|
||||
<input type="hidden" name="name" value="{{ vm.name }}"/>
|
||||
<input type="hidden" name="compute_id" value="{{ vm.compute_id }}"/>
|
||||
{% ifequal vm.status 5 %}
|
||||
{% if inst.instance.is_template %}
|
||||
<button class="btn btn-sm btn-default" type="button" name="clone" title="{% trans "Clone" %}" onclick="goto_instance_clone({{ vm.compute_id }}, '{{ vm.name }}');">
|
||||
<input type="hidden" name="name" value="{{ vm }}"/>
|
||||
<input type="hidden" name="compute_id" value="{{ host.0 }}"/>
|
||||
{% ifequal info.status 5 %}
|
||||
{% if info.is_template %}
|
||||
<button class="btn btn-sm btn-default" type="button" name="clone" title="{% trans "Clone" %}" onclick="goto_instance_clone({{ host.0 }}, '{{ vm }}');">
|
||||
<span class="glyphicon glyphicon-duplicate"></span>
|
||||
</button>
|
||||
{% else %}
|
||||
|
@ -91,6 +98,9 @@
|
|||
<span class="glyphicon glyphicon-play"></span>
|
||||
</button>
|
||||
{% endif %}
|
||||
<button class="btn btn-sm btn-default disabled" title="{% trans "Suspend" %}">
|
||||
<span class="glyphicon glyphicon-pause"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Off" %}">
|
||||
<span class="glyphicon glyphicon-off"></span>
|
||||
</button>
|
||||
|
@ -101,31 +111,37 @@
|
|||
<span class="glyphicon glyphicon-eye-open"></span>
|
||||
</button>
|
||||
{% endifequal %}
|
||||
{% ifequal vm.status 3 %}
|
||||
<button class="btn btn-sm btn-default disabled" title="{% trans "Power On" %}">
|
||||
{% ifequal info.status 3 %}
|
||||
<button class="btn btn-sm btn-default" type="submit" name="resume" title="{% trans "Resume" %}">
|
||||
<span class="glyphicon glyphicon-play"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-default disabled" title="{% trans "Suspend" %}">
|
||||
<span class="glyphicon glyphicon-pause"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Off" %}">
|
||||
<span class="glyphicon glyphicon-off"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Cycle" %}">
|
||||
<span class="glyphicon glyphicon-refresh"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-default disabled" title="{% trans "VNC/Spice Console" %}">
|
||||
<button class="btn btn-sm btn-default disabled" title="{% trans "VNC Console" %}">
|
||||
<span class="glyphicon glyphicon-eye-open"></span>
|
||||
</button>
|
||||
{% endifequal %}
|
||||
{% ifequal vm.status 1 %}
|
||||
{% ifequal info.status 1 %}
|
||||
<button class="btn btn-sm btn-default disabled" title="{% trans "Power On" %}">
|
||||
<span class="glyphicon glyphicon-play"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-default" type="submit" name="poweroff" title="{% trans "Power Off" %}">
|
||||
<button class="btn btn-sm btn-default" type="submit" name="suspend" title="{% trans "Suspend" %}">
|
||||
<span class="glyphicon glyphicon-pause"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-default" type="submit" name="poweroff" title="{% trans "Power Off" %}" onclick="return confirm('Are you sure?')">
|
||||
<span class="glyphicon glyphicon-off"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-default" type="submit" name="powercycle" title="{% trans "Power Cycle" %}" onclick="return confirm('Are you sure?')">
|
||||
<span class="glyphicon glyphicon-refresh"></span>
|
||||
</button>
|
||||
<a href="#" class="btn btn-sm btn-default" onclick='open_console("{{ vm.compute_id }}-{{ vm.uuid }}")' title="{% trans "Console" %}">
|
||||
<a href="#" class="btn btn-sm btn-default" onclick='open_console("{{ host.0 }}-{{ info.uuid }}")' title="{% trans "Console" %}">
|
||||
<span class="glyphicon glyphicon-eye-open"></span>
|
||||
</a>
|
||||
{% endifequal %}
|
||||
|
@ -133,12 +149,11 @@
|
|||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block script %}
|
||||
|
|
|
@ -2,6 +2,7 @@ from django.conf.urls import url
|
|||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', views.allinstances, name='allinstances'),
|
||||
url(r'^(?P<compute_id>[0-9]+)/(?P<vname>[\w\-\.]+)/$', views.instance, name='instance'),
|
||||
url(r'^statistics/(?P<compute_id>[0-9]+)/(?P<vname>[\w\-\.]+)/$', views.inst_graph, name='inst_graph'),
|
||||
url(r'^status/(?P<compute_id>[0-9]+)/(?P<vname>[\w\-\.]+)/$', views.inst_status, name='inst_status'),
|
||||
|
|
|
@ -26,175 +26,72 @@ from logs.views import addlogmsg
|
|||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
|
||||
|
||||
@login_required
|
||||
def index(request):
|
||||
"""
|
||||
:param request:
|
||||
:return:
|
||||
"""
|
||||
|
||||
return HttpResponseRedirect(reverse('instances'))
|
||||
return HttpResponseRedirect(reverse('allinstances'))
|
||||
|
||||
|
||||
@login_required
|
||||
def instances(request):
|
||||
def allinstances(request):
|
||||
"""
|
||||
INSTANCES LIST FOR ALL HOSTS
|
||||
:param request:
|
||||
:return:
|
||||
"""
|
||||
all_host_vms = {}
|
||||
error_messages = []
|
||||
computes = Compute.objects.all().order_by("name")
|
||||
|
||||
if not request.user.is_superuser:
|
||||
all_user_vms = get_user_instances(request)
|
||||
else:
|
||||
for comp in computes:
|
||||
try:
|
||||
all_host_vms.update(get_host_instances(request,comp))
|
||||
except libvirtError as lib_err:
|
||||
error_messages.append(lib_err)
|
||||
|
||||
if request.method == 'POST':
|
||||
try:
|
||||
instances_actions(request)
|
||||
except libvirtError as lib_err:
|
||||
error_messages.append(lib_err)
|
||||
addlogmsg(request.user.username, instance.name, lib_err.message)
|
||||
|
||||
view_style = settings.VIEW_INSTANCES_LIST_STYLE
|
||||
|
||||
return render(request, 'allinstances.html', locals())
|
||||
|
||||
|
||||
@login_required
|
||||
def instances(request, compute_id):
|
||||
"""
|
||||
:param request:
|
||||
:return:
|
||||
"""
|
||||
|
||||
error_messages = []
|
||||
all_host_vms = {}
|
||||
all_user_vms = {}
|
||||
computes = Compute.objects.all().order_by("name")
|
||||
|
||||
def get_userinstances_info(instance):
|
||||
info = {}
|
||||
uis = UserInstance.objects.filter(instance=instance)
|
||||
info['count'] = uis.count()
|
||||
if info['count'] > 0:
|
||||
info['first_user'] = uis[0]
|
||||
else:
|
||||
info['first_user'] = None
|
||||
return info
|
||||
|
||||
def refresh_instance_database(comp, vm, info):
|
||||
instances = Instance.objects.filter(name=vm)
|
||||
if instances.count() > 1:
|
||||
for i in instances:
|
||||
user_instances_count = UserInstance.objects.filter(instance=i).count()
|
||||
if user_instances_count == 0:
|
||||
addlogmsg(request.user.username, i.name, _("Deleting due to multiple records."))
|
||||
i.delete()
|
||||
|
||||
try:
|
||||
check_uuid = Instance.objects.get(compute_id=comp["id"], name=vm)
|
||||
if check_uuid.uuid != info['uuid']:
|
||||
check_uuid.save()
|
||||
|
||||
all_host_vms[comp["id"],
|
||||
comp["name"],
|
||||
comp["status"],
|
||||
comp["cpu"],
|
||||
comp["mem_size"],
|
||||
comp["mem_perc"]][vm]['is_template'] = check_uuid.is_template
|
||||
all_host_vms[comp["id"],
|
||||
comp["name"],
|
||||
comp["status"],
|
||||
comp["cpu"],
|
||||
comp["mem_size"],
|
||||
comp["mem_perc"]][vm]['userinstances'] = get_userinstances_info(check_uuid)
|
||||
except Instance.DoesNotExist:
|
||||
check_uuid = Instance(compute_id=comp["id"], name=vm, uuid=info['uuid'])
|
||||
check_uuid.save()
|
||||
compute = get_object_or_404(Compute, pk=compute_id)
|
||||
|
||||
if not request.user.is_superuser:
|
||||
user_instances = UserInstance.objects.filter(user_id=request.user.id)
|
||||
for usr_inst in user_instances:
|
||||
if connection_manager.host_is_up(usr_inst.instance.compute.type,
|
||||
usr_inst.instance.compute.hostname):
|
||||
conn = wvmHostDetails(usr_inst.instance.compute,
|
||||
usr_inst.instance.compute.login,
|
||||
usr_inst.instance.compute.password,
|
||||
usr_inst.instance.compute.type)
|
||||
all_user_vms[usr_inst] = conn.get_user_instances(usr_inst.instance.name)
|
||||
all_user_vms[usr_inst].update({'compute_id': usr_inst.instance.compute.id})
|
||||
all_user_vms = get_user_instances(request)
|
||||
else:
|
||||
for comp in computes:
|
||||
status = connection_manager.host_is_up(comp.type, comp.hostname)
|
||||
if status:
|
||||
try:
|
||||
conn = wvmHostDetails(comp, comp.login, comp.password, comp.type)
|
||||
comp_node_info = conn.get_node_info()
|
||||
comp_mem = conn.get_memory_usage()
|
||||
comp_instances = conn.get_host_instances(True)
|
||||
|
||||
if comp_instances:
|
||||
comp_info= {
|
||||
"id": comp.id,
|
||||
"name": comp.name,
|
||||
"status": status,
|
||||
"cpu": comp_node_info[3],
|
||||
"mem_size": comp_node_info[2],
|
||||
"mem_perc": comp_mem['percent']
|
||||
}
|
||||
all_host_vms[comp_info["id"], comp_info["name"], comp_info["status"], comp_info["cpu"],
|
||||
comp_info["mem_size"], comp_info["mem_perc"]] = comp_instances
|
||||
for vm, info in comp_instances.items():
|
||||
refresh_instance_database(comp_info, vm, info)
|
||||
|
||||
conn.close()
|
||||
all_host_vms = get_host_instances(request, compute)
|
||||
except libvirtError as lib_err:
|
||||
error_messages.append(lib_err)
|
||||
|
||||
if request.method == 'POST':
|
||||
name = request.POST.get('name', '')
|
||||
compute_id = request.POST.get('compute_id', '')
|
||||
instance = Instance.objects.get(compute_id=compute_id, name=name)
|
||||
try:
|
||||
conn = wvmInstances(instance.compute.hostname,
|
||||
instance.compute.login,
|
||||
instance.compute.password,
|
||||
instance.compute.type)
|
||||
if 'poweron' in request.POST:
|
||||
msg = _("Power On")
|
||||
addlogmsg(request.user.username, instance.name, msg)
|
||||
conn.start(name)
|
||||
return HttpResponseRedirect(request.get_full_path())
|
||||
|
||||
if 'poweroff' in request.POST:
|
||||
msg = _("Power Off")
|
||||
addlogmsg(request.user.username, instance.name, msg)
|
||||
conn.shutdown(name)
|
||||
return HttpResponseRedirect(request.get_full_path())
|
||||
|
||||
if 'powercycle' in request.POST:
|
||||
msg = _("Power Cycle")
|
||||
conn.force_shutdown(name)
|
||||
conn.start(name)
|
||||
addlogmsg(request.user.username, instance.name, msg)
|
||||
return HttpResponseRedirect(request.get_full_path())
|
||||
|
||||
if 'getvvfile' in request.POST:
|
||||
msg = _("Send console.vv file")
|
||||
addlogmsg(request.user.username, instance.name, msg)
|
||||
response = HttpResponse(content='', content_type='application/x-virt-viewer', status=200, reason=None, charset='utf-8')
|
||||
response.writelines('[virt-viewer]\n')
|
||||
response.writelines('type=' + conn.graphics_type(name) + '\n')
|
||||
response.writelines('host=' + conn.graphics_listen(name) + '\n')
|
||||
response.writelines('port=' + conn.graphics_port(name) + '\n')
|
||||
response.writelines('title=' + conn.domain_name(name) + '\n')
|
||||
response.writelines('password=' + conn.graphics_passwd(name) + '\n')
|
||||
response.writelines('enable-usbredir=1\n')
|
||||
response.writelines('disable-effects=all\n')
|
||||
response.writelines('secure-attention=ctrl+alt+ins\n')
|
||||
response.writelines('release-cursor=ctrl+alt\n')
|
||||
response.writelines('fullscreen=1\n')
|
||||
response.writelines('delete-this-file=1\n')
|
||||
response['Content-Disposition'] = 'attachment; filename="console.vv"'
|
||||
return response
|
||||
|
||||
if request.user.is_superuser:
|
||||
|
||||
if 'suspend' in request.POST:
|
||||
msg = _("Suspend")
|
||||
addlogmsg(request.user.username, instance.name, msg)
|
||||
conn.suspend(name)
|
||||
return HttpResponseRedirect(request.get_full_path())
|
||||
|
||||
if 'resume' in request.POST:
|
||||
msg = _("Resume")
|
||||
addlogmsg(request.user.username, instance.name, msg)
|
||||
conn.resume(name)
|
||||
return HttpResponseRedirect(request.get_full_path())
|
||||
|
||||
instances_actions(request)
|
||||
except libvirtError as lib_err:
|
||||
error_messages.append(lib_err)
|
||||
addlogmsg(request.user.username, instance.name, lib_err.message)
|
||||
|
||||
view_style = settings.VIEW_INSTANCES_LIST_STYLE
|
||||
|
||||
return render(request, 'instances.html', locals())
|
||||
|
||||
|
||||
|
@ -453,7 +350,8 @@ def instance(request, compute_id, vname):
|
|||
instance.delete()
|
||||
|
||||
try:
|
||||
del_userinstance = UserInstance.objects.filter(instance__compute_id=compute_id, instance__name=vname)
|
||||
del_userinstance = UserInstance.objects.filter(instance__compute_id=compute_id,
|
||||
instance__name=vname)
|
||||
del_userinstance.delete()
|
||||
except UserInstance.DoesNotExist:
|
||||
pass
|
||||
|
@ -507,7 +405,8 @@ def instance(request, compute_id, vname):
|
|||
msg = _("Please shutdown down your instance and then try again")
|
||||
error_messages.append(msg)
|
||||
|
||||
if 'resize' in request.POST and (request.user.is_superuser or request.user.is_staff or userinstance.is_change):
|
||||
if 'resize' in request.POST and (
|
||||
request.user.is_superuser or request.user.is_staff or userinstance.is_change):
|
||||
new_vcpu = request.POST.get('vcpu', '')
|
||||
new_cur_vcpu = request.POST.get('cur_vcpu', '')
|
||||
new_memory = request.POST.get('memory', '')
|
||||
|
@ -705,7 +604,8 @@ def instance(request, compute_id, vname):
|
|||
|
||||
conn.change_network(network_data)
|
||||
addlogmsg(request.user.username, instance.name, msg)
|
||||
if conn.get_status() != 5: messages.success(request, _("Network Devices are changed. Please reboot instance to activate."))
|
||||
msg = _("Network Devices are changed. Please reboot instance to activate.")
|
||||
if conn.get_status() != 5: messages.success(request, msg)
|
||||
return HttpResponseRedirect(request.get_full_path() + '#network')
|
||||
|
||||
if 'add_network' in request.POST:
|
||||
|
@ -717,7 +617,9 @@ def instance(request, compute_id, vname):
|
|||
conn.add_network(mac, source, source_type, nwfilter=nwfilter)
|
||||
|
||||
addlogmsg(request.user.username, instance.name, msg)
|
||||
if conn.get_status() != 5: messages.success(request, _("Network Device is added. Please reboot instance to activate."))
|
||||
msg = _("Network Device is added. Please reboot instance to activate.")
|
||||
if conn.get_status() != 5: messages.success(request, msg)
|
||||
|
||||
return HttpResponseRedirect(request.get_full_path() + '#network')
|
||||
|
||||
if 'delete_network' in request.POST:
|
||||
|
@ -726,7 +628,8 @@ def instance(request, compute_id, vname):
|
|||
|
||||
conn.delete_network(mac_address)
|
||||
addlogmsg(request.user.username, instance.name, msg)
|
||||
if conn.get_status() != 5: messages.success(request, _("Network Device is deleted. Please reboot instance to activate."))
|
||||
msg = _("Network Device is deleted. Please reboot instance to activate.")
|
||||
if conn.get_status() != 5: messages.success(request, msg)
|
||||
return HttpResponseRedirect(request.get_full_path() + '#network')
|
||||
|
||||
if 'add_owner' in request.POST:
|
||||
|
@ -755,7 +658,6 @@ def instance(request, compute_id, vname):
|
|||
addlogmsg(request.user.username, instance.name, msg)
|
||||
return HttpResponseRedirect(request.get_full_path() + '#users')
|
||||
|
||||
|
||||
if request.user.is_superuser or request.user.userattributes.can_clone_instances:
|
||||
if 'clone' in request.POST:
|
||||
clone_data = {}
|
||||
|
@ -786,14 +688,16 @@ def instance(request, compute_id, vname):
|
|||
elif not re.match(r'^[a-zA-Z0-9-]+$', clone_data['name']):
|
||||
msg = _("Instance name '%s' contains invalid characters!" % clone_data['name'])
|
||||
error_messages.append(msg)
|
||||
elif not re.match(r'^([0-9A-F]{2})(\:?[0-9A-F]{2}){5}$', clone_data['clone-net-mac-0'], re.IGNORECASE):
|
||||
elif not re.match(r'^([0-9A-F]{2})(\:?[0-9A-F]{2}){5}$', clone_data['clone-net-mac-0'],
|
||||
re.IGNORECASE):
|
||||
msg = _("Instance mac '%s' invalid format!" % clone_data['clone-net-mac-0'])
|
||||
error_messages.append(msg)
|
||||
else:
|
||||
new_uuid = conn.clone_instance(clone_data)
|
||||
new_instance = Instance(compute_id=compute_id, name=clone_data['name'], uuid=new_uuid)
|
||||
new_instance.save()
|
||||
userinstance = UserInstance(instance_id=new_instance.id, user_id=request.user.id, is_delete=True)
|
||||
userinstance = UserInstance(instance_id=new_instance.id, user_id=request.user.id,
|
||||
is_delete=True)
|
||||
userinstance.save()
|
||||
|
||||
msg = _("Clone of '%s'" % instance.name)
|
||||
|
@ -801,7 +705,8 @@ def instance(request, compute_id, vname):
|
|||
if settings.CLONE_INSTANCE_AUTO_MIGRATE:
|
||||
new_compute = Compute.objects.order_by('?').first()
|
||||
migrate_instance(new_compute, new_instance, xml_del=True, offline=True)
|
||||
return HttpResponseRedirect(reverse('instance', args=[new_instance.compute.id, new_instance.name]))
|
||||
return HttpResponseRedirect(
|
||||
reverse('instance', args=[new_instance.compute.id, new_instance.name]))
|
||||
|
||||
if 'change_options' in request.POST:
|
||||
instance.is_template = request.POST.get('is_template', False)
|
||||
|
@ -851,6 +756,154 @@ def inst_status(request, compute_id, vname):
|
|||
return response
|
||||
|
||||
|
||||
def get_host_instances(request,comp):
|
||||
|
||||
def refresh_instance_database(comp, inst_name, info):
|
||||
def get_userinstances_info(instance):
|
||||
info = {}
|
||||
uis = UserInstance.objects.filter(instance=instance)
|
||||
info['count'] = uis.count()
|
||||
if info['count'] > 0:
|
||||
info['first_user'] = uis[0]
|
||||
else:
|
||||
info['first_user'] = None
|
||||
return info
|
||||
|
||||
instances = Instance.objects.filter(name=inst_name)
|
||||
if instances.count() > 1:
|
||||
for i in instances:
|
||||
user_instances_count = UserInstance.objects.filter(instance=i).count()
|
||||
if user_instances_count == 0:
|
||||
addlogmsg(request.user.username, i.name, _("Deleting due to multiple records."))
|
||||
i.delete()
|
||||
|
||||
try:
|
||||
inst_on_db = Instance.objects.get(compute_id=comp["id"], name=inst_name)
|
||||
if inst_on_db.uuid != info['uuid']:
|
||||
inst_on_db.save()
|
||||
|
||||
all_host_vms[comp["id"],
|
||||
comp["name"],
|
||||
comp["status"],
|
||||
comp["cpu"],
|
||||
comp["mem_size"],
|
||||
comp["mem_perc"]][inst_name]['is_template'] = inst_on_db.is_template
|
||||
all_host_vms[comp["id"],
|
||||
comp["name"],
|
||||
comp["status"],
|
||||
comp["cpu"],
|
||||
comp["mem_size"],
|
||||
comp["mem_perc"]][inst_name]['userinstances'] = get_userinstances_info(inst_on_db)
|
||||
except Instance.DoesNotExist:
|
||||
inst_on_db = Instance(compute_id=comp["id"], name=inst_name, uuid=info['uuid'])
|
||||
inst_on_db.save()
|
||||
|
||||
all_host_vms = {}
|
||||
status = connection_manager.host_is_up(comp.type, comp.hostname)
|
||||
|
||||
if status:
|
||||
|
||||
conn = wvmHostDetails(comp, comp.login, comp.password, comp.type)
|
||||
comp_node_info = conn.get_node_info()
|
||||
comp_mem = conn.get_memory_usage()
|
||||
comp_instances = conn.get_host_instances(True)
|
||||
|
||||
if comp_instances:
|
||||
comp_info = {
|
||||
"id": comp.id,
|
||||
"name": comp.name,
|
||||
"status": status,
|
||||
"cpu": comp_node_info[3],
|
||||
"mem_size": comp_node_info[2],
|
||||
"mem_perc": comp_mem['percent']
|
||||
}
|
||||
all_host_vms[comp_info["id"], comp_info["name"], comp_info["status"], comp_info["cpu"],
|
||||
comp_info["mem_size"], comp_info["mem_perc"]] = comp_instances
|
||||
for vm, info in comp_instances.items():
|
||||
refresh_instance_database(comp_info, vm, info)
|
||||
|
||||
conn.close()
|
||||
|
||||
return all_host_vms
|
||||
|
||||
def get_user_instances(request):
|
||||
all_user_vms = {}
|
||||
user_instances = UserInstance.objects.filter(user_id=request.user.id)
|
||||
for usr_inst in user_instances:
|
||||
if connection_manager.host_is_up(usr_inst.instance.compute.type,
|
||||
usr_inst.instance.compute.hostname):
|
||||
conn = wvmHostDetails(usr_inst.instance.compute,
|
||||
usr_inst.instance.compute.login,
|
||||
usr_inst.instance.compute.password,
|
||||
usr_inst.instance.compute.type)
|
||||
all_user_vms[usr_inst] = conn.get_user_instances(usr_inst.instance.name)
|
||||
all_user_vms[usr_inst].update({'compute_id': usr_inst.instance.compute.id})
|
||||
return all_user_vms
|
||||
|
||||
|
||||
def instances_actions(request):
|
||||
name = request.POST.get('name', '')
|
||||
compute_id = request.POST.get('compute_id', '')
|
||||
instance = Instance.objects.get(compute_id=compute_id, name=name)
|
||||
|
||||
conn = wvmInstances(instance.compute.hostname,
|
||||
instance.compute.login,
|
||||
instance.compute.password,
|
||||
instance.compute.type)
|
||||
if 'poweron' in request.POST:
|
||||
msg = _("Power On")
|
||||
addlogmsg(request.user.username, instance.name, msg)
|
||||
conn.start(name)
|
||||
return HttpResponseRedirect(request.get_full_path())
|
||||
|
||||
if 'poweroff' in request.POST:
|
||||
msg = _("Power Off")
|
||||
addlogmsg(request.user.username, instance.name, msg)
|
||||
conn.shutdown(name)
|
||||
return HttpResponseRedirect(request.get_full_path())
|
||||
|
||||
if 'powercycle' in request.POST:
|
||||
msg = _("Power Cycle")
|
||||
conn.force_shutdown(name)
|
||||
conn.start(name)
|
||||
addlogmsg(request.user.username, instance.name, msg)
|
||||
return HttpResponseRedirect(request.get_full_path())
|
||||
|
||||
if 'getvvfile' in request.POST:
|
||||
msg = _("Send console.vv file")
|
||||
addlogmsg(request.user.username, instance.name, msg)
|
||||
response = HttpResponse(content='', content_type='application/x-virt-viewer', status=200, reason=None,
|
||||
charset='utf-8')
|
||||
response.writelines('[virt-viewer]\n')
|
||||
response.writelines('type=' + conn.graphics_type(name) + '\n')
|
||||
response.writelines('host=' + conn.graphics_listen(name) + '\n')
|
||||
response.writelines('port=' + conn.graphics_port(name) + '\n')
|
||||
response.writelines('title=' + conn.domain_name(name) + '\n')
|
||||
response.writelines('password=' + conn.graphics_passwd(name) + '\n')
|
||||
response.writelines('enable-usbredir=1\n')
|
||||
response.writelines('disable-effects=all\n')
|
||||
response.writelines('secure-attention=ctrl+alt+ins\n')
|
||||
response.writelines('release-cursor=ctrl+alt\n')
|
||||
response.writelines('fullscreen=1\n')
|
||||
response.writelines('delete-this-file=1\n')
|
||||
response['Content-Disposition'] = 'attachment; filename="console.vv"'
|
||||
return response
|
||||
|
||||
if request.user.is_superuser:
|
||||
|
||||
if 'suspend' in request.POST:
|
||||
msg = _("Suspend")
|
||||
addlogmsg(request.user.username, instance.name, msg)
|
||||
conn.suspend(name)
|
||||
return HttpResponseRedirect(request.get_full_path())
|
||||
|
||||
if 'resume' in request.POST:
|
||||
msg = _("Resume")
|
||||
addlogmsg(request.user.username, instance.name, msg)
|
||||
conn.resume(name)
|
||||
return HttpResponseRedirect(request.get_full_path())
|
||||
|
||||
|
||||
@login_required
|
||||
def inst_graph(request, compute_id, vname):
|
||||
"""
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
<li class="active">
|
||||
<i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-server"></i> <a href="{% url 'instances' compute.id %}">{% trans "Instances" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a>
|
||||
</li>
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
<li class="active">
|
||||
<i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-server"></i> <a href="{% url 'instances' compute.id %}">{% trans "Instances" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a>
|
||||
</li>
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
<li class="active">
|
||||
<i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-server"></i> <a href="{% url 'instances' compute.id %}">{% trans "Instances" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a>
|
||||
</li>
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
<li class="active">
|
||||
<i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-server"></i> <a href="{% url 'instances' compute.id %}">{% trans "Instances" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a>
|
||||
</li>
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
<li class="active">
|
||||
<i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-server"></i> <a href="{% url 'instances' compute.id %}">{% trans "Instances" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a>
|
||||
</li>
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
<li class="active">
|
||||
<i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-server"></i> <a href="{% url 'instances' compute.id %}">{% trans "Instances" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a>
|
||||
</li>
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
<li class="active">
|
||||
<i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-server"></i> <a href="{% url 'instances' compute.id %}">{% trans "Instances" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a>
|
||||
</li>
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
<li class="active">
|
||||
<i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-server"></i> <a href="{% url 'instances' compute.id %}">{% trans "Instances" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a>
|
||||
</li>
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
<li class="active">
|
||||
<i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-server"></i> <a href="{% url 'instances' compute.id %}">{% trans "Instances" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-hdd-o"></i> {% trans "Storages" %}
|
||||
</li>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<div id="navbar" class="navbar-collapse collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li {% class_active request "^/instance" %}>
|
||||
<a href="{% url 'instances' %}"><i class="fa fa-fw fa-desktop"></i> {% trans "Instances" %}</a>
|
||||
<a href="{% url 'allinstances' %}"><i class="fa fa-fw fa-desktop"></i> {% trans "Instances" %}</a>
|
||||
</li>
|
||||
{% if request.user.is_superuser %}
|
||||
<li {% class_active request "^/compute" %}{% class_active request "^/create" %}>
|
||||
|
|
|
@ -19,6 +19,7 @@ INSTALLED_APPS = (
|
|||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'dashboards',
|
||||
'computes',
|
||||
'console',
|
||||
'networks',
|
||||
|
|
|
@ -1,36 +1,18 @@
|
|||
from django.conf.urls import include, url
|
||||
|
||||
from instances.views import instances, instance, index
|
||||
from storages.views import storages, storage
|
||||
from networks.views import networks, network
|
||||
from secrets.views import secrets
|
||||
from create.views import create_instance
|
||||
from interfaces.views import interfaces, interface
|
||||
from instances.views import index
|
||||
from console.views import console
|
||||
from nwfilters.views import nwfilters, nwfilter
|
||||
# from django.contrib import admin
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', index, name='index'),
|
||||
url(r'^instances/$', instances, name='instances'),
|
||||
|
||||
url(r'^instance/', include('instances.urls')),
|
||||
url(r'^instances/', include('instances.urls')),
|
||||
url(r'^accounts/', include('accounts.urls')),
|
||||
url(r'^computes/', include('computes.urls')),
|
||||
url(r'^logs/', include('logs.urls')),
|
||||
url(r'^datasource/', include('datasource.urls')),
|
||||
|
||||
url(r'^compute/(?P<compute_id>[0-9]+)/storages/$', storages, name='storages'),
|
||||
url(r'^compute/(?P<compute_id>[0-9]+)/storage/(?P<pool>[\w\-\.\/]+)/$', storage, name='storage'),
|
||||
url(r'^compute/(?P<compute_id>[0-9]+)/networks/$', networks, name='networks'),
|
||||
url(r'^compute/(?P<compute_id>[0-9]+)/network/(?P<pool>[\w\-\.]+)/$', network, name='network'),
|
||||
url(r'^compute/(?P<compute_id>[0-9]+)/interfaces/$', interfaces, name='interfaces'),
|
||||
url(r'^compute/(?P<compute_id>[0-9]+)/interface/(?P<iface>[\w\-\.\:]+)/$', interface, name='interface'),
|
||||
url(r'^compute/(?P<compute_id>[0-9]+)/nwfilters/$', nwfilters, name='nwfilters'),
|
||||
url(r'^compute/(?P<compute_id>[0-9]+)/nwfilter/(?P<nwfltr>[\w\-\.\:]+)/$', nwfilter, name='nwfilter'),
|
||||
url(r'^compute/(?P<compute_id>[0-9]+)/secrets/$', secrets, name='secrets'),
|
||||
url(r'^compute/(?P<compute_id>[0-9]+)/create/$', create_instance, name='create_instance'),
|
||||
|
||||
|
||||
url(r'^console/$', console, name='console'),
|
||||
# (r'^admin/', include(admin.site.urls)),
|
||||
|
|
Loading…
Reference in a new issue