mirror of
				https://github.com/retspen/webvirtcloud
				synced 2025-07-31 12:41:08 +00:00 
			
		
		
		
	Added admin application
- Manage users - Manage groups - Manage logs
This commit is contained in:
		
							parent
							
								
									38befa4362
								
							
						
					
					
						commit
						27f62dff6c
					
				
					 38 changed files with 933 additions and 742 deletions
				
			
		| 
						 | 
				
			
			@ -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="pull-right search">
 | 
			
		||||
                        <input id="filter" class="form-control" type="text" placeholder="Search">
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <h1 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">×</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>{% trans "Username" %}</th>
 | 
			
		||||
                                    <th>{% trans "Status" %}</th>
 | 
			
		||||
                                    <th>{% trans "Staff" %}</th>
 | 
			
		||||
                                    <th>{% trans "Superuser" %}</th>
 | 
			
		||||
                                    <th>{% 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 'account' user.id %}"><strong>{{ user.username }}</strong></a>
 | 
			
		||||
                                        <a data-toggle="modal" href="#editUser{{ user.id }}" class="pull-right" title="{% trans "Edit" %}">
 | 
			
		||||
                                            <span class="glyphicon glyphicon-cog"></span>
 | 
			
		||||
                                        </a>
 | 
			
		||||
                                    </td>
 | 
			
		||||
                                    <td>
 | 
			
		||||
                                        {% if user.is_active %}
 | 
			
		||||
                                            {% trans "Active" %}
 | 
			
		||||
                                        {% else %}
 | 
			
		||||
                                            {% trans "Blocked" %}
 | 
			
		||||
                                        {% endif %}
 | 
			
		||||
                                    </td>
 | 
			
		||||
                                    <td>{% if user.is_staff %}<span class="glyphicon glyphicon-ok"></span>{% endif %}</td>
 | 
			
		||||
                                    <td>{% if user.is_superuser %}<span class="glyphicon glyphicon-ok"></span>{% endif %}</td>
 | 
			
		||||
                                    <td>{% if user.userattributes.can_clone_instances %}<span class="glyphicon glyphicon-ok"></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 class="form-horizontal" method="post" role="form">{% csrf_token %}
 | 
			
		||||
                                        <div class="modal-header">
 | 
			
		||||
                                            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
 | 
			
		||||
                                            <h4 class="modal-title">{% trans "Edit user info" %}</h4>
 | 
			
		||||
                                        </div>
 | 
			
		||||
                                        <div class="modal-body">
 | 
			
		||||
                                            <div class="form-group">
 | 
			
		||||
                                                <label class="col-sm-4 control-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">
 | 
			
		||||
                                                <label class="col-sm-4 control-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">
 | 
			
		||||
                                                <label class="col-sm-4 control-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">
 | 
			
		||||
                                                <label class="col-sm-4 control-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">
 | 
			
		||||
                                                <label class="col-sm-4 control-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">
 | 
			
		||||
                                                <label class="col-sm-4 control-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">
 | 
			
		||||
                                                <label class="col-sm-4 control-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">
 | 
			
		||||
                                                <label class="col-sm-4 control-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">
 | 
			
		||||
                                                <label class="col-sm-4 control-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="pull-left btn btn-danger" name="delete">
 | 
			
		||||
                                                {% trans "Delete" %}
 | 
			
		||||
                                            </button>
 | 
			
		||||
                                            {% if user.is_active %}
 | 
			
		||||
                                                <button type="submit" class="pull-left btn btn-warning" name="block">
 | 
			
		||||
                                                    {% trans "Block" %}
 | 
			
		||||
                                                </button>
 | 
			
		||||
                                            {% else %}
 | 
			
		||||
                                                <button type="submit" class="pull-left btn btn-success" name="unblock">
 | 
			
		||||
                                                    {% trans "Unblock" %}
 | 
			
		||||
                                                </button>
 | 
			
		||||
                                            {% endif %}
 | 
			
		||||
                                            <button type="button" class="btn btn-default" 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 %}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,144 +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' %}
 | 
			
		||||
                    <h1 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">×</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-xs-12 col-sm-4">
 | 
			
		||||
                            <div class="panel {% if user.is_active %}panel-success{% else %}panel-danger{% endif %} panel-data">
 | 
			
		||||
                                <div class="panel-heading">
 | 
			
		||||
                                    <h3 class="panel-title">
 | 
			
		||||
                                        <a href="{% url 'account' user.id %}"><strong>{{ user.username }}</strong></a>
 | 
			
		||||
                                        <a data-toggle="modal" href="#editUser{{ user.id }}" class="pull-right" title="{% trans "Edit" %}">
 | 
			
		||||
                                            <span class="glyphicon glyphicon-cog"></span>
 | 
			
		||||
                                        </a>
 | 
			
		||||
                                    </h3>
 | 
			
		||||
                                </div>
 | 
			
		||||
                                <div class="panel-body">
 | 
			
		||||
                                    <div class="col-xs-4 col-sm-4">
 | 
			
		||||
                                        <p><strong>{% trans "Status:" %}</strong></p>
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                    <div class="col-xs-4 col-sm-6">
 | 
			
		||||
                                        {% if user.is_active %}
 | 
			
		||||
                                            <p>{% trans "Active" %}</p>
 | 
			
		||||
                                        {% else %}
 | 
			
		||||
                                            <p>{% trans "Blocked" %}</p>
 | 
			
		||||
                                        {% endif %}
 | 
			
		||||
                                    </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">
 | 
			
		||||
                                        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
 | 
			
		||||
                                        <h4 class="modal-title">{% trans "Edit user info" %}</h4>
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                    <div class="modal-body">
 | 
			
		||||
                                        <form class="form-horizontal" method="post" role="form">{% csrf_token %}
 | 
			
		||||
                                            <div class="form-group">
 | 
			
		||||
                                                <label class="col-sm-4 control-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">
 | 
			
		||||
                                                <label class="col-sm-4 control-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">
 | 
			
		||||
                                                <label class="col-sm-4 control-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">
 | 
			
		||||
                                                <label class="col-sm-4 control-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">
 | 
			
		||||
                                                <label class="col-sm-4 control-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">
 | 
			
		||||
                                                <label class="col-sm-4 control-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">
 | 
			
		||||
                                                <label class="col-sm-4 control-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">
 | 
			
		||||
                                                <label class="col-sm-4 control-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">
 | 
			
		||||
                                                <label class="col-sm-4 control-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="pull-left btn btn-danger" name="delete">
 | 
			
		||||
                                            {% trans "Delete" %}
 | 
			
		||||
                                        </button>
 | 
			
		||||
                                        {% if user.is_active %}
 | 
			
		||||
                                            <button type="submit" class="pull-left btn btn-warning" name="block">
 | 
			
		||||
                                                {% trans "Block" %}
 | 
			
		||||
                                            </button>
 | 
			
		||||
                                        {% else %}
 | 
			
		||||
                                            <button type="submit" class="pull-left btn btn-success" name="unblock">
 | 
			
		||||
                                                {% trans "Unblock" %}
 | 
			
		||||
                                            </button>
 | 
			
		||||
                                        {% endif %}
 | 
			
		||||
                                        <button type="button" class="btn btn-default" 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 %}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,38 +0,0 @@
 | 
			
		|||
{% load i18n %}
 | 
			
		||||
{% if request.user.is_superuser %}
 | 
			
		||||
    <a href="#AddUser" type="button" class="btn btn-success btn-header pull-right" data-toggle="modal">
 | 
			
		||||
        <span class="glyphicon glyphicon-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 class="form-horizontal" method="post" action="" role="form">{% csrf_token %}
 | 
			
		||||
                    <div class="modal-header">
 | 
			
		||||
                        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
 | 
			
		||||
                        <h4 class="modal-title">{% trans "Add New User" %}</h4>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="modal-body">
 | 
			
		||||
                        <div class="form-group">
 | 
			
		||||
                            <label class="col-sm-4 control-label">{% trans "Name" %}</label>
 | 
			
		||||
                            <div class="col-sm-6">
 | 
			
		||||
                                <input type="text" class="form-control" name="name" placeholder="john" required pattern="[a-z0-9]+">
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="form-group">
 | 
			
		||||
                            <label class="col-sm-4 control-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-default" 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 %}
 | 
			
		||||
| 
						 | 
				
			
			@ -5,6 +5,6 @@ from . import views
 | 
			
		|||
urlpatterns = [
 | 
			
		||||
    path('login/', auth_views.LoginView.as_view(template_name='login.html'), name='login'),
 | 
			
		||||
    path('logout/', auth_views.LogoutView.as_view(template_name='logout.html'), name='logout'),
 | 
			
		||||
    path('profile/', views.profile, name='profile'), path('', views.accounts, name='accounts'),
 | 
			
		||||
    re_path(r'^profile/(?P<user_id>[0-9]+)/$', views.account, name='account'),
 | 
			
		||||
    path('profile/', views.profile, name='profile'),
 | 
			
		||||
    path('profile/<int:user_id>/', views.account, name='account'),
 | 
			
		||||
]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,12 +1,14 @@
 | 
			
		|||
from django.shortcuts import render
 | 
			
		||||
from django.http import HttpResponseRedirect
 | 
			
		||||
from django.urls import reverse
 | 
			
		||||
from django.utils.translation import ugettext_lazy as _
 | 
			
		||||
from accounts.models import *
 | 
			
		||||
from instances.models import Instance
 | 
			
		||||
from accounts.forms import UserAddForm
 | 
			
		||||
from django.conf import settings
 | 
			
		||||
from django.core.validators import ValidationError
 | 
			
		||||
from django.http import HttpResponseRedirect
 | 
			
		||||
from django.shortcuts import render
 | 
			
		||||
from django.urls import reverse
 | 
			
		||||
from django.utils.translation import ugettext_lazy as _
 | 
			
		||||
 | 
			
		||||
from accounts.forms import UserAddForm
 | 
			
		||||
from accounts.models import *
 | 
			
		||||
from admin.decorators import superuser_only
 | 
			
		||||
from instances.models import Instance
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def profile(request):
 | 
			
		||||
