Validate SRV records have the correct name on the recordset
Change-Id: Ibaf48d0b540f6c72c061dec94c43213c6e724c0b Closes-Bug: #1441146
This commit is contained in:
parent
7170fe4cb9
commit
1e10782836
|
@ -352,7 +352,8 @@ class DesignateObject(object):
|
|||
|
||||
def __setattr__(self, name, value):
|
||||
"""Enforces all object attributes are private or well defined"""
|
||||
if name[0:5] == '_obj_' or name in self.FIELDS.keys():
|
||||
if name[0:5] == '_obj_' or name in self.FIELDS.keys() \
|
||||
or name == 'FIELDS':
|
||||
super(DesignateObject, self).__setattr__(name, value)
|
||||
|
||||
else:
|
||||
|
|
|
@ -117,6 +117,12 @@ class Record(base.DictObjectMixin, base.PersistentObjectMixin,
|
|||
},
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def get_recordset_schema_changes(cls):
|
||||
# This is to allow record types to override the validation on a
|
||||
# recordset
|
||||
return {}
|
||||
|
||||
|
||||
class RecordList(base.ListObjectMixin, base.DesignateObject):
|
||||
LIST_ITEM_TYPE = Record
|
||||
|
|
|
@ -12,14 +12,19 @@
|
|||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
import logging
|
||||
from copy import deepcopy
|
||||
|
||||
from designate import exceptions
|
||||
from designate import utils
|
||||
from designate.objects import base
|
||||
from designate.objects.validation_error import ValidationError
|
||||
from designate.objects.validation_error import ValidationErrorList
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RecordSet(base.DictObjectMixin, base.PersistentObjectMixin,
|
||||
base.DesignateObject):
|
||||
|
||||
|
@ -120,6 +125,15 @@ class RecordSet(base.DictObjectMixin, base.PersistentObjectMixin,
|
|||
record_list_cls = self.obj_cls_from_name('%sList' % self.type)
|
||||
record_cls = self.obj_cls_from_name(self.type)
|
||||
|
||||
# Get any rules that the record type imposes on the record
|
||||
changes = record_cls.get_recordset_schema_changes()
|
||||
old_fields = {}
|
||||
if changes:
|
||||
LOG.debug("Record %s is overriding the RecordSet schema with: %s" %
|
||||
(record_cls.obj_name(), changes))
|
||||
old_fields = deepcopy(self.FIELDS)
|
||||
self.FIELDS = utils.deep_dict_merge(self.FIELDS, changes)
|
||||
|
||||
errors = ValidationErrorList()
|
||||
error_indexes = []
|
||||
# Copy these for safekeeping
|
||||
|
@ -182,6 +196,9 @@ class RecordSet(base.DictObjectMixin, base.PersistentObjectMixin,
|
|||
raise exceptions.InvalidObject(
|
||||
"Provided object does not match "
|
||||
"schema", errors=errors, object=self)
|
||||
finally:
|
||||
if old_fields:
|
||||
self.FIELDS = old_fields
|
||||
# Send in the traditional Record objects to central / storage
|
||||
self.records = old_records
|
||||
|
||||
|
|
|
@ -56,6 +56,16 @@ class SRV(Record):
|
|||
}
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def get_recordset_schema_changes(cls):
|
||||
return {
|
||||
'name': {
|
||||
'schema': {
|
||||
'format': 'srv-hostname',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
def _to_string(self):
|
||||
return "%(priority)s %(weight)s %(target)s %(port)s" % self
|
||||
|
||||
|
|
|
@ -26,6 +26,9 @@ LOG = logging.getLogger(__name__)
|
|||
RE_DOMAINNAME = r'^(?!.{255,})(?:(?!\-)[A-Za-z0-9_\-]{1,63}(?<!\-)\.)+$'
|
||||
RE_HOSTNAME = r'^(?!.{255,})(?:(?:^\*|(?!\-)[A-Za-z0-9_\-]{1,63})(?<!\-)\.)+$'
|
||||
|
||||
RE_SRV_HOST_NAME = r'^(?:(?!\-)(?:\_[A-Za-z0-9_\-]{1,63}\.){2})(?!.{255,})' \
|
||||
r'(?:(?!\-)[A-Za-z0-9_\-]{1,63}(?<!\-)\.)+$'
|
||||
|
||||
# The TLD name will not end in a period.
|
||||
RE_TLDNAME = r'^(?!.{255,})(?:(?!\-)[A-Za-z0-9_\-]{1,63}(?<!\-))' \
|
||||
r'(?:\.(?:(?!\-)[A-Za-z0-9_\-]{1,63}(?<!\-)))*$'
|
||||
|
@ -106,6 +109,17 @@ def is_domainname(instance):
|
|||
return True
|
||||
|
||||
|
||||
@draft4_format_checker.checks("srv-hostname")
|
||||
def is_srv_hostname(instance):
|
||||
if not isinstance(instance, compat.str_types):
|
||||
return True
|
||||
|
||||
if not re.match(RE_SRV_HOST_NAME, instance):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@draft3_format_checker.checks("tld-name")
|
||||
@draft4_format_checker.checks("tldname")
|
||||
def is_tldname(instance):
|
||||
|
|
Loading…
Reference in New Issue