1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-03-22 02:24:56 +00:00
This commit is contained in:
catborise 2020-10-16 15:14:50 +03:00
commit 3125e9d17c
65 changed files with 1126 additions and 1231 deletions

View file

@ -10,19 +10,19 @@ def apply_change_password(sender, **kwargs):
from django.conf import settings from django.conf import settings
from django.contrib.auth.models import User, Permission from django.contrib.auth.models import User, Permission
if hasattr(settings, 'SHOW_PROFILE_EDIT_PASSWORD'): if hasattr(settings, 'SHOW_PROFILE_EDIT_PASSWORD'):
print('\033[92mSHOW_PROFILE_EDIT_PASSWORD is found inside settings.py\033[0m') print('\033[1m! \033[92mSHOW_PROFILE_EDIT_PASSWORD is found inside settings.py\033[0m')
print('\033[92mApplying permission can_change_password for all users\033[0m') print('\033[1m* \033[92mApplying permission can_change_password for all users\033[0m')
users = User.objects.all() users = User.objects.all()
permission = Permission.objects.get(codename='change_password') permission = Permission.objects.get(codename='change_password')
if settings.SHOW_PROFILE_EDIT_PASSWORD: if settings.SHOW_PROFILE_EDIT_PASSWORD:
print('\033[91mWarning!!! Setting to True for all users\033[0m') print('\033[1m! \033[91mWarning!!! Setting to True for all users\033[0m')
for user in users: for user in users:
user.user_permissions.add(permission) user.user_permissions.add(permission)
else: else:
print('\033[91mWarning!!! Setting to False for all users\033[0m') print('\033[1m* \033[91mWarning!!! Setting to False for all users\033[0m')
for user in users: for user in users:
user.user_permissions.remove(permission) user.user_permissions.remove(permission)
print('\033[1mDon`t forget to remove the option from settings.py\033[0m') print('\033[1m! Don`t forget to remove the option from settings.py\033[0m')
def create_admin(sender, **kwargs): def create_admin(sender, **kwargs):
@ -32,11 +32,11 @@ def create_admin(sender, **kwargs):
from django.contrib.auth.models import User from django.contrib.auth.models import User
from accounts.models import UserAttributes from accounts.models import UserAttributes
plan = kwargs['plan'] plan = kwargs.get('plan', [])
for migration, rolled_back in plan: for migration, rolled_back in plan:
if migration.app_label == 'accounts' and migration.name == '0001_initial' and not rolled_back: if migration.app_label == 'accounts' and migration.name == '0001_initial' and not rolled_back:
if User.objects.count() == 0: if User.objects.count() == 0:
print('\033[92mCreating default admin user\033[0m') print('\033[1m* \033[92mCreating default admin user\033[0m')
admin = User.objects.create_superuser('admin', None, 'admin') admin = User.objects.create_superuser('admin', None, 'admin')
UserAttributes(user=admin, max_instances=-1, max_cpus=-1, max_memory=-1, max_disk_size=-1).save() UserAttributes(user=admin, max_instances=-1, max_cpus=-1, max_memory=-1, max_disk_size=-1).save()
break break
@ -47,5 +47,5 @@ class AccountsConfig(AppConfig):
verbose_name = 'Accounts' verbose_name = 'Accounts'
def ready(self): def ready(self):
post_migrate.connect(apply_change_password, sender=self)
post_migrate.connect(create_admin, sender=self) post_migrate.connect(create_admin, sender=self)
post_migrate.connect(apply_change_password, sender=self)

View file

@ -1,7 +1,7 @@
from appsettings.settings import app_settings from appsettings.settings import app_settings
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.forms import ModelForm, ValidationError from django.forms import ModelForm, ValidationError
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from .models import UserInstance, UserSSHKey from .models import UserInstance, UserSSHKey
from .utils import validate_ssh_key from .utils import validate_ssh_key

View file

@ -1,7 +1,7 @@
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.validators import MinValueValidator from django.core.validators import MinValueValidator
from django.db import models from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from instances.models import Instance from instances.models import Instance

View file

@ -5,13 +5,13 @@
{% load qr_code %} {% load qr_code %}
{% block title %}{% trans "User Profile" %} - {{ user }}{% endblock %} {% block title %}{% trans "User Profile" %} - {{ user }}{% endblock %}
{% block page_header %}{% trans "User Profile" %}: {{ user }}{% endblock page_header %} {% block page_heading %}{% trans "User Profile" %}: {{ user }}{% endblock page_heading %}
{% block page_header_extra %} {% block page_heading_extra %}
<a href="{% url 'accounts:user_instance_create' user.id %}" class="btn btn-success"> <a href="{% url 'accounts:user_instance_create' user.id %}" class="btn btn-success">
{% icon 'plus' %} {% icon 'plus' %}
</a> </a>
{% endblock page_header_extra %} {% endblock page_heading_extra %}
{% block content %} {% block content %}
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">

View file

@ -1,175 +0,0 @@
{% extends "base.html" %}
{% load i18n %}
{% load staticfiles %}
{% block title %}{% trans "Users" %}{% endblock %}
{% block content %}
<!-- Page Heading -->
<div class="row">
<div class="col-lg-12">
{% include 'create_user_block.html' %}
<div class="float-right search">
<input id="filter" class="form-control" type="text" placeholder="{% trans 'Search' %}">
</div>
<h2 class="page-header">{% trans "Users" %}</h1>
</div>
</div>
<!-- /.row -->
{% include 'errors_block.html' %}
<div class="row">
{% if not users %}
<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 user" %}
</div>
</div>
{% else %}
<div class="col-lg-12">
<table class="table table-striped table-hover">
<thead>
<tr>
<th scope="col">{% trans "Username" %}</th>
<th scope="col">{% trans "Status" %}</th>
<th scope="col">{% trans "Staff" %}</th>
<th scope="col">{% trans "Superuser" %}</th>
<th scope="col">{% trans "Clone" %}</th>
</tr>
</thead>
<tbody class="searchable">
{% for user in users %}
<tr class="{% if not user.is_active %}danger{% endif %}">
<td>
<a href="{% url 'accounts:account' user.id %}"><strong>{{ user.username }}</strong></a>
<a data-toggle="modal" href="#editUser{{ user.id }}" class="float-right" title="{% trans "Edit" %}">
<span class="fa fa-cog"></span>
</a>
</td>
<td>
{% if user.is_active %}
{% trans "Active" %}
{% else %}
{% trans "Blocked" %}
{% endif %}
</td>
<td>{% if user.is_staff %}<span class="fa fa-check"></span>{% endif %}</td>
<td>{% if user.is_superuser %}<span class="fa fa-check"></span>{% endif %}</td>
<td>{% if perms.instances.clone_instances %}<span class="fa fa-check"></span>{% endif %}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% for user in users %}
<!-- Modal Edit -->
<div class="modal fade" id="editUser{{ user.id }}" tabindex="-1" role="dialog" aria-labelledby="editUserLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<form method="post" role="form" aria-label="Edit user form">{% csrf_token %}
<div class="modal-header">
<h5 class="modal-title">{% trans "Edit user info" %}</h5>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
</div>
<div class="modal-body">
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Name" %}</label>
<div class="col-sm-6">
<input type="hidden" name="user_id" value="{{ user.id }}">
<input type="text" name="name" class="form-control" value="{{ user.username }}" disabled>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Password" %}</label>
<div class="col-sm-6">
<input type="password" name="user_pass" class="form-control" value="">
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Is staff" %}</label>
<div class="col-sm-2">
<input type="checkbox" name="user_is_staff" {% if user.is_staff %}checked{% endif %}>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Is superuser" %}</label>
<div class="col-sm-2">
<input type="checkbox" name="user_is_superuser" {% if user.is_superuser %}checked{% endif %}>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Can clone instances" %}</label>
<div class="col-sm-2">
<input type="checkbox" name="userattributes_can_clone_instances" {% if user.userattributes.can_clone_instances %}checked{% endif %}>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Max instances" %}</label>
<div class="col-sm-6">
<input type="text" name="userattributes_max_instances" class="form-control" value="{{ user.userattributes.max_instances }}">
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Max cpus" %}</label>
<div class="col-sm-6">
<input type="text" name="userattributes_max_cpus" class="form-control" value="{{ user.userattributes.max_cpus }}">
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Max memory (MB)" %}</label>
<div class="col-sm-6">
<input type="text" name="userattributes_max_memory" class="form-control" value="{{ user.userattributes.max_memory }}">
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Max disk size (GB)" %}</label>
<div class="col-sm-6">
<input type="text" name="userattributes_max_disk_size" class="form-control" value="{{ user.userattributes.max_disk_size }}">
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="float-left btn btn-danger" name="delete">
{% trans "Delete" %}
</button>
{% if user.is_active %}
<button type="submit" class="btn btn-warning mr-auto" name="block">
{% trans "Block" %}
</button>
{% else %}
<button type="submit" class="btn btn-success mr-auto" name="unblock">
{% trans "Unblock" %}
</button>
{% endif %}
<button type="button" class="btn btn-secondary" data-dismiss="modal">
{% trans "Close" %}
</button>
<button type="submit" class="btn btn-primary" name="edit">
{% trans "Edit" %}
</button>
</div>
</form>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
{% endfor %}
</div>
{% endif %}
</div>
{% endblock %}
{% block script %}
<script>
function filter_table() {
var rex = new RegExp($(this).val(), 'i');
$('.searchable tr').hide();
$('.searchable tr').filter(function () {
return rex.test($(this).text());
}).show();
}
$(document).ready(function () {
(function ($) {
$('#filter').keyup(filter_table)
}(jQuery));
});
</script>
{% endblock %}

View file