| 
						 | 
				
			
			@ -16,7 +18,7 @@ def profile(request):
 | 
			
		|||
    """
 | 
			
		||||
 | 
			
		||||
    error_messages = []
 | 
			
		||||
    user = User.objects.get(id=request.user.id)
 | 
			
		||||
    # user = User.objects.get(id=request.user.id)
 | 
			
		||||
    publickeys = UserSSHKey.objects.filter(user_id=request.user.id)
 | 
			
		||||
    show_profile_edit_password = settings.SHOW_PROFILE_EDIT_PASSWORD
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -26,7 +28,7 @@ def profile(request):
 | 
			
		|||
            email = request.POST.get('email', '')
 | 
			
		||||
            user.first_name = username
 | 
			
		||||
            user.email = email
 | 
			
		||||
            user.save()
 | 
			
		||||
            request.user.save()
 | 
			
		||||
            return HttpResponseRedirect(request.get_full_path())
 | 
			
		||||
        if 'oldpasswd' in request.POST:
 | 
			
		||||
            oldpasswd = request.POST.get('oldpasswd', '')
 | 
			
		||||
| 
						 | 
				
			
			@ -36,11 +38,11 @@ def profile(request):
 | 
			
		|||
                error_messages.append("Passwords didn't enter")
 | 
			
		||||
            if password1 and password2 and password1 != password2:
 | 
			
		||||
                error_messages.append("Passwords don't match")
 | 
			
		||||
            if not user.check_password(oldpasswd):
 | 
			
		||||
            if not request.user.check_password(oldpasswd):
 | 
			
		||||
                error_messages.append("Old password is wrong!")
 | 
			
		||||
            if not error_messages:
 | 
			
		||||
                user.set_password(password1)
 | 
			
		||||
                user.save()
 | 
			
		||||
                request.user.set_password(password1)
 | 
			
		||||
                request.user.save()
 | 
			
		||||
                return HttpResponseRedirect(request.get_full_path())
 | 
			
		||||
        if 'keyname' in request.POST:
 | 
			
		||||
            keyname = request.POST.get('keyname', '')
 | 
			
		||||
| 
						 | 
				
			
			@ -67,85 +69,7 @@ def profile(request):
 | 
			
		|||
    return render(request, 'profile.html', locals())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def accounts(request):
 | 
			
		||||
    """
 | 
			
		||||
    :param request:
 | 
			
		||||
    :return:
 | 
			
		||||
    """
 | 
			
		||||
    if not request.user.is_superuser:
 | 
			
		||||
        return HttpResponseRedirect(reverse('index'))
 | 
			
		||||
 | 
			
		||||
    error_messages = []
 | 
			
		||||
    users = User.objects.all().order_by('username')
 | 
			
		||||
    allow_empty_password = settings.ALLOW_EMPTY_PASSWORD
 | 
			
		||||
 | 
			
		||||
    if request.method == 'POST':
 | 
			
		||||
        if 'create' in request.POST:
 | 
			
		||||
            form = UserAddForm(request.POST)
 | 
			
		||||
            if form.is_valid():
 | 
			
		||||
                data = form.cleaned_data
 | 
			
		||||
            else:
 | 
			
		||||
                for msg_err in form.errors.values():
 | 
			
		||||
                    error_messages.append(msg_err.as_text())
 | 
			
		||||
            if not error_messages:
 | 
			
		||||
                new_user = User.objects.create_user(data['name'], None, data['password'])
 | 
			
		||||
                new_user.save()
 | 
			
		||||
                UserAttributes.configure_user(new_user)
 | 
			
		||||
                return HttpResponseRedirect(request.get_full_path())
 | 
			
		||||
        if 'edit' in request.POST:
 | 
			
		||||
            CHECKBOX_MAPPING = {'on': True, 'off': False, }
 | 
			
		||||
 | 
			
		||||
            user_id = request.POST.get('user_id', '')
 | 
			
		||||
            user_pass = request.POST.get('user_pass', '')
 | 
			
		||||
            user_edit = User.objects.get(id=user_id)
 | 
			
		||||
 | 
			
		||||
            if user_pass != '': user_edit.set_password(user_pass)
 | 
			
		||||
            user_edit.is_staff = CHECKBOX_MAPPING.get(request.POST.get('user_is_staff', 'off'))
 | 
			
		||||
            user_edit.is_superuser = CHECKBOX_MAPPING.get(request.POST.get('user_is_superuser', 'off'))
 | 
			
		||||
            user_edit.save()
 | 
			
		||||
 | 
			
		||||
            UserAttributes.create_missing_userattributes(user_edit)
 | 
			
		||||
            user_edit.userattributes.can_clone_instances = CHECKBOX_MAPPING.get(request.POST.get('userattributes_can_clone_instances', 'off'))
 | 
			
		||||
            user_edit.userattributes.max_instances = request.POST.get('userattributes_max_instances', 0)
 | 
			
		||||
            user_edit.userattributes.max_cpus = request.POST.get('userattributes_max_cpus', 0)
 | 
			
		||||
            user_edit.userattributes.max_memory = request.POST.get('userattributes_max_memory', 0)
 | 
			
		||||
            user_edit.userattributes.max_disk_size = request.POST.get('userattributes_max_disk_size', 0)
 | 
			
		||||
 | 
			
		||||
            try:
 | 
			
		||||
                user_edit.userattributes.clean_fields()
 | 
			
		||||
            except ValidationError as exc:
 | 
			
		||||
                error_messages.append(exc)
 | 
			
		||||
            else:
 | 
			
		||||
                user_edit.userattributes.save()
 | 
			
		||||
                return HttpResponseRedirect(request.get_full_path())
 | 
			
		||||
        if 'block' in request.POST:
 | 
			
		||||
            user_id = request.POST.get('user_id', '')
 | 
			
		||||
            user_block = User.objects.get(id=user_id)
 | 
			
		||||
            user_block.is_active = False
 | 
			
		||||
            user_block.save()
 | 
			
		||||
            return HttpResponseRedirect(request.get_full_path())
 | 
			
		||||
        if 'unblock' in request.POST:
 | 
			
		||||
            user_id = request.POST.get('user_id', '')
 | 
			
		||||
            user_unblock = User.objects.get(id=user_id)
 | 
			
		||||
            user_unblock.is_active = True
 | 
			
		||||
            user_unblock.save()
 | 
			
		||||
            return HttpResponseRedirect(request.get_full_path())
 | 
			
		||||
        if 'delete' in request.POST:
 | 
			
		||||
            user_id = request.POST.get('user_id', '')
 | 
			
		||||
            try:
 | 
			
		||||
                del_user_inst = UserInstance.objects.filter(user_id=user_id)
 | 
			
		||||
                del_user_inst.delete()
 | 
			
		||||
            finally:
 | 
			
		||||
                user_delete = User.objects.get(id=user_id)
 | 
			
		||||
                user_delete.delete()
 | 
			
		||||
            return HttpResponseRedirect(request.get_full_path())
 | 
			
		||||
 | 
			
		||||
    accounts_template_file = 'accounts.html'
 | 
			
		||||
    if settings.VIEW_ACCOUNTS_STYLE == "list":
 | 
			
		||||
        accounts_template_file = 'accounts-list.html'
 | 
			
		||||
    return render(request, accounts_template_file, locals())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@superuser_only
 | 
			
		||||
def account(request, user_id):
 | 
			
		||||
    """
 | 
			
		||||
    :param request:
 | 
			
		||||
| 
						 | 
				
			
			@ -153,9 +77,6 @@ def account(request, user_id):
 | 
			
		|||
    :return:
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    if not request.user.is_superuser:
 | 
			
		||||
        return HttpResponseRedirect(reverse('index'))
 | 
			
		||||
 | 
			
		||||
    error_messages = []
 | 
			
		||||
    user = User.objects.get(id=user_id)
 | 
			
		||||
    user_insts = UserInstance.objects.filter(user_id=user_id)
 | 
			
		||||
| 
						 | 
				
			
			@ -181,12 +102,12 @@ def account(request, user_id):
 | 
			
		|||
            return HttpResponseRedirect(request.get_full_path())
 | 
			
		||||
        if 'add' in request.POST:
 | 
			
		||||
            inst_id = request.POST.get('inst_id', '')
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            if settings.ALLOW_INSTANCE_MULTIPLE_OWNER:
 | 
			
		||||
                check_inst = UserInstance.objects.filter(instance_id=int(inst_id), user_id=int(user_id))
 | 
			
		||||
            else:
 | 
			
		||||
                check_inst = UserInstance.objects.filter(instance_id=int(inst_id))
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            if check_inst:
 | 
			
		||||
                msg = _("Instance already added")
 | 
			
		||||
                error_messages.append(msg)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										5
									
								
								admin/apps.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								admin/apps.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
from django.apps import AppConfig
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AdminConfig(AppConfig):
 | 
			
		||||
    name = 'admin'
 | 
			
		||||
							
								
								
									
										10
									
								
								admin/decorators.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								admin/decorators.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,10 @@
 | 
			
		|||
from django.core.exceptions import PermissionDenied
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def superuser_only(function):
 | 
			
		||||
    def _inner(request, *args, **kwargs):
 | 
			
		||||
        if not request.user.is_superuser:
 | 
			
		||||
            raise PermissionDenied
 | 
			
		||||
        return function(request, *args, **kwargs)
 | 
			
		||||
 | 
			
		||||
    return _inner
 | 
			
		||||
							
								
								
									
										94
									
								
								admin/forms.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								admin/forms.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,94 @@
 | 
			
		|||
from django import forms
 | 
			
		||||
from django.contrib.auth.models import Group, User
 | 
			
		||||
from django.utils.translation import ugettext_lazy as _
 | 
			
		||||
 | 
			
		||||
from accounts.models import UserAttributes
 | 
			
		||||
 | 
			
		||||
