mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
--extra-vars option for ansible-playbook
Conflicts: lib/ansible/playbook.py Removed unneccessary shlex and replaced with basic split, some repurcussions in runner that can be eliminated once we consistently pass args as a string (soon).
This commit is contained in:
parent
6db87a5018
commit
f11de2f5c9
4 changed files with 51 additions and 15 deletions
|
@ -37,6 +37,8 @@ def main(args):
|
||||||
help='set the number of forks to start up')
|
help='set the number of forks to start up')
|
||||||
parser.add_option("-i", "--inventory-file", dest="inventory",
|
parser.add_option("-i", "--inventory-file", dest="inventory",
|
||||||
help="inventory host file", default=C.DEFAULT_HOST_LIST)
|
help="inventory host file", default=C.DEFAULT_HOST_LIST)
|
||||||
|
parser.add_option('-e', '--extra-vars', dest='extra_vars',
|
||||||
|
help='arguments to pass to the inventory script')
|
||||||
parser.add_option("-k", "--ask-pass", default=False, action="store_true",
|
parser.add_option("-k", "--ask-pass", default=False, action="store_true",
|
||||||
help="ask for SSH password")
|
help="ask for SSH password")
|
||||||
parser.add_option("-M", "--module-path", dest="module_path",
|
parser.add_option("-M", "--module-path", dest="module_path",
|
||||||
|
@ -71,6 +73,7 @@ def main(args):
|
||||||
pb = ansible.playbook.PlayBook(
|
pb = ansible.playbook.PlayBook(
|
||||||
playbook=playbook,
|
playbook=playbook,
|
||||||
host_list=options.inventory,
|
host_list=options.inventory,
|
||||||
|
extra_vars=options.extra_vars,
|
||||||
module_path=options.module_path,
|
module_path=options.module_path,
|
||||||
forks=options.forks,
|
forks=options.forks,
|
||||||
verbose=True,
|
verbose=True,
|
||||||
|
|
|
@ -56,6 +56,7 @@ class PlayBook(object):
|
||||||
remote_pass = C.DEFAULT_REMOTE_PASS,
|
remote_pass = C.DEFAULT_REMOTE_PASS,
|
||||||
remote_port = C.DEFAULT_REMOTE_PORT,
|
remote_port = C.DEFAULT_REMOTE_PORT,
|
||||||
override_hosts = None,
|
override_hosts = None,
|
||||||
|
extra_vars = None,
|
||||||
verbose = False,
|
verbose = False,
|
||||||
callbacks = None,
|
callbacks = None,
|
||||||
runner_callbacks = None,
|
runner_callbacks = None,
|
||||||
|
@ -75,13 +76,14 @@ class PlayBook(object):
|
||||||
self.callbacks = callbacks
|
self.callbacks = callbacks
|
||||||
self.runner_callbacks = runner_callbacks
|
self.runner_callbacks = runner_callbacks
|
||||||
self.override_hosts = override_hosts
|
self.override_hosts = override_hosts
|
||||||
|
self.extra_vars = extra_vars
|
||||||
self.stats = stats
|
self.stats = stats
|
||||||
|
|
||||||
self.basedir = os.path.dirname(playbook)
|
self.basedir = os.path.dirname(playbook)
|
||||||
self.playbook = self._parse_playbook(playbook)
|
self.playbook = self._parse_playbook(playbook)
|
||||||
|
|
||||||
self.host_list, self.groups = ansible.runner.Runner.parse_hosts(
|
self.host_list, self.groups = ansible.runner.Runner.parse_hosts(
|
||||||
host_list, override_hosts=self.override_hosts)
|
host_list, override_hosts=self.override_hosts, extra_vars=self.extra_vars)
|
||||||
|
|
||||||
# *****************************************************
|
# *****************************************************
|
||||||
|
|
||||||
|
@ -267,8 +269,8 @@ class PlayBook(object):
|
||||||
timeout=self.timeout, remote_user=remote_user,
|
timeout=self.timeout, remote_user=remote_user,
|
||||||
remote_port=self.remote_port,
|
remote_port=self.remote_port,
|
||||||
setup_cache=SETUP_CACHE, basedir=self.basedir,
|
setup_cache=SETUP_CACHE, basedir=self.basedir,
|
||||||
conditional=only_if, callbacks=self.runner_callbacks,
|
conditional=only_if, callbacks=self.runner_callbacks,
|
||||||
sudo=sudo
|
extra_vars=self.extra_vars, sudo=sudo
|
||||||
)
|
)
|
||||||
|
|
||||||
if async_seconds == 0:
|
if async_seconds == 0:
|
||||||
|
@ -286,16 +288,16 @@ class PlayBook(object):
|
||||||
name = task.get('name', None)
|
name = task.get('name', None)
|
||||||
action = task.get('action', None)
|
action = task.get('action', None)
|
||||||
if action is None:
|
if action is None:
|
||||||
raise errors.AnsibleError("action is required for each item in tasks")
|
raise errors.AnsibleError("action is required for each item in tasks: offending task is %s" % name if name else "unknown")
|
||||||
if name is None:
|
if name is None:
|
||||||
name = action
|
name = action
|
||||||
only_if = task.get('only_if', 'True')
|
only_if = task.get('only_if', 'True')
|
||||||
async_seconds = int(task.get('async', 0)) # not async by default
|
async_seconds = int(task.get('async', 0)) # not async by default
|
||||||
async_poll_interval = int(task.get('poll', 10)) # default poll = 10 seconds
|
async_poll_interval = int(task.get('poll', 10)) # default poll = 10 seconds
|
||||||
|
|
||||||
tokens = shlex.split(action, posix=False)
|
tokens = action.split(None, 1)
|
||||||
module_name = tokens[0]
|
module_name = tokens[0]
|
||||||
module_args = tokens[1:]
|
module_args = tokens[1]
|
||||||
|
|
||||||
# tasks can be direct (run on all nodes matching
|
# tasks can be direct (run on all nodes matching
|
||||||
# the pattern) or conditional, where they ran
|
# the pattern) or conditional, where they ran
|
||||||
|
@ -445,6 +447,13 @@ class PlayBook(object):
|
||||||
for (host, result) in setup_ok.iteritems():
|
for (host, result) in setup_ok.iteritems():
|
||||||
SETUP_CACHE[host] = result
|
SETUP_CACHE[host] = result
|
||||||
|
|
||||||
|
if self.extra_vars:
|
||||||
|
extra_vars = utils.parse_kv(shlex.split(self.extra_vars))
|
||||||
|
for h in self.host_list:
|
||||||
|
try:
|
||||||
|
SETUP_CACHE[h].update(extra_vars)
|
||||||
|
except:
|
||||||
|
SETUP_CACHE[h] = extra_vars
|
||||||
return host_list
|
return host_list
|
||||||
|
|
||||||
# *****************************************************
|
# *****************************************************
|
||||||
|
|
|
@ -74,7 +74,7 @@ class Runner(object):
|
||||||
remote_user=C.DEFAULT_REMOTE_USER, remote_pass=C.DEFAULT_REMOTE_PASS,
|
remote_user=C.DEFAULT_REMOTE_USER, remote_pass=C.DEFAULT_REMOTE_PASS,
|
||||||
remote_port=C.DEFAULT_REMOTE_PORT, background=0, basedir=None, setup_cache=None,
|
remote_port=C.DEFAULT_REMOTE_PORT, background=0, basedir=None, setup_cache=None,
|
||||||
transport='paramiko', conditional='True', groups={}, callbacks=None, verbose=False,
|
transport='paramiko', conditional='True', groups={}, callbacks=None, verbose=False,
|
||||||
sudo=False):
|
sudo=False, extra_vars=None):
|
||||||
|
|
||||||
if setup_cache is None:
|
if setup_cache is None:
|
||||||
setup_cache = {}
|
setup_cache = {}
|
||||||
|
@ -101,6 +101,7 @@ class Runner(object):
|
||||||
self.forks = int(forks)
|
self.forks = int(forks)
|
||||||
self.pattern = pattern
|
self.pattern = pattern
|
||||||
self.module_args = module_args
|
self.module_args = module_args
|
||||||
|
self.extra_vars = extra_vars
|
||||||
self.timeout = timeout
|
self.timeout = timeout
|
||||||
self.verbose = verbose
|
self.verbose = verbose
|
||||||
self.remote_user = remote_user
|
self.remote_user = remote_user
|
||||||
|
@ -143,14 +144,17 @@ class Runner(object):
|
||||||
# *****************************************************
|
# *****************************************************
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def parse_hosts_from_script(cls, host_list):
|
def parse_hosts_from_script(cls, host_list, extra_vars):
|
||||||
''' evaluate a script that returns list of hosts by groups '''
|
''' evaluate a script that returns list of hosts by groups '''
|
||||||
|
|
||||||
results = []
|
results = []
|
||||||
groups = dict(ungrouped=[])
|
groups = dict(ungrouped=[])
|
||||||
host_list = os.path.abspath(host_list)
|
host_list = os.path.abspath(host_list)
|
||||||
cls._external_variable_script = host_list
|
cls._external_variable_script = host_list
|
||||||
cmd = subprocess.Popen([host_list], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)
|
cmd = [host_list, '--list']
|
||||||
|
if extra_vars:
|
||||||
|
cmd.extend(['--extra-vars', extra_vars])
|
||||||
|
cmd = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)
|
||||||
out, err = cmd.communicate()
|
out, err = cmd.communicate()
|
||||||
try:
|
try:
|
||||||
groups = utils.json_loads(out)
|
groups = utils.json_loads(out)
|
||||||
|
@ -165,7 +169,7 @@ class Runner(object):
|
||||||
# *****************************************************
|
# *****************************************************
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def parse_hosts(cls, host_list, override_hosts=None):
|
def parse_hosts(cls, host_list, override_hosts=None, extra_vars=None):
|
||||||
''' parse the host inventory file, returns (hosts, groups) '''
|
''' parse the host inventory file, returns (hosts, groups) '''
|
||||||
|
|
||||||
if override_hosts is not None:
|
if override_hosts is not None:
|
||||||
|
@ -183,7 +187,7 @@ class Runner(object):
|
||||||
if not os.access(host_list, os.X_OK):
|
if not os.access(host_list, os.X_OK):
|
||||||
return Runner.parse_hosts_from_regular_file(host_list)
|
return Runner.parse_hosts_from_regular_file(host_list)
|
||||||
else:
|
else:
|
||||||
return Runner.parse_hosts_from_script(host_list)
|
return Runner.parse_hosts_from_script(host_list, extra_vars)
|
||||||
|
|
||||||
# *****************************************************
|
# *****************************************************
|
||||||
|
|
||||||
|
@ -275,7 +279,12 @@ class Runner(object):
|
||||||
''' support per system variabes from external variable scripts, see web docs '''
|
''' support per system variabes from external variable scripts, see web docs '''
|
||||||
|
|
||||||
host = conn.host
|
host = conn.host
|
||||||
cmd = subprocess.Popen([Runner._external_variable_script, host],
|
|
||||||
|
cmd = [Runner._external_variable_script, '--host', host]
|
||||||
|
if self.extra_vars:
|
||||||
|
cmd.extend(['--extra-vars', self.extra_vars])
|
||||||
|
|
||||||
|
cmd = subprocess.Popen(cmd,
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE,
|
stderr=subprocess.PIPE,
|
||||||
shell=False
|
shell=False
|
||||||
|
@ -384,9 +393,13 @@ class Runner(object):
|
||||||
''' transfer & execute a module that is not 'copy' or 'template' '''
|
''' transfer & execute a module that is not 'copy' or 'template' '''
|
||||||
|
|
||||||
# shell and command are the same module
|
# shell and command are the same module
|
||||||
|
# FIXME: keep these args as strings as long as possible...
|
||||||
if module_name == 'shell':
|
if module_name == 'shell':
|
||||||
module_name = 'command'
|
module_name = 'command'
|
||||||
self.module_args.append("#USE_SHELL")
|
if type(self.module_args) == list:
|
||||||
|
self.module_args.append("#USE_SHELL")
|
||||||
|
else:
|
||||||
|
self.module_args += " #USE_SHELL"
|
||||||
|
|
||||||
module = self._transfer_module(conn, tmp, module_name)
|
module = self._transfer_module(conn, tmp, module_name)
|
||||||
(result, executed) = self._execute_module(conn, tmp, module, self.module_args)
|
(result, executed) = self._execute_module(conn, tmp, module, self.module_args)
|
||||||
|
@ -406,7 +419,12 @@ class Runner(object):
|
||||||
module_args = self.module_args
|
module_args = self.module_args
|
||||||
if module_name == 'shell':
|
if module_name == 'shell':
|
||||||
module_name = 'command'
|
module_name = 'command'
|
||||||
module_args.append("#USE_SHELL")
|
# FIXME: this will become cleaner once we keep args as a string
|
||||||
|
# throughout the app
|
||||||
|
if type(module_args) == list:
|
||||||
|
module_args.append("#USE_SHELL")
|
||||||
|
else:
|
||||||
|
module_args += " #USE_SHELL"
|
||||||
|
|
||||||
async = self._transfer_module(conn, tmp, 'async_wrapper')
|
async = self._transfer_module(conn, tmp, 'async_wrapper')
|
||||||
module = self._transfer_module(conn, tmp, module_name)
|
module = self._transfer_module(conn, tmp, module_name)
|
||||||
|
|
|
@ -271,7 +271,13 @@ def unquote_string(string):
|
||||||
def parse_kv(args, unquote=True):
|
def parse_kv(args, unquote=True):
|
||||||
''' convert a string of key/value items to a dict '''
|
''' convert a string of key/value items to a dict '''
|
||||||
options = {}
|
options = {}
|
||||||
for x in args:
|
# FIXME: this should be mostly unneccessary once we convert
|
||||||
|
# things to stop parsing/unparsing
|
||||||
|
if type(args) == list:
|
||||||
|
vargs = args
|
||||||
|
else:
|
||||||
|
vargs = shlex.split(args, posix=True)
|
||||||
|
for x in vargs:
|
||||||
if x.find("=") != -1:
|
if x.find("=") != -1:
|
||||||
k, v = x.split("=")
|
k, v = x.split("=")
|
||||||
if unquote:
|
if unquote:
|
||||||
|
|
Loading…
Reference in a new issue