@ -1,151 +0,0 @@
{% extends "base.html" %}
{% load i18n %}
{% block title %}{% trans "Users" %}{% endblock %}
{% block content %}
<!-- Page Heading -->
<div class="row">
<div class="col-lg-12">
{% include 'create_user_block.html' %}
<h2 class="page-header">{% trans "Users" %}</h2>
</div>
</div>
<!-- /.row -->
{% include 'errors_block.html' %}
<div class="row">
{% if not users %}
<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 user" %}
</div>
</div>
{% else %}
{% for user in users %}
<div id="{{ user.username }}" class="col-sm-12 col-md-4">
{% if user.is_active %}
<div class="card border-success shadow">
<div class="card-header bg-success">
{% else %}
<div class="card border-secondary shadow">
<div class="card-header bg-secondary">
{% endif %}
<h5 class="my-0 card-title">
<a class="card-link text-light" href="{% url 'accounts:account' user.id %}"><strong>{{ user.username }}</strong></a>
<a class="card-link text-light float-right" data-toggle="modal" href="#editUser{{ user.id }}" title="{% trans "Edit" %}">
<span class="fa fa-cog"></span>
</a>
</h5>
</div>
<div class="card-body">
<div class="row row-cols-2">
<div class="col">
<p class="card-text font-weight-bold">{% trans "Status" %}:</p>
</div>
<div class="col">
{% if user.is_active %}
<p>{% trans "Active" %}</p>
{% else %}
<p>{% trans "Blocked" %}</p>
{% endif %}
</div>
</div>
</div>
</div>
</div>
<!-- Modal Edit -->
<div class="modal fade" id="editUser{{ user.id }}" tabindex="-1" role="dialog" aria-labelledby="editUserLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">{% trans "Edit user info" %}</h5>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
</div>
<div class="modal-body">
<form method="post" aria-label="Edit user form">{% csrf_token %}
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Name" %}</label>
<div class="col-sm-6">
<input type="hidden" name="user_id" value="{{ user.id }}">
<input type="text" name="name" class="form-control" value="{{ user.username }}" disabled>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Password" %}</label>
<div class="col-sm-6">
<input type="password" name="user_pass" class="form-control" value="">
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Is staff" %}</label>
<div class="form-check form-check-inline col-sm-2 ml-3">
<input class="form-check-input position-static" type="checkbox" name="user_is_staff" {% if user.is_staff %}checked{% endif %}>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Is superuser" %}</label>
<div class="form-check form-check-inline col-sm-2 ml-3">
<input class="form-check-input position-static" type="checkbox" name="user_is_superuser" {% if user.is_superuser %}checked{% endif %}>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Can clone instances" %}</label>
<div class="form-check form-check-inline col-sm-2 ml-3">
<input class="form-check-input position-static" type="checkbox" name="userattributes_can_clone_instances" {% if user.userattributes.can_clone_instances %}checked{% endif %}>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Max instances" %}</label>
<div class="col-sm-6">
<input type="text" name="userattributes_max_instances" class="form-control" value="{{ user.userattributes.max_instances}}" required="True" >
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Max cpus" %}</label>
<div class="col-sm-6">
<input type="text" name="userattributes_max_cpus" class="form-control" value="{{ user.userattributes.max_cpus }}" required="True">
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Max memory (MB)" %}</label>
<div class="col-sm-6">
<input type="text" name="userattributes_max_memory" class="form-control" value="{{ user.userattributes.max_memory}}" required="True">
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Max disk size (GB)" %}</label>
<div class="col-sm-6">
<input type="text" name="userattributes_max_disk_size" class="form-control" value="{{ user.userattributes.max_disk_size }}" required="True">
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-danger" name="delete">
{% trans "Delete" %}
</button>
{% if user.is_active %}
<button type="submit" class="btn btn-warning mr-auto" name="block">
{% trans "Block" %}
</button>
{% else %}
<button type="submit" class="btn btn-success mr-auto" name="unblock">
{% trans "Unblock" %}
</button>
{% endif %}
<button type="submit" class="btn btn-secondary" data-dismiss="modal">
{% trans "Close" %}
</button>
<button type="submit" class="btn btn-primary" name="edit">
{% trans "Edit" %}
</button>
</form>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
{% endfor %}
{% endif %}
</div>
{% endblock %}

View file

@ -1,38 +0,0 @@
{% load i18n %}
{% if request.user.is_superuser %}
<a href="#AddUser" type="button" class="btn btn-success btn-header float-right" data-toggle="modal">
<span class="fa fa-plus" aria-hidden="true"></span>
</a>
<!-- Modal pool -->
<div class="modal fade" id="AddUser" tabindex="-1" role="dialog" aria-labelledby="AddUserLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<form method="post" aria-label="Add user form">{% csrf_token %}
<div class="modal-header">
<h5 class="modal-title">{% trans "Add New User" %}</h5>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
</div>
<div class="modal-body">
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Name" %}</label>
<div class="col-sm-6">
<input type="text" class="form-control" name="name" placeholder="{% trans "john" %}" required pattern="[a-z0-9]+">
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Password" %}</label>
<div class="col-sm-6">
<input type="password" class="form-control" name="password" placeholder="*******" {% if not allow_empty_password %}required{% endif %}>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">{% trans "Close" %}</button>
<button type="submit" class="btn btn-primary" name="create">{% trans "Create" %}</button>
</div>
</form>
</div> <!-- /.modal-content -->
</div> <!-- /.modal-dialog -->
</div> <!-- /.modal -->
{% endif %}

View file

@ -6,7 +6,7 @@
{% block title %}{% trans "Profile" %}: {{ request.user.first_name }} {{ request.user.last_name}}{% endblock %} {% block title %}{% trans "Profile" %}: {{ request.user.first_name }} {{ request.user.last_name}}{% endblock %}
{% block page_header %}{% trans "Profile" %}: {{ request.user.first_name }} {{ request.user.last_name}}{% endblock page_header %} {% block page_heading %}{% trans "Profile" %}: {{ request.user.first_name }} {{ request.user.last_name}}{% endblock page_heading %}
{% block content %} {% block content %}
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">

View file

@ -0,0 +1 @@
defautl_app_config = 'admin.apps.AdminConfig'

View file

@ -3,7 +3,7 @@ from django.contrib.auth.models import Group, User
from django.contrib.auth.forms import ReadOnlyPasswordHashField from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.utils.text import format_lazy from django.utils.text import format_lazy
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from accounts.models import UserAttributes from accounts.models import UserAttributes

View file

@ -1,28 +0,0 @@
{% extends "base.html" %}
{% load icons %}
{% load i18n %}
{% block title %}{{ title }}{% endblock %}
{% block content %}
{% if create_url %}
<a class="btn btn-success float-right" href="{% url create_url %}">{% icon 'plus' %} {%trans "Create New" %}</a>
{% endif %}
<table class="table table-hover">
{% for object in object_list %}
<tr>
<td>{{ object }}
<div class="btn-group float-right">
<a class="btn btn-success" href="{% url update_url object.id %}">{% icon 'edit' %} {%trans "Edit"%}</a>
{% if extra_urls %}
{% for url in extra_urls %}
<a class="btn btn-primary" href="{% url url.0 object.id %}">{{ url.1 }}</a>
{% endfor %}
{% endif %}
<a class="btn btn-danger" href="{% url delete_url object.id %}">{% icon 'times' %} {%trans "Delete" %}</a>
</div>
</td>
</tr>
{% endfor %}
</table>
{% endblock %}

View file

@ -15,7 +15,6 @@
<h1 class="page-header">{% trans "Groups" %}</h1> <h1 class="page-header">{% trans "Groups" %}</h1>
</div> </div>
</div> </div>
{% include 'errors_block.html' %}
<div class="row"> <div class="row">
{% if not groups %} {% if not groups %}
<div class="col-lg-12"> <div class="col-lg-12">

View file

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

View file

@ -3,16 +3,13 @@
{% load icons %} {% load icons %}
{% load i18n %} {% load i18n %}
{% block title %}{% trans "User" %}{% endblock %} {% block title %}{{ title }}{% endblock %}
{% block page_heading %}{{ title }}{% endblock page_heading %}
{% block content %} {% block content %}
<div class="row"> <div class="card col-sm-10 offset-1">
<div class="col-lg-12"> <div class="card-body">
<h2 class="page-header">{{ title }}</h2>
</div>
</div>
<div class="row">
<div class="thumbnail col-sm-10 offset-1">
<form id="create-update" action="" method="post"> <form id="create-update" action="" method="post">
{% csrf_token %} {% csrf_token %}
{% bootstrap_form user_form layout='horizontal' %} {% bootstrap_form user_form layout='horizontal' %}

View file

@ -3,20 +3,21 @@
{% load static %} {% load static %}
{% load common_tags %} {% load common_tags %}
{% load icons %} {% load icons %}
{% block title %}{% trans "Users" %}{% endblock %}
{% block content %} {% block title %}{{ title }}{% endblock %}
<div class="row">
<div class="col-lg-12"> {% block page_heading %}{{ title }}{% endblock page_heading %}
<a href="{% url 'admin:user_create' %}" class="btn btn-success btn-header float-right">
{% icon 'plus' %} {% block page_heading_extra %}
</a> <a href="{% url 'admin:user_create' %}" class="btn btn-success btn-header float-right">
<div class="float-right search"> {% icon 'plus' %}
<input id="filter" class="form-control" type="text" placeholder="{% trans "Search" %}"> </a>
</div> <div class="float-right search">
<h1 class="page-header">{% trans "Users" %}</h1> <input id="filter" class="form-control" type="text" placeholder="{% trans "Search" %}">
</div>
</div> </div>
{% include 'errors_block.html' %} {% endblock page_heading_extra %}
{% block content %}
<div class="row"> <div class="row">
{% if not users %} {% if not users %}
<div class="col-lg-12"> <div class="col-lg-12">

View file

@ -5,7 +5,7 @@ from django.contrib.auth.forms import AdminPasswordChangeForm
from django.contrib.auth.models import Group, User from django.contrib.auth.models import Group, User
from django.core.paginator import Paginator from django.core.paginator import Paginator
from django.shortcuts import get_object_or_404, redirect, render from django.shortcuts import get_object_or_404, redirect, render
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from accounts.models import UserAttributes, UserInstance, Instance from accounts.models import UserAttributes, UserInstance, Instance
from appsettings.settings import app_settings from appsettings.settings import app_settings

View file

@ -1,7 +1,8 @@
# Generated by Django 2.2.12 on 2020-05-23 12:05 # Generated by Django 2.2.12 on 2020-05-23 12:05
from django.db import migrations from django.db import migrations
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
def add_default_settings(apps, schema_editor): def add_default_settings(apps, schema_editor):
setting = apps.get_model("appsettings", "AppSettings") setting = apps.get_model("appsettings", "AppSettings")

View file

@ -1,7 +1,7 @@
# Generated by Django 2.2.13 on 2020-07-16 06:37 # Generated by Django 2.2.13 on 2020-07-16 06:37
from django.db import migrations from django.db import migrations
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
def add_default_settings(apps, schema_editor): def add_default_settings(apps, schema_editor):

View file

@ -1,5 +1,6 @@
from django.db import models from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
class AppSettings(models.Model): class AppSettings(models.Model):

View file