from .models import Permission
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GroupForm(forms.ModelForm):
 | 
			
		||||
    permissions = forms.ModelMultipleChoiceField(
 | 
			
		||||
        widget=forms.CheckboxSelectMultiple,
 | 
			
		||||
        queryset=Permission.objects.filter(content_type__model='permissionset'),
 | 
			
		||||
        required=False,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    users = forms.ModelMultipleChoiceField(
 | 
			
		||||
        widget=forms.CheckboxSelectMultiple,
 | 
			
		||||
        queryset=User.objects.all(),
 | 
			
		||||
        required=False,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        super(GroupForm, self).__init__(*args, **kwargs)
 | 
			
		||||
        instance = getattr(self, 'instance', None)
 | 
			
		||||
        if instance and instance.id:
 | 
			
		||||
            self.fields['users'].initial = self.instance.user_set.all()
 | 
			
		||||
 | 
			
		||||
    def save_m2m(self):
 | 
			
		||||
        self.instance.user_set.set(self.cleaned_data['users'])
 | 
			
		||||
 | 
			
		||||
    def save(self, *args, **kwargs):
 | 
			
		||||
        instance = super(GroupForm, self).save()
 | 
			
		||||
        self.save_m2m()
 | 
			
		||||
        return instance
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        model = Group
 | 
			
		||||
        fields = '__all__'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UserForm(forms.ModelForm):
 | 
			
		||||
    user_permissions = forms.ModelMultipleChoiceField(
 | 
			
		||||
        widget=forms.CheckboxSelectMultiple,
 | 
			
		||||
        queryset=Permission.objects.filter(content_type__model='permissionset'),
 | 
			
		||||
        label=_('Permissions'),
 | 
			
		||||
        required=False,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    groups = forms.ModelMultipleChoiceField(
 | 
			
		||||
        widget=forms.CheckboxSelectMultiple,
 | 
			
		||||
        queryset=Group.objects.all(),
 | 
			
		||||
        label=_('Groups'),
 | 
			
		||||
        required=False,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        model = User
 | 
			
		||||
        fields = [
 | 
			
		||||
            'username',
 | 
			
		||||
            'groups',
 | 
			
		||||
            'first_name',
 | 
			
		||||
            'last_name',
 | 
			
		||||
            'email',
 | 
			
		||||
            'user_permissions',
 | 
			
		||||
            'is_staff',
 | 
			
		||||
            'is_active',
 | 
			
		||||
            'is_superuser',
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UserCreateForm(UserForm):
 | 
			
		||||
    password = forms.CharField(widget=forms.PasswordInput)
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        model = User
 | 
			
		||||
        fields = [
 | 
			
		||||
            'username',
 | 
			
		||||
            'password',
 | 
			
		||||
            'groups',
 | 
			
		||||
            'first_name',
 | 
			
		||||
            'last_name',
 | 
			
		||||
            'email',
 | 
			
		||||
            'user_permissions',
 | 
			
		||||
            'is_staff',
 | 
			
		||||
            'is_active',
 | 
			
		||||
            'is_superuser',
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UserAttributesForm(forms.ModelForm):
 | 
			
		||||
    class Meta:
 | 
			
		||||
        model = UserAttributes
 | 
			
		||||
        exclude = ['user']
 | 
			
		||||
							
								
								
									
										30
									
								
								admin/migrations/0001_initial.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								admin/migrations/0001_initial.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,30 @@
 | 
			
		|||
# Generated by Django 2.2.12 on 2020-05-27 07:01
 | 
			
		||||
 | 
			
		||||
import django.contrib.auth.models
 | 
			
		||||
from django.db import migrations
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    initial = True
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ('auth', '0011_update_proxy_permissions'),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name='Permission',
 | 
			
		||||
            fields=[
 | 
			
		||||
            ],
 | 
			
		||||
            options={
 | 
			
		||||
                'proxy': True,
 | 
			
		||||
                'indexes': [],
 | 
			
		||||
                'constraints': [],
 | 
			
		||||
            },
 | 
			
		||||
            bases=('auth.permission',),
 | 
			
		||||
            managers=[
 | 
			
		||||
                ('objects', django.contrib.auth.models.PermissionManager()),
 | 
			
		||||
            ],
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
							
								
								
									
										0
									
								
								admin/migrations/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								admin/migrations/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										11
									
								
								admin/models.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								admin/models.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
from django.contrib.auth.models import Permission as P
 | 
			
		||||
 | 
			
		||||
class Permission(P):
 | 
			
		||||
    """
 | 
			
		||||
    Proxy model to Django Permissions model allows us to override __str__
 | 
			
		||||
    """
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return f'{self.content_type.app_label}: {self.name}'
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        proxy = True
 | 
			
		||||
							
								
								
									
										19
									
								
								admin/templates/admin/common/confirm_delete.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								admin/templates/admin/common/confirm_delete.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,19 @@
 | 
			
		|||
{% extends "base.html" %}
 | 
			
		||||
{% load bootstrap3 %}
 | 
			
		||||
{% load font_awesome %}
 | 
			
		||||
{% load i18n %}
 | 
			
		||||
 | 
			
		||||
{% block title %}{%trans "Delete" %}{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
<form method="post">
 | 
			
		||||
    {% csrf_token %}
 | 
			
		||||
    <div class="alert alert-warning">
 | 
			
		||||
        {%trans "Are you sure you want to delete" %} "{{ object }}"?
 | 
			
		||||
    </div>
 | 
			
		||||
    <a class="btn btn-primary" href="javascript:history.back()">{% icon 'times' %} {% trans "Cancel" %}</a>
 | 
			
		||||
    <button type="submit" class="btn btn-danger">
 | 
			
		||||
        {% icon 'check' %} {% trans "Delete" %}
 | 
			
		||||
    </button>
 | 
			
		||||
</form>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
							
								
								
									
										28
									
								
								admin/templates/admin/common/form.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								admin/templates/admin/common/form.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,28 @@
 | 
			
		|||
{% extends "base.html" %}
 | 
			
		||||
{% load bootstrap3 %}
 | 
			
		||||
{% load font_awesome %}
 | 
			
		||||
{% load i18n %}
 | 
			
		||||
 | 
			
		||||
{% block title %}{% trans "User" %}{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% 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 col-sm-offset-1">
 | 
			
		||||
        <form id="create-update" action="" method="post" class="form-horizontal">
 | 
			
		||||
            {% csrf_token %}
 | 
			
		||||
            {% bootstrap_form form layout='horizontal' %}
 | 
			
		||||
        </form>
 | 
			
		||||
        <div class="form-group pull-right">
 | 
			
		||||
            <a class="btn btn-primary" href="javascript:history.back()">{% icon 'times' %} {% trans "Cancel" %}</a>
 | 
			
		||||
            <button type="submit" form="create-update" class="btn btn-success">
 | 
			
		||||
                {% icon 'check' %} {% trans "Save" %}
 | 
			
		||||
            </button>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
{% endblock content %}
 | 
			
		||||
							
								
								
									
										28
									
								
								admin/templates/admin/common/list.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								admin/templates/admin/common/list.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,28 @@
 | 
			
		|||
{% extends "base.html" %}
 | 
			
		||||
{% load font_awesome %}
 | 
			
		||||
{% load i18n %}
 | 
			
		||||
 | 
			
		||||
{% block title %}{{ title }}{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
{% if create_url %}
 | 
			
		||||
<a class="btn btn-success pull-right" href="{% url create_url %}">{% icon 'plus' %} {%trans "Create New" %}</a>
 | 
			
		||||
{% endif %}
 | 
			
		||||
<table class="table table-hover table-striped">
 | 
			
		||||
    {% for object in object_list %}
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td>{{ object }}
 | 
			
		||||
            <div class="btn-group pull-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 %}
 | 
			
		||||
							
								
								
									
										63
									
								
								admin/templates/admin/group_list.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								admin/templates/admin/group_list.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,63 @@
 | 
			
		|||
{% extends "base.html" %}
 | 
			
		||||
{% load i18n %}
 | 
			
		||||
{% load static %}
 | 
			
		||||
{% load font_awesome %}
 | 
			
		||||
{% block title %}{% trans "Users" %}{% endblock %}
 | 
			
		||||
{% block content %}
 | 
			
		||||
<div class="row">
 | 
			
		||||
    <div class="col-lg-12">
 | 
			
		||||
        <a href="{% url 'admin:group_create' %}" class="btn btn-success btn-header pull-right">
 | 
			
		||||
            {% icon 'plus' %}
 | 
			
		||||
        </a>
 | 
			
		||||
        <div class="pull-right search">
 | 
			
		||||
            <input id="filter" class="form-control" type="text" placeholder="{% trans "Search" %}">
 | 
			
		||||
        </div>
 | 
			
		||||
        <h1 class="page-header">{% trans "Groups" %}</h1>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
{% include 'errors_block.html' %}
 | 
			
		||||
<div class="row">
 | 
			
		||||
    {% if not groups %}
 | 
			
		||||
        <div class="col-lg-12">
 | 
			
		||||
            <div class="alert alert-warning alert-dismissable">
 | 
			
		||||
                <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
 | 
			
		||||
                {% icon 'exclamation-triangle '%} <strong>{% trans "Warning" %}:</strong> {% trans "You don't have any groups" %}
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    {% else %}
 | 
			
		||||
        <div class="col-lg-12">
 | 
			
		||||
            <table class="table table-striped table-hover">
 | 
			
		||||
                <thead>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <th>{% trans "Group Name" %}</th>
 | 
			
		||||
                        <th>{% trans "Actions" %}</th>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                </thead>
 | 
			
		||||
                <tbody class="searchable">
 | 
			
		||||
                {% for group in groups %}
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <td>
 | 
			
		||||
                            <a href=""><strong>{{ group.name }}</strong></a>
 | 
			
		||||
                        </td>
 | 
			
		||||
                        <td>
 | 
			
		||||
                            <div class="pull-right btn-group">
 | 
			
		||||
                                <a class="btn btn-primary" href="{% url 'admin:group_update' group.id %}" title="{%trans "Edit" %}">
 | 
			
		||||
                                    {% icon 'pencil' %}
 | 
			
		||||
                                </a>
 | 
			
		||||
                                <a class="btn btn-danger" href="{% url 'admin:group_delete' group.id %}" title="{%trans "Delete" %}">
 | 
			
		||||
                                    {% icon 'times' %}
 | 
			
		||||
                                </a>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                {% endfor %}
 | 
			
		||||
                </tbody>
 | 
			
		||||
            </table>
 | 
			
		||||
        </div>
 | 
			
		||||
    {% endif %}
 | 
			
		||||
</div>
 | 
			
		||||
{% endblock content %}
 | 
			
		||||
 | 
			
		||||
{% block script %}
 | 
			
		||||
<script src="{% static "js/filter-table.js" %}"></script>
 | 
			
		||||
{% endblock script %}
 | 
			
		||||
							
								
								
									
										29
									
								
								admin/templates/admin/user_form.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								admin/templates/admin/user_form.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,29 @@
 | 
			
		|||
{% extends "base.html" %}
 | 
			
		||||
{% load bootstrap3 %}
 | 
			
		||||
{% load font_awesome %}
 | 
			
		||||
{% load i18n %}
 | 
			
		||||
 | 
			
		||||
{% block title %}{% trans "User" %}{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% 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 col-sm-offset-1">
 | 
			
		||||
        <form id="create-update" action="" method="post" class="form-horizontal">
 | 
			
		||||
            {% csrf_token %}
 | 
			
		||||
            {% bootstrap_form user_form layout='horizontal' %}
 | 
			
		||||
            {% bootstrap_form attributes_form layout='horizontal' %}
 | 
			
		||||
        </form>
 | 
			
		||||
        <div class="form-group pull-right">
 | 
			
		||||
            <a class="btn btn-primary" href="javascript:history.back()">{% icon 'times' %} {% trans "Cancel" %}</a>
 | 
			
		||||
            <button type="submit" form="create-update" class="btn btn-success">
 | 
			
		||||
                {% icon 'check' %} {% trans "Save" %}
 | 
			
		||||
            </button>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
{% endblock content %}
 | 
			
		||||
							
								
								
									
										79
									
								
								admin/templates/admin/user_list.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								admin/templates/admin/user_list.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,79 @@
 | 
			
		|||
{% extends "base.html" %}
 | 
			
		||||
{% load i18n %}
 | 
			
		||||
{% load static %}
 | 
			
		||||
{% load font_awesome %}
 | 
			
		||||
{% 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 pull-right">
 | 
			
		||||
            {% icon 'plus' %}
 | 
			
		||||
        </a>
 | 
			
		||||
        <div class="pull-right search">
 | 
			
		||||
            <input id="filter" class="form-control" type="text" placeholder="{% trans "Search" %}">
 | 
			
		||||
        </div>
 | 
			
		||||
        <h1 class="page-header">{% trans "Users" %}</h1>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
{% 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">×</button>
 | 
			
		||||
                {% icon 'exclamation-triangle '%} <strong>{% trans "Warning" %}:</strong> {% trans "You don't have any users" %}
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    {% else %}
 | 
			
		||||
        <div class="col-lg-12">
 | 
			
		||||
            <table class="table table-striped table-hover">
 | 
			
		||||
                <thead>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <th>{% trans "Username" %}</th>
 | 
			
		||||
                        <th>{% trans "Status" %}</th>
 | 
			
		||||
                        <th>{% trans "Staff" %}</th>
 | 
			
		||||
                        <th>{% trans "Superuser" %}</th>
 | 
			
		||||
                        <th>{% trans "Clone" %}</th>
 | 
			
		||||
                        <th>{% trans "" %}</th>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                </thead>
 | 
			
		||||
                <tbody class="searchable">
 | 
			
		||||
                {% for user in users %}
 | 
			
		||||
                    <tr class="{% if not user.is_active %}danger{% endif %}">
 | 
			
		||||
                        <td>
 | 
			
		||||
                            {{ user.username }}
 | 
			
		||||
                        </td>
 | 
			
		||||
                        <td>
 | 
			
		||||
                            {% if user.is_active %}
 | 
			
		||||
                                {% trans "Active" %}
 | 
			
		||||
                            {% else %}
 | 
			
		||||
                                {% trans "Blocked" %}
 | 
			
		||||
                            {% endif %}
 | 
			
		||||
                        </td>
 | 
			
		||||
                        <td>{% if user.is_staff %}{% icon 'check' %}{% endif %}</td>
 | 
			
		||||
                        <td>{% if user.is_superuser %}{% icon 'check' %}</span>{% endif %}</td>
 | 
			
		||||
                        <td>{% if user.userattributes.can_clone_instances %}{% icon 'check' %}{% endif %}</td>
 | 
			
		||||
                        <td>
 | 
			
		||||
                            <div class="pull-right btn-group">
 | 
			
		||||
                                <a class="btn btn-success" title="{%trans "View Profile" %}" href="{% url 'account' user.id %}">{% icon 'eye' %}</a>
 | 
			
		||||
                                <a class="btn btn-primary" title="{%trans "Edit" %}" href="{% url 'admin:user_update' user.id %}">{% icon 'pencil' %}</a>
 | 
			
		||||
                                {% if user.is_active %}
 | 
			
		||||
                                    <a class="btn btn-warning" title="{%trans "Block" %}" href="{% url 'admin:user_block' user.id %}">{% icon 'stop' %}</a>
 | 
			
		||||
                                {% else %}
 | 
			
		||||
                                    <a class="btn btn-success" title="{%trans "Unblock" %}" href="{% url 'admin:user_unblock' user.id %}">{% icon 'play' %}</a>
 | 
			
		||||
                                {% endif %}
 | 
			
		||||
                                <a class="btn btn-danger" title="{%trans "Delete" %}" href="{% url 'admin:user_delete' user.id %}">{% icon 'times' %}</a>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                {% endfor %}
 | 
			
		||||
                </tbody>
 | 
			
		||||
            </table>
 | 
			
		||||
        </div>
 | 
			
		||||
    {% endif %}
 | 
			
		||||
</div>
 | 
			
		||||
{% endblock content %}
 | 
			
		||||
 | 
			
		||||
{% block script %}
 | 
			
		||||
<script src="{% static "js/filter-table.js" %}"></script>
 | 
			
		||||
{% endblock script %}
 | 
			
		||||
							
								
								
									
										18
									
								
								admin/urls.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								admin/urls.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,18 @@
 | 
			
		|||
from django.urls import path
 | 
			
		||||
from django.contrib.auth.views import PasswordChangeView, PasswordChangeDoneView
 | 
			
		||||
 | 
			
		||||
from . import views
 | 
			
		||||
 | 
			
		||||
urlpatterns = [
 | 
			
		||||
    path('groups/', views.group_list, name='group_list'),
 | 
			
		||||
    path('groups/create/', views.group_create, name='group_create'),
 | 
			
		||||
    path('groups/<int:pk>/update/', views.group_update, name='group_update'),
 | 
			
		||||
    path('groups/<int:pk>/delete/', views.group_delete, name='group_delete'),
 | 
			
		||||
    path('users/', views.user_list, name='user_list'),
 | 
			
		||||
    path('users/create/', views.user_create, name='user_create'),
 | 
			
		||||
    path('users/<int:pk>/update/', views.user_update, name='user_update'),
 | 
			
		||||
    path('users/<int:pk>/delete/', views.user_delete, name='user_delete'),
 | 
			
		||||
    path('users/<int:pk>/block/', views.user_block, name='user_block'),
 | 
			
		||||
    path('users/<int:pk>/unblock/', views.user_unblock, name='user_unblock'),
 | 
			
		||||
    path('logs/', views.logs, name='logs'),
 | 
			
		||||
]
 | 
			
		||||
							
								
								
									
										171
									
								
								admin/views.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								admin/views.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,171 @@
 | 
			
		|||
from django.conf import settings
 | 
			
		||||
from django.contrib.auth.decorators import user_passes_test
 | 
			
		||||
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 accounts.models import UserAttributes
 | 
			
		||||
from logs.models import Logs
 | 
			
		||||
 | 
			
		||||
from . import forms
 | 
			
		||||
from .decorators import superuser_only
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@superuser_only
 | 
			
		||||
def group_list(request):
 | 
			
		||||
    groups = Group.objects.all()
 | 
			
		||||
    return render(
 | 
			
		||||
        request,
 | 
			
		||||
        'admin/group_list.html',
 | 
			
		||||
        {
 | 
			
		||||
            'groups': groups,
 | 
			
		||||
        },
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@superuser_only
 | 
			
		||||
def group_create(request):
 | 
			
		||||
    form = forms.GroupForm(request.POST or None)
 | 
			
		||||
    if form.is_valid():
 | 
			
		||||
        form.save()
 | 
			
		||||
        return redirect('admin:group_list')
 | 
			
		||||
    return render(
 | 
			
		||||
        request,
 | 
			
		||||
        'admin/common/form.html',
 | 
			
		||||
        {
 | 
			
		||||
            'form': form,
 | 
			
		||||
            'title': _('Create Group'),
 | 
			
		||||
        },
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@superuser_only
 | 
			
		||||
def group_update(request, pk):
 | 
			
		||||
    group = get_object_or_404(Group, pk=pk)
 | 
			
		||||
    form = forms.GroupForm(request.POST or None, instance=group)
 | 
			
		||||
    if form.is_valid():
 | 
			
		||||
        form.save()
 | 
			
		||||
        return redirect('admin:group_list')
 | 
			
		||||
 | 
			
		||||
    return render(
 | 
			
		||||
        request,
 | 
			
		||||
        'admin/common/form.html',
 | 
			
		||||
        {
 | 
			
		||||
            'form': form,
 | 
			
		||||
            'title': _('Update Group'),
 | 
			
		||||
        },
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@superuser_only
 | 
			
		||||
def group_delete(request, pk):
 | 
			
		||||
    group = get_object_or_404(Group, pk=pk)
 | 
			
		||||
    if request.method == 'POST':
 | 
			
		||||
        group.delete()
 | 
			
		||||
        return redirect('admin:group_list')
 | 
			
		||||
 | 
			
		||||
    return render(
 | 
			
		||||
        request,
 | 
			
		||||
        'admin/common/confirm_delete.html',
 | 
			
		||||
        {'object': group},
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@superuser_only
 | 
			
		||||
def user_list(request):
 | 
			
		||||
    users = User.objects.all()
 | 
			
		||||
    return render(
 | 
			
		||||
        request,
 | 
			
		||||
        'admin/user_list.html',
 | 
			
		||||
        {
 | 
			
		||||
            'users': users,
 | 
			
		||||
            'title': _('Users'),
 | 
			
		||||
        },
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@superuser_only
 | 
			
		||||
def user_create(request):
 | 
			
		||||
    user_form = forms.UserCreateForm(request.POST or None)
 | 
			
		||||
    attributes_form = forms.UserAttributesForm(request.POST or None)
 | 
			
		||||
    if user_form.is_valid() and attributes_form.is_valid():
 | 
			
		||||
        user = user_form.save()
 | 
			
		||||
        password = user_form.cleaned_data['password']
 | 
			
		||||
        user.set_password(password)
 | 
			
		||||
        user.save()
 | 
			
		||||
        attributes = attributes_form.save(commit=False)
 | 
			
		||||
        attributes.user = user
 | 
			
		||||
        attributes.save()
 | 
			
		||||
        return redirect('admin:user_list')
 | 
			
		||||
 | 
			
		||||
    return render(
 | 
			
		||||
        request,
 | 
			
		||||
        'admin/user_form.html',
 | 
			
		||||
        {
 | 
			
		||||
            'user_form': user_form,
 | 
			
		||||
            'attributes_form': attributes_form,
 | 
			
		||||
            'title': _('Create User')
 | 
			
		||||
        },
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@superuser_only
 | 
			
		||||
def user_update(request, pk):
 | 
			
		||||
    user = get_object_or_404(User, pk=pk)
 | 
			
		||||
    attributes = UserAttributes.objects.get(user=user)
 | 
			
		||||
    user_form = forms.UserForm(request.POST or None, instance=user)
 | 
			
		||||
    attributes_form = forms.UserAttributesForm(request.POST or None, instance=attributes)
 | 
			
		||||
    if user_form.is_valid() and attributes_form.is_valid():
 | 
			
		||||
        user_form.save()
 | 
			
		||||
        attributes_form.save()
 | 
			
		||||
        return redirect('admin:user_list')
 | 
			
		||||
 | 
			
		||||
    return render(
 | 
			
		||||
        request,
 | 
			
		||||
        'admin/user_form.html',
 | 
			
		||||
        {
 | 
			
		||||
            'user_form': user_form,
 | 
			
		||||
            'attributes_form': attributes_form,
 | 
			
		||||
            'title': _('Update User')
 | 
			
		||||
        },
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@superuser_only
 | 
			
		||||
def user_delete(request, pk):
 | 
			
		||||
    user = get_object_or_404(User, pk=pk)
 | 
			
		||||
    if request.method == 'POST':
 | 
			
		||||
        user.delete()
 | 
			
		||||
        return redirect('admin:user_list')
 | 
			
		||||
 | 
			
		||||
    return render(
 | 
			
		||||
        request,
 | 
			
		||||
        'admin/common/confirm_delete.html',
 | 
			
		||||
        {'object': user},
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@superuser_only
 | 
			
		||||
def user_block(request, pk):
 | 
			
		||||
    user: User = get_object_or_404(User, pk=pk)
 | 
			
		||||
    user.is_active = False
 | 
			
		||||
    user.save()
 | 
			
		||||
    return redirect('admin:user_list')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@superuser_only
 | 
			
		||||
def user_unblock(request, pk):
 | 
			
		||||
    user: User = get_object_or_404(User, pk=pk)
 | 
			
		||||
    user.is_active = True
 | 
			
		||||
    user.save()
 | 
			
		||||
    return redirect('admin:user_list')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@superuser_only
 | 
			
		||||
def logs(request):
 | 
			
		||||
    l = Logs.objects.order_by('-date')
 | 
			
		||||
    paginator = Paginator(l, settings.LOGS_PER_PAGE)
 | 
			
		||||
    page = request.GET.get('page', 1)
 | 
			
		||||
    logs = paginator.page(page)
 | 
			
		||||
    return render(request, 'admin/logs.html', {'logs': logs})
 | 
			
		||||
| 
						 | 
				
			
			@ -10,38 +10,37 @@ from computes.forms import ComputeAddTcpForm, ComputeAddSshForm, ComputeEditHost
 | 
			
		|||
from vrtManager.hostdetails import wvmHostDetails
 | 
			
		||||
from vrtManager.connection import CONN_SSH, CONN_TCP, CONN_TLS, CONN_SOCKET, connection_manager, wvmConnect
 | 
			
		||||
from libvirt import libvirtError
 | 
			
		||||
from admin.decorators import superuser_only
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@superuser_only
 | 
			
		||||
def computes(request):
 | 
			
		||||
    """
 | 
			
		||||
    :param request:
 | 
			
		||||
    :return:
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    if not request.user.is_superuser:
 | 
			
		||||
        return HttpResponseRedirect(reverse('index'))
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
                                 })
 | 
			
		||||
            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
 | 
			
		||||
 | 
			
		||||
    error_messages = []
 | 
			
		||||
    computes = Compute.objects.filter().order_by('name')
 | 
			
		||||
    computes_info = get_hosts_status(computes)
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    if request.method == 'POST':
 | 
			
		||||
        if 'host_del' in request.POST:
 | 
			
		||||
            compute_id = request.POST.get('host_id', '')
 | 
			
		||||
| 
						 | 
				
			
			@ -133,6 +132,7 @@ def computes(request):
 | 
			
		|||
    return render(request, 'computes.html', locals())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@superuser_only
 | 
			
		||||
def overview(request, compute_id):
 | 
			
		||||
    """
 | 
			
		||||
    :param request:
 | 
			
		||||
| 
						 | 
				
			
			@ -140,17 +140,16 @@ def overview(request, compute_id):
 | 
			
		|||
    :return:
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    if not request.user.is_superuser:
 | 
			
		||||
        return HttpResponseRedirect(reverse('index'))
 | 
			
		||||
 | 
			
		||||
    error_messages = []
 | 
			
		||||
    compute = get_object_or_404(Compute, pk=compute_id)
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        conn = wvmHostDetails(compute.hostname,
 | 
			
		||||
                              compute.login,
 | 
			
		||||
                              compute.password,
 | 
			
		||||
                              compute.type)
 | 
			
		||||
        conn = wvmHostDetails(
 | 
			
		||||
            compute.hostname,
 | 
			
		||||
            compute.login,
 | 
			
		||||
            compute.password,
 | 
			
		||||
            compute.type,
 | 
			
		||||
        )
 | 
			
		||||
        hostname, host_arch, host_memory, logical_cpu, model_cpu, uri_conn = conn.get_node_info()
 | 
			
		||||
        hypervisor = conn.get_hypervisors_domain_types()
 | 
			
		||||
        mem_usage = conn.get_memory_usage()
 | 
			
		||||
| 
						 | 
				
			
			@ -172,10 +171,12 @@ def compute_graph(request, compute_id):
 | 
			
		|||
    """
 | 
			
		||||
    compute = get_object_or_404(Compute, pk=compute_id)
 | 
			
		||||
    try:
 | 
			
		||||
        conn = wvmHostDetails(compute.hostname,
 | 
			
		||||
                              compute.login,
 | 
			
		||||
                              compute.password,
 | 
			
		||||
                              compute.type)
 | 
			
		||||
        conn = wvmHostDetails(
 | 
			
		||||
            compute.hostname,
 | 
			
		||||
            compute.login,
 | 
			
		||||
            compute.password,
 | 
			
		||||
            compute.type,
 | 
			
		||||
        )
 | 
			
		||||
        current_time = timezone.now().strftime("%H:%M:%S")
 | 
			
		||||
        cpu_usage = conn.get_cpu_usage()
 | 
			
		||||
        mem_usage = conn.get_memory_usage()
 | 
			
		||||
| 
						 | 
				
			
			@ -184,9 +185,11 @@ def compute_graph(request, compute_id):
 | 
			
		|||
        cpu_usage = {'usage': 0}
 | 
			
		||||
        mem_usage = {'usage': 0}
 | 
			
		||||
 | 
			
		||||
    data = json.dumps({'cpudata': cpu_usage['usage'],
 | 
			
		||||
                       'memdata': mem_usage,
 | 
			
		||||
                       'timeline': current_time})
 | 
			
		||||
    data = json.dumps({
 | 
			
		||||
        'cpudata': cpu_usage['usage'],
 | 
			
		||||
        'memdata': mem_usage,
 | 
			
		||||
        'timeline': current_time,
 | 
			
		||||
    })
 | 
			
		||||
    response = HttpResponse()
 | 
			
		||||
    response['Content-Type'] = "text/javascript"
 | 
			
		||||
    response.write(data)
 | 
			
		||||
| 
						 | 
				
			
			@ -197,10 +200,12 @@ def get_compute_disk_buses(request, compute_id, arch, machine, disk):
 | 
			
		|||
    data = dict()
 | 
			
		||||
    compute = get_object_or_404(Compute, pk=compute_id)
 | 
			
		||||
    try:
 | 
			
		||||
        conn = wvmConnect(compute.hostname,
 | 
			
		||||
                          compute.login,
 | 
			
		||||
                          compute.password,
 | 
			
		||||
                          compute.type)
 | 
			
		||||
        conn = wvmConnect(
 | 
			
		||||
            compute.hostname,
 | 
			
		||||
            compute.login,
 | 
			
		||||
            compute.password,
 | 
			
		||||
            compute.type,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        disk_device_types = conn.get_disk_device_types(arch, machine)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -223,10 +228,12 @@ def get_compute_machine_types(request, compute_id, arch):
 | 
			
		|||
    data = dict()
 | 
			
		||||
    try:
 | 
			
		||||
        compute = get_object_or_404(Compute, pk=compute_id)
 | 
			
		||||
        conn = wvmConnect(compute.hostname,
 | 
			
		||||
                          compute.login,
 | 
			
		||||
                          compute.password,
 | 
			
		||||
                          compute.type)
 | 
			
		||||
        conn = wvmConnect(
 | 
			
		||||
            compute.hostname,
 | 
			
		||||
            compute.login,
 | 
			
		||||
            compute.password,
 | 
			
		||||
            compute.type,
 | 
			
		||||
        )
 | 
			
		||||
        data['machines'] = conn.get_machine_types(arch)
 | 
			
		||||
    except libvirtError:
 | 
			
		||||
        pass
 | 
			
		||||
| 
						 | 
				
			
			@ -238,10 +245,12 @@ def get_compute_video_models(request, compute_id, arch, machine):
 | 
			
		|||
    data = dict()
 | 
			
		||||
    try:
 | 
			
		||||
        compute = get_object_or_404(Compute, pk=compute_id)
 | 
			
		||||
        conn = wvmConnect(compute.hostname,
 | 
			
		||||
                          compute.login,
 | 
			
		||||
                          compute.password,
 | 
			
		||||
                          compute.type)
 | 
			
		||||
        conn = wvmConnect(
 | 
			
		||||
            compute.hostname,
 | 
			
		||||
            compute.login,
 | 
			
		||||
            compute.password,
 | 
			
		||||
            compute.type,
 | 
			
		||||
        )
 | 
			
		||||
        data['videos'] = conn.get_video_models(arch, machine)
 | 
			
		||||
    except libvirtError:
 | 
			
		||||
        pass
 | 
			
		||||
| 
						 | 
				
			
			@ -253,10 +262,12 @@ def get_dom_capabilities(request, compute_id, arch, machine):
 | 
			
		|||
    data = dict()
 | 
			
		||||
    try:
 | 
			
		||||
        compute = get_object_or_404(Compute, pk=compute_id)
 | 
			
		||||
        conn = wvmConnect(compute.hostname,
 | 
			
		||||
                          compute.login,
 | 
			
		||||
                          compute.password,
 | 
			
		||||
                          compute.type)
 | 
			
		||||
        conn = wvmConnect(
 | 
			
		||||
            compute.hostname,
 | 
			
		||||
            compute.login,
 | 
			
		||||
            compute.password,
 | 
			
		||||
            compute.type,
 | 
			
		||||
        )
 | 
			
		||||
        data['videos'] = conn.get_disk_device_types(arch, machine)
 | 
			
		||||
        data['bus'] = conn.get_disk_device_types(arch, machine)
 | 
			
		||||
    except libvirtError:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,6 @@
 | 
			
		|||
Django==2.2.12
 | 
			
		||||
django-bootstrap3==12.1.0
 | 
			
		||||
django-fa==1.0.0
 | 
			
		||||
django-login-required-middleware==0.5.0
 | 
			
		||||
gunicorn==20.0.4
 | 
			
		||||
libvirt-python==6.1.0
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,13 +23,12 @@ from webvirtcloud.settings import INSTANCE_FIRMWARE_DEFAULT_TYPE
 | 
			
		|||
 | 
			
		||||
from django.contrib import messages
 | 
			
		||||
from logs.views import addlogmsg
 | 
			
		||||
from admin.decorators import superuser_only
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@superuser_only
 | 
			
		||||
def create_instance_select_type(request, compute_id):
 | 
			
		||||
 | 
			
		||||
    if not request.user.is_superuser:
 | 
			
		||||
        return HttpResponseRedirect(reverse('index'))
 | 
			
		||||
 | 
			
		||||
    conn = None
 | 
			
		||||
    error_messages = list()
 | 
			
		||||
    storages = list()
 | 
			
		||||
| 
						 | 
				
			
			@ -39,10 +38,7 @@ def create_instance_select_type(request, compute_id):
 | 
			
		|||
    compute = get_object_or_404(Compute, pk=compute_id)
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        conn = wvmCreate(compute.hostname,
 | 
			
		||||
                         compute.login,
 | 
			
		||||
                         compute.password,
 | 
			
		||||
                         compute.type)
 | 
			
		||||
        conn = wvmCreate(compute.hostname, compute.login, compute.password, compute.type)
 | 
			
		||||
        instances = conn.get_instances()
 | 
			
		||||
        all_hypervisors = conn.get_hypervisors_machines()
 | 
			
		||||
        # Supported hypervisors by webvirtcloud: i686, x86_64(for now)
 | 
			
		||||
| 
						 | 
				
			
			@ -74,6 +70,7 @@ def create_instance_select_type(request, compute_id):
 | 
			
		|||
    return render(request, 'create_instance_w1.html', locals())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@superuser_only
 | 
			
		||||
def create_instance(request, compute_id, arch, machine):
 | 
			
		||||
    """
 | 
			
		||||
    :param request:
 | 
			
		||||
| 
						 | 
				
			
			@ -82,8 +79,6 @@ def create_instance(request, compute_id, arch, machine):
 | 
			
		|||
    :param machine:
 | 
			
		||||
    :return:
 | 
			
		||||
    """
 | 
			
		||||
    if not request.user.is_superuser:
 | 
			
		||||
        return HttpResponseRedirect(reverse('index'))
 | 
			
		||||
 | 
			
		||||
    conn = None
 | 
			
		||||
    error_messages = list()
 | 
			
		||||
| 
						 | 
				
			
			@ -96,10 +91,7 @@ def create_instance(request, compute_id, arch, machine):
 | 
			
		|||
    flavors = Flavor.objects.filter().order_by('id')
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        conn = wvmCreate(compute.hostname,
 | 
			
		||||
                         compute.login,
 | 
			
		||||
                         compute.password,
 | 
			
		||||
                         compute.type)
 | 
			
		||||
        conn = wvmCreate(compute.hostname, compute.login, compute.password, compute.type)
 | 
			
		||||
 | 
			
		||||
        default_firmware = INSTANCE_FIRMWARE_DEFAULT_TYPE
 | 
			
		||||
        default_cpu_mode = INSTANCE_CPU_DEFAULT_MODE
 | 
			
		||||
| 
						 | 
				
			
			@ -150,10 +142,7 @@ def create_instance(request, compute_id, arch, machine):
 | 
			
		|||
                form = FlavorAddForm(request.POST)
 | 
			
		||||
                if form.is_valid():
 | 
			
		||||
                    data = form.cleaned_data
 | 
			
		||||
                    create_flavor = Flavor(label=data['label'],
 | 
			
		||||
                                           vcpu=data['vcpu'],
 | 
			
		||||
                                           memory=data['memory'],
 | 
			
		||||
                                           disk=data['disk'])
 | 
			
		||||
                    create_flavor = Flavor(label=data['label'], vcpu=data['vcpu'], memory=data['memory'], disk=data['disk'])
 | 
			
		||||
                    create_flavor.save()
 | 
			
		||||
                    return HttpResponseRedirect(request.get_full_path())
 | 
			
		||||
            if 'delete_flavor' in request.POST:
 | 
			
		||||
| 
						 | 
				
			
			@ -184,7 +173,9 @@ def create_instance(request, compute_id, arch, machine):
 | 
			
		|||
                                error_messages.append(error_msg)
 | 
			
		||||
                            else:
 | 
			
		||||
                                try:
 | 
			
		||||
                                    path = conn.create_volume(data['storage'], data['name'], data['hdd_size'],
 | 
			
		||||
                                    path = conn.create_volume(data['storage'],
 | 
			
		||||
                                                              data['name'],
 | 
			
		||||
                                                              data['hdd_size'],
 | 
			
		||||
                                                              metadata=meta_prealloc)
 | 
			
		||||
                                    volume = dict()
 | 
			
		||||
                                    volume['path'] = path
 | 
			
		||||
| 
						 | 
				
			
			@ -203,7 +194,10 @@ def create_instance(request, compute_id, arch, machine):
 | 
			
		|||
                                error_msg = _("Image has already exist. Please check volumes or change instance name")
 | 
			
		||||
                                error_messages.append(error_msg)
 | 
			
		||||
                            else:
 | 
			
		||||
                                clone_path = conn.clone_from_template(data['name'], templ_path, data['storage'], metadata=meta_prealloc)
 | 
			
		||||
                                clone_path = conn.clone_from_template(data['name'],
 | 
			
		||||
                                                                      templ_path,
 | 
			
		||||
                                                                      data['storage'],
 | 
			
		||||
                                                                      metadata=meta_prealloc)
 | 
			
		||||
                                volume = dict()
 | 
			
		||||
                                volume['path'] = clone_path
 | 
			
		||||
                                volume['type'] = conn.get_volume_type(clone_path)
 | 
			
		||||
| 
						 | 
				
			
			@ -238,23 +232,36 @@ def create_instance(request, compute_id, arch, machine):
 | 
			
		|||
                            firmware["readonly"] = 'yes'
 | 
			
		||||
                            firmware["type"] = 'pflash'
 | 
			
		||||
                            if 'secboot' in firmware["loader"] and machine != 'q35':
 | 
			
		||||
                                messages.warning(request, "Changing machine type from '%s' to 'q35' "
 | 
			
		||||
                                                          "which is required for UEFI secure boot." % machine)
 | 
			
		||||
                                messages.warning(
 | 
			
		||||
                                    request, "Changing machine type from '%s' to 'q35' "
 | 
			
		||||
                                    "which is required for UEFI secure boot." % machine)
 | 
			
		||||
                                machine = 'q35'
 | 
			
		||||
                                firmware["secure"] = 'yes'
 | 
			
		||||
 | 
			
		||||
                        if not error_messages:
 | 
			
		||||
                            uuid = util.randomUUID()
 | 
			
		||||
                            try:
 | 
			
		||||
                                conn.create_instance(name=data['name'], memory=data['memory'], vcpu=data['vcpu'],
 | 
			
		||||
                                                     vcpu_mode=data['vcpu_mode'], uuid=uuid, arch=arch, machine=machine,
 | 
			
		||||
                                conn.create_instance(name=data['name'],
 | 
			
		||||
                                                     memory=data['memory'],
 | 
			
		||||
                                                     vcpu=data['vcpu'],
 | 
			
		||||
                                                     vcpu_mode=data['vcpu_mode'],
 | 
			
		||||
                                                     uuid=uuid,
 | 
			
		||||
                                                     arch=arch,
 | 
			
		||||
                                                     machine=machine,
 | 
			
		||||
                                                     firmware=firmware,
 | 
			
		||||
                                                     images=volume_list, cache_mode=data['cache_mode'],
 | 
			
		||||
                                                     io_mode=default_io, discard_mode=default_discard, detect_zeroes_mode=default_zeroes,
 | 
			
		||||
                                                     networks=data['networks'], virtio=data['virtio'],
 | 
			
		||||
                                                     listen_addr=data["listener_addr"], nwfilter=data["nwfilter"],
 | 
			
		||||
                                                     graphics=data["graphics"], video=data["video"],
 | 
			
		||||
                                                     console_pass=data["console_pass"], mac=data['mac'],
 | 
			
		||||
                                                     images=volume_list,
 | 
			
		||||
                                                     cache_mode=data['cache_mode'],
 | 
			
		||||
                                                     io_mode=default_io,
 | 
			
		||||
                                                     discard_mode=default_discard,
 | 
			
		||||
                                                     detect_zeroes_mode=default_zeroes,
 | 
			
		||||
                                                     networks=data['networks'],
 | 
			
		||||
                                                     virtio=data['virtio'],
 | 
			
		||||
                                                     listen_addr=data["listener_addr"],
 | 
			
		||||
                                                     nwfilter=data["nwfilter"],
 | 
			
		||||
                                                     graphics=data["graphics"],
 | 
			
		||||
                                                     video=data["video"],
 | 
			
		||||
                                                     console_pass=data["console_pass"],
 | 
			
		||||
                                                     mac=data['mac'],
 | 
			
		||||
                                                     qemu_ga=data['qemu_ga'])
 | 
			
		||||
                                create_instance = Instance(compute_id=compute_id, name=data['name'], uuid=uuid)
 | 
			
		||||
                                create_instance.save()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,11 +0,0 @@
 | 
			
		|||
from django import template
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
register = template.Library()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@register.simple_tag
 | 
			
		||||
def class_active(request, pattern):
 | 
			
		||||
    if re.search(pattern, request.path):
 | 
			
		||||
        return 'class="active"'
 | 
			
		||||
    return ''
 | 
			
		||||
| 
						 | 
				
			
			@ -5,8 +5,10 @@ from computes.models import Compute
 | 
			
		|||
from interfaces.forms import AddInterface
 | 
			
		||||
from vrtManager.interface import wvmInterface, wvmInterfaces
 | 
			
		||||
from libvirt import libvirtError
 | 
			
		||||
from admin.decorators import superuser_only
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@superuser_only
 | 
			
		||||
def interfaces(request, compute_id):
 | 
			
		||||
    """
 | 
			
		||||
    :param request:
 | 
			
		||||
| 
						 | 
				
			
			@ -14,18 +16,12 @@ def interfaces(request, compute_id):
 | 
			
		|||
    :return:
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    if not request.user.is_superuser:
 | 
			
		||||
        return HttpResponseRedirect(reverse('index'))
 | 
			
		||||
 | 
			
		||||
    ifaces_all = []
 | 
			
		||||
    error_messages = []
 | 
			
		||||
    compute = get_object_or_404(Compute, pk=compute_id)
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        conn = wvmInterfaces(compute.hostname,
 | 
			
		||||
                             compute.login,
 | 
			
		||||
                             compute.password,
 | 
			
		||||
                             compute.type)
 | 
			
		||||
        conn = wvmInterfaces(compute.hostname, compute.login, compute.password, compute.type)
 | 
			
		||||
        ifaces = conn.get_ifaces()
 | 
			
		||||
        try:
 | 
			
		||||
            netdevs = conn.get_net_devices()
 | 
			
		||||
| 
						 | 
				
			
			@ -40,10 +36,9 @@ def interfaces(request, compute_id):
 | 
			
		|||
                form = AddInterface(request.POST)
 | 
			
		||||
                if form.is_valid():
 | 
			
		||||
                    data = form.cleaned_data
 | 
			
		||||
                    conn.create_iface(data['name'], data['itype'], data['start_mode'], data['netdev'],
 | 
			
		||||
                                      data['ipv4_type'], data['ipv4_addr'], data['ipv4_gw'],
 | 
			
		||||
                                      data['ipv6_type'], data['ipv6_addr'], data['ipv6_gw'],
 | 
			
		||||
                                      data['stp'], data['delay'])
 | 
			
		||||
                    conn.create_iface(data['name'], data['itype'], data['start_mode'], data['netdev'], data['ipv4_type'],
 | 
			
		||||
                                      data['ipv4_addr'], data['ipv4_gw'], data['ipv6_type'], data['ipv6_addr'],
 | 
			
		||||
                                      data['ipv6_gw'], data['stp'], data['delay'])
 | 
			
		||||
                    return HttpResponseRedirect(request.get_full_path())
 | 
			
		||||
                else:
 | 
			
		||||
                    for msg_err in form.errors.values():
 | 
			
		||||
| 
						 | 
				
			
			@ -55,6 +50,7 @@ def interfaces(request, compute_id):
 | 
			
		|||
    return render(request, 'interfaces.html', locals())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@superuser_only
 | 
			
		||||
def interface(request, compute_id, iface):
 | 
			
		||||
    """
 | 
			
		||||
    :param request:
 | 
			
		||||
| 
						 | 
				
			
			@ -63,19 +59,12 @@ def interface(request, compute_id, iface):
 | 
			
		|||
    :return:
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    if not request.user.is_superuser:
 | 
			
		||||
        return HttpResponseRedirect(reverse('index'))
 | 
			
		||||
 | 
			
		||||
    ifaces_all = []
 | 
			
		||||
    error_messages = []
 | 
			
		||||
    compute = get_object_or_404(Compute, pk=compute_id)
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        conn = wvmInterface(compute.hostname,
 | 
			
		||||
                            compute.login,
 | 
			
		||||
                            compute.password,
 | 
			
		||||
                            compute.type,
 | 
			
		||||
                            iface)
 | 
			
		||||
        conn = wvmInterface(compute.hostname, compute.login, compute.password, compute.type, iface)
 | 
			
		||||
        start_mode = conn.get_start_mode()
 | 
			
		||||
        state = conn.is_active()
 | 
			
		||||
        mac = conn.get_mac()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,5 @@ from django.urls import path, re_path
 | 
			
		|||
from . import views
 | 
			
		||||
 | 
			
		||||
urlpatterns = [
 | 
			
		||||
    path('', views.showlogs, name='showlogs'),
 | 
			
		||||
    re_path(r'^(?P<page>[0-9]+)/$', views.showlogs, name='showlogspage'),
 | 
			
		||||
    re_path(r'^vm_logs/(?P<vname>[\w\-\.]+)/$', views.vm_logs, name='vm_logs'),
 | 
			
		||||
]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,10 +1,13 @@
 | 
			
		|||
from django.shortcuts import render
 | 
			
		||||
import json
 | 
			
		||||
 | 
			
		||||
from django.conf import settings
 | 
			
		||||
from django.http import HttpResponse, HttpResponseRedirect
 | 
			
		||||
from django.shortcuts import render
 | 
			
		||||
from django.urls import reverse
 | 
			
		||||
 | 
			
		||||
from admin.decorators import superuser_only
 | 
			
		||||
from instances.models import Instance
 | 
			
		||||
from logs.models import Logs
 | 
			
		||||
from django.conf import settings
 | 
			
		||||
import json
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def addlogmsg(user, instance, message):
 | 
			
		||||
| 
						 | 
				
			
			@ -18,35 +21,13 @@ def addlogmsg(user, instance, message):
 | 
			
		|||
    add_log_msg.save()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def showlogs(request, page=1):
 | 
			
		||||
    """
 | 
			
		||||
    :param request:
 | 
			
		||||
    :param page:
 | 
			
		||||
    :return:
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    if not request.user.is_superuser:
 | 
			
		||||
        return HttpResponseRedirect(reverse('index'))
 | 
			
		||||
 | 
			
		||||
    page = int(page)
 | 
			
		||||
    limit_from = (page-1)*settings.LOGS_PER_PAGE
 | 
			
		||||
    limit_to = page*settings.LOGS_PER_PAGE
 | 
			
		||||
    logs = Logs.objects.all().order_by('-date')[limit_from:limit_to+1]
 | 
			
		||||
    has_next_page = logs.count() > settings.LOGS_PER_PAGE
 | 
			
		||||
    # TODO: remove last element from queryset, but do not affect database
 | 
			
		||||
 | 
			
		||||
    return render(request, 'showlogs.html', locals())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@superuser_only
 | 
			
		||||
def vm_logs(request, vname):
 | 
			
		||||
    """
 | 
			
		||||
    :param request:
 | 
			
		||||
    :param vname:
 | 
			
		||||
    :return:
 | 
			
		||||
    """
 | 
			
		||||
    
 | 
			
		||||
    if not request.user.is_superuser:
 | 
			
		||||
        return HttpResponseRedirect(reverse('index'))
 | 
			
		||||
 | 
			
		||||
    vm = Instance.objects.get(name=vname)
 | 
			
		||||
    logs_ = Logs.objects.filter(instance=vm.name, date__gte=vm.created).order_by('-date')
 | 
			
		||||
| 
						 | 
				
			
			@ -58,5 +39,5 @@ def vm_logs(request, vname):
 | 
			
		|||
        log['message'] = l.message
 | 
			
		||||
        log['date'] = l.date.strftime('%x %X')
 | 
			
		||||
        logs.append(log)
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    return HttpResponse(json.dumps(logs))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,15 +1,17 @@
 | 
			
		|||
from django.shortcuts import render, get_object_or_404
 | 
			
		||||
from django.contrib import messages
 | 
			
		||||
from django.http import HttpResponseRedirect
 | 
			
		||||
from django.utils.translation import ugettext_lazy as _
 | 
			
		||||
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 networks.forms import AddNetPool
 | 
			
		||||
from vrtManager.network import wvmNetwork, wvmNetworks
 | 
			
		||||
from vrtManager.network import network_size
 | 
			
		||||
from libvirt import libvirtError
 | 
			
		||||
from django.contrib import messages
 | 
			
		||||
from vrtManager.network import network_size, wvmNetwork, wvmNetworks
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@superuser_only
 | 
			
		||||
def networks(request, compute_id):
 | 
			
		||||
    """
 | 
			
		||||
    :param request:
 | 
			
		||||
| 
						 | 
				
			
			@ -17,17 +19,16 @@ def networks(request, compute_id):
 | 
			
		|||
    :return:
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    if not request.user.is_superuser:
 | 
			
		||||
        return HttpResponseRedirect(reverse('index'))
 | 
			
		||||
 | 
			
		||||
    error_messages = []
 | 
			
		||||
    compute = get_object_or_404(Compute, pk=compute_id)
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        conn = wvmNetworks(compute.hostname,
 | 
			
		||||
                           compute.login,
 | 
			
		||||
                           compute.password,
 | 
			
		||||
                           compute.type)
 | 
			
		||||
        conn = wvmNetworks(
 | 
			
		||||
            compute.hostname,
 | 
			
		||||
            compute.login,
 | 
			
		||||
            compute.password,
 | 
			
		||||
            compute.type,
 | 
			
		||||
        )
 | 
			
		||||
        networks = conn.get_networks_info()
 | 
			
		||||
        dhcp4 = netmask4 = gateway4 = ''
 | 
			
		||||
        dhcp6 = prefix6 = gateway6 = ''
 | 
			
		||||
| 
						 | 
				
			
			@ -52,11 +53,21 @@ def networks(request, compute_id):
 | 
			
		|||
                        if prefix6 != '64':
 | 
			
		||||
                            error_messages.append(_('For libvirt, the IPv6 network prefix must be /64'))
 | 
			
		||||
                    if not error_messages:
 | 
			
		||||
                        conn.create_network(data['name'],
 | 
			
		||||
                                            data['forward'],
 | 
			
		||||
                                            ipv4, gateway4, netmask4, dhcp4,
 | 
			
		||||
                                            ipv6, gateway6, prefix6, dhcp6,
 | 
			
		||||
                                            data['bridge_name'], data['openvswitch'], data['fixed'])
 | 
			
		||||
                        conn.create_network(
 | 
			
		||||
                            data['name'],
 | 
			
		||||
                            data['forward'],
 | 
			
		||||
                            ipv4,
 | 
			
		||||
                            gateway4,
 | 
			
		||||
                            netmask4,
 | 
			
		||||
                            dhcp4,
 | 
			
		||||
                            ipv6,
 | 
			
		||||
                            gateway6,
 | 
			
		||||
                            prefix6,
 | 
			
		||||
                            dhcp6,
 | 
			
		||||
                            data['bridge_name'],
 | 
			
		||||
                            data['openvswitch'],
 | 
			
		||||
                            data['fixed'],
 | 
			
		||||
                        )
 | 
			
		||||
                        return HttpResponseRedirect(reverse('network', args=[compute_id, data['name']]))
 | 
			
		||||
                else:
 | 
			
		||||
                    for msg_err in form.errors.values():
 | 
			
		||||
| 
						 | 
				
			
			@ -68,6 +79,7 @@ def networks(request, compute_id):
 | 
			
		|||
    return render(request, 'networks.html', locals())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@superuser_only
 | 
			
		||||
def network(request, compute_id, pool):
 | 
			
		||||
    """
 | 
			
		||||
    :param request:
 | 
			
		||||
| 
						 | 
				
			
			@ -76,18 +88,17 @@ def network(request, compute_id, pool):
 | 
			
		|||
    :return:
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    if not request.user.is_superuser:
 | 
			
		||||
        return HttpResponseRedirect(reverse('index'))
 | 
			
		||||
 | 
			
		||||
    error_messages = []
 | 
			
		||||
    compute = get_object_or_404(Compute, pk=compute_id)
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        conn = wvmNetwork(compute.hostname,
 | 
			
		||||
                          compute.login,
 | 
			
		||||
                          compute.password,
 | 
			
		||||
                          compute.type,
 | 
			
		||||
                          pool)
 | 
			
		||||
        conn = wvmNetwork(
 | 
			
		||||
            compute.hostname,
 | 
			
		||||
            compute.login,
 | 
			
		||||
            compute.password,
 | 
			
		||||
            compute.type,
 | 
			
		||||
            pool,
 | 
			
		||||
        )
 | 
			
		||||
        networks = conn.get_networks()
 | 
			
		||||
        state = conn.is_active()
 | 
			
		||||
        device = conn.get_bridge_device()
 | 
			
		||||
| 
						 | 
				
			
			@ -187,8 +198,7 @@ def network(request, compute_id, pool):
 | 
			
		|||
            if edit_xml:
 | 
			
		||||
                conn.edit_network(edit_xml)
 | 
			
		||||
                if conn.is_active():
 | 
			
		||||
                    messages.success(request, _("Network XML is changed. \\"
 | 
			
		||||
                                                "Stop and start network to activate new config."))
 | 
			
		||||
                    messages.success(request, _("Network XML is changed. \\" "Stop and start network to activate new config."))
 | 
			
		||||
                else:
 | 
			
		||||
                    messages.success(request, _("Network XML is changed."))
 | 
			
		||||
                return HttpResponseRedirect(request.get_full_path())
 | 
			
		||||
| 
						 | 
				
			
			@ -201,8 +211,10 @@ def network(request, compute_id, pool):
 | 
			
		|||
            try:
 | 
			
		||||
                conn.set_qos(qos_dir, average, peak, burst)
 | 
			
		||||
                if conn.is_active():
 | 
			
		||||
                    messages.success(request, _("{} Qos is set. Network XML is changed.").format(qos_dir.capitalize()) +
 | 
			
		||||
                                     _("Stop and start network to activate new config"))
 | 
			
		||||
                    messages.success(
 | 
			
		||||
                        request,
 | 
			
		||||
                        _("{} Qos is set. Network XML is changed.").format(qos_dir.capitalize()) +
 | 
			
		||||
                        _("Stop and start network to activate new config"))
 | 
			
		||||
                else:
 | 
			
		||||
                    messages.success(request, _("{} Qos is set").format(qos_dir.capitalize()))
 | 
			
		||||
            except libvirtError as lib_err:
 | 
			
		||||
| 
						 | 
				
			
			@ -213,8 +225,10 @@ def network(request, compute_id, pool):
 | 
			
		|||
            conn.unset_qos(qos_dir)
 | 
			
		||||
 | 
			
		||||
            if conn.is_active():
 | 
			
		||||
                messages.success(request, _("{} Qos is deleted. Network XML is changed. ").format(qos_dir.capitalize()) +
 | 
			
		||||
                                 _("Stop and start network to activate new config."))
 | 
			
		||||
                messages.success(
 | 
			
		||||
                    request,
 | 
			
		||||
                    _("{} Qos is deleted. Network XML is changed. ").format(qos_dir.capitalize()) +
 | 
			
		||||
                    _("Stop and start network to activate new config."))
 | 
			
		||||
            else:
 | 
			
		||||
                messages.success(request, _("{} Qos is deleted").format(qos_dir.capitalize()))
 | 
			
		||||
            return HttpResponseRedirect(request.get_full_path())
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,17 +2,20 @@
 | 
			
		|||
from __future__ import unicode_literals
 | 
			
		||||
 | 
			
		||||
from django.http import HttpResponseRedirect
 | 
			
		||||
from django.shortcuts import render, get_object_or_404
 | 
			
		||||
from django.utils.translation import ugettext_lazy as _
 | 
			
		||||
from django.shortcuts import get_object_or_404, render
 | 
			
		||||
from django.urls import reverse
 | 
			
		||||
from computes.models import Compute
 | 
			
		||||
from vrtManager import util
 | 
			
		||||
from vrtManager.nwfilters import wvmNWFilters, wvmNWFilter
 | 
			
		||||
from vrtManager.instance import wvmInstances, wvmInstance
 | 
			
		||||
from django.utils.translation import ugettext_lazy as _
 | 
			
		||||
from libvirt import libvirtError
 | 
			
		||||
 | 
			
		||||
from admin.decorators import superuser_only
 | 
			
		||||
from computes.models import Compute
 | 
			
		||||
from logs.views import addlogmsg
 | 
			
		||||
from vrtManager import util
 | 
			
		||||
from vrtManager.instance import wvmInstance, wvmInstances
 | 
			
		||||
from vrtManager.nwfilters import wvmNWFilter, wvmNWFilters
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@superuser_only
 | 
			
		||||
def nwfilters(request, compute_id):
 | 
			
		||||
    """
 | 
			
		||||
    :param request:
 | 
			
		||||
| 
						 | 
				
			
			@ -20,18 +23,12 @@ def nwfilters(request, compute_id):
 | 
			
		|||
    :return:
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    if not request.user.is_superuser:
 | 
			
		||||
        return HttpResponseRedirect(reverse('index'))
 | 
			
		||||
 | 
			
		||||
    error_messages = []
 | 
			
		||||
    nwfilters_all = []
 | 
			
		||||
    compute = get_object_or_404(Compute, pk=compute_id)
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        conn = wvmNWFilters(compute.hostname,
 | 
			
		||||
                            compute.login,
 | 
			
		||||
                            compute.password,
 | 
			
		||||
                            compute.type)
 | 
			
		||||
        conn = wvmNWFilters(compute.hostname, compute.login, compute.password, compute.type)
 | 
			
		||||
 | 
			
		||||
        if request.method == 'POST':
 | 
			
		||||
            if 'create_nwfilter' in request.POST:
 | 
			
		||||
| 
						 | 
				
			
			@ -105,9 +102,11 @@ def nwfilters(request, compute_id):
 | 
			
		|||
        error_messages.append(err)
 | 
			
		||||
        addlogmsg(request.user.username, compute.hostname, err)
 | 
			
		||||
 | 
			
		||||
    return render(request, 'nwfilters.html', {'error_messages': error_messages,
 | 
			
		||||
                                              'nwfilters': nwfilters_all,
 | 
			
		||||
                                              'compute': compute})
 | 
			
		||||
    return render(request, 'nwfilters.html', {
 | 
			
		||||
        'error_messages': error_messages,
 | 
			
		||||
        'nwfilters': nwfilters_all,
 | 
			
		||||
        'compute': compute
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def nwfilter(request, compute_id, nwfltr):
 | 
			
		||||
| 
						 | 
				
			
			@ -117,15 +116,8 @@ def nwfilter(request, compute_id, nwfltr):
 | 
			
		|||
    compute = get_object_or_404(Compute, pk=compute_id)
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        nwfilter = wvmNWFilter(compute.hostname,
 | 
			
		||||
                               compute.login,
 | 
			
		||||
                               compute.password,
 | 
			
		||||
                               compute.type,
 | 
			
		||||
                               nwfltr)
 | 
			
		||||
        conn = wvmNWFilters(compute.hostname,
 | 
			
		||||
                            compute.login,
 | 
			
		||||
                            compute.password,
 | 
			
		||||
                            compute.type)
 | 
			
		||||
        nwfilter = wvmNWFilter(compute.hostname, compute.login, compute.password, compute.type, nwfltr)
 | 
			
		||||
        conn = wvmNWFilters(compute.hostname, compute.login, compute.password, compute.type)
 | 
			
		||||
 | 
			
		||||
        for nwf in conn.get_nwfilters():
 | 
			
		||||
            nwfilters_all.append(conn.get_nwfilter_info(nwf))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,12 +1,16 @@
 | 
			
		|||
from django.shortcuts import render, get_object_or_404
 | 
			
		||||
from django.http import HttpResponseRedirect
 | 
			
		||||
from django.urls import reverse
 | 
			
		||||
from computes.models import Compute
 | 
			
		||||
from secrets.forms import AddSecret
 | 
			
		||||
from vrtManager.secrets import wvmSecrets
 | 
			
		||||
 | 
			
		||||
from django.http import HttpResponseRedirect
 | 
			
		||||
from django.shortcuts import get_object_or_404, render
 | 
			
		||||
from django.urls import reverse
 | 
			
		||||
from libvirt import libvirtError
 | 
			
		||||
 | 
			
		||||
from admin.decorators import superuser_only
 | 
			
		||||
from computes.models import Compute
 | 
			
		||||
from vrtManager.secrets import wvmSecrets
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@superuser_only
 | 
			
		||||
def secrets(request, compute_id):
 | 
			
		||||
    """
 | 
			
		||||
    :param request:
 | 
			
		||||
| 
						 | 
				
			
			@ -14,17 +18,11 @@ def secrets(request, compute_id):
 | 
			
		|||
    :return:
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    if not request.user.is_superuser:
 | 
			
		||||
        return HttpResponseRedirect(reverse('index'))
 | 
			
		||||
 | 
			
		||||
    secrets_all = []
 | 
			
		||||
    error_messages = []
 | 
			
		||||
    compute = get_object_or_404(Compute, pk=compute_id)
 | 
			
		||||
    try:
 | 
			
		||||
        conn = wvmSecrets(compute.hostname,
 | 
			
		||||
                          compute.login,
 | 
			
		||||
                          compute.password,
 | 
			
		||||
                          compute.type)
 | 
			
		||||
        conn = wvmSecrets(compute.hostname, compute.login, compute.password, compute.type)
 | 
			
		||||
        secrets = conn.get_secrets()
 | 
			
		||||
 | 
			
		||||
        for uuid in secrets:
 | 
			
		||||
| 
						 | 
				
			
			@ -33,11 +31,12 @@ def secrets(request, compute_id):
 | 
			
		|||
                secret_value = conn.get_secret_value(uuid)
 | 
			
		||||
            except libvirtError as lib_err:
 | 
			
		||||
                secret_value = None
 | 
			
		||||
            secrets_all.append({'usage': secrt.usageID(),
 | 
			
		||||
                                'uuid': secrt.UUIDString(),
 | 
			
		||||
                                'usageType': secrt.usageType(),
 | 
			
		||||
                                'value': secret_value
 | 
			
		||||
                                })
 | 
			
		||||
            secrets_all.append({
 | 
			
		||||
                'usage': secrt.usageID(),
 | 
			
		||||
                'uuid': secrt.UUIDString(),
 | 
			
		||||
                'usageType': secrt.usageType(),
 | 
			
		||||
                'value': secret_value
 | 
			
		||||
            })
 | 
			
		||||
        if request.method == 'POST':
 | 
			
		||||
            if 'create' in request.POST:
 | 
			
		||||
                form = AddSecret(request.POST)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -154,4 +154,15 @@ p {
 | 
			
		|||
 | 
			
		||||
.bottom-bar-margin {
 | 
			
		||||
    margin-top: 65px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.thumbnail {
 | 
			
		||||
    padding: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* make dropdowns show on hover */
 | 
			
		||||
@media only screen and (min-width: 768px) {
 | 
			
		||||
  .dropdown:hover .dropdown-menu {
 | 
			
		||||
    display: block;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								static/js/filter-table.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								static/js/filter-table.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
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));
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			@ -8,8 +8,10 @@ from vrtManager.storage import wvmStorage, wvmStorages
 | 
			
		|||
from libvirt import libvirtError
 | 
			
		||||
from django.contrib import messages
 | 
			
		||||
import json
 | 
			
		||||
from admin.decorators import superuser_only
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@superuser_only
 | 
			
		||||
def storages(request, compute_id):
 | 
			
		||||
    """
 | 
			
		||||
    :param request:
 | 
			
		||||
| 
						 | 
				
			
			@ -17,17 +19,11 @@ def storages(request, compute_id):
 | 
			
		|||
    :return:
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    if not request.user.is_superuser:
 | 
			
		||||
        return HttpResponseRedirect(reverse('index'))
 | 
			
		||||
 | 
			
		||||
    error_messages = []
 | 
			
		||||
    compute = get_object_or_404(Compute, pk=compute_id)
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        conn = wvmStorages(compute.hostname,
 | 
			
		||||
                           compute.login,
 | 
			
		||||
                           compute.password,
 | 
			
		||||
                           compute.type)
 | 
			
		||||
        conn = wvmStorages(compute.hostname, compute.login, compute.password, compute.type)
 | 
			
		||||
        storages = conn.get_storages_info()
 | 
			
		||||
        secrets = conn.get_secrets()
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -48,12 +44,10 @@ def storages(request, compute_id):
 | 
			
		|||
                            error_messages.append(msg)
 | 
			
		||||
                    if not error_messages:
 | 
			
		||||
                        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'])
 | 
			
		||||
                        elif data['stg_type'] == 'netfs':
 | 
			
		||||
                            conn.create_storage_netfs(data['stg_type'], data['name'],
 | 
			
		||||
                                                      data['netfs_host'], data['source'],
 | 
			
		||||
                            conn.create_storage_netfs(data['stg_type'], data['name'], data['netfs_host'], data['source'],
 | 
			
		||||
                                                      data['source_format'], data['target'])
 | 
			
		||||
                        else:
 | 
			
		||||
                            conn.create_storage(data['stg_type'], data['name'], data['source'], data['target'])
 | 
			
		||||
| 
						 | 
				
			
			@ -68,6 +62,7 @@ def storages(request, compute_id):
 | 
			
		|||
    return render(request, 'storages.html', locals())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@superuser_only
 | 
			
		||||
def storage(request, compute_id, pool):
 | 
			
		||||
    """
 | 
			
		||||
    :param request:
 | 
			
		||||
| 
						 | 
				
			
			@ -75,10 +70,6 @@ def storage(request, compute_id, pool):
 | 
			
		|||
    :param pool:
 | 
			
		||||
    :return:
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    if not request.user.is_superuser:
 | 
			
		||||
        return HttpResponseRedirect(reverse('index'))
 | 
			
		||||
 | 
			
		||||
    def handle_uploaded_file(path, f_name):
 | 
			
		||||
        target = path + '/' + str(f_name)
 | 
			
		||||
        destination = open(target, 'wb+')
 | 
			
		||||
| 
						 | 
				
			
			@ -91,11 +82,7 @@ def storage(request, compute_id, pool):
 | 
			
		|||
    meta_prealloc = False
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        conn = wvmStorage(compute.hostname,
 | 
			
		||||
                          compute.login,
 | 
			
		||||
                          compute.password,
 | 
			
		||||
                          compute.type,
 | 
			
		||||
                          pool)
 | 
			
		||||
        conn = wvmStorage(compute.hostname, compute.login, compute.password, compute.type, pool)
 | 
			
		||||
 | 
			
		||||
        storages = conn.get_storages()
 | 
			
		||||
        state = conn.is_active()
 | 
			
		||||
| 
						 | 
				
			
			@ -216,11 +203,7 @@ def get_volumes(request, compute_id, pool):
 | 
			
		|||
    data = {}
 | 
			
		||||
    compute = get_object_or_404(Compute, pk=compute_id)
 | 
			
		||||
    try:
 | 
			
		||||
        conn = wvmStorage(compute.hostname,
 | 
			
		||||
                          compute.login,
 | 
			
		||||
                          compute.password,
 | 
			
		||||
                          compute.type,
 | 
			
		||||
                          pool)
 | 
			
		||||
        conn = wvmStorage(compute.hostname, compute.login, compute.password, compute.type, pool)
 | 
			
		||||
        conn.refresh()
 | 
			
		||||
        data['vols'] = sorted(conn.get_volumes())
 | 
			
		||||
    except libvirtError:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										15
									
								
								templates/403.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								templates/403.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
{% extends "base_auth.html" %}
 | 
			
		||||
{% load i18n %}
 | 
			
		||||
{% block title %}{% trans "404" %}{% endblock %}
 | 
			
		||||
{% block content %}
 | 
			
		||||
    <div class="row">
 | 
			
		||||
        <div class="col-xs-12" style="text-align: center;">
 | 
			
		||||
            <h1>{% trans 'Oops!'%}</h1>
 | 
			
		||||
 | 
			
		||||
            <p class="lead">{% trans "403 Forbidden" %}</p>
 | 
			
		||||
 | 
			
		||||
            <p>{% trans "You do not have permission to access this page." %}</p>
 | 
			
		||||
            <a class="btn btn-medium btn-success" href="javascript:history.back()">← {% trans 'Back'%}</a>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,48 +1,59 @@
 | 
			
		|||
{% load i18n %}
 | 
			
		||||
{% load tags_active %}
 | 
			
		||||
        <!-- Fixed navbar -->
 | 
			
		||||
        <nav class="navbar navbar-default navbar-fixed-top">
 | 
			
		||||
          <div class="container">
 | 
			
		||||
            <div class="navbar-header">
 | 
			
		||||
              <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
 | 
			
		||||
                <span class="sr-only">{% trans 'Toggle navigation' %}</span>
 | 
			
		||||
                <span class="icon-bar"></span>
 | 
			
		||||
                <span class="icon-bar"></span>
 | 
			
		||||
                <span class="icon-bar"></span>
 | 
			
		||||
              </button>
 | 
			
		||||
              <a class="navbar-brand" href="{% url 'index' %}">WebVirtCloud</a>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div id="navbar" class="navbar-collapse collapse">
 | 
			
		||||
              <ul class="nav navbar-nav">
 | 
			
		||||
                <li {% class_active request "^/instance" %}>
 | 
			
		||||
                    <a href="{% url 'allinstances' %}"><i class="fa fa-fw fa-desktop"></i> {% trans "Instances" %}</a>
 | 
			
		||||
                </li>
 | 
			
		||||
                {% if request.user.is_superuser %}
 | 
			
		||||
                    <li {% class_active request "^/compute" %}{% class_active request "^/create" %}>
 | 
			
		||||
                        <a href="{% url 'computes' %}"><i class="fa fa-fw fa-server"></i> {% trans "Computes" %}</a>
 | 
			
		||||
                    </li>
 | 
			
		||||
                    <li {% class_active request "^/account" %}>
 | 
			
		||||
                        <a href="{% url 'accounts' %}"><i class="fa fa-fw fa-users"></i> {% trans "Users" %}</a>
 | 
			
		||||
                    </li>
 | 
			
		||||
                    <li {% class_active request "^/log" %}>
 | 
			
		||||
                        <a href="{% url 'showlogs' %}"><i class="fa fa-fw fa-list-alt"></i> {% trans "Logs" %}</a>
 | 
			
		||||
                    </li>
 | 
			
		||||
                {% endif %}
 | 
			
		||||
              </ul>
 | 
			
		||||
              <ul class="nav navbar-nav navbar-right">
 | 
			
		||||
                <li class="dropdown">
 | 
			
		||||
                  <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><i class="fa fa-fw fa-user"></i> {{ request.user.username }} <span class="caret"></span></a>
 | 
			
		||||
                  <ul class="dropdown-menu" role="menu">
 | 
			
		||||
                    <li>
 | 
			
		||||
                        <a href="{% url 'profile' %}"><i class="fa fa-fw fa-pencil-square-o"></i> {% trans "Profile" %}</a>
 | 
			
		||||
                    </li>
 | 
			
		||||
                    <li class="divider"></li>
 | 
			
		||||
                    <li>
 | 
			
		||||
                        <a href="{% url 'logout' %}"><i class="fa fa-fw fa-power-off"></i> {% trans "Log Out" %}</a>
 | 
			
		||||
                    </li>
 | 
			
		||||
                  </ul>
 | 
			
		||||
                </li>
 | 
			
		||||
              </ul>
 | 
			
		||||
            </div><!--/.nav-collapse -->
 | 
			
		||||
          </div>
 | 
			
		||||
        </nav>
 | 
			
		||||
{% load font_awesome %}
 | 
			
		||||
{% load common_tags %}
 | 
			
		||||
<!-- Fixed navbar -->
 | 
			
		||||
<nav class="navbar navbar-default navbar-fixed-top">
 | 
			
		||||
  <div class="container">
 | 
			
		||||
    <div class="navbar-header">
 | 
			
		||||
      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
 | 
			
		||||
        <span class="sr-only">{% trans 'Toggle navigation' %}</span>
 | 
			
		||||
        <span class="icon-bar"></span>
 | 
			
		||||
        <span class="icon-bar"></span>
 | 
			
		||||
        <span class="icon-bar"></span>
 | 
			
		||||
      </button>
 | 
			
		||||
      <a class="navbar-brand" href="{% url 'index' %}">WebVirtCloud</a>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div id="navbar" class="navbar-collapse collapse">
 | 
			
		||||
      <ul class="nav navbar-nav">
 | 
			
		||||
        <li {% class_active request '^/instance' %}>
 | 
			
		||||
            <a href="{% url 'allinstances' %}"><i class="fa fa-fw fa-desktop"></i> {% trans "Instances" %}</a>
 | 
			
		||||
        </li>
 | 
			
		||||
        {% if request.user.is_superuser %}
 | 
			
		||||
          <li {% class_active request "^/compute" %}>
 | 
			
		||||
              <a href="{% url 'computes' %}"><i class="fa fa-fw fa-server"></i> {% trans "Computes" %}</a>
 | 
			
		||||
          </li>
 | 
			
		||||
          <li class="dropdown {% app_active request 'admin' %}">
 | 
			
		||||
            <a id="administration" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
 | 
			
		||||
              {% trans "Administration" %} {% icon 'caret-down' %}
 | 
			
		||||
            </a>
 | 
			
		||||
            <ul class="dropdown-menu" aria-labelledby="administration">
 | 
			
		||||
              <li class="{% view_active request 'admin:user_list' %}">
 | 
			
		||||
                <a href="{% url 'admin:user_list' %}">{% icon 'user-plus' %} {% trans "Users" %}</a>
 | 
			
		||||
              </li>
 | 
			
		||||
              <li class="{% view_active request 'admin:group_list' %}">
 | 
			
		||||
                <a href="{% url 'admin:group_list' %}">{% icon 'users' %} {% trans "Groups" %}</a>
 | 
			
		||||
              </li>
 | 
			
		||||
              <li class="{% view_active request 'admin:logs' %}">
 | 
			
		||||
                <a href="{% url 'admin:logs' %}">{% icon 'list-alt' %} {% trans "Logs" %}</a>
 | 
			
		||||
              </li>
 | 
			
		||||
            </ul>
 | 
			
		||||
          </li>
 | 
			
		||||
        {% endif %}
 | 
			
		||||
      </ul>
 | 
			
		||||
      <ul class="nav navbar-nav navbar-right">
 | 
			
		||||
        <li class="dropdown">
 | 
			
		||||
          <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><i class="fa fa-fw fa-user"></i> {{ request.user.username }} <span class="caret"></span></a>
 | 
			
		||||
          <ul class="dropdown-menu" role="menu">
 | 
			
		||||
            <li>
 | 
			
		||||
                <a href="{% url 'profile' %}"><i class="fa fa-fw fa-pencil-square-o"></i> {% trans "Profile" %}</a>
 | 
			
		||||
            </li>
 | 
			
		||||
            <li class="divider"></li>
 | 
			
		||||
            <li>
 | 
			
		||||
                <a href="{% url 'logout' %}"><i class="fa fa-fw fa-power-off"></i> {% trans "Log Out" %}</a>
 | 
			
		||||
            </li>
 | 
			
		||||
          </ul>
 | 
			
		||||
        </li>
 | 
			
		||||
      </ul>
 | 
			
		||||
    </div><!--/.nav-collapse -->
 | 
			
		||||
  </div>
 | 
			
		||||
</nav>
 | 
			
		||||
							
								
								
									
										26
									
								
								webvirtcloud/common_tags.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								webvirtcloud/common_tags.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,26 @@
 | 
			
		|||
from django import template
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
register = template.Library()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@register.simple_tag
 | 
			
		||||
def app_active(request, app_name):
 | 
			
		||||
    if request.resolver_match.app_name == app_name:
 | 
			
		||||
        return 'active'
 | 
			
		||||
    return ''
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@register.simple_tag
 | 
			
		||||
def view_active(request, view_name):
 | 
			
		||||
    if request.resolver_match.view_name == view_name:
 | 
			
		||||
        return 'active'
 | 
			
		||||
    return ''
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@register.simple_tag
 | 
			
		||||
def class_active(request, pattern):
 | 
			
		||||
    if re.search(pattern, request.path):
 | 
			
		||||
        # Not sure why 'class="active"' returns class=""active""
 | 
			
		||||
        return 'class=active'
 | 
			
		||||
    return ''
 | 
			
		||||
| 
						 | 
				
			
			@ -14,17 +14,18 @@ DEBUG = True
 | 
			
		|||
 | 
			
		||||
ALLOWED_HOSTS = ['*']
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Application definition
 | 
			
		||||
 | 
			
		||||
INSTALLED_APPS = [
 | 
			
		||||
    'django.contrib.admin',
 | 
			
		||||
    'django.contrib.auth',
 | 
			
		||||
    'django.contrib.contenttypes',
 | 
			
		||||
    'django.contrib.sessions',
 | 
			
		||||
    'django.contrib.messages',
 | 
			
		||||
    'django.contrib.staticfiles',
 | 
			
		||||
    'bootstrap3',
 | 
			
		||||
    'fa',
 | 
			
		||||
    'accounts',
 | 
			
		||||
    'admin',
 | 
			
		||||
    'computes',
 | 
			
		||||
    'console',
 | 
			
		||||
    'create',
 | 
			
		||||
| 
						 | 
				
			
			@ -56,7 +57,9 @@ ROOT_URLCONF = 'webvirtcloud.urls'
 | 
			
		|||
TEMPLATES = [
 | 
			
		||||
    {
 | 
			
		||||
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
 | 
			
		||||
        'DIRS': [ os.path.join(BASE_DIR, 'templates'), ],
 | 
			
		||||
        'DIRS': [
 | 
			
		||||
            os.path.join(BASE_DIR, 'templates'),
 | 
			
		||||
        ],
 | 
			
		||||
        'APP_DIRS': True,
 | 
			
		||||
        'OPTIONS': {
 | 
			
		||||
            'context_processors': [
 | 
			
		||||
| 
						 | 
				
			
			@ -65,13 +68,15 @@ TEMPLATES = [
 | 
			
		|||
                'django.contrib.auth.context_processors.auth',
 | 
			
		||||
                'django.contrib.messages.context_processors.messages',
 | 
			
		||||
            ],
 | 
			
		||||
            'libraries': {
 | 
			
		||||
                'common_tags': 'webvirtcloud.common_tags',
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
WSGI_APPLICATION = 'webvirtcloud.wsgi.application'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Database
 | 
			
		||||
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -84,12 +89,12 @@ DATABASES = {
 | 
			
		|||
 | 
			
		||||
AUTHENTICATION_BACKENDS = [
 | 
			
		||||
    'django.contrib.auth.backends.ModelBackend',
 | 
			
		||||
    #'django.contrib.auth.backends.RemoteUserBackend',
 | 
			
		||||
    #'accounts.backends.MyRemoteUserBackend',
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
LOGIN_URL = '/accounts/login'
 | 
			
		||||
 | 
			
		||||
LOGOUT_REDIRECT_URL = '/accounts/login'
 | 
			
		||||
 | 
			
		||||
LANGUAGE_CODE = 'en-us'
 | 
			
		||||
 | 
			
		||||
TIME_ZONE = 'UTC'
 | 
			
		||||
| 
						 | 
				
			
			@ -168,9 +173,6 @@ SHOW_ACCESS_ROOT_PASSWORD = False
 | 
			
		|||
SHOW_ACCESS_SSH_KEYS = False
 | 
			
		||||
SHOW_PROFILE_EDIT_PASSWORD = False
 | 
			
		||||
 | 
			
		||||
# available: default (grid), list
 | 
			
		||||
VIEW_ACCOUNTS_STYLE = 'grid'
 | 
			
		||||
 | 
			
		||||
# available list style: default (grouped), nongrouped
 | 
			
		||||
VIEW_INSTANCES_LIST_STYLE = 'grouped'
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue