1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-03-21 18:14:51 +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.contrib.auth.models import User, Permission
if hasattr(settings, 'SHOW_PROFILE_EDIT_PASSWORD'):
print('\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[92mSHOW_PROFILE_EDIT_PASSWORD is found inside settings.py\033[0m')
print('\033[1m* \033[92mApplying permission can_change_password for all users\033[0m')
users = User.objects.all()
permission = Permission.objects.get(codename='change_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:
user.user_permissions.add(permission)
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:
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):
@ -32,11 +32,11 @@ def create_admin(sender, **kwargs):
from django.contrib.auth.models import User
from accounts.models import UserAttributes
plan = kwargs['plan']
plan = kwargs.get('plan', [])
for migration, rolled_back in plan:
if migration.app_label == 'accounts' and migration.name == '0001_initial' and not rolled_back:
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')
UserAttributes(user=admin, max_instances=-1, max_cpus=-1, max_memory=-1, max_disk_size=-1).save()
break
@ -47,5 +47,5 @@ class AccountsConfig(AppConfig):
verbose_name = 'Accounts'
def ready(self):
post_migrate.connect(apply_change_password, 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 django.contrib.auth import get_user_model
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 .utils import validate_ssh_key

View file

@ -1,7 +1,7 @@
from django.contrib.auth.models import User
from django.core.validators import MinValueValidator
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

View file

@ -5,13 +5,13 @@
{% load qr_code %}
{% 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">
{% icon 'plus' %}
</a>
{% endblock page_header_extra %}
{% endblock page_heading_extra %}
{% block content %}
<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 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 %}
<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.urls import reverse_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
@ -78,7 +78,7 @@ class UserForm(forms.ModelForm):
label=_("Password"),
help_text=format_lazy(_("""Raw passwords are not stored, so there is no way to see
this user's password, but you can change the password using <a href='{}'>this form</a>."""),
reverse_lazy('admin:user_update_password',
reverse_lazy('admin:user_update_password',
args=[self.instance.id,]))
)
self.fields['Password'] = password

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>
</div>
</div>
{% include 'errors_block.html' %}
<div class="row">
{% if not groups %}
<div class="col-lg-12">

View file

@ -1,55 +1,48 @@
{% extends "base.html" %}
{% load i18n %}
{% load bootstrap4 %}
{% block title %}{% trans "Logs" %}{% endblock %}
{% block page_heading %}{% trans "Logs" %}{% endblock page_heading %}
{% block content %}
<!-- Page Heading -->
<div class="row">
<div class="col-lg-12">
<h2 class="page-header">{% trans "Logs" %}</h2>
</div>
</div>
<!-- /.row -->
{% 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 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>
{% else %}
{% include "paging.html" %}
<div class="table-responsive">
<table class="table table-bordered table-hover">
<thead>
</div>
{% else %}
<div class="table-responsive">
<table class="table table-hover table-striped">
<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>
<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>
<td>{{ log.id }}</td>
<td style="width:130px;">{{ log.date|date:"M d H:i:s" }}</td>
<td>{{ log.user }}</td>
<td>{{ log.instance }}</td>
<td>{{ log.message }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% bootstrap_pagination logs %}
{% endif %}
</div>
<td>{{ log.id }}</td>
<td style="width:130px;">{{ log.date|date:"M d H:i:s" }}</td>
<td>{{ log.user }}</td>
<td>{{ log.instance }}</td>
<td>{{ log.message }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% bootstrap_pagination logs %}
{% endif %}
</div>
</div>
{% endblock %}

View file

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

View file

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

View file

@ -1,7 +1,8 @@
# Generated by Django 2.2.12 on 2020-05-23 12:05
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):
setting = apps.get_model("appsettings", "AppSettings")

View file

@ -1,7 +1,7 @@
# Generated by Django 2.2.13 on 2020-07-16 06:37
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):
@ -22,7 +22,7 @@ def del_default_settings(apps, schema_editor):
setting.objects.using(db_alias).filter(key="CONSOLE_VIEW_ONLY").delete()
setting.objects.using(db_alias).filter(key="CONSOLE_RESIZE_SESSION").delete()
setting.objects.using(db_alias).filter(key="CONSOLE_CLIP_VIEWPORT").delete()
class Migration(migrations.Migration):

