Adjustment in domain template feature to work with python3

This commit is contained in:
Khanh Ngo 2018-03-31 08:21:02 +07:00
commit 29d1cf4117
11 changed files with 1034 additions and 33 deletions

View File

@ -18,6 +18,8 @@ from flask_login import AnonymousUserMixin
from app import app, db from app import app, db
from app.lib import utils from app.lib import utils
from app.lib.log import logger from app.lib.log import logger
# LOG CONFIGS
logging = logger('MODEL', app.config['LOG_LEVEL'], app.config['LOG_FILE']).config() logging = logger('MODEL', app.config['LOG_LEVEL'], app.config['LOG_FILE']).config()
if 'LDAP_TYPE' in app.config.keys(): if 'LDAP_TYPE' in app.config.keys():
@ -894,7 +896,7 @@ class Record(object):
list_deleted_records = [x for x in list_current_records if x not in list_new_records] list_deleted_records = [x for x in list_current_records if x not in list_new_records]
# convert back to list of hash # convert back to list of hash
deleted_records = [x for x in current_records if [x['name'],x['type']] in list_deleted_records and x['type'] in app.config['RECORDS_ALLOW_EDIT']] deleted_records = [x for x in current_records if [x['name'],x['type']] in list_deleted_records and (x['type'] in app.config['RECORDS_ALLOW_EDIT'] and x['type'] != 'SOA')]
# return a tuple # return a tuple
return deleted_records, new_records return deleted_records, new_records
@ -1042,12 +1044,14 @@ class Record(object):
}) })
postdata_for_new = {"rrsets": final_records} postdata_for_new = {"rrsets": final_records}
logging.info(postdata_for_new)
logging.info(postdata_for_delete)
logging.info(urljoin(PDNS_STATS_URL, API_EXTENDED_URL + '/servers/localhost/zones/{0}'.format(domain)))
try: try:
headers = {} headers = {}
headers['X-API-Key'] = PDNS_API_KEY headers['X-API-Key'] = PDNS_API_KEY
jdata1 = utils.fetch_json(urljoin(PDNS_STATS_URL, API_EXTENDED_URL + '/servers/localhost/zones/%s' % domain), headers=headers, method='PATCH', data=postdata_for_delete) jdata1 = utils.fetch_json(urljoin(PDNS_STATS_URL, API_EXTENDED_URL + '/servers/localhost/zones/{0}'.format(domain)), headers=headers, method='PATCH', data=postdata_for_delete)
jdata2 = utils.fetch_json(urljoin(PDNS_STATS_URL, API_EXTENDED_URL + '/servers/localhost/zones/%s' % domain), headers=headers, method='PATCH', data=postdata_for_new) jdata2 = utils.fetch_json(urljoin(PDNS_STATS_URL, API_EXTENDED_URL + '/servers/localhost/zones/{0}'.format(domain)), headers=headers, method='PATCH', data=postdata_for_new)
if 'error' in jdata2.keys(): if 'error' in jdata2.keys():
logging.error('Cannot apply record changes.') logging.error('Cannot apply record changes.')
@ -1058,7 +1062,7 @@ class Record(object):
logging.info('Record was applied successfully.') logging.info('Record was applied successfully.')
return {'status': 'ok', 'msg': 'Record was applied successfully'} return {'status': 'ok', 'msg': 'Record was applied successfully'}
except Exception as e: except Exception as e:
logging.error("Cannot apply record changes to domain %s. DETAIL: %s" % (e, domain)) logging.error("Cannot apply record changes to domain {0}. DETAIL: {1}".format(e, domain))
return {'status': 'error', 'msg': 'There was something wrong, please contact administrator'} return {'status': 'error', 'msg': 'There was something wrong, please contact administrator'}
def auto_ptr(self, domain, new_records, deleted_records): def auto_ptr(self, domain, new_records, deleted_records):
@ -1127,12 +1131,18 @@ class Record(object):
logging.error("Cannot remove record %s/%s/%s from domain %s" % (self.name, self.type, self.data, domain)) logging.error("Cannot remove record %s/%s/%s from domain %s" % (self.name, self.type, self.data, domain))
return {'status': 'error', 'msg': 'There was something wrong, please contact administrator'} return {'status': 'error', 'msg': 'There was something wrong, please contact administrator'}
def is_allowed(self): def is_allowed_edit(self):
""" """
Check if record is allowed to edit/removed Check if record is allowed to edit
""" """
return self.type in app.config['RECORDS_ALLOW_EDIT'] return self.type in app.config['RECORDS_ALLOW_EDIT']
def is_allowed_delete(self):
"""
Check if record is allowed to removed
"""
return (self.type in app.config['RECORDS_ALLOW_EDIT'] and self.type != 'SOA')
def exists(self, domain): def exists(self, domain):
""" """
Check if record is present within domain records, and if it's present set self to found record Check if record is present within domain records, and if it's present set self to found record
@ -1361,3 +1371,83 @@ class Setting(db.Model):
logging.debug(traceback.format_exec()) logging.debug(traceback.format_exec())
db.session.rollback() db.session.rollback()
return False return False
class DomainTemplate(db.Model):
__tablename__ = "domain_template"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255), index=True, unique=True)
description = db.Column(db.String(255))
records = db.relationship('DomainTemplateRecord', back_populates='template', cascade="all, delete-orphan")
def __repr__(self):
return '<DomainTemplate %s>' % self.name
def __init__(self, name=None, description=None):
self.id = None
self.name = name
self.description = description
def replace_records(self, records):
try:
self.records = []
for record in records:
self.records.append(record)
db.session.commit()
return {'status': 'ok', 'msg': 'Template records have been modified'}
except Exception as e:
logging.error('Cannot create template records Error: {0}'.format(e))
db.session.rollback()
return {'status': 'error', 'msg': 'Can not create template records'}
def create(self):
try:
db.session.add(self)
db.session.commit()
return {'status': 'ok', 'msg': 'Template has been created'}
except Exception as e:
logging.error('Can not update domain template table. Error: {0}'.format(e))
db.session.rollback()
return {'status': 'error', 'msg': 'Can not update domain template table'}
def delete_template(self):
try:
self.records = []
db.session.delete(self)
db.session.commit()
return {'status': 'ok', 'msg': 'Template has been deleted'}
except Exception as e:
logging.error('Can not delete domain template. Error: {0}'.format(e))
db.session.rollback()
return {'status': 'error', 'msg': 'Can not delete domain template'}
class DomainTemplateRecord(db.Model):
__tablename__ = "domain_template_record"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255))
type = db.Column(db.String(64))
ttl = db.Column(db.Integer)
data = db.Column(db.String(255))
status = db.Column(db.Boolean)
template_id = db.Column(db.Integer, db.ForeignKey('domain_template.id'))
template = db.relationship('DomainTemplate', back_populates='records')
def __repr__(self):
return '<DomainTemplateRecord %i>' % self.id
def __init__(self, id=None, name=None, type=None, ttl=None, data=None, status=None):
self.id = id
self.name = name
self.type = type
self.ttl = ttl
self.data = data
self.status = status
def apply(self):
try:
db.session.commit()
except Exception as e:
logging.error('Can not update domain template table. Error: {0}'.format(e))
db.session.rollback()
return {'status': 'error', 'msg': 'Can not update domain template table'}

