1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2024-12-25 15:45:23 +00:00

Merge pull request #255 from catborise/master

Some Updates & Rearrange/fix
This commit is contained in:
Anatoliy Guskov 2019-10-24 14:08:28 +03:00 committed by GitHub
commit fb26a002c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
44 changed files with 3380 additions and 3223 deletions

View file

@ -2,139 +2,139 @@
{% load i18n %} {% load i18n %}
{% block title %}{% trans "User" %} - {{ user }}{% endblock %} {% block title %}{% trans "User" %} - {{ user }}{% endblock %}
{% block content %} {% block content %}
<!-- Page Heading --> <!-- Page Heading -->
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
{% include 'create_user_inst_block.html' %} {% include 'create_user_inst_block.html' %}
<h1 class="page-header">{{ user }}</h1> <h1 class="page-header">{{ user }}</h1>
</div> </div>
</div>
<!-- /.row -->
{% include 'errors_block.html' %}
{% if request.user.is_superuser and publickeys %}
<div class="row">
<div class="col-lg-12">
<div class="table-responsive">
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>{% trans "Key name" %}</th>
<th>{% trans "Public key" %}</th>
</tr>
</thead>
<tbody>
{% for publickey in publickeys %}
<tr>
<td>{{ publickey.keyname }}</td>
<td title="{{ publickey.keypublic }}">{{ publickey.keypublic|truncatechars:64 }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div> </div>
<!-- /.row --> </div>
</div>
{% endif %}
{% include 'errors_block.html' %} <div class="row">
<div class="col-lg-12">
{% if request.user.is_superuser and publickeys %} {% if not user_insts %}
<div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<div class="table-responsive"> <div class="alert alert-warning alert-dismissable">
<table class="table table-bordered table-hover"> <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<thead> <i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning:" %}</strong> {% trans "User doesn't have any Instace" %}
<tr>
<th>{% trans "Key name" %}</th>
<th>{% trans "Public key" %}</th>
</tr>
</thead>
<tbody>
{% for publickey in publickeys %}
<tr>
<td>{{ publickey.keyname }}</td>
<td title="{{ publickey.keypublic }}">{{ publickey.keypublic|truncatechars:64 }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div> </div>
</div> </div>
</div> {% else %}
{% endif %} <div class="table-responsive">
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>#</th>
<th>{% trans "Instance" %}</th>
<th>{% trans "VNC" %}</th>
<th>{% trans "Resize" %}</th>
<th>{% trans "Delete" %}</th>
<th colspan="2">{% trans "Action" %}</th>
</tr>
</thead>
<tbody>
{% for inst in user_insts %}
<tr>
<td>{{ forloop.counter }}</td>
<td><a href="{% url 'instance' inst.instance.compute.id inst.instance.name %}">{{ inst.instance.name }}</a></td>
<td>{{ inst.is_vnc }}</td>
<td>{{ inst.is_change }}</td>
<td>{{ inst.is_delete }}</td>
<td style="width:5px;">
<a href="#editPriv{{ forloop.counter }}" type="button" class="btn btn-xs btn-default" data-toggle="modal">
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
</a>
<div class="row"> <!-- Modal pool -->
<div class="col-lg-12"> <div class="modal fade" id="editPriv{{ forloop.counter }}" tabindex="-1" role="dialog" aria-labelledby="editPrivLabel" aria-hidden="true">
{% if not user_insts %} <div class="modal-dialog">
<div class="col-lg-12"> <div class="modal-content">
<div class="alert alert-warning alert-dismissable"> <div class="modal-header">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning:" %}</strong> {% trans "User doesn't have any Instace" %} <h4 class="modal-title">{% trans "Edit privilegies for" %} {{ inst.instance.name }}</h4>
</div> </div>
</div> <div class="modal-body">
{% else %} <form class="form-horizontal" method="post" action="" role="form">{% csrf_token %}
<div class="table-responsive"> <input type="hidden" name="user_inst" value="{{ inst.id }}">
<table class="table table-bordered table-hover"> <div class="form-group">
<thead> <label class="col-sm-4 control-label">{% trans "VNC" %}</label>
<tr> <div class="col-sm-6">
<th>#</th> <select type="text" class="form-control" name="inst_vnc">
<th>{% trans "Instance" %}</th> <option value="">False</option>
<th>{% trans "VNC" %}</th> <option value="1" {% if inst.is_vnc %}selected{% endif %}>True</option>
<th>{% trans "Resize" %}</th> </select>
<th>{% trans "Delete" %}</th> </div>
<th colspan="2">{% trans "Action" %}</th>
</tr>
</thead>
<tbody>
{% for inst in user_insts %}
<tr>
<td>{{ forloop.counter }}</td>
<td><a href="{% url 'instance' inst.instance.compute.id inst.instance.name %}">{{ inst.instance.name }}</a></td>
<td>{{ inst.is_vnc }}</td>
<td>{{ inst.is_change }}</td>
<td>{{ inst.is_delete }}</td>
<td style="width:5px;">
<a href="#editPriv{{ forloop.counter }}" type="button" class="btn btn-xs btn-default" data-toggle="modal">
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
</a>
<!-- Modal pool -->
<div class="modal fade" id="editPriv{{ forloop.counter }}" tabindex="-1" role="dialog" aria-labelledby="editPrivLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">{% trans "Edit privilegies for" %} {{ inst.instance.name }}</h4>
</div> </div>
<div class="modal-body"> <div class="form-group">
<form class="form-horizontal" method="post" action="" role="form">{% csrf_token %} <label class="col-sm-4 control-label">{% trans "Resize" %}</label>
<input type="hidden" name="user_inst" value="{{ inst.id }}"> <div class="col-sm-6">
<div class="form-group"> <select type="text" class="form-control" name="inst_change">
<label class="col-sm-4 control-label">{% trans "VNC" %}</label> <option value="">False</option>
<div class="col-sm-6"> <option value="1" {% if inst.is_change %}selected{% endif %}>True</option>
<select type="text" class="form-control" name="inst_vnc"> </select>
<option value="">False</option> </div>
<option value="1" {% if inst.is_vnc %}selected{% endif %}>True</option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Resize" %}</label>
<div class="col-sm-6">
<select type="text" class="form-control" name="inst_change">
<option value="">False</option>
<option value="1" {% if inst.is_change %}selected{% endif %}>True</option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Delete" %}</label>
<div class="col-sm-6">
<select type="text" class="form-control" name="inst_delete">
<option value="">False</option>
<option value="1" {% if inst.is_delete %}selected{% endif %}>True</option>
</select>
</div>
</div>
</div> </div>
<div class="modal-footer"> <div class="form-group">
<button type="button" class="btn btn-default" data-dismiss="modal">{% trans "Close" %}</button> <label class="col-sm-4 control-label">{% trans "Delete" %}</label>
<button type="submit" class="btn btn-primary" name="permission">{% trans "Edit" %}</button> <div class="col-sm-6">
<select type="text" class="form-control" name="inst_delete">
<option value="">False</option>
<option value="1" {% if inst.is_delete %}selected{% endif %}>True</option>
</select>
</div>
</div> </div>
</form> </div>
</div> <!-- /.modal-content --> <div class="modal-footer">
</div> <!-- /.modal-dialog --> <button type="button" class="btn btn-default" data-dismiss="modal">{% trans "Close" %}</button>
</div> <!-- /.modal --> <button type="submit" class="btn btn-primary" name="permission">{% trans "Edit" %}</button>
</td> </div>
<td style="width:5px;"> </form>
<form action="" method="post" role="form">{% csrf_token %} </div> <!-- /.modal-content -->
<input type="hidden" name="user_inst" value="{{ inst.id }}"> </div> <!-- /.modal-dialog -->
<button type="submit" class="btn btn-xs btn-default" name="delete" tittle="{% trans "Delete" %}" onclick="return confirm('{% trans "Are you sure?" %}')"> </div> <!-- /.modal -->
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span> </td>
</button> <td style="width:5px;">
</form> <form action="" method="post" role="form">{% csrf_token %}
</td> <input type="hidden" name="user_inst" value="{{ inst.id }}">
</tr> <button type="submit" class="btn btn-xs btn-default" name="delete" tittle="{% trans "Delete" %}" onclick="return confirm('{% trans "Are you sure?" %}')">
{% endfor %} <span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
</tbody> </button>
</table> </form>
</div> </td>
{% endif %} </tr>
{% endfor %}
</tbody>
</table>
</div> </div>
</div> {% endif %}
</div>
</div>
{% endblock %} {% endblock %}

View file

@ -30,11 +30,11 @@
<table class="table table-striped table-hover"> <table class="table table-striped table-hover">
<thead> <thead>
<tr> <tr>
<th>Username</th> <th>{% trans "Username" %}</th>
<th>Status</th> <th>{% trans "Status" %}</th>
<th>Staff</th> <th>{% trans "Staff" %}</th>
<th>Superuser</th> <th>{% trans "Superuser" %}</th>
<th>Clone</th> <th>{% trans "Clone" %}</th>
</tr> </tr>
</thead> </thead>
<tbody class="searchable"> <tbody class="searchable">

View file

@ -2,7 +2,6 @@ from django.shortcuts import render
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from accounts.models import * from accounts.models import *
from instances.models import Instance from instances.models import Instance
@ -11,7 +10,6 @@ from django.conf import settings
from django.core.validators import ValidationError from django.core.validators import ValidationError
@login_required @login_required
def profile(request): def profile(request):
""" """
@ -70,6 +68,7 @@ def profile(request):
return HttpResponseRedirect(request.get_full_path()) return HttpResponseRedirect(request.get_full_path())
return render(request, 'profile.html', locals()) return render(request, 'profile.html', locals())
@login_required @login_required
def accounts(request): def accounts(request):
""" """
@ -154,6 +153,7 @@ def accounts(request):
def account(request, user_id): def account(request, user_id):
""" """
:param request: :param request:
:param user_id:
:return: :return:
""" """

View file

@ -2,251 +2,250 @@
{% load i18n %} {% load i18n %}
{% block title %}{% trans "Computes" %}{% endblock %} {% block title %}{% trans "Computes" %}{% endblock %}
{% block content %} {% block content %}
<!-- Page Heading --> <!-- Page Heading -->
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
{% include 'create_comp_block.html' %} {% include 'create_comp_block.html' %}
<h1 class="page-header">{% trans "Computes" %}</h1> <h1 class="page-header">{% trans "Computes" %}</h1>
</div> </div>
</div> </div>
<!-- /.row --> <!-- /.row -->
{% include 'errors_block.html' %} {% include 'errors_block.html' %}
<div class="row"> <div class="row">
{% if computes_info %} {% if computes_info %}
{% for compute in computes_info %} {% for compute in computes_info %}
<div id="{{ compute.name }}" class="col-xs-12 col-sm-4"> <div id="{{ compute.name }}" class="col-xs-12 col-sm-4">
<div class="panel {% if compute.status %}panel-success{% else %}panel-danger{% endif %} panel-data"> <div class="panel {% if compute.status %}panel-success{% else %}panel-danger{% endif %} panel-data">
<div class="panel-heading"> <div class="panel-heading">
{% ifequal compute.status 1 %} {% ifequal compute.status 1 %}
<h3 class="panel-title"> <h3 class="panel-title">
<a href="{% url 'overview' compute.id %}"><strong>{{ compute.name }}</strong></a> <a href="{% url 'overview' compute.id %}"><strong>{{ compute.name }}</strong></a>
<a data-toggle="modal" href="#editHost{{ compute.id }}" class="pull-right" title="{% trans "Edit" %}"> <a data-toggle="modal" href="#editHost{{ compute.id }}" class="pull-right" title="{% trans "Edit" %}">
<i class="fa fa-cog"></i> <i class="fa fa-cog"></i>
</a> </a>
</h3> </h3>
{% else %} {% else %}
<h3 class="panel-title"><strong>{{ compute.name }}</strong> <h3 class="panel-title"><strong>{{ compute.name }}</strong>
<a data-toggle="modal" href="#editHost{{ compute.id }}" class="pull-right" title="{% trans "Edit" %}"> <a data-toggle="modal" href="#editHost{{ compute.id }}" class="pull-right" title="{% trans "Edit" %}">
<span class="glyphicon glyphicon-cog"></span> <span class="glyphicon glyphicon-cog"></span>
</a> </a>
</h3> </h3>
{% endifequal %} {% endifequal %}
</div>
<div class="panel-body">
<div class="row">
<div class="col-xs-4 col-sm-4">
<p><strong>{% trans "Status" %}:</strong></p>
</div> </div>
<div class="panel-body"> <div class="col-xs-4 col-sm-6">
<div class="row"> {% if compute.status %}
<div class="col-xs-4 col-sm-4"> <p>{% trans "Connected" %}</p>
<p><strong>{% trans "Status:" %}</strong></p> {% else %}
</div> <p>{% trans "Not Connected" %}</p>
<div class="col-xs-4 col-sm-6"> {% endif %}
{% if compute.status %} {% if compute.details %}
<p>{% trans "Connected" %}</p> <p>{% trans compute.details %}</p>
{% else %} {% else %}
<p>{% trans "Not Connected" %}</p> <p>{% trans "No details available" %}</p>
{% endif %} {% endif %}
{% if compute.details %}
<p>{% trans compute.details %}</p>
{% else %}
<p>{% trans "No details available" %}</p>
{% endif %}
</div>
</div>
<!-- Modal Edit -->
<div class="modal fade" id="editHost{{ compute.id }}" tabindex="-1" role="dialog" aria-labelledby="editHostLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">{% trans "Edit connection" %}</h4>
</div>
{% ifequal compute.type 1 %}
<form class="form-horizontal" method="post" role="form">{% csrf_token %}
<div class="modal-body">
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Label" %}</label>
<div class="col-sm-6">
<input type="hidden" name="host_id" value="{{ compute.id }}">
<input type="text" name="name" class="form-control" value="{{ compute.name }}" maxlength="20" required pattern="[a-zA-Z0-9\.\-_]+">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "FQDN / IP" %}</label>
<div class="col-sm-6">
<input type="text" name="hostname" class="form-control" value="{{ compute.hostname }}" required pattern="[a-z0-9\.\-_]+">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Username" %}</label>
<div class="col-sm-6">
<input type="text" name="login" class="form-control" value="{{ compute.login }}">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Password" %}</label>
<div class="col-sm-6">
<input type="password" name="password" class="form-control" value="{{ compute.password }}">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Details" %}</label>
<div class="col-sm-6">
<input type="text" name="details" class="form-control" placeholder="Details" value="{{ compute.details }}">
</div>
</div></div>
<div class="modal-footer">
<button type="submit" class="pull-left btn btn-danger" name="host_del">
{% trans "Delete" %}
</button>
<button type="button" class="btn btn-default" data-dismiss="modal">
{% trans "Close" %}
</button>
<button type="submit" class="btn btn-primary" name="host_edit">
{% trans "Change" %}
</button>
</div>
</form>
{% endifequal %}
{% ifequal compute.type 2 %}
<form class="form-horizontal" method="post" role="form">{% csrf_token %}
<div class="modal-body">
<p class="modal-body">{% trans "Need create ssh <a href='https://github.com/retspen/webvirtmgr/wiki/Setup-SSH-Authorization'>authorization key</a>. If you have another SSH port on your server, you can add IP:PORT like '192.168.1.1:2222'." %}</p>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Label" %}</label>
<div class="col-sm-6">
<input type="hidden" name="host_id" value="{{ compute.id }}">
<input type="text" name="name" class="form-control" value="{{ compute.name }}" maxlength="20" required pattern="[a-z0-9\.\-_]+">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "FQDN / IP" %}</label>
<div class="col-sm-6">
<input type="text" name="hostname" class="form-control" value="{{ compute.hostname }}" required pattern="[a-z0-9\:\.\-_]+">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Username" %}</label>
<div class="col-sm-6">
<input type="text" name="login" class="form-control" value="{{ compute.login }}">
<input type="hidden" name="password" value="{{ compute.password }}">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Details" %}</label>
<div class="col-sm-6">
<input type="text" name="details" class="form-control" placeholder="Details" value="{{ compute.details }}">
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="pull-left btn btn-danger" name="host_del">
{% trans "Delete" %}
</button>
<button type="button" class="btn btn-default" data-dismiss="modal">
{% trans "Close" %}
</button>
<button type="submit" class="btn btn-primary" name="host_edit">
{% trans "Change" %}
</button>
</div>
</form>
{% endifequal %}
{% ifequal compute.type 3 %}
<form class="form-horizontal" method="post" role="form">{% csrf_token %}
<div class="modal-body">
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Label" %}</label>
<div class="col-sm-6">
<input type="hidden" name="host_id" value="{{ compute.id }}">
<input type="text" name="name" class="form-control" value="{{ compute.name }}" maxlength="20" required pattern="[a-z0-9\.\-_]+">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "FQDN / IP" %}</label>
<div class="col-sm-6">
<input type="text" name="hostname" class="form-control" value="{{ compute.hostname }}" required pattern="[a-z0-9\:\.\-_]+">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Username" %}</label>
<div class="col-sm-6">
<input type="text" name="login" class="form-control" placeholder="{% trans "Name" %}">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Password" %}</label>
<div class="col-sm-6">
<input type="password" name="password" class="form-control" value="{{ compute.password }}">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Details" %}</label>
<div class="col-sm-6">
<input type="text" name="details" class="form-control" placeholder="Details" value="{{ compute.details }}">
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="pull-left btn btn-danger" name="host_del">
{% trans "Delete" %}
</button>
<button type="button" class="btn btn-default" data-dismiss="modal">
{% trans "Close" %}
</button>
<button type="submit" class="btn btn-primary" name="host_edit">
{% trans "Change" %}
</button>
</div>
</form>
{% endifequal %}
{% ifequal compute.type 4 %}
<form class="form-horizontal" method="post" role="form">{% csrf_token %}
<div class="modal-body">
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Label" %}</label>
<div class="col-sm-6">
<input type="hidden" name="host_id" value="{{ compute.id }}">
<input type="text" name="name" class="form-control" value="{{ compute.name }}" maxlength="20" required pattern="[a-z0-9\.\-_]+">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Details" %}</label>
<div class="col-sm-6">
<input type="text" name="details" class="form-control" placeholder="Details" value="{{ compute.details }}">
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="pull-left btn btn-danger" name="host_del">
{% trans "Delete" %}
</button>
<button type="button" class="btn btn-default" data-dismiss="modal">
{% trans "Close" %}
</button>
<button type="submit" class="btn btn-primary" name="host_edit">
{% trans "Change" %}
</button>
</div>
</form>
{% endifequal %}
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</div> </div>
</div> </div>
<!-- Modal Edit -->
<div class="modal fade" id="editHost{{ compute.id }}" tabindex="-1" role="dialog" aria-labelledby="editHostLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">{% trans "Edit connection" %}</h4>
</div>
{% ifequal compute.type 1 %}
<form class="form-horizontal" method="post" role="form">{% csrf_token %}
<div class="modal-body">
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Label" %}</label>
<div class="col-sm-6">
<input type="hidden" name="host_id" value="{{ compute.id }}">
<input type="text" name="name" class="form-control" value="{{ compute.name }}" maxlength="20" required pattern="[a-zA-Z0-9\.\-_]+">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "FQDN / IP" %}</label>
<div class="col-sm-6">
<input type="text" name="hostname" class="form-control" value="{{ compute.hostname }}" required pattern="[a-z0-9\.\-_]+">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Username" %}</label>
<div class="col-sm-6">
<input type="text" name="login" class="form-control" value="{{ compute.login }}">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Password" %}</label>
<div class="col-sm-6">
<input type="password" name="password" class="form-control" value="{{ compute.password }}">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Details" %}</label>
<div class="col-sm-6">
<input type="text" name="details" class="form-control" placeholder="Details" value="{{ compute.details }}">
</div>
</div></div>
<div class="modal-footer">
<button type="submit" class="pull-left btn btn-danger" name="host_del">
{% trans "Delete" %}
</button>
<button type="button" class="btn btn-default" data-dismiss="modal">
{% trans "Close" %}
</button>
<button type="submit" class="btn btn-primary" name="host_edit">
{% trans "Change" %}
</button>
</div>
</form>
{% endifequal %}
{% ifequal compute.type 2 %}
<form class="form-horizontal" method="post" role="form">{% csrf_token %}
<div class="modal-body">
<p class="modal-body">{% trans "Need create ssh <a href='https://github.com/retspen/webvirtmgr/wiki/Setup-SSH-Authorization'>authorization key</a>. If you have another SSH port on your server, you can add IP:PORT like '192.168.1.1:2222'." %}</p>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Label" %}</label>
<div class="col-sm-6">
<input type="hidden" name="host_id" value="{{ compute.id }}">
<input type="text" name="name" class="form-control" value="{{ compute.name }}" maxlength="20" required pattern="[a-z0-9\.\-_]+">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "FQDN / IP" %}</label>
<div class="col-sm-6">
<input type="text" name="hostname" class="form-control" value="{{ compute.hostname }}" required pattern="[a-z0-9\:\.\-_]+">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Username" %}</label>
<div class="col-sm-6">
<input type="text" name="login" class="form-control" value="{{ compute.login }}">
<input type="hidden" name="password" value="{{ compute.password }}">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Details" %}</label>
<div class="col-sm-6">
<input type="text" name="details" class="form-control" placeholder="Details" value="{{ compute.details }}">
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="pull-left btn btn-danger" name="host_del">
{% trans "Delete" %}
</button>
<button type="button" class="btn btn-default" data-dismiss="modal">
{% trans "Close" %}
</button>
<button type="submit" class="btn btn-primary" name="host_edit">
{% trans "Change" %}
</button>
</div>
</form>
{% endifequal %}
{% ifequal compute.type 3 %}
<form class="form-horizontal" method="post" role="form">{% csrf_token %}
<div class="modal-body">
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Label" %}</label>
<div class="col-sm-6">
<input type="hidden" name="host_id" value="{{ compute.id }}">
<input type="text" name="name" class="form-control" value="{{ compute.name }}" maxlength="20" required pattern="[a-z0-9\.\-_]+">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "FQDN / IP" %}</label>
<div class="col-sm-6">
<input type="text" name="hostname" class="form-control" value="{{ compute.hostname }}" required pattern="[a-z0-9\:\.\-_]+">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Username" %}</label>
<div class="col-sm-6">
<input type="text" name="login" class="form-control" placeholder="{% trans "Name" %}">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Password" %}</label>
<div class="col-sm-6">
<input type="password" name="password" class="form-control" value="{{ compute.password }}">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Details" %}</label>
<div class="col-sm-6">
<input type="text" name="details" class="form-control" placeholder="Details" value="{{ compute.details }}">
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="pull-left btn btn-danger" name="host_del">
{% trans "Delete" %}
</button>
<button type="button" class="btn btn-default" data-dismiss="modal">
{% trans "Close" %}
</button>
<button type="submit" class="btn btn-primary" name="host_edit">
{% trans "Change" %}
</button>
</div>
</form>
{% endifequal %}
{% ifequal compute.type 4 %}
<form class="form-horizontal" method="post" role="form">{% csrf_token %}
<div class="modal-body">
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Label" %}</label>
<div class="col-sm-6">
<input type="hidden" name="host_id" value="{{ compute.id }}">
<input type="text" name="name" class="form-control" value="{{ compute.name }}" maxlength="20" required pattern="[a-z0-9\.\-_]+">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Details" %}</label>
<div class="col-sm-6">
<input type="text" name="details" class="form-control" placeholder="Details" value="{{ compute.details }}">
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="pull-left btn btn-danger" name="host_del">
{% trans "Delete" %}
</button>
<button type="button" class="btn btn-default" data-dismiss="modal">
{% trans "Close" %}
</button>
<button type="submit" class="btn btn-primary" name="host_edit">
{% trans "Change" %}
</button>
</div>
</form>
{% endifequal %}
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</div> </div>
{% endfor %} </div>
{% else %} </div>
<div class="col-lg-12"> {% endfor %}
<div class="alert alert-warning alert-dismissable"> {% else %}
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button> <div class="col-lg-12">
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning:" %}</strong> {% trans "Hypervisor doesn't have any Computes" %} <div class="alert alert-warning alert-dismissable">
</div> <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
</div> <i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning" %}:</strong> {% trans "Hypervisor doesn't have any Computes" %}
{% endif %} </div>
</div> </div>
{% endif %}
</div>
{% endblock %} {% endblock %}

