mirror of https://github.com/ansible/ansible.git
Merge 3402dade1b into 869088b959
commit
2cdf1f22e7
@ -0,0 +1,64 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright: (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
DOCUMENTATION = r'''
|
||||
---
|
||||
module: set_vars
|
||||
short_description: set a variable to a value at a given scope
|
||||
description:
|
||||
- This module allows setting variables in the current ansible run at different scopesA
|
||||
- If a variable already exists it will be overriden or merged depending on 'hash behaviour'
|
||||
otherwise it will be created
|
||||
author: Ansible Project
|
||||
options:
|
||||
defs:
|
||||
description:
|
||||
- A list of dictionaries that represent a variable definition
|
||||
type: list
|
||||
required: true
|
||||
scope:
|
||||
required: false
|
||||
choices: ['host', 'host_fact', 'extra', 'play']
|
||||
description:
|
||||
- scope to which variables apply to, this sets the default for every definition but each one can override it
|
||||
type: string
|
||||
default: 'host'
|
||||
version_added: "2.12"
|
||||
'''
|
||||
|
||||
EXAMPLES = r'''
|
||||
- name: create/update an extra var
|
||||
set_vars:
|
||||
scope: extra
|
||||
defs:
|
||||
- name: packages_to_install
|
||||
value:
|
||||
- apache
|
||||
- nginx
|
||||
- haproxy
|
||||
- pound
|
||||
|
||||
- name: set a host fact (not the same as set_facts + cacheable=true, only 1 var is created)
|
||||
set_vars:
|
||||
defs:
|
||||
- name: pretty
|
||||
value: no
|
||||
scope: host_fact
|
||||
|
||||
- name: set a host variable (higher priority than facts), this is equivalent of set_fact + cacheable=false
|
||||
set_vars:
|
||||
defs:
|
||||
- name: presents
|
||||
value: all
|
||||
scope: host
|
||||
'''
|
||||
|
||||
RETURNS = r'''
|
||||
# should i return list of var names + scope set?
|
||||
'''
|
||||
@ -0,0 +1,85 @@
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
from ansible import constants as C
|
||||
from ansible.errors import AnsibleActionFail
|
||||
from ansible.module_utils.common._collections_compat import Mapping, Sequence
|
||||
from ansible.module_utils.six import string_types
|
||||
from ansible.plugins.action import ActionBase
|
||||
from ansible.utils.vars import isidentifier, combine_vars
|
||||
|
||||
|
||||
class ActionModule(ActionBase):
|
||||
|
||||
TRANSFERS_FILES = False
|
||||
_VALID_VARS_DEF = frozenset(('scope', 'name', 'value'))
|
||||
_VALID_ARGS = frozenset(('scope', 'defs'))
|
||||
|
||||
def _extract_validated_var_definition(self, var_def, global_scope):
|
||||
|
||||
if not isinstance(var_def, Mapping):
|
||||
raise AnsibleActionFail("The variable definition should be a dictionary, but got a %s" % type(var_def))
|
||||
|
||||
try:
|
||||
name = var_def.pop('name')
|
||||
except KeyError:
|
||||
raise AnsibleActionFail("The variable definition requires a 'name' entry")
|
||||
|
||||
if not isidentifier(name):
|
||||
raise AnsibleActionFail("The variable name '%s' is not valid. Variables must start with a letter or underscore character, and contain only "
|
||||
"letters, numbers and underscores." % name)
|
||||
try:
|
||||
value = var_def.pop('value')
|
||||
except KeyError:
|
||||
raise AnsibleActionFail("The variable definition requires a 'value' entry")
|
||||
|
||||
scope = var_def.pop('scope', global_scope)
|
||||
if not isinstance(scope, string_types):
|
||||
raise AnsibleActionFail("The 'scope' option for '%s' should be a string, but got a %s" % (name, type(scope)))
|
||||
elif scope not in C.VALID_VAR_SCOPES:
|
||||
raise AnsibleActionFail("Invalid 'scope' option for '%s', got '%s' but should be one of: %s" % (name, scope, ', '.join(C.VALID_VAR_SCOPES)))
|
||||
|
||||
if len(var_def) > 0:
|
||||
raise AnsibleActionFail("Unknown arguments were passed into variable definition for '%s', only '%s' are valid." % (name, ', '.join(self._VALID_VARS_DEF)))
|
||||
|
||||
return name, value, scope
|
||||
|
||||
def run(self, tmp=None, task_vars=None):
|
||||
if task_vars is None:
|
||||
task_vars = dict()
|
||||
|
||||
result = super(ActionModule, self).run(tmp, task_vars)
|
||||
|
||||
result['_ansible_vars'] = {}
|
||||
if self._task.args:
|
||||
|
||||
try:
|
||||
vars_list = self._task.args.pop('defs')
|
||||
except KeyError:
|
||||
raise AnsibleActionFail("set_var requires a 'defs' option, none was provided")
|
||||
|
||||
scope = self._task.args.pop('scope', 'host')
|
||||
|
||||
if len(self._task.args) > 0:
|
||||
raise AnsibleActionFail("Unknown arguments were passed into set_var, only valid ones are: %s" % ', '.join(self._VALID_ARGS))
|
||||
|
||||
if isinstance(vars_list, string_types) or not isinstance(vars_list, Sequence):
|
||||
raise AnsibleActionFail("set_var takes a list of variable definitions, but got a '%s' instead" % type(vars_list))
|
||||
|
||||
for var_def in vars_list:
|
||||
|
||||
name, value, scope = self._extract_validated_var_definition(var_def, scope)
|
||||
|
||||
if scope not in result['_ansible_vars']:
|
||||
result['_ansible_vars'][scope] = {}
|
||||
|
||||
# allow for setting in loop
|
||||
if '_ansible_vars' in task_vars and scope in task_vars['_ansilbe_vars'] and name in task_vars['_ansible_vars'][scope]:
|
||||
result['_ansible_vars'][scope][name] = combine_vars(task_vars['_ansible_facts'][scope][name], value)
|
||||
else:
|
||||
result['_ansible_vars'][scope][name] = value
|
||||
|
||||
result['changed'] = False
|
||||
|
||||
return result
|
||||
@ -0,0 +1,3 @@
|
||||
#/usr/bin/bash
|
||||
|
||||
echo '{"failed": "false", "msg": "tested module"}'
|
||||
Loading…
Reference in New Issue