View File

@ -127,6 +127,7 @@
<li><a href="{{ url_for('domain_add') }}"><i class="fa fa-plus"></i> <span>New Domain</span></a></li> <li><a href="{{ url_for('domain_add') }}"><i class="fa fa-plus"></i> <span>New Domain</span></a></li>
<li class="header">ADMINISTRATION</li> <li class="header">ADMINISTRATION</li>
<li><a href="{{ url_for('admin') }}"><i class="fa fa-wrench"></i> <span>Admin Console</span></a></li> <li><a href="{{ url_for('admin') }}"><i class="fa fa-wrench"></i> <span>Admin Console</span></a></li>
<li><a href="{{ url_for('templates') }}"><i class="fa fa-clone"></i> <span>Domain Templates</span></a></li>
<li><a href="{{ url_for('admin_manageuser') }}"><i class="fa fa-users"></i> <span>Users</span></a></li> <li><a href="{{ url_for('admin_manageuser') }}"><i class="fa fa-users"></i> <span>Users</span></a></li>
<li><a href="{{ url_for('admin_history') }}"><i class="fa fa-calendar"></i> <span>History</span></a></li> <li><a href="{{ url_for('admin_history') }}"><i class="fa fa-calendar"></i> <span>History</span></a></li>
<li><a href="{{ url_for('admin_settings') }}"><i class="fa fa-cog"></i> <span>Settings</span></a></li> <li><a href="{{ url_for('admin_settings') }}"><i class="fa fa-cog"></i> <span>Settings</span></a></li>

View File

@ -203,6 +203,31 @@
var domain = $(this).prop('id'); var domain = $(this).prop('id');
getdnssec($SCRIPT_ROOT + '/domain/' + domain + '/dnssec'); getdnssec($SCRIPT_ROOT + '/domain/' + domain + '/dnssec');
}); });
$(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');
});
</script> </script>
{% endblock %} {% endblock %}
{% block modals %} {% block modals %}
@ -252,4 +277,27 @@
<!-- /.modal-dialog --> <!-- /.modal-dialog -->
</div> </div>
<!-- /.modal --> <!-- /.modal -->
<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">&times;</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>
{% endblock %} {% endblock %}

View File

@ -27,14 +27,11 @@
{% endmacro %} {% endmacro %}
{% macro actions(domain) %} {% macro actions(domain) %}
{% if current_user.role.name !='Administrator' %} {% if current_user.role.name =='Administrator' %}
<td width="6%"> <td width="25%">
<button type="button" class="btn btn-flat btn-success" onclick="window.location.href='{{ url_for('domain', domain_name=domain.name) }}'"> <button type="button" class="btn btn-flat btn-success button_template" id="{{ domain.name }}">
Manage&nbsp;<i class="fa fa-cog"></i> Template&nbsp;<i class="fa fa-clone"></i>
</button> </button>
</td>
{% else %}
<td width="20%">
<button type="button" class="btn btn-flat btn-success" onclick="window.location.href='{{ url_for('domain', domain_name=domain.name) }}'"> <button type="button" class="btn btn-flat btn-success" onclick="window.location.href='{{ url_for('domain', domain_name=domain.name) }}'">
Manage&nbsp;<i class="fa fa-cog"></i> Manage&nbsp;<i class="fa fa-cog"></i>
</button> </button>
@ -42,5 +39,11 @@
Admin&nbsp;<i class="fa fa-cog"></i> Admin&nbsp;<i class="fa fa-cog"></i>
</button> </button>
</td> </td>
{% else %}
<td width="6%">
<button type="button" class="btn btn-flat btn-success" onclick="window.location.href='{{ url_for('domain', domain_name=domain.name) }}'">
Manage&nbsp;<i class="fa fa-cog"></i>
</button>
</td>
{% endif %} {% endif %}
{% endmacro %} {% endmacro %}

View File

@ -70,25 +70,23 @@
</td> </td>
{% if domain.type != 'Slave' %} {% if domain.type != 'Slave' %}
<td width="6%"> <td width="6%">
{% if record.is_allowed() %} {% if record.is_allowed_edit() %}
<button type="button" class="btn btn-flat btn-warning button_edit" id="{{ (record.name,domain.name)|display_record_name }}">Edit&nbsp;<i class="fa fa-edit"></i></button> <button type="button" class="btn btn-flat btn-warning button_edit" id="{{ (record.name,domain.name)|display_record_name }}">Edit&nbsp;<i class="fa fa-edit"></i></button>
{% else %} {% else %}
<button type="button" class="btn btn-flat btn-warning"">&nbsp;&nbsp;<i class="fa fa-exclamation-circle"></i>&nbsp;&nbsp;</button> <button type="button" class="btn btn-flat btn-warning"">&nbsp;&nbsp;<i class="fa fa-exclamation-circle"></i>&nbsp;&nbsp;</button>
{% endif %} {% endif %}
</td> </td>
<td width="6%"> <td width="6%">
{% if record.is_allowed() %} {% if record.is_allowed_delete() %}
<button type="button" class="btn btn-flat btn-danger button_delete" id="{{ (record.name,domain.name)|display_record_name }}">Delete&nbsp;<i class="fa fa-trash"></i></button> <button type="button" class="btn btn-flat btn-danger button_delete" id="{{ (record.name,domain.name)|display_record_name }}">Delete&nbsp;<i class="fa fa-trash"></i></button>
{% else %}
<button type="button" class="btn btn-flat btn-warning"">&nbsp;&nbsp;<i class="fa fa-exclamation-circle"></i>&nbsp;&nbsp;</button>
{% endif %} {% endif %}
{% else %} {% else %}
<td width="6%"> <td width="6%">
<button type="button" class="btn btn-flat btn-warning"">&nbsp;&nbsp;<i class="fa fa-exclamation-circle"></i>&nbsp;&nbsp;</button> <button type="button" class="btn btn-flat btn-warning">&nbsp;&nbsp;<i class="fa fa-exclamation-circle"></i>&nbsp;&nbsp;</button>
</td> </td>
<td width="6%"> <td width="6%">
<button type="button" class="btn btn-flat btn-warning"">&nbsp;&nbsp;<i class="fa fa-exclamation-circle"></i>&nbsp;&nbsp;</button> <button type="button" class="btn btn-flat btn-warning">&nbsp;&nbsp;<i class="fa fa-exclamation-circle"></i>&nbsp;&nbsp;</button>
</td> </td>
{% endif %} {% endif %}
</td> </td>
<!-- hidden column that we can sort on --> <!-- hidden column that we can sort on -->