View file

@ -3,107 +3,107 @@
{% load staticfiles %} {% load staticfiles %}
{% block title %}{% trans "Overview" %} - {{ compute.name }}{% endblock %} {% block title %}{% trans "Overview" %} - {{ compute.name }}{% endblock %}
{% block content %} {% block content %}
<!-- Page Heading --> <!-- Page Heading -->
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<h1 class="page-header">{{ compute.name }}</h1> <h1 class="page-header">{{ compute.name }}</h1>
<ol class="breadcrumb"> <ol class="breadcrumb">
<li class="active"> <li class="active">
<i class="fa fa-dashboard"></i> {% trans "Overview" %} <i class="fa fa-dashboard"></i> {% trans "Overview" %}
</li> </li>
<li> <li>
<i class="fa fa-server"></i> <a href="{% url 'instances' compute.id %}">{% trans "Instances" %}</a> <i class="fa fa-server"></i> <a href="{% url 'instances' compute.id %}">{% trans "Instances" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a> <i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-sitemap"></i> <a href="{% url 'networks' compute.id %}">{% trans "Networks" %}</a> <i class="fa fa-sitemap"></i> <a href="{% url 'networks' compute.id %}">{% trans "Networks" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-wifi"></i> <a href="{% url 'interfaces' compute.id %}">{% trans "Interfaces" %}</a> <i class="fa fa-wifi"></i> <a href="{% url 'interfaces' compute.id %}">{% trans "Interfaces" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-filter"></i> <a href="{% url 'nwfilters' compute.id %}">{% trans "NWFilters" %}</a> <i class="fa fa-filter"></i> <a href="{% url 'nwfilters' compute.id %}">{% trans "NWFilters" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-key"></i> <a href="{% url 'secrets' compute.id %}">{% trans "Secrets" %}</a> <i class="fa fa-key"></i> <a href="{% url 'secrets' compute.id %}">{% trans "Secrets" %}</a>
</li> </li>
</ol> </ol>
</div> </div>
</div> </div>
<!-- /.row --> <!-- /.row -->
{% include 'errors_block.html' %} {% include 'errors_block.html' %}
<div class="row" id="max-width-page"> <div class="row" id="max-width-page">
<h3 class="page-header">{% trans "Basic details" %}</h3> <h3 class="page-header">{% trans "Basic details" %}</h3>
<div class="col-xs-4 col-sm-3"> <div class="col-xs-4 col-sm-3">
<p>{% trans "Hostname" %}</p> <p>{% trans "Hostname" %}</p>
<p>{% trans "Hypervisors" %}</p> <p>{% trans "Hypervisors" %}</p>
<p>{% trans "Emulator" %}</p> <p>{% trans "Emulator" %}</p>
<p>{% trans "Version" %}</p> <p>{% trans "Version" %}</p>
<p>{% trans "Memory" %}</p> <p>{% trans "Memory" %}</p>
<p>{% trans "Architecture" %}</p> <p>{% trans "Architecture" %}</p>
<p>{% trans "Logical CPUs" %}</p> <p>{% trans "Logical CPUs" %}</p>
<p>{% trans "Processor" %}</p> <p>{% trans "Processor" %}</p>
<p>{% trans "Connection" %}</p> <p>{% trans "Connection" %}</p>
<p>{% trans "Details" %}</p> <p>{% trans "Details" %}</p>
</div>
<div class="col-xs-8 col-sm-9">
<p>{{ hostname }}</p>
<p>{% for arch, hpv in hypervisor.items %}
<span class="glyphicon glyphicon-chevron-right"></span>
<span class="label label-default">{{ arch }}</span>
{% for h in hpv %}
<span class="label label-primary">{{ h }}</span>
{% endfor %}
{% endfor %}
</p>
<p>{{ emulator }}</p>
<p>
<span class="label label-default">Qemu</span>
<span class="label label-primary">{{ version }}</span> &nbsp;
<span class="label label-default">Libvirt</span>
<span class="label label-primary">{{ lib_version }}</span> &nbsp;
</p>
<p>{{ host_memory|filesizeformat }}</p>
<p>{{ host_arch }}</p>
<p>{{ logical_cpu }}</p>
<p>{{ model_cpu }}</p>
<p>{{ uri_conn }}</p>
<p>{{ compute.details }}</p>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<h3 class="page-header">{% trans "Performance" %}</h3>
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title"><i class="fa fa-long-arrow-right"></i> {% trans "CPU Utilization" %}</h3>
</div> </div>
<div class="col-xs-8 col-sm-9"> <div class="panel-body">
<p>{{ hostname }}</p> <div class="flot-chart">
<p>{% for arch, hpv in hypervisor.items %} <div class="flot-chart-content" id="flot-moving-line-chart" style="padding: 0px; position: relative;">
<span class="glyphicon glyphicon-chevron-right"></span> <canvas id="cpuChart" width="735" height="160"></canvas>
<span class="label label-default">{{ arch }}</span>
{% for h in hpv %}
<span class="label label-primary">{{ h }}</span>
{% endfor %}
{% endfor %}
</p>
<p>{{ emulator }}</p>
<p>
<span class="label label-default">{% trans 'Qemu' %} </span>
<span class="label label-primary">{{ version }}</span> &nbsp;
<span class="label label-default">{% trans 'Libvirt' %} </span>
<span class="label label-primary">{{ lib_version }}</span> &nbsp;
</p>
<p>{{ host_memory|filesizeformat }}</p>
<p>{{ host_arch }}</p>
<p>{{ logical_cpu }}</p>
<p>{{ model_cpu }}</p>
<p>{{ uri_conn }}</p>
<p>{{ compute.details }}</p>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<h3 class="page-header">{% trans "Performance" %}</h3>
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title"><i class="fa fa-long-arrow-right"></i> {% trans "CPU Utilization" %}</h3>
</div>
<div class="panel-body">
<div class="flot-chart">
<div class="flot-chart-content" id="flot-moving-line-chart" style="padding: 0px; position: relative;">
<canvas id="cpuChart" width="735" height="160"></canvas>
</div>
</div>
</div>
</div>
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title"><i class="fa fa-long-arrow-right"></i> {% trans "RAM Utilization" %}</h3>
</div>
<div class="panel-body">
<div class="flot-chart">
<div class="flot-chart-content" id="flot-moving-line-chart" style="padding: 0px; position: relative;">
<canvas id="memChart" width="735" height="160"></canvas>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title"><i class="fa fa-long-arrow-right"></i> {% trans "RAM Utilization" %}</h3>
</div>
<div class="panel-body">
<div class="flot-chart">
<div class="flot-chart-content" id="flot-moving-line-chart" style="padding: 0px; position: relative;">
<canvas id="memChart" width="735" height="160"></canvas>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %} {% endblock %}
{% block script %} {% block script %}
<script src="{% static "js/Chart.bundle.min.js" %}"></script> <script src="{% static "js/Chart.bundle.min.js" %}"></script>

View file

@ -1,4 +1,3 @@
import time
import json import json
from django.utils import timezone from django.utils import timezone
from django.http import HttpResponse, HttpResponseRedirect from django.http import HttpResponse, HttpResponseRedirect
@ -140,6 +139,7 @@ def computes(request):
def overview(request, compute_id): def overview(request, compute_id):
""" """
:param request: :param request:
:param compute_id:
:return: :return:
""" """
@ -171,6 +171,7 @@ def overview(request, compute_id):
def compute_graph(request, compute_id): def compute_graph(request, compute_id):
""" """
:param request: :param request:
:param compute_id:
:return: :return:
""" """
compute = get_object_or_404(Compute, pk=compute_id) compute = get_object_or_404(Compute, pk=compute_id)
@ -207,17 +208,16 @@ def get_compute_disk_buses(request, compute_id, disk):
compute.type) compute.type)
disk_device_types = conn.get_disk_device_types() disk_device_types = conn.get_disk_device_types()
disk_bus_types = conn.get_disk_bus_types()
if disk in disk_device_types: if disk in disk_device_types:
if disk == 'disk': if disk == 'disk':
data['bus'] = sorted(disk_device_types) data['bus'] = sorted(disk_device_types)
elif disk == 'cdrom': elif disk == 'cdrom':
data['bus'] = ['ide', 'sata', 'scsi',] data['bus'] = ['ide', 'sata', 'scsi']
elif disk == 'floppy': elif disk == 'floppy':
data['bus'] = ['fdc',] data['bus'] = ['fdc']
elif disk == 'lun': elif disk == 'lun':
data['bus'] = ['scsi',] data['bus'] = ['scsi']
except libvirtError: except libvirtError:
pass pass

View file

