From 33c1666cc9fbc0716901cce3875ad6129e5f440f Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Fri, 8 Mar 2019 07:11:56 +0100 Subject: [PATCH] add cidr notation to domainnameoption if allow_ip is True (fixes #5) --- test/test_config_domain.py | 15 ++++++-- tiramisu/option/domainnameoption.py | 57 ++++++++++++++++------------- tiramisu/option/ipoption.py | 13 +++++-- 3 files changed, 52 insertions(+), 33 deletions(-) diff --git a/test/test_config_domain.py b/test/test_config_domain.py index 4de4438..d2e5d15 100644 --- a/test/test_config_domain.py +++ b/test/test_config_domain.py @@ -4,8 +4,7 @@ do_autopath() import warnings, sys from py.test import raises -from tiramisu import Config -from tiramisu.option import DomainnameOption, EmailOption, URLOption, OptionDescription +from tiramisu import Config, DomainnameOption, EmailOption, URLOption, OptionDescription from tiramisu.error import ValueWarning from tiramisu.i18n import _ from tiramisu.storage import list_sessions @@ -19,9 +18,11 @@ def test_domainname(): d = DomainnameOption('d', '') f = DomainnameOption('f', '', allow_without_dot=True) g = DomainnameOption('g', '', allow_ip=True) - od = OptionDescription('a', '', [d, f, g]) + h = DomainnameOption('h', '', allow_ip=True, cidr=True) + od = OptionDescription('a', '', [d, f, g, h]) cfg = Config(od) cfg.property.read_write() + # cfg.option('d').value.set('toto.com') raises(ValueError, "cfg.option('d').value.set('toto')") cfg.option('d').value.set('toto3.com') @@ -40,9 +41,17 @@ def test_domainname(): cfg.option('f').value.set('d.t') # raises(ValueError, "cfg.option('f').value.set('192.168.1.1')") + raises(ValueError, "cfg.option('f').value.set('192.168.1.0/24')") + # cfg.option('g').value.set('toto.com') cfg.option('g').value.set('192.168.1.0') cfg.option('g').value.set('192.168.1.29') + raises(ValueError, "cfg.option('g').value.set('192.168.1.0/24')") + # + cfg.option('h').value.set('toto.com') + raises(ValueError, "cfg.option('h').value.set('192.168.1.0')") + raises(ValueError, "cfg.option('h').value.set('192.168.1.29')") + cfg.option('h').value.set('192.168.1.0/24') def test_domainname_upper(): diff --git a/tiramisu/option/domainnameoption.py b/tiramisu/option/domainnameoption.py index e09f95a..487d3ed 100644 --- a/tiramisu/option/domainnameoption.py +++ b/tiramisu/option/domainnameoption.py @@ -19,15 +19,14 @@ # the whole pypy projet is under MIT licence # ____________________________________________________________ import re -from ipaddress import ip_address, IPv4Address - +from ipaddress import ip_address from ..setting import undefined, Undefined, OptionBag from ..i18n import _ from .option import Option -from .stroption import StrOption +from .ipoption import IPOption -class DomainnameOption(StrOption): +class DomainnameOption(IPOption): """represents the choice of a domain name netbios: for MS domain hostname: to identify the device @@ -44,16 +43,17 @@ class DomainnameOption(StrOption): default=None, default_multi=None, requires=None, - multi=False, + multi: bool=False, callback=None, callback_params=None, validator=None, validator_params=None, properties=None, - allow_ip=False, - type_='domainname', - warnings_only=False, - allow_without_dot=False): + allow_ip: bool=False, + cidr: bool=False, + type_: str='domainname', + warnings_only: bool=False, + allow_without_dot=False) -> None: if type_ not in ['netbios', 'hostname', 'domainname']: raise ValueError(_('unknown type_ {0} for hostname').format(type_)) @@ -73,25 +73,29 @@ class DomainnameOption(StrOption): else: regexp = r'((?!-)[a-z0-9-]{{1,{0}}})'.format(self._get_len(type_)) if allow_ip: - regexp = r'^(?:{0}|(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){{3}}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)))$'.format(regexp) + if not cidr: + regexp = r'^(?:{0}|(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){{3}}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)))$'.format(regexp) + else: + regexp = r'^(?:{0}|(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){{3}}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/[0-9][0-9]))$'.format(regexp) else: regexp = r'^{0}$'.format(regexp) extra['_domain_re'] = re.compile(regexp) extra['_has_upper'] = re.compile('[A-Z]') - super(DomainnameOption, self).__init__(name, - doc, - default=default, - default_multi=default_multi, - callback=callback, - callback_params=callback_params, - requires=requires, - multi=multi, - validator=validator, - validator_params=validator_params, - properties=properties, - warnings_only=warnings_only, - extra=extra) + super().__init__(name, + doc, + default=default, + default_multi=default_multi, + callback=callback, + callback_params=callback_params, + requires=requires, + multi=multi, + validator=validator, + validator_params=validator_params, + properties=properties, + warnings_only=warnings_only, + cidr=cidr, + _extra=extra) def _get_len(self, type_): if type_ == 'netbios': @@ -117,9 +121,10 @@ class DomainnameOption(StrOption): except ValueError: pass else: - if self.impl_get_extra('_allow_ip') is True: - return - raise ValueError(_('must not be an IP')) + if self.impl_get_extra('_allow_ip') is False: + raise ValueError(_('must not be an IP')) + # it's an IP so validate with IPOption + return super()._validate(value, option_bag, current_opt) part_name_length = self._get_len(self.impl_get_extra('_dom_type')) if self.impl_get_extra('_dom_type') == 'domainname': if not self.impl_get_extra('_allow_without_dot') and not "." in value: diff --git a/tiramisu/option/ipoption.py b/tiramisu/option/ipoption.py index 551ca91..4775493 100644 --- a/tiramisu/option/ipoption.py +++ b/tiramisu/option/ipoption.py @@ -50,10 +50,15 @@ class IPOption(StrOption): private_only=False, allow_reserved=False, warnings_only=False, - cidr=False): - extra = {'_private_only': private_only, - '_allow_reserved': allow_reserved, - '_cidr': cidr} + cidr=False, + _extra=None): + if _extra is None: + extra = {} + else: + extra = _extra + extra['_private_only'] = private_only + extra['_allow_reserved'] = allow_reserved + extra['_cidr'] = cidr super().__init__(name, doc, default=default,