View File

@ -47,6 +47,15 @@
</label> </label>
</div> </div>
</div> </div>
<div class="form-group">
<label>Select a template</label>
<select class="form-control" id="domain_template" name="domain_template">
<option value="0">No template</option>
{% for template in templates %}
<option value="{{ template.id }}">{{ template.name }}</option>
{% endfor %}
</select>
</div>
<div class="form-group" style="display: none;" id="domain_master_address_div"> <div class="form-group" style="display: none;" id="domain_master_address_div">
<input type="text" class="form-control" name="domain_master_address" id="domain_master_address" placeholder="Enter valid master ip addresses (separated by commas)"> <input type="text" class="form-control" name="domain_master_address" id="domain_master_address" placeholder="Enter valid master ip addresses (separated by commas)">
</div> </div>

116
app/templates/template.html Normal file
View File

@ -0,0 +1,116 @@
{% extends "base.html" %}
{% block title %}<title>DNS Control Panel - Templates</title>{% endblock %}
{% block dashboard_stat %}
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>
Templates
<small>List</small>
</h1>
<ol class="breadcrumb">
<li><a href="{{ url_for('templates') }}"><i class="fa fa-dashboard"></i> Templates</a></li>
<li class="active">List</li>
</ol>
</section>
{% endblock %}
{% block content %}
<!-- Main content -->
<section class="content">
{% with errors = get_flashed_messages(category_filter=["error"]) %} {% if errors %}
<div class="row">
<div class="col-md-12">
<div class="alert alert-danger alert-dismissible">
<button type="button" class="close" data-dismiss="alert"
aria-hidden="true">&times;</button>
<h4>
<i class="icon fa fa-ban"></i> Error!
</h4>
<div class="alert-message block-message error">
<a class="close" href="#">x</a>
<ul>
{%- for msg in errors %}
<li>{{ msg }}</li> {% endfor -%}
</ul>
</div>
</div>
</div>
</div>
{% endif %} {% endwith %}
<div class="row">
<div class="col-xs-12">
<div class="box">
<div class="box-header">
<h3 class="box-title">Templates</h3>
</div>
<div class="box-body">
<a href="{{ url_for('create_template') }}">
<button type="button" class="btn btn-flat btn-primary pull-left">
Create Template&nbsp;<i class="fa fa-plus"></i>
</button>
</a>
</div>
<div class="box-body">
<table id="tbl_template_list" class="table table-bordered table-striped">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Number of Records</th>
<th width="20%">Action</th>
</tr>
</thead>
<tbody>
{% for template in templates %}
<tr>
<td>
<a href="{{ url_for('edit_template', template=template.name) }}"><strong>{{ template.name }}</strong></a>
</td>
<td>
{{ template.description }}
</td>
<td>
{{ template.records|count }}
</td>
<td>
<a href="{{ url_for('edit_template', template=template.name) }}">
<button type="button" class="btn btn-flat btn-warning button_edit" id="">
Edit&nbsp;<i class="fa fa-edit"></i>
</button>
</a>
<a href="{{ url_for('delete_template', template=template.name) }}">
<button type="button" class="btn btn-flat btn-danger button_delete" id="">
Delete&nbsp;<i class="fa fa-trash"></i>
</button>
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
</div>
<!-- /.col -->
</div>
<!-- /.row -->
</section>
<!-- /.content -->
{% endblock %}
{% block extrascripts %}
<script>
// set up history data table
$("#tbl_template_list").DataTable({
"paging" : true,
"lengthChange" : true,
"searching" : true,
"ordering" : true,
"info" : false,
"autoWidth" : false
});
</script>
{% endblock %}
{% block modals %}
{% endblock %}

View File

@ -0,0 +1,104 @@
{% extends "base.html" %}
{% block title %}<title>DNS Control Panel - Create Template</title>{% endblock %}
{% block dashboard_stat %}
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>
Template
<small>Create</small>
</h1>
<ol class="breadcrumb">
<li><a href="{{ url_for('templates') }}"><i class="fa fa-dashboard"></i> Templates</a></li>
<li class="active">Create</li>
</ol>
</section>
{% endblock %}
{% block content %}
<section class="content">
{% with errors = get_flashed_messages(category_filter=["error"]) %} {%
if errors %}
<div class="row">
<div class="col-md-12">
<div class="alert alert-danger alert-dismissible">
<button type="button" class="close" data-dismiss="alert"
aria-hidden="true">&times;</button>
<h4>
<i class="icon fa fa-ban"></i> Error!
</h4>
<div class="alert-message block-message error">
<a class="close" href="#">x</a>
<ul>
{%- for msg in errors %}
<li>{{ msg }}</li> {% endfor -%}
</ul>
</div>
</div>
</div>
</div>
{% endif %} {% endwith %}
<div class="row">
<div class="col-md-4">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">Create new template</h3>
</div>
<!-- /.box-header -->
<!-- form start -->
<form role="form" method="post"
action="{{ url_for('create_template') }}">
<div class="box-body">
<div class="form-group">
<input type="text" class="form-control" name="name" id="name"
placeholder="Enter a valid template name (required)">
</div>
<div class="form-group">
<input type="text" class="form-control" name="description"
id="description"
placeholder="Enter a template description (optional)">
</div>
</div>
<div class="box-footer">
<button type="submit" class="btn btn-flat btn-primary">Submit</button>
<button type="button" class="btn btn-flat btn-default"
onclick="window.location.href='{{ url_for('templates') }}'">Cancel</button>
</div>
</form>
</div>
<!-- /.box -->
</div>
<div class="col-md-8">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">Help with creating a new template</h3>
</div>
<div class="box-body">
<dl class="dl-horizontal">
<dt>Template name</dt>
<dd>Enter your template name, this is the name of the template that
will be shown to users. The name should not have any spaces but
can have symbols.</dd>
<dt>Template description</dt>
<dd>Enter your template description, this is to help better
identify the template.</dd>
</dl>
</div>
</div>
</div>
</div>
</section>
{% endblock %}
{% block extrascripts %}
<script>
$("input[name=radio_type]").change(function() {
var type = $(this).val();
if (type == "slave") {
$("#domain_master_address_div").show();
} else {
$("#domain_master_address_div").hide();
}
});
</script>
{% endblock %}

