add consistency in_network for IPOption

This new consistency can validate that an IPv4 is a specified (network/netmask) network
This commit is contained in:
Emmanuel Garette 2014-03-11 18:57:19 +01:00
parent f2154e2322
commit d7b04ebed0
4 changed files with 203 additions and 160 deletions

View file

@ -169,6 +169,29 @@ def test_consistency_network_netmask():
raises(ValueError, "c.a = '192.168.1.1'")
def test_consistency_ip_in_network():
a = NetworkOption('a', '')
b = NetmaskOption('b', '')
c = IPOption('c', '')
od = OptionDescription('od', '', [a, b, c])
c.impl_add_consistency('in_network', a, b)
cfg = Config(od)
cfg.a = '192.168.1.0'
cfg.b = '255.255.255.0'
cfg.c = '192.168.1.1'
raises(ValueError, "cfg.c = '192.168.2.1'")
def test_consistency_ip_in_network_len_error():
a = NetworkOption('a', '')
b = NetmaskOption('b', '')
c = IPOption('c', '')
od = OptionDescription('od', '', [a, b, c])
c.impl_add_consistency('in_network', a)
cfg = Config(od)
raises(ConfigError, "cfg.a = '192.168.2.0'")
def test_consistency_ip_netmask_network_error():
a = IPOption('a', '')
b = NetworkOption('b', '')

View file

