From 61ae3c732ff024a9102d5f423eb7fa0c69ae1c46 Mon Sep 17 00:00:00 2001 From: Monty Taylor Date: Sun, 26 Oct 2014 10:41:58 -0700 Subject: [PATCH] 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. --- lib/ansible/module_utils/basic.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/ansible/module_utils/basic.py b/lib/ansible/module_utils/basic.py index 8a4548dc16..779d8f4cde 100644 --- a/lib/ansible/module_utils/basic.py +++ b/lib/ansible/module_utils/basic.py @@ -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():