View File

@ -0,0 +1,415 @@
{% extends "base.html" %}
{% block title %}<title>DNS Control Panel - Edit Template</title>{% endblock %}
{% block dashboard_stat %}
<section class="content-header">
<h1>
Edit template <small>{{ template }}</small>
</h1>
<ol class="breadcrumb">
<li><a href="{{ url_for('dashboard') }}"><i
class="fa fa-dashboard"></i> Home</a></li>
<li>Templates</li>
<li class="active">{{ template }}</li>
</ol>
</section>
{% endblock %}
{% block content %}
<section class="content">
<div class="row">
<div class="col-xs-12">
<div class="box">
<div class="box-header">
<h3 class="box-title">Manage Template Records for {{ template }}</h3>
</div>
<div class="box-body">
<button type="button" class="btn btn-flat btn-primary pull-left button_add_record" id="{{ template }}">
Add Record&nbsp;<i class="fa fa-plus"></i>
</button>
<button type="button" class="btn btn-flat btn-primary pull-right button_apply_changes" id="{{ template }}">
Apply Changes&nbsp;<i class="fa fa-floppy-o"></i>
</button>
</div>
<div class="box-body">
<table id="tbl_records" class="table table-bordered table-striped">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Status</th>
<th>TTL</th>
<th>Data</th>
<th>Edit</th>
<th>Delete</th>
<th>ID</th>
</tr>
</thead>
<tbody>
{% for record in records %}
<tr class="odd row_record" id="{{ record.name }}">
<td>
{{ record.name }}
</td>
<td>
{{ record.type }}
</td>
<td>
{{ record.status }}
</td>
<td>
{{ record.ttl }}
</td>
<td class="length-break">
{{ record.data }}
</td>
<td width="6%">
<button type="button" class="btn btn-flat btn-warning button_edit" id="{{ record.name }}">
Edit&nbsp;<i class="fa fa-edit"></i>
</button>
</td>
<td width="6%">
<button type="button" class="btn btn-flat btn-danger button_delete" id="{{ record.name }}">
Delete&nbsp;<i class="fa fa-trash"></i>
</button>
</td>
<td>
{{ record.id }}
</td>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</section>
{% endblock %}
{% block extrascripts %}
<script>
// superglobals
window.records_allow_edit = {{ editable_records|tojson }};
window.nEditing = null;
window.nNew = false;
// set up user data table
$("#tbl_records").DataTable({
"paging" : true,
"lengthChange" : true,
"searching" : true,
"ordering" : true,
"info" : true,
"autoWidth" : false,
{% if default_record_table_size_setting in ['5','15','20'] %}
"lengthMenu": [ [5, 15, 20, -1],
[5, 15, 20, "All"]],
{% else %}
"lengthMenu": [ [5, 15, 20, {{ default_record_table_size_setting }}, -1],
[5, 15, 20, {{ default_record_table_size_setting }}, "All"]],
{% endif %}
"pageLength": {{ default_record_table_size_setting }},
"language": {
"lengthMenu": " _MENU_ records"
},
"retrieve" : true,
"columnDefs": [{
"targets": [ 7 ],
"visible": false,
"searchable": false
}]
});
// handle delete button
$(document.body).on("click", ".button_delete", function(e) {
e.stopPropagation();
var modal = $("#modal_delete");
var table = $("#tbl_records").DataTable();
var record = $(this).prop('id');
var nRow = $(this).parents('tr')[0];
var info = "Are you sure you want to delete " + record + "?";
modal.find('.modal-body p').text(info);
modal.find('#button_delete_confirm').click(function() {
table.row(nRow).remove().draw();
modal.modal('hide');
})
modal.modal('show');
});
// handle edit button
$(document.body).on("click", ".button_edit, .row_record", function(e) {
e.stopPropagation();
if ($(this).is('tr')) {
var nRow = $(this)[0];
} else {
var nRow = $(this).parents('tr')[0];
}
var table = $("#tbl_records").DataTable();
if (nEditing == nRow) {
/* click on row already being edited, do nothing */
} else if (nEditing !== null && nEditing != nRow && nNew == false) {
/* Currently editing - but not this row - restore the old before continuing to edit mode */
restoreRow(table, nEditing);
editRow(table, nRow);
nEditing = nRow;
} else if (nNew == true) {
/* adding a new row, delete it and start editing */
table.row(nEditing).remove().draw();
nNew = false;
editRow(table, nRow);
nEditing = nRow;
} else {
/* No edit in progress - let's start one */
editRow(table, nRow);
nEditing = nRow;
}
});
// handle apply changes button
$(document.body).on("click",".button_apply_changes", function() {
var modal = $("#modal_apply_changes");
var table = $("#tbl_records").DataTable();
var template = $(this).prop('id');
var info = "Are you sure you want to apply your changes?";
modal.find('.modal-body p').text(info);
modal.find('#button_apply_confirm').click(function() {
var data = getTableData(table);
applyChanges(data, '/template/' + template + '/apply', true);
modal.modal('hide');
})
modal.modal('show');
});
// handle add record button
$(document.body).on("click", ".button_add_record", function (e) {
if (nNew || nEditing) {
// TODO: replace this alert with modal
alert("Previous record not saved. Please save it before adding more record.")
return;
}
var table = $("#tbl_records").DataTable();
var aiNew = table.row.add(['', 'A', 'Active', 3600, '', '', '', '']).draw();
var nRow = aiNew.index();
editRow(table, nRow);
nEditing = nRow;
nNew = true;
});
//handle cancel button
$(document.body).on("click", ".button_cancel", function (e) {
e.stopPropagation();
var oTable = $("#tbl_records").DataTable();
if (nNew) {
oTable.row(nEditing).remove().draw();
nEditing = null;
nNew = false;
} else {
restoreRow(oTable, nEditing);
nEditing = null;
}
});
//handle save button
$(document.body).on("click", ".button_save", function (e) {
e.stopPropagation();
var table = $("#tbl_records").DataTable();
saveRow(table, nEditing);
nEditing = null;
nNew = false;
});
{% if record_helper_setting %}
//handle wacky record types
$(document.body).on("focus", "#current_edit_record_data", function (e) {
var record_type = $(this).parents("tr").find('#record_type').val();
var record_data = $(this);
if (record_type == "MX") {
var modal = $("#modal_custom_record");
if (record_data.val() == "") {
var form = " <label for=\"mx_priority\">MX Priority</label> \
<input type=\"text\" class=\"form-control\" name=\"mx_priority\" id=\"mx_priority\" placeholder=\"10\"> \
<label for=\"mx_server\">MX Server</label> \
<input type=\"text\" class=\"form-control\" name=\"mx_server\" id=\"mx_server\" placeholder=\"postfix.example.com\"> \
";
} else {
var parts = record_data.val().split(" ");
var form = " <label for=\"mx_priority\">MX Priority</label> \
<input type=\"text\" class=\"form-control\" name=\"mx_priority\" id=\"mx_priority\" placeholder=\"10\" value=\"" + parts[0] + "\"> \
<label for=\"mx_server\">MX Server</label> \
<input type=\"text\" class=\"form-control\" name=\"mx_server\" id=\"mx_server\" placeholder=\"postfix.example.com\" value=\"" + parts[1] + "\"> \
";
}
modal.find('.modal-body p').html(form);
modal.find('#button_save').click(function() {
mx_server = modal.find('#mx_server').val();
mx_priority = modal.find('#mx_priority').val();
data = mx_priority + " " + mx_server;
record_data.val(data);
modal.modal('hide');
})
modal.modal('show');
} else if (record_type == "SRV") {
var modal = $("#modal_custom_record");
if (record_data.val() == "") {
var form = " <label for=\"srv_priority\">SRV Priority</label> \
<input type=\"text\" class=\"form-control\" name=\"srv_priority\" id=\"srv_priority\" placeholder=\"0\"> \
<label for=\"srv_weight\">SRV Weight</label> \
<input type=\"text\" class=\"form-control\" name=\"srv_weight\" id=\"srv_weight\" placeholder=\"10\"> \
<label for=\"srv_port\">SRV Port</label> \
<input type=\"text\" class=\"form-control\" name=\"srv_port\" id=\"srv_port\" placeholder=\"5060\"> \
<label for=\"srv_target\">SRV Target</label> \
<input type=\"text\" class=\"form-control\" name=\"srv_target\" id=\"srv_target\" placeholder=\"sip.example.com\"> \
";
} else {
var parts = record_data.val().split(" ");
var form = " <label for=\"srv_priority\">SRV Priority</label> \
<input type=\"text\" class=\"form-control\" name=\"srv_priority\" id=\"srv_priority\" placeholder=\"0\" value=\"" + parts[0] + "\"> \
<label for=\"srv_weight\">SRV Weight</label> \
<input type=\"text\" class=\"form-control\" name=\"srv_weight\" id=\"srv_weight\" placeholder=\"10\" value=\"" + parts[1] + "\"> \
<label for=\"srv_port\">SRV Port</label> \
<input type=\"text\" class=\"form-control\" name=\"srv_port\" id=\"srv_port\" placeholder=\"5060\" value=\"" + parts[2] + "\"> \
<label for=\"srv_target\">SRV Target</label> \
<input type=\"text\" class=\"form-control\" name=\"srv_target\" id=\"srv_target\" placeholder=\"sip.example.com\" value=\"" + parts[3] + "\"> \
";
}
modal.find('.modal-body p').html(form);
modal.find('#button_save').click(function() {
srv_priority = modal.find('#srv_priority').val();
srv_weight = modal.find('#srv_weight').val();
srv_port = modal.find('#srv_port').val();
srv_target = modal.find('#srv_target').val();
data = srv_priority + " " + srv_weight + " " + srv_port + " " + srv_target;
record_data.val(data);
modal.modal('hide');
})
modal.modal('show');
} else if (record_type == "SOA") {
var modal = $("#modal_custom_record");
if (record_data.val() == "") {
var form = " <label for=\"soa_primaryns\">Primary Name Server</label> \
<input type=\"text\" class=\"form-control\" name=\"soa_primaryns\" id=\"soa_primaryns\" placeholder=\"ns1.example.com\"> \
<label for=\"soa_adminemail\">Primary Contact</label> \
<input type=\"text\" class=\"form-control\" name=\"soa_adminemail\" id=\"soa_adminemail\" placeholder=\"admin.example.com\"> \
<label for=\"soa_serial\">Serial</label> \
<input type=\"text\" class=\"form-control\" name=\"soa_serial\" id=\"soa_serial\" placeholder=\"2016010101\"> \
<label for=\"soa_zonerefresh\">Zone refresh timer</label> \
<input type=\"text\" class=\"form-control\" name=\"soa_zonerefresh\" id=\"soa_zonerefresh\" placeholder=\"86400\"> \
<label for=\"soa_failedzonerefresh\">Failed refresh retry timer</label> \
<input type=\"text\" class=\"form-control\" name=\"soa_failedzonerefresh\" id=\"soa_failedzonerefresh\" placeholder=\"7200\"> \
<label for=\"soa_zoneexpiry\">Zone expiry timer</label> \
<input type=\"text\" class=\"form-control\" name=\"soa_zoneexpiry\" id=\"soa_zoneexpiry\" placeholder=\"604800\"> \
<label for=\"soa_minimumttl\">Minimum TTL</label> \
<input type=\"text\" class=\"form-control\" name=\"soa_minimumttl\" id=\"soa_minimumttl\" placeholder=\"300\"> \
";
} else {
var parts = record_data.val().split(" ");
var form = " <label for=\"soa_primaryns\">Primary Name Server</label> \
<input type=\"text\" class=\"form-control\" name=\"soa_primaryns\" id=\"soa_primaryns\" value=\"" + parts[0] + "\"> \
<label for=\"soa_adminemail\">Primary Contact</label> \
<input type=\"text\" class=\"form-control\" name=\"soa_adminemail\" id=\"soa_adminemail\" value=\"" + parts[1] + "\"> \
<label for=\"soa_serial\">Serial</label> \
<input type=\"text\" class=\"form-control\" name=\"soa_serial\" id=\"soa_serial\" value=\"" + parts[2] + "\"> \
<label for=\"soa_zonerefresh\">Zone refresh timer</label> \
<input type=\"text\" class=\"form-control\" name=\"soa_zonerefresh\" id=\"soa_zonerefresh\" value=\"" + parts[3] + "\"> \
<label for=\"soa_failedzonerefresh\">Failed refresh retry timer</label> \
<input type=\"text\" class=\"form-control\" name=\"soa_failedzonerefresh\" id=\"soa_failedzonerefresh\" value=\"" + parts[4] + "\"> \
<label for=\"soa_zoneexpiry\">Zone expiry timer</label> \
<input type=\"text\" class=\"form-control\" name=\"soa_zoneexpiry\" id=\"soa_zoneexpiry\" value=\"" + parts[5] + "\"> \
<label for=\"soa_minimumttl\">Minimum TTL</label> \
<input type=\"text\" class=\"form-control\" name=\"soa_minimumttl\" id=\"soa_minimumttl\" value=\"" + parts[6] + "\"> \
";
}
modal.find('.modal-body p').html(form);
modal.find('#button_save').click(function() {
soa_primaryns = modal.find('#soa_primaryns').val();
soa_adminemail = modal.find('#soa_adminemail').val();
soa_serial = modal.find('#soa_serial').val();
soa_zonerefresh = modal.find('#soa_zonerefresh').val();
soa_failedzonerefresh = modal.find('#soa_failedzonerefresh').val();
soa_zoneexpiry = modal.find('#soa_zoneexpiry').val();
soa_minimumttl = modal.find('#soa_minimumttl').val();
data = soa_primaryns + " " + soa_adminemail + " " + soa_serial + " " + soa_zonerefresh + " " + soa_failedzonerefresh + " " + soa_zoneexpiry + " " + soa_minimumttl;
record_data.val(data);
modal.modal('hide');
})
modal.modal('show');
}
});
{% endif %}
</script>
{% endblock %}
{% block modals %}
<div class="modal fade modal-warning" id="modal_delete">
<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">&times;</span>
</button>
<h4 class="modal-title">Confirmation</h4>
</div>
<div class="modal-body">
<p></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-flat btn-default pull-left"
data-dismiss="modal">Close</button>
<button type="button" class="btn btn-flat btn-danger" id="button_delete_confirm">Delete</button>
</div>
</div>
<!-- /.modal-content -->
</div>
<!-- /.modal-dialog -->
</div>
<div class="modal fade modal-primary" id="modal_apply_changes">
<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">&times;</span>
</button>
<h4 class="modal-title">Confirmation</h4>
</div>
<div class="modal-body">
<p></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-flat btn-default pull-left"
data-dismiss="modal">Close</button>
<button type="button" class="btn btn-flat btn-primary" id="button_apply_confirm">Apply</button>
</div>
</div>
<!-- /.modal-content -->
</div>
<!-- /.modal-dialog -->
</div>
<div class="modal fade modal-primary" id="modal_custom_record">
<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">&times;</span>
</button>
<h4 class="modal-title">Custom Record</h4>
</div>
<div class="modal-body">
<p></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-flat btn-primary" id="button_save">Save</button>
</div>
</div>
<!-- /.modal-content -->
</div>
<!-- /.modal-dialog -->
</div>
{% endblock %}

