Add required_if to AnsibleModule

There is a common pattern in modules where some parameters are required
only if another parameter is present AND set to a particular value. For
instance, if a cloud server state is "present" it's important to
indicate the image to be used, but if it's "absent", the image that was
used to launch it is not necessary. Provide a check that takes as an
input a list of 3-element tuples containing parameter to depend on, the
value it should be set to, and a list of parameters which are required
if the required parameter is set to the required value.
This commit is contained in:
Monty Taylor 2014-10-26 10:41:58 -07:00
parent 7cb489eca3
commit 61ae3c732f

View file

@ -247,7 +247,8 @@ class AnsibleModule(object):
def __init__(self, argument_spec, bypass_checks=False, no_log=False,
check_invalid_arguments=True, mutually_exclusive=None, required_together=None,
required_one_of=None, add_file_common_args=False, supports_check_mode=False):
required_one_of=None, add_file_common_args=False, supports_check_mode=False,
required_if=None):
'''
common code for quickly building an ansible module in Python
@ -295,6 +296,7 @@ class AnsibleModule(object):
self._check_argument_types()
self._check_required_together(required_together)
self._check_required_one_of(required_one_of)
self._check_required_if(required_if)
self._set_defaults(pre=False)
if not self.no_log:
@ -852,6 +854,20 @@ class AnsibleModule(object):
if len(missing) > 0:
self.fail_json(msg="missing required arguments: %s" % ",".join(missing))
def _check_required_if(self, spec):
''' ensure that parameters which conditionally required are present '''
if spec is None:
return
for (key, val, requirements) in spec:
missing = []
if key in self.params and self.params[key] == val:
for check in requirements:
count = self._count_terms(check)
if count == 0:
missing.append(check)
if len(missing) > 0:
self.fail_json(msg="%s is %s but the following are missing: %s" % (key, val, ','.join(missing))
def _check_argument_values(self):
''' ensure all arguments have the requested values, and there are no stray arguments '''
for (k,v) in self.argument_spec.iteritems():