2015-12-13 09:34:12 +00:00
|
|
|
{% extends "base.html" %}
|
2018-08-18 11:41:59 +00:00
|
|
|
{% set active_page = "dashboard" %}
|
2018-08-18 15:42:18 +00:00
|
|
|
{% block title %}<title>Dashboard - {{ SITE_NAME }}</title>{% endblock %}
|
2015-12-13 09:34:12 +00:00
|
|
|
|
|
|
|
{% block dashboard_stat %}
|
2016-06-18 04:41:01 +00:00
|
|
|
<!-- Content Header (Page header) -->
|
2016-04-22 00:37:33 +00:00
|
|
|
<section class="content-header">
|
|
|
|
<h1>
|
|
|
|
Dashboard
|
|
|
|
<small>Info</small>
|
|
|
|
</h1>
|
|
|
|
<ol class="breadcrumb">
|
|
|
|
<li><a href="{{ url_for('dashboard') }}"><i class="fa fa-dashboard"></i> Home</a></li>
|
|
|
|
<li class="active">Dashboard</li>
|
|
|
|
</ol>
|
|
|
|
</section>
|
2015-12-13 09:34:12 +00:00
|
|
|
{% endblock %}
|
|
|
|
|
|
|
|
{% block content %}
|
2016-04-22 00:37:33 +00:00
|
|
|
<!-- Main content -->
|
|
|
|
<section class="content">
|
|
|
|
{% if current_user.role.name == 'Administrator' %}
|
|
|
|
<div class="row">
|
|
|
|
<div class="col-xs-3">
|
2016-06-18 04:41:01 +00:00
|
|
|
<div class="box">
|
|
|
|
<div class="box-header">
|
|
|
|
<h3 class="box-title">Statistics</h3>
|
|
|
|
</div>
|
|
|
|
<div class="box-body">
|
|
|
|
<div class="row">
|
|
|
|
<div class="col-lg-6">
|
|
|
|
<!-- small box -->
|
|
|
|
<div class="small-box bg-aqua">
|
|
|
|
<div class="inner">
|
|
|
|
<h3>{{ domain_count }}</h3>
|
|
|
|
<p>{% if domain_count > 1 %}Domains{% else %}Domain{% endif %}</p>
|
|
|
|
</div>
|
|
|
|
<div class="icon">
|
|
|
|
<i class="fa fa-book"></i>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="col-lg-6">
|
|
|
|
<a href="{{ url_for('admin_manageuser') }}">
|
|
|
|
<div class="small-box bg-green">
|
|
|
|
<div class="inner">
|
|
|
|
<h3>{{ users|length }}</h3>
|
|
|
|
<p>{% if users|length > 1 %}Users{% else %}User{% endif %}</p>
|
|
|
|
</div>
|
|
|
|
<div class="icon">
|
|
|
|
<i class="fa fa-users"></i>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</a>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="row">
|
|
|
|
<div class="col-lg-6">
|
|
|
|
<a href="{{ url_for('admin_history') }}">
|
|
|
|
<div class="small-box bg-green">
|
|
|
|
<div class="inner">
|
|
|
|
<h3>{{ history_number }}</h3>
|
|
|
|
<p>{% if history_number > 1 %}Histories{% else %}History{% endif %}</p>
|
|
|
|
</div>
|
|
|
|
<div class="icon">
|
|
|
|
<i class="fa fa-calendar"></i>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</a>
|
|
|
|
</div>
|
|
|
|
<div class="col-lg-6">
|
|
|
|
<a href="{{ url_for('admin') }}">
|
|
|
|
<div class="small-box bg-green">
|
|
|
|
<div class="inner">
|
|
|
|
<h3><span style="font-size: 18px">{{ uptime|display_second_to_time }}</span></h3>
|
|
|
|
<p>Uptime</p>
|
|
|
|
</div>
|
|
|
|
<div class="icon">
|
|
|
|
<i class="fa fa-clock-o"></i>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</a>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
2016-04-22 00:37:33 +00:00
|
|
|
</div>
|
|
|
|
<div class="col-xs-9">
|
2016-06-18 04:41:01 +00:00
|
|
|
<div class="box">
|
|
|
|
<div class="box-header">
|
|
|
|
<h3 class="box-title">Recent History</h3>
|
|
|
|
</div>
|
|
|
|
<div class="box-body">
|
|
|
|
<table id="tbl_history" class="table table-bordered table-striped">
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th>Changed By</th>
|
|
|
|
<th>Content</th>
|
|
|
|
<th>Time</th>
|
|
|
|
<th>Detail</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
{% for history in histories %}
|
|
|
|
<tr class="odd">
|
|
|
|
<td>{{ history.created_by }}</td>
|
|
|
|
<td>{{ history.msg }}</td>
|
|
|
|
<td>{{ history.created_on }}</td>
|
|
|
|
<td width="6%">
|
|
|
|
<button type="button" class="btn btn-flat btn-primary history-info-button" value='{{ history.detail|replace("[]","None") }}'>
|
|
|
|
Info <i class="fa fa-info"></i>
|
|
|
|
</button>
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
{% endfor %}
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
</div>
|
2016-04-22 00:37:33 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
{% endif %}
|
|
|
|
<div class="row">
|
|
|
|
<div class="col-xs-12">
|
|
|
|
<div class="box">
|
|
|
|
<div class="box-header">
|
2018-06-08 11:23:04 +00:00
|
|
|
<h3 class="box-title">Hosted Domains</h3>{% if show_bg_domain_button %}<button type="button" class="btn btn-flat btn-primary refresh-bg-button pull-right"><i class="fa fa-refresh"></i> Sync domains </button>{% endif %}
|
2016-04-22 00:37:33 +00:00
|
|
|
</div>
|
|
|
|
<div class="box-body">
|
|
|
|
<table id="tbl_domain_list" class="table table-bordered table-striped">
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th>Name</th>
|
|
|
|
<th>DNSSEC</th>
|
|
|
|
<th>Type</th>
|
|
|
|
<th>Serial</th>
|
|
|
|
<th>Master</th>
|
Initial support for Accounts
This adds initial support for accounts a concept meant to signify a customer, a department or any other entity that somehow owns or manages one or more domains.
The purpose is to be able to assign an account to any number of domains, making it easy to track who owns or manages a domain, significantly improving manageability in setups with a large number of domains.
An account consists of a mandatory, unique `name` and optional `description`, `contact` name and `mail` address. The account `name` is stripped of spaces and symbols, and lower cased before getting stored in the database and in PowerDNS, to help ensure some type of predictability and uniqueness in the database.
The term *account* is actually taken from the PowerDNS database, where the `domains.account` column is used to store the account relationship, in in the form of the account `name`.
The link to a domain in PowerDNS-Admin is done through the `domain.account_id` FOREIGN KEY, that is linked to the `account.id` PRIMARY KEY.
(cherry picked from commits 4e95f33dfb0676d1c401a033c28bca3be7d6ec26, da0d596bd019a339549e2c59630a8fdee65d0e22, 7f06e6aaf4fd8011c784f24b7bbbba5f52aef319, 1c624dad8749024033d1d15dd6242ca52b39f135)
2018-06-04 15:10:02 +00:00
|
|
|
<th>Account</th>
|
2018-04-01 07:45:13 +00:00
|
|
|
<th {% if current_user.role.name !='Administrator' %}width="6%"{% else %}width="25%"{% endif %}>Action</th>
|
2016-04-22 00:37:33 +00:00
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
2017-06-30 16:18:06 +00:00
|
|
|
<!-- Content loaded via AJAX. -->
|
2016-04-22 00:37:33 +00:00
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
<!-- /.box-body -->
|
|
|
|
</div>
|
|
|
|
<!-- /.box -->
|
|
|
|
</div>
|
|
|
|
<!-- /.col -->
|
|
|
|
</div>
|
|
|
|
<!-- /.row -->
|
|
|
|
</section>
|
|
|
|
<!-- /.content -->
|
2015-12-13 09:34:12 +00:00
|
|
|
{% endblock %}
|
2016-04-27 23:55:04 +00:00
|
|
|
{% block extrascripts %}
|
|
|
|
<script>
|
2018-08-20 02:59:19 +00:00
|
|
|
PDNS_VERSION = '{{ SETTING.get("pdns_version") }}'
|
2016-06-18 04:41:01 +00:00
|
|
|
// set up history data table
|
|
|
|
$("#tbl_history").DataTable({
|
|
|
|
"paging" : false,
|
|
|
|
"lengthChange" : false,
|
|
|
|
"searching" : false,
|
|
|
|
"ordering" : false,
|
|
|
|
"info" : false,
|
2018-04-17 06:28:54 +00:00
|
|
|
"autoWidth" : false,
|
|
|
|
"columnDefs": [
|
|
|
|
{
|
|
|
|
"render": function ( data, type, row ) {
|
|
|
|
return moment.utc(data).local().format('YYYY-MM-DD HH:mm:ss');
|
|
|
|
},
|
|
|
|
"targets": 2
|
|
|
|
}
|
|
|
|
]
|
2017-06-30 16:18:06 +00:00
|
|
|
});
|
2016-07-05 15:14:41 +00:00
|
|
|
// set up domain list
|
2016-06-30 11:37:40 +00:00
|
|
|
$("#tbl_domain_list").DataTable({
|
|
|
|
"paging" : true,
|
|
|
|
"lengthChange" : true,
|
|
|
|
"searching" : true,
|
|
|
|
"ordering" : true,
|
Initial support for Accounts
This adds initial support for accounts a concept meant to signify a customer, a department or any other entity that somehow owns or manages one or more domains.
The purpose is to be able to assign an account to any number of domains, making it easy to track who owns or manages a domain, significantly improving manageability in setups with a large number of domains.
An account consists of a mandatory, unique `name` and optional `description`, `contact` name and `mail` address. The account `name` is stripped of spaces and symbols, and lower cased before getting stored in the database and in PowerDNS, to help ensure some type of predictability and uniqueness in the database.
The term *account* is actually taken from the PowerDNS database, where the `domains.account` column is used to store the account relationship, in in the form of the account `name`.
The link to a domain in PowerDNS-Admin is done through the `domain.account_id` FOREIGN KEY, that is linked to the `account.id` PRIMARY KEY.
(cherry picked from commits 4e95f33dfb0676d1c401a033c28bca3be7d6ec26, da0d596bd019a339549e2c59630a8fdee65d0e22, 7f06e6aaf4fd8011c784f24b7bbbba5f52aef319, 1c624dad8749024033d1d15dd6242ca52b39f135)
2018-06-04 15:10:02 +00:00
|
|
|
"columnDefs": [
|
|
|
|
{ "orderable": false, "targets": [-1] }
|
|
|
|
{% if current_user.role.name != 'Administrator' %},{ "visible": false, "targets": [-2] }{% endif %}
|
|
|
|
],
|
2017-06-30 16:18:06 +00:00
|
|
|
"processing" : true,
|
|
|
|
"serverSide" : true,
|
|
|
|
"ajax" : "{{ url_for('dashboard_domains') }}",
|
2016-06-30 11:37:40 +00:00
|
|
|
"info" : false,
|
2016-07-05 15:14:41 +00:00
|
|
|
"autoWidth" : false,
|
2018-08-18 11:41:59 +00:00
|
|
|
{% if SETTING.get('default_domain_table_size') in ['10','25','50','100'] %}
|
2018-04-01 08:48:08 +00:00
|
|
|
"lengthMenu": [ [10, 25, 50, 100, -1],
|
|
|
|
[10, 25, 50, 100, "All"]],
|
|
|
|
{% else %}
|
2018-08-18 11:41:59 +00:00
|
|
|
"lengthMenu": [ [10, 25, 50, 100, {{ SETTING.get('default_domain_table_size') }}, -1],
|
|
|
|
[10, 25, 50, 100, {{ SETTING.get('default_domain_table_size') }}, "All"]],
|
2018-04-01 08:48:08 +00:00
|
|
|
{% endif %}
|
2018-08-18 11:41:59 +00:00
|
|
|
"pageLength": {{ SETTING.get('default_domain_table_size') }}
|
2016-06-30 11:37:40 +00:00
|
|
|
});
|
2016-07-01 22:31:14 +00:00
|
|
|
$(document.body).on('click', '.history-info-button', function() {
|
2016-06-18 04:41:01 +00:00
|
|
|
var modal = $("#modal_history_info");
|
|
|
|
var info = $(this).val();
|
2016-08-21 14:46:23 +00:00
|
|
|
$('#modal-code-content').html(json_library.prettyPrint(info));
|
2016-06-18 04:41:01 +00:00
|
|
|
modal.modal('show');
|
|
|
|
});
|
2018-01-23 15:23:21 +00:00
|
|
|
|
2018-06-08 11:25:43 +00:00
|
|
|
$(document.body).on('click', '.refresh-bg-button', function() {
|
|
|
|
var modal = $("#modal_bg_reload");
|
|
|
|
modal.modal('show');
|
|
|
|
reload_domains($SCRIPT_ROOT + '/dashboard-domains-updater');
|
|
|
|
});
|
|
|
|
|
2018-01-23 15:23:21 +00:00
|
|
|
$(document.body).on("click", ".button_template", function (e) {
|
|
|
|
var modal = $("#modal_template");
|
|
|
|
var domain = $(this).prop('id');
|
|
|
|
var form = " <label for=\"template_name\">Template name</label> \
|
|
|
|
<input type=\"text\" class=\"form-control\" name=\"template_name\" id=\"template_name\" placeholder=\"Enter a valid template name (required)\"> \
|
|
|
|
<label for=\"template_description\">Template description</label> \
|
|
|
|
<input type=\"text\" class=\"form-control\" name=\"template_description\" id=\"template_description\" placeholder=\"Enter a template description (optional)\"> \
|
|
|
|
<input id=\"domain\" name=\"domain\" type=\"hidden\" value=\""+domain+"\"> \
|
|
|
|
";
|
|
|
|
modal.find('.modal-body p').html(form);
|
|
|
|
modal.find('#button_save').click(function() {
|
|
|
|
var data = {};
|
|
|
|
data['name'] = modal.find('#template_name').val();
|
|
|
|
data['description'] = modal.find('#template_description').val();
|
|
|
|
data['domain'] = modal.find('#domain').val();
|
|
|
|
applyChanges(data, $SCRIPT_ROOT + "{{ url_for('create_template_from_zone') }}", true);
|
|
|
|
modal.modal('hide');
|
|
|
|
})
|
|
|
|
modal.find('#button_close').click(function() {
|
|
|
|
modal.modal('hide');
|
|
|
|
})
|
|
|
|
|
|
|
|
modal.modal('show');
|
|
|
|
});
|
2018-04-02 06:38:53 +00:00
|
|
|
|
2018-06-06 10:42:57 +00:00
|
|
|
{% if current_user.role.name == 'Administrator' or dnssec_adm_only == false %}
|
2016-07-01 22:31:14 +00:00
|
|
|
$(document.body).on("click", ".button_dnssec", function() {
|
2016-06-18 04:41:01 +00:00
|
|
|
var domain = $(this).prop('id');
|
2018-04-02 06:38:53 +00:00
|
|
|
getdnssec($SCRIPT_ROOT + '/domain/' + domain + '/dnssec', domain);
|
2016-06-18 04:41:01 +00:00
|
|
|
});
|
2018-03-05 10:18:29 +00:00
|
|
|
|
|
|
|
$(document.body).on("click", ".button_dnssec_enable", function() {
|
|
|
|
var domain = $(this).prop('id');
|
|
|
|
enable_dns_sec($SCRIPT_ROOT + '/domain/' + domain + '/dnssec/enable');
|
2018-03-05 13:50:33 +00:00
|
|
|
|
2018-03-05 10:18:29 +00:00
|
|
|
});
|
2018-03-05 13:59:32 +00:00
|
|
|
|
|
|
|
$(document.body).on("click", ".button_dnssec_disable", function() {
|
|
|
|
var domain = $(this).prop('id');
|
|
|
|
enable_dns_sec($SCRIPT_ROOT + '/domain/' + domain + '/dnssec/disable');
|
|
|
|
|
|
|
|
});
|
2018-06-06 10:42:57 +00:00
|
|
|
{% endif %}
|
2016-04-27 23:55:04 +00:00
|
|
|
</script>
|
|
|
|
{% endblock %}
|
|
|
|
{% block modals %}
|
|
|
|
<div class="modal fade" id="modal_history_info">
|
2016-06-18 04:41:01 +00:00
|
|
|
<div class="modal-dialog">
|
|
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header">
|
|
|
|
<button type="button" class="close" data-dismiss="modal"
|
|
|
|
aria-label="Close">
|
|
|
|
<span aria-hidden="true">×</span>
|
|
|
|
</button>
|
|
|
|
<h4 class="modal-title">History Details</h4>
|
|
|
|
</div>
|
|
|
|
<div class="modal-body">
|
2016-08-21 14:46:23 +00:00
|
|
|
<pre><code id="modal-code-content"></code></pre>
|
2016-06-18 04:41:01 +00:00
|
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
|
|
<button type="button" class="btn btn-flat btn-default pull-right"
|
|
|
|
data-dismiss="modal">Close</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- /.modal-content -->
|
|
|
|
</div>
|
|
|
|
<!-- /.modal-dialog -->
|
2016-04-27 23:55:04 +00:00
|
|
|
</div>
|
2018-01-23 15:23:21 +00:00
|
|
|
<div class="modal fade modal-primary" id="modal_template">
|
|
|
|
<div class="modal-dialog">
|
|
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header">
|
|
|
|
<button type="button" class="close" data-dismiss="modal"
|
|
|
|
aria-label="Close">
|
|
|
|
<span aria-hidden="true">×</span>
|
|
|
|
</button>
|
|
|
|
<h4 class="modal-title">Clone to template</h4>
|
|
|
|
</div>
|
|
|
|
<div class="modal-body">
|
|
|
|
<p></p>
|
|
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
|
|
<button type="button" class="btn btn-flat btn-default pull-left"
|
|
|
|
id="button_close" data-dismiss="modal">Close</button>
|
|
|
|
<button type="button" class="btn btn-flat btn-primary" id="button_save">Save</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- /.modal-content -->
|
|
|
|
</div>
|
|
|
|
<!-- /.modal-dialog -->
|
|
|
|
</div>
|
2016-04-27 23:55:04 +00:00
|
|
|
<!-- /.modal -->
|
2016-04-29 16:23:05 +00:00
|
|
|
<div class="modal fade" id="modal_dnssec_info">
|
2016-06-18 04:41:01 +00:00
|
|
|
<div class="modal-dialog">
|
|
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header">
|
|
|
|
<button type="button" class="close" data-dismiss="modal"
|
|
|
|
aria-label="Close">
|
|
|
|
<span aria-hidden="true">×</span>
|
|
|
|
</button>
|
|
|
|
<h4 class="modal-title">DNSSEC</h4>
|
|
|
|
</div>
|
|
|
|
<div class="modal-body">
|
|
|
|
<p></p>
|
|
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
|
|
<button type="button" class="btn btn-flat btn-default pull-right"
|
|
|
|
data-dismiss="modal">Close</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- /.modal-content -->
|
|
|
|
</div>
|
|
|
|
<!-- /.modal-dialog -->
|
2016-04-29 16:23:05 +00:00
|
|
|
</div>
|
|
|
|
<!-- /.modal -->
|
2018-06-08 11:25:21 +00:00
|
|
|
<div class="modal fade" id="modal_bg_reload">
|
|
|
|
<div class="modal-dialog">
|
|
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header">
|
|
|
|
<button type="button" class="close" data-dismiss="modal"
|
|
|
|
aria-label="Close">
|
|
|
|
<span aria-hidden="true">×</span>
|
|
|
|
</button>
|
|
|
|
<h4 class="modal-title">Sync domains from nameserver</h4>
|
|
|
|
</div>
|
|
|
|
<div class="modal-body">
|
|
|
|
|
|
|
|
<div class="overlay">
|
|
|
|
<div id="modal_bg_reload_content"><i class="fa fa-refresh fa-spin"></i> Update in progress ..</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
|
|
<button type="button" class="btn btn-flat btn-default pull-right"
|
|
|
|
data-dismiss="modal">Close</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- /.modal-content -->
|
|
|
|
</div>
|
|
|
|
<!-- /.modal-dialog -->
|
|
|
|
</div>
|
2016-04-27 23:55:04 +00:00
|
|
|
{% endblock %}
|