@ -1,80 +1,74 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load i18n %} {% load i18n %}
{% block title %}{% trans "Edit Settings" %}{% endblock %}
{% block title %}{% trans "Edit Settings" %}{% endblock title %}
{% block page_heading %}{% trans "Edit Settings" %}{% endblock page_heading %}
{% block content %} {% block content %}
<!-- Page Heading --> <div class="">
<div class="row"> <div class="col-lg-12">
<div class="col-lg-12"> <h3 class="page-header">{% trans "App Settings" %}</h3>
<h2 class="page-header">{% trans "Edit Settings" %}</h2> <form action="{% url 'set_language' %}" method="post" style="display:inline" aria-label="Edit language.name_local settings form">{% csrf_token %}
<div class="form-group row">
<input name="next" type="hidden" value="{{ redirect_to }}">
<label class="col-sm-3 col-form-label">{% trans "Language" %}</label>
<div class="col-sm-6">
<select name="language" class="form-control" onchange="this.form.submit()">
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
{% get_language_info_list for LANGUAGES as languages %}
{% for language in languages %}
<option value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected{% endif %}>
{{ language.name_local }} ({{ language.code }})
</option>
{% endfor %}
</select>
</div>
</div> </div>
</div> </form>
<!-- /.row --> {% if request.user.is_superuser %}
<form method="post" action="" role="form" aria-label="Edit sass directory settings form">{% csrf_token %}
{% include 'errors_block.html' %} <div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans sass_dir.name %}</label>
<div class=""> <div class="col-sm-6">
<div class="col-lg-12"> <input class="form-control" name="{{ sass_dir.key }}" value="{{ sass_dir.value }}" onchange="this.form.submit()" title="{% trans sass_dir.description %}"/>
<h3 class="page-header">{% trans "App Settings" %}</h3> </div>
<form action="{% url 'set_language' %}" method="post" style="display:inline" aria-label="Edit language.name_local settings form">{% csrf_token %} </div>
<div class="form-group row"> </form>
<input name="next" type="hidden" value="{{ redirect_to }}"> <form method="post" action="" role="form" aria-label="Edit theme settings form">{% csrf_token %}
<label class="col-sm-3 col-form-label">{% trans "Language" %}</label> <div class="form-group row">
<div class="col-sm-6"> <label class="col-sm-3 col-form-label">{% trans bootstrap_theme.name %}</label>
<select name="language" class="form-control" onchange="this.form.submit()"> <div class="col-sm-6">
{% get_current_language as LANGUAGE_CODE %} <select class="form-control" name="{{ bootstrap_theme.key }}" onchange="this.form.submit()" title="{% trans bootstrap_theme.description %}">
{% get_available_languages as LANGUAGES %} {% for theme in themes_list %}
{% get_language_info_list for LANGUAGES as languages %} <option {% if bootstrap_theme.value == theme %}selected{% endif %} value="{{ theme }}">{{ theme }}</option>
{% for language in languages %} {% endfor %}
<option value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected{% endif %}> </select>
{{ language.name_local }} ({{ language.code }}) <span class="text-muted">{% trans "After change please full refresh page with 'Ctrl + F5' "%}</span>
</option> </div>
{% endfor %} </div>
</select> </form>
</div> {% endif %}
</div> <h3 class="page-header">{% trans "Other Settings" %}</h3>
</form> {% for setting in appsettings %}
{% if request.user.is_superuser %} <form method="post" action="" role="form" aria-label="{{setting.name}} form">{% csrf_token %}
<form method="post" action="" role="form" aria-label="Edit sass directory settings form">{% csrf_token %} <div class="form-group row">
<div class="form-group row"> <label class="col-sm-3 col-form-label">{% trans setting.name %}</label>
<label class="col-sm-3 col-form-label">{% trans sass_dir.name %}</label> <div class="col-sm-6">
<div class="col-sm-6"> {% if setting.choices %}
<input class="form-control" name="{{ sass_dir.key }}" value="{{ sass_dir.value }}" onchange="this.form.submit()" title="{% trans sass_dir.description %}"/> <select class="form-control" name="{{ setting.key }}" onchange="this.form.submit()" title="{% trans setting.description %}">
</div> {% for choice in setting.choices_as_list %}
</div> <option {% if setting.value == choice %} selected {% endif %} value={{ choice }}>{% trans choice %}</option>
</form>
<form method="post" action="" role="form" aria-label="Edit theme settings form">{% csrf_token %}
<div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans bootstrap_theme.name %}</label>
<div class="col-sm-6">
<select class="form-control" name="{{ bootstrap_theme.key }}" onchange="this.form.submit()" title="{% trans bootstrap_theme.description %}">
{% for theme in themes_list %}
<option {% if bootstrap_theme.value == theme %}selected{% endif %} value="{{ theme }}">{{ theme }}</option>
{% endfor %} {% endfor %}
</select> </select>
<span class="text-muted">{% trans "After change please full refresh page with 'Ctrl + F5' "%}</span> {% else %}
</div> <input class="form-control" name="{{ setting.key }}" value="{{ setting.value }}" title="{% trans setting.description %}" onchange="this.form.submit()"/>
{% endif%}
</div> </div>
</form> </div>
{% endif %} </form>
<h3 class="page-header">{% trans "Other Settings" %}</h3> {% endfor %}
{% for setting in appsettings %} </div>
<form method="post" action="" role="form" aria-label="{{setting.name}} form">{% csrf_token %} </div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans setting.name %}</label>
<div class="col-sm-6">
{% if setting.choices %}
<select class="form-control" name="{{ setting.key }}" onchange="this.form.submit()" title="{% trans setting.description %}">
{% for choice in setting.choices_as_list %}
<option {% if setting.value == choice %} selected {% endif %} value={{ choice }}>{% trans choice %}</option>
{% endfor %}
</select>
{% else %}
<input class="form-control" name="{{ setting.key }}" value="{{ setting.value }}" title="{% trans setting.description %}" onchange="this.form.submit()"/>
{% endif%}
</div>
</div>
</form>
{% endfor %}
</div>
</div>
{% endblock %} {% endblock %}

View file

@ -1,16 +1,14 @@
import sass
import os import os
from django.shortcuts import render import sass
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.decorators import login_required
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.decorators import login_required
from appsettings.models import AppSettings from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.utils.translation import gettext_lazy as _
from logs.views import addlogmsg from logs.views import addlogmsg
from appsettings.models import AppSettings
@login_required @login_required
@ -19,20 +17,18 @@ def appsettings(request):
:param request: :param request:
:return: :return:
""" """
error_messages = []
main_css = "wvc-main.min.css" main_css = "wvc-main.min.css"
sass_dir = AppSettings.objects.get(key="SASS_DIR") sass_dir = AppSettings.objects.get(key="SASS_DIR")
bootstrap_theme = AppSettings.objects.get(key="BOOTSTRAP_THEME") bootstrap_theme = AppSettings.objects.get(key="BOOTSTRAP_THEME")
try: try:
themes_list = os.listdir(sass_dir.value + "/wvc-theme") themes_list = os.listdir(sass_dir.value + "/wvc-theme")
except FileNotFoundError as err: except FileNotFoundError as err:
error_messages.append(err) messages.error(request, err)
addlogmsg(request.user.username, "", err) addlogmsg(request.user.username, "", err)
# Bootstrap settings related with filesystems, because of that they are excluded from other settings # Bootstrap settings related with filesystems, because of that they are excluded from other settings
appsettings = AppSettings.objects.exclude(description__startswith="Bootstrap").order_by("name") appsettings = AppSettings.objects.exclude(description__startswith="Bootstrap").order_by("name")
if request.method == 'POST': if request.method == 'POST':
if 'SASS_DIR' in request.POST: if 'SASS_DIR' in request.POST:
try: try:
@ -43,7 +39,7 @@ def appsettings(request):
messages.success(request, msg) messages.success(request, msg)
except Exception as err: except Exception as err:
msg = err msg = err
error_messages.append(msg) messages.error(request, msg)
addlogmsg(request.user.username, "", msg) addlogmsg(request.user.username, "", msg)
return HttpResponseRedirect(request.get_full_path()) return HttpResponseRedirect(request.get_full_path())
@ -58,7 +54,8 @@ def appsettings(request):
with open(sass_dir.value + "/wvc-main.scss", "w") as main: with open(sass_dir.value + "/wvc-main.scss", "w") as main:
main.write(scss_var + "\n" + scss_boot + "\n" + scss_bootswatch + "\n") main.write(scss_var + "\n" + scss_boot + "\n" + scss_bootswatch + "\n")
css_compressed = sass.compile(string=scss_var + "\n"+ scss_boot + "\n" + scss_bootswatch, output_style='compressed') css_compressed = sass.compile(string=scss_var + "\n" + scss_boot + "\n" + scss_bootswatch,
output_style='compressed')
with open("static/css/" + main_css, "w") as css: with open("static/css/" + main_css, "w") as css:
css.write(css_compressed) css.write(css_compressed)
@ -69,7 +66,7 @@ def appsettings(request):
messages.success(request, msg) messages.success(request, msg)
except Exception as err: except Exception as err:
msg = err msg = err
error_messages.append(msg) messages.error(request, msg)
addlogmsg(request.user.username, "", msg) addlogmsg(request.user.username, "", msg)
return HttpResponseRedirect(request.get_full_path()) return HttpResponseRedirect(request.get_full_path())
@ -84,10 +81,9 @@ def appsettings(request):
messages.success(request, msg) messages.success(request, msg)
except Exception as err: except Exception as err:
msg = err msg = err
error_messages.append(msg) messages.error(request, msg)
addlogmsg(request.user.username, "", msg) addlogmsg(request.user.username, "", msg)
return HttpResponseRedirect(request.get_full_path()) return HttpResponseRedirect(request.get_full_path())
return render(request, 'appsettings.html', locals()) return render(request, 'appsettings.html', locals())

View file

@ -1,8 +1,9 @@
import re
from django import forms from django import forms
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from vrtManager.connection import CONN_SOCKET, CONN_SSH, CONN_TCP, CONN_TLS
from computes.models import Compute from computes.models import Compute
from vrtManager.connection import CONN_TCP, CONN_SSH, CONN_TLS, CONN_SOCKET
from .validators import validate_hostname from .validators import validate_hostname

View file

@ -1,6 +1,6 @@
from django.db.models import CharField, IntegerField, Model from django.db.models import CharField, IntegerField, Model
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from libvirt import virConnect from libvirt import virConnect
from vrtManager.connection import connection_manager from vrtManager.connection import connection_manager

View file

@ -6,9 +6,9 @@
{% block style %} {% block style %}
<link rel="stylesheet" href="{% static "css/sortable-theme-bootstrap.css" %}" /> <link rel="stylesheet" href="{% static "css/sortable-theme-bootstrap.css" %}" />
{% endblock %} {% endblock %}
{% block page_header %}{{ compute.name }}{% endblock page_header %} {% block page_heading %}{{ compute.name }}{% endblock page_heading %}
{% block page_header_extra %} {% block page_heading_extra %}
<a href="{% url 'instances:create_instance_select_type' compute.id %}" <a href="{% url 'instances:create_instance_select_type' compute.id %}"
class="btn btn-success btn-header float-right"> class="btn btn-success btn-header float-right">
{% icon 'plus' %} {% icon 'plus' %}
@ -18,7 +18,7 @@
<input id="filter" class="form-control" type="text" placeholder="{% trans 'Search' %}"> <input id="filter" class="form-control" type="text" placeholder="{% trans 'Search' %}">
</div> </div>
{% endif %} {% endif %}
{% endblock page_header_extra %} {% endblock page_heading_extra %}
{% block content %} {% block content %}
<div class="row"> <div class="row">

View file

@ -12,7 +12,6 @@
<h3 class="page-header">{% trans "Computes" %}</h3> <h3 class="page-header">{% trans "Computes" %}</h3>
</div> </div>
</div> </div>
{% include 'errors_block.html' %}
<div class="row"> <div class="row">
{% if not computes %} {% if not computes %}
<div class="col-lg-12"> <div class="col-lg-12">

View file

@ -1,42 +1,42 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load i18n %} {% load i18n %}
{% load staticfiles %} {% load staticfiles %}
{% load icons %}
{% block title %}{% trans "Overview" %} - {{ compute.name }}{% endblock %} {% block title %}{% trans "Overview" %} - {{ compute.name }}{% endblock %}
{% block page_heading %}{{ compute.name }}{% endblock page_heading %}
{% block content %} {% block content %}
<!-- Page Heading -->
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<h2 class="page-header">{{ compute.name }}</h2>
<nav aria-label="breadcrumb"> <nav aria-label="breadcrumb">
<ol class="breadcrumb bg-light shadow-sm"> <ol class="breadcrumb bg-light shadow-sm">
<li class="breadcrumb-item active"> <li class="breadcrumb-item">
<span class="font-weight-bold"><i class="fa fa-dashboard"></i> {% trans "Overview" %}</span> <span class="font-weight-bold">{% icon 'dashboard' %} {% trans "Overview" %}</span>
</li> </li>
<li class="breadcrumb-item"> <li class="breadcrumb-item">
<a href="{% url 'instances' compute.id %}"><i class="fa fa-server"></i> {% trans "Instances" %}</a> <a href="{% url 'instances' compute.id %}">{% icon 'server' %} {% trans "Instances" %}</a>
</li> </li>
<li class="breadcrumb-item"> <li class="breadcrumb-item">
<a href="{% url 'storages' compute.id %}"><i class="fa fa-hdd-o"></i> {% trans "Storages" %}</a> <a href="{% url 'storages' compute.id %}">{% icon 'hdd-o' %} {% trans "Storages" %}</a>
</li> </li>
<li class="breadcrumb-item"> <li class="breadcrumb-item">
<a href="{% url 'networks' compute.id %}"><i class="fa fa-sitemap"></i> {% trans "Networks" %}</a> <a href="{% url 'networks' compute.id %}">{% icon 'sitemap' %} {% trans "Networks" %}</a>
</li> </li>
<li class="breadcrumb-item"> <li class="breadcrumb-item">
<a href="{% url 'interfaces' compute.id %}"><i class="fa fa-wifi"></i> {% trans "Interfaces" %}</a> <a href="{% url 'interfaces' compute.id %}">{% icon 'wifi' %} {% trans "Interfaces" %}</a>
</li> </li>
<li class="breadcrumb-item"> <li class="breadcrumb-item">
<a href="{% url 'nwfilters' compute.id %}"><i class="fa fa-filter"></i> {% trans "NWFilters" %}</a> <a href="{% url 'nwfilters' compute.id %}">{% icon 'filter' %} {% trans "NWFilters" %}</a>
</li> </li>
<li class="breadcrumb-item"> <li class="breadcrumb-item">
<a href="{% url 'secrets' compute.id %}"><i class="fa fa-key"></i> {% trans "Secrets" %}</a> <a href="{% url 'secrets' compute.id %}">{% icon 'key' %} {% trans "Secrets" %}</a>
</li> </li>
</ol> </ol>
</nav> </nav>
</div> </div>
</div> </div>
<!-- /.row -->
{% include 'errors_block.html' %}
<div class="shadow-sm"> <div class="shadow-sm">
<h3 class="page-header">{% trans "Basic details" %}</h3> <h3 class="page-header">{% trans "Basic details" %}</h3>

View file

@ -1,6 +1,6 @@
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
import re import re
have_symbol = re.compile('[^a-zA-Z0-9._-]+') have_symbol = re.compile('[^a-zA-Z0-9._-]+')

View file

@ -1,7 +1,6 @@
<domain type="kvm"> <domain type="kvm">
<name>test-vm</name> <name>test-vm</name>
<uuid>1bd3c1f2-dd12-4b8d-a298-dff387cb9f93</uuid> <uuid>1bd3c1f2-dd12-4b8d-a298-dff387cb9f93</uuid>
<description>None</description>
<memory unit="KiB">131072</memory> <memory unit="KiB">131072</memory>
<currentMemory unit="KiB">131072</currentMemory> <currentMemory unit="KiB">131072</currentMemory>
<vcpu placement="static">1</vcpu> <vcpu placement="static">1</vcpu>

View file

@ -6,38 +6,41 @@ def migrate_can_clone_instances(sender, **kwargs):
''' '''
Migrate can clone instances user attribute to permission Migrate can clone instances user attribute to permission
''' '''
from django.conf import settings from django.contrib.auth.models import Permission, User
from django.contrib.auth.models import User, Permission
from accounts.models import UserAttributes
plan = kwargs['plan'] plan = kwargs.get('plan', [])
for migration, rolled_back in plan: for migration, rolled_back in plan:
if migration.app_label == 'instances' and migration.name == '0002_permissionset' and not rolled_back: if migration.app_label == 'instances' and migration.name == '0002_permissionset' and not rolled_back:
users = User.objects.all() users = User.objects.all()
permission = Permission.objects.get(codename='clone_instances') permission = Permission.objects.get(codename='clone_instances')
print('\033[92mMigrating can_clone_instaces user attribute to permission\033[0m') print('\033[1m* \033[92mMigrating can_clone_instaces user attribute to permission\033[0m')
for user in users: for user in users:
if user.userattributes: if user.userattributes:
if user.userattributes.can_clone_instances: if user.userattributes.can_clone_instances:
user.user_permissions.add(permission) user.user_permissions.add(permission)
break break
def apply_passwordless_console(sender, **kwargs): def apply_passwordless_console(sender, **kwargs):
''' '''
Apply new passwordless_console permission for all users Apply new passwordless_console permission for all users
''' '''
from django.conf import settings from django.contrib.auth.models import Permission
from django.contrib.auth.models import User, Permission from django.contrib.auth import get_user_model
User = get_user_model()
plan = kwargs.get('plan', [])
for migration, rolled_back in plan:
if migration.app_label == 'instances' and migration.name == '0009_auto_20200717_0524' and not rolled_back:
print('\033[1m* \033[92mApplying permission passwordless_console for all users\033[0m')
users = User.objects.all()
permission = Permission.objects.get(codename='passwordless_console')
for user in users:
user.user_permissions.add(permission)
print('\033[92mApplying permission passwordless_console for all users\033[0m')
users = User.objects.all()
permission = Permission.objects.get(codename='passwordless_console')
for user in users:
user.user_permissions.add(permission)
class InstancesConfig(AppConfig): class InstancesConfig(AppConfig):
name = 'instances' name = 'instances'
verbose_name = 'instances' verbose_name = 'Instances'
def ready(self): def ready(self):
post_migrate.connect(migrate_can_clone_instances, sender=self) post_migrate.connect(migrate_can_clone_instances, sender=self)

View file

@ -1,7 +1,7 @@
import re import re
from django import forms from django import forms
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from appsettings.models import AppSettings from appsettings.models import AppSettings
from webvirtcloud.settings import QEMU_CONSOLE_LISTEN_ADDRESSES, QEMU_KEYMAPS from webvirtcloud.settings import QEMU_CONSOLE_LISTEN_ADDRESSES, QEMU_KEYMAPS
@ -61,6 +61,4 @@ class NewVMForm(forms.Form):
have_symbol = re.match('^[a-zA-Z0-9._-]+$', name) have_symbol = re.match('^[a-zA-Z0-9._-]+$', name)
if not have_symbol: if not have_symbol:
raise forms.ValidationError(_('The name of the virtual machine must not contain any special characters')) raise forms.ValidationError(_('The name of the virtual machine must not contain any special characters'))
elif len(name) > 64:
raise forms.ValidationError(_('The name of the virtual machine must not exceed 20 characters'))
return name return name

View file

@ -1,6 +1,6 @@
from django.db import models from django.db import models
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from libvirt import VIR_DOMAIN_XML_SECURE from libvirt import VIR_DOMAIN_XML_SECURE
from computes.models import Compute from computes.models import Compute

View file

@ -6,16 +6,16 @@
{% block style %} {% block style %}
<link rel="stylesheet" href="{% static "css/sortable-theme-bootstrap.css" %}" /> <link rel="stylesheet" href="{% static "css/sortable-theme-bootstrap.css" %}" />
{% endblock %} {% endblock %}
{% block page_header %}{% trans "Instances" %}{% endblock page_header %} {% block page_heading %}{% trans "Instances" %}{% endblock page_heading %}
{% block page_header_extra %} {% block page_heading_extra %}
{% if request.user.is_superuser %} {% if request.user.is_superuser %}
{% include 'create_inst_block.html' %} {% include 'create_inst_block.html' %}
{% endif %} {% endif %}
<div class="float-right search"> <div class="float-right search">
<input id="filter" class="form-control" type="text" placeholder="{% trans 'Search' %}"> <input id="filter" class="form-control" type="text" placeholder="{% trans 'Search' %}">
</div> </div>
{% endblock page_header_extra %} {% endblock page_heading_extra %}
{% block content %} {% block content %}
{% for compute in computes %} {% for compute in computes %}

View file

@ -1,21 +1,15 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load i18n %} {% load i18n %}
{% load staticfiles %} {% load staticfiles %}
{% block title %}{% trans "Create new instance" %} - {% trans "Select Type" %}{% endblock %} {% block title %}{% trans "Create new instance" %} - {% trans "Select Type" %}{% endblock %}
{% block content %} {% block page_heading%}
<!-- Page Heading --> {% blocktrans with host=compute.name %}New instance on {{ host }} {% endblocktrans %}
<div class="row"> {% endblock page_heading %}
<div class="col-lg-12">
<h3 class="page-header">
{% blocktrans with host=compute.name %}New instance on {{ host }} {% endblocktrans %}
</h3>
</div>
</div>
<!-- /.row -->
{% include 'errors_block.html' %}
{% include 'pleasewaitdialog.html' %}
{% block content %}
{% include 'pleasewaitdialog.html' %}
{% if form.errors %} {% if form.errors %}
{% for field in form %} {% for field in form %}

View file

@ -3,22 +3,17 @@
{% load staticfiles %} {% load staticfiles %}
{% load icons %} {% load icons %}
{% block title %}{% trans "Create new instance" %}{% endblock %} {% block title %}{% trans "Create new instance" %}{% endblock %}
{% block style %} {% block style %}
<link href="{% static "css/bootstrap-multiselect.css" %}" rel="stylesheet"> <link href="{% static "css/bootstrap-multiselect.css" %}" rel="stylesheet">
{% endblock %} {% endblock %}
{% block content %}
<!-- Page Heading -->
<div class="row">
<div class="col-lg-12">
<h3 class="page-header">
{% blocktrans with host=compute.name %}New instance on {{ host }} {% endblocktrans %}</h3>
</h3>
</div>
</div>
<!-- /.row -->
{% include 'errors_block.html' %}
{% include 'pleasewaitdialog.html' %}
{% block page_heading %}
{% blocktrans with host=compute.name %}New instance on {{ host }} {% endblocktrans %}
{% endblock page_heading %}
{% block content %}
{% include 'pleasewaitdialog.html' %}
{% if form.errors %} {% if form.errors %}
{% for field in form %} {% for field in form %}

View file

@ -1,14 +1,16 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load i18n %} {% load i18n %}
{% block title %}{% trans "Instance" %} - {{ instance.name }}{% endblock %} {% block title %}{% trans "Instance" %} - {{ instance.name }}{% endblock %}
{% block page_heading %}
{{ instance.name }}{% if instance.title %} ({{ instance.title }}){% endif %}
{% endblock page_heading %}
{% block content %} {% block content %}
{% include 'pleasewaitdialog.html' %} {% include 'pleasewaitdialog.html' %}
<!-- Page Heading -->
<div> <div>
<div>
<h3>{{ instance.name }}{% if instance.title %}&nbsp;({{ instance.title }}){% endif %}</h3>
</div>
<div> <div>
{% if instance.status == 5 %} {% if instance.status == 5 %}
<span class="badge badge-danger">{% trans "Off" %}</span> <span class="badge badge-danger">{% trans "Off" %}</span>
@ -62,8 +64,6 @@
<hr> <hr>
</div> </div>
{% include 'errors_block.html' %}
<div class="row" id="max-width-page"> <div class="row" id="max-width-page">
<div class="container"> <div class="container">
<div role="tabpanel"> <div role="tabpanel">

View file

@ -4,9 +4,9 @@
{% trans "Confirm Destroy" %} {% trans "Confirm Destroy" %}
{% endblock title %} {% endblock title %}
{% block page_header %} {% block page_heading %}
{% trans "Destroy instance" %} {{ instance }} {% trans "Destroy instance" %} {{ instance }}
{% endblock page_header %} {% endblock page_heading %}
{% block content %} {% block content %}
{% if request.user.is_superuser or userinstance.is_delete %} {% if request.user.is_superuser or userinstance.is_delete %}

File diff suppressed because it is too large Load diff

View file

@ -65,5 +65,5 @@ urlpatterns = [
path('guess_clone_name/', views.guess_clone_name, name='guess_clone_name'), path('guess_clone_name/', views.guess_clone_name, name='guess_clone_name'),
path('random_mac_address/', views.random_mac_address, name='random_mac_address'), path('random_mac_address/', views.random_mac_address, name='random_mac_address'),
path('check_instance/<vname>/', views.check_instance, name='check_instance'), path('check_instance/<vname>/', views.check_instance, name='check_instance'),
path('sshkeys/<vname>/', views.sshkeys, name='sshkeys'), path('<int:pk>/sshkeys/', views.sshkeys, name='sshkeys'),
] ]

View file

@ -1,40 +1,17 @@
import os import os
import random import random
import string import string
from collections import OrderedDict
from django.conf import settings
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _
from accounts.models import UserInstance from accounts.models import UserInstance
from appsettings.settings import app_settings from appsettings.settings import app_settings
from logs.views import addlogmsg from django.conf import settings
from django.utils.translation import gettext_lazy as _
from vrtManager.connection import connection_manager from vrtManager.connection import connection_manager
from vrtManager.hostdetails import wvmHostDetails
from vrtManager.instance import wvmInstance, wvmInstances from vrtManager.instance import wvmInstance, wvmInstances
from .models import Instance from .models import Instance
def filesizefstr(size_str):
if size_str == '':
return 0
size_str = size_str.upper().replace("B", "")
if size_str[-1] == 'K':
return int(float(size_str[:-1])) << 10
elif size_str[-1] == 'M':
return int(float(size_str[:-1])) << 20
elif size_str[-1] == 'G':
return int(float(size_str[:-1])) << 30
elif size_str[-1] == 'T':
return int(float(size_str[:-1])) << 40
elif size_str[-1] == 'P':
return int(float(size_str[:-1])) << 50
else:
return int(float(size_str))
def get_clone_free_names(size=10): def get_clone_free_names(size=10):
prefix = app_settings.CLONE_INSTANCE_DEFAULT_PREFIX prefix = app_settings.CLONE_INSTANCE_DEFAULT_PREFIX
free_names = [] free_names = []
@ -186,36 +163,6 @@ def migrate_instance(
instance.save() instance.save()
def get_hosts_status(computes):
"""
Function return all hosts all vds on host
"""
compute_data = []
for compute in computes:
compute_data.append({
'id': compute.id,
'name': compute.name,
'hostname': compute.hostname,
'status': connection_manager.host_is_up(compute.type, compute.hostname),
'type': compute.type,
'login': compute.login,
'password': compute.password,
'details': compute.details,
})
return compute_data
def get_userinstances_info(instance):
info = {}
uis = UserInstance.objects.filter(instance=instance)
info['count'] = uis.count()
if info['count'] > 0:
info['first_user'] = uis[0]
else:
info['first_user'] = None
return info
def refr(compute): def refr(compute):
if compute.status is True: if compute.status is True:
domains = compute.proxy.wvm.listAllDomains() domains = compute.proxy.wvm.listAllDomains()
@ -229,83 +176,6 @@ def refr(compute):
Instance(compute=compute, name=domain.name(), uuid=domain.UUIDString()).save() Instance(compute=compute, name=domain.name(), uuid=domain.UUIDString()).save()
def refresh_instance_database(comp, inst_name, info, all_host_vms, user):
# Multiple Instance Name Check
instances = Instance.objects.filter(name=inst_name)
if instances.count() > 1:
for i in instances:
user_instances_count = UserInstance.objects.filter(instance=i).count()
if user_instances_count == 0:
addlogmsg(user.username, i.name, _("Deleting due to multiple(Instance Name) records."))
i.delete()
# Multiple UUID Check
instances = Instance.objects.filter(uuid=info['uuid'])
if instances.count() > 1:
for i in instances:
if i.name != inst_name:
addlogmsg(user.username, i.name, _("Deleting due to multiple(UUID) records."))
i.delete()
try:
inst_on_db = Instance.objects.get(compute_id=comp["id"], name=inst_name)
if inst_on_db.uuid != info['uuid']:
inst_on_db.save()
all_host_vms[comp["id"], comp["name"], comp["status"], comp["cpu"], comp["mem_size"],
comp["mem_perc"]][inst_name]['is_template'] = inst_on_db.is_template
all_host_vms[comp["id"], comp["name"], comp["status"], comp["cpu"], comp["mem_size"],
comp["mem_perc"]][inst_name]['userinstances'] = get_userinstances_info(inst_on_db)
except Instance.DoesNotExist:
inst_on_db = Instance(compute_id=comp["id"], name=inst_name, uuid=info['uuid'])
inst_on_db.save()
def get_user_instances(user):
all_user_vms = {}
user_instances = UserInstance.objects.filter(user=user)
for usr_inst in user_instances:
if connection_manager.host_is_up(usr_inst.instance.compute.type, usr_inst.instance.compute.hostname):
conn = wvmHostDetails(
usr_inst.instance.compute.hostname,
usr_inst.instance.compute.login,
usr_inst.instance.compute.password,
usr_inst.instance.compute.type,
)
all_user_vms[usr_inst] = conn.get_user_instances(usr_inst.instance.name)
all_user_vms[usr_inst].update({'compute_id': usr_inst.instance.compute.id})
return all_user_vms
def get_host_instances(compute):
all_host_vms = OrderedDict()
# if compute.status:
comp_node_info = compute.proxy.get_node_info()
comp_mem = compute.proxy.get_memory_usage()
comp_instances = compute.proxy.get_host_instances(True)
# if comp_instances:
comp_info = {
"id": compute.id,
"name": compute.name,
"status": compute.status,
"cpu": comp_node_info[3],
"mem_size": comp_node_info[2],
"mem_perc": comp_mem['percent'],
}
# refr(compute)
all_host_vms[comp_info["id"], comp_info["name"], comp_info["status"], comp_info["cpu"], comp_info["mem_size"],
comp_info["mem_perc"]] = comp_instances
for vm, info in comp_instances.items():
# TODO: Delete this function completely
refresh_instance_database(comp_info, vm, info, all_host_vms, User.objects.get(pk=1))
# else:
# raise libvirtError(_(f"Problem occurred with host: {compute.name} - {status}"))
return all_host_vms
def get_dhcp_mac_address(vname): def get_dhcp_mac_address(vname):
dhcp_file = settings.BASE_DIR + '/dhcpd.conf' dhcp_file = settings.BASE_DIR + '/dhcpd.conf'
mac = '' mac = ''
@ -342,20 +212,3 @@ def get_clone_disk_name(disk, prefix, clone_name=''):
else: else:
image = f"{disk['image']}-clone" image = f"{disk['image']}-clone"
return image return image
# TODO: this function is not used
def _get_clone_disks(disks, vname=''):
clone_disks = []
for disk in disks:
new_image = get_clone_disk_name(disk, vname)
if not new_image:
continue
new_disk = {
'dev': disk['dev'],
'storage': disk['storage'],
'image': new_image,
'format': disk['format'],
}
clone_disks.append(new_disk)
return clone_disks

View file

@ -18,7 +18,7 @@ from django.contrib.auth.models import User
from django.http import Http404, HttpResponse, JsonResponse from django.http import Http404, HttpResponse, JsonResponse
from django.shortcuts import get_object_or_404, redirect, render from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse from django.urls import reverse
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from libvirt import (VIR_DOMAIN_UNDEFINE_KEEP_NVRAM, VIR_DOMAIN_UNDEFINE_NVRAM, libvirtError) from libvirt import (VIR_DOMAIN_UNDEFINE_KEEP_NVRAM, VIR_DOMAIN_UNDEFINE_NVRAM, libvirtError)
from logs.views import addlogmsg from logs.views import addlogmsg
from vrtManager import util from vrtManager import util
@ -51,7 +51,7 @@ def index(request):
def instance(request, pk): def instance(request, pk):
instance: Instance = get_object_or_404(Instance, pk=pk) instance: Instance = get_instance(request.user, pk)
compute: Compute = instance.compute compute: Compute = instance.compute
computes = Compute.objects.all().order_by('name') computes = Compute.objects.all().order_by('name')
computes_count = computes.count() computes_count = computes.count()
@ -59,7 +59,6 @@ def instance(request, pk):
publickeys = UserSSHKey.objects.filter(user_id=request.user.id) publickeys = UserSSHKey.objects.filter(user_id=request.user.id)
keymaps = settings.QEMU_KEYMAPS keymaps = settings.QEMU_KEYMAPS
console_types = AppSettings.objects.get(key="QEMU_CONSOLE_DEFAULT_TYPE").choices_as_list() console_types = AppSettings.objects.get(key="QEMU_CONSOLE_DEFAULT_TYPE").choices_as_list()
#
console_form = ConsoleForm( console_form = ConsoleForm(
initial={ initial={
'type': instance.console_type, 'type': instance.console_type,
@ -67,7 +66,6 @@ def instance(request, pk):
'password': instance.console_passwd, 'password': instance.console_passwd,
'keymap': instance.console_keymap, 'keymap': instance.console_keymap,
}) })
#
console_listen_addresses = settings.QEMU_CONSOLE_LISTEN_ADDRESSES console_listen_addresses = settings.QEMU_CONSOLE_LISTEN_ADDRESSES
bottom_bar = app_settings.VIEW_INSTANCE_DETAIL_BOTTOM_BAR bottom_bar = app_settings.VIEW_INSTANCE_DETAIL_BOTTOM_BAR
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
@ -78,15 +76,6 @@ def instance(request, pk):
except UserInstance.DoesNotExist: except UserInstance.DoesNotExist:
userinstance = None userinstance = None
if not request.user.is_superuser:
if not userinstance:
return redirect(reverse('index'))
if len(instance.media) != 0:
media_iso = sorted(instance.proxy.get_iso_media())
else:
media_iso = []
memory_range = [256, 512, 768, 1024, 2048, 3072, 4096, 6144, 8192, 16384] memory_range = [256, 512, 768, 1024, 2048, 3072, 4096, 6144, 8192, 16384]
if instance.memory not in memory_range: if instance.memory not in memory_range:
insort(memory_range, instance.memory) insort(memory_range, instance.memory)
@ -127,18 +116,11 @@ def instance(request, pk):
vcpu_host = len(instance.vcpu_range) vcpu_host = len(instance.vcpu_range)
memory_host = instance.proxy.get_max_memory() memory_host = instance.proxy.get_max_memory()
bus_host = instance.proxy.get_disk_bus_types(instance.arch, instance.machine) bus_host = instance.proxy.get_disk_bus_types(instance.arch, instance.machine)
# videos_host = instance.proxy.get_video_models(instance.arch, instance.machine)
networks_host = sorted(instance.proxy.get_networks()) networks_host = sorted(instance.proxy.get_networks())
nwfilters_host = instance.proxy.get_nwfilters() nwfilters_host = instance.proxy.get_nwfilters()
storages_host = sorted(instance.proxy.get_storages(True)) storages_host = sorted(instance.proxy.get_storages(True))
net_models_host = instance.proxy.get_network_models() net_models_host = instance.proxy.get_network_models()
try:
interfaces_host = sorted(instance.proxy.get_ifaces())
except Exception as e:
addlogmsg(request.user.username, instance.name, e)
messages.error(request, e)
return render(request, 'instance.html', locals()) return render(request, 'instance.html', locals())
@ -210,18 +192,18 @@ def check_instance(request, vname):
data = {'vname': vname, 'exists': False} data = {'vname': vname, 'exists': False}
if instance: if instance:
data['exists'] = True data['exists'] = True
return HttpResponse(json.dumps(data)) return JsonResponse(data)
def sshkeys(request, vname): def sshkeys(request, pk):
""" """
:param request: :param request:
:param vname: :param vname:
:return: :return:
""" """
instance = get_instance(request.user, pk)
instance_keys = [] instance_keys = []
userinstances = UserInstance.objects.filter(instance__name=vname) userinstances = UserInstance.objects.filter(instance=instance)
for ui in userinstances: for ui in userinstances:
keys = UserSSHKey.objects.filter(user=ui.user) keys = UserSSHKey.objects.filter(user=ui.user)
@ -239,7 +221,7 @@ def get_instance(user, pk):
''' '''
Check that instance is available for user, if not raise 404 Check that instance is available for user, if not raise 404
''' '''
instance = Instance.objects.get(pk=pk) instance = get_object_or_404(Instance, pk=pk)
user_instances = user.userinstance_set.all().values_list('instance', flat=True) user_instances = user.userinstance_set.all().values_list('instance', flat=True)
if user.is_superuser or instance.id in user_instances: if user.is_superuser or instance.id in user_instances:
@ -498,7 +480,6 @@ def resize_disk(request, pk):
if request.user.is_superuser or request.user.is_staff or userinstance.is_change: if request.user.is_superuser or request.user.is_staff or userinstance.is_change:
disks_new = list() disks_new = list()
for disk in disks: for disk in disks:
# input_disk_size = utils.filesizefstr(request.POST.get('disk_size_' + disk['dev'], ''))
input_disk_size = int(request.POST.get('disk_size_' + disk['dev'], '0')) * 1073741824 input_disk_size = int(request.POST.get('disk_size_' + disk['dev'], '0')) * 1073741824
if input_disk_size > disk['size'] + (64 << 20): if input_disk_size > disk['size'] + (64 << 20):
disk['size_new'] = input_disk_size disk['size_new'] = input_disk_size
@ -1005,7 +986,7 @@ def add_owner(request, pk):
if app_settings.ALLOW_INSTANCE_MULTIPLE_OWNER == 'False': if app_settings.ALLOW_INSTANCE_MULTIPLE_OWNER == 'False':
check_inst = UserInstance.objects.filter(instance=instance).count() check_inst = UserInstance.objects.filter(instance=instance).count()
if check_inst > 1: if check_inst > 0:
messages.error(request, _("Only one owner is allowed and the one already added")) messages.error(request, _("Only one owner is allowed and the one already added"))
else: else:
add_user_inst = UserInstance(instance=instance, user_id=user_id) add_user_inst = UserInstance(instance=instance, user_id=user_id)
@ -1027,7 +1008,7 @@ def del_owner(request, pk):
return redirect(request.META.get('HTTP_REFERER') + '#users') return redirect(request.META.get('HTTP_REFERER') + '#users')
@permission_required('instances.clone_instances') @permission_required('instances.clone_instances', raise_exception=True)
def clone(request, pk): def clone(request, pk):
instance = get_instance(request.user, pk) instance = get_instance(request.user, pk)

View file

@ -1,6 +1,6 @@
import re import re
from django import forms from django import forms
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
class AddInterface(forms.Form): class AddInterface(forms.Form):

View file

@ -1,11 +1,13 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load i18n %} {% load i18n %}
{% block title %}{% trans "Interface" %} - {{ iface }}{% endblock %} {% block title %}{% trans "Interface" %} - {{ iface }}{% endblock %}
{% block page_heading %}{% trans "Interface" %}: {{ iface }}{% endblock page_heading %}
{% block content %} {% block content %}
<!-- Page Heading -->
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<h2 class="page-header">{% trans "Interface" %}: {{ iface }}</h2>
<ol class="breadcrumb bg-light shadow-sm"> <ol class="breadcrumb bg-light shadow-sm">
<li class="breadcrumb-item active"> <li class="breadcrumb-item active">
<a href="{% url 'overview' compute.id %}"><i class="fa fa-dashboard"></i> {% trans "Overview" %}</a> <a href="{% url 'overview' compute.id %}"><i class="fa fa-dashboard"></i> {% trans "Overview" %}</a>
@ -31,9 +33,6 @@
</ol> </ol>
</div> </div>
</div> </div>
<!-- /.row -->
{% include 'errors_block.html' %}
<div class="row"> <div class="row">
<dl class="ml-3 row"> <dl class="ml-3 row">