View File

@ -11,17 +11,21 @@ from io import BytesIO
import jinja2 import jinja2
import qrcode as qrc import qrcode as qrc
import qrcode.image.svg as qrc_svg import qrcode.image.svg as qrc_svg
from flask import g, request, make_response, jsonify, render_template, session, redirect, url_for, send_from_directory, abort from flask import g, request, make_response, jsonify, render_template, session, redirect, url_for, send_from_directory, abort, flash
from flask_login import login_user, logout_user, current_user, login_required from flask_login import login_user, logout_user, current_user, login_required
from werkzeug import secure_filename from werkzeug import secure_filename
from werkzeug.security import gen_salt from werkzeug.security import gen_salt
from .models import User, Domain, Record, Server, History, Anonymous, Setting, DomainSetting from .models import User, Domain, Record, Server, History, Anonymous, Setting, DomainSetting, DomainTemplate, DomainTemplateRecord
from app import app, login_manager, github, google from app import app, login_manager, github, google
from app.lib import utils from app.lib import utils
from app.lib.log import logger
from app.decorators import admin_role_required, can_access_domain from app.decorators import admin_role_required, can_access_domain
# LOG CONFIG
logging = logger('MODEL', app.config['LOG_LEVEL'], app.config['LOG_FILE']).config()
# FILTERS
jinja2.filters.FILTERS['display_record_name'] = utils.display_record_name jinja2.filters.FILTERS['display_record_name'] = utils.display_record_name
jinja2.filters.FILTERS['display_master_name'] = utils.display_master_name jinja2.filters.FILTERS['display_master_name'] = utils.display_master_name
jinja2.filters.FILTERS['display_second_to_time'] = utils.display_time jinja2.filters.FILTERS['display_second_to_time'] = utils.display_time
@ -436,10 +440,13 @@ def domain(domain_name):
@login_required @login_required
@admin_role_required @admin_role_required
def domain_add(): def domain_add():
templates = DomainTemplate.query.all()
if request.method == 'POST': if request.method == 'POST':
try: try:
domain_name = request.form.getlist('domain_name')[0] domain_name = request.form.getlist('domain_name')[0]
domain_type = request.form.getlist('radio_type')[0] domain_type = request.form.getlist('radio_type')[0]
domain_template = request.form.getlist('domain_template')[0]
logging.info("Selected template ==== {0}".format(domain_template))
soa_edit_api = request.form.getlist('radio_type_soa_edit_api')[0] soa_edit_api = request.form.getlist('radio_type_soa_edit_api')[0]
if ' ' in domain_name or not domain_name or not domain_type: if ' ' in domain_name or not domain_name or not domain_type:
@ -457,12 +464,28 @@ def domain_add():
if result['status'] == 'ok': if result['status'] == 'ok':
history = History(msg='Add domain %s' % domain_name, detail=str({'domain_type': domain_type, 'domain_master_ips': domain_master_ips}), created_by=current_user.username) history = History(msg='Add domain %s' % domain_name, detail=str({'domain_type': domain_type, 'domain_master_ips': domain_master_ips}), created_by=current_user.username)
history.add() history.add()
if domain_template != '0':
template = DomainTemplate.query.filter(DomainTemplate.id == domain_template).first()
template_records = DomainTemplateRecord.query.filter(DomainTemplateRecord.template_id == domain_template).all()
record_data = []
for template_record in template_records:
record_row = {'record_data': template_record.data, 'record_name': template_record.name, 'record_status': template_record.status, 'record_ttl': template_record.ttl, 'record_type': template_record.type}
record_data.append(record_row)
r = Record()
result = r.apply(domain_name, record_data)
if result['status'] == 'ok':
history = History(msg='Applying template %s to %s, created records successfully.' % (template.name, domain_name), detail=str(result), created_by=current_user.username)
history.add()
else:
history = History(msg='Applying template %s to %s, FAILED to created records.' % (template.name, domain_name), detail=str(result), created_by=current_user.username)
history.add()
return redirect(url_for('dashboard')) return redirect(url_for('dashboard'))
else: else:
return render_template('errors/400.html', msg=result['msg']), 400 return render_template('errors/400.html', msg=result['msg']), 400
except: except:
logging.error(traceback.print_exc())
return redirect(url_for('error', code=500)) return redirect(url_for('error', code=500))
return render_template('domain_add.html') return render_template('domain_add.html', templates=templates)
@app.route('/admin/domain/<path:domain_name>/delete', methods=['GET']) @app.route('/admin/domain/<path:domain_name>/delete', methods=['GET'])
@ -534,7 +557,7 @@ def record_apply(domain_name):
else: else:
return make_response(jsonify( result ), 400) return make_response(jsonify( result ), 400)
except: except:
traceback.print_exc() logging.error(traceback.print_exc())
return make_response(jsonify( {'status': 'error', 'msg': 'Error when applying new changes'} ), 500) return make_response(jsonify( {'status': 'error', 'msg': 'Error when applying new changes'} ), 500)
@ -557,7 +580,7 @@ def record_update(domain_name):
else: else:
return make_response(jsonify( {'status': 'error', 'msg': result['msg']} ), 500) return make_response(jsonify( {'status': 'error', 'msg': result['msg']} ), 500)
except: except:
traceback.print_exc() logging.error(traceback.print_exc())
return make_response(jsonify( {'status': 'error', 'msg': 'Error when applying new changes'} ), 500) return make_response(jsonify( {'status': 'error', 'msg': 'Error when applying new changes'} ), 500)
@ -571,7 +594,7 @@ def record_delete(domain_name, record_name, record_type):
if result['status'] == 'error': if result['status'] == 'error':
print(result['msg']) print(result['msg'])
except: except:
traceback.print_exc() logging.error(traceback.print_exc())
return redirect(url_for('error', code=500)), 500 return redirect(url_for('error', code=500)), 500
return redirect(url_for('domain', domain_name=domain_name)) return redirect(url_for('domain', domain_name=domain_name))
@ -621,10 +644,182 @@ def admin_setdomainsetting(domain_name):
else: else:
return make_response(jsonify( { 'status': 'error', 'msg': 'Action not supported.' } ), 400) return make_response(jsonify( { 'status': 'error', 'msg': 'Action not supported.' } ), 400)
except: except:
traceback.print_exc() logging.error(traceback.print_exc())
return make_response(jsonify( { 'status': 'error', 'msg': 'There is something wrong, please contact Administrator.' } ), 400) return make_response(jsonify( { 'status': 'error', 'msg': 'There is something wrong, please contact Administrator.' } ), 400)
@app.route('/templates', methods=['GET', 'POST'])
@app.route('/templates/list', methods=['GET', 'POST'])
@login_required
@admin_role_required
def templates():
templates = DomainTemplate.query.all()
return render_template('template.html', templates=templates)
@app.route('/template/create', methods=['GET', 'POST'])
@login_required
@admin_role_required
def create_template():
if request.method == 'GET':
return render_template('template_add.html')
if request.method == 'POST':
try:
name = request.form.getlist('name')[0]
description = request.form.getlist('description')[0]
if ' ' in name or not name or not type:
flash("Please correct your input", 'error')
return redirect(url_for('create_template'))
if DomainTemplate.query.filter(DomainTemplate.name == name).first():
flash("A template with the name %s already exists!" % name, 'error')
return redirect(url_for('create_template'))
t = DomainTemplate(name=name, description=description)
result = t.create()
if result['status'] == 'ok':
history = History(msg='Add domain template %s' % name, detail=str({'name': name, 'description': description}), created_by=current_user.username)
history.add()
return redirect(url_for('templates'))
else:
flash(result['msg'], 'error')
return redirect(url_for('create_template'))
except:
logging.error(traceback.print_exc())
return redirect(url_for('error', code=500))
return redirect(url_for('templates'))
@app.route('/template/createfromzone', methods=['POST'])
@login_required
@admin_role_required
def create_template_from_zone():
try:
jdata = request.json
name = jdata['name']
description = jdata['description']
domain_name = jdata['domain']
if ' ' in name or not name or not type:
return make_response(jsonify({'status': 'error', 'msg': 'Please correct template name'}), 500)
if DomainTemplate.query.filter(DomainTemplate.name == name).first():
return make_response(jsonify({'status': 'error', 'msg': 'A template with the name %s already exists!' % name}), 500)
t = DomainTemplate(name=name, description=description)
result = t.create()
if result['status'] == 'ok':
history = History(msg='Add domain template %s' % name, detail=str({'name': name, 'description': description}), created_by=current_user.username)
history.add()
records = []
r = Record()
domain = Domain.query.filter(Domain.name == domain_name).first()
if domain:
# query domain info from PowerDNS API
zone_info = r.get_record_data(domain.name)
if zone_info:
jrecords = zone_info['records']
if NEW_SCHEMA:
for jr in jrecords:
name = '@' if jr['name'] == domain_name else jr['name']
if jr['type'] in app.config['RECORDS_ALLOW_EDIT']:
for subrecord in jr['records']:
record = DomainTemplateRecord(name=name, type=jr['type'], status=True if subrecord['disabled'] else False, ttl=jr['ttl'], data=subrecord['content'])
records.append(record)
else:
for jr in jrecords:
if jr['type'] in app.config['RECORDS_ALLOW_EDIT']:
record = DomainTemplateRecord(name=name, type=jr['type'], status=True if jr['disabled'] else False, ttl=jr['ttl'], data=jr['content'])
records.append(record)
result_records = t.replace_records(records)
if result_records['status'] == 'ok':
return make_response(jsonify({'status': 'ok', 'msg': result['msg']}), 200)
else:
result = t.delete_template()
return make_response(jsonify({'status': 'error', 'msg': result_records['msg']}), 500)
else:
return make_response(jsonify({'status': 'error', 'msg': result['msg']}), 500)
except:
logging.error(traceback.print_exc())
return make_response(jsonify({'status': 'error', 'msg': 'Error when applying new changes'}), 500)
@app.route('/template/<string:template>/edit', methods=['GET'])
@login_required
@admin_role_required
def edit_template(template):
try:
t = DomainTemplate.query.filter(DomainTemplate.name == template).first()
if t is not None:
records = []
for jr in t.records:
if jr.type in app.config['RECORDS_ALLOW_EDIT']:
record = DomainTemplateRecord(name=jr.name, type=jr.type, status='Disabled' if jr.status else 'Active', ttl=jr.ttl, data=jr.data)
records.append(record)
return render_template('template_edit.html', template=t.name, records=records, editable_records=app.config['RECORDS_ALLOW_EDIT'])
except:
logging.error(traceback.print_exc())
return redirect(url_for('error', code=500))
return redirect(url_for('templates'))
@app.route('/template/<string:template>/apply', methods=['POST'], strict_slashes=False)
@login_required
def apply_records(template):
try:
jdata = request.json
records = []
for j in jdata:
name = '@' if j['record_name'] in ['@', ''] else j['record_name']
type = j['record_type']
data = j['record_data']
disabled = True if j['record_status'] == 'Disabled' else False
ttl = int(j['record_ttl']) if j['record_ttl'] else 3600
dtr = DomainTemplateRecord(name=name, type=type, data=data, status=disabled, ttl=ttl)
records.append(dtr)
t = DomainTemplate.query.filter(DomainTemplate.name == template).first()
result = t.replace_records(records)
if result['status'] == 'ok':
history = History(msg='Apply domain template record changes to domain template %s' % template, detail=str(jdata), created_by=current_user.username)
history.add()
return make_response(jsonify(result), 200)
else:
return make_response(jsonify(result), 400)
except:
logging.error(traceback.print_exc())
return make_response(jsonify({'status': 'error', 'msg': 'Error when applying new changes'}), 500)
@app.route('/template/<string:template>/delete', methods=['GET'])
@login_required
@admin_role_required
def delete_template(template):
try:
t = DomainTemplate.query.filter(DomainTemplate.name == template).first()
if t is not None:
result = t.delete_template()
if result['status'] == 'ok':
history = History(msg='Deleted domain template %s' % template, detail=str({'name': template}), created_by=current_user.username)
history.add()
return redirect(url_for('templates'))
else:
flash(result['msg'], 'error')
return redirect(url_for('templates'))
except:
logging.error(traceback.print_exc())
return redirect(url_for('error', code=500))
return redirect(url_for('templates'))
@app.route('/admin', methods=['GET', 'POST']) @app.route('/admin', methods=['GET', 'POST'])
@login_required @login_required
@admin_role_required @admin_role_required
@ -718,7 +913,7 @@ def admin_manageuser():
else: else:
return make_response(jsonify( { 'status': 'error', 'msg': 'Action not supported.' } ), 400) return make_response(jsonify( { 'status': 'error', 'msg': 'Action not supported.' } ), 400)
except: except:
traceback.print_exc() logging.error(traceback.print_exc())
return make_response(jsonify( { 'status': 'error', 'msg': 'There is something wrong, please contact Administrator.' } ), 400) return make_response(jsonify( { 'status': 'error', 'msg': 'There is something wrong, please contact Administrator.' } ), 400)
@ -883,7 +1078,7 @@ def dyndns_update():
r = Record() r = Record()
r.name = hostname r.name = hostname
# check if the user requested record exists within this domain # check if the user requested record exists within this domain
if r.exists(domain.name) and r.is_allowed: if r.exists(domain.name) and r.is_allowed_edit():
if r.data == myip: if r.data == myip:
# record content did not change, return 'nochg' # record content did not change, return 'nochg'
history = History(msg="DynDNS update: attempted update of %s but record did not change" % hostname, created_by=current_user.username) history = History(msg="DynDNS update: attempted update of %s but record did not change" % hostname, created_by=current_user.username)
@ -898,7 +1093,7 @@ def dyndns_update():
return render_template('dyndns.html', response='good'), 200 return render_template('dyndns.html', response='good'), 200
else: else:
return render_template('dyndns.html', response='911'), 200 return render_template('dyndns.html', response='911'), 200
elif r.is_allowed: elif r.is_allowed_edit():
ondemand_creation = DomainSetting.query.filter(DomainSetting.domain == domain).filter(DomainSetting.setting == 'create_via_dyndns').first() ondemand_creation = DomainSetting.query.filter(DomainSetting.domain == domain).filter(DomainSetting.setting == 'create_via_dyndns').first()
if (ondemand_creation != None) and (strtobool(ondemand_creation.value) == True): if (ondemand_creation != None) and (strtobool(ondemand_creation.value) == True):
record = Record(name=hostname,type='A',data=myip,status=False,ttl=3600) record = Record(name=hostname,type='A',data=myip,status=False,ttl=3600)