View file

@ -1,5 +1,6 @@
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):

View file

@ -1,80 +1,74 @@
{% extends "base.html" %}
{% 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 %}
<!-- Page Heading -->
<div class="row">
<div class="col-lg-12">
<h2 class="page-header">{% trans "Edit Settings" %}</h2>
<div class="">
<div class="col-lg-12">
<h3 class="page-header">{% trans "App Settings" %}</h3>
<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>
<!-- /.row -->
{% include 'errors_block.html' %}
<div class="">
<div class="col-lg-12">
<h3 class="page-header">{% trans "App Settings" %}</h3>
<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>
</form>
{% if request.user.is_superuser %}
<form method="post" action="" role="form" aria-label="Edit sass directory settings form">{% csrf_token %}
<div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans sass_dir.name %}</label>
<div class="col-sm-6">
<input class="form-control" name="{{ sass_dir.key }}" value="{{ sass_dir.value }}" onchange="this.form.submit()" title="{% trans sass_dir.description %}"/>
</div>
</div>
</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>
</form>
{% if request.user.is_superuser %}
<form method="post" action="" role="form" aria-label="Edit sass directory settings form">{% csrf_token %}
<div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans sass_dir.name %}</label>
<div class="col-sm-6">
<input class="form-control" name="{{ sass_dir.key }}" value="{{ sass_dir.value }}" onchange="this.form.submit()" title="{% trans sass_dir.description %}"/>
</div>
</div>
</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 %}
</select>
<span class="text-muted">{% trans "After change please full refresh page with 'Ctrl + F5' "%}</span>
</div>
</div>
</form>
{% endif %}
<h3 class="page-header">{% trans "Other Settings" %}</h3>
{% for setting in appsettings %}
<form method="post" action="" role="form" aria-label="{{setting.name}} form">{% csrf_token %}
<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>
<span class="text-muted">{% trans "After change please full refresh page with 'Ctrl + F5' "%}</span>
</div>
</select>
{% else %}
<input class="form-control" name="{{ setting.key }}" value="{{ setting.value }}" title="{% trans setting.description %}" onchange="this.form.submit()"/>
{% endif%}
</div>
</form>
{% endif %}
<h3 class="page-header">{% trans "Other Settings" %}</h3>
{% for setting in appsettings %}
<form method="post" action="" role="form" aria-label="{{setting.name}} form">{% csrf_token %}
<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>
</div>
</form>
{% endfor %}
</div>
</div>
{% endblock %}

View file