View file

@ -1,13 +1,16 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load i18n %} {% load i18n %}
{% load staticfiles %} {% load staticfiles %}
{% block title %}{% trans "Interfaces" %} - {{ compute.name }}{% endblock %} {% block title %}{% trans "Interfaces" %} - {{ compute.name }}{% endblock %}
{% block page_heading%}{% trans "Interfaces" %} - {{ compute.name }}{% endblock page_heading %}
{% block page_heading_extra %}{% include 'create_iface_block.html' %}{% endblock page_heading_extra %}
{% block content %} {% block content %}
<!-- Page Heading -->
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
{% include 'create_iface_block.html' %}
<h2 class="page-header">{{ compute.name }}</h2>
<nav aria-label="breadcrumb"> <nav aria-label="breadcrumb">
<ol class="breadcrumb bg-light shadow-sm"> <ol class="breadcrumb bg-light shadow-sm">
<li class="breadcrumb-item active"> <li class="breadcrumb-item active">
@ -35,9 +38,6 @@
</nav> </nav>
</div> </div>
</div> </div>
<!-- /.row -->
{% include 'errors_block.html' %}
<div class="row"> <div class="row">
{% if not ifaces_all %} {% if not ifaces_all %}

View file

@ -1,3 +1,4 @@
from django.contrib import messages
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.urls import reverse from django.urls import reverse
@ -17,7 +18,6 @@ def interfaces(request, compute_id):
""" """
ifaces_all = [] ifaces_all = []
error_messages = []
compute = get_object_or_404(Compute, pk=compute_id) compute = get_object_or_404(Compute, pk=compute_id)
try: try:
@ -42,10 +42,10 @@ def interfaces(request, compute_id):
return HttpResponseRedirect(request.get_full_path()) return HttpResponseRedirect(request.get_full_path())
else: else:
for msg_err in form.errors.values(): for msg_err in form.errors.values():
error_messages.append(msg_err.as_text()) messages.error(request, msg_err.as_text())
conn.close() conn.close()
except libvirtError as lib_err: except libvirtError as lib_err:
error_messages.append(lib_err) messages.error(request, lib_err)
return render(request, 'interfaces.html', locals()) return render(request, 'interfaces.html', locals())
@ -60,7 +60,6 @@ def interface(request, compute_id, iface):
""" """
ifaces_all = [] ifaces_all = []
error_messages = []
compute = get_object_or_404(Compute, pk=compute_id) compute = get_object_or_404(Compute, pk=compute_id)
try: try:
@ -88,6 +87,6 @@ def interface(request, compute_id, iface):
return HttpResponseRedirect(reverse('interfaces', args=[compute_id])) return HttpResponseRedirect(reverse('interfaces', args=[compute_id]))
conn.close() conn.close()
except libvirtError as lib_err: except libvirtError as lib_err:
error_messages.append(lib_err) messages.error(request, lib_err)
return render(request, 'interface.html', locals()) return render(request, 'interface.html', locals())

View file

@ -1,5 +1,5 @@
from django.db.models import Model, CharField, DateTimeField from django.db.models import Model, CharField, DateTimeField
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
class Logs(Model): class Logs(Model):

View file

@ -1,12 +0,0 @@
<div class="center-block">
{% if page > 1 %}
<a href="{% url 'showlogspage' page|add:"-1" %}">&larr;</a>
{% else %}
&nbsp;
{% endif %}
{% if has_next_page %}
<a href="{% url 'showlogspage' page|add:"1" %}">&rarr;</a>
{% else %}
&nbsp;
{% endif %}
</div>

View file

@ -1,6 +1,6 @@
import re import re
from django import forms from django import forms
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
class AddNetPool(forms.Form): class AddNetPool(forms.Form):

View file

@ -1,13 +1,14 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load i18n %} {% load i18n %}
{% load staticfiles %} {% load staticfiles %}
{% block title %}{% trans "Network" %} - {{ pool }}{% endblock %} {% block title %}{% trans "Network" %} - {{ pool }}{% endblock %}
{% block page_heading %}{% trans "Network" %}: {{ pool }}{% endblock page_heading %}
{% block content %} {% block content %}
<!-- Page Heading -->
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<h2 class="page-header">{% trans "Network" %}: {{ pool }}</h2>
<ol class="breadcrumb bg-light shadow-sm"> <ol class="breadcrumb bg-light shadow-sm">
<li class="breadcrumb-item"> <li class="breadcrumb-item">
<a href="{% url 'overview' compute.id %}"><i class="fa fa-dashboard"></i> {% trans "Overview" %}</a> <a href="{% url 'overview' compute.id %}"><i class="fa fa-dashboard"></i> {% trans "Overview" %}</a>
@ -34,9 +35,6 @@
</div> </div>
</div> </div>
<!-- /.row -->
{% include 'errors_block.html' %}
<div class="row"> <div class="row">
<dl class="ml-3 row"> <dl class="ml-3 row">

View file

@ -1,14 +1,13 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load i18n %} {% load i18n %}
{% block title %}{% trans "Networks" %} - {{ compute.name }}{% endblock %}
{% block title %}{{ compute.name }} - {% trans "Networks" %}{% endblock %}
{% block page_heading %}{{ compute.name }} - {% trans "Networks" %}{% endblock page_heading %}
{% block page_heading_extra %}{% include 'create_net_block.html' %}{% endblock page_heading_extra %}
{% block content %} {% block content %}
<!-- Page Heading -->
<div class="row">
<div class="col-lg-12">
{% include 'create_net_block.html' %}
<h2 class="page-header">{{ compute.name }} - {% trans "Networks" %}</h2>
</div>
</div>
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<nav aria-label="breadcrumb"> <nav aria-label="breadcrumb">
@ -38,9 +37,6 @@
</nav> </nav>
</div> </div>
</div> </div>
<!-- /.row -->
{% include 'errors_block.html' %}
<div class="row"> <div class="row">
{% if not networks %} {% if not networks %}

View file

