add cidr notation to domainnameoption if allow_ip is True (fixes #5)

This commit is contained in:
Emmanuel Garette 2019-03-08 07:11:56 +01:00
parent 2a6df8c8d8
commit 33c1666cc9
3 changed files with 52 additions and 33 deletions

View File

@ -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():

View File

@ -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,13 +73,16 @@ class DomainnameOption(StrOption):
else:
regexp = r'((?!-)[a-z0-9-]{{1,{0}}})'.format(self._get_len(type_))
if allow_ip:
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,
super().__init__(name,
doc,
default=default,
default_multi=default_multi,
@ -91,7 +94,8 @@ class DomainnameOption(StrOption):
validator_params=validator_params,
properties=properties,
warnings_only=warnings_only,
extra=extra)
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
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:

View File

@ -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,