From 057f50621e030ce1f47c630b4356f5723fba94a5 Mon Sep 17 00:00:00 2001 From: Terrence Cole Date: Thu, 13 Jul 2017 15:10:33 -0700 Subject: [PATCH] RackSpace does not escape ;. --- octodns/provider/rackspace.py | 48 +++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/octodns/provider/rackspace.py b/octodns/provider/rackspace.py index 8f80abf..be8bda5 100644 --- a/octodns/provider/rackspace.py +++ b/octodns/provider/rackspace.py @@ -7,6 +7,7 @@ from __future__ import absolute_import, division, print_function, \ from requests import HTTPError, Session, post from collections import defaultdict import logging +import string from ..record import Create, Record from .base import BaseProvider @@ -39,6 +40,16 @@ def add_quotes(s): return '"{}"'.format(s) +def escape_semicolon(s): + assert s + return string.replace(s, ';', '\;') + + +def unescape_semicolon(s): + assert s + return string.replace(s, '\;', ';') + + class RackspaceProvider(BaseProvider): SUPPORTS_GEO = False TIMEOUT = 5 @@ -162,15 +173,15 @@ class RackspaceProvider(BaseProvider): _data_for_CNAME = _data_for_single _data_for_PTR = _data_for_single - # def _data_for_quoted(self, rrset): - # return { - # 'type': rrset[0]['type'], - # 'values': [strip_quotes(r['data']) for r in rrset], - # 'ttl': rrset[0]['ttl'] - # } + def _data_for_textual(self, rrset): + return { + 'type': rrset[0]['type'], + 'values': [escape_semicolon(r['data']) for r in rrset], + 'ttl': rrset[0]['ttl'] + } - _data_for_SPF = _data_for_multiple - _data_for_TXT = _data_for_multiple + _data_for_SPF = _data_for_textual + _data_for_TXT = _data_for_textual def _data_for_MX(self, rrset): values = [] @@ -304,17 +315,16 @@ class RackspaceProvider(BaseProvider): _record_for_CNAME = _record_for_named _record_for_PTR = _record_for_named - # @staticmethod - # def _record_for_quoted(record, value): - # return { - # 'name': record.fqdn, - # 'type': record._type, - # 'data': add_quotes(value), - # 'ttl': max(record.ttl, 300), - # } - - _record_for_SPF = _record_for_single - _record_for_TXT = _record_for_single + @staticmethod + def _record_for_textual(record, value): + return { + 'name': record.fqdn, + 'type': record._type, + 'data': unescape_semicolon(value), + 'ttl': max(record.ttl, 300), + } + _record_for_SPF = _record_for_textual + _record_for_TXT = _record_for_textual @staticmethod def _record_for_MX(record, value):