@ -2,7 +2,7 @@ from django.contrib import messages
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render from django.shortcuts import get_object_or_404, render
from django.urls import reverse from django.urls import reverse
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from libvirt import libvirtError from libvirt import libvirtError
from admin.decorators import superuser_only from admin.decorators import superuser_only
@ -19,8 +19,8 @@ def networks(request, compute_id):
:return: :return:
""" """
error_messages = []
compute = get_object_or_404(Compute, pk=compute_id) compute = get_object_or_404(Compute, pk=compute_id)
errors = False
try: try:
conn = wvmNetworks( conn = wvmNetworks(
@ -41,9 +41,11 @@ def networks(request, compute_id):
data = form.cleaned_data data = form.cleaned_data
if data['name'] in networks: if data['name'] in networks:
msg = _("Network pool name already in use") msg = _("Network pool name already in use")
error_messages.append(msg) messages.error(request, msg)
errors = True
if data['forward'] in ['bridge', 'macvtap'] and data['bridge_name'] == '': if data['forward'] in ['bridge', 'macvtap'] and data['bridge_name'] == '':
error_messages.append(_('Please enter bridge/dev name')) messages.error(request, _('Please enter bridge/dev name'))
errors = True
if data['subnet']: if data['subnet']:
ipv4 = True ipv4 = True
gateway4, netmask4, dhcp4 = network_size(data['subnet'], data['dhcp4']) gateway4, netmask4, dhcp4 = network_size(data['subnet'], data['dhcp4'])
@ -51,8 +53,9 @@ def networks(request, compute_id):
ipv6 = True ipv6 = True
gateway6, prefix6, dhcp6 = network_size(data['subnet6'], data['dhcp6']) gateway6, prefix6, dhcp6 = network_size(data['subnet6'], data['dhcp6'])
if prefix6 != '64': if prefix6 != '64':
error_messages.append(_('For libvirt, the IPv6 network prefix must be /64')) messages.error(request, _('For libvirt, the IPv6 network prefix must be /64'))
if not error_messages: errors = True
if not errors:
conn.create_network( conn.create_network(
data['name'], data['name'],
data['forward'], data['forward'],
@ -71,10 +74,10 @@ def networks(request, compute_id):
return HttpResponseRedirect(reverse('network', args=[compute_id, data['name']])) return HttpResponseRedirect(reverse('network', args=[compute_id, data['name']]))
else: else:
for msg_err in form.errors.values(): for msg_err in form.errors.values():
error_messages.append(msg_err.as_text()) messages.error(request, msg_err.as_text())
conn.close() conn.close()
except libvirtError as lib_err: except libvirtError as lib_err:
error_messages.append(lib_err) messages.error(request, lib_err)
return render(request, 'networks.html', locals()) return render(request, 'networks.html', locals())
@ -88,7 +91,6 @@ def network(request, compute_id, pool):
:return: :return:
""" """
error_messages = []
compute = get_object_or_404(Compute, pk=compute_id) compute = get_object_or_404(Compute, pk=compute_id)
try: try:
@ -125,7 +127,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) messages.error(request, lib_err)
return HttpResponseRedirect(reverse('networks', args=compute_id)) return HttpResponseRedirect(reverse('networks', args=compute_id))
if request.method == 'POST': if request.method == 'POST':
@ -134,31 +136,31 @@ def network(request, compute_id, pool):
conn.start() conn.start()
return HttpResponseRedirect(request.get_full_path()) return HttpResponseRedirect(request.get_full_path())
except libvirtError as lib_err: except libvirtError as lib_err:
error_messages.append(lib_err) messages.error(request, lib_err)
if 'stop' in request.POST: if 'stop' in request.POST:
try: try:
conn.stop() conn.stop()
return HttpResponseRedirect(request.get_full_path()) return HttpResponseRedirect(request.get_full_path())
except libvirtError as lib_err: except libvirtError as lib_err:
error_messages.append(lib_err) messages.error(request, lib_err)
if 'delete' in request.POST: if 'delete' in request.POST:
try: try:
conn.delete() conn.delete()
return HttpResponseRedirect(reverse('networks', args=[compute_id])) return HttpResponseRedirect(reverse('networks', args=[compute_id]))
except libvirtError as lib_err: except libvirtError as lib_err:
error_messages.append(lib_err) messages.error(request, lib_err)
if 'set_autostart' in request.POST: if 'set_autostart' in request.POST:
try: try:
conn.set_autostart(1) conn.set_autostart(1)
return HttpResponseRedirect(request.get_full_path()) return HttpResponseRedirect(request.get_full_path())
except libvirtError as lib_err: except libvirtError as lib_err:
error_messages.append(lib_err) messages.error(request, lib_err)
if 'unset_autostart' in request.POST: if 'unset_autostart' in request.POST:
try: try:
conn.set_autostart(0) conn.set_autostart(0)
return HttpResponseRedirect(request.get_full_path()) return HttpResponseRedirect(request.get_full_path())
except libvirtError as lib_err: except libvirtError as lib_err:
error_messages.append(lib_err) messages.error(request, lib_err)
if 'modify_fixed_address' in request.POST: if 'modify_fixed_address' in request.POST:
name = request.POST.get('name', '') name = request.POST.get('name', '')
address = request.POST.get('address', '') address = request.POST.get('address', '')
@ -174,9 +176,9 @@ def network(request, compute_id, pool):
messages.success(request, _(f"{family.upper()} Fixed Address Operation Completed.")) messages.success(request, _(f"{family.upper()} Fixed Address Operation Completed."))
return HttpResponseRedirect(request.get_full_path()) return HttpResponseRedirect(request.get_full_path())
except libvirtError as lib_err: except libvirtError as lib_err:
error_messages.append(lib_err) messages.error(request, lib_err)
except ValueError as val_err: except ValueError as val_err:
error_messages.append(val_err) messages.error(request, val_err)
if 'delete_fixed_address' in request.POST: if 'delete_fixed_address' in request.POST:
ip = request.POST.get('address', '') ip = request.POST.get('address', '')
family = request.POST.get('family', 'ipv4') family = request.POST.get('family', 'ipv4')
@ -192,7 +194,7 @@ def network(request, compute_id, pool):
messages.success(request, _(f"{family.upper()} DHCP Range is Changed.")) messages.success(request, _(f"{family.upper()} DHCP Range is Changed."))
return HttpResponseRedirect(request.get_full_path()) return HttpResponseRedirect(request.get_full_path())
except libvirtError as lib_err: except libvirtError as lib_err:
error_messages.append(lib_err) messages.error(request, lib_err)
if 'edit_network' in request.POST: if 'edit_network' in request.POST:
edit_xml = request.POST.get('edit_xml', '') edit_xml = request.POST.get('edit_xml', '')
if edit_xml: if edit_xml:

View file

@ -1,12 +1,14 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load i18n %} {% load i18n %}
{% load staticfiles %} {% load staticfiles %}
{% block title %}{% trans "NWFilters" %} - {{ compute.name }}{% endblock %}
{% block title %}{% trans "NWFilter" %}: {{ name }}{% endblock %}
{% block page_heading %}{% trans "NWFilter" %}: {{ name }}{% endblock page_heading %}
{% block content %} {% block content %}
<!-- Page Heading -->
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<h3 class="page-header">{% trans "NWFilter" %}: {{ name }}</h3>
<ol class="breadcrumb bg-light shadow-sm"> <ol class="breadcrumb bg-light shadow-sm">
<li class="breadcrumb-item active"> <li class="breadcrumb-item active">
<a href="{% url 'overview' compute.id %}"><i class="fa fa-dashboard"></i> {% trans "Overview" %}</a> <a href="{% url 'overview' compute.id %}"><i class="fa fa-dashboard"></i> {% trans "Overview" %}</a>
@ -32,11 +34,6 @@
</ol> </ol>
</div> </div>
</div> </div>
<!-- /.row -->
{% include 'errors_block.html' %}
{% include 'messages_block.html' %}
<dl class="ml-3 row"> <dl class="ml-3 row">
<dt class="col-4">{% trans "UUID" %}:</dt> <dt class="col-4">{% trans "UUID" %}:</dt>

View file

@ -1,18 +1,19 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load i18n %} {% load i18n %}
{% load staticfiles %} {% load staticfiles %}
{% block title %}{% trans "NWFilters" %} - {{ compute.name }}{% endblock %}
{% block title %}{{ compute.name }} - {% trans "NWFilters" %}{% endblock %}
{% block page_heading %}{{ compute.name }} - {% trans "NWFilters" %}{% endblock page_heading %}
{% block page_heading_extra %}
{% include 'create_nwfilter_block.html' %}
<div class="float-right search">
<input id="filter" class="form-control" type="text" placeholder="{% trans 'Search' %}">
</div>
{% endblock page_heading_extra %}
{% block content %} {% block content %}
<!-- Page Heading -->
<div class="row">
<div class="col-lg-12">
{% include 'create_nwfilter_block.html' %}
<div class="float-right search">
<input id="filter" class="form-control" type="text" placeholder="{% trans 'Search' %}">
</div>
<h2 class="page-header">{{ compute.name }} - {% trans "NWFilters" %}</h2>
</div>
</div>
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<nav aria-label="breadcrumb"> <nav aria-label="breadcrumb">
@ -42,10 +43,6 @@
</nav> </nav>
</div> </div>
</div> </div>
<!-- /.row -->
{% include 'errors_block.html' %}
{% include 'messages_block.html' %}
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">

View file

@ -1,11 +1,10 @@
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
from libvirt import libvirtError
from admin.decorators import superuser_only from admin.decorators import superuser_only
from computes.models import Compute from computes.models import Compute
from django.contrib import messages
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.utils.translation import gettext_lazy as _
from libvirt import libvirtError
from logs.views import addlogmsg from logs.views import addlogmsg
from vrtManager import util from vrtManager import util
from vrtManager.instance import wvmInstance, wvmInstances from vrtManager.instance import wvmInstance, wvmInstances
@ -20,7 +19,6 @@ def nwfilters(request, compute_id):
:return: :return:
""" """
error_messages = []
nwfilters_all = [] nwfilters_all = []
compute = get_object_or_404(Compute, pk=compute_id) compute = get_object_or_404(Compute, pk=compute_id)
@ -51,7 +49,7 @@ def nwfilters(request, compute_id):
conn.create_nwfilter(xml) conn.create_nwfilter(xml)
addlogmsg(request.user.username, compute.hostname, msg) addlogmsg(request.user.username, compute.hostname, msg)
except libvirtError as lib_err: except libvirtError as lib_err:
error_messages.append(lib_err) messages.error(request, lib_err)
addlogmsg(request.user.username, compute.hostname, lib_err) addlogmsg(request.user.username, compute.hostname, lib_err)
if 'del_nwfilter' in request.POST: if 'del_nwfilter' in request.POST:
@ -69,7 +67,7 @@ def nwfilters(request, compute_id):
if name in dom_filterrefs: if name in dom_filterrefs:
in_use = True in_use = True
msg = _(f"NWFilter is in use by {inst}. Cannot be deleted.") msg = _(f"NWFilter is in use by {inst}. Cannot be deleted.")
error_messages.append(msg) messages.error(request, msg)
addlogmsg(request.user.username, compute.hostname, msg) addlogmsg(request.user.username, compute.hostname, msg)
i_conn.close() i_conn.close()
break break
@ -93,16 +91,15 @@ def nwfilters(request, compute_id):
conn.close() conn.close()
except libvirtError as lib_err: except libvirtError as lib_err:
error_messages.append(lib_err) messages.error(request, lib_err)
addlogmsg(request.user.username, compute.hostname, lib_err) addlogmsg(request.user.username, compute.hostname, lib_err)
except Exception as err: except Exception as err:
error_messages.append(err) messages.error(request, err)
addlogmsg(request.user.username, compute.hostname, err) addlogmsg(request.user.username, compute.hostname, err)
return render(request, 'nwfilters.html', { return render(request, 'nwfilters.html', {
'error_messages': error_messages,
'nwfilters': nwfilters_all, 'nwfilters': nwfilters_all,
'compute': compute 'compute': compute,
}) })
@ -113,7 +110,6 @@ def nwfilter(request, compute_id, nwfltr):
:param nwfltr: :param nwfltr:
:return: :return:
""" """
error_messages = []
nwfilters_all = [] nwfilters_all = []
compute = get_object_or_404(Compute, pk=compute_id) compute = get_object_or_404(Compute, pk=compute_id)
@ -194,8 +190,8 @@ def nwfilter(request, compute_id, nwfltr):
conn.close() conn.close()
nwfilter.close() nwfilter.close()
except libvirtError as lib_err: except libvirtError as lib_err:
error_messages.append(lib_err) messages.error(request, lib_err)
except Exception as error_msg: except Exception as error_msg:
error_messages.append(error_msg) messages.error(request, error_msg)
return render(request, 'nwfilter.html', locals()) return render(request, 'nwfilter.html', locals())

View file

@ -2,15 +2,19 @@
{% load i18n %} {% load i18n %}
{% load staticfiles %} {% load staticfiles %}
{% block title %}{% trans "Secrets" %} - {{ compute.name }}{% endblock %} {% block title %}{% trans "Secrets" %} - {{ compute.name }}{% endblock %}
{% block style %} {% block style %}
<link rel="stylesheet" href="{% static "css/sortable-theme-bootstrap.css" %}" /> <link rel="stylesheet" href="{% static "css/sortable-theme-bootstrap.css" %}" />
{% endblock %} {% endblock %}
{% block page_heading %}{{ compute }} - {% trans "Secrets" %}{% endblock page_heading %}
{% block page_heading_extra %}{% include 'create_secret_block.html' %}{% endblock page_heading_extra %}
{% block content %} {% block content %}
<!-- Page Heading -->
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
{% include 'create_secret_block.html' %} <h2 class="page-header"></h2>
<h2 class="page-header">{% trans "Secrets" %}</h2>
<nav aria-label="breadcrumb"> <nav aria-label="breadcrumb">
<ol class="breadcrumb bg-light shadow-sm"> <ol class="breadcrumb bg-light shadow-sm">
<li class="breadcrumb-item active"> <li class="breadcrumb-item active">
@ -38,9 +42,6 @@
</nav> </nav>
</div> </div>
</div> </div>
<!-- /.row -->
{% include 'errors_block.html' %}
<div class="row"> <div class="row">
{% if not secrets_all %} {% if not secrets_all %}

View file

@ -1,17 +1,12 @@
from secrets.forms import AddSecret
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from libvirt import libvirtError
from libvirt import (VIR_SECRET_USAGE_TYPE_NONE,
VIR_SECRET_USAGE_TYPE_CEPH,
VIR_SECRET_USAGE_TYPE_TLS,
VIR_SECRET_USAGE_TYPE_VOLUME,
VIR_SECRET_USAGE_TYPE_ISCSI)
from admin.decorators import superuser_only from admin.decorators import superuser_only
from computes.models import Compute from computes.models import Compute
from secrets.forms import AddSecret from django.contrib import messages
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from libvirt import (VIR_SECRET_USAGE_TYPE_CEPH, VIR_SECRET_USAGE_TYPE_ISCSI, VIR_SECRET_USAGE_TYPE_NONE,
VIR_SECRET_USAGE_TYPE_TLS, VIR_SECRET_USAGE_TYPE_VOLUME, libvirtError)
from vrtManager.secrets import wvmSecrets from vrtManager.secrets import wvmSecrets
@ -24,7 +19,6 @@ def secrets(request, compute_id):
""" """
secrets_all = [] secrets_all = []
error_messages = []
compute = get_object_or_404(Compute, pk=compute_id) compute = get_object_or_404(Compute, pk=compute_id)
secret_usage_types = { secret_usage_types = {
VIR_SECRET_USAGE_TYPE_NONE: "none", VIR_SECRET_USAGE_TYPE_NONE: "none",
@ -59,11 +53,12 @@ def secrets(request, compute_id):
data['ephemeral'], data['ephemeral'],
data['private'], data['private'],
data['usage_type'], data['usage_type'],
data['data']) data['data'],
)
return HttpResponseRedirect(request.get_full_path()) return HttpResponseRedirect(request.get_full_path())
else: else:
for msg_err in form.errors.values(): for msg_err in form.errors.values():
error_messages.append(msg_err.as_text()) messages.error(request, msg_err.as_text())
if 'delete' in request.POST: if 'delete' in request.POST:
uuid = request.POST.get('uuid', '') uuid = request.POST.get('uuid', '')
conn.delete_secret(uuid) conn.delete_secret(uuid)
@ -74,9 +69,9 @@ def secrets(request, compute_id):
try: try:
conn.set_secret_value(uuid, value) conn.set_secret_value(uuid, value)
except Exception as err: except Exception as err:
error_messages.append(err) messages.error(request, err)
return HttpResponseRedirect(request.get_full_path()) return HttpResponseRedirect(request.get_full_path())
except libvirtError as err: except libvirtError as err:
error_messages.append(err) messages.error(request, err)
return render(request, 'secrets.html', locals()) return render(request, 'secrets.html', locals())

View file

@ -1,6 +1,6 @@
import re import re
from django import forms from django import forms
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
class AddStgPool(forms.Form): class AddStgPool(forms.Form):

View file

@ -1,17 +1,19 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load i18n %} {% load i18n %}
{% load staticfiles %} {% load staticfiles %}
{% block title %}{% trans "Storage" %} - {{ pool }}{% endblock %} {% block title %}{{ compute }} - {% trans "Storage" %}: {{ pool }}{% endblock %}
{% block style %} {% block style %}
<link rel="stylesheet" href="{% static "css/sortable-theme-bootstrap.css" %}"/> <link rel="stylesheet" href="{% static "css/sortable-theme-bootstrap.css" %}"/>
{% endblock %} {% endblock %}
{% block content %}
<!-- Page Heading --> {% block page_heading %}{{ compute }} - {% trans "Storage" %}: {{ pool }}{% endblock page_heading %}
{% block page_heading_extra %}{% include 'create_stg_vol_block.html' %}{% endblock page_heading_extra %}
{% block content %}
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
{% include 'create_stg_vol_block.html' %} <h2 class="page-header"></h2>
<h2 class="page-header">{% trans "Storage" %}: {{ pool }}</h2>
<ol class="breadcrumb bg-light shadow-sm"> <ol class="breadcrumb bg-light shadow-sm">
<li class="breadcrumb-item active"> <li class="breadcrumb-item active">
<a href="{% url 'overview' compute.id %}"><i class="fa fa-dashboard"></i> {% trans "Overview" %}</a> <a href="{% url 'overview' compute.id %}"><i class="fa fa-dashboard"></i> {% trans "Overview" %}</a>
@ -37,9 +39,6 @@
</ol> </ol>
</div> </div>
</div> </div>
<!-- /.row -->
{% include 'errors_block.html' %}
<dl class="ml-3 row"> <dl class="ml-3 row">
<dt class="col-6">{% trans "Pool name" %}</dt> <dt class="col-6">{% trans "Pool name" %}</dt>

