Skip to content

Commit

Permalink
Ref #242 - Add RPSLObject support for overwriting new changed lines.
Browse files Browse the repository at this point in the history
  • Loading branch information
mxsasha committed Jul 8, 2019
1 parent e17d9ee commit fdb4767
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 0 deletions.
40 changes: 40 additions & 0 deletions irrd/rpsl/parser.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import datetime
import json
import re
from collections import OrderedDict, Counter
Expand Down Expand Up @@ -397,6 +398,45 @@ def _update_attribute_value(self, attribute, new_values):
self._object_data.insert(insert_idx, (attribute, new_value, []))
insert_idx += 1

def overwrite_date_new_changed_attributes(self, existing_obj=None) -> None:
"""
Overwrite the date in any newly added changed attributes per #242.
Which changed attributes are new is determined by comparing to existing_obj,
which should be another RPSLObject, or None if all changed lines
should be considered new.
"""
parsed_values_to_overwrite = set(self.parsed_data['changed']) - set(existing_obj.parsed_data['changed'])

new_object_data = []
overwritten_values_with_comment: List[Tuple[int, str]] = []
for idx, (attr_name, attr_value, continuation_chars) in enumerate(self._object_data):
if attr_name == 'changed':
attr_value_clean = attr_value.split('#')[0].strip()
if attr_value_clean in parsed_values_to_overwrite:
overwritten_values_with_comment.append((idx, attr_value))
continue
new_object_data.append((attr_name, attr_value, continuation_chars))
self._object_data = new_object_data

# As the value is already validated by RPSLChangedField,
# we can safely make assumptions on the format.
current_date = datetime.datetime.now().strftime('%Y%m%d')
for idx, value in overwritten_values_with_comment:
try:
content, comment = value.split('#')
content = content.strip()
comment = comment.strip()
except ValueError:
content = value.strip()
comment = ''
email = content.split(' ')[0] # Ignore existing date
if comment:
new_value = f'{email} {current_date} # {comment}'
else:
new_value = f'{email} {current_date}'
self._object_data.insert(idx, ('changed', new_value, []))
self.messages.info(f'Set date in changed line "{value}" to today.')

def __repr__(self):
source = self.parsed_data.get('source', '')
return f'{self.rpsl_object_class}/{self.pk()}/{source}'
Expand Down
35 changes: 35 additions & 0 deletions irrd/rpsl/tests/test_rpsl_objects.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import datetime

import pytest
from IPy import IP
from pytest import raises
Expand Down Expand Up @@ -478,3 +480,36 @@ def test_parse(self):
]
assert obj.references_strong_inbound() == set()
assert obj.render_rpsl_text() == rpsl_text


class TestOverwriteDateNewChangedAttributes:
expected_date = datetime.datetime.now().strftime('%Y%m%d')

# This applies to all objects identically - only one test needed
def test_changed_line_overwrite_with_date_and_comment(self):
new_rpsl_text = self._generate_old_new_object('changed: new1@example.com 19980101#comment')
assert 'changed: changed@example.com 20190701 # comment' in new_rpsl_text
assert f'changed: new1@example.com {self.expected_date} # comment' in new_rpsl_text

def test_changed_line_overwrite_without_comment(self):
new_rpsl_text = self._generate_old_new_object('changed: new1@example.com 19980101')
assert 'changed: changed@example.com 20190701 # comment' in new_rpsl_text
assert f'changed: new1@example.com {self.expected_date}' in new_rpsl_text

def test_changed_line_overwrite_without_date_with_comment(self):
new_rpsl_text = self._generate_old_new_object('changed: new1@example.com#comment')
assert 'changed: changed@example.com 20190701 # comment' in new_rpsl_text
assert f'changed: new1@example.com {self.expected_date} # comment' in new_rpsl_text

def _generate_old_new_object(self, new_changed_line):
rpsl_text = object_sample_mapping[RPSLRouteSet().rpsl_object_class]
obj_current = rpsl_object_from_text(rpsl_text, strict_validation=True)

lines = rpsl_text.splitlines()
lines.insert(4, new_changed_line)
rpsl_text = '\n'.join(lines)
obj_new = rpsl_object_from_text(rpsl_text, strict_validation=True)

obj_new.overwrite_date_new_changed_attributes(obj_current)
assert f'Set date in changed line' in obj_new.messages.infos()[1]
return obj_new.render_rpsl_text()

0 comments on commit fdb4767

Please sign in to comment.