@ -1,16 +1,14 @@
import sass
import os
from django.shortcuts import render
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
import sass
from django.contrib import messages
from appsettings.models import AppSettings
from django.contrib.auth.decorators import login_required
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.utils.translation import gettext_lazy as _
from logs.views import addlogmsg
from appsettings.models import AppSettings
@login_required
@ -19,19 +17,17 @@ def appsettings(request):
:param request:
:return:
"""
error_messages = []
main_css = "wvc-main.min.css"
sass_dir = AppSettings.objects.get(key="SASS_DIR")
bootstrap_theme = AppSettings.objects.get(key="BOOTSTRAP_THEME")
try:
themes_list = os.listdir(sass_dir.value + "/wvc-theme")
except FileNotFoundError as err:
error_messages.append(err)
addlogmsg(request.user.username, "", err)
messages.error(request, err)
addlogmsg(request.user.username, "", err)
# Bootstrap settings related with filesystems, because of that they are excluded from other settings
appsettings = AppSettings.objects.exclude(description__startswith="Bootstrap").order_by("name")
if request.method == 'POST':
if 'SASS_DIR' in request.POST:
@ -43,24 +39,25 @@ def appsettings(request):
messages.success(request, msg)
except Exception as err:
msg = err
error_messages.append(msg)
messages.error(request, msg)
addlogmsg(request.user.username, "", msg)
return HttpResponseRedirect(request.get_full_path())
if 'BOOTSTRAP_THEME' in request.POST:
theme = request.POST.get("BOOTSTRAP_THEME", "")
scss_var = f"@import '{sass_dir.value}/wvc-theme/{theme}/variables';"
scss_bootswatch = f"@import '{sass_dir.value}/wvc-theme/{theme}/bootswatch';"
scss_bootswatch = f"@import '{sass_dir.value}/wvc-theme/{theme}/bootswatch';"
scss_boot = f"@import '{sass_dir.value}/bootstrap-overrides.scss';"
try:
try:
with open(sass_dir.value + "/wvc-main.scss", "w") as main:
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:
css.write(css_compressed)
css.write(css_compressed)
bootstrap_theme.value = theme
bootstrap_theme.save()
@ -69,8 +66,8 @@ def appsettings(request):
messages.success(request, msg)
except Exception as err:
msg = err
error_messages.append(msg)
messages.error(request, msg)
addlogmsg(request.user.username, "", msg)
return HttpResponseRedirect(request.get_full_path())
@ -84,10 +81,9 @@ def appsettings(request):
messages.success(request, msg)
except Exception as err:
msg = err
error_messages.append(msg)
messages.error(request, msg)
addlogmsg(request.user.username, "", msg)
return HttpResponseRedirect(request.get_full_path())
return render(request, 'appsettings.html', locals())

View file

@ -1,8 +1,9 @@
import re
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 vrtManager.connection import CONN_TCP, CONN_SSH, CONN_TLS, CONN_SOCKET
from .validators import validate_hostname

View file

@ -1,6 +1,6 @@
from django.db.models import CharField, IntegerField, Model
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 vrtManager.connection import connection_manager

View file

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

View file

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

View file

@ -1,42 +1,42 @@
{% extends "base.html" %}
{% load i18n %}
{% load staticfiles %}
{% load icons %}
{% block title %}{% trans "Overview" %} - {{ compute.name }}{% endblock %}
{% block page_heading %}{{ compute.name }}{% endblock page_heading %}
{% block content %}
<!-- Page Heading -->
<div class="row">
<div class="col-lg-12">
<h2 class="page-header">{{ compute.name }}</h2>
<nav aria-label="breadcrumb">
<ol class="breadcrumb bg-light shadow-sm">
<li class="breadcrumb-item active">
<span class="font-weight-bold"><i class="fa fa-dashboard"></i> {% trans "Overview" %}</span>
<li class="breadcrumb-item">
<span class="font-weight-bold">{% icon 'dashboard' %} {% trans "Overview" %}</span>
</li>
<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 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 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 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 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 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>
</ol>
</nav>
</div>
</div>
<!-- /.row -->
{% include 'errors_block.html' %}
<div class="shadow-sm">
<h3 class="page-header">{% trans "Basic details" %}</h3>

View file

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

View file

@ -1,7 +1,6 @@
<domain type="kvm">
<name>test-vm</name>
<uuid>1bd3c1f2-dd12-4b8d-a298-dff387cb9f93</uuid>
<description>None</description>
<memory unit="KiB">131072</memory>
<currentMemory unit="KiB">131072</currentMemory>
<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
'''
from django.conf import settings
from django.contrib.auth.models import User, Permission
from accounts.models import UserAttributes
from django.contrib.auth.models import Permission, User
plan = kwargs['plan']
plan = kwargs.get('plan', [])
for migration, rolled_back in plan:
if migration.app_label == 'instances' and migration.name == '0002_permissionset' and not rolled_back:
users = User.objects.all()
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:
if user.userattributes:
if user.userattributes.can_clone_instances:
user.user_permissions.add(permission)
break
def apply_passwordless_console(sender, **kwargs):
'''
Apply new passwordless_console permission for all users
'''
from django.conf import settings
from django.contrib.auth.models import User, Permission
from django.contrib.auth.models import 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):
name = 'instances'
verbose_name = 'instances'
verbose_name = 'Instances'
def ready(self):
post_migrate.connect(migrate_can_clone_instances, sender=self)

View file

@ -1,7 +1,7 @@
import re
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 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)
if not have_symbol:
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

View file

@ -1,6 +1,6 @@
from django.db import models
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 computes.models import Compute

View file

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

View file

@ -1,21 +1,15 @@
{% extends "base.html" %}
{% load i18n %}
{% load staticfiles %}
{% block title %}{% trans "Create new instance" %} - {% trans "Select Type" %}{% 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>
</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 %}
{% for field in form %}

View file

@ -3,22 +3,17 @@
{% load staticfiles %}
{% load icons %}
{% block title %}{% trans "Create new instance" %}{% endblock %}
{% block style %}
<link href="{% static "css/bootstrap-multiselect.css" %}" rel="stylesheet">
{% 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 %}
{% for field in form %}

View file

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

View file

@ -4,9 +4,9 @@
{% trans "Confirm Destroy" %}
{% endblock title %}
{% block page_header %}
{% block page_heading %}
{% trans "Destroy instance" %} {{ instance }}
{% endblock page_header %}
{% endblock page_heading %}
{% block content %}
{% 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('random_mac_address/', views.random_mac_address, name='random_mac_address'),
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 random
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 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.hostdetails import wvmHostDetails
from vrtManager.instance import wvmInstance, wvmInstances
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):
prefix = app_settings.CLONE_INSTANCE_DEFAULT_PREFIX
free_names = []
@ -186,36 +163,6 @@ def migrate_instance(
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):
if compute.status is True:
domains = compute.proxy.wvm.listAllDomains()
@ -229,83 +176,6 @@ def refr(compute):
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):
dhcp_file = settings.BASE_DIR + '/dhcpd.conf'
mac = ''
@ -342,20 +212,3 @@ def get_clone_disk_name(disk, prefix, clone_name=''):
else:
image = f"{disk['image']}-clone"
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.shortcuts import get_object_or_404, redirect, render
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 logs.views import addlogmsg
from vrtManager import util
@ -51,7 +51,7 @@ def index(request):
def instance(request, pk):
instance: Instance = get_object_or_404(Instance, pk=pk)
instance: Instance = get_instance(request.user, pk)
compute: Compute = instance.compute
computes = Compute.objects.all().order_by('name')
computes_count = computes.count()
@ -59,7 +59,6 @@ def instance(request, pk):
publickeys = UserSSHKey.objects.filter(user_id=request.user.id)
keymaps = settings.QEMU_KEYMAPS
console_types = AppSettings.objects.get(key="QEMU_CONSOLE_DEFAULT_TYPE").choices_as_list()
#
console_form = ConsoleForm(
initial={
'type': instance.console_type,
@ -67,7 +66,6 @@ def instance(request, pk):
'password': instance.console_passwd,
'keymap': instance.console_keymap,
})
#
console_listen_addresses = settings.QEMU_CONSOLE_LISTEN_ADDRESSES
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
@ -78,15 +76,6 @@ def instance(request, pk):
except UserInstance.DoesNotExist:
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]
if instance.memory not in memory_range:
insort(memory_range, instance.memory)
@ -127,18 +116,11 @@ def instance(request, pk):
vcpu_host = len(instance.vcpu_range)
memory_host = instance.proxy.get_max_memory()
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())
nwfilters_host = instance.proxy.get_nwfilters()
storages_host = sorted(instance.proxy.get_storages(True))
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())
@ -210,18 +192,18 @@ def check_instance(request, vname):
data = {'vname': vname, 'exists': False}
if instance:
data['exists'] = True
return HttpResponse(json.dumps(data))
return JsonResponse(data)
def sshkeys(request, vname):
def sshkeys(request, pk):
"""
:param request:
:param vname:
:return:
"""
instance = get_instance(request.user, pk)
instance_keys = []
userinstances = UserInstance.objects.filter(instance__name=vname)
userinstances = UserInstance.objects.filter(instance=instance)
for ui in userinstances:
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
'''
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)
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:
disks_new = list()
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
if input_disk_size > disk['size'] + (64 << 20):
disk['size_new'] = input_disk_size
@ -1005,7 +986,7 @@ def add_owner(request, pk):
if app_settings.ALLOW_INSTANCE_MULTIPLE_OWNER == 'False':
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"))
else:
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')
@permission_required('instances.clone_instances')
@permission_required('instances.clone_instances', raise_exception=True)
def clone(request, pk):
instance = get_instance(request.user, pk)

View file

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

View file

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

View file

@ -1,13 +1,16 @@
{% extends "base.html" %}
{% load i18n %}
{% load staticfiles %}
{% 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 %}
<!-- Page Heading -->
<div class="row">
<div class="col-lg-12">
{% include 'create_iface_block.html' %}
<h2 class="page-header">{{ compute.name }}</h2>
<nav aria-label="breadcrumb">
<ol class="breadcrumb bg-light shadow-sm">
<li class="breadcrumb-item active">
@ -35,9 +38,6 @@
</nav>
</div>
</div>
<!-- /.row -->
{% include 'errors_block.html' %}
<div class="row">
{% 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.http import HttpResponseRedirect
from django.urls import reverse
@ -17,7 +18,6 @@ def interfaces(request, compute_id):
"""
ifaces_all = []
error_messages = []
compute = get_object_or_404(Compute, pk=compute_id)
try:
@ -42,10 +42,10 @@ def interfaces(request, compute_id):
return HttpResponseRedirect(request.get_full_path())
else:
for msg_err in form.errors.values():
error_messages.append(msg_err.as_text())
messages.error(request, msg_err.as_text())
conn.close()
except libvirtError as lib_err:
error_messages.append(lib_err)
messages.error(request, lib_err)
return render(request, 'interfaces.html', locals())
@ -60,7 +60,6 @@ def interface(request, compute_id, iface):
"""
ifaces_all = []
error_messages = []
compute = get_object_or_404(Compute, pk=compute_id)
try:
@ -88,6 +87,6 @@ def interface(request, compute_id, iface):
return HttpResponseRedirect(reverse('interfaces', args=[compute_id]))
conn.close()
except libvirtError as lib_err:
error_messages.append(lib_err)
messages.error(request, lib_err)
return render(request, 'interface.html', locals())

View file

@ -1,5 +1,5 @@
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):

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
from django import forms
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
class AddNetPool(forms.Form):

View file

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

View file

@ -1,14 +1,13 @@
{% extends "base.html" %}
{% 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 %}
<!-- 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="col-lg-12">
<nav aria-label="breadcrumb">
@ -38,9 +37,6 @@
</nav>
</div>
</div>
<!-- /.row -->
{% include 'errors_block.html' %}
<div class="row">
{% if not networks %}

View file

@ -2,7 +2,7 @@ from django.contrib import messages
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 django.utils.translation import gettext_lazy as _
from libvirt import libvirtError
from admin.decorators import superuser_only
@ -19,8 +19,8 @@ def networks(request, compute_id):
:return:
"""
error_messages = []
compute = get_object_or_404(Compute, pk=compute_id)
errors = False
try:
conn = wvmNetworks(
@ -41,9 +41,11 @@ def networks(request, compute_id):
data = form.cleaned_data
if data['name'] in networks:
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'] == '':
error_messages.append(_('Please enter bridge/dev name'))
messages.error(request, _('Please enter bridge/dev name'))
errors = True
if data['subnet']:
ipv4 = True
gateway4, netmask4, dhcp4 = network_size(data['subnet'], data['dhcp4'])
@ -51,8 +53,9 @@ def networks(request, compute_id):
ipv6 = True
gateway6, prefix6, dhcp6 = network_size(data['subnet6'], data['dhcp6'])
if prefix6 != '64':
error_messages.append(_('For libvirt, the IPv6 network prefix must be /64'))
if not error_messages:
messages.error(request, _('For libvirt, the IPv6 network prefix must be /64'))
errors = True
if not errors:
conn.create_network(
data['name'],
data['forward'],
@ -71,10 +74,10 @@ def networks(request, compute_id):
return HttpResponseRedirect(reverse('network', args=[compute_id, data['name']]))
else:
for msg_err in form.errors.values():
error_messages.append(msg_err.as_text())
messages.error(request, msg_err.as_text())
conn.close()
except libvirtError as lib_err:
error_messages.append(lib_err)
messages.error(request, lib_err)
return render(request, 'networks.html', locals())
@ -88,7 +91,6 @@ def network(request, compute_id, pool):
:return:
"""
error_messages = []
compute = get_object_or_404(Compute, pk=compute_id)
try:
@ -125,7 +127,7 @@ def network(request, compute_id, pool):
xml = conn._XMLDesc(0)
except libvirtError as lib_err:
error_messages.append(lib_err)
messages.error(request, lib_err)
return HttpResponseRedirect(reverse('networks', args=compute_id))
if request.method == 'POST':
@ -134,31 +136,31 @@ def network(request, compute_id, pool):
conn.start()
return HttpResponseRedirect(request.get_full_path())
except libvirtError as lib_err:
error_messages.append(lib_err)
messages.error(request, lib_err)
if 'stop' in request.POST:
try:
conn.stop()
return HttpResponseRedirect(request.get_full_path())
except libvirtError as lib_err:
error_messages.append(lib_err)
messages.error(request, lib_err)
if 'delete' in request.POST:
try:
conn.delete()
return HttpResponseRedirect(reverse('networks', args=[compute_id]))
except libvirtError as lib_err:
error_messages.append(lib_err)
messages.error(request, lib_err)
if 'set_autostart' in request.POST:
try:
conn.set_autostart(1)
return HttpResponseRedirect(request.get_full_path())
except libvirtError as lib_err:
error_messages.append(lib_err)
messages.error(request, lib_err)
if 'unset_autostart' in request.POST:
try:
conn.set_autostart(0)
return HttpResponseRedirect(request.get_full_path())
except libvirtError as lib_err:
error_messages.append(lib_err)
messages.error(request, lib_err)
if 'modify_fixed_address' in request.POST:
name = request.POST.get('name', '')
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."))
return HttpResponseRedirect(request.get_full_path())
except libvirtError as lib_err:
error_messages.append(lib_err)
messages.error(request, lib_err)
except ValueError as val_err:
error_messages.append(val_err)
messages.error(request, val_err)
if 'delete_fixed_address' in request.POST:
ip = request.POST.get('address', '')
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."))
return HttpResponseRedirect(request.get_full_path())
except libvirtError as lib_err:
error_messages.append(lib_err)
messages.error(request, lib_err)
if 'edit_network' in request.POST:
edit_xml = request.POST.get('edit_xml', '')
if edit_xml:
@ -212,7 +214,7 @@ def network(request, compute_id, pool):
conn.set_qos(qos_dir, average, peak, burst)
if conn.is_active():
messages.success(
request,
request,
_(f"{qos_dir.capitalize()} QoS is set. Network XML is changed.") +
_("Stop and start network to activate new config"))
else:
@ -226,7 +228,7 @@ def network(request, compute_id, pool):
if conn.is_active():
messages.success(
request,
request,
_(f"{qos_dir.capitalize()} QoS is deleted. Network XML is changed. ") +
_("Stop and start network to activate new config."))
else:

View file

@ -1,12 +1,14 @@
{% extends "base.html" %}
{% load i18n %}
{% 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 %}
<!-- Page Heading -->
<div class="row">
<div class="col-lg-12">
<h3 class="page-header">{% trans "NWFilter" %}: {{ name }}</h3>
<ol class="breadcrumb bg-light shadow-sm">
<li class="breadcrumb-item active">
<a href="{% url 'overview' compute.id %}"><i class="fa fa-dashboard"></i> {% trans "Overview" %}</a>
@ -32,12 +34,7 @@
</ol>
</div>
</div>
<!-- /.row -->
{% include 'errors_block.html' %}
{% include 'messages_block.html' %}
<dl class="ml-3 row">
<dt class="col-4">{% trans "UUID" %}:</dt>
<dd class="col-8">{{ uuid }}</dd>

View file

@ -1,18 +1,19 @@
{% extends "base.html" %}
{% load i18n %}
{% 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 %}
<!-- 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="col-lg-12">
<nav aria-label="breadcrumb">
@ -42,10 +43,6 @@
</nav>
</div>
</div>
<!-- /.row -->
{% include 'errors_block.html' %}
{% include 'messages_block.html' %}
<div class="row">
<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 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 vrtManager import util
from vrtManager.instance import wvmInstance, wvmInstances
@ -20,7 +19,6 @@ def nwfilters(request, compute_id):
:return:
"""
error_messages = []
nwfilters_all = []
compute = get_object_or_404(Compute, pk=compute_id)
@ -51,7 +49,7 @@ def nwfilters(request, compute_id):
conn.create_nwfilter(xml)
addlogmsg(request.user.username, compute.hostname, msg)
except libvirtError as lib_err:
error_messages.append(lib_err)
messages.error(request, lib_err)
addlogmsg(request.user.username, compute.hostname, lib_err)
if 'del_nwfilter' in request.POST:
@ -69,7 +67,7 @@ def nwfilters(request, compute_id):
if name in dom_filterrefs:
in_use = True
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)
i_conn.close()
break
@ -93,16 +91,15 @@ def nwfilters(request, compute_id):
conn.close()
except libvirtError as lib_err:
error_messages.append(lib_err)
messages.error(request, lib_err)
addlogmsg(request.user.username, compute.hostname, lib_err)
except Exception as err:
error_messages.append(err)
messages.error(request, err)
addlogmsg(request.user.username, compute.hostname, err)
return render(request, 'nwfilters.html', {
'error_messages': error_messages,
'nwfilters': nwfilters_all,
'compute': compute
'compute': compute,
})
@ -113,7 +110,6 @@ def nwfilter(request, compute_id, nwfltr):
:param nwfltr:
:return:
"""
error_messages = []
nwfilters_all = []
compute = get_object_or_404(Compute, pk=compute_id)
@ -194,8 +190,8 @@ def nwfilter(request, compute_id, nwfltr):
conn.close()
nwfilter.close()
except libvirtError as lib_err:
error_messages.append(lib_err)
messages.error(request, lib_err)
except Exception as error_msg:
error_messages.append(error_msg)
messages.error(request, error_msg)
return render(request, 'nwfilter.html', locals())

View file

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

View file

@ -1,17 +1,12 @@
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 secrets.forms import AddSecret
from admin.decorators import superuser_only
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
@ -24,7 +19,6 @@ def secrets(request, compute_id):
"""
secrets_all = []
error_messages = []
compute = get_object_or_404(Compute, pk=compute_id)
secret_usage_types = {
VIR_SECRET_USAGE_TYPE_NONE: "none",
@ -59,11 +53,12 @@ def secrets(request, compute_id):
data['ephemeral'],
data['private'],
data['usage_type'],
data['data'])
data['data'],
)
return HttpResponseRedirect(request.get_full_path())
else:
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:
uuid = request.POST.get('uuid', '')
conn.delete_secret(uuid)
@ -74,9 +69,9 @@ def secrets(request, compute_id):
try:
conn.set_secret_value(uuid, value)
except Exception as err:
error_messages.append(err)
messages.error(request, err)
return HttpResponseRedirect(request.get_full_path())
except libvirtError as err:
error_messages.append(err)
messages.error(request, err)
return render(request, 'secrets.html', locals())

View file

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

View file

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

View file

@ -1,14 +1,13 @@
{% extends "base.html" %}
{% 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 %}
<!-- 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="col-lg-12">
<nav aria-label="breadcrumb">
@ -38,10 +37,6 @@
</nav>
</div>
</div>
<!-- /.row -->
{% include 'errors_block.html' %}
<div class="row">
{% if not storages %}
<div class="col-lg-12">

View file

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

View file

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

View file

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

View file

@ -5,7 +5,7 @@
{% block title %}{{ title }}{% endblock %}
{% block page_header %}{{ title }}{% endblock page_header %}
{% block page_heading %}{{ title }}{% endblock page_heading %}
{% block content %}
<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.shortcuts import render
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from libvirt import libvirtError