View file

@ -1,14 +1,13 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load i18n %} {% load i18n %}
{% block title %}{% trans "Storages" %} - {{ compute.name }}{% endblock %}
{% block title %}{{ compute.name }} - {% trans "Storages" %}{% endblock %}
{% block page_heading %}{{ compute.name }} - {% trans "Storages" %}{% endblock page_heading %}
{% block page_heading_extra %}{% include 'create_stg_block.html' %}{% endblock page_heading_extra %}
{% block content %} {% block content %}
<!-- Page Heading -->
<div class="row">
<div class="col-lg-12">
{% include 'create_stg_block.html' %}
<h2 class="page-header">{{ compute.name }} - {% trans "Storages" %}</h2>
</div>
</div>
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<nav aria-label="breadcrumb"> <nav aria-label="breadcrumb">
@ -38,10 +37,6 @@
</nav> </nav>
</div> </div>
</div> </div>
<!-- /.row -->
{% include 'errors_block.html' %}
<div class="row"> <div class="row">
{% if not storages %} {% if not storages %}
<div class="col-lg-12"> <div class="col-lg-12">

View file

@ -4,7 +4,7 @@ from django.contrib import messages
from django.http import HttpResponse, HttpResponseRedirect from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, redirect, render from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse from django.urls import reverse
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from libvirt import libvirtError from libvirt import libvirtError
from admin.decorators import superuser_only from admin.decorators import superuser_only
@ -23,8 +23,8 @@ def storages(request, compute_id):
:return: :return:
""" """
error_messages = []
compute = get_object_or_404(Compute, pk=compute_id) compute = get_object_or_404(Compute, pk=compute_id)
errors = False
try: try:
conn = wvmStorages(compute.hostname, compute.login, compute.password, compute.type) conn = wvmStorages(compute.hostname, compute.login, compute.password, compute.type)
@ -38,15 +38,18 @@ def storages(request, compute_id):
data = form.cleaned_data data = form.cleaned_data
if data['name'] in storages: if data['name'] in storages:
msg = _("Pool name already use") msg = _("Pool name already use")
error_messages.append(msg) messages.error(request, msg)
errors = True
if data['stg_type'] == 'rbd': if data['stg_type'] == 'rbd':
if not data['secret']: if not data['secret']:
msg = _("You need create secret for pool") msg = _("You need create secret for pool")
error_messages.append(msg) messages.error(request, msg)
errors = True
if not data['ceph_pool'] and not data['ceph_host'] and not data['ceph_user']: if not data['ceph_pool'] and not data['ceph_host'] and not data['ceph_user']:
msg = _("You need input all fields for creating ceph pool") msg = _("You need input all fields for creating ceph pool")
error_messages.append(msg) messages.error(request, msg)
if not error_messages: errors = True
if not errors:
if data['stg_type'] == 'rbd': if data['stg_type'] == 'rbd':
conn.create_storage_ceph(data['stg_type'], data['name'], data['ceph_pool'], data['ceph_host'], conn.create_storage_ceph(data['stg_type'], data['name'], data['ceph_pool'], data['ceph_host'],
data['ceph_user'], data['secret']) data['ceph_user'], data['secret'])
@ -58,10 +61,10 @@ def storages(request, compute_id):
return HttpResponseRedirect(reverse('storage', args=[compute_id, data['name']])) return HttpResponseRedirect(reverse('storage', args=[compute_id, data['name']]))
else: else:
for msg_err in form.errors.values(): for msg_err in form.errors.values():
error_messages.append(msg_err.as_text()) messages.error(request, msg_err.as_text())
conn.close() conn.close()
except libvirtError as lib_err: except libvirtError as lib_err:
error_messages.append(lib_err) messages.error(request, lib_err)
return render(request, 'storages.html', locals()) return render(request, 'storages.html', locals())

View file

@ -40,15 +40,16 @@
<div class"row"> <div class"row">
<div class="col-sm-12"> <div class="col-sm-12">
<div class="float-right"> <div class="float-right">
{% block page_header_extra %} {% block page_heading_extra %}
{% endblock page_header_extra %} {% endblock page_heading_extra %}
</div> </div>
<h3 class="page-header"> <h3 class="page-header">
{% block page_header %} {% block page_heading %}
{% endblock page_header %} {% endblock page_heading %}
</h3> </h3>
</div> </div>
</div> </div>
<hr>
{% bootstrap_messages %} {% bootstrap_messages %}
{% block content %}{% endblock %} {% block content %}{% endblock %}
</div> </div>

View file

@ -5,7 +5,7 @@
{% block title %}{{ title }}{% endblock %} {% block title %}{{ title }}{% endblock %}
{% block page_header %}{{ title }}{% endblock page_header %} {% block page_heading %}{{ title }}{% endblock page_heading %}
{% block content %} {% block content %}
<div class="row"> <div class="row">

View file

@ -5,7 +5,7 @@
{% block title %}{{ title }}{% endblock %} {% block title %}{{ title }}{% endblock %}
{% block page_header %}{{ title }}{% endblock page_header %} {% block page_heading %}{{ title }}{% endblock page_heading %}
{% block content %} {% block content %}
<div class="card"> <div class="card">

View file

@ -1,17 +0,0 @@
{% load i18n %}
{% if error_messages %}
{% for error in error_messages %}
<!-- Error Messages -->
<div class="row">
<div class="col-lg-12">
<div class="alert alert-danger alert-dismissible" role="alert">
<strong>{% trans 'Error' %}:</strong> {{ error }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
</div>
</div>
<!-- /.row -->
{% endfor %}
{% endif %}

View file

@ -1,17 +0,0 @@
{% load i18n %}
{% if messages %}
{% for message in messages %}
<!-- Success Messages -->
<div class="row">
<div class="col-lg-12">
<div class="alert alert-success alert-dismissible" role="alert">
<strong>{% trans 'Success' %}:</strong> {{ message }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
</div>
</div>
<!-- /.row -->
{% endfor %}
{% endif %}

View file

@ -1,6 +1,6 @@
from django.contrib import messages from django.contrib import messages
from django.shortcuts import render from django.shortcuts import render
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from libvirt import libvirtError from libvirt import libvirtError