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.
This commit is contained in:
Thomas Haller 2017-11-16 16:48:40 +01:00
parent 55e2e43401
commit 6d0b0c1468

View file

@ -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']