@ -784,6 +784,18 @@ class IPOption(Option):
if self._private_only and not ip.iptype() == 'PRIVATE':
raise ValueError(_("invalid IP, must be in private class"))
def _cons_in_network(self, opts, vals):
if len(vals) != 3:
raise ConfigError(_('invalid len for vals'))
if None in vals:
return
ip, network, netmask = vals
if IP(ip) not in IP('{0}/{1}'.format(network, netmask)):
raise ValueError(_('invalid IP {0} ({1}) with network {2} '
'({3}) and netmask {4} ({5})').format(
ip, opts[0]._name, network,
opts[1]._name, netmask, opts[2]._name))
class PortOption(Option):
"""represents the choice of a port

View file

@ -2,7 +2,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Tiramisu\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-03-09 20:13+CET\n"
"POT-Creation-Date: 2014-03-11 18:51+CET\n"
"PO-Revision-Date: \n"
"Last-Translator: Emmanuel Garette <egarette@cadoles.com>\n"
"Language-Team: Tiramisu's team <egarette@cadoles.com>\n"
@ -203,187 +203,191 @@ msgstr "adresse IP invalide, ne doit pas être d'une classe reservée"
msgid "invalid IP, must be in private class"
msgstr "adresse IP invalide, doit être dans la classe privée"
#: tiramisu/option.py:823
#: tiramisu/option.py:789 tiramisu/option.py:955
msgid "invalid len for vals"
msgstr "longueur invalide pour vals"
#: tiramisu/option.py:794
msgid "invalid IP {0} ({1}) with network {2} ({3}) and netmask {4} ({5})"
msgstr "IP invalide {0} ({1}) avec le réseau {2} ({3}) et le masque {4} ({5})"
#: tiramisu/option.py:835
msgid "inconsistency in allowed range"
msgstr "inconsistence dans la plage autorisée"
#: tiramisu/option.py:828
#: tiramisu/option.py:840
msgid "max value is empty"
msgstr "la valeur maximum est vide"
#: tiramisu/option.py:845
#: tiramisu/option.py:857
msgid "invalid port, range must have two values only"
msgstr "port invalide, une plage doit avoir deux valeurs seulement"
#: tiramisu/option.py:848
#: tiramisu/option.py:860
msgid "invalid port, first port in range must be smaller than the second one"
msgstr ""
"port invalide, le premier port d'une plage doit être plus petit que le second"
#: tiramisu/option.py:857
#: tiramisu/option.py:869
msgid "invalid port"
msgstr "port invalide"
#: tiramisu/option.py:859
#: tiramisu/option.py:871
msgid "invalid port, must be an between {0} and {1}"
msgstr "port invalide, port doit être entre {0} et {1}"
#: tiramisu/option.py:873
#: tiramisu/option.py:885
msgid "invalid network address"
msgstr "adresse réseau invalide"
#: tiramisu/option.py:878
#: tiramisu/option.py:890
msgid "invalid network address, must not be in reserved class"
msgstr "adresse réseau invalide, ne doit pas être dans la classe reservée"
#: tiramisu/option.py:890
#: tiramisu/option.py:902
msgid "invalid netmask address"
msgstr "masque de sous-réseau invalide"
#: tiramisu/option.py:906
#: tiramisu/option.py:918
msgid "invalid len for opts"
msgstr "longueur invalide pour opts"
#: tiramisu/option.py:920
#: tiramisu/option.py:932
msgid "invalid IP {0} ({1}) with netmask {2}, this IP is a network"
msgstr "IP invalide {0} ({1}) avec masque {2}, cette IP est un réseau"
#: tiramisu/option.py:925
#: tiramisu/option.py:937
msgid "invalid network {0} ({1}) with netmask {2}"
msgstr "réseau invalide {0} ({1}) avec masque {2}"
#: tiramisu/option.py:939
#: tiramisu/option.py:951
msgid "invalid broadcast address"
msgstr "adresse de broadcast invalide"
#: tiramisu/option.py:943
msgid "invalid len for vals"
msgstr "longueur invalide pour vals"
#: tiramisu/option.py:948
#: tiramisu/option.py:960
msgid ""
"invalid broadcast {0} ({1}) with network {2} ({3}) and netmask {4} ({5})"
msgstr ""
"Broadcast invalide {0} ({1}) avec le réseau {2} ({3}) et le masque {4} ({5})"
#: tiramisu/option.py:970
#: tiramisu/option.py:982
msgid "unknown type_ {0} for hostname"
msgstr "type_ inconnu {0} pour le nom d'hôte"
#: tiramisu/option.py:973
#: tiramisu/option.py:985
msgid "allow_ip must be a boolean"
msgstr "allow_ip doit être un booléen"
#: tiramisu/option.py:975
#: tiramisu/option.py:987
msgid "allow_without_dot must be a boolean"
msgstr "allow_without_dot doit être un booléen"
#: tiramisu/option.py:1019
#: tiramisu/option.py:1031
msgid "invalid domainname, must have dot"
msgstr "nom de domaine invalide, doit avoir un point"
#: tiramisu/option.py:1021
#: tiramisu/option.py:1033
msgid "invalid domainname's length (max 255)"
msgstr "longueur du nom de domaine invalide (maximum {1})"
#: tiramisu/option.py:1023
#: tiramisu/option.py:1035
msgid "invalid domainname's length (min 2)"
msgstr "longueur du nom de domaine invalide (minimum 2)"
#: tiramisu/option.py:1025
#: tiramisu/option.py:1037
msgid "invalid domainname"
msgstr "nom de domaine invalide"
#: tiramisu/option.py:1038
#: tiramisu/option.py:1050
msgid "invalid email address, should contains one @"
msgstr "adresse email invalide, devrait contenir un @"
#: tiramisu/option.py:1041
#: tiramisu/option.py:1053
msgid "invalid username in email address"
msgstr "nom d'utilisateur invalide dans une adresse email"
#: tiramisu/option.py:1054
#: tiramisu/option.py:1066
msgid "invalid url, should start with http:// or https://"
msgstr "URL invalide, devrait démarré avec http:// ou https://"
#: tiramisu/option.py:1073
#: tiramisu/option.py:1085
msgid "invalid url, port must be an between 0 and 65536"
msgstr "URL invalide, port doit être entre 0 et 65536"
#: tiramisu/option.py:1079
#: tiramisu/option.py:1091
msgid "invalid url, should ends with filename"
msgstr "URL invalide, devrait finir avec un nom de fichier"
#: tiramisu/option.py:1091
#: tiramisu/option.py:1103
msgid "invalid username"
msgstr "utilisateur invalide"
#: tiramisu/option.py:1102
#: tiramisu/option.py:1114
msgid "invalid filename"
msgstr "nom de fichier invalide"
#: tiramisu/option.py:1129
#: tiramisu/option.py:1141
msgid "duplicate option name: {0}"
msgstr "nom de l'option dupliqué : {0}"
#: tiramisu/option.py:1147
#: tiramisu/option.py:1159
msgid "unknown Option {0} in OptionDescription {1}"
msgstr "Option {0} inconnue pour l'OptionDescription {1}"
#: tiramisu/option.py:1198
#: tiramisu/option.py:1210
msgid "duplicate option: {0}"
msgstr "option dupliquée : {0}"
#: tiramisu/option.py:1228
#: tiramisu/option.py:1240
msgid "consistency with option {0} which is not in Config"
msgstr "consistency avec l'option {0} qui n'est pas dans une Config"
#: tiramisu/option.py:1236
#: tiramisu/option.py:1248
msgid "no option for path {0}"
msgstr "pas d'option pour le chemin {0}"
#: tiramisu/option.py:1242
#: tiramisu/option.py:1254
msgid "no option {0} found"
msgstr "pas d'option {0} trouvée"
#: tiramisu/option.py:1252
#: tiramisu/option.py:1264
msgid "cannot change group_type if already set (old {0}, new {1})"
msgstr "ne peut changer group_type si déjà spécifié (ancien {0}, nouveau {1})"
#: tiramisu/option.py:1264
#: tiramisu/option.py:1276
msgid "master group {0} shall not have a subgroup"
msgstr "groupe maître {0} ne doit pas avoir de sous-groupe"
#: tiramisu/option.py:1267
#: tiramisu/option.py:1279
msgid "master group {0} shall not have a symlinkoption"
msgstr "groupe maître {0} ne doit pas avoir de symlinkoption"
#: tiramisu/option.py:1270
#: tiramisu/option.py:1282
msgid "not allowed option {0} in group {1}: this option is not a multi"
msgstr ""
"option non autorisée {0} dans le groupe {1} : cette option n'est pas une "
"multi"
#: tiramisu/option.py:1280
#: tiramisu/option.py:1292
msgid "master group with wrong master name for {0}"
msgstr "le groupe maître avec un nom de maître érroné pour {0}"
#: tiramisu/option.py:1288
#: tiramisu/option.py:1300
msgid "callback of master's option shall not refered a slave's ones"
msgstr ""
"callback d'une variable maitre ne devrait pas référencer des variables "
"esclaves"
#: tiramisu/option.py:1296
#: tiramisu/option.py:1308
msgid "group_type: {0} not allowed"
msgstr "group_type : {0} non autorisé"
#: tiramisu/option.py:1385
#: tiramisu/option.py:1397
msgid "malformed requirements type for option: {0}, must be a dict"
msgstr ""
"type requirements malformé pour l'option : {0}, doit être un dictionnaire"
#: tiramisu/option.py:1402
#: tiramisu/option.py:1414
msgid ""
"malformed requirements for option: {0} require must have option, expected "
"and action keys"
@ -391,66 +395,66 @@ msgstr ""
"requirements malformé pour l'option : {0} l'exigence doit avoir les clefs "
"option, expected et action"
#: tiramisu/option.py:1407
#: tiramisu/option.py:1419
msgid "malformed requirements for option: {0} inverse must be boolean"
msgstr ""
"requirements mal formés pour l'option : {0} inverse doit être un booléen"
#: tiramisu/option.py:1411
#: tiramisu/option.py:1423
msgid "malformed requirements for option: {0} transitive must be boolean"
msgstr ""
"requirements mal formés pour l'option : {0} transitive doit être booléen"
#: tiramisu/option.py:1415
#: tiramisu/option.py:1427
msgid "malformed requirements for option: {0} same_action must be boolean"
msgstr ""
"requirements mal formés pour l'option : {0} same_action doit être un booléen"
#: tiramisu/option.py:1419
#: tiramisu/option.py:1431
msgid "malformed requirements must be an option in option {0}"
msgstr "requirements mal formés doit être une option dans l'option {0}"
#: tiramisu/option.py:1422
#: tiramisu/option.py:1434
msgid "malformed requirements option {0} should not be a multi"
msgstr "requirements mal formés l'option {0} ne doit pas être une multi"
#: tiramisu/option.py:1428
#: tiramisu/option.py:1440
msgid ""
"malformed requirements second argument must be valid for option {0}: {1}"
msgstr ""
"requirements mal formés deuxième argument doit être valide pour l'option "
"{0} : {1}"
#: tiramisu/option.py:1433
#: tiramisu/option.py:1445
msgid "inconsistency in action types for option: {0} action: {1}"
msgstr "incohérence dans les types action pour l'option : {0} action {1}"
#: tiramisu/option.py:1458
#: tiramisu/option.py:1470
msgid "{0} should be a function"
msgstr "{0} doit être une fonction"
#: tiramisu/option.py:1461
#: tiramisu/option.py:1473
msgid "{0}_params should be a dict"
msgstr "{0}_params devrait être un dict"
#: tiramisu/option.py:1464
#: tiramisu/option.py:1476
msgid "{0}_params with key {1} should not have length different to 1"
msgstr ""
"{0}_params avec la clef {1} devrait ne pas avoir une longueur différent de 1"
#: tiramisu/option.py:1468
#: tiramisu/option.py:1480
msgid "{0}_params should be tuple for key \"{1}\""
msgstr "{0}_params devrait être un tuple pour la clef \"{1}\""
#: tiramisu/option.py:1474
#: tiramisu/option.py:1486
msgid "validator not support tuple"
msgstr "validator n'accepte pas de tuple"
#: tiramisu/option.py:1477
#: tiramisu/option.py:1489
msgid "{0}_params should have an option not a {0} for first argument"
msgstr "{0}_params devrait avoir une option pas un {0} pour premier argument"
#: tiramisu/option.py:1481
#: tiramisu/option.py:1493
msgid "{0}_params should have a boolean not a {0} for second argument"
msgstr "{0}_params devrait avoir un boolean pas un {0} pour second argument"

View file

@ -5,7 +5,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2014-03-09 20:13+CET\n"
"POT-Creation-Date: 2014-03-11 18:51+CET\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -192,235 +192,239 @@ msgstr ""
msgid "invalid IP, must be in private class"
msgstr ""
#: tiramisu/option.py:823
msgid "inconsistency in allowed range"
msgstr ""
#: tiramisu/option.py:828
msgid "max value is empty"
msgstr ""
#: tiramisu/option.py:845
msgid "invalid port, range must have two values only"
msgstr ""
#: tiramisu/option.py:848
msgid "invalid port, first port in range must be smaller than the second one"
msgstr ""
#: tiramisu/option.py:857
msgid "invalid port"
msgstr ""
#: tiramisu/option.py:859
msgid "invalid port, must be an between {0} and {1}"
msgstr ""
#: tiramisu/option.py:873
msgid "invalid network address"
msgstr ""
#: tiramisu/option.py:878
msgid "invalid network address, must not be in reserved class"
msgstr ""
#: tiramisu/option.py:890
msgid "invalid netmask address"
msgstr ""
#: tiramisu/option.py:906
msgid "invalid len for opts"
msgstr ""
#: tiramisu/option.py:920
msgid "invalid IP {0} ({1}) with netmask {2}, this IP is a network"
msgstr ""
#: tiramisu/option.py:925
msgid "invalid network {0} ({1}) with netmask {2}"
msgstr ""
#: tiramisu/option.py:939
msgid "invalid broadcast address"
msgstr ""
#: tiramisu/option.py:943
#: tiramisu/option.py:789 tiramisu/option.py:955
msgid "invalid len for vals"
msgstr ""
#: tiramisu/option.py:948
#: tiramisu/option.py:794
msgid "invalid IP {0} ({1}) with network {2} ({3}) and netmask {4} ({5})"
msgstr ""
#: tiramisu/option.py:835
msgid "inconsistency in allowed range"
msgstr ""
#: tiramisu/option.py:840
msgid "max value is empty"
msgstr ""
#: tiramisu/option.py:857
msgid "invalid port, range must have two values only"
msgstr ""
#: tiramisu/option.py:860
msgid "invalid port, first port in range must be smaller than the second one"
msgstr ""
#: tiramisu/option.py:869
msgid "invalid port"
msgstr ""
#: tiramisu/option.py:871
msgid "invalid port, must be an between {0} and {1}"
msgstr ""
#: tiramisu/option.py:885
msgid "invalid network address"
msgstr ""
#: tiramisu/option.py:890
msgid "invalid network address, must not be in reserved class"
msgstr ""
#: tiramisu/option.py:902
msgid "invalid netmask address"
msgstr ""
#: tiramisu/option.py:918
msgid "invalid len for opts"
msgstr ""
#: tiramisu/option.py:932
msgid "invalid IP {0} ({1}) with netmask {2}, this IP is a network"
msgstr ""
#: tiramisu/option.py:937
msgid "invalid network {0} ({1}) with netmask {2}"
msgstr ""
#: tiramisu/option.py:951
msgid "invalid broadcast address"
msgstr ""
#: tiramisu/option.py:960
msgid "invalid broadcast {0} ({1}) with network {2} ({3}) and netmask {4} ({5})"
msgstr ""
#: tiramisu/option.py:970
#: tiramisu/option.py:982
msgid "unknown type_ {0} for hostname"
msgstr ""
#: tiramisu/option.py:973
#: tiramisu/option.py:985
msgid "allow_ip must be a boolean"
msgstr ""
#: tiramisu/option.py:975
#: tiramisu/option.py:987
msgid "allow_without_dot must be a boolean"
msgstr ""
#: tiramisu/option.py:1019
#: tiramisu/option.py:1031
msgid "invalid domainname, must have dot"
msgstr ""
#: tiramisu/option.py:1021
#: tiramisu/option.py:1033
msgid "invalid domainname's length (max 255)"
msgstr ""
#: tiramisu/option.py:1023
#: tiramisu/option.py:1035
msgid "invalid domainname's length (min 2)"
msgstr ""
#: tiramisu/option.py:1025
#: tiramisu/option.py:1037
msgid "invalid domainname"
msgstr ""
#: tiramisu/option.py:1038
#: tiramisu/option.py:1050
msgid "invalid email address, should contains one @"
msgstr ""
#: tiramisu/option.py:1041
#: tiramisu/option.py:1053
msgid "invalid username in email address"
msgstr ""
#: tiramisu/option.py:1054
#: tiramisu/option.py:1066
msgid "invalid url, should start with http:// or https://"
msgstr ""
#: tiramisu/option.py:1073
#: tiramisu/option.py:1085
msgid "invalid url, port must be an between 0 and 65536"
msgstr ""
#: tiramisu/option.py:1079
#: tiramisu/option.py:1091
msgid "invalid url, should ends with filename"
msgstr ""
#: tiramisu/option.py:1091
#: tiramisu/option.py:1103
msgid "invalid username"
msgstr ""
#: tiramisu/option.py:1102
#: tiramisu/option.py:1114
msgid "invalid filename"
msgstr ""
#: tiramisu/option.py:1129
#: tiramisu/option.py:1141
msgid "duplicate option name: {0}"
msgstr ""
#: tiramisu/option.py:1147
#: tiramisu/option.py:1159
msgid "unknown Option {0} in OptionDescription {1}"
msgstr ""
#: tiramisu/option.py:1198
#: tiramisu/option.py:1210
msgid "duplicate option: {0}"
msgstr ""
#: tiramisu/option.py:1228
#: tiramisu/option.py:1240
msgid "consistency with option {0} which is not in Config"
msgstr ""
#: tiramisu/option.py:1236
#: tiramisu/option.py:1248
msgid "no option for path {0}"
msgstr ""
#: tiramisu/option.py:1242
#: tiramisu/option.py:1254
msgid "no option {0} found"
msgstr ""
#: tiramisu/option.py:1252
#: tiramisu/option.py:1264
msgid "cannot change group_type if already set (old {0}, new {1})"
msgstr ""
#: tiramisu/option.py:1264
#: tiramisu/option.py:1276
msgid "master group {0} shall not have a subgroup"
msgstr ""
#: tiramisu/option.py:1267
#: tiramisu/option.py:1279
msgid "master group {0} shall not have a symlinkoption"
msgstr ""
#: tiramisu/option.py:1270
#: tiramisu/option.py:1282
msgid "not allowed option {0} in group {1}: this option is not a multi"
msgstr ""
#: tiramisu/option.py:1280
#: tiramisu/option.py:1292
msgid "master group with wrong master name for {0}"
msgstr ""
#: tiramisu/option.py:1288
#: tiramisu/option.py:1300
msgid "callback of master's option shall not refered a slave's ones"
msgstr ""
#: tiramisu/option.py:1296
#: tiramisu/option.py:1308
msgid "group_type: {0} not allowed"
msgstr ""
#: tiramisu/option.py:1385
#: tiramisu/option.py:1397
msgid "malformed requirements type for option: {0}, must be a dict"
msgstr ""
#: tiramisu/option.py:1402
#: tiramisu/option.py:1414
msgid "malformed requirements for option: {0} require must have option, expected and action keys"
msgstr ""
#: tiramisu/option.py:1407
#: tiramisu/option.py:1419
msgid "malformed requirements for option: {0} inverse must be boolean"
msgstr ""
#: tiramisu/option.py:1411
#: tiramisu/option.py:1423
msgid "malformed requirements for option: {0} transitive must be boolean"
msgstr ""
#: tiramisu/option.py:1415
#: tiramisu/option.py:1427
msgid "malformed requirements for option: {0} same_action must be boolean"
msgstr ""
#: tiramisu/option.py:1419
#: tiramisu/option.py:1431
msgid "malformed requirements must be an option in option {0}"
msgstr ""
#: tiramisu/option.py:1422
#: tiramisu/option.py:1434
msgid "malformed requirements option {0} should not be a multi"
msgstr ""
#: tiramisu/option.py:1428
#: tiramisu/option.py:1440
msgid "malformed requirements second argument must be valid for option {0}: {1}"
msgstr ""
#: tiramisu/option.py:1433
#: tiramisu/option.py:1445
msgid "inconsistency in action types for option: {0} action: {1}"
msgstr ""
#: tiramisu/option.py:1458
#: tiramisu/option.py:1470
msgid "{0} should be a function"
msgstr ""
#: tiramisu/option.py:1461
#: tiramisu/option.py:1473
msgid "{0}_params should be a dict"
msgstr ""
#: tiramisu/option.py:1464
#: tiramisu/option.py:1476
msgid "{0}_params with key {1} should not have length different to 1"
msgstr ""
#: tiramisu/option.py:1468
#: tiramisu/option.py:1480
msgid "{0}_params should be tuple for key \"{1}\""
msgstr ""
#: tiramisu/option.py:1474
#: tiramisu/option.py:1486
msgid "validator not support tuple"
msgstr ""
#: tiramisu/option.py:1477
#: tiramisu/option.py:1489
msgid "{0}_params should have an option not a {0} for first argument"
msgstr ""
#: tiramisu/option.py:1481
#: tiramisu/option.py:1493
msgid "{0}_params should have a boolean not a {0} for second argument"
msgstr ""