mirror of
				https://github.com/github/octodns.git
				synced 2024-05-11 05:55:00 +00:00 
			
		
		
		
	Merge pull request #115 from github/long-txt-records
Implement "chunked" TXT/SPF value support for long values
This commit is contained in:
		| @@ -455,7 +455,7 @@ class DynProvider(BaseProvider): | ||||
|         return [{ | ||||
|             'txtdata': v, | ||||
|             'ttl': record.ttl, | ||||
|         } for v in record.values] | ||||
|         } for v in record.chunked_values] | ||||
|  | ||||
|     def _kwargs_for_SRV(self, record): | ||||
|         return [{ | ||||
|   | ||||
| @@ -114,8 +114,7 @@ class _Route53Record(object): | ||||
|                 for v in record.values] | ||||
|  | ||||
|     def _values_for_quoted(self, record): | ||||
|         return ['"{}"'.format(v.replace('"', '\\"')) | ||||
|                 for v in record.values] | ||||
|         return record.chunked_values | ||||
|  | ||||
|     _values_for_SPF = _values_for_quoted | ||||
|     _values_for_TXT = _values_for_quoted | ||||
|   | ||||
| @@ -704,8 +704,8 @@ class SshfpRecord(_ValuesMixin, Record): | ||||
| _unescaped_semicolon_re = re.compile(r'\w;') | ||||
|  | ||||
|  | ||||
| class SpfRecord(_ValuesMixin, Record): | ||||
|     _type = 'SPF' | ||||
| class _ChunkedValuesMixin(_ValuesMixin): | ||||
|     CHUNK_SIZE = 255 | ||||
|  | ||||
|     @classmethod | ||||
|     def _validate_value(cls, value): | ||||
| @@ -714,9 +714,29 @@ class SpfRecord(_ValuesMixin, Record): | ||||
|         return [] | ||||
|  | ||||
|     def _process_values(self, values): | ||||
|         ret = [] | ||||
|         for v in values: | ||||
|             if v and v[0] == '"': | ||||
|                 v = v[1:-1] | ||||
|             ret.append(v.replace('" "', '')) | ||||
|         return ret | ||||
|  | ||||
|     @property | ||||
|     def chunked_values(self): | ||||
|         values = [] | ||||
|         for v in self.values: | ||||
|             v = v.replace('"', '\\"') | ||||
|             vs = [v[i:i + self.CHUNK_SIZE] | ||||
|                   for i in range(0, len(v), self.CHUNK_SIZE)] | ||||
|             vs = '" "'.join(vs) | ||||
|             values.append('"{}"'.format(vs)) | ||||
|         return values | ||||
|  | ||||
|  | ||||
| class SpfRecord(_ChunkedValuesMixin, Record): | ||||
|     _type = 'SPF' | ||||
|  | ||||
|  | ||||
| class SrvValue(object): | ||||
|  | ||||
|     @classmethod | ||||
| @@ -797,14 +817,5 @@ class SrvRecord(_ValuesMixin, Record): | ||||
|         return [SrvValue(v) for v in values] | ||||
|  | ||||
|  | ||||
| class TxtRecord(_ValuesMixin, Record): | ||||
| class TxtRecord(_ChunkedValuesMixin, Record): | ||||
|     _type = 'TXT' | ||||
|  | ||||
|     @classmethod | ||||
|     def _validate_value(cls, value): | ||||
|         if _unescaped_semicolon_re.search(value): | ||||
|             return ['unescaped ;'] | ||||
|         return [] | ||||
|  | ||||
|     def _process_values(self, values): | ||||
|         return values | ||||
|   | ||||
| @@ -1490,3 +1490,63 @@ class TestRecordValidation(TestCase): | ||||
|                 'value': 'this has some; semi-colons\; in it', | ||||
|             }) | ||||
|         self.assertEquals(['unescaped ;'], ctx.exception.reasons) | ||||
|  | ||||
|     def test_TXT_long_value_chunking(self): | ||||
|         expected = '"Lorem ipsum dolor sit amet, consectetur adipiscing ' \ | ||||
|             'elit, sed do eiusmod tempor incididunt ut labore et dolore ' \ | ||||
|             'magna aliqua. Ut enim ad minim veniam, quis nostrud ' \ | ||||
|             'exercitation ullamco laboris nisi ut aliquip ex ea commodo ' \ | ||||
|             'consequat. Duis aute irure dolor i" "n reprehenderit in ' \ | ||||
|             'voluptate velit esse cillum dolore eu fugiat nulla pariatur. ' \ | ||||
|             'Excepteur sint occaecat cupidatat non proident, sunt in culpa ' \ | ||||
|             'qui officia deserunt mollit anim id est laborum."' | ||||
|  | ||||
|         long_value = 'Lorem ipsum dolor sit amet, consectetur adipiscing ' \ | ||||
|             'elit, sed do eiusmod tempor incididunt ut labore et dolore ' \ | ||||
|             'magna aliqua. Ut enim ad minim veniam, quis nostrud ' \ | ||||
|             'exercitation ullamco laboris nisi ut aliquip ex ea commodo ' \ | ||||
|             'consequat. Duis aute irure dolor in reprehenderit in ' \ | ||||
|             'voluptate velit esse cillum dolore eu fugiat nulla ' \ | ||||
|             'pariatur. Excepteur sint occaecat cupidatat non proident, ' \ | ||||
|             'sunt in culpa qui officia deserunt mollit anim id est ' \ | ||||
|             'laborum.' | ||||
|         # Single string | ||||
|         single = Record.new(self.zone, '', { | ||||
|             'type': 'TXT', | ||||
|             'ttl': 600, | ||||
|             'values': [ | ||||
|                 'hello world', | ||||
|                 long_value, | ||||
|                 'this has some\; semi-colons\; in it', | ||||
|             ] | ||||
|         }) | ||||
|         self.assertEquals(3, len(single.values)) | ||||
|         self.assertEquals(3, len(single.chunked_values)) | ||||
|         # Note we are checking that this normalizes the chunking, not that we | ||||
|         # get out what we put in. | ||||
|         self.assertEquals(expected, single.chunked_values[0]) | ||||
|  | ||||
|         long_split_value = '"Lorem ipsum dolor sit amet, consectetur ' \ | ||||
|             'adipiscing elit, sed do eiusmod tempor incididunt ut ' \ | ||||
|             'labore et dolore magna aliqua. Ut enim ad minim veniam, ' \ | ||||
|             'quis nostrud exercitation ullamco laboris nisi ut aliquip ' \ | ||||
|             'ex" " ea commodo consequat. Duis aute irure dolor in ' \ | ||||
|             'reprehenderit in voluptate velit esse cillum dolore eu ' \ | ||||
|             'fugiat nulla pariatur. Excepteur sint occaecat cupidatat ' \ | ||||
|             'non proident, sunt in culpa qui officia deserunt mollit ' \ | ||||
|             'anim id est laborum."' | ||||
|         # Chunked | ||||
|         chunked = Record.new(self.zone, '', { | ||||
|             'type': 'TXT', | ||||
|             'ttl': 600, | ||||
|             'values': [ | ||||
|                 '"hello world"', | ||||
|                 long_split_value, | ||||
|                 '"this has some\; semi-colons\; in it"', | ||||
|             ] | ||||
|         }) | ||||
|         self.assertEquals(expected, chunked.chunked_values[0]) | ||||
|         # should be single values, no quoting | ||||
|         self.assertEquals(single.values, chunked.values) | ||||
|         # should be chunked values, with quoting | ||||
|         self.assertEquals(single.chunked_values, chunked.chunked_values) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user