From 6d0b0c1468c8c01c642e4182d2644901bc9e1bcb Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 16 Nov 2017 16:48:40 +0100 Subject: [PATCH] library: add provider specifiy pre-validation step of input Depending on the provider, we have additional restrictions on the input arguments. Validate them early. Without this, we will only fail later when we want to get the 'interface_name' of a parent or a master profile. Fail early. The major reason for this, is to expose this validation so that it can be used by unit tests, to check whether proceeding will lead to a known failure. --- library/network_connections.py | 41 +++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/library/network_connections.py b/library/network_connections.py index e89360f..f698440 100755 --- a/library/network_connections.py +++ b/library/network_connections.py @@ -48,6 +48,10 @@ class ValidationError(MyError): self.error_message = message self.name = name + @staticmethod + def from_connection(idx, message): + return ValidationError('connection[' + str(idx) + ']', message) + class Util: PY3 = (sys.version_info[0] == 3) @@ -442,7 +446,6 @@ class ArgUtil: c = ArgUtil.connection_find_by_name(name, connections, n_connections) if not c: raise MyError('invalid master/parent "%s"' % (name)) - assert c.get('nm.uuid', None) return c['nm.uuid'] @staticmethod @@ -926,6 +929,31 @@ class ArgValidator_ListConnections(ArgValidatorList): raise ValidationError(name + '[' + str(idx) + '].parent', 'references non-existing "parent" connection "%s"' % (connection['parent'])) return result + VALIDATE_ONE_MODE_NM = 'nm' + VALIDATE_ONE_MODE_INITSCRIPTS = 'initscripts' + + def validate_connection_one(self, mode, connections, idx): + connection = connections[idx] + if 'type' not in connection: + return + + if ( (connection['parent']) + and ( ( (mode == self.VALIDATE_ONE_MODE_INITSCRIPTS) + and (connection['type'] == 'vlan')) + or ( (connection['type'] == 'infiniband') + and (connection['infiniband_p_key'] not in [ None, -1 ])))): + try: + ArgUtil.connection_find_master(connection['parent'], connections, idx) + except MyError as e: + raise ValidationError.from_connection(idx, 'profile references a parent "%s" which has \'interface_name\' missing' % (connection['parent'])) + + if ( (connection['master']) + and (mode == self.VALIDATE_ONE_MODE_INITSCRIPTS)): + try: + ArgUtil.connection_find_master(connection['master'], connections, idx) + except MyError as e: + raise ValidationError.from_connection(idx, 'profile references a master "%s" which has \'interface_name\' missing' % (connection['master'])) + ############################################################################### class IfcfgUtil: @@ -1972,6 +2000,13 @@ class Cmd: AnsibleUtil.fail_json('unsupported provider %s' % (provider)) def run(self): + for idx, connection in enumerate(AnsibleUtil.connections): + try: + AnsibleUtil.ARGS_CONNECTIONS.validate_connection_one(self.validate_one_type, + AnsibleUtil.connections, + idx) + except ValidationError as e: + AnsibleUtil.log_fatal(idx, str(e)) self.run_prepare() while AnsibleUtil.check_mode_next() != CheckMode.DONE: for idx, connection in enumerate(AnsibleUtil.connections): @@ -2033,6 +2068,7 @@ class Cmd_nm(Cmd): def __init__(self): self._nmutil = None + self.validate_one_type = ArgValidator_ListConnections.VALIDATE_ONE_MODE_NM @property def nmutil(self): @@ -2222,6 +2258,9 @@ class Cmd_nm(Cmd): class Cmd_initscripts(Cmd): + def __init__(self): + self.validate_one_type = ArgValidator_ListConnections.VALIDATE_ONE_MODE_INITSCRIPTS + def check_name(self, idx, name = None): if name is None: name = AnsibleUtil.connections[idx]['name']