View File

@ -9,7 +9,7 @@ from migrate.versioning import api
from config import SQLALCHEMY_DATABASE_URI from config import SQLALCHEMY_DATABASE_URI
from config import SQLALCHEMY_MIGRATE_REPO from config import SQLALCHEMY_MIGRATE_REPO
from app import db from app import db
from app.models import Role, Setting from app.models import Role, Setting, DomainTemplate
def start(): def start():
@ -69,6 +69,23 @@ def init_settings(db, setting_names):
for setting in settings: for setting in settings:
db.session.add(setting) db.session.add(setting)
def init_domain_templates(db, domain_template_names):
# Get key name of data
name_of_domain_templates = map(lambda r: r.name, domain_template_names)
# Query to get current data
rows = db.session.query(DomainTemplate).filter(DomainTemplate.name.in_(name_of_domain_templates)).all()
# Check which data that need to insert
name_of_rows = map(lambda r: r.name, rows)
domain_templates = filter(lambda r: r.name not in name_of_rows, domain_template_names)
# Insert data
for domain_template in domain_templates:
db.session.add(domain_template)
def init_records(): def init_records():
# Create initial user roles and turn off maintenance mode # Create initial user roles and turn off maintenance mode
init_roles(db, [ init_roles(db, [
@ -84,7 +101,12 @@ def init_records():
Setting('default_domain_table_size', '10'), Setting('default_domain_table_size', '10'),
Setting('auto_ptr','False') Setting('auto_ptr','False')
]) ])
# TODO: add sample records to sample templates
init_domain_templates(db, [
DomainTemplate('basic_template_1', 'Basic Template #1'),
DomainTemplate('basic_template_2', 'Basic Template #2'),
DomainTemplate('basic_template_3', 'Basic Template #3')
])
db_commit = db.session.commit() db_commit = db.session.commit()
commit_version_control(db_commit) commit_version_control(db_commit)