@ -120,7 +120,7 @@ def get_connection_infos(token):
console_host = conn.get_console_listen_addr() console_host = conn.get_console_listen_addr()
console_port = conn.get_console_port() console_port = conn.get_console_port()
console_socket = conn.get_console_socket() console_socket = conn.get_console_socket()
except Exception, e: except Exception as e:
logging.error('Fail to retrieve console connection infos for token %s : %s' % (token, e)) logging.error('Fail to retrieve console connection infos for token %s : %s' % (token, e))
raise raise
return (connhost, connport, connuser, conntype, console_host, return (connhost, connport, connuser, conntype, console_host,

View file

@ -1,7 +1,5 @@
import re import re
from django.shortcuts import render from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from instances.models import Instance from instances.models import Instance
from vrtManager.instance import wvmInstance from vrtManager.instance import wvmInstance

View file

@ -17,7 +17,6 @@
<form class="form-horizontal" method="post" role="form">{% csrf_token %} <form class="form-horizontal" method="post" role="form">{% csrf_token %}
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">{% trans "Name" %}</label> <label class="col-sm-3 control-label">{% trans "Name" %}</label>
<div class="col-sm-6"> <div class="col-sm-6">
<input type="text" name="label" class="form-control" placeholder="Micro" maxlength="20" <input type="text" name="label" class="form-control" placeholder="Micro" maxlength="20"
required pattern="[a-zA-Z0-9]+"> required pattern="[a-zA-Z0-9]+">
@ -25,7 +24,6 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">{% trans "VCPU" %}</label> <label class="col-sm-3 control-label">{% trans "VCPU" %}</label>
<div class="col-sm-6"> <div class="col-sm-6">
<input type="text" class="form-control" name="vcpu" value="1" maxlength="1" required <input type="text" class="form-control" name="vcpu" value="1" maxlength="1" required
pattern="[0-9]"> pattern="[0-9]">
@ -33,7 +31,6 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">{% trans "RAM" %}</label> <label class="col-sm-3 control-label">{% trans "RAM" %}</label>
<div class="col-sm-6"> <div class="col-sm-6">
<input type="text" class="form-control" name="memory" value="512" maxlength="5" required <input type="text" class="form-control" name="memory" value="512" maxlength="5" required
pattern="[0-9]+"> pattern="[0-9]+">
@ -42,7 +39,6 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">{% trans "HDD" %}</label> <label class="col-sm-3 control-label">{% trans "HDD" %}</label>
<div class="col-sm-6"> <div class="col-sm-6">
<input type="text" class="form-control" name="disk" value="10" maxlength="3" required <input type="text" class="form-control" name="disk" value="10" maxlength="3" required
pattern="[0-9]+"> pattern="[0-9]+">

View file

@ -224,7 +224,7 @@
<button class="btn btn-primary disabled">{% trans "Create" %}</button> <button class="btn btn-primary disabled">{% trans "Create" %}</button>
{% endif %} {% endif %}
</div> </div>
</form> </form>
</div> </div>
</div> </div>
</div> </div>
@ -436,7 +436,6 @@
</div> </div>
<label class="col-sm-1 control-label">{% trans "MB" %}</label> <label class="col-sm-1 control-label">{% trans "MB" %}</label>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">{% trans "HDD" %}</label> <label class="col-sm-3 control-label">{% trans "HDD" %}</label>
<input id="images" name="images" type="hidden" value=""/> <input id="images" name="images" type="hidden" value=""/>
@ -582,8 +581,7 @@
</div> </div>
<div class="clearfix"></div> <div class="clearfix"></div>
</div> </div>
</div> </div><!-- /Tab panes -->
<!-- /Tab panes -->
</div> </div>
{% endblock %} {% endblock %}
@ -607,7 +605,6 @@
} }
$(document).ready(function () { $(document).ready(function () {
$('#image-control').multiselect({ $('#image-control').multiselect({
disableIfEmpty: true, disableIfEmpty: true,
enableCaseInsensitiveFiltering: true, enableCaseInsensitiveFiltering: true,
@ -716,7 +713,6 @@
function get_disk_bus_choices(compute_id, dev_idx, disk_type){ function get_disk_bus_choices(compute_id, dev_idx, disk_type){
get_diskBus_url = "/computes/" + compute_id + "/disk/" + disk_type + "/buses"; get_diskBus_url = "/computes/" + compute_id + "/disk/" + disk_type + "/buses";
$.getJSON(get_diskBus_url, function (data) { $.getJSON(get_diskBus_url, function (data) {
$("#bus" + dev_idx).find('option').remove(); $("#bus" + dev_idx).find('option').remove();
$.each(data['bus'], function(i, item) { $.each(data['bus'], function(i, item) {

View file

@ -21,6 +21,7 @@ from logs.views import addlogmsg
def create_instance(request, compute_id): def create_instance(request, compute_id):
""" """
:param request: :param request:
:param compute_id:
:return: :return:
""" """
@ -41,9 +42,6 @@ def create_instance(request, compute_id):
compute.password, compute.password,
compute.type) compute.type)
storages = sorted(conn.get_storages(only_actives=True))
networks = sorted(conn.get_networks())
nwfilters = conn.get_nwfilters()
instances = conn.get_instances() instances = conn.get_instances()
videos = conn.get_video() videos = conn.get_video()
cache_modes = sorted(conn.get_cache_modes().items()) cache_modes = sorted(conn.get_cache_modes().items())
@ -53,6 +51,9 @@ def create_instance(request, compute_id):
disk_devices = conn.get_disk_device_types() disk_devices = conn.get_disk_device_types()
disk_buses = conn.get_disk_bus_types() disk_buses = conn.get_disk_bus_types()
default_bus = INSTANCE_VOLUME_DEFAULT_BUS default_bus = INSTANCE_VOLUME_DEFAULT_BUS
networks = sorted(conn.get_networks())
nwfilters = conn.get_nwfilters()
storages = sorted(conn.get_storages(only_actives=True))
except libvirtError as lib_err: except libvirtError as lib_err:
error_messages.append(lib_err) error_messages.append(lib_err)
@ -109,7 +110,7 @@ def create_instance(request, compute_id):
msg = _("A virtual machine with this name already exists") msg = _("A virtual machine with this name already exists")
error_messages.append(msg) error_messages.append(msg)
if Instance.objects.filter(name__exact=data['name']): if Instance.objects.filter(name__exact=data['name']):
messages.warning(request,_("There is an instance with same name. Are you sure?")) messages.warning(request, _("There is an instance with same name. Are you sure?"))
if not error_messages: if not error_messages:
if data['hdd_size']: if data['hdd_size']:
if not data['mac']: if not data['mac']:
@ -148,7 +149,6 @@ def create_instance(request, compute_id):
else: else:
for idx, vol in enumerate(data['images'].split(',')): for idx, vol in enumerate(data['images'].split(',')):
try: try:
path = conn.get_volume_path(vol) path = conn.get_volume_path(vol)
volume = dict() volume = dict()
volume['path'] = path volume['path'] = path
@ -175,7 +175,7 @@ def create_instance(request, compute_id):
addlogmsg(request.user.username, create_instance.name, msg) addlogmsg(request.user.username, create_instance.name, msg)
return HttpResponseRedirect(reverse('instance', args=[compute_id, data['name']])) return HttpResponseRedirect(reverse('instance', args=[compute_id, data['name']]))
except libvirtError as lib_err: except libvirtError as lib_err:
if data['hdd_size'] or volume_list.count() > 0: if data['hdd_size'] or len(volume_list) > 0:
for vol in volume_list: for vol in volume_list:
conn.delete_volume(vol['path']) conn.delete_volume(vol['path'])
error_messages.append(lib_err) error_messages.append(lib_err)

View file

@ -26,7 +26,7 @@ def os_metadata_json(request, version):
if version == 'latest': if version == 'latest':
ip = get_client_ip(request) ip = get_client_ip(request)
hostname = get_hostname_by_ip(ip) hostname = get_hostname_by_ip(ip)
response = { 'uuid': OS_UUID, 'hostname': hostname } response = {'uuid': OS_UUID, 'hostname': hostname}
return HttpResponse(json.dumps(response)) return HttpResponse(json.dumps(response))
else: else:
err = 'Invalid version: {}'.format(version) err = 'Invalid version: {}'.format(version)
@ -70,8 +70,8 @@ def get_client_ip(request):
def get_hostname_by_ip(ip): def get_hostname_by_ip(ip):
try: try:
addrs = socket.gethostbyaddr(ip) addrs = socket.gethostbyaddr(ip)
except Exception: except:
addrs = [ip,] addrs = [ip]
return addrs[0] return addrs[0]

View file

@ -24,10 +24,10 @@
<label class="col-sm-4 control-label">{% trans "Network" %}</label> <label class="col-sm-4 control-label">{% trans "Network" %}</label>
<div class="col-sm-6"> <div class="col-sm-6">
<select class="form-control" name="add-net-network"> <select class="form-control" name="add-net-network">
{% for c_net in compute_networks %} {% for c_net in networks_host %}
<option value="net:{{ c_net }}">Network {{ c_net }}</option> <option value="net:{{ c_net }}">Network {{ c_net }}</option>
{% endfor %} {% endfor %}
{% for c_iface in compute_interfaces %} {% for c_iface in interfaces_host %}
<option value="iface:{{ c_iface }}">Interface {{ c_iface }}</option> <option value="iface:{{ c_iface }}">Interface {{ c_iface }}</option>
{% endfor %} {% endfor %}
</select> </select>
@ -38,7 +38,7 @@
<div class="col-sm-6"> <div class="col-sm-6">
<select class="form-control" name="add-net-nwfilter"> <select class="form-control" name="add-net-nwfilter">
<option value="">{% trans "None" %}</option> <option value="">{% trans "None" %}</option>
{% for nwfilter in compute_nwfilters %} {% for nwfilter in nwfilters_host %}
<option value="{{ nwfilter }}">{{ nwfilter }}</option> <option value="{{ nwfilter }}">{{ nwfilter }}</option>
{% endfor %} {% endfor %}
</select> </select>

View file

@ -1,121 +1,62 @@
{% load i18n %} {% load i18n %}
{% if request.user.is_superuser %} {% if request.user.is_superuser %}
<a href="#addvol" type="button" class="btn btn-success pull-right" data-toggle="modal" title="Add Volume"> <a href="#addvol" type="button" class="btn btn-success pull-right" data-toggle="modal" title="Add Volume">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
</a> </a>
<!-- Modal pool --> <!-- Modal pool -->
<div class="modal fade" id="addvol" tabindex="-1" role="dialog" aria-labelledby="addInstanceVolumeLabel" aria-hidden="true"> <div class="modal fade" id="addvol" tabindex="-1" role="dialog" aria-labelledby="addInstanceVolumeLabel" aria-hidden="true">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">{% trans "Add Instance Volume" %}</h4> <h4 class="modal-title">{% trans "Add Instance Volume" %}</h4>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div class="row"> <div class="row">
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">
<li role="presentation" class="active"><a href="#NewDisk" data-toggle="tab">{% trans 'New Disk' %}</a></li> <li role="presentation" class="active"><a href="#NewDisk" data-toggle="tab">{% trans 'New Disk' %}</a></li>
<li role="presentation"><a href="#ExistingDisk" data-toggle="tab">{% trans 'Existing Disk' %}</a></li> <li role="presentation"><a href="#ExistingDisk" data-toggle="tab">{% trans 'Existing Disk' %}</a></li>
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
<div class="tab-pane active" id="NewDisk"> <div class="tab-pane active" id="NewDisk">
<form class="form-horizontal" method="post" role="form">{% csrf_token %} <form class="form-horizontal" method="post" role="form">{% csrf_token %}
<p style="font-weight:bold;">{% trans "Volume parameters" %}</p>
<div class="form-group">
<label class="col-sm-3 control-label">{% trans "Storage" %}</label>
<div class="col-sm-4">
<select name="storage" class="form-control image-format">
{% for storage in storages %}
<option value="{{ storage }}">{{ storage }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">{% trans "Name" %}</label>
<div class="col-sm-4">
<input type="text" class="form-control" name="name" placeholder="{% trans "Name" %}" required pattern="[a-zA-Z0-9\.\-_]+">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">{% trans "Format" %}</label>
<div class="col-sm-4">
<select name="format" class="form-control image-format">
{% for format in formats %}
<option value="{{ format }}" {% if format == default_format %}selected{% endif %}>{% trans format %}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">{% trans "Size" %}</label>
<div class="col-sm-4">
<input type="text" class="form-control" name="size" value="10" maxlength="5" required pattern="[0-9]+">
</div>
<label class="col-sm-1 control-label">{% trans "GB" %}</label>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">{% trans "Bus" %}</label>
<div class="col-sm-4">
<select name="bus" class="form-control image-format">
{% for bus in busses %}
<option value="{{ bus }}" {% if bus == default_bus %}selected{% endif %}>{% trans bus %}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">{% trans "Cache" %}</label>
<div class="col-sm-4">
<select name="cache" class="form-control image-format">
{% for mode, name in cache_modes %}
<option value="{{ mode }}" {% if mode == default_cache %}selected{% endif %}>{% trans name %}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group meta-prealloc">
<label class="col-sm-3 control-label">{% trans "Metadata" %}</label>
<div class="col-sm-4">
<input type="checkbox" name="meta_prealloc" value="true">
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-lg btn-success pull-right" name="add_new_vol">{% trans "Add Volume" %}</button>
</div>
</form>
</div>
<div class="tab-pane" id="ExistingDisk">
<form class="form-horizontal" method="post" role="form">{% csrf_token %}
<div class="modal-body">
<p style="font-weight:bold;">{% trans "Volume parameters" %}</p> <p style="font-weight:bold;">{% trans "Volume parameters" %}</p>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">{% trans "Storage" %}</label> <label class="col-sm-3 control-label">{% trans "Storage" %}</label>
<div class="col-sm-4"> <div class="col-sm-4">
<div class="dropdown"> <select name="storage" class="form-control image-format">
<button id="select_storage" class="btn btn-default dropdown-toggle form-control" type="button" data-toggle="dropdown">{% trans 'Select Pool...' %} {% for storage in storages_host %}
<span class="caret"></span></button> <option value="{{ storage }}">{{ storage }}</option>
<ul class="dropdown-menu"> {% endfor %}
{% for storage in storages %} </select>
<li><a href="#" onclick="get_volumes({{ compute_id }}, '{{ storage }}')">{{ storage }}</a></li>
{% endfor %}
</ul>
<input id="selected_storage" name="selected_storage" hidden/>
</div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label" >{% trans "Volume" %}</label> <label class="col-sm-3 control-label">{% trans "Name" %}</label>
<div class="col-sm-4"> <div class="col-sm-4">
<select id="vols" name="vols" class="form-control" disabled> <input type="text" class="form-control" name="name" placeholder="{% trans "Name" %}" required pattern="[a-zA-Z0-9\.\-_]+">
<option value="" selected>{% trans 'None' %}</option> </div>
<!-- populate with javascript --> </div>
<div class="form-group">
<label class="col-sm-3 control-label">{% trans "Format" %}</label>
<div class="col-sm-4">
<select name="format" class="form-control image-format">
{% for format in formats %}
<option value="{{ format }}" {% if format == default_format %}selected{% endif %}>{% trans format %}</option>
{% endfor %}
</select> </select>
</div> </div>
</div> </div>
<div class="form-group">
<label class="col-sm-3 control-label">{% trans "Size" %}</label>
<div class="col-sm-4">
<input type="text" class="form-control" name="size" value="10" maxlength="5" required pattern="[0-9]+">
</div>
<label class="col-sm-1 control-label">{% trans "GB" %}</label>
</div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">{% trans "Bus" %}</label> <label class="col-sm-3 control-label">{% trans "Bus" %}</label>
<div class="col-sm-4"> <div class="col-sm-4">
@ -136,16 +77,75 @@
</select> </select>
</div> </div>
</div> </div>
<div class="form-group meta-prealloc">
<label class="col-sm-3 control-label">{% trans "Metadata" %}</label>
<div class="col-sm-4">
<input type="checkbox" name="meta_prealloc" value="true">
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-lg btn-success pull-right" name="add_new_vol">{% trans "Add Volume" %}</button>
</div>
</form>
</div> </div>
<div class="modal-footer"> <div class="tab-pane" id="ExistingDisk">
<button type="submit" class="btn btn-lg btn-success pull-right" name="add_existing_vol">{% trans "Add Volume" %}</button> <form class="form-horizontal" method="post" role="form">{% csrf_token %}
<div class="modal-body">
<p style="font-weight:bold;">{% trans "Volume parameters" %}</p>
<div class="form-group">
<label class="col-sm-3 control-label">{% trans "Storage" %}</label>
<div class="col-sm-4">
<div class="dropdown">
<button id="select_storage" class="btn btn-default dropdown-toggle form-control" type="button" data-toggle="dropdown">{% trans 'Select Pool...' %}
<span class="caret"></span></button>
<ul class="dropdown-menu">
{% for storage in storages %}
<li><a href="#" onclick="get_volumes({{ compute_id }}, '{{ storage }}')">{{ storage }}</a></li>
{% endfor %}
</ul>
<input id="selected_storage" name="selected_storage" hidden/>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" >{% trans "Volume" %}</label>
<div class="col-sm-4">
<select id="vols" name="vols" class="form-control" disabled>
<option value="" selected>{% trans 'None' %}</option>
<!-- populate with javascript -->
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">{% trans "Bus" %}</label>
<div class="col-sm-4">
<select name="bus" class="form-control image-format">
{% for bus in busses %}
<option value="{{ bus }}" {% if bus == default_bus %}selected{% endif %}>{% trans bus %}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">{% trans "Cache" %}</label>
<div class="col-sm-4">
<select name="cache" class="form-control image-format">
{% for mode, name in cache_modes %}
<option value="{{ mode }}" {% if mode == default_cache %}selected{% endif %}>{% trans name %}</option>
{% endfor %}
</select>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-lg btn-success pull-right" name="add_existing_vol">{% trans "Add Volume" %}</button>
</div>
</form>
</div> </div>
</form>
</div> </div>
</div> </div> <!-- row -->
</div> <!-- row --> </div> <!-- /.modal-body -->
</div> <!-- /.modal-body --> </div> <!-- /.modal-content -->
</div> <!-- /.modal-content --> </div> <!-- /.modal-dialog -->
</div> <!-- /.modal-dialog --> </div> <!-- /.modal -->
</div> <!-- /.modal -->
{% endif %} {% endif %}

View file

@ -6,140 +6,140 @@
<link rel="stylesheet" href="{% static "css/sortable-theme-bootstrap.css" %}" /> <link rel="stylesheet" href="{% static "css/sortable-theme-bootstrap.css" %}" />
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<!-- Page Heading --> <!-- Page Heading -->
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
{% if request.user.is_superuser %} {% if request.user.is_superuser %}
{% include 'create_inst_block.html' %} {% include 'create_inst_block.html' %}
{% endif %} {% endif %}
{% if all_host_vms or all_user_vms %} {% if all_host_vms or all_user_vms %}
<div class="pull-right search"> <div class="pull-right search">
<input id="filter" class="form-control" type="text" placeholder="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">&times</button>
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning:" %}</strong> {% trans "You don't have any Instance" %}
</div> </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">&times</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">&times;</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>{% trans 'Name' %}</th>
<th>{% trans 'Status' %}</th>
<th>{% trans 'VCPU' %}</th>
<th>{% trans 'Memory' %}</th>
<th data-sortable="false" style="width: 165px;">{% trans '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> {% else %}
</div> {% 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">&times;</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>{% trans 'Name' %}</th>
<th>{% trans 'Status' %}</th>
<th>{% trans 'VCPU' %}</th>
<th>{% trans 'Memory' %}</th>
<th data-sortable="false" style="width: 165px;">{% trans '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 %} {% endblock %}
{% block script %} {% block script %}
<script src="{% static "js/sortable.min.js" %}"></script> <script src="{% static "js/sortable.min.js" %}"></script>

View file

@ -3,7 +3,7 @@
<thead> <thead>
<tr> <tr>
<th><a href="#" id="hide_all_instances" onclick="hide_all_host_instances()">#</a> </th> <th><a href="#" id="hide_all_instances" onclick="hide_all_host_instances()">#</a> </th>
<th>{% trans "Name" %}<br>{% trans "Description" %}</th></th> <th>{% trans "Name" %}<br>{% trans "Description" %}</th>
<th>{% trans "User"%}</th> <th>{% trans "User"%}</th>
<th>{% trans "Status" %}</th> <th>{% trans "Status" %}</th>
<th>{% trans "VCPU" %}</th> <th>{% trans "VCPU" %}</th>
@ -71,16 +71,16 @@
<span class="glyphicon glyphicon-play"></span> <span class="glyphicon glyphicon-play"></span>
</button> </button>
{% endif %} {% endif %}
<button class="btn btn-sm btn-default disabled" title="{% trans "Suspend" %}"> <button class="btn btn-sm btn-default disabled" title="{% trans "Suspend" %}" disabled>
<span class="glyphicon glyphicon-pause"></span> <span class="glyphicon glyphicon-pause"></span>
</button> </button>
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Off" %}"> <button class="btn btn-sm btn-default disabled" title="{% trans "Power Off" %}" disabled>
<span class="glyphicon glyphicon-off"></span> <span class="glyphicon glyphicon-off"></span>
</button> </button>
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Cycle" %}"> <button class="btn btn-sm btn-default disabled" title="{% trans "Power Cycle" %}" disabled>
<span class="glyphicon glyphicon-refresh"></span> <span class="glyphicon glyphicon-refresh"></span>
</button> </button>
<button class="btn btn-sm btn-default disabled" title="{% trans "VNC Console" %}"> <button class="btn btn-sm btn-default disabled" title="{% trans "VNC Console" %}" disabled>
<span class="glyphicon glyphicon-eye-open"></span> <span class="glyphicon glyphicon-eye-open"></span>
</button> </button>
{% endifequal %} {% endifequal %}
@ -88,21 +88,21 @@
<button class="btn btn-sm btn-default" type="submit" name="resume" title="{% trans "Resume" %}"> <button class="btn btn-sm btn-default" type="submit" name="resume" title="{% trans "Resume" %}">
<span class="glyphicon glyphicon-play"></span> <span class="glyphicon glyphicon-play"></span>
</button> </button>
<button class="btn btn-sm btn-default disabled" title="{% trans "Suspend" %}"> <button class="btn btn-sm btn-default disabled" title="{% trans "Suspend" %}" disabled>
<span class="glyphicon glyphicon-pause"></span> <span class="glyphicon glyphicon-pause"></span>
</button> </button>
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Off" %}"> <button class="btn btn-sm btn-default" type="submit" name="powerforce" title="{% trans "Force Off" %}" onclick="return confirm('Are you sure to force it down?')">
<span class="glyphicon glyphicon-off"></span> <span class="glyphicon glyphicon-off"></span>
</button> </button>
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Cycle" %}"> <button class="btn btn-sm btn-default disabled" title="{% trans "Power Cycle" %}" disabled>
<span class="glyphicon glyphicon-refresh"></span> <span class="glyphicon glyphicon-refresh"></span>
</button> </button>
<button class="btn btn-sm btn-default disabled" title="{% trans "VNC Console" %}"> <button class="btn btn-sm btn-default disabled" title="{% trans "VNC Console" %}" disabled>
<span class="glyphicon glyphicon-eye-open"></span> <span class="glyphicon glyphicon-eye-open"></span>
</button> </button>
{% endifequal %} {% endifequal %}
{% ifequal info.status 1 %} {% ifequal info.status 1 %}
<button class="btn btn-sm btn-default disabled" title="{% trans "Power On" %}"> <button class="btn btn-sm btn-default disabled" title="{% trans "Power On" %}" disabled>
<span class="glyphicon glyphicon-play"></span> <span class="glyphicon glyphicon-play"></span>
</button> </button>
<button class="btn btn-sm btn-default" type="submit" name="suspend" title="{% trans "Suspend" %}"> <button class="btn btn-sm btn-default" type="submit" name="suspend" title="{% trans "Suspend" %}">
@ -114,9 +114,9 @@
<button class="btn btn-sm btn-default" type="submit" name="powercycle" title="{% trans "Power Cycle" %}" onclick="return confirm('Are you sure?')"> <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> <span class="glyphicon glyphicon-refresh"></span>
</button> </button>
<a href="#" class="btn btn-sm btn-default" onclick='open_console("{{ host.0 }}-{{ info.uuid }}")' title="{% trans "Console" %}"> <button class="btn btn-sm btn-default" type="button" onclick='open_console("{{ host.0 }}-{{ info.uuid }}")' title="{% trans "Console" %}">
<span class="glyphicon glyphicon-eye-open"></span> <span class="glyphicon glyphicon-eye-open"></span>
</a> </button>
{% endifequal %} {% endifequal %}
</form> </form>
</td> </td>

View file

@ -2,11 +2,11 @@
<table class="table table-hover table-striped sortable-theme-bootstrap" data-sortable> <table class="table table-hover table-striped sortable-theme-bootstrap" data-sortable>
<thead> <thead>
<tr> <tr>
<th>Name<br>Description</th> <th>{% trans "Name" %}<br>{% trans "Description" %}</th>
<th>Host<br>User</th> <th>{% trans "Host" %}<br>{% trans "User"%}</th>
<th>Status</th> <th>{% trans "Status" %}</th>
<th>VCPU</th> <th>{% trans "VCPU" %}</th>
<th>Memory</th> <th>{% trans "Memory" %}</th>
<th data-sortable="false" style="width:205px;">{% trans "Actions" %}</th> <th data-sortable="false" style="width:205px;">{% trans "Actions" %}</th>
</tr> </tr>
</thead> </thead>
@ -23,67 +23,68 @@
</td> </td>
<td>{{ info.vcpu }}</td> <td>{{ info.vcpu }}</td>
<td>{{ info.memory|filesizeformat }}</td> <td>{{ info.memory|filesizeformat }}</td>
<td><form action="" method="post" role="form">{% csrf_token %} <td>
<input type="hidden" name="name" value="{{ vm }}"/> <form action="" method="post" role="form">{% csrf_token %}
<input type="hidden" name="compute_id" value="{{ host.0 }}"/> <input type="hidden" name="name" value="{{ vm }}"/>
{% ifequal info.status 5 %} <input type="hidden" name="compute_id" value="{{ host.0 }}"/>
{% if info.is_template %} {% ifequal info.status 5 %}
<button class="btn btn-sm btn-default" type="button" name="clone" title="{% trans "Clone" %}" onclick="goto_instance_clone({{ host.0 }}, '{{ vm }}');"> {% if info.is_template %}
<span class="glyphicon glyphicon-duplicate"></span> <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 %}
<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 "Suspend" %}" disabled>
<span class="glyphicon glyphicon-pause"></span>
</button> </button>
{% else %} <button class="btn btn-sm btn-default disabled" title="{% trans "Power Off" %}" disabled>
<button class="btn btn-sm btn-default" type="submit" name="poweron" title="{% trans "Power On" %}"> <span class="glyphicon glyphicon-off"></span>
</button>
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Cycle" %}" disabled>
<span class="glyphicon glyphicon-refresh"></span>
</button>
<button class="btn btn-sm btn-default disabled" title="{% trans "VNC Console" %}" disabled>
<span class="glyphicon glyphicon-eye-open"></span>
</button>
{% endifequal %}
{% ifequal info.status 3 %}
<button class="btn btn-sm btn-default" type="submit" name="resume" title="{% trans "Resume" %}">
<span class="glyphicon glyphicon-play"></span> <span class="glyphicon glyphicon-play"></span>
</button> </button>
{% endif %} <button class="btn btn-sm btn-default disabled" title="{% trans "Suspend" %}" disabled>
<button class="btn btn-sm btn-default disabled" title="{% trans "Suspend" %}"> <span class="glyphicon glyphicon-pause"></span>
<span class="glyphicon glyphicon-pause"></span> </button>
</button> <button class="btn btn-sm btn-default" type="submit" name="powerforce" title="{% trans "Force Off" %}" onclick="return confirm('Are you sure to force it down?')">
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Off" %}"> <span class="glyphicon glyphicon-off"></span>
<span class="glyphicon glyphicon-off"></span> </button>
</button> <button class="btn btn-sm btn-default disabled" title="{% trans "Power Cycle" %}" disabled>
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Cycle" %}"> <span class="glyphicon glyphicon-refresh"></span>
<span class="glyphicon glyphicon-refresh"></span> </button>
</button> <button class="btn btn-sm btn-default disabled" title="{% trans "VNC Console" %}" disabled>
<button class="btn btn-sm btn-default disabled" title="{% trans "VNC Console" %}"> <span class="glyphicon glyphicon-eye-open"></span>
<span class="glyphicon glyphicon-eye-open"></span> </button>
</button> {% endifequal %}
{% endifequal %} {% ifequal info.status 1 %}
{% ifequal info.status 3 %} <button class="btn btn-sm btn-default disabled" title="{% trans "Power On" %}" disabled>
<button class="btn btn-sm btn-default" type="submit" name="resume" title="{% trans "Resume" %}"> <span class="glyphicon glyphicon-play"></span>
<span class="glyphicon glyphicon-play"></span> </button>
</button> <button class="btn btn-sm btn-default" type="submit" name="suspend" title="{% trans "Suspend" %}">
<button class="btn btn-sm btn-default disabled" title="{% trans "Suspend" %}"> <span class="glyphicon glyphicon-pause"></span>
<span class="glyphicon glyphicon-pause"></span> </button>
</button> <button class="btn btn-sm btn-default" type="submit" name="poweroff" title="{% trans "Power Off" %}" onclick="return confirm('Are you sure?')">
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Off" %}"> <span class="glyphicon glyphicon-off"></span>
<span class="glyphicon glyphicon-off"></span> </button>
</button> <button class="btn btn-sm btn-default" type="submit" name="powercycle" title="{% trans "Power Cycle" %}" onclick="return confirm('Are you sure?')">
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Cycle" %}"> <span class="glyphicon glyphicon-refresh"></span>
<span class="glyphicon glyphicon-refresh"></span> </button>
</button> <button class="btn btn-sm btn-default" type="button" onclick='open_console("{{ host.0 }}-{{ info.uuid }}")' title="{% trans "Console" %}">
<button class="btn btn-sm btn-default disabled" title="{% trans "VNC Console" %}"> <span class="glyphicon glyphicon-eye-open"></span>
<span class="glyphicon glyphicon-eye-open"></span> </button>
</button> {% endifequal %}
{% endifequal %} </form>
{% 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="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("{{ host.0 }}-{{ info.uuid }}")' title="{% trans "Console" %}">
<span class="glyphicon glyphicon-eye-open"></span>
</a>
{% endifequal %}
</form>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}

File diff suppressed because it is too large Load diff

View file

@ -7,156 +7,155 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<!-- Page Heading --> <!-- Page Heading -->
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
{% if request.user.is_superuser %} {% if request.user.is_superuser %}
<a href="{% url 'create_instance' compute.id %}" type="button" class="btn btn-success btn-header pull-right" data-toggle="modal"> <a href="{% url 'create_instance' compute.id %}" type="button" class="btn btn-success btn-header pull-right" data-toggle="modal">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
</a> </a>
{% endif %} {% endif %}
{% if all_host_vms or all_user_vms %} {% if all_host_vms or all_user_vms %}
<div class="pull-right search"> <div class="pull-right search">
<input id="filter" class="form-control" type="text" placeholder="Search"> <input id="filter" class="form-control" type="text" placeholder="Search">
</div>
{% endif %}
<h1 class="page-header">{{ compute.name }}</h1>
</div>
</div> </div>
<div class="row"> {% endif %}
<div class="col-lg-12"> <h1 class="page-header">{{ compute.name }}</h1>
</div>
<ol class="breadcrumb"> </div>
<li class="active"> <div class="row">
<i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a> <div class="col-lg-12">
</li> <ol class="breadcrumb">
<li> <li class="active">
<i class="fa fa-server"></i> {% trans "Instances" %} <i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a> <i class="fa fa-server"></i> {% trans "Instances" %}
</li> </li>
<li> <li>
<i class="fa fa-sitemap"></i> <a href="{% url 'networks' compute.id %}">{% trans "Networks" %}</a> <i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-wifi"></i> <a href="{% url 'interfaces' compute.id %}">{% trans "Interfaces" %}</a> <i class="fa fa-sitemap"></i> <a href="{% url 'networks' compute.id %}">{% trans "Networks" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-filter"></i> <a href="{% url 'nwfilters' compute.id %}">{% trans "NWFilters" %}</a> <i class="fa fa-wifi"></i> <a href="{% url 'interfaces' compute.id %}">{% trans "Interfaces" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-key"></i> <a href="{% url 'secrets' compute.id %}">{% trans "Secrets" %}</a> <i class="fa fa-filter"></i> <a href="{% url 'nwfilters' compute.id %}">{% trans "NWFilters" %}</a>
</li> </li>
</ol> <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">
{% 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">&times;</button>
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning" %}:</strong> {% trans "Hypervisor doesn't have any instances" %}
</div> </div>
</div> </div>
<!-- /.row --> {% else %}
<div class="col-lg-12">
{% include 'errors_block.html' %} <table class="table table-hover table-striped sortable-theme-bootstrap" data-sortable>
<div class="row"> <thead>
{% if not all_host_vms %} <tr>
<div class="col-lg-12"> <th>{% trans 'Name' %}<br>{% trans 'Description' %}</th>
<div class="alert alert-warning alert-dismissable"> <th>{% trans 'User' %}</th>
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button> <th>{% trans 'Status' %}</th>
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning:" %}</strong> {% trans "Hypervisor doesn't have any instances" %} <th>{% trans 'VCPU' %}</th>
</div> <th>{% trans 'Memory' %}</th>
</div> <th data-sortable="false" style="width:205px;">{% trans 'Actions' %}</th>
{% else %} </tr>
<div class="col-lg-12"> </thead>
<table class="table table-hover table-striped sortable-theme-bootstrap" data-sortable> <tbody class="searchable">
<thead> {% for host, inst in all_host_vms.items %}
{% for vm, info in inst.items %}
<tr> <tr>
<th>{% trans 'Name' %}<br>{% trans 'Description' %}</th> <td><a href="{% url 'instance' host.0 vm %}">{{ vm }}</a><br><small><em>{{ info.title }}</em></small></td>
<th>{% trans 'Host' %}<br>{% trans 'User' %}</th> <td><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></td>
<th>{% trans 'Status' %}</th> <td>
<th>{% trans 'VCPU' %}</th> {% ifequal info.status 1 %}<span class="text-success">{% trans "Active" %}</span>{% endifequal %}
<th>{% trans 'Memory' %}</th> {% ifequal info.status 5 %}<span class="text-danger">{% trans "Off" %}</span>{% endifequal %}
<th data-sortable="false" style="width:205px;">{% trans 'Actions' %}</th> {% ifequal info.status 3 %}<span class="text-warning">{% trans "Suspend" %}</span>{% endifequal %}
</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 }}"/>
<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 %}
<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 "Suspend" %}" disabled>
<span class="glyphicon glyphicon-pause"></span>
</button>
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Off" %}" disabled>
<span class="glyphicon glyphicon-off"></span>
</button>
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Cycle" %}" disabled>
<span class="glyphicon glyphicon-refresh"></span>
</button>
<button class="btn btn-sm btn-default disabled" title="{% trans "VNC Console" %}" disabled>
<span class="glyphicon glyphicon-eye-open"></span>
</button>
{% endifequal %}
{% 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" %}" disabled>
<span class="glyphicon glyphicon-pause"></span>
</button>
<button class="btn btn-sm btn-default" type="submit" name="powerforce" title="{% trans "Force Off" %}" onclick="return confirm('Are you sure to force it down?')">
<span class="glyphicon glyphicon-off"></span>
</button>
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Cycle" %}" disabled>
<span class="glyphicon glyphicon-refresh"></span>
</button>
<button class="btn btn-sm btn-default disabled" title="{% trans "VNC Console" %}" disabled>
<span class="glyphicon glyphicon-eye-open"></span>
</button>
{% endifequal %}
{% ifequal info.status 1 %}
<button class="btn btn-sm btn-default disabled" title="{% trans "Power On" %}" disabled>
<span class="glyphicon glyphicon-play"></span>
</button>
<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>
<button class="btn btn-sm btn-default" type="button" onclick='open_console("{{ host.0 }}-{{ info.uuid }}")' title="{% trans "Console" %}">
<span class="glyphicon glyphicon-eye-open"></span>
</button>
{% endifequal %}
</form>
</td>
</tr> </tr>
</thead> {% endfor %}
<tbody class="searchable"> {% endfor %}
{% for host, inst in all_host_vms.items %} </tbody>
{% for vm, info in inst.items %} </table>
<tr> </div>
<td><a href="{% url 'instance' host.0 vm %}">{{ vm }}</a><br><small><em>{{ info.title }}</em></small></td> {% endif %}
<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> </div>
<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>{{ info.vcpu }}</td>
<td>{{ info.memory|filesizeformat }}</td>
<td><form action="" method="post" role="form">{% csrf_token %}
<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 %}
<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 "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 Console" %}">
<span class="glyphicon glyphicon-eye-open"></span>
</button>
{% endifequal %}
{% 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 Console" %}">
<span class="glyphicon glyphicon-eye-open"></span>
</button>
{% endifequal %}
{% 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="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("{{ host.0 }}-{{ info.uuid }}")' title="{% trans "Console" %}">
<span class="glyphicon glyphicon-eye-open"></span>
</a>
{% endifequal %}
</form>
</td>
</tr>
{% endfor %}
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
</div>
{% endblock %} {% endblock %}
{% block script %} {% block script %}
<script src="{% static "js/sortable.min.js" %}"></script> <script src="{% static "js/sortable.min.js" %}"></script>

View file

@ -27,6 +27,7 @@ from logs.views import addlogmsg
from django.conf import settings from django.conf import settings
from django.contrib import messages from django.contrib import messages
@login_required @login_required
def index(request): def index(request):
""" """
@ -100,11 +101,12 @@ def instances(request, compute_id):
def instance(request, compute_id, vname): def instance(request, compute_id, vname):
""" """
:param request: :param request:
:param compute_id:
:param vname:
:return: :return:
""" """
error_messages = [] error_messages = []
# messages = []
compute = get_object_or_404(Compute, pk=compute_id) compute = get_object_or_404(Compute, pk=compute_id)
computes = Compute.objects.all().order_by('name') computes = Compute.objects.all().order_by('name')
computes_count = computes.count() computes_count = computes.count()
@ -257,9 +259,6 @@ def instance(request, compute_id, vname):
compute.password, compute.password,
compute.type, compute.type,
vname) vname)
compute_networks = sorted(conn.get_networks())
compute_interfaces = sorted(conn.get_ifaces())
compute_nwfilters = conn.get_nwfilters()
status = conn.get_status() status = conn.get_status()
autostart = conn.get_autostart() autostart = conn.get_autostart()
bootmenu = conn.get_bootmenu() bootmenu = conn.get_bootmenu()
@ -271,13 +270,13 @@ def instance(request, compute_id, vname):
cur_memory = conn.get_cur_memory() cur_memory = conn.get_cur_memory()
title = conn.get_title() title = conn.get_title()
description = conn.get_description() description = conn.get_description()
networks = conn.get_net_device()
disks = conn.get_disk_devices() disks = conn.get_disk_devices()
media = conn.get_media_devices() media = conn.get_media_devices()
if len(media) != 0: if len(media) != 0:
media_iso = sorted(conn.get_iso_media()) media_iso = sorted(conn.get_iso_media())
else: else:
media_iso = [] media_iso = []
networks = conn.get_net_device()
vcpu_range = conn.get_max_cpus() vcpu_range = conn.get_max_cpus()
memory_range = [256, 512, 768, 1024, 2048, 3072, 4096, 6144, 8192, 16384] memory_range = [256, 512, 768, 1024, 2048, 3072, 4096, 6144, 8192, 16384]
@ -285,8 +284,6 @@ def instance(request, compute_id, vname):
insort(memory_range, memory) insort(memory_range, memory)
if cur_memory not in memory_range: if cur_memory not in memory_range:
insort(memory_range, cur_memory) insort(memory_range, cur_memory)
memory_host = conn.get_max_memory()
vcpu_host = len(vcpu_range)
telnet_port = conn.get_telnet_port() telnet_port = conn.get_telnet_port()
console_type = conn.get_console_type() console_type = conn.get_console_type()
console_port = conn.get_console_port() console_port = conn.get_console_port()
@ -298,18 +295,16 @@ def instance(request, compute_id, vname):
console_passwd = conn.get_console_passwd() console_passwd = conn.get_console_passwd()
clone_free_names = get_clone_free_names() clone_free_names = get_clone_free_names()
user_quota_msg = check_user_quota(0, 0, 0, 0) user_quota_msg = check_user_quota(0, 0, 0, 0)
storages = sorted(conn.get_storages())
cache_modes = sorted(conn.get_cache_modes().items()) cache_modes = sorted(conn.get_cache_modes().items())
default_cache = settings.INSTANCE_VOLUME_DEFAULT_CACHE default_cache = settings.INSTANCE_VOLUME_DEFAULT_CACHE
default_format = settings.INSTANCE_VOLUME_DEFAULT_FORMAT default_format = settings.INSTANCE_VOLUME_DEFAULT_FORMAT
default_owner = settings.INSTANCE_VOLUME_DEFAULT_OWNER default_owner = settings.INSTANCE_VOLUME_DEFAULT_OWNER
formats = conn.get_image_formats() formats = conn.get_image_formats()
busses = conn.get_disk_bus_types()
default_bus = settings.INSTANCE_VOLUME_DEFAULT_BUS
show_access_root_password = settings.SHOW_ACCESS_ROOT_PASSWORD show_access_root_password = settings.SHOW_ACCESS_ROOT_PASSWORD
show_access_ssh_keys = settings.SHOW_ACCESS_SSH_KEYS show_access_ssh_keys = settings.SHOW_ACCESS_SSH_KEYS
clone_instance_auto_name = settings.CLONE_INSTANCE_AUTO_NAME clone_instance_auto_name = settings.CLONE_INSTANCE_AUTO_NAME
default_bus = settings.INSTANCE_VOLUME_DEFAULT_BUS
try: try:
instance = Instance.objects.get(compute_id=compute_id, name=vname) instance = Instance.objects.get(compute_id=compute_id, name=vname)
@ -327,6 +322,15 @@ def instance(request, compute_id, vname):
userinstances = UserInstance.objects.filter(instance=instance).order_by('user__username') userinstances = UserInstance.objects.filter(instance=instance).order_by('user__username')
allow_admin_or_not_template = request.user.is_superuser or request.user.is_staff or not instance.is_template allow_admin_or_not_template = request.user.is_superuser or request.user.is_staff or not instance.is_template
# Host resources
vcpu_host = len(vcpu_range)
memory_host = conn.get_max_memory()
bus_host = conn.get_disk_bus_types()
networks_host = sorted(conn.get_networks())
interfaces_host = sorted(conn.get_ifaces())
nwfilters_host = conn.get_nwfilters()
storages_host = sorted(conn.get_storages(True))
if request.method == 'POST': if request.method == 'POST':
if 'poweron' in request.POST: if 'poweron' in request.POST:
if instance.is_template: if instance.is_template:
@ -460,11 +464,70 @@ def instance(request, compute_id, vname):
addlogmsg(request.user.username, instance.name, msg) addlogmsg(request.user.username, instance.name, msg)
return HttpResponseRedirect(request.get_full_path() + '#resize') return HttpResponseRedirect(request.get_full_path() + '#resize')
if 'resizevm_cpu' 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', '')
quota_msg = check_user_quota(0, int(new_vcpu) - vcpu, 0, 0)
if not request.user.is_superuser and quota_msg:
msg = _("User %s quota reached, cannot resize CPU of '%s'!" % (quota_msg, instance.name))
error_messages.append(msg)
else:
cur_vcpu = new_cur_vcpu
vcpu = new_vcpu
conn.resize_cpu(cur_vcpu, vcpu)
msg = _("Resize CPU")
addlogmsg(request.user.username, instance.name, msg)
return HttpResponseRedirect(request.get_full_path() + '#resize')
if 'resizevm_mem' in request.POST and (
request.user.is_superuser or request.user.is_staff or userinstance.is_change):
new_memory = request.POST.get('memory', '')
new_memory_custom = request.POST.get('memory_custom', '')
if new_memory_custom:
new_memory = new_memory_custom
new_cur_memory = request.POST.get('cur_memory', '')
new_cur_memory_custom = request.POST.get('cur_memory_custom', '')
if new_cur_memory_custom:
new_cur_memory = new_cur_memory_custom
quota_msg = check_user_quota(0, 0, int(new_memory) - memory, 0)
if not request.user.is_superuser and quota_msg:
msg = _("User %s quota reached, cannot resize memory of '%s'!" % (quota_msg, instance.name))
error_messages.append(msg)
else:
cur_memory = new_cur_memory
memory = new_memory
conn.resize_mem(cur_memory, memory)
msg = _("Resize Memory")
addlogmsg(request.user.username, instance.name, msg)
return HttpResponseRedirect(request.get_full_path() + '#resize')
if 'resizevm_disk' in request.POST and (
request.user.is_superuser or request.user.is_staff or userinstance.is_change):
disks_new = list()
for disk in disks:
input_disk_size = filesizefstr(request.POST.get('disk_size_' + disk['dev'], ''))
if input_disk_size > disk['size'] + (64 << 20):
disk['size_new'] = input_disk_size
disks_new.append(disk)
disk_sum = sum([disk['size'] >> 30 for disk in disks_new])
disk_new_sum = sum([disk['size_new'] >> 30 for disk in disks_new])
quota_msg = check_user_quota(0, 0, 0, disk_new_sum - disk_sum)
if not request.user.is_superuser and quota_msg:
msg = _("User %s quota reached, cannot resize disks of '%s'!" % (quota_msg, instance.name))
error_messages.append(msg)
else:
conn.resize_disk(disks_new)
msg = _("Resize")
addlogmsg(request.user.username, instance.name, msg)
return HttpResponseRedirect(request.get_full_path() + '#resize')
if 'add_new_vol' in request.POST and allow_admin_or_not_template: if 'add_new_vol' in request.POST and allow_admin_or_not_template:
connCreate = wvmCreate(compute.hostname, conn_create = wvmCreate(compute.hostname,
compute.login, compute.login,
compute.password, compute.password,
compute.type) compute.type)
storage = request.POST.get('storage', '') storage = request.POST.get('storage', '')
name = request.POST.get('name', '') name = request.POST.get('name', '')
format = request.POST.get('format', default_format) format = request.POST.get('format', default_format)
@ -474,7 +537,7 @@ def instance(request, compute_id, vname):
cache = request.POST.get('cache', default_cache) cache = request.POST.get('cache', default_cache)
target = get_new_disk_dev(media, disks, bus) target = get_new_disk_dev(media, disks, bus)
path = connCreate.create_volume(storage, name, size, format, meta_prealloc, default_owner) path = conn_create.create_volume(storage, name, size, format, meta_prealloc, default_owner)
conn.attach_disk(path, target, subdriver=format, cache=cache, targetbus=bus) conn.attach_disk(path, target, subdriver=format, cache=cache, targetbus=bus)
msg = _('Attach new disk {} ({})'.format(name, format)) msg = _('Attach new disk {} ({})'.format(name, format))
addlogmsg(request.user.username, instance.name, msg) addlogmsg(request.user.username, instance.name, msg)
@ -486,16 +549,16 @@ def instance(request, compute_id, vname):
bus = request.POST.get('bus', default_bus) bus = request.POST.get('bus', default_bus)
cache = request.POST.get('cache', default_cache) cache = request.POST.get('cache', default_cache)
connCreate = wvmStorage(compute.hostname, conn_create = wvmStorage(compute.hostname,
compute.login, compute.login,
compute.password, compute.password,
compute.type, compute.type,
storage) storage)
format = connCreate.get_volume_type(name) format = conn_create.get_volume_type(name)
path = connCreate.get_target_path() path = conn_create.get_target_path()
target = get_new_disk_dev(media, disks, bus) target = get_new_disk_dev(media, disks, bus)
source = path + "/" + name; source = path + "/" + name
conn.attach_disk(source, target, subdriver=format, cache=cache, targetbus=bus) conn.attach_disk(source, target, subdriver=format, cache=cache, targetbus=bus)
msg = _('Attach Existing disk: ' + target) msg = _('Attach Existing disk: ' + target)
@ -504,17 +567,17 @@ def instance(request, compute_id, vname):
if 'delete_vol' in request.POST and allow_admin_or_not_template: if 'delete_vol' in request.POST and allow_admin_or_not_template:
storage = request.POST.get('storage', '') storage = request.POST.get('storage', '')
connDelete = wvmStorage(compute.hostname, conn_delete = wvmStorage(compute.hostname,
compute.login, compute.login,
compute.password, compute.password,
compute.type, compute.type,
storage) storage)
dev = request.POST.get('dev', '') dev = request.POST.get('dev', '')
path = request.POST.get('path', '') path = request.POST.get('path', '')
name = request.POST.get('name', '') name = request.POST.get('name', '')
conn.detach_disk(dev) conn.detach_disk(dev)
connDelete.del_volume(name) conn_delete.del_volume(name)
msg = _('Delete disk: ' + dev) msg = _('Delete disk: ' + dev)
addlogmsg(request.user.username, instance.name, msg) addlogmsg(request.user.username, instance.name, msg)
@ -625,8 +688,8 @@ def instance(request, compute_id, vname):
if bootorder: if bootorder:
order_list = {} order_list = {}
for idx, val in enumerate(bootorder.split(',')): for idx, val in enumerate(bootorder.split(',')):
type, dev = val.split(':', 1) dev_type, dev = val.split(':', 1)
order_list[idx] = {"type": type, "dev": dev} order_list[idx] = {"type": dev_type, "dev": dev}
conn.set_bootorder(order_list) conn.set_bootorder(order_list)
msg = _("Set boot order") msg = _("Set boot order")
@ -796,7 +859,7 @@ def instance(request, compute_id, vname):
elif not re.match(r'^[a-zA-Z0-9-]+$', clone_data['name']): elif not re.match(r'^[a-zA-Z0-9-]+$', clone_data['name']):
msg = _("Instance name '%s' contains invalid characters!" % clone_data['name']) msg = _("Instance name '%s' contains invalid characters!" % clone_data['name'])
error_messages.append(msg) error_messages.append(msg)
elif not re.match(r'^([0-9A-F]{2})(\:?[0-9A-F]{2}){5}$', clone_data['clone-net-mac-0'], elif not re.match(r'^([0-9A-F]{2})(:?[0-9A-F]{2}){5}$', clone_data['clone-net-mac-0'],
re.IGNORECASE): re.IGNORECASE):
msg = _("Instance mac '%s' invalid format!" % clone_data['clone-net-mac-0']) msg = _("Instance mac '%s' invalid format!" % clone_data['clone-net-mac-0'])
error_messages.append(msg) error_messages.append(msg)
@ -847,6 +910,8 @@ def instance(request, compute_id, vname):
def inst_status(request, compute_id, vname): def inst_status(request, compute_id, vname):
""" """
:param request: :param request:
:param compute_id:
:param vname:
:return: :return:
""" """
@ -904,17 +969,17 @@ def get_host_instances(request, comp):
inst_on_db.save() inst_on_db.save()
all_host_vms[comp["id"], all_host_vms[comp["id"],
comp["name"], comp["name"],
comp["status"], comp["status"],
comp["cpu"], comp["cpu"],
comp["mem_size"], comp["mem_size"],
comp["mem_perc"]][inst_name]['is_template'] = inst_on_db.is_template comp["mem_perc"]][inst_name]['is_template'] = inst_on_db.is_template
all_host_vms[comp["id"], all_host_vms[comp["id"],
comp["name"], comp["name"],
comp["status"], comp["status"],
comp["cpu"], comp["cpu"],
comp["mem_size"], comp["mem_size"],
comp["mem_perc"]][inst_name]['userinstances'] = get_userinstances_info(inst_on_db) comp["mem_perc"]][inst_name]['userinstances'] = get_userinstances_info(inst_on_db)
except Instance.DoesNotExist: except Instance.DoesNotExist:
inst_on_db = Instance(compute_id=comp["id"], name=inst_name, uuid=info['uuid']) inst_on_db = Instance(compute_id=comp["id"], name=inst_name, uuid=info['uuid'])
inst_on_db.save() inst_on_db.save()
@ -988,6 +1053,12 @@ def instances_actions(request):
conn.shutdown(name) conn.shutdown(name)
return HttpResponseRedirect(request.get_full_path()) return HttpResponseRedirect(request.get_full_path())
if 'powerforce' in request.POST:
conn.force_shutdown(name)
msg = _("Force Off")
addlogmsg(request.user.username, instance.name, msg)
return HttpResponseRedirect(request.get_full_path())
if 'powercycle' in request.POST: if 'powercycle' in request.POST:
msg = _("Power Cycle") msg = _("Power Cycle")
conn.force_shutdown(name) conn.force_shutdown(name)
@ -1027,7 +1098,7 @@ def instances_actions(request):
addlogmsg(request.user.username, instance.name, msg) addlogmsg(request.user.username, instance.name, msg)
conn.resume(name) conn.resume(name)
return HttpResponseRedirect(request.get_full_path()) return HttpResponseRedirect(request.get_full_path())
return HttpResponseRedirect(request.get_full_path())
@login_required @login_required
def inst_graph(request, compute_id, vname): def inst_graph(request, compute_id, vname):
@ -1174,7 +1245,7 @@ def _get_clone_disks(disks, vname=''):
def sshkeys(request, vname): def sshkeys(request, vname):
""" """
:param request: :param request:
:param vm: :param vname:
:return: :return:
""" """
@ -1213,7 +1284,7 @@ def delete_instance(instance, delete_disk=False):
print("Forcing shutdown") print("Forcing shutdown")
conn.force_shutdown() conn.force_shutdown()
if delete_disk: if delete_disk:
snapshots = sorted(conn.get_snapshot(), reverse=True, key=lambda k:k['date']) snapshots = sorted(conn.get_snapshot(), reverse=True, key=lambda k: k['date'])
for snap in snapshots: for snap in snapshots:
print("Deleting snapshot {}".format(snap['name'])) print("Deleting snapshot {}".format(snap['name']))
conn.snapshot_delete(snap['name']) conn.snapshot_delete(snap['name'])

View file

@ -2,72 +2,72 @@
{% load i18n %} {% load i18n %}
{% block title %}{% trans "Interface" %} - {{ iface }}{% endblock %} {% block title %}{% trans "Interface" %} - {{ iface }}{% endblock %}
{% block content %} {% block content %}
<!-- Page Heading --> <!-- Page Heading -->
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<h1 class="page-header">{% trans "Interface:" %} {{ iface }}</h1> <h1 class="page-header">{% trans "Interface:" %} {{ iface }}</h1>
<ol class="breadcrumb"> <ol class="breadcrumb">
<li class="active"> <li class="active">
<i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a> <i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-server"></i> <a href="{% url 'instances' compute.id %}">{% trans "Instances" %}</a> <i class="fa fa-server"></i> <a href="{% url 'instances' compute.id %}">{% trans "Instances" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a> <i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-sitemap"></i> <a href="{% url 'networks' compute.id %}">{% trans "Networks" %}</a> <i class="fa fa-sitemap"></i> <a href="{% url 'networks' compute.id %}">{% trans "Networks" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-wifi"></i> <a href="{% url 'interfaces' compute.id %}">{% trans "Interfaces" %}</a> <i class="fa fa-wifi"></i> <a href="{% url 'interfaces' compute.id %}">{% trans "Interfaces" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-filter"></i> <a href="{% url 'nwfilters' compute.id %}">{% trans "NWFilters" %}</a> <i class="fa fa-filter"></i> <a href="{% url 'nwfilters' compute.id %}">{% trans "NWFilters" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-key"></i> <a href="{% url 'secrets' compute.id %}">{% trans "Secrets" %}</a> <i class="fa fa-key"></i> <a href="{% url 'secrets' compute.id %}">{% trans "Secrets" %}</a>
</li> </li>
</ol> </ol>
</div> </div>
</div> </div>
<!-- /.row --> <!-- /.row -->
{% include 'errors_block.html' %} {% include 'errors_block.html' %}
<div class="row"> <div class="row">
<div class="col-xs-6 col-sm-4"> <div class="col-xs-6 col-sm-4">
<p>{% trans "Interface:" %}</p> <p>{% trans "Interface" %}:</p>
<p>{% trans "IPv4:" %} ({% ifequal ipv4 None %}None{% else %}{{ ipv4_type }}{% endifequal %})</p> <p>{% trans "IPv4" %}: ({% ifequal ipv4 None %}{% trans 'None' %}{% else %}{{ ipv4_type }}{% endifequal %})</p>
<p>{% trans "IPv6:" %} ({% ifequal ipv6 None %}None{% else %}{{ ipv6_type }}{% endifequal %})</p> <p>{% trans "IPv6" %}: ({% ifequal ipv6 None %}{% trans 'None' %}{% else %}{{ ipv6_type }}{% endifequal %})</p>
<p>{% trans "MAC Adress:" %}</p> <p>{% trans "MAC Adress" %}:</p>
<p>{% trans "Interface Type:" %}</p> <p>{% trans "Interface Type" %}:</p>
{% ifequal itype 'bridge' %} {% ifequal itype 'bridge' %}
<p>{% trans "Bridge device" %}</p> <p>{% trans "Bridge device" %}</p>
{% endifequal %}
<p>{% trans "Boot Mode" %}:</p>
<p>{% trans "State" %}:</p>
</div>
<div class="col-xs-6 col-sm-6">
<p><strong>{{ iface }}</strong></p>
<p>{{ ipv4 }}</p>
<p>{{ ipv6 }}</p>
<p>{{ mac }}</p>
<p>{{ itype }}</p>
{% ifequal itype 'bridge' %}
<p>{{ bridge }}</p>
{% endifequal %}
<p>{{ start_mode }}</p>
<p>
<form action="" method="post" role="form">{% csrf_token %}
{% ifequal state 0 %}
<input type="submit" class="btn btn-xs btn-default" name="start" value="{% trans "Start" %}">
<input type="submit" class="btn btn-xs btn-default" name="delete" value="{% trans "Delete" %}" onclick="return confirm('{% trans "Are you sure?" %}')">
{% else %}
<input type="submit" class="btn btn-xs btn-default" name="stop" value="{% trans "Stop" %}" onclick="return confirm('{% trans "Are you sure?" %}')">
{% endifequal %} {% endifequal %}
<p>{% trans "Boot Mode:" %}</p> </form>
<p>{% trans "State:" %}</p> </p>
</div> </div>
<div class="col-xs-6 col-sm-6"> </div>
<p><strong>{{ iface }}</strong></p>
<p>{{ ipv4 }}</p>
<p>{{ ipv6 }}</p>
<p>{{ mac }}</p>
<p>{{ itype }}</p>
{% ifequal itype 'bridge' %}
<p>{{ bridge }}</p>
{% endifequal %}
<p>{{ start_mode }}</p>
<p>
<form action="" method="post" role="form">{% csrf_token %}
{% ifequal state 0 %}
<input type="submit" class="btn btn-xs btn-default" name="start" value="{% trans "Start" %}">
<input type="submit" class="btn btn-xs btn-default" name="delete" value="{% trans "Delete" %}" onclick="return confirm('{% trans "Are you sure?" %}')">
{% else %}
<input type="submit" class="btn btn-xs btn-default" name="stop" value="{% trans "Stop" %}" onclick="return confirm('{% trans "Are you sure?" %}')">
{% endifequal %}
</form>
</p>
</div>
</div>
{% endblock %} {% endblock %}

View file

@ -3,73 +3,73 @@
{% load staticfiles %} {% load staticfiles %}
{% block title %}{% trans "Interfaces" %} - {{ compute.name }}{% endblock %} {% block title %}{% trans "Interfaces" %} - {{ compute.name }}{% endblock %}
{% block content %} {% block content %}
<!-- Page Heading --> <!-- Page Heading -->
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
{% include 'create_iface_block.html' %} {% include 'create_iface_block.html' %}
<h1 class="page-header">{{ compute.name }}</h1> <h1 class="page-header">{{ compute.name }}</h1>
<ol class="breadcrumb"> <ol class="breadcrumb">
<li class="active"> <li class="active">
<i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a> <i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-server"></i> <a href="{% url 'instances' compute.id %}">{% trans "Instances" %}</a> <i class="fa fa-server"></i> <a href="{% url 'instances' compute.id %}">{% trans "Instances" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a> <i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-sitemap"></i> <a href="{% url 'networks' compute.id %}">{% trans "Networks" %}</a> <i class="fa fa-sitemap"></i> <a href="{% url 'networks' compute.id %}">{% trans "Networks" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-wifi"></i> {% trans "Interfaces" %} <i class="fa fa-wifi"></i> {% trans "Interfaces" %}
</li> </li>
<li> <li>
<i class="fa fa-filter"></i> <a href="{% url 'nwfilters' compute.id %}">{% trans "NWFilters" %}</a> <i class="fa fa-filter"></i> <a href="{% url 'nwfilters' compute.id %}">{% trans "NWFilters" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-key"></i> <a href="{% url 'secrets' compute.id %}">{% trans "Secrets" %}</a> <i class="fa fa-key"></i> <a href="{% url 'secrets' compute.id %}">{% trans "Secrets" %}</a>
</li> </li>
</ol> </ol>
</div>
</div>
<!-- /.row -->
{% include 'errors_block.html' %}
<div class="row">
{% if not ifaces_all %}
<div class="col-lg-12">
<div class="alert alert-warning alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning:" %}</strong> {% trans "Hypervisor doesn't have any Interfaces" %}
</div> </div>
</div> </div>
<!-- /.row --> {% else %}
{% for iface in ifaces_all %}
{% include 'errors_block.html' %} <div class="col-xs-12 col-sm-4">
<div class="panel {% ifequal iface.state 1 %}panel-success{% else %}panel-danger{% endifequal %} panel-data">
<div class="row"> <div class="panel-heading">
{% if not ifaces_all %} <h3 class="panel-title"><a href="{% url 'interface' compute.id iface.name %}">{{ iface.name }}</a>
<div class="col-lg-12"> </h3>
<div class="alert alert-warning alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning:" %}</strong> {% trans "Hypervisor doesn't have any Interfaces" %}
</div> </div>
</div> <div class="panel-body">
{% else %} <div class="row">
{% for iface in ifaces_all %} <div class="col-xs-4 col-sm-4">
<div class="col-xs-12 col-sm-4"> <p><strong>{% trans "Type:" %}</strong></p>
<div class="panel {% ifequal iface.state 1 %}panel-success{% else %}panel-danger{% endifequal %} panel-data"> <p><strong>{% trans "MAC:" %}</strong></p>
<div class="panel-heading">
<h3 class="panel-title"><a href="{% url 'interface' compute.id iface.name %}">{{ iface.name }}</a>
</h3>
</div> </div>
<div class="panel-body"> <div class="col-xs-6 col-sm-7">
<div class="row"> <p>{{ iface.type }}</p>
<div class="col-xs-4 col-sm-4"> <p>{{ iface.mac }}</p>
<p><strong>{% trans "Type:" %}</strong></p>
<p><strong>{% trans "MAC:" %}</strong></p>
</div>
<div class="col-xs-6 col-sm-7">
<p>{{ iface.type }}</p>
<p>{{ iface.mac }}</p>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
{% endfor %} </div>
{% endif %} </div>
</div> {% endfor %}
{% endif %}
</div>
{% endblock %} {% endblock %}
{% block script %} {% block script %}
<script> <script>

View file

@ -12,6 +12,7 @@ from libvirt import libvirtError
def interfaces(request, compute_id): def interfaces(request, compute_id):
""" """
:param request: :param request:
:param compute_id:
:return: :return:
""" """
@ -60,6 +61,7 @@ def interfaces(request, compute_id):
def interface(request, compute_id, iface): def interface(request, compute_id, iface):
""" """
:param request: :param request:
:param iface:
:return: :return:
""" """

View file

@ -5,7 +5,7 @@
&nbsp; &nbsp;
{% endif %} {% endif %}
{% if has_next_page %} {% if has_next_page %}
<a href="{% url 'showlogspage' page|add:"1" %}">&rarr;</a> <a href="{% url 'showlogspage' page|add:"1" %}">&rarr;</a>
{% else %} {% else %}
&nbsp; &nbsp;
{% endif %} {% endif %}

View file

@ -2,53 +2,53 @@
{% load i18n %} {% load i18n %}
{% block title %}{% trans "Logs" %}{% endblock %} {% block title %}{% trans "Logs" %}{% endblock %}
{% block content %} {% block content %}
<!-- Page Heading --> <!-- Page Heading -->
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<h1 class="page-header">{% trans "Logs" %}</h1> <h1 class="page-header">{% trans "Logs" %}</h1>
</div> </div>
</div> </div>
<!-- /.row --> <!-- /.row -->
{% include 'errors_block.html' %} {% include 'errors_block.html' %}
<div class="row"> <div class="row">
<div class="col-lg-12">
{% if not logs %}
<div class="col-lg-12"> <div class="col-lg-12">
{% if not logs %} <div class="alert alert-warning alert-dismissable">
<div class="col-lg-12"> <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<div class="alert alert-warning alert-dismissable"> <i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning" %}:</strong> {% trans "You don't have any Logs" %}
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button> </div>
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning:" %}</strong> {% trans "You don't have any Logs" %}
</div>
</div>
{% else %}
{% include "paging.html" %}
<div class="table-responsive">
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>#</th>
<th>{% trans "Date" %}</th>
<th>{% trans "User" %}</th>
<th>{% trans "Instance" %}</th>
<th>{% trans "Message" %}</th>
</tr>
</thead>
<tbody>
{% for log in logs %}
<tr>
<td>{{ log.id }}</td>
<td style="width:130px;">{{ log.date|date:"M d H:i:s" }}</td>
<td>{{ log.user }}</a></td>
<td>{{ log.instance }}</a></td>
<td>{{ log.message }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% include "paging.html" %}
{% endif %}
</div> </div>
</div> {% else %}
{% include "paging.html" %}
<div class="table-responsive">
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>#</th>
<th>{% trans "Date" %}</th>
<th>{% trans "User" %}</th>
<th>{% trans "Instance" %}</th>
<th>{% trans "Message" %}</th>
</tr>
</thead>
<tbody>
{% for log in logs %}
<tr>
<td>{{ log.id }}</td>
<td style="width:130px;">{{ log.date|date:"M d H:i:s" }}</td>
<td>{{ log.user }}</td>
<td>{{ log.instance }}</td>
<td>{{ log.message }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% include "paging.html" %}
{% endif %}
</div>
</div>
{% endblock %} {% endblock %}

View file

@ -10,7 +10,9 @@ import json
def addlogmsg(user, instance, message): def addlogmsg(user, instance, message):
""" """
:param request: :param user:
:param instance:
:param message:
:return: :return:
""" """
add_log_msg = Logs(user=user, instance=instance, message=message) add_log_msg = Logs(user=user, instance=instance, message=message)
@ -21,6 +23,7 @@ def addlogmsg(user, instance, message):
def showlogs(request, page=1): def showlogs(request, page=1):
""" """
:param request: :param request:
:param page:
:return: :return:
""" """
@ -36,11 +39,12 @@ def showlogs(request, page=1):
return render(request, 'showlogs.html', locals()) return render(request, 'showlogs.html', locals())
@login_required @login_required
def vm_logs(request, vname): def vm_logs(request, vname):
""" """
:param request: :param request:
:param vm: :param vname:
:return: :return:
""" """
@ -51,7 +55,7 @@ def vm_logs(request, vname):
logs_ = Logs.objects.filter(instance=vm.name, date__gte=vm.created).order_by('-date') logs_ = Logs.objects.filter(instance=vm.name, date__gte=vm.created).order_by('-date')
logs = [] logs = []
for l in logs_: for l in logs_:
log = {} log = dict()
log['user'] = l.user log['user'] = l.user
log['instance'] = l.instance log['instance'] = l.instance
log['message'] = l.message log['message'] = l.message

View file

@ -39,7 +39,6 @@
<input type="text" class="form-control" name="mac" required pattern="[0-9\/\:]+"> <input type="text" class="form-control" name="mac" required pattern="[0-9\/\:]+">
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">

View file

@ -3,219 +3,219 @@
{% load staticfiles %} {% load staticfiles %}
{% block title %}{% trans "Network" %} - {{ pool }}{% endblock %} {% block title %}{% trans "Network" %} - {{ pool }}{% endblock %}
{% block content %} {% block content %}
<!-- Page Heading --> <!-- Page Heading -->
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<h1 class="page-header">{% trans "Network:" %} {{ pool }}</h1> <h1 class="page-header">{% trans "Network:" %} {{ pool }}</h1>
<ol class="breadcrumb"> <ol class="breadcrumb">
<li class="active"> <li class="active">
<i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a> <i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-server"></i> <a href="{% url 'instances' compute.id %}">{% trans "Instances" %}</a> <i class="fa fa-server"></i> <a href="{% url 'instances' compute.id %}">{% trans "Instances" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a> <i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-sitemap"></i> <a href="{% url 'networks' compute.id %}">{% trans "Networks" %}</a> <i class="fa fa-sitemap"></i> <a href="{% url 'networks' compute.id %}">{% trans "Networks" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-wifi"></i> <a href="{% url 'interfaces' compute.id %}">{% trans "Interfaces" %}</a> <i class="fa fa-wifi"></i> <a href="{% url 'interfaces' compute.id %}">{% trans "Interfaces" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-filter"></i> <a href="{% url 'nwfilters' compute.id %}">{% trans "NWFilters" %}</a> <i class="fa fa-filter"></i> <a href="{% url 'nwfilters' compute.id %}">{% trans "NWFilters" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-key"></i> <a href="{% url 'secrets' compute.id %}">{% trans "Secrets" %}</a> <i class="fa fa-key"></i> <a href="{% url 'secrets' compute.id %}">{% trans "Secrets" %}</a>
</li> </li>
</ol> </ol>
</div> </div>
</div> </div>
<!-- /.row --> <!-- /.row -->
{% include 'errors_block.html' %} {% include 'errors_block.html' %}
{% include 'messages_block.html' %} {% include 'messages_block.html' %}
<div class="row"> <div class="row">
<div class="col-xs-6 col-sm-4"> <div class="col-xs-6 col-sm-4">
<p>{% trans "Network name" %}:</p> <p>{% trans "Network name" %}:</p>
<p>{% trans "Device" %}:</p> <p>{% trans "Device" %}:</p>
<p>{% trans "State" %}:</p> <p>{% trans "State" %}:</p>
<p>{% trans "Autostart" %}:</p> <p>{% trans "Autostart" %}:</p>
</div> </div>
<div class="col-xs-6 col-sm-6"> <div class="col-xs-6 col-sm-6">
<p>{{ pool }}</p> <p>{{ pool }}</p>
<p>{{ device }}</p> <p>{{ device }}</p>
<p> <p>
<form action="" method="post" role="form">{% csrf_token %} <form action="" method="post" role="form">{% csrf_token %}
{% ifequal state 0 %} {% ifequal state 0 %}
<input type="submit" class="btn btn-xs btn-default" name="start" value="{% trans "Start" %}"> <input type="submit" class="btn btn-xs btn-default" name="start" value="{% trans "Start" %}">
<input type="submit" class="btn btn-xs btn-default" name="delete" value="{% trans "Delete" %}" onclick="return confirm('{% trans "Are you sure?" %}')"> <input type="submit" class="btn btn-xs btn-default" name="delete" value="{% trans "Delete" %}" onclick="return confirm('{% trans "Are you sure?" %}')">
{% else %} {% else %}
<input type="submit" class="btn btn-xs btn-default" name="stop" value="{% trans "Stop" %}" onclick="return confirm('{% trans "Are you sure?" %}')"> <input type="submit" class="btn btn-xs btn-default" name="stop" value="{% trans "Stop" %}" onclick="return confirm('{% trans "Are you sure?" %}')">
{% endifequal %} {% endifequal %}
</form> </form>
</p> </p>
<p> <p>
<form action="" method="post" role="form">{% csrf_token %} <form action="" method="post" role="form">{% csrf_token %}
{% ifequal autostart 0 %} {% ifequal autostart 0 %}
<input type="submit" class="btn btn-xs btn-default" name="set_autostart" value="{% trans "Enable" %}"> <input type="submit" class="btn btn-xs btn-default" name="set_autostart" value="{% trans "Enable" %}">
{% else %} {% else %}
<input type="submit" class="btn btn-xs btn-default" name="unset_autostart" onclick="return confirm('{% trans "Are you sure?" %}')" value="{% trans "Disable" %}"> <input type="submit" class="btn btn-xs btn-default" name="unset_autostart" onclick="return confirm('{% trans "Are you sure?" %}')" value="{% trans "Disable" %}">
{% endifequal %} {% endifequal %}
</form> </form>
</p> </p>
</div>
</div>
<div class="row">
<h3 class="page-header"></h3>
</div>
<div class="panel-group" id="accordion">
<div class="panel panel-default">
<div class="panel-heading">
<a data-toggle="collapse" data-parent="#accordion" href="#collapseOne">
{% trans 'XML' %}
</a>
</div>
<div id="collapseOne" class="panel-collapse collapse">
<div class="panel-body">
<form class="form-inline" method="post" role="form">{% csrf_token %}
<div class="col-xs-12" id="xmlheight">
<input type="hidden" name="edit_xml"/>
<textarea id="edit_editor">{{ xml }}</textarea>
</div>
<button type="submit" class="btn btn-primary pull-right" name="edit_network">
{% trans "Edit" %}
</button>
</form>
</div> </div>
</div> </div>
<div class="row"> </div>
<h3 class="page-header"></h3> </div>
</div> <div class="row">
<div class="panel-group" id="accordion"> <h3 class="page-header">{% trans "IPv4 Configuration" %}</h3>
<div class="panel panel-default"> </div>
<div class="panel-heading"> <div class="row">
<a data-toggle="collapse" data-parent="#accordion" href="#collapseOne"> <div class="col-xs-6 col-sm-4">
{% trans 'XML' %} <p>{% trans "IPv4 Forwarding:" %}</p>
</a> <p>{% trans "Network:" %}</p>
</div> <p>{% trans "DHCP:" %}</p>
<div id="collapseOne" class="panel-collapse collapse"> {% if ipv4_dhcp_range_start and ipv4_dhcp_range_end %}
<div class="panel-body"> <p>{% trans "Start:" %}</p>
<form class="form-inline" method="post" role="form">{% csrf_token %} <p>{% trans "End:" %}</p>
<div class="col-xs-12" id="xmlheight">
<input type="hidden" name="edit_xml"/>
<textarea id="edit_editor">{{ xml }}</textarea>
</div>
<button type="submit" class="btn btn-primary pull-right" name="edit_network">
{% trans "Edit" %}
</button>
</form>
</div>
</div>
</div>
</div>
<div class="row">
<h3 class="page-header">{% trans "IPv4 Configuration" %}</h3>
</div>
<div class="row">
<div class="col-xs-6 col-sm-4">
<p>{% trans "IPv4 Forwarding:" %}</p>
<p>{% trans "Network:" %}</p>
<p>{% trans "DHCP:" %}</p>
{% if ipv4_dhcp_range_start and ipv4_dhcp_range_end %}
<p>{% trans "Start:" %}</p>
<p>{% trans "End:" %}</p>
{% endif %}
</div>
<div class="col-xs-6 col-sm-4">
<p>
{% ifequal ipv4_forward.0 'nat' %}
{% trans "NAT" %}
{% endifequal %}
{% ifequal ipv4_forward.0 'route' %}
{% trans "ROUTE" %}
{% endifequal %}
{% ifequal ipv4_forward.0 'bridge' %}
{% trans "BRIDGE" %}
{% endifequal %}
{% if not ipv4_forward.0 %}
{% trans "ISOLATE" %}
{% endif %}
</p>
<p>{{ ipv4_network }}</p>
<p>
{% if ipv4_dhcp_range_start and ipv4_dhcp_range_end %}
<span class="text-success">{% trans "ON" %}</span>
{% else %}
<span class="text-danger">{% trans "OFF" %}</span>
{% endif %}
</p>
{% if ipv4_dhcp_range_start and ipv4_dhcp_range_end %}
<form method="post" role="form">{% csrf_token %}
{% if state %}
<p>{{ ipv4_dhcp_range_start }}</p>
<p>{{ ipv4_dhcp_range_end }}</p>
{% else %}
<p><input name="range_start" value="{{ ipv4_dhcp_range_start }}"/></p>
<p><input name="range_end" value="{{ ipv4_dhcp_range_end }}"/></p>
<div class="col-xs-10 col-sm-8">
<input type="submit" class="btn btn-primary btn-block" value="Apply"
name="modify_dhcp_range"
title="Edit DHCP Range" onclick="return confirm('{% trans "Are you sure?" %}')"/>
</div>
{% endif %}
</form>
{% endif %}
</div>
</div>
{% ifequal ipv4_forward.0 'nat' %}
{% if state %}
{% include 'modify_fixed_address.html' %}
{% endif %} {% endif %}
<div class="row"> </div>
<h3 class="page-header">{% trans "Fixed Address" %}</h3> <div class="col-xs-6 col-sm-4">
</div> <p>
{% endifequal %} {% ifequal ipv4_forward.0 'nat' %}
{% if fixed_address %} {% trans "NAT" %}
<div class="row"> {% endifequal %}
<div class="col-xs-12"> {% ifequal ipv4_forward.0 'route' %}
<div class="panel-group" id="accordion"> {% trans "ROUTE" %}
<div class="panel panel-default"> {% endifequal %}
<div class="panel-heading"> {% ifequal ipv4_forward.0 'bridge' %}
<a data-toggle="collapse" data-parent="#accordion" href="#collapseTwo"> {% trans "BRIDGE" %}
{% trans 'Show' %} {% endifequal %}
</a> {% if not ipv4_forward.0 %}
</div> {% trans "ISOLATE" %}
<div id="collapseTwo" class="panel-collapse collapse"> {% endif %}
<div class="panel-body"> </p>
<p>{{ ipv4_network }}</p>
<p>
{% if ipv4_dhcp_range_start and ipv4_dhcp_range_end %}
<span class="text-success">{% trans "ON" %}</span>
{% else %}
<span class="text-danger">{% trans "OFF" %}</span>
{% endif %}
</p>
{% if ipv4_dhcp_range_start and ipv4_dhcp_range_end %}
<form method="post" role="form">{% csrf_token %}
{% if state %}
<p>{{ ipv4_dhcp_range_start }}</p>
<p>{{ ipv4_dhcp_range_end }}</p>
{% else %}
<p><input name="range_start" value="{{ ipv4_dhcp_range_start }}"/></p>
<p><input name="range_end" value="{{ ipv4_dhcp_range_end }}"/></p>
<div class="col-xs-10 col-sm-8">
<input type="submit" class="btn btn-primary btn-block" value="Apply"
name="modify_dhcp_range"
title="Edit DHCP Range" onclick="return confirm('{% trans "Are you sure?" %}')"/>
</div>
{% endif %}
</form>
{% endif %}
</div>
</div>
{% ifequal ipv4_forward.0 'nat' %}
{% if state %}
{% include 'modify_fixed_address.html' %}
{% endif %}
<div class="row">
<h3 class="page-header">{% trans "Fixed Address" %}</h3>
</div>
{% endifequal %}
{% if fixed_address %}
<div class="row">
<div class="col-xs-12">
<div class="panel-group" id="accordion">
<div class="panel panel-default">
<div class="panel-heading">
<a data-toggle="collapse" data-parent="#accordion" href="#collapseTwo">
{% trans 'Show' %}
</a>
</div>
<div id="collapseTwo" class="panel-collapse collapse">
<div class="panel-body">
<div class="input-append form-inline pull-right"> <div class="input-append form-inline pull-right">
<div class="form-group"> <div class="form-group">
<input type="text" class="form-control" id="filter_input"> <input type="text" class="form-control" id="filter_input">
</div>
<input type="button" class="btn btn-default" id="filter_button" value="Filter">
<button type="button" class="btn btn-default" id="filter_clear">{% trans 'Clear' %}</button>
</div>
<table class="table table-hover">
<thead>
<tr>
<th style="text-align: center">{% trans "MAC" %}</th>
<th style="text-align: center">{% trans "Address" %}</th>
<th style="text-align: center">{% trans "Name" %}</th>
<th style="text-align: center">{% trans "Action" %}</th>
</tr>
</thead>
<tbody style="text-align: center">
{% for fix in fixed_address %}
<tr>
<form method="post" role="form">{% csrf_token %}
<td><label class="form-control" disabled="true">{{ fix.mac }}</label></td>
<td><input class="form-control" value="{{ fix.ip }}" name="address" /></td>
<td><input class="form-control" value="{{ fix.name }}" name="name" /></td>
<td>
<input hidden name="mac" value="{{ fix.mac }}"/>
<button type="submit" class="btn btn-sm btn-primary"
name="modify_fixed_address"
title="Edit entry" onclick="return confirm('{% trans "Are you sure?" %}')">
<i class="glyphicon glyphicon-save"></i>
</button>
<button type="submit" class="btn btn-sm btn-danger"
name="delete_fixed_address"
title="Delete entry" onclick="return confirm('{% trans "Are you sure?" %}')">
<i class="glyphicon glyphicon-trash"></i>
</button>
</td>
</form>
</tr>
{% endfor %}
</tbody>
</table>
</div> </div>
<input type="button" class="btn btn-default" id="filter_button" value="Filter">
<button type="button" class="btn btn-default" id="filter_clear">{% trans 'Clear' %}</button>
</div> </div>
<table class="table table-hover">
<thead>
<tr>
<th style="text-align: center">{% trans "MAC" %}</th>
<th style="text-align: center">{% trans "Address" %}</th>
<th style="text-align: center">{% trans "Name" %}</th>
<th style="text-align: center">{% trans "Action" %}</th>
</tr>
</thead>
<tbody style="text-align: center">
{% for fix in fixed_address %}
<tr>
<form method="post" role="form">{% csrf_token %}
<td><label class="form-control" disabled="true">{{ fix.mac }}</label></td>
<td><input class="form-control" value="{{ fix.ip }}" name="address" /></td>
<td><input class="form-control" value="{{ fix.name }}" name="name" /></td>
<td>
<input hidden name="mac" value="{{ fix.mac }}"/>
<button type="submit" class="btn btn-sm btn-primary"
name="modify_fixed_address"
title="Edit entry" onclick="return confirm('{% trans "Are you sure?" %}')">
<i class="glyphicon glyphicon-save"></i>
</button>
<button type="submit" class="btn btn-sm btn-danger"
name="delete_fixed_address"
title="Delete entry" onclick="return confirm('{% trans "Are you sure?" %}')">
<i class="glyphicon glyphicon-trash"></i>
</button>
</td>
</form>
</tr>
{% endfor %}
</tbody>
</table>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{% endif %} </div>
</div>
{% endif %}
{% endblock %} {% endblock %}
{% block script %} {% block script %}
<script> <script>

View file

@ -2,72 +2,72 @@
{% load i18n %} {% load i18n %}
{% block title %}{% trans "Networks" %} - {{ compute.name }}{% endblock %} {% block title %}{% trans "Networks" %} - {{ compute.name }}{% endblock %}
{% block content %} {% block content %}
<!-- Page Heading --> <!-- Page Heading -->
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
{% include 'create_net_block.html' %} {% include 'create_net_block.html' %}
<h1 class="page-header">{{ compute.name }}</h1> <h1 class="page-header">{{ compute.name }}</h1>
<ol class="breadcrumb"> <ol class="breadcrumb">
<li class="active"> <li class="active">
<i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a> <i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-server"></i> <a href="{% url 'instances' compute.id %}">{% trans "Instances" %}</a> <i class="fa fa-server"></i> <a href="{% url 'instances' compute.id %}">{% trans "Instances" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a> <i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-sitemap"></i> {% trans "Networks" %} <i class="fa fa-sitemap"></i> {% trans "Networks" %}
</li> </li>
<li> <li>
<i class="fa fa-wifi"></i> <a href="{% url 'interfaces' compute.id %}">{% trans "Interfaces" %}</a> <i class="fa fa-wifi"></i> <a href="{% url 'interfaces' compute.id %}">{% trans "Interfaces" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-filter"></i> <a href="{% url 'nwfilters' compute.id %}">{% trans "NWFilters" %}</a> <i class="fa fa-filter"></i> <a href="{% url 'nwfilters' compute.id %}">{% trans "NWFilters" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-key"></i> <a href="{% url 'secrets' compute.id %}">{% trans "Secrets" %}</a> <i class="fa fa-key"></i> <a href="{% url 'secrets' compute.id %}">{% trans "Secrets" %}</a>
</li> </li>
</ol> </ol>
</div>
</div>
<!-- /.row -->
{% include 'errors_block.html' %}
<div class="row">
{% if not networks %}
<div class="col-lg-12">
<div class="alert alert-warning alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<i class="fa fa-exclamation-triangle"></i><strong>{% trans "Warning:" %}</strong> {% trans "Hypervisor doesn't have any Networks" %}
</div> </div>
</div> </div>
<!-- /.row --> {% else %}
{% for pool in networks %}
{% include 'errors_block.html' %} <div class="col-xs-12 col-sm-4">
<div class="panel {% if pool.status %}panel-success{% else %}panel-danger{% endif %} panel-data">
<div class="row"> <div class="panel-heading">
{% if not networks %} <h3 class="panel-title"><a href="{% url 'network' compute.id pool.name %}">{{ pool.name }}</a></h3>
<div class="col-lg-12">
<div class="alert alert-warning alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning:" %}</strong> {% trans "Hypervisor doesn't have any Networks" %}
</div> </div>
</div> <div class="panel-body">
{% else %} <div class="row">
{% for pool in networks %} <div class="col-xs-4 col-sm-4">
<div class="col-xs-12 col-sm-4"> <p><strong>{% trans "Device:" %}</strong></p>
<div class="panel {% if pool.status %}panel-success{% else %}panel-danger{% endif %} panel-data"> <p><strong>{% trans "Forward:" %}</strong></p>
<div class="panel-heading">
<h3 class="panel-title"><a href="{% url 'network' compute.id pool.name %}">{{ pool.name }}</a></h3>
</div> </div>
<div class="panel-body"> <div class="col-xs-6 col-sm-7">
<div class="row"> <p>{{ pool.device }}</p>
<div class="col-xs-4 col-sm-4"> <p>{{ pool.forward|upper }}</p>
<p><strong>{% trans "Device:" %}</strong></p>
<p><strong>{% trans "Forward:" %}</strong></p>
</div>
<div class="col-xs-6 col-sm-7">
<p>{{ pool.device }}</p>
<p>{{ pool.forward|upper }}</p>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
{% endfor %} </div>
{% endif %} </div>
</div> {% endfor %}
{% endif %}
</div>
{% endblock %} {% endblock %}
{% block script %} {% block script %}
<script> <script>

View file

@ -15,6 +15,7 @@ from django.contrib import messages
def networks(request, compute_id): def networks(request, compute_id):
""" """
:param request: :param request:
:param compute_id:
:return: :return:
""" """
@ -64,6 +65,8 @@ def networks(request, compute_id):
def network(request, compute_id, pool): def network(request, compute_id, pool):
""" """
:param request: :param request:
:param compute_id:
:param pool:
:return: :return:
""" """
@ -91,6 +94,7 @@ def network(request, compute_id, pool):
xml = conn._XMLDesc(0) xml = conn._XMLDesc(0)
except libvirtError as lib_err: except libvirtError as lib_err:
error_messages.append(lib_err) error_messages.append(lib_err)
return HttpResponseRedirect(reverse('networks', args=compute_id))
if request.method == 'POST': if request.method == 'POST':
if 'start' in request.POST: if 'start' in request.POST:
@ -154,9 +158,9 @@ def network(request, compute_id, pool):
if edit_xml: if edit_xml:
try: try:
new_conn = wvmNetworks(compute.hostname, new_conn = wvmNetworks(compute.hostname,
compute.login, compute.login,
compute.password, compute.password,
compute.type) compute.type)
conn.define_network(edit_xml) conn.define_network(edit_xml)
if conn.is_active(): if conn.is_active():
messages.success(request, _("Network XML is changed. Stop and start network to activate new config.")) messages.success(request, _("Network XML is changed. Stop and start network to activate new config."))

View file

@ -1,8 +1,8 @@
{% load i18n %} {% load i18n %}
{% if request.user.is_superuser %} {% if request.user.is_superuser %}
<a href="#AddNWFilterRule" type="button" class="btn btn-success pull-right" data-toggle="modal"> <a href="#AddNWFilterRule" type="button" class="btn btn-success pull-right" data-toggle="modal">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
</a> </a>
<!-- Modal Secret --> <!-- Modal Secret -->
<div class="modal fade" id="AddNWFilterRule" tabindex="-1" role="dialog" aria-labelledby="AddNWFilterRule" aria-hidden="true"> <div class="modal fade" id="AddNWFilterRule" tabindex="-1" role="dialog" aria-labelledby="AddNWFilterRule" aria-hidden="true">

View file

@ -3,158 +3,158 @@
{% load staticfiles %} {% load staticfiles %}
{% block title %}{% trans "NWFilters" %} - {{ compute.name }}{% endblock %} {% block title %}{% trans "NWFilters" %} - {{ compute.name }}{% endblock %}
{% block content %} {% block content %}
<!-- Page Heading --> <!-- Page Heading -->
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
{% include 'create_nwfilter_block.html' %} {% include 'create_nwfilter_block.html' %}
<h1 class="page-header">{{ compute.name }}</h1> <h1 class="page-header">{{ compute.name }}</h1>
<ol class="breadcrumb"> <ol class="breadcrumb">
<li class="active"> <li class="active">
<i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a> <i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-server"></i> <a href="{% url 'instances' compute.id %}">{% trans "Instances" %}</a> <i class="fa fa-server"></i> <a href="{% url 'instances' compute.id %}">{% trans "Instances" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a> <i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-sitemap"></i> <a href="{% url 'networks' compute.id %}">{% trans "Networks" %}</a> <i class="fa fa-sitemap"></i> <a href="{% url 'networks' compute.id %}">{% trans "Networks" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-wifi"></i> <a href="{% url 'interfaces' compute.id %}">{% trans "Interfaces" %}</a> <i class="fa fa-wifi"></i> <a href="{% url 'interfaces' compute.id %}">{% trans "Interfaces" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-filter"></i> {% trans "NWFilters" %} <i class="fa fa-filter"></i> {% trans "NWFilters" %}
</li> </li>
<li> <li>
<i class="fa fa-key"></i> <a href="{% url 'secrets' compute.id %}">{% trans "Secrets" %}</a> <i class="fa fa-key"></i> <a href="{% url 'secrets' compute.id %}">{% trans "Secrets" %}</a>
</li> </li>
</ol> </ol>
</div> </div>
</div>
<!-- /.row -->
{% include 'errors_block.html' %}
{% include 'messages_block.html' %}
<div class="row">
<div class="col-lg-12">
<div class="pull-right">
<input id="filter" class="form-control" type="text" placeholder="Search">
</div> </div>
<!-- /.row --> <div class="row">
<h3 class="page-header">{% trans "NWFilters" %}</h3>
{% include 'errors_block.html' %} </div>
{% include 'messages_block.html' %} {% if nwfilters %}
<div class="table-responsive">
<div class="row"> <table class="table table-striped sortable-theme-bootstrap" data-sortable>
<div class="col-lg-12"> <thead>
<div class="pull-right">
<input id="filter" class="form-control" type="text" placeholder="Search">
</div>
<div class="row">
<h3 class="page-header">{% trans "NWFilters" %}</h3>
</div>
{% if nwfilters %}
<div class="table-responsive">
<table class="table table-striped sortable-theme-bootstrap" data-sortable>
<thead>
<tr>
<th style="width: 45px;">#</th>
<th>{% trans "UUID" %}</th>
<th>{% trans "Name" %}</th>
<th data-sortable="false" colspan="3">{% trans "Action" %}</th>
</tr>
</thead>
<tbody class="searchable">
{% for nwfilter in nwfilters %}
<tr> <tr>
<td>{{ forloop.counter }}</td> <th style="width: 45px;">#</th>
<td><a href="{% url "nwfilter" compute.id nwfilter.name %} ">{{ nwfilter.uuid }}</a></td> <th>{% trans "UUID" %}</th>
<td>{{ nwfilter.name }}</td> <th>{% trans "Name" %}</th>
<td style="width:30px;"> <th data-sortable="false" colspan="3">{% trans "Action" %}</th>
<div class="modal fade" id="Show{{ forloop.counter }}" tabindex="-1" role="dialog" aria-labelledby="showNWFilter" aria-hidden="true"> </tr>
<div class="modal-dialog"> </thead>
<div class="modal-content"> <tbody class="searchable">
<div class="modal-header"> {% for nwfilter in nwfilters %}
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> <tr>
<h4 class="modal-title">{% trans "Details of NWFilter" %}: <span class="text-danger">{{ nwfilter.name }}</span></h4> <td>{{ forloop.counter }}</td>
</div> <td><a href="{% url "nwfilter" compute.id nwfilter.name %} ">{{ nwfilter.uuid }}</a></td>
<div class="modal-body"> <td>{{ nwfilter.name }}</td>
<pre> <td style="width:30px;">
<code> <div class="modal fade" id="Show{{ forloop.counter }}" tabindex="-1" role="dialog" aria-labelledby="showNWFilter" aria-hidden="true">
{{ nwfilter.xml }} <div class="modal-dialog">
</code> <div class="modal-content">
</pre> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">{% trans "Details of NWFilter" %}: <span class="text-danger">{{ nwfilter.name }}</span></h4>
</div> </div>
<div class="modal-footer"> <div class="modal-body">
<button type="button" class="btn btn-default" data-dismiss="modal">{% trans "Close" %}</button> <pre>
<code>
{{ nwfilter.xml }}
</code>
</pre>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{% trans "Close" %}</button>
</div>
</div> <!-- /.modal-content -->
</div> <!-- /.modal-dialog -->
</div> <!-- /.modal -->
<a data-toggle="modal" href="#Show{{ forloop.counter }}" class="btn btn-sm btn-default" title="{% trans "Show" %}"><i class="fa fa-eye"></i></a>
</td>
<td style="width:30px;">
<div class="modal fade" id="Clone{{ forloop.counter }}" tabindex="-1" role="dialog" aria-labelledby="addNwFilterLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">{% trans "Clone nwfilter" %} <span class="text-danger">{{ nwfilter.name }}</span></h4>
</div> </div>
</div> <!-- /.modal-content --> <form class="form-horizontal" method="post" role="form">{% csrf_token %}
</div> <!-- /.modal-dialog --> <div class="modal-body">
</div> <!-- /.modal --> <div class="form-group">
<a data-toggle="modal" href="#Show{{ forloop.counter }}" class="btn btn-sm btn-default" title="{% trans "Show" %}"><i class="fa fa-eye"></i></a> <label class="col-sm-3 control-label">{% trans "Name" %}</label>
</td> <div class="col-sm-6">
<td style="width:30px;"> <input type="text" class="form-control" name="cln_name" placeholder="{% trans "Name" %}" required pattern="[a-zA-Z0-9\.\-_]+">
<div class="modal fade" id="Clone{{ forloop.counter }}" tabindex="-1" role="dialog" aria-labelledby="addNwFilterLabel" aria-hidden="true"> <input type="hidden" name="nwfiltername" value="{{ nwfilter.name }}">
<div class="modal-dialog"> </div>
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">{% trans "Clone nwfilter" %} <span class="text-danger">{{ nwfilter.name }}</span></h4>
</div>
<form class="form-horizontal" method="post" role="form">{% csrf_token %}
<div class="modal-body">
<div class="form-group">
<label class="col-sm-3 control-label">{% trans "Name" %}</label>
<div class="col-sm-6">
<input type="text" class="form-control" name="cln_name" placeholder="{% trans "Name" %}" required pattern="[a-zA-Z0-9\.\-_]+">
<input type="hidden" name="nwfiltername" value="{{ nwfilter.name }}">
</div> </div>
</div> </div>
</div> <div class="modal-footer">
<div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">{% trans "Close" %}</button>
<button type="button" class="btn btn-default" data-dismiss="modal">{% trans "Close" %}</button> <button type="submit" class="btn btn-primary" name="cln_nwfilter">{% trans "Clone" %}</button>
<button type="submit" class="btn btn-primary" name="cln_nwfilter">{% trans "Clone" %}</button> </div>
</div> </form>
</form> </div> <!-- /.modal-content -->
</div> <!-- /.modal-content --> </div> <!-- /.modal-dialog -->
</div> <!-- /.modal-dialog --> </div> <!-- /.modal -->
</div> <!-- /.modal --> <a data-toggle="modal" href="#Clone{{ forloop.counter }}" class="btn btn-sm btn-default" title="{% trans "Clone" %}"><i class="fa fa-files-o"></i></a>
<a data-toggle="modal" href="#Clone{{ forloop.counter }}" class="btn btn-sm btn-default" title="{% trans "Clone" %}"><i class="fa fa-files-o"></i></a> </td>
</td> <td style="width:30px;">
<td style="width:30px;"> <form action="" method="post" style="height:10px" role="form">{% csrf_token %}
<form action="" method="post" style="height:10px" role="form">{% csrf_token %} <input type="hidden" name="nwfiltername" value="{{ nwfilter.name }}">
<input type="hidden" name="nwfiltername" value="{{ nwfilter.name }}"> <button type="submit" class="btn btn-sm btn-default" name="del_nwfilter" title="{% trans "Delete" %}" onclick="return confirm('{% trans "Are you sure?" %}')">
<button type="submit" class="btn btn-sm btn-default" name="del_nwfilter" title="{% trans "Delete" %}" onclick="return confirm('{% trans "Are you sure?" %}')"> <i class="fa fa-trash"></i>
<i class="fa fa-trash"></i> </button>
</button> </form>
</form> </td>
</td> </tr>
</tr> {% endfor %}
{% endfor %} </tbody>
</tbody> </table>
</table> </div>
</div> {% else %}
{% else %} <div class="col-lg-12">
<div class="col-lg-12"> <div class="alert alert-warning alert-dismissable">
<div class="alert alert-warning alert-dismissable"> <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button> <i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning:" %}</strong> {% trans "Hypervisor doesn't have any NWFilters" %}
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning:" %}</strong> {% trans "Hypervisor doesn't have any NWFilters" %} </div>
</div> </div>
{% endif %}
</div> </div>
{% endif %}
</div> </div>
</div>
{% endblock %} {% endblock %}
{% block script %} {% block script %}
<script src="{% static "js/sortable.min.js" %}"></script> <script src="{% static "js/sortable.min.js" %}"></script>
<script> <script>
$(document).ready(function () { $(document).ready(function () {
(function ($) { (function ($) {
$('#filter').keyup(function () { $('#filter').keyup(function () {
var rex = new RegExp($(this).val(), 'i'); var rex = new RegExp($(this).val(), 'i');
$('.searchable tr').hide(); $('.searchable tr').hide();
$('.searchable tr').filter(function () { $('.searchable tr').filter(function () {
return rex.test($(this).text()); return rex.test($(this).text());
}).show(); }).show();
}) })
}(jQuery)); }(jQuery));
}); });
</script> </script>
<script src="{% static "js/ace.js" %}"></script> <script src="{% static "js/ace.js" %}"></script>
<script> <script>

View file

@ -6,122 +6,122 @@
<link rel="stylesheet" href="{% static "css/sortable-theme-bootstrap.css" %}" /> <link rel="stylesheet" href="{% static "css/sortable-theme-bootstrap.css" %}" />
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<!-- Page Heading --> <!-- Page Heading -->
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
{% include 'create_secret_block.html' %} {% include 'create_secret_block.html' %}
<h1 class="page-header">{% trans "Secrets" %}</h1> <h1 class="page-header">{% trans "Secrets" %}</h1>
<ol class="breadcrumb"> <ol class="breadcrumb">
<li class="active"> <li class="active">
<i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a> <i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-server"></i> <a href="{% url 'instances' compute.id %}">{% trans "Instances" %}</a> <i class="fa fa-server"></i> <a href="{% url 'instances' compute.id %}">{% trans "Instances" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a> <i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-sitemap"></i> <a href="{% url 'networks' compute.id %}">{% trans "Networks" %}</a> <i class="fa fa-sitemap"></i> <a href="{% url 'networks' compute.id %}">{% trans "Networks" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-wifi"></i> <a href="{% url 'interfaces' compute.id %}">{% trans "Interfaces" %}</a> <i class="fa fa-wifi"></i> <a href="{% url 'interfaces' compute.id %}">{% trans "Interfaces" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-filter"></i> <a href="{% url 'nwfilters' compute.id %}">{% trans "NWFilters" %}</a> <i class="fa fa-filter"></i> <a href="{% url 'nwfilters' compute.id %}">{% trans "NWFilters" %}</a>
</li> </li>
<li> <li>
<i class="fa fa-key"></i> {% trans "Secrets" %} <i class="fa fa-key"></i> {% trans "Secrets" %}
</li> </li>
</ol> </ol>
</div>
</div>
<!-- /.row -->
{% include 'errors_block.html' %}
<div class="row">
{% if not secrets_all %}
<div class="col-lg-12">
<div class="alert alert-warning alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning:" %}</strong> {% trans "Hypervisor doesn't have any Secrets" %}
</div> </div>
</div> </div>
<!-- /.row --> {% else %}
<div class="col-lg-12">
<div class="table-responsive">
<table class="table table-hover sortable-theme-bootstrap" data-sortable>
<thead>
<tr class="active">
<th>{% trans "UUID" %}</th>
<th>{% trans "Type" %}</th>
<th>{% trans "Usage" %}</th>
<th data-sortable="false" style="width:90px;">{% trans "Action" %}</th>
</tr>
</thead>
<tbody>
{% for secret in secrets_all %}
<tr>
<td>{{ secret.uuid }}</td>
<td>{% ifequal secret.usageType 0 %}
{% trans "volume" %}
{% endifequal %}
{% ifequal secret.usageType 1 %}
{% trans "iscsi" %}
{% endifequal %}
{% ifequal secret.usageType 2 %}
{% trans "ceph" %}
{% endifequal %}
</td>
<td>{{ secret.usage }}</td>
<td>
<form action="" method="post" role="form">{% csrf_token %}
<input type="hidden" name="uuid" value="{{ secret.uuid }}"/>
<a data-toggle="modal" href="#editSecret{{ secret.uuid }}" class="btn btn-sm btn-default" title="{% trans "Edit" %}">
<span class="glyphicon glyphicon-pencil"></span>
</a>
<button type="submit" class="btn btn-sm btn-default" name="delete" title="{% trans "Delete" %}" onclick="return confirm('{% trans "Are you sure?" %}')">
<span class="glyphicon glyphicon-trash"></span>
</button>
</form>
{% include 'errors_block.html' %} <!-- Modal -->
<div class="modal fade" id="editSecret{{ secret.uuid }}" tabindex="-1" role="dialog"
<div class="row"> aria-labelledby="editSecret" aria-hidden="true">
{% if not secrets_all %} <div class="modal-dialog">
<div class="col-lg-12"> <div class="modal-content">
<div class="alert alert-warning alert-dismissable"> <div class="modal-header">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning:" %}</strong> {% trans "Hypervisor doesn't have any Secrets" %} <h4 class="modal-title">{% trans "Set secret value" %}</h4>
</div> </div>
</div> <div class="tab-content">
{% else %} <form class="form-horizontal" method="post" role="form">{% csrf_token %}
<div class="col-lg-12"> <div class="form-group">
<div class="table-responsive"> <label class="col-sm-3 control-label">{% trans "Value" %}</label>
<table class="table table-hover sortable-theme-bootstrap" data-sortable> <div class="col-sm-6">
<thead> <input type="hidden" name="uuid" value="{{ secret.uuid }}">
<tr class="active"> <input type="text" name="value" class="form-control" value="{{ secret.value }}" maxlength="45" required pattern="[a-zA-Z0-9]$+">
<th>{% trans "UUID" %}</th> </div>
<th>{% trans "Type" %}</th>
<th>{% trans "Usage" %}</th>
<th data-sortable="false" style="width:90px;">{% trans "Action" %}</th>
</tr>
</thead>
<tbody>
{% for secret in secrets_all %}
<tr>
<td>{{ secret.uuid }}</td>
<td>{% ifequal secret.usageType 0 %}
{% trans "volume" %}
{% endifequal %}
{% ifequal secret.usageType 1 %}
{% trans "iscsi" %}
{% endifequal %}
{% ifequal secret.usageType 2 %}
{% trans "ceph" %}
{% endifequal %}
</td>
<td>{{ secret.usage }}</td>
<td>
<form action="" method="post" role="form">{% csrf_token %}
<input type="hidden" name="uuid" value="{{ secret.uuid }}"/>
<a data-toggle="modal" href="#editSecret{{ secret.uuid }}" class="btn btn-sm btn-default" title="{% trans "Edit" %}">
<span class="glyphicon glyphicon-pencil"></span>
</a>
<button type="submit" class="btn btn-sm btn-default" name="delete" title="{% trans "Delete" %}" onclick="return confirm('{% trans "Are you sure?" %}')">
<span class="glyphicon glyphicon-trash"></span>
</button>
</form>
<!-- Modal -->
<div class="modal fade" id="editSecret{{ secret.uuid }}" tabindex="-1" role="dialog"
aria-labelledby="editSecret" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">{% trans "Set secret value" %}</h4>
</div> </div>
<div class="tab-content"> <div class="modal-footer">
<form class="form-horizontal" method="post" role="form">{% csrf_token %} <button type="button" class="btn btn-default" data-dismiss="modal">{% trans "Close" %}</button>
<div class="form-group"> <button type="submit" class="btn btn-primary" name="set_value">{% trans "Set" %}</button>
<label class="col-sm-3 control-label">{% trans "Value" %}</label> </div>
<div class="col-sm-6"> </form>
<input type="hidden" name="uuid" value="{{ secret.uuid }}"> </div> <!-- /.modal-content -->
<input type="text" name="value" class="form-control" value="{{ secret.value }}" maxlength="45" required pattern="[a-zA-Z0-9]$+"> </div> <!-- /.tab-content -->
</div> </div> <!-- /.modal-dialog -->
</div> </div> <!-- /.modal -->
<div class="modal-footer"> </td>
<button type="button" class="btn btn-default" data-dismiss="modal">{% trans "Close" %}</button> </tr>
<button type="submit" class="btn btn-primary" name="set_value">{% trans "Set" %}</button> {% endfor %}
</div> </tbody>
</form> </table>
</div> <!-- /.modal-content --> </div>
</div> <!-- /.tab-content -->
</div> <!-- /.modal-dialog -->
</div> <!-- /.modal -->
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endif %}
</div> </div>
{% endif %}
</div>
{% endblock %} {% endblock %}
{% block script %} {% block script %}
<script src="{% static "js/sortable.min.js" %}"></script> <script src="{% static "js/sortable.min.js" %}"></script>

View file

@ -7,194 +7,194 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<!-- Page Heading --> <!-- Page Heading -->
<div class="row"> <div class="row">
<div class="col-lg-12">
{% include 'create_stg_vol_block.html' %}
<h1 class="page-header">{% trans "Storage:" %} {{ pool }}</h1>
<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> <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>
<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' %}
{% include 'messages_block.html' %}
<div class="row">
<div class="col-xs-6 col-sm-6">
<p>{% trans "Pool name:" %}</p>
<p>{% trans "Pool type:" %}</p>
<p>{% trans "Pool path:" %}</p>
<p>{% trans "Pool status:" %}</p>
<p>{% trans "Size:" %} ({{ size|filesizeformat }} / {{ used|filesizeformat }})</p>
<p>{% trans "State:" %}</p>
<p>{% trans "Autostart:" %}</p>
</div>
<div class="col-xs-6 col-sm-6">
<p>{{ pool }}</p>
<p>{% if not type %}{% trans "None" %}{% else %}{{ type }}{% endif %}</p>
<p>{% if not path %}{% trans "None" %}{% else %}{{ path }}{% endif %}</p>
<p>{% if not status %}{% trans "None" %}{% else %}{{ status }}{% endif %}</p>
<p>{% trans "Usage:" %} {{ percent }}%</p>
<p>
<form action="" method="post" role="form">{% csrf_token %}
{% ifequal state 0 %}
<input type="submit" class="btn btn-xs btn-default" name="start" value="{% trans "Start" %}">
<input type="submit" class="btn btn-xs btn-default" name="delete" value="{% trans "Delete" %}"
onclick="return confirm('{% trans "Are you sure?" %}')">
{% else %}
<input type="submit" class="btn btn-xs btn-default" name="stop" value="{% trans "Stop" %}"
onclick="return confirm('{% trans "Are you sure?" %}')">
{% endifequal %}
</form>
</p>
<p>
<form action="" method="post" role="form">{% csrf_token %}
{% ifequal autostart 0 %}
<input type="submit" class="btn btn-xs btn-default" name="set_autostart"
value="{% trans "Enable" %}">
{% else %}
<input type="submit" class="btn btn-xs btn-default" name="unset_autostart"
onclick="return confirm('{% trans "Are you sure?" %}')" value="{% trans "Disable" %}">
{% endifequal %}
</form>
</p>
</div>
</div>
<div class="row">
<div class="col-lg-12">
{% if state %}
<div class="row">
<div class="pull-right">
<input id="filter" class="form-control" type="text" placeholder="Search">
</div>
<h3 class="page-header">{% trans "Volumes" %}</h3>
</div>
{% if volumes %}
<div class="table-responsive">
<table class="table table-striped sortable-theme-bootstrap" data-sortable>
<thead>
<tr>
<th style="width: 45px;">#</th>
<th>{% trans "Name" %}</th>
<th>{% trans "Allocated" %}</th>
<th>{% trans "Size" %}</th>
<th>{% trans "Format" %}</th>
<th data-sortable="false" colspan="2">{% trans "Action" %}</th>
</tr>
</thead>
<tbody class="searchable">
{% for volume in volumes %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ volume.name }}</td>
<td>{{ volume.allocation|filesizeformat }}</td>
<td>{{ volume.size|filesizeformat }}</td>
<td>{{ volume.type }}</td>
<td style="width:30px;">
<!-- Modal Clone -->
<div class="modal fade" id="Clone{{ forloop.counter }}" tabindex="-1" role="dialog"
aria-labelledby="addHostLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">{% trans "Clone image" %} <span class="text-danger">{{ volume.name }}</span></h4>
</div>
<form class="form-horizontal" method="post" role="form">{% csrf_token %}
<div class="modal-body">
<div class="form-group">
<label class="col-sm-3 control-label">{% trans "Name" %}</label>
<div class="col-sm-6">
<input type="text" class="form-control" name="name" placeholder="{% trans "Name" %}" required pattern="[a-zA-Z0-9\.\-_]+">
<input type="hidden" name="image" value="{{ volume.name }}">
</div>
</div>
<div class="form-group" id="image_format">
<label class="col-sm-3 control-label">{% trans "Convert" %}</label>
<div class="col-sm-6">
<input class="volume-convert" type="checkbox" name="convert" value="true">
</div>
</div>
<div class="form-group format-convert">
<label class="col-sm-3 control-label">{% trans "Format" %}</label>
<div class="col-sm-6">
<select name="format" class="form-control image-format">
<option value="raw">{% trans "raw" %}</option>
<option value="qcow">{% trans "qcow" %}</option>
<option value="qcow2">{% trans "qcow2" %}</option>
</select>
</div>
</div>
<div class="form-group meta-prealloc" style="display: none;">
<label class="col-sm-3 control-label">{% trans "Metadata" %}</label>
<div class="col-sm-6">
<input type="checkbox" name="meta_prealloc" value="true">
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{% trans "Close" %}</button>
<button type="submit" class="btn btn-primary" name="cln_volume" onclick="showPleaseWaitDialog();">{% trans "Clone" %}</button>
</div>
</form>
</div> <!-- /.modal-content -->
</div> <!-- /.modal-dialog -->
</div> <!-- /.modal -->
{% ifnotequal volume.type "iso" %}
<a data-toggle="modal" href="#Clone{{ forloop.counter }}" class="btn btn-sm btn-default" title="{% trans "Clone" %}"><i class="fa fa-files-o"></i></a>
{% else %}
<a class="btn btn-sm btn-default disabled"><i class="fa fa-files-o"></i></a>
{% endifnotequal %}
</td>
<td style="width:30px;">
<form action="" method="post" style="height:10px" role="form">{% csrf_token %}
<input type="hidden" name="volname" value="{{ volume.name }}">
<button type="submit" class="btn btn-sm btn-default" name="del_volume" title="{% trans "Delete" %}" onclick="return confirm('{% trans "Are you sure?" %}')">
<i class="fa fa-trash"></i>
</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="col-lg-12"> <div class="col-lg-12">
<div class="alert alert-warning alert-dismissable"> {% include 'create_stg_vol_block.html' %}
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button> <h1 class="page-header">{% trans "Storage:" %} {{ pool }}</h1>
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning:" %}</strong> {% trans "Hypervisor doesn't have any Volumes" %} <ol class="breadcrumb">
</div> <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>
<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>
{% endif %}
{% endif %}
</div> </div>
</div> <!-- /.row -->
{% include 'pleasewaitdialog.html' %}
{% include 'errors_block.html' %}
{% include 'messages_block.html' %}
<div class="row">
<div class="col-xs-6 col-sm-6">
<p>{% trans "Pool name" %}:</p>
<p>{% trans "Pool type" %}:</p>
<p>{% trans "Pool path" %}:</p>
<p>{% trans "Pool status" %}:</p>
<p>{% trans "Size" %}: ({{ size|filesizeformat }} / {{ used|filesizeformat }})</p>
<p>{% trans "State" %}:</p>
<p>{% trans "Autostart" %}:</p>
</div>
<div class="col-xs-6 col-sm-6">
<p>{{ pool }}</p>
<p>{% if not type %}{% trans "None" %}{% else %}{{ type }}{% endif %}</p>
<p>{% if not path %}{% trans "None" %}{% else %}{{ path }}{% endif %}</p>
<p>{% if not status %}{% trans "None" %}{% else %}{{ status }}{% endif %}</p>
<p>{% trans "Usage" %}: {{ percent }}%</p>
<p>
<form action="" method="post" role="form">{% csrf_token %}
{% ifequal state 0 %}
<input type="submit" class="btn btn-xs btn-default" name="start" value="{% trans "Start" %}">
<input type="submit" class="btn btn-xs btn-default" name="delete" value="{% trans "Delete" %}"
onclick="return confirm('{% trans "Are you sure?" %}')">
{% else %}
<input type="submit" class="btn btn-xs btn-default" name="stop" value="{% trans "Stop" %}"
onclick="return confirm('{% trans "Are you sure?" %}')">
{% endifequal %}
</form>
</p>
<p>
<form action="" method="post" role="form">{% csrf_token %}
{% ifequal autostart 0 %}
<input type="submit" class="btn btn-xs btn-default" name="set_autostart"
value="{% trans "Enable" %}">
{% else %}
<input type="submit" class="btn btn-xs btn-default" name="unset_autostart"
onclick="return confirm('{% trans "Are you sure?" %}')" value="{% trans "Disable" %}">
{% endifequal %}
</form>
</p>
</div>
</div>
<div class="row">
<div class="col-lg-12">
{% if state %}
<div class="row">
<div class="pull-right">
<input id="filter" class="form-control" type="text" placeholder="Search">
</div>
<h3 class="page-header">{% trans "Volumes" %}</h3>
</div>
{% if volumes %}
<div class="table-responsive">
<table class="table table-striped sortable-theme-bootstrap" data-sortable>
<thead>
<tr>
<th style="width: 45px;">#</th>
<th>{% trans "Name" %}</th>
<th>{% trans "Allocated" %}</th>
<th>{% trans "Size" %}</th>
<th>{% trans "Format" %}</th>
<th data-sortable="false" colspan="2">{% trans "Action" %}</th>
</tr>
</thead>
<tbody class="searchable">
{% for volume in volumes %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ volume.name }}</td>
<td>{{ volume.allocation|filesizeformat }}</td>
<td>{{ volume.size|filesizeformat }}</td>
<td>{{ volume.type }}</td>
<td style="width:30px;">
<!-- Modal Clone -->
<div class="modal fade" id="Clone{{ forloop.counter }}" tabindex="-1" role="dialog"
aria-labelledby="addHostLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">{% trans "Clone image" %} <span class="text-danger">{{ volume.name }}</span></h4>
</div>
<form class="form-horizontal" method="post" role="form">{% csrf_token %}
<div class="modal-body">
<div class="form-group">
<label class="col-sm-3 control-label">{% trans "Name" %}</label>
<div class="col-sm-6">
<input type="text" class="form-control" name="name" placeholder="{% trans "Name" %}" required pattern="[a-zA-Z0-9\.\-_]+">
<input type="hidden" name="image" value="{{ volume.name }}">
</div>
</div>
<div class="form-group" id="image_format">
<label class="col-sm-3 control-label">{% trans "Convert" %}</label>
<div class="col-sm-6">
<input class="volume-convert" type="checkbox" name="convert" value="true">
</div>
</div>
<div class="form-group format-convert">
<label class="col-sm-3 control-label">{% trans "Format" %}</label>
<div class="col-sm-6">
<select name="format" class="form-control image-format">
<option value="raw">{% trans "raw" %}</option>
<option value="qcow">{% trans "qcow" %}</option>
<option value="qcow2">{% trans "qcow2" %}</option>
</select>
</div>
</div>
<div class="form-group meta-prealloc" style="display: none;">
<label class="col-sm-3 control-label">{% trans "Metadata" %}</label>
<div class="col-sm-6">
<input type="checkbox" name="meta_prealloc" value="true">
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{% trans "Close" %}</button>
<button type="submit" class="btn btn-primary" name="cln_volume" onclick="showPleaseWaitDialog();">{% trans "Clone" %}</button>
</div>
</form>
</div> <!-- /.modal-content -->
</div> <!-- /.modal-dialog -->
</div> <!-- /.modal -->
{% ifnotequal volume.type "iso" %}
<a data-toggle="modal" href="#Clone{{ forloop.counter }}" class="btn btn-sm btn-default" title="{% trans "Clone" %}"><i class="fa fa-files-o"></i></a>
{% else %}
<a class="btn btn-sm btn-default disabled"><i class="fa fa-files-o"></i></a>
{% endifnotequal %}
</td>
<td style="width:30px;">
<form action="" method="post" style="height:10px" role="form">{% csrf_token %}
<input type="hidden" name="volname" value="{{ volume.name }}">
<button type="submit" class="btn btn-sm btn-default" name="del_volume" title="{% trans "Delete" %}" onclick="return confirm('{% trans "Are you sure?" %}')">
<i class="fa fa-trash"></i>
</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="col-lg-12">
<div class="alert alert-warning alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning" %}:</strong> {% trans "Hypervisor doesn't have any Volumes" %}
</div>
</div>
{% endif %}
{% endif %}
</div>
</div>
{% include 'pleasewaitdialog.html' %}
{% endblock %} {% endblock %}
{% block script %} {% block script %}
<script src="{% static "js/sortable.min.js" %}"></script> <script src="{% static "js/sortable.min.js" %}"></script>

View file

@ -10,10 +10,12 @@ from libvirt import libvirtError
from django.contrib import messages from django.contrib import messages
import json import json
@login_required @login_required
def storages(request, compute_id): def storages(request, compute_id):
""" """
:param request: :param request:
:param compute_id:
:return: :return:
""" """
@ -72,6 +74,8 @@ def storages(request, compute_id):
def storage(request, compute_id, pool): def storage(request, compute_id, pool):
""" """
:param request: :param request:
:param compute_id:
:param pool:
:return: :return:
""" """

View file

@ -6,7 +6,7 @@ Further Information might be available at:
https://github.com/haypo/python-ipy https://github.com/haypo/python-ipy
""" """
__version__ = '0.83' __version__ = '1.00'
import bisect import bisect
import collections import collections
@ -21,7 +21,7 @@ IPv4ranges = {
'00000000': 'PRIVATE', # 0/8 '00000000': 'PRIVATE', # 0/8
'00001010': 'PRIVATE', # 10/8 '00001010': 'PRIVATE', # 10/8
'0110010001': 'CARRIER_GRADE_NAT', # 100.64/10 '0110010001': 'CARRIER_GRADE_NAT', # 100.64/10
'01111111': 'PRIVATE', # 127.0/8 '01111111': 'LOOPBACK', # 127.0/8
'1': 'PUBLIC', # fall back '1': 'PUBLIC', # fall back
'1010100111111110': 'PRIVATE', # 169.254/16 '1010100111111110': 'PRIVATE', # 169.254/16
'101011000001': 'PRIVATE', # 172.16/12 '101011000001': 'PRIVATE', # 172.16/12
@ -243,7 +243,7 @@ class IPint(object):
else: else:
raise ValueError("can't parse") raise ValueError("can't parse")
(self.ip, parsedVersion) = parseAddress(ip) (self.ip, parsedVersion) = parseAddress(ip, ipversion)
if ipversion == 0: if ipversion == 0:
ipversion = parsedVersion ipversion = parsedVersion
if prefixlen == -1: if prefixlen == -1:
@ -473,7 +473,7 @@ class IPint(object):
"""Return a description of the IP type ('PRIVATE', 'RESERVED', etc). """Return a description of the IP type ('PRIVATE', 'RESERVED', etc).
>>> print(IP('127.0.0.1').iptype()) >>> print(IP('127.0.0.1').iptype())
PRIVATE LOOPBACK
>>> print(IP('192.168.1.1').iptype()) >>> print(IP('192.168.1.1').iptype())
PRIVATE PRIVATE
>>> print(IP('195.185.1.2').iptype()) >>> print(IP('195.185.1.2').iptype())
@ -553,6 +553,9 @@ class IPint(object):
""" """
return True return True
def __bool__(self):
return self.__nonzero__()
def __len__(self): def __len__(self):
""" """
Return the length of a subnet. Return the length of a subnet.
@ -757,6 +760,9 @@ class IPint(object):
def __lt__(self, other): def __lt__(self, other):
return self.__cmp__(other) < 0 return self.__cmp__(other) < 0
def __le__(self, other):
return self.__cmp__(other) <= 0
def __hash__(self): def __hash__(self):
"""Called for the key object for dictionary operations, and by """Called for the key object for dictionary operations, and by
the built-in function hash(). Should return a 32-bit integer the built-in function hash(). Should return a 32-bit integer
@ -1328,7 +1334,7 @@ def _parseAddressIPv6(ipstr):
return value return value
def parseAddress(ipstr): def parseAddress(ipstr, ipversion=0):
""" """
Parse a string and return the corresponding IP address (as integer) Parse a string and return the corresponding IP address (as integer)
and a guess of the IP version. and a guess of the IP version.
@ -1397,7 +1403,7 @@ def parseAddress(ipstr):
# assume IPv6 in pure hexadecimal notation # assume IPv6 in pure hexadecimal notation
return (hexval, 6) return (hexval, 6)
elif ipstr.find('.') != -1 or (intval is not None and intval < 256): elif ipstr.find('.') != -1 or (intval is not None and intval < 256 and ipversion != 6):
# assume IPv4 ('127' gets interpreted as '127.0.0.0') # assume IPv4 ('127' gets interpreted as '127.0.0.0')
bytes = ipstr.split('.') bytes = ipstr.split('.')
if len(bytes) > 4: if len(bytes) > 4:
@ -1415,7 +1421,7 @@ def parseAddress(ipstr):
# will be interpreted as IPv4 first byte # will be interpreted as IPv4 first byte
if intval > MAX_IPV6_ADDRESS: if intval > MAX_IPV6_ADDRESS:
raise ValueError("IP Address can't be larger than %x: %x" % (MAX_IPV6_ADDRESS, intval)) raise ValueError("IP Address can't be larger than %x: %x" % (MAX_IPV6_ADDRESS, intval))
if intval <= MAX_IPV4_ADDRESS: if intval <= MAX_IPV4_ADDRESS and ipversion != 6:
return (intval, 4) return (intval, 4)
else: else:
return (intval, 6) return (intval, 6)

View file

@ -2,7 +2,7 @@ import libvirt
import threading import threading
import socket import socket
from vrtManager import util from vrtManager import util
from rwlock import ReadWriteLock from vrtManager.rwlock import ReadWriteLock
from django.conf import settings from django.conf import settings
from libvirt import libvirtError from libvirt import libvirtError

View file

@ -2,7 +2,6 @@ import string
from vrtManager import util from vrtManager import util
from vrtManager.connection import wvmConnect from vrtManager.connection import wvmConnect
from webvirtcloud.settings import QEMU_CONSOLE_DEFAULT_TYPE from webvirtcloud.settings import QEMU_CONSOLE_DEFAULT_TYPE
from webvirtcloud.settings import QEMU_CONSOLE_LISTEN_ADDRESSES
from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_OWNER as default_owner from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_OWNER as default_owner
from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_FORMAT from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_FORMAT
@ -39,7 +38,7 @@ class wvmCreate(wvmConnect):
except: except:
pass pass
for img in stg.listVolumes(): for img in stg.listVolumes():
if img.endswith('.iso'): if img.lower().endswith('.iso'):
pass pass
else: else:
images.append(img) images.append(img)
@ -107,7 +106,7 @@ class wvmCreate(wvmConnect):
if not pool: if not pool:
storages = self.get_storages(only_actives=True) storages = self.get_storages(only_actives=True)
else: else:
storages = [pool,] storages = [pool]
for storage in storages: for storage in storages:
stg = self.get_storage(storage) stg = self.get_storage(storage)
if stg.info()[0] != 0: if stg.info()[0] != 0:
@ -204,7 +203,6 @@ class wvmCreate(wvmConnect):
hd_disk_letters = list(string.lowercase) hd_disk_letters = list(string.lowercase)
sd_disk_letters = list(string.lowercase) sd_disk_letters = list(string.lowercase)
add_cd = True add_cd = True
#for image, img_type in images.items():
for volume in images: for volume in images:
stg = self.get_storage_by_vol_path(volume['path']) stg = self.get_storage_by_vol_path(volume['path'])
stg_type = util.get_xml_path(stg.XMLDesc(0), "/pool/@type") stg_type = util.get_xml_path(stg.XMLDesc(0), "/pool/@type")
@ -283,8 +281,4 @@ class wvmCreate(wvmConnect):
<memballoon model='virtio'/> <memballoon model='virtio'/>
</devices> </devices>
</domain>""" % video </domain>""" % video
self._defineXML(xml) self._defineXML(xml)

View file

@ -58,13 +58,13 @@ class wvmHostDetails(wvmConnect):
""" """
Function return host server information: hostname, cpu, memory, ... Function return host server information: hostname, cpu, memory, ...
""" """
info = [] info = list()
info.append(self.wvm.getHostname()) # hostname info.append(self.wvm.getHostname()) # hostname
info.append(self.wvm.getInfo()[0]) # architecture info.append(self.wvm.getInfo()[0]) # architecture
info.append(self.wvm.getInfo()[1] * 1048576) # memory info.append(self.wvm.getInfo()[1] * 1048576) # memory
info.append(self.wvm.getInfo()[2]) # cpu core count info.append(self.wvm.getInfo()[2]) # cpu core count
info.append(get_xml_path(self.wvm.getSysinfo(0), func=cpu_version)) # cpu version info.append(get_xml_path(self.wvm.getSysinfo(0), func=cpu_version)) # cpu version
info.append(self.wvm.getURI()) #uri info.append(self.wvm.getURI()) # uri
return info return info

View file

@ -96,7 +96,7 @@ class wvmInstances(wvmConnect):
if listen_addr is None: if listen_addr is None:
listen_addr = util.get_xml_path(inst.XMLDesc(0), "/domain/devices/graphics/listen/@address") listen_addr = util.get_xml_path(inst.XMLDesc(0), "/domain/devices/graphics/listen/@address")
if listen_addr is None: if listen_addr is None:
return "None" return "None"
return listen_addr return listen_addr
def graphics_port(self, name): def graphics_port(self, name):
@ -237,9 +237,9 @@ class wvmInstance(wvmConnect):
try: try:
net = self.get_network(network_host) net = self.get_network(network_host)
ip = get_mac_ipaddr(net, mac_host) ip = get_mac_ipaddr(net, mac_host)
except libvirtError as e: except libvirtError:
ip = None ip = None
result.append({'mac': mac_host, 'nic': network_host, 'target': target_host,'ip': ip, 'filterref': filterref_host}) result.append({'mac': mac_host, 'nic': network_host, 'target': target_host, 'ip': ip, 'filterref': filterref_host})
return result return result
return util.get_xml_path(self._XMLDesc(0), func=networks) return util.get_xml_path(self._XMLDesc(0), func=networks)
@ -322,7 +322,7 @@ class wvmInstance(wvmConnect):
os = tree.find('os') os = tree.find('os')
menu = os.find("bootmenu") menu = os.find("bootmenu")
if menu == None: if menu is None:
bootmenu = ElementTree.fromstring("<bootmenu enable='yes'/>") bootmenu = ElementTree.fromstring("<bootmenu enable='yes'/>")
os.append(bootmenu) os.append(bootmenu)
menu = os.find("bootmenu") menu = os.find("bootmenu")
@ -365,7 +365,7 @@ class wvmInstance(wvmConnect):
for dev in devices: for dev in devices:
dev_target = dev_type = dev_device = dev_alias = None dev_target = dev_type = dev_device = dev_alias = None
boot_dev = dev.find('boot') boot_dev = dev.find('boot')
if boot_dev != None: if boot_dev is not None:
idx = boot_dev.get('order') idx = boot_dev.get('order')
dev_type = dev.get('type') dev_type = dev.get('type')
dev_device = dev.get('device') dev_device = dev.get('device')
@ -398,7 +398,7 @@ class wvmInstance(wvmConnect):
# Remove rest of them # Remove rest of them
for dev in tree.find('devices'): for dev in tree.find('devices'):
boot_dev = dev.find('boot') boot_dev = dev.find('boot')
if boot_dev != None: if boot_dev is not None:
dev.remove(boot_dev) dev.remove(boot_dev)
return tree return tree
@ -410,19 +410,19 @@ class wvmInstance(wvmConnect):
devices = tree.findall("./devices/disk[@device='disk']") devices = tree.findall("./devices/disk[@device='disk']")
for d in devices: for d in devices:
device = d.find("./target[@dev='{}']".format(dev['dev'])) device = d.find("./target[@dev='{}']".format(dev['dev']))
if device != None: if device is not None:
d.append(order) d.append(order)
elif dev['type'] == 'cdrom': elif dev['type'] == 'cdrom':
devices = tree.findall("./devices/disk[@device='cdrom']") devices = tree.findall("./devices/disk[@device='cdrom']")
for d in devices: for d in devices:
device = d.find("./target[@dev='{}']".format(dev['dev'])) device = d.find("./target[@dev='{}']".format(dev['dev']))
if device != None: if device is not None:
d.append(order) d.append(order)
elif dev['type'] == 'network': elif dev['type'] == 'network':
devices = tree.findall("./devices/interface[@type='network']") devices = tree.findall("./devices/interface[@type='network']")
for d in devices: for d in devices:
device = d.find("mac[@address='{}']".format(dev['dev'])) device = d.find("mac[@address='{}']".format(dev['dev']))
if device != None: if device is not None:
d.append(order) d.append(order)
else: else:
raise Exception('Invalid Device Type for boot order') raise Exception('Invalid Device Type for boot order')
@ -478,7 +478,6 @@ class wvmInstance(wvmConnect):
self._defineXML(xmldom) self._defineXML(xmldom)
def attach_disk(self, source, target, sourcetype='file', device='disk', driver='qemu', subdriver='raw', cache='none', targetbus='ide'): def attach_disk(self, source, target, sourcetype='file', device='disk', driver='qemu', subdriver='raw', cache='none', targetbus='ide'):
tree = ElementTree.fromstring(self._XMLDesc(0))
xml_disk = "<disk type='%s' device='%s'>" % (sourcetype, device) xml_disk = "<disk type='%s' device='%s'>" % (sourcetype, device)
if device == 'cdrom': if device == 'cdrom':
xml_disk += "<driver name='%s' type='%s'/>" % (driver, subdriver) xml_disk += "<driver name='%s' type='%s'/>" % (driver, subdriver)
@ -622,7 +621,7 @@ class wvmInstance(wvmConnect):
if listen_addr is None: if listen_addr is None:
listen_addr = util.get_xml_path(self._XMLDesc(0), "/domain/devices/graphics/listen/@address") listen_addr = util.get_xml_path(self._XMLDesc(0), "/domain/devices/graphics/listen/@address")
if listen_addr is None: if listen_addr is None:
return "127.0.0.1" return "127.0.0.1"
return listen_addr return listen_addr
def set_console_listen_addr(self, listen_addr): def set_console_listen_addr(self, listen_addr):
@ -656,7 +655,7 @@ class wvmInstance(wvmConnect):
return socket return socket
def get_console_type(self): def get_console_type(self):
console_type = util.get_xml_path(self._XMLDesc(0),"/domain/devices/graphics/@type") console_type = util.get_xml_path(self._XMLDesc(0), "/domain/devices/graphics/@type")
return console_type return console_type
def set_console_type(self, console_type): def set_console_type(self, console_type):
@ -741,7 +740,6 @@ class wvmInstance(wvmConnect):
""" """
Function change ram and cpu on vds. Function change ram and cpu on vds.
""" """
memory = int(memory) * 1024 memory = int(memory) * 1024
cur_memory = int(cur_memory) * 1024 cur_memory = int(cur_memory) * 1024
# if dom is running change only ram # if dom is running change only ram
@ -769,6 +767,58 @@ class wvmInstance(wvmConnect):
new_xml = ElementTree.tostring(tree) new_xml = ElementTree.tostring(tree)
self._defineXML(new_xml) self._defineXML(new_xml)
def resize_cpu(self, cur_vcpu, vcpu):
"""
Function change ram and cpu on vds.
"""
xml = self._XMLDesc(VIR_DOMAIN_XML_SECURE)
tree = ElementTree.fromstring(xml)
set_vcpu = tree.find('vcpu')
set_vcpu.text = vcpu
set_vcpu.set('current', cur_vcpu)
new_xml = ElementTree.tostring(tree)
self._defineXML(new_xml)
def resize_mem(self, cur_memory, memory):
"""
Function change ram and cpu on vds.
"""
memory = int(memory) * 1024
cur_memory = int(cur_memory) * 1024
# if dom is running change only ram
if self.get_status() == VIR_DOMAIN_RUNNING:
self.set_memory(cur_memory, VIR_DOMAIN_AFFECT_LIVE)
self.set_memory(cur_memory, VIR_DOMAIN_AFFECT_CONFIG)
return
xml = self._XMLDesc(VIR_DOMAIN_XML_SECURE)
tree = ElementTree.fromstring(xml)
set_mem = tree.find('memory')
set_mem.text = str(memory)
set_cur_mem = tree.find('currentMemory')
set_cur_mem.text = str(cur_memory)
new_xml = ElementTree.tostring(tree)
self._defineXML(new_xml)
def resize_disk(self, disks):
"""
Function change disks on vds.
"""
xml = self._XMLDesc(VIR_DOMAIN_XML_SECURE)
tree = ElementTree.fromstring(xml)
for disk in disks:
source_dev = disk['path']
vol = self.get_volume_by_path(source_dev)
vol.resize(disk['size_new'])
new_xml = ElementTree.tostring(tree)
self._defineXML(new_xml)
def get_iso_media(self): def get_iso_media(self):
iso = [] iso = []
storages = self.get_storages(only_actives=True) storages = self.get_storages(only_actives=True)
@ -780,7 +830,7 @@ class wvmInstance(wvmConnect):
except: except:
pass pass
for img in stg.listVolumes(): for img in stg.listVolumes():
if img.endswith('.iso'): if img.lower().endswith('.iso'):
iso.append(img) iso.append(img)
return iso return iso
@ -956,7 +1006,6 @@ class wvmInstance(wvmConnect):
return bridge_name return bridge_name
def add_network(self, mac_address, source, source_type='net', interface_type='bridge', model='virtio', nwfilter=None): def add_network(self, mac_address, source, source_type='net', interface_type='bridge', model='virtio', nwfilter=None):
tree = ElementTree.fromstring(self._XMLDesc(0))
bridge_name = self.get_bridge_name(source, source_type) bridge_name = self.get_bridge_name(source, source_type)
xml_interface = """ xml_interface = """
<interface type='%s'> <interface type='%s'>
@ -978,7 +1027,6 @@ class wvmInstance(wvmConnect):
def delete_network(self, mac_address): def delete_network(self, mac_address):
tree = ElementTree.fromstring(self._XMLDesc(0)) tree = ElementTree.fromstring(self._XMLDesc(0))
devices = tree.find('devices')
for interface in tree.findall('devices/interface'): for interface in tree.findall('devices/interface'):
source = interface.find('mac') source = interface.find('mac')
if source.get('address', '') == mac_address: if source.get('address', '') == mac_address:
@ -1038,7 +1086,7 @@ class wvmInstance(wvmConnect):
option = tree.find(o) option = tree.find(o)
option_value = options.get(o, '').strip() option_value = options.get(o, '').strip()
if not option_value: if not option_value:
if not option is None: if option is not None:
tree.remove(option) tree.remove(option)
else: else:
if option is None: if option is None:

View file

@ -22,6 +22,7 @@ def network_size(net, dhcp=None):
class wvmNetworks(wvmConnect): class wvmNetworks(wvmConnect):
def get_networks_info(self): def get_networks_info(self):
get_networks = self.get_networks() get_networks = self.get_networks()
networks = [] networks = []
@ -166,7 +167,7 @@ class wvmNetwork(wvmConnect):
return dhcp[1] return dhcp[1]
def can_pxe(self): def can_pxe(self):
xml = self.get_xml() xml = self._XMLDesc(0)
forward = self.get_ipv4_forward()[0] forward = self.get_ipv4_forward()[0]
if forward and forward != "nat": if forward and forward != "nat":
return True return True
@ -204,14 +205,14 @@ class wvmNetwork(wvmConnect):
break break
if host is None: if host is None:
self.update(VIR_NETWORK_UPDATE_COMMAND_ADD_LAST, VIR_NETWORK_SECTION_IP_DHCP_HOST, -1, new_xml, self.update(VIR_NETWORK_UPDATE_COMMAND_ADD_LAST, VIR_NETWORK_SECTION_IP_DHCP_HOST, -1, new_xml,
VIR_NETWORK_UPDATE_AFFECT_LIVE|VIR_NETWORK_UPDATE_AFFECT_CONFIG) VIR_NETWORK_UPDATE_AFFECT_LIVE | VIR_NETWORK_UPDATE_AFFECT_CONFIG)
else: else:
# change the host # change the host
if host.get('name') == new_host_xml.get('name') and host.get('ip') == new_host_xml.get('ip'): if host.get('name') == new_host_xml.get('name') and host.get('ip') == new_host_xml.get('ip'):
return False return False
else: else:
self.update(VIR_NETWORK_UPDATE_COMMAND_MODIFY, VIR_NETWORK_SECTION_IP_DHCP_HOST, -1, new_xml, self.update(VIR_NETWORK_UPDATE_COMMAND_MODIFY, VIR_NETWORK_SECTION_IP_DHCP_HOST, -1, new_xml,
VIR_NETWORK_UPDATE_AFFECT_LIVE|VIR_NETWORK_UPDATE_AFFECT_CONFIG) VIR_NETWORK_UPDATE_AFFECT_LIVE | VIR_NETWORK_UPDATE_AFFECT_CONFIG)
def delete_fixed_address(self, mac): def delete_fixed_address(self, mac):
util.validate_macaddr(mac) util.validate_macaddr(mac)
@ -222,7 +223,7 @@ class wvmNetwork(wvmConnect):
if h.get('mac') == mac: if h.get('mac') == mac:
new_xml = '<host mac="{}" name="{}" ip="{}"/>'.format(mac, h.get('name'), h.get('ip')) new_xml = '<host mac="{}" name="{}" ip="{}"/>'.format(mac, h.get('name'), h.get('ip'))
self.update(VIR_NETWORK_UPDATE_COMMAND_DELETE, VIR_NETWORK_SECTION_IP_DHCP_HOST, -1, new_xml, self.update(VIR_NETWORK_UPDATE_COMMAND_DELETE, VIR_NETWORK_SECTION_IP_DHCP_HOST, -1, new_xml,
VIR_NETWORK_UPDATE_AFFECT_LIVE|VIR_NETWORK_UPDATE_AFFECT_CONFIG) VIR_NETWORK_UPDATE_AFFECT_LIVE | VIR_NETWORK_UPDATE_AFFECT_CONFIG)
break break
def modify_dhcp_range(self, range_start, range_end): def modify_dhcp_range(self, range_start, range_end):

View file

@ -12,7 +12,7 @@ class wvmNWFilters(wvmConnect):
def create_nwfilter(self, xml): def create_nwfilter(self, xml):
self.wvm.nwfilterDefineXML(xml) self.wvm.nwfilterDefineXML(xml)
def clone_nwfilter(self,name, cln_name): def clone_nwfilter(self, name, cln_name):
nwfilter = self.get_nwfilter(name) nwfilter = self.get_nwfilter(name)
if nwfilter: if nwfilter:
tree = ElementTree.fromstring(nwfilter.XMLDesc(0)) tree = ElementTree.fromstring(nwfilter.XMLDesc(0))

View file

@ -7,11 +7,11 @@ class wvmSecrets(wvmConnect):
xml = """<secret ephemeral='%s' private='%s'> xml = """<secret ephemeral='%s' private='%s'>
<usage type='%s'>""" % (ephemeral, private, secret_type) <usage type='%s'>""" % (ephemeral, private, secret_type)
if secret_type == 'ceph': if secret_type == 'ceph':
xml += """<name>%s</name>""" % (data) xml += """<name>%s</name>""" % data
if secret_type == 'volume': if secret_type == 'volume':
xml += """<volume>%s</volume>""" % (data) xml += """<volume>%s</volume>""" % data
if secret_type == 'iscsi': if secret_type == 'iscsi':
xml += """<target>%s</target>""" % (data) xml += """<target>%s</target>""" % data
xml += """</usage> xml += """</usage>
</secret>""" </secret>"""
self.wvm.secretDefineXML(xml) self.wvm.secretDefineXML(xml)

View file

@ -110,7 +110,7 @@ def get_xpath(doc, path):
if ret is not None: if ret is not None:
if type(ret) == list: if type(ret) == list:
if len(ret) >= 1: if len(ret) >= 1:
if hasattr(ret[0],'text'): if hasattr(ret[0], 'text'):
result = ret[0].text result = ret[0].text
else: else:
result = ret[0] result = ret[0]
@ -119,6 +119,7 @@ def get_xpath(doc, path):
return result return result
def pretty_mem(val): def pretty_mem(val):
val = int(val) val = int(val)
if val > (10 * 1024 * 1024): if val > (10 * 1024 * 1024):
@ -146,8 +147,8 @@ def validate_uuid(val):
if form is None: if form is None:
raise ValueError( raise ValueError(
"UUID must be a 32-digit hexadecimal number. It may take " "UUID must be a 32-digit hexadecimal number. It may take "
"the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx or may " "the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx or may "
"omit hyphens altogether.") "omit hyphens altogether.")
else: # UUID had no dashes, so add them in else: # UUID had no dashes, so add them in
val = (val[0:8] + "-" + val[8:12] + "-" + val[12:16] + val = (val[0:8] + "-" + val[8:12] + "-" + val[12:16] +