Fix rrest typo in history detail

There is a misspelling of rrset throughout the history logic, which also
effects the json payload in the database. Code-wise this is a simple
search-and-replace, and the migration will fix the payloads.
This commit is contained in:
corubba 2022-05-19 00:53:35 +02:00
parent 1961581527
commit 0dfcdb6c3e
4 changed files with 100 additions and 53 deletions

View File

@ -0,0 +1,46 @@
"""Fix typo in history detail
Revision ID: 6ea7dc05f496
Revises: fbc7cf864b24
Create Date: 2022-05-10 10:16:58.784497
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '6ea7dc05f496'
down_revision = 'fbc7cf864b24'
branch_labels = None
depends_on = None
history_table = sa.sql.table('history',
sa.Column('detail', sa.Text),
)
def upgrade():
op.execute(
history_table.update()
.where(history_table.c.detail.like('%"add_rrests":%'))
.values({
'detail': sa.func.replace(
sa.func.replace(history_table.c.detail, '"add_rrests":', '"add_rrsets":'),
'"del_rrests":', '"del_rrsets":'
)
})
)
def downgrade():
op.execute(
history_table.update()
.where(history_table.c.detail.like('%"add_rrsets":%'))
.values({
'detail': sa.func.replace(
sa.func.replace(history_table.c.detail, '"add_rrsets":', '"add_rrests":'),
'"del_rrsets":', '"del_rrests":'
)
})
)

View File

@ -23,6 +23,7 @@ from ..models.domain_template_record import DomainTemplateRecord
from ..models.api_key import ApiKey from ..models.api_key import ApiKey
from ..models.base import db from ..models.base import db
from ..lib.errors import ApiKeyCreateFail
from ..lib.schema import ApiPlainKeySchema from ..lib.schema import ApiPlainKeySchema
apikey_plain_schema = ApiPlainKeySchema(many=True) apikey_plain_schema = ApiPlainKeySchema(many=True)
@ -43,10 +44,10 @@ change_type: "addition" or "deletion" or "status" for status change or "unchange
Note: A change in "content", is considered a deletion and recreation of the same record, Note: A change in "content", is considered a deletion and recreation of the same record,
holding the new content value. holding the new content value.
""" """
def get_record_changes(del_rrest, add_rrest): def get_record_changes(del_rrset, add_rrset):
changeSet = [] changeSet = []
delSet = del_rrest['records'] if 'records' in del_rrest else [] delSet = del_rrset['records'] if 'records' in del_rrset else []
addSet = add_rrest['records'] if 'records' in add_rrest else [] addSet = add_rrset['records'] if 'records' in add_rrset else []
for d in delSet: # get the deletions and status changes for d in delSet: # get the deletions and status changes
exists = False exists = False
for a in addSet: for a in addSet:
@ -86,44 +87,44 @@ def get_record_changes(del_rrest, add_rrest):
return changeSet return changeSet
# out_changes is a list of HistoryRecordEntry objects in which we will append the new changes # out_changes is a list of HistoryRecordEntry objects in which we will append the new changes
# a HistoryRecordEntry represents a pair of add_rrest and del_rrest # a HistoryRecordEntry represents a pair of add_rrset and del_rrset
def extract_changelogs_from_a_history_entry(out_changes, history_entry, change_num, record_name=None, record_type=None): def extract_changelogs_from_a_history_entry(out_changes, history_entry, change_num, record_name=None, record_type=None):
if history_entry.detail is None: if history_entry.detail is None:
return return
if "add_rrests" in history_entry.detail: if "add_rrsets" in history_entry.detail:
detail_dict = json.loads(history_entry.detail) detail_dict = json.loads(history_entry.detail)
else: # not a record entry else: # not a record entry
return return
add_rrests = detail_dict['add_rrests'] add_rrsets = detail_dict['add_rrsets']
del_rrests = detail_dict['del_rrests'] del_rrsets = detail_dict['del_rrsets']
for add_rrest in add_rrests: for add_rrset in add_rrsets:
exists = False exists = False
for del_rrest in del_rrests: for del_rrset in del_rrsets:
if del_rrest['name'] == add_rrest['name'] and del_rrest['type'] == add_rrest['type']: if del_rrset['name'] == add_rrset['name'] and del_rrset['type'] == add_rrset['type']:
exists = True exists = True
if change_num not in out_changes: if change_num not in out_changes:
out_changes[change_num] = [] out_changes[change_num] = []
out_changes[change_num].append(HistoryRecordEntry(history_entry, del_rrest, add_rrest, "*")) out_changes[change_num].append(HistoryRecordEntry(history_entry, del_rrset, add_rrset, "*"))
break break
if not exists: # this is a new record if not exists: # this is a new record
if change_num not in out_changes: if change_num not in out_changes:
out_changes[change_num] = [] out_changes[change_num] = []
out_changes[change_num].append(HistoryRecordEntry(history_entry, [], add_rrest, "+")) # (add_rrest, del_rrest, change_type) out_changes[change_num].append(HistoryRecordEntry(history_entry, [], add_rrset, "+")) # (add_rrset, del_rrset, change_type)
for del_rrest in del_rrests: for del_rrset in del_rrsets:
exists = False exists = False
for add_rrest in add_rrests: for add_rrset in add_rrsets:
if del_rrest['name'] == add_rrest['name'] and del_rrest['type'] == add_rrest['type']: if del_rrset['name'] == add_rrset['name'] and del_rrset['type'] == add_rrset['type']:
exists = True # no need to add in the out_changes set exists = True # no need to add in the out_changes set
break break
if not exists: # this is a deletion if not exists: # this is a deletion
if change_num not in out_changes: if change_num not in out_changes:
out_changes[change_num] = [] out_changes[change_num] = []
out_changes[change_num].append(HistoryRecordEntry(history_entry, del_rrest, [], "-")) out_changes[change_num].append(HistoryRecordEntry(history_entry, del_rrset, [], "-"))
# only used for changelog per record # only used for changelog per record
@ -133,9 +134,9 @@ def extract_changelogs_from_a_history_entry(out_changes, history_entry, change_n
else: else:
return return
for hre in changes_i: # for each history record entry in changes_i for hre in changes_i: # for each history record entry in changes_i
if 'type' in hre.add_rrest and hre.add_rrest['name'] == record_name and hre.add_rrest['type'] == record_type: if 'type' in hre.add_rrset and hre.add_rrset['name'] == record_name and hre.add_rrset['type'] == record_type:
continue continue
elif 'type' in hre.del_rrest and hre.del_rrest['name'] == record_name and hre.del_rrest['type'] == record_type: elif 'type' in hre.del_rrset and hre.del_rrset['name'] == record_name and hre.del_rrset['type'] == record_type:
continue continue
else: else:
out_changes[change_num].remove(hre) out_changes[change_num].remove(hre)
@ -144,42 +145,42 @@ def extract_changelogs_from_a_history_entry(out_changes, history_entry, change_n
# records with same (name,type) are considered as a single HistoryRecordEntry # records with same (name,type) are considered as a single HistoryRecordEntry
# history_entry is of type History - used to extract created_by and created_on # history_entry is of type History - used to extract created_by and created_on
# add_rrest is a dictionary of replace # add_rrset is a dictionary of replace
# del_rrest is a dictionary of remove # del_rrset is a dictionary of remove
class HistoryRecordEntry: class HistoryRecordEntry:
def __init__(self, history_entry, del_rrest, add_rrest, change_type): def __init__(self, history_entry, del_rrset, add_rrset, change_type):
# search the add_rrest index into the add_rrest set for the key (name, type) # search the add_rrset index into the add_rrset set for the key (name, type)
self.history_entry = history_entry self.history_entry = history_entry
self.add_rrest = add_rrest self.add_rrset = add_rrset
self.del_rrest = del_rrest self.del_rrset = del_rrset
self.change_type = change_type # "*": edit or unchanged, "+" new tuple(name,type), "-" deleted (name,type) tuple self.change_type = change_type # "*": edit or unchanged, "+" new tuple(name,type), "-" deleted (name,type) tuple
self.changed_fields = [] # contains a subset of : [ttl, name, type] self.changed_fields = [] # contains a subset of : [ttl, name, type]
self.changeSet = [] # all changes for the records of this add_rrest-del_rrest pair self.changeSet = [] # all changes for the records of this add_rrset-del_rrset pair
if change_type == "+": # addition if change_type == "+": # addition
self.changed_fields.append("name") self.changed_fields.append("name")
self.changed_fields.append("type") self.changed_fields.append("type")
self.changed_fields.append("ttl") self.changed_fields.append("ttl")
self.changeSet = get_record_changes(del_rrest, add_rrest) self.changeSet = get_record_changes(del_rrset, add_rrset)
elif change_type == "-": # removal elif change_type == "-": # removal
self.changed_fields.append("name") self.changed_fields.append("name")
self.changed_fields.append("type") self.changed_fields.append("type")
self.changed_fields.append("ttl") self.changed_fields.append("ttl")
self.changeSet = get_record_changes(del_rrest, add_rrest) self.changeSet = get_record_changes(del_rrset, add_rrset)
elif change_type == "*": # edit of unchanged elif change_type == "*": # edit of unchanged
if add_rrest['ttl'] != del_rrest['ttl']: if add_rrset['ttl'] != del_rrset['ttl']:
self.changed_fields.append("ttl") self.changed_fields.append("ttl")
self.changeSet = get_record_changes(del_rrest, add_rrest) self.changeSet = get_record_changes(del_rrset, add_rrset)
def toDict(self): def toDict(self):
return { return {
"add_rrest" : self.add_rrest, "add_rrset" : self.add_rrset,
"del_rrest" : self.del_rrest, "del_rrset" : self.del_rrset,
"changed_fields" : self.changed_fields, "changed_fields" : self.changed_fields,
"created_on" : self.history_entry.created_on, "created_on" : self.history_entry.created_on,
"created_by" : self.history_entry.created_by, "created_by" : self.history_entry.created_by,
@ -803,7 +804,7 @@ class DetailedHistory():
authenticator=detail_dict['authenticator'], authenticator=detail_dict['authenticator'],
ip_address=detail_dict['ip_address']) ip_address=detail_dict['ip_address'])
elif 'add_rrests' in detail_dict: # this is a domain record change elif 'add_rrsets' in detail_dict: # this is a domain record change
# changes_set = [] # changes_set = []
self.detailed_msg = "" self.detailed_msg = ""
# extract_changelogs_from_a_history_entry(changes_set, history, 0) # extract_changelogs_from_a_history_entry(changes_set, history, 0)
@ -902,7 +903,7 @@ def convert_histories(histories):
detailedHistories = [] detailedHistories = []
j = 0 j = 0
for i in range(len(histories)): for i in range(len(histories)):
if histories[i].detail and ('add_rrests' in histories[i].detail or 'del_rrests' in histories[i].detail): if histories[i].detail and ('add_rrsets' in histories[i].detail or 'del_rrsets' in histories[i].detail):
extract_changelogs_from_a_history_entry(changes_set, histories[i], j) extract_changelogs_from_a_history_entry(changes_set, histories[i], j)
if j in changes_set: if j in changes_set:
detailedHistories.append(DetailedHistory(histories[i], changes_set[j])) detailedHistories.append(DetailedHistory(histories[i], changes_set[j]))

View File

@ -63,7 +63,7 @@ def domain(domain_name):
# Query domain's rrsets from PowerDNS API # Query domain's rrsets from PowerDNS API
rrsets = Record().get_rrsets(domain.name) rrsets = Record().get_rrsets(domain.name)
current_app.logger.debug("Fetched rrests: \n{}".format(pretty_json(rrsets))) current_app.logger.debug("Fetched rrsets: \n{}".format(pretty_json(rrsets)))
# API server might be down, misconfigured # API server might be down, misconfigured
if not rrsets and domain.type != 'Slave': if not rrsets and domain.type != 'Slave':
@ -202,7 +202,7 @@ def changelog(domain_name):
# Query domain's rrsets from PowerDNS API # Query domain's rrsets from PowerDNS API
rrsets = Record().get_rrsets(domain.name) rrsets = Record().get_rrsets(domain.name)
current_app.logger.debug("Fetched rrests: \n{}".format(pretty_json(rrsets))) current_app.logger.debug("Fetched rrsets: \n{}".format(pretty_json(rrsets)))
# API server might be down, misconfigured # API server might be down, misconfigured
if not rrsets and domain.type != 'Slave': if not rrsets and domain.type != 'Slave':
@ -290,7 +290,7 @@ def record_changelog(domain_name, record_name, record_type):
abort(404) abort(404)
# Query domain's rrsets from PowerDNS API # Query domain's rrsets from PowerDNS API
rrsets = Record().get_rrsets(domain.name) rrsets = Record().get_rrsets(domain.name)
current_app.logger.debug("Fetched rrests: \n{}".format(pretty_json(rrsets))) current_app.logger.debug("Fetched rrsets: \n{}".format(pretty_json(rrsets)))
# API server might be down, misconfigured # API server might be down, misconfigured
if not rrsets and domain.type != 'Slave': if not rrsets and domain.type != 'Slave':
@ -328,9 +328,9 @@ def record_changelog(domain_name, record_name, record_type):
for change_num in changes_set_of_record: for change_num in changes_set_of_record:
changes_i = changes_set_of_record[change_num] changes_i = changes_set_of_record[change_num]
for hre in changes_i: # for each history record entry in changes_i for hre in changes_i: # for each history record entry in changes_i
if 'type' in hre.add_rrest and hre.add_rrest['name'] == record_name and hre.add_rrest['type'] == record_type: if 'type' in hre.add_rrset and hre.add_rrset['name'] == record_name and hre.add_rrset['type'] == record_type:
continue continue
elif 'type' in hre.del_rrest and hre.del_rrest['name'] == record_name and hre.del_rrest['type'] == record_type: elif 'type' in hre.del_rrset and hre.del_rrset['name'] == record_name and hre.del_rrset['type'] == record_type:
continue continue
else: else:
changes_set_of_record[change_num].remove(hre) changes_set_of_record[change_num].remove(hre)
@ -450,9 +450,9 @@ def add():
domain_name, domain_name,
'template': 'template':
template.name, template.name,
'add_rrests': 'add_rrsets':
result['data'][0]['rrsets'], result['data'][0]['rrsets'],
'del_rrests': 'del_rrsets':
result['data'][1]['rrsets'] result['data'][1]['rrsets']
}), }),
created_by=current_user.username, created_by=current_user.username,
@ -685,8 +685,8 @@ def record_apply(domain_name):
msg='Apply record changes to domain {0}'.format(pretty_domain_name(domain_name)), msg='Apply record changes to domain {0}'.format(pretty_domain_name(domain_name)),
detail = json.dumps({ detail = json.dumps({
'domain': domain_name, 'domain': domain_name,
'add_rrests': result['data'][0]['rrsets'], 'add_rrsets': result['data'][0]['rrsets'],
'del_rrests': result['data'][1]['rrsets'] 'del_rrsets': result['data'][1]['rrsets']
}), }),
created_by=current_user.username, created_by=current_user.username,
domain_id=domain.id) domain_id=domain.id)

View File

@ -7,28 +7,28 @@
<th colspan="3"> <th colspan="3">
{% if hist_rec_entry.change_type == "+" %} {% if hist_rec_entry.change_type == "+" %}
<span <span
style="background-color: lightgreen">{{hist_rec_entry.add_rrest['name']}} style="background-color: lightgreen">{{hist_rec_entry.add_rrset['name']}}
{{hist_rec_entry.add_rrest['type']}}</span> {{hist_rec_entry.add_rrset['type']}}</span>
{% elif hist_rec_entry.change_type == "-" %} {% elif hist_rec_entry.change_type == "-" %}
<s <s
style="text-decoration-color: rgba(194, 10,10, 0.6); text-decoration-thickness: 2px;"> style="text-decoration-color: rgba(194, 10,10, 0.6); text-decoration-thickness: 2px;">
{{hist_rec_entry.del_rrest['name']}} {{hist_rec_entry.del_rrset['name']}}
{{hist_rec_entry.del_rrest['type']}} {{hist_rec_entry.del_rrset['type']}}
</s> </s>
{% else %} {% else %}
{{hist_rec_entry.add_rrest['name']}} {{hist_rec_entry.add_rrset['name']}}
{{hist_rec_entry.add_rrest['type']}} {{hist_rec_entry.add_rrset['type']}}
{% endif %} {% endif %}
, TTL: , TTL:
{% if "ttl" in hist_rec_entry.changed_fields %} {% if "ttl" in hist_rec_entry.changed_fields %}
<s <s
style="text-decoration-color: rgba(194, 10,10, 0.6); text-decoration-thickness: 2px;"> style="text-decoration-color: rgba(194, 10,10, 0.6); text-decoration-thickness: 2px;">
{{hist_rec_entry.del_rrest['ttl']}}</s> {{hist_rec_entry.del_rrset['ttl']}}</s>
<span <span
style="background-color: lightgreen">{{hist_rec_entry.add_rrest['ttl']}}</span> style="background-color: lightgreen">{{hist_rec_entry.add_rrset['ttl']}}</span>
{% else %} {% else %}
{{hist_rec_entry.add_rrest['ttl']}} {{hist_rec_entry.add_rrset['ttl']}}
{% endif %} {% endif %}
</th> </th>
@ -120,7 +120,7 @@
</table> </table>
</td> </td>
<td> <td>
{% for comments in hist_rec_entry.add_rrest['comments'] %} {% for comments in hist_rec_entry.add_rrset['comments'] %}
{{comments['content'] }} {{comments['content'] }}
<br/> <br/>
{% endfor %} {% endfor %}
@ -130,4 +130,4 @@
</tbody> </tbody>
</table> </table>
{% endfor %} {% endfor %}
{%- endmacro %} {%- endmacro %}