mirror of
https://github.com/cwinfo/powerdns-admin.git
synced 2024-11-08 14:40:27 +00:00
Add per-domain settings. Allows ondemand dyndns A records. Fixes #61.
This commit adds a new table to store per-domain settings, so a database migrate/upgrade will be required. The first use-case is to allow dyndns updates to create a record if one doesn't yet exist but only if the per-domain setting is set.
This commit is contained in:
parent
54954082c5
commit
d093c1976d
@ -395,6 +395,35 @@ class Role(db.Model):
|
||||
def __repr__(self):
|
||||
return '<Role %r>' % (self.name)
|
||||
|
||||
class DomainSetting(db.Model):
|
||||
__tablename__ = 'domain_setting'
|
||||
id = db.Column(db.Integer, primary_key = True)
|
||||
domain_id = db.Column(db.Integer, db.ForeignKey('domain.id'))
|
||||
domain = db.relationship('Domain', back_populates='settings')
|
||||
setting = db.Column(db.String(255), nullable = False)
|
||||
value = db.Column(db.String(255))
|
||||
|
||||
def __init__(self, id=None, setting=None, value=None):
|
||||
self.id = id
|
||||
self.setting = setting
|
||||
self.value = value
|
||||
|
||||
def __repr__(self):
|
||||
return '<DomainSetting %r for $d>' % (setting, self.domain.name)
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.setting == other.setting
|
||||
|
||||
def set(self, value):
|
||||
try:
|
||||
self.value = value
|
||||
db.session.commit()
|
||||
return True
|
||||
except:
|
||||
logging.error('Unable to set DomainSetting value')
|
||||
logging.debug(traceback.format_exc())
|
||||
db.session.rollback()
|
||||
return False
|
||||
|
||||
class Domain(db.Model):
|
||||
id = db.Column(db.Integer, primary_key = True)
|
||||
@ -405,6 +434,7 @@ class Domain(db.Model):
|
||||
notified_serial = db.Column(db.Integer)
|
||||
last_check = db.Column(db.Integer)
|
||||
dnssec = db.Column(db.Integer)
|
||||
settings = db.relationship('DomainSetting', back_populates='domain')
|
||||
|
||||
def __init__(self, id=None, name=None, master=None, type='NATIVE', serial=None, notified_serial=None, last_check=None, dnssec=None):
|
||||
self.id = id
|
||||
@ -418,6 +448,15 @@ class Domain(db.Model):
|
||||
|
||||
def __repr__(self):
|
||||
return '<Domain %r>' % (self.name)
|
||||
|
||||
def add_setting(self, setting, value):
|
||||
try:
|
||||
self.settings.append(DomainSetting(setting=setting, value=value))
|
||||
db.session.commit()
|
||||
return True
|
||||
except Exception, e:
|
||||
logging.error('Can not create settting %s for domain %s. %s' % (setting, self.name, str(e)))
|
||||
return False
|
||||
|
||||
def get_domains(self):
|
||||
"""
|
||||
|
@ -55,6 +55,21 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="box">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title">DynDNS 2 Settings</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<p><input type="checkbox" id="{{ domain.name }}" class="dyndns_on_demand_toggle"
|
||||
{% for setting in domain.settings %}{% if setting.setting=='create_via_dyndns' and setting.value=='1' %}checked{% endif %}{% endfor %}>
|
||||
Allow on-demand creation of records via DynDNS updates?</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="box">
|
||||
@ -74,8 +89,28 @@
|
||||
{% endblock %}
|
||||
{% block extrascripts %}
|
||||
<script>
|
||||
//initialize pretty checkboxes
|
||||
$('.dyndns_on_demand_toggle').iCheck({
|
||||
checkboxClass : 'icheckbox_square-blue',
|
||||
increaseArea : '20%' // optional
|
||||
});
|
||||
|
||||
$("#domain_multi_user").multiSelect();
|
||||
|
||||
//handle checkbox toggling
|
||||
$('.dyndns_on_demand_toggle').on('ifToggled', function(event) {
|
||||
var is_checked = $(this).prop('checked');
|
||||
var domain = $(this).prop('id');
|
||||
postdata = {
|
||||
'action' : 'set_setting',
|
||||
'data' : {
|
||||
'setting' : 'create_via_dyndns',
|
||||
'value' : is_checked
|
||||
}
|
||||
};
|
||||
applyChanges(postdata, '/domain/' + domain + '/managesetting', true);
|
||||
});
|
||||
|
||||
// handle deletion of user
|
||||
$(document.body).on('click', '.delete_domain', function() {
|
||||
var modal = $("#modal_delete_domain");
|
||||
|
102
app/views.py
102
app/views.py
@ -12,11 +12,12 @@ from werkzeug import secure_filename
|
||||
|
||||
from lib import utils
|
||||
from app import app, login_manager
|
||||
from .models import User, Role, Domain, DomainUser, Record, Server, History, Anonymous, Setting
|
||||
from .models import User, Role, Domain, DomainUser, Record, Server, History, Anonymous, Setting, DomainSetting
|
||||
|
||||
from io import BytesIO
|
||||
from distutils.util import strtobool
|
||||
from distutils.version import StrictVersion
|
||||
from optparse import Values
|
||||
|
||||
jinja2.filters.FILTERS['display_record_name'] = utils.display_record_name
|
||||
jinja2.filters.FILTERS['display_master_name'] = utils.display_master_name
|
||||
@ -440,6 +441,45 @@ def domain_dnssec(domain_name):
|
||||
dnssec = domain.get_domain_dnssec(domain_name)
|
||||
return make_response(jsonify(dnssec), 200)
|
||||
|
||||
@app.route('/domain/<string:domain_name>/managesetting', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
@admin_role_required
|
||||
def admin_setdomainsetting(domain_name):
|
||||
if request.method == 'POST':
|
||||
#
|
||||
# post data should in format
|
||||
# {'action': 'set_setting', 'setting': 'default_action, 'value': 'True'}
|
||||
#
|
||||
try:
|
||||
pdata = request.data
|
||||
jdata = json.loads(pdata)
|
||||
data = jdata['data']
|
||||
if jdata['action'] == 'set_setting':
|
||||
new_setting = data['setting']
|
||||
new_value = data['value']
|
||||
domain = Domain.query.filter(Domain.name == domain_name).first()
|
||||
setting = DomainSetting.query.filter(DomainSetting.domain == domain).filter(DomainSetting.setting == new_setting).first()
|
||||
|
||||
if setting:
|
||||
if setting.set(new_value):
|
||||
history = History(msg='Setting %s changed value to %s for %s' % (new_setting, new_value, domain.name), created_by=current_user.username)
|
||||
history.add()
|
||||
return make_response(jsonify( { 'status': 'ok', 'msg': 'Setting updated.' } ))
|
||||
else:
|
||||
return make_response(jsonify( { 'status': 'error', 'msg': 'Unable to set value of setting.' } ))
|
||||
else:
|
||||
if domain.add_setting(new_setting, new_value):
|
||||
history = History(msg='New setting %s with value %s for %s has been created' % (new_setting, new_value, domain.name), created_by=current_user.username)
|
||||
history.add()
|
||||
return make_response(jsonify( { 'status': 'ok', 'msg': 'New setting created and updated.' } ))
|
||||
else:
|
||||
return make_response(jsonify( { 'status': 'error', 'msg': 'Unable to create new setting.' } ))
|
||||
else:
|
||||
return make_response(jsonify( { 'status': 'error', 'msg': 'Action not supported.' } ), 400)
|
||||
except:
|
||||
print traceback.format_exc()
|
||||
return make_response(jsonify( { 'status': 'error', 'msg': 'There is something wrong, please contact Administrator.' } ), 400)
|
||||
|
||||
|
||||
@app.route('/admin', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
@ -679,26 +719,50 @@ def dyndns_update():
|
||||
domains = User(id=current_user.id).get_domain()
|
||||
except:
|
||||
return render_template('dyndns.html', response='911'), 200
|
||||
for domain in domains:
|
||||
# create new record object to use for searching and updating
|
||||
r = Record()
|
||||
r.name = hostname
|
||||
# check if the user requested record exists within this domain
|
||||
if r.exists(domain.name) and r.is_allowed:
|
||||
if r.data == myip:
|
||||
# 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)
|
||||
|
||||
domain = None
|
||||
domain_segments = hostname.split('.')
|
||||
for index in range(len(domain_segments)):
|
||||
domain_segments.pop(0)
|
||||
full_domain = '.'.join(domain_segments)
|
||||
potential_domain = Domain.query.filter(Domain.name == full_domain).first()
|
||||
if potential_domain in domains:
|
||||
domain = potential_domain
|
||||
break
|
||||
|
||||
if not domain:
|
||||
history = History(msg="DynDNS update: attempted update of %s but it does not exist for this user" % hostname, created_by=current_user.username)
|
||||
history.add()
|
||||
return render_template('dyndns.html', response='nohost'), 200
|
||||
|
||||
r = Record()
|
||||
r.name = hostname
|
||||
# check if the user requested record exists within this domain
|
||||
if r.exists(domain.name) and r.is_allowed:
|
||||
if r.data == myip:
|
||||
# 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.add()
|
||||
return render_template('dyndns.html', response='nochg'), 200
|
||||
else:
|
||||
oldip = r.data
|
||||
result = r.update(domain.name, myip)
|
||||
if result['status'] == 'ok':
|
||||
history = History(msg='DynDNS update: updated record %s in zone %s, it changed from %s to %s' % (hostname,domain.name,oldip,myip), detail=str(result), created_by=current_user.username)
|
||||
history.add()
|
||||
return render_template('dyndns.html', response='nochg'), 200
|
||||
return render_template('dyndns.html', response='good'), 200
|
||||
else:
|
||||
oldip = r.data
|
||||
result = r.update(domain.name, myip)
|
||||
if result['status'] == 'ok':
|
||||
history = History(msg='DynDNS update: updated record %s in zone %s, it changed from %s to %s' % (hostname,domain.name,oldip,myip), detail=str(result), created_by=current_user.username)
|
||||
history.add()
|
||||
return render_template('dyndns.html', response='good'), 200
|
||||
else:
|
||||
return render_template('dyndns.html', response='911'), 200
|
||||
return render_template('dyndns.html', response='911'), 200
|
||||
elif r.is_allowed:
|
||||
ondemand_creation = DomainSetting.query.filter(DomainSetting.domain == domain).filter(DomainSetting.setting == 'create_via_dyndns').first()
|
||||
if bool(int(ondemand_creation.value)) == True:
|
||||
record = Record(name=hostname,type='A',data=myip,status=True,ttl=3600)
|
||||
result = record.add(domain.name)
|
||||
if result['status'] == 'ok':
|
||||
history = History(msg='DynDNS update: created record %s in zone %s, it now represents %s' % (hostname,domain.name,myip), detail=str(result), created_by=current_user.username)
|
||||
history.add()
|
||||
return render_template('dyndns.html', response='good'), 200
|
||||
|
||||
history = History(msg="DynDNS update: attempted update of %s but it does not exist for this user" % hostname, created_by=current_user.username)
|
||||
history.add()
|
||||
return render_template('dyndns.html', response='nohost'), 200
|
||||
|
Loading…
Reference in New Issue
Block a user