Merge pull request #761 from ngoduykhanh/record_rollback

Fix #752 - Rollback the removed record if apply operation failed
This commit is contained in:
Khanh Ngo 2020-10-11 13:01:26 +02:00 committed by GitHub
commit 3034630bc0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 57 additions and 36 deletions

View File

@ -278,6 +278,17 @@ class Record(object):
return new_rrsets, del_rrsets return new_rrsets, del_rrsets
def apply_rrsets(self, domain_name, rrsets):
headers = {'X-API-Key': self.PDNS_API_KEY}
jdata = utils.fetch_json(urljoin(
self.PDNS_STATS_URL, self.API_EXTENDED_URL +
'/servers/localhost/zones/{0}'.format(domain_name)),
headers=headers,
method='PATCH',
verify=Setting().get('verify_ssl_connections'),
data=rrsets)
return jdata
def apply(self, domain_name, submitted_records): def apply(self, domain_name, submitted_records):
""" """
Apply record changes to a domain. This function Apply record changes to a domain. This function
@ -301,44 +312,43 @@ class Record(object):
# Submit the changes to PDNS API # Submit the changes to PDNS API
try: try:
headers = {'X-API-Key': self.PDNS_API_KEY}
if del_rrsets["rrsets"]: if del_rrsets["rrsets"]:
jdata1 = utils.fetch_json(urljoin( result = self.apply_rrsets(domain_name, del_rrsets)
self.PDNS_STATS_URL, self.API_EXTENDED_URL + if 'error' in result.keys():
'/servers/localhost/zones/{0}'.format(domain_name)),
headers=headers,
method='PATCH',
verify=Setting().get('verify_ssl_connections'),
data=del_rrsets)
if 'error' in jdata1.keys():
current_app.logger.error( current_app.logger.error(
'Cannot apply record changes with deleting rrsets step. PDNS error: {}' 'Cannot apply record changes with deleting rrsets step. PDNS error: {}'
.format(jdata1['error'])) .format(result['error']))
print(jdata1['error'])
return { return {
'status': 'error', 'status': 'error',
'msg': jdata1['error'].replace("'", "") 'msg': result['error'].replace("'", "")
} }
if new_rrsets["rrsets"]: if new_rrsets["rrsets"]:
jdata2 = utils.fetch_json( result = self.apply_rrsets(domain_name, new_rrsets)
urljoin( if 'error' in result.keys():
self.PDNS_STATS_URL, self.API_EXTENDED_URL +
'/servers/localhost/zones/{0}'.format(domain_name)),
headers=headers,
timeout=int(Setting().get('pdns_api_timeout')),
method='PATCH',
verify=Setting().get('verify_ssl_connections'),
data=new_rrsets)
if 'error' in jdata2.keys():
current_app.logger.error( current_app.logger.error(
'Cannot apply record changes with adding rrsets step. PDNS error: {}' 'Cannot apply record changes with adding rrsets step. PDNS error: {}'
.format(jdata2['error'])) .format(result['error']))
return {
'status': 'error', # rollback - re-add the removed record if the adding operation is failed.
'msg': jdata2['error'].replace("'", "") if del_rrsets["rrsets"]:
} rollback_rrests = del_rrsets
for r in del_rrsets["rrsets"]:
r['changetype'] = 'REPLACE'
rollback = self.apply_rrsets(domain_name, rollback_rrests)
if 'error' in rollback.keys():
return dict(status='error',
msg='Failed to apply changes. Cannot rollback previous failed operation: {}'
.format(rollback['error'].replace("'", "")))
else:
return dict(status='error',
msg='Failed to apply changes. Rolled back previous failed operation: {}'
.format(result['error'].replace("'", "")))
else:
return {
'status': 'error',
'msg': result['error'].replace("'", "")
}
self.auto_ptr(domain_name, new_rrsets, del_rrsets) self.auto_ptr(domain_name, new_rrsets, del_rrsets)
self.update_db_serial(domain_name) self.update_db_serial(domain_name)

View File

@ -439,6 +439,15 @@ def record_apply(domain_name):
history.add() history.add()
return make_response(jsonify(result), 200) return make_response(jsonify(result), 200)
else: else:
history = History(
msg='Failed to apply record changes to domain {0}'.format(domain_name),
detail=str(
json.dumps({
"domain": domain_name,
"msg": result['msg'],
})),
created_by=current_user.username)
history.add()
return make_response(jsonify(result), 400) return make_response(jsonify(result), 400)
except Exception as e: except Exception as e:
current_app.logger.error( current_app.logger.error(

View File

@ -74,7 +74,7 @@
{% if record.is_allowed_edit() %} {% if record.is_allowed_edit() %}
<button type="button" class="btn btn-flat btn-warning button_edit">Edit&nbsp;<i class="fa fa-edit"></i></button> <button type="button" class="btn btn-flat btn-warning button_edit">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></button>
{% endif %} {% endif %}
</td> </td>
<td width="6%"> <td width="6%">
@ -243,7 +243,7 @@
// add new row // add new row
var default_type = records_allow_edit[0] var default_type = records_allow_edit[0]
var nRow = jQuery('#tbl_records').dataTable().fnAddData(['', default_type, 'Active', {{ ttl_options | tojson }}[0][0], '', '', '', '', '0']); var nRow = jQuery('#tbl_records').dataTable().fnAddData(['', default_type, 'Active', window.ttl_options[0][0], '', '', '', '', '0']);
editRow($("#tbl_records").DataTable(), nRow); editRow($("#tbl_records").DataTable(), nRow);
document.getElementById("edit-row-focus").focus(); document.getElementById("edit-row-focus").focus();
nEditing = nRow; nEditing = nRow;

View File

@ -113,9 +113,11 @@
<p><input type="checkbox" id="{{ domain.name }}" class="auto_ptr_toggle" <p><input type="checkbox" id="{{ domain.name }}" class="auto_ptr_toggle"
{% for setting in domain.settings %}{% if setting.setting=='auto_ptr' and setting.value=='True' %}checked{% endif %}{% endfor %} {% for setting in domain.settings %}{% if setting.setting=='auto_ptr' and setting.value=='True' %}checked{% endif %}{% endfor %}
{% if SETTING.get('auto_ptr') %}disabled="True" {% endif %}> {% if SETTING.get('auto_ptr') %}disabled="True" {% endif %}>
&nbsp;Allow automatic reverse pointer creation on record updates?{% if &nbsp;Allow automatic reverse pointer creation on record updates?
SETTING.get('auto_ptr') %}</br><code>Auto-ptr is enabled globally on the PDA {% if SETTING.get('auto_ptr') %}
system!</code>{% endif %}</p> <br/><code>Auto-ptr is enabled globally on the PDA system!</code>
{% endif %}
</p>
</div> </div>
</div> </div>
</div> </div>
@ -369,4 +371,4 @@
</div> </div>
<!-- /.modal-dialog --> <!-- /.modal-dialog -->
</div> </div>
{% endblock %} {% endblock %}

View File

@ -37,7 +37,7 @@
<h1>We&rsquo;ll be back soon!</h1> <h1>We&rsquo;ll be back soon!</h1>
<div> <div>
<p>Sorry for the inconvenience but we&rsquo;re performing some maintenance at the moment. Please contact the System <p>Sorry for the inconvenience but we&rsquo;re performing some maintenance at the moment. Please contact the System
Administrator if you need more information</a>, otherwise we&rsquo;ll be back online shortly!</p> Administrator if you need more information, otherwise we&rsquo;ll be back online shortly!</p>
<p>&mdash; Team</p> <p>&mdash; Team</p>
</div> </div>
</article> </article>