mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Moving ConnectionInformation -> PlayContext
Also making PlayContext a child class of the Playbook Base class, which gives it access to all of the FieldAttribute code to ensure field values are correctly typed after post_validation Fixes #11381
This commit is contained in:
parent
919aaa5c42
commit
e64989beb4
36 changed files with 477 additions and 459 deletions
|
@ -89,12 +89,12 @@ class PlayIterator:
|
||||||
FAILED_RESCUE = 4
|
FAILED_RESCUE = 4
|
||||||
FAILED_ALWAYS = 8
|
FAILED_ALWAYS = 8
|
||||||
|
|
||||||
def __init__(self, inventory, play, connection_info, all_vars):
|
def __init__(self, inventory, play, play_context, all_vars):
|
||||||
self._play = play
|
self._play = play
|
||||||
|
|
||||||
self._blocks = []
|
self._blocks = []
|
||||||
for block in self._play.compile():
|
for block in self._play.compile():
|
||||||
new_block = block.filter_tagged_tasks(connection_info, all_vars)
|
new_block = block.filter_tagged_tasks(play_context, all_vars)
|
||||||
if new_block.has_tasks():
|
if new_block.has_tasks():
|
||||||
self._blocks.append(new_block)
|
self._blocks.append(new_block)
|
||||||
|
|
||||||
|
@ -103,12 +103,12 @@ class PlayIterator:
|
||||||
self._host_states[host.name] = HostState(blocks=self._blocks)
|
self._host_states[host.name] = HostState(blocks=self._blocks)
|
||||||
# if we're looking to start at a specific task, iterate through
|
# if we're looking to start at a specific task, iterate through
|
||||||
# the tasks for this host until we find the specified task
|
# the tasks for this host until we find the specified task
|
||||||
if connection_info.start_at_task is not None:
|
if play_context.start_at_task is not None:
|
||||||
while True:
|
while True:
|
||||||
(s, task) = self.get_next_task_for_host(host, peek=True)
|
(s, task) = self.get_next_task_for_host(host, peek=True)
|
||||||
if s.run_state == self.ITERATING_COMPLETE:
|
if s.run_state == self.ITERATING_COMPLETE:
|
||||||
break
|
break
|
||||||
if task.get_name() != connection_info.start_at_task:
|
if task.get_name() != play_context.start_at_task:
|
||||||
self.get_next_task_for_host(host)
|
self.get_next_task_for_host(host)
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
|
@ -94,7 +94,7 @@ class WorkerProcess(multiprocessing.Process):
|
||||||
try:
|
try:
|
||||||
if not self._main_q.empty():
|
if not self._main_q.empty():
|
||||||
debug("there's work to be done!")
|
debug("there's work to be done!")
|
||||||
(host, task, basedir, job_vars, connection_info, shared_loader_obj) = self._main_q.get(block=False)
|
(host, task, basedir, job_vars, play_context, shared_loader_obj) = self._main_q.get(block=False)
|
||||||
debug("got a task/handler to work on: %s" % task)
|
debug("got a task/handler to work on: %s" % task)
|
||||||
|
|
||||||
# because the task queue manager starts workers (forks) before the
|
# because the task queue manager starts workers (forks) before the
|
||||||
|
@ -111,11 +111,11 @@ class WorkerProcess(multiprocessing.Process):
|
||||||
# apply the given task's information to the connection info,
|
# apply the given task's information to the connection info,
|
||||||
# which may override some fields already set by the play or
|
# which may override some fields already set by the play or
|
||||||
# the options specified on the command line
|
# the options specified on the command line
|
||||||
new_connection_info = connection_info.set_task_and_host_override(task=task, host=host)
|
new_play_context = play_context.set_task_and_host_override(task=task, host=host)
|
||||||
|
|
||||||
# execute the task and build a TaskResult from the result
|
# execute the task and build a TaskResult from the result
|
||||||
debug("running TaskExecutor() for %s/%s" % (host, task))
|
debug("running TaskExecutor() for %s/%s" % (host, task))
|
||||||
executor_result = TaskExecutor(host, task, job_vars, new_connection_info, self._new_stdin, self._loader, shared_loader_obj).run()
|
executor_result = TaskExecutor(host, task, job_vars, new_play_context, self._new_stdin, self._loader, shared_loader_obj).run()
|
||||||
debug("done running TaskExecutor() for %s/%s" % (host, task))
|
debug("done running TaskExecutor() for %s/%s" % (host, task))
|
||||||
task_result = TaskResult(host, task, executor_result)
|
task_result = TaskResult(host, task, executor_result)
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,6 @@ import time
|
||||||
|
|
||||||
from ansible import constants as C
|
from ansible import constants as C
|
||||||
from ansible.errors import AnsibleError, AnsibleParserError
|
from ansible.errors import AnsibleError, AnsibleParserError
|
||||||
from ansible.executor.connection_info import ConnectionInformation
|
|
||||||
from ansible.playbook.conditional import Conditional
|
from ansible.playbook.conditional import Conditional
|
||||||
from ansible.playbook.task import Task
|
from ansible.playbook.task import Task
|
||||||
from ansible.plugins import lookup_loader, connection_loader, action_loader
|
from ansible.plugins import lookup_loader, connection_loader, action_loader
|
||||||
|
@ -52,11 +51,11 @@ class TaskExecutor:
|
||||||
# the module
|
# the module
|
||||||
SQUASH_ACTIONS = frozenset(('apt', 'yum', 'pkgng', 'zypper', 'dnf'))
|
SQUASH_ACTIONS = frozenset(('apt', 'yum', 'pkgng', 'zypper', 'dnf'))
|
||||||
|
|
||||||
def __init__(self, host, task, job_vars, connection_info, new_stdin, loader, shared_loader_obj):
|
def __init__(self, host, task, job_vars, play_context, new_stdin, loader, shared_loader_obj):
|
||||||
self._host = host
|
self._host = host
|
||||||
self._task = task
|
self._task = task
|
||||||
self._job_vars = job_vars
|
self._job_vars = job_vars
|
||||||
self._connection_info = connection_info
|
self._play_context = play_context
|
||||||
self._new_stdin = new_stdin
|
self._new_stdin = new_stdin
|
||||||
self._loader = loader
|
self._loader = loader
|
||||||
self._shared_loader_obj = shared_loader_obj
|
self._shared_loader_obj = shared_loader_obj
|
||||||
|
@ -208,11 +207,11 @@ class TaskExecutor:
|
||||||
|
|
||||||
# fields set from the play/task may be based on variables, so we have to
|
# fields set from the play/task may be based on variables, so we have to
|
||||||
# do the same kind of post validation step on it here before we use it.
|
# do the same kind of post validation step on it here before we use it.
|
||||||
self._connection_info.post_validate(templar=templar)
|
self._play_context.post_validate(templar=templar)
|
||||||
|
|
||||||
# now that the connection information is finalized, we can add 'magic'
|
# now that the play context is finalized, we can add 'magic'
|
||||||
# variables to the variable dictionary
|
# variables to the variable dictionary
|
||||||
self._connection_info.update_vars(variables)
|
self._play_context.update_vars(variables)
|
||||||
|
|
||||||
# Evaluate the conditional (if any) for this task, which we do before running
|
# Evaluate the conditional (if any) for this task, which we do before running
|
||||||
# the final task post-validation. We do this before the post validation due to
|
# the final task post-validation. We do this before the post validation due to
|
||||||
|
@ -362,7 +361,7 @@ class TaskExecutor:
|
||||||
'normal',
|
'normal',
|
||||||
task=async_task,
|
task=async_task,
|
||||||
connection=self._connection,
|
connection=self._connection,
|
||||||
connection_info=self._connection_info,
|
play_context=self._play_context,
|
||||||
loader=self._loader,
|
loader=self._loader,
|
||||||
templar=templar,
|
templar=templar,
|
||||||
shared_loader_obj=self._shared_loader_obj,
|
shared_loader_obj=self._shared_loader_obj,
|
||||||
|
@ -392,16 +391,16 @@ class TaskExecutor:
|
||||||
# FIXME: delegate_to calculation should be done here
|
# FIXME: delegate_to calculation should be done here
|
||||||
# FIXME: calculation of connection params/auth stuff should be done here
|
# FIXME: calculation of connection params/auth stuff should be done here
|
||||||
|
|
||||||
if not self._connection_info.remote_addr:
|
if not self._play_context.remote_addr:
|
||||||
self._connection_info.remote_addr = self._host.ipv4_address
|
self._play_context.remote_addr = self._host.ipv4_address
|
||||||
|
|
||||||
if self._task.delegate_to is not None:
|
if self._task.delegate_to is not None:
|
||||||
self._compute_delegate(variables)
|
self._compute_delegate(variables)
|
||||||
|
|
||||||
conn_type = self._connection_info.connection
|
conn_type = self._play_context.connection
|
||||||
if conn_type == 'smart':
|
if conn_type == 'smart':
|
||||||
conn_type = 'ssh'
|
conn_type = 'ssh'
|
||||||
if sys.platform.startswith('darwin') and self._connection_info.password:
|
if sys.platform.startswith('darwin') and self._play_context.password:
|
||||||
# due to a current bug in sshpass on OSX, which can trigger
|
# due to a current bug in sshpass on OSX, which can trigger
|
||||||
# a kernel panic even for non-privileged users, we revert to
|
# a kernel panic even for non-privileged users, we revert to
|
||||||
# paramiko on that OS when a SSH password is specified
|
# paramiko on that OS when a SSH password is specified
|
||||||
|
@ -413,7 +412,7 @@ class TaskExecutor:
|
||||||
if "Bad configuration option" in err:
|
if "Bad configuration option" in err:
|
||||||
conn_type = "paramiko"
|
conn_type = "paramiko"
|
||||||
|
|
||||||
connection = connection_loader.get(conn_type, self._connection_info, self._new_stdin)
|
connection = connection_loader.get(conn_type, self._play_context, self._new_stdin)
|
||||||
if not connection:
|
if not connection:
|
||||||
raise AnsibleError("the connection plugin '%s' was not found" % conn_type)
|
raise AnsibleError("the connection plugin '%s' was not found" % conn_type)
|
||||||
|
|
||||||
|
@ -437,7 +436,7 @@ class TaskExecutor:
|
||||||
handler_name,
|
handler_name,
|
||||||
task=self._task,
|
task=self._task,
|
||||||
connection=connection,
|
connection=connection,
|
||||||
connection_info=self._connection_info,
|
play_context=self._play_context,
|
||||||
loader=self._loader,
|
loader=self._loader,
|
||||||
templar=templar,
|
templar=templar,
|
||||||
shared_loader_obj=self._shared_loader_obj,
|
shared_loader_obj=self._shared_loader_obj,
|
||||||
|
@ -458,16 +457,16 @@ class TaskExecutor:
|
||||||
this_info = {}
|
this_info = {}
|
||||||
|
|
||||||
# get the real ssh_address for the delegate and allow ansible_ssh_host to be templated
|
# get the real ssh_address for the delegate and allow ansible_ssh_host to be templated
|
||||||
#self._connection_info.remote_user = self._compute_delegate_user(self.delegate_to, delegate['inject'])
|
#self._play_context.remote_user = self._compute_delegate_user(self.delegate_to, delegate['inject'])
|
||||||
self._connection_info.remote_addr = this_info.get('ansible_ssh_host', self._task.delegate_to)
|
self._play_context.remote_addr = this_info.get('ansible_ssh_host', self._task.delegate_to)
|
||||||
self._connection_info.port = this_info.get('ansible_ssh_port', self._connection_info.port)
|
self._play_context.port = this_info.get('ansible_ssh_port', self._play_context.port)
|
||||||
self._connection_info.password = this_info.get('ansible_ssh_pass', self._connection_info.password)
|
self._play_context.password = this_info.get('ansible_ssh_pass', self._play_context.password)
|
||||||
self._connection_info.private_key_file = this_info.get('ansible_ssh_private_key_file', self._connection_info.private_key_file)
|
self._play_context.private_key_file = this_info.get('ansible_ssh_private_key_file', self._play_context.private_key_file)
|
||||||
self._connection_info.connection = this_info.get('ansible_connection', C.DEFAULT_TRANSPORT)
|
self._play_context.connection = this_info.get('ansible_connection', C.DEFAULT_TRANSPORT)
|
||||||
self._connection_info.become_pass = this_info.get('ansible_sudo_pass', self._connection_info.become_pass)
|
self._play_context.become_pass = this_info.get('ansible_sudo_pass', self._play_context.become_pass)
|
||||||
|
|
||||||
if self._connection_info.remote_addr in ('127.0.0.1', 'localhost'):
|
if self._play_context.remote_addr in ('127.0.0.1', 'localhost'):
|
||||||
self._connection_info.connection = 'local'
|
self._play_context.connection = 'local'
|
||||||
|
|
||||||
# Last chance to get private_key_file from global variables.
|
# Last chance to get private_key_file from global variables.
|
||||||
# this is useful if delegated host is not defined in the inventory
|
# this is useful if delegated host is not defined in the inventory
|
||||||
|
|
|
@ -27,11 +27,11 @@ import sys
|
||||||
|
|
||||||
from ansible import constants as C
|
from ansible import constants as C
|
||||||
from ansible.errors import AnsibleError
|
from ansible.errors import AnsibleError
|
||||||
from ansible.executor.connection_info import ConnectionInformation
|
|
||||||
from ansible.executor.play_iterator import PlayIterator
|
from ansible.executor.play_iterator import PlayIterator
|
||||||
from ansible.executor.process.worker import WorkerProcess
|
from ansible.executor.process.worker import WorkerProcess
|
||||||
from ansible.executor.process.result import ResultProcess
|
from ansible.executor.process.result import ResultProcess
|
||||||
from ansible.executor.stats import AggregateStats
|
from ansible.executor.stats import AggregateStats
|
||||||
|
from ansible.playbook.play_context import PlayContext
|
||||||
from ansible.plugins import callback_loader, strategy_loader
|
from ansible.plugins import callback_loader, strategy_loader
|
||||||
from ansible.template import Templar
|
from ansible.template import Templar
|
||||||
|
|
||||||
|
@ -236,10 +236,10 @@ class TaskQueueManager:
|
||||||
new_play = play.copy()
|
new_play = play.copy()
|
||||||
new_play.post_validate(templar)
|
new_play.post_validate(templar)
|
||||||
|
|
||||||
connection_info = ConnectionInformation(new_play, self._options, self.passwords)
|
play_context = PlayContext(new_play, self._options, self.passwords)
|
||||||
for callback_plugin in self._callback_plugins:
|
for callback_plugin in self._callback_plugins:
|
||||||
if hasattr(callback_plugin, 'set_connection_info'):
|
if hasattr(callback_plugin, 'set_play_context'):
|
||||||
callback_plugin.set_connection_info(connection_info)
|
callback_plugin.set_play_context(play_context)
|
||||||
|
|
||||||
self.send_callback('v2_playbook_on_play_start', new_play)
|
self.send_callback('v2_playbook_on_play_start', new_play)
|
||||||
|
|
||||||
|
@ -252,10 +252,10 @@ class TaskQueueManager:
|
||||||
raise AnsibleError("Invalid play strategy specified: %s" % new_play.strategy, obj=play._ds)
|
raise AnsibleError("Invalid play strategy specified: %s" % new_play.strategy, obj=play._ds)
|
||||||
|
|
||||||
# build the iterator
|
# build the iterator
|
||||||
iterator = PlayIterator(inventory=self._inventory, play=new_play, connection_info=connection_info, all_vars=all_vars)
|
iterator = PlayIterator(inventory=self._inventory, play=new_play, play_context=play_context, all_vars=all_vars)
|
||||||
|
|
||||||
# and run the play using the strategy
|
# and run the play using the strategy
|
||||||
return strategy.run(iterator, connection_info)
|
return strategy.run(iterator, play_context)
|
||||||
|
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
debug("RUNNING CLEANUP")
|
debug("RUNNING CLEANUP")
|
||||||
|
|
|
@ -295,6 +295,11 @@ class Base:
|
||||||
for item in value:
|
for item in value:
|
||||||
if not isinstance(item, attribute.listof):
|
if not isinstance(item, attribute.listof):
|
||||||
raise AnsibleParserError("the field '%s' should be a list of %s, but the item '%s' is a %s" % (name, attribute.listof, item, type(item)), obj=self.get_ds())
|
raise AnsibleParserError("the field '%s' should be a list of %s, but the item '%s' is a %s" % (name, attribute.listof, item, type(item)), obj=self.get_ds())
|
||||||
|
elif attribute.isa == 'set':
|
||||||
|
if not isinstance(value, (list, set)):
|
||||||
|
value = [ value ]
|
||||||
|
if not isinstance(value, set):
|
||||||
|
value = set(value)
|
||||||
elif attribute.isa == 'dict' and not isinstance(value, dict):
|
elif attribute.isa == 'dict' and not isinstance(value, dict):
|
||||||
raise TypeError("%s is not a dictionary" % value)
|
raise TypeError("%s is not a dictionary" % value)
|
||||||
|
|
||||||
|
|
|
@ -301,16 +301,16 @@ class Block(Base, Become, Conditional, Taggable):
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def filter_tagged_tasks(self, connection_info, all_vars):
|
def filter_tagged_tasks(self, play_context, all_vars):
|
||||||
'''
|
'''
|
||||||
Creates a new block, with task lists filtered based on the tags contained
|
Creates a new block, with task lists filtered based on the tags contained
|
||||||
within the connection_info object.
|
within the play_context object.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def evaluate_and_append_task(target):
|
def evaluate_and_append_task(target):
|
||||||
tmp_list = []
|
tmp_list = []
|
||||||
for task in target:
|
for task in target:
|
||||||
if task.evaluate_tags(connection_info.only_tags, connection_info.skip_tags, all_vars=all_vars):
|
if task.evaluate_tags(play_context.only_tags, play_context.skip_tags, all_vars=all_vars):
|
||||||
tmp_list.append(task)
|
tmp_list.append(task)
|
||||||
return tmp_list
|
return tmp_list
|
||||||
|
|
||||||
|
|
|
@ -26,11 +26,13 @@ import random
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from ansible import constants as C
|
from ansible import constants as C
|
||||||
|
from ansible.errors import AnsibleError
|
||||||
|
from ansible.playbook.attribute import Attribute, FieldAttribute
|
||||||
|
from ansible.playbook.base import Base
|
||||||
from ansible.template import Templar
|
from ansible.template import Templar
|
||||||
from ansible.utils.boolean import boolean
|
from ansible.utils.boolean import boolean
|
||||||
from ansible.errors import AnsibleError
|
|
||||||
|
|
||||||
__all__ = ['ConnectionInformation']
|
__all__ = ['PlayContext']
|
||||||
|
|
||||||
SU_PROMPT_LOCALIZATIONS = [
|
SU_PROMPT_LOCALIZATIONS = [
|
||||||
'Password',
|
'Password',
|
||||||
|
@ -67,7 +69,7 @@ SU_PROMPT_LOCALIZATIONS = [
|
||||||
]
|
]
|
||||||
|
|
||||||
# the magic variable mapping dictionary below is used to translate
|
# the magic variable mapping dictionary below is used to translate
|
||||||
# host/inventory variables to fields in the ConnectionInformation
|
# host/inventory variables to fields in the PlayContext
|
||||||
# object. The dictionary values are tuples, to account for aliases
|
# object. The dictionary values are tuples, to account for aliases
|
||||||
# in variable names.
|
# in variable names.
|
||||||
|
|
||||||
|
@ -131,7 +133,7 @@ SU_PROMPT_LOCALIZATIONS = [
|
||||||
'密碼',
|
'密碼',
|
||||||
]
|
]
|
||||||
|
|
||||||
class ConnectionInformation:
|
class PlayContext(Base):
|
||||||
|
|
||||||
'''
|
'''
|
||||||
This class is used to consolidate the connection information for
|
This class is used to consolidate the connection information for
|
||||||
|
@ -139,48 +141,49 @@ class ConnectionInformation:
|
||||||
connection/authentication information.
|
connection/authentication information.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
# connection fields, some are inherited from Base:
|
||||||
|
# (connection, port, remote_user, environment, no_log)
|
||||||
|
_remote_addr = FieldAttribute(isa='string')
|
||||||
|
_password = FieldAttribute(isa='string')
|
||||||
|
_private_key_file = FieldAttribute(isa='string', default=C.DEFAULT_PRIVATE_KEY_FILE)
|
||||||
|
_timeout = FieldAttribute(isa='int', default=C.DEFAULT_TIMEOUT)
|
||||||
|
_shell = FieldAttribute(isa='string')
|
||||||
|
|
||||||
|
# privilege escalation fields
|
||||||
|
_become = FieldAttribute(isa='bool')
|
||||||
|
_become_method = FieldAttribute(isa='string')
|
||||||
|
_become_user = FieldAttribute(isa='string')
|
||||||
|
_become_pass = FieldAttribute(isa='string')
|
||||||
|
_become_exe = FieldAttribute(isa='string')
|
||||||
|
_become_flags = FieldAttribute(isa='string')
|
||||||
|
_prompt = FieldAttribute(isa='string')
|
||||||
|
|
||||||
|
# backwards compatibility fields for sudo/su
|
||||||
|
_sudo_exe = FieldAttribute(isa='string')
|
||||||
|
_sudo_flags = FieldAttribute(isa='string')
|
||||||
|
_sudo_pass = FieldAttribute(isa='string')
|
||||||
|
_su_exe = FieldAttribute(isa='string')
|
||||||
|
_su_flags = FieldAttribute(isa='string')
|
||||||
|
_su_pass = FieldAttribute(isa='string')
|
||||||
|
|
||||||
|
# general flags
|
||||||
|
_verbosity = FieldAttribute(isa='int', default=0)
|
||||||
|
_only_tags = FieldAttribute(isa='set', default=set())
|
||||||
|
_skip_tags = FieldAttribute(isa='set', default=set())
|
||||||
|
_check_mode = FieldAttribute(isa='bool', default=False)
|
||||||
|
_force_handlers = FieldAttribute(isa='bool', default=False)
|
||||||
|
_start_at_task = FieldAttribute(isa='string')
|
||||||
|
_step = FieldAttribute(isa='bool', default=False)
|
||||||
|
|
||||||
def __init__(self, play=None, options=None, passwords=None):
|
def __init__(self, play=None, options=None, passwords=None):
|
||||||
|
|
||||||
|
super(PlayContext, self).__init__()
|
||||||
|
|
||||||
if passwords is None:
|
if passwords is None:
|
||||||
passwords = {}
|
passwords = {}
|
||||||
|
|
||||||
# connection
|
self.password = passwords.get('conn_pass','')
|
||||||
self.connection = None
|
self.become_pass = passwords.get('become_pass','')
|
||||||
self.remote_addr = None
|
|
||||||
self.remote_user = None
|
|
||||||
self.password = passwords.get('conn_pass','')
|
|
||||||
self.port = None
|
|
||||||
self.private_key_file = C.DEFAULT_PRIVATE_KEY_FILE
|
|
||||||
self.timeout = C.DEFAULT_TIMEOUT
|
|
||||||
self.shell = None
|
|
||||||
|
|
||||||
# privilege escalation
|
|
||||||
self.become = None
|
|
||||||
self.become_method = None
|
|
||||||
self.become_user = None
|
|
||||||
self.become_pass = passwords.get('become_pass','')
|
|
||||||
self.become_exe = None
|
|
||||||
self.become_flags = None
|
|
||||||
self.prompt = None
|
|
||||||
self.success_key = None
|
|
||||||
|
|
||||||
# backwards compat
|
|
||||||
self.sudo_exe = None
|
|
||||||
self.sudo_flags = None
|
|
||||||
self.sudo_pass = None
|
|
||||||
self.su_exe = None
|
|
||||||
self.su_flags = None
|
|
||||||
self.su_pass = None
|
|
||||||
|
|
||||||
# general flags (should we move out?)
|
|
||||||
self.verbosity = 0
|
|
||||||
self.only_tags = set()
|
|
||||||
self.skip_tags = set()
|
|
||||||
self.no_log = False
|
|
||||||
self.check_mode = False
|
|
||||||
self.force_handlers = False
|
|
||||||
self.start_at_task = None
|
|
||||||
self.step = False
|
|
||||||
|
|
||||||
#TODO: just pull options setup to above?
|
#TODO: just pull options setup to above?
|
||||||
# set options before play to allow play to override them
|
# set options before play to allow play to override them
|
||||||
|
@ -213,8 +216,9 @@ class ConnectionInformation:
|
||||||
self.become_user = play.become_user
|
self.become_user = play.become_user
|
||||||
|
|
||||||
# non connection related
|
# non connection related
|
||||||
self.no_log = play.no_log
|
self.no_log = play.no_log
|
||||||
self.environment = play.environment
|
self.environment = play.environment
|
||||||
|
|
||||||
if play.force_handlers is not None:
|
if play.force_handlers is not None:
|
||||||
self.force_handlers = play.force_handlers
|
self.force_handlers = play.force_handlers
|
||||||
|
|
||||||
|
@ -268,22 +272,22 @@ class ConnectionInformation:
|
||||||
elif isinstance(options.skip_tags, basestring):
|
elif isinstance(options.skip_tags, basestring):
|
||||||
self.skip_tags.update(options.skip_tags.split(','))
|
self.skip_tags.update(options.skip_tags.split(','))
|
||||||
|
|
||||||
def copy(self, ci):
|
#def copy(self, ci):
|
||||||
'''
|
# '''
|
||||||
Copies the connection info from another connection info object, used
|
# Copies the connection info from another connection info object, used
|
||||||
when merging in data from task overrides.
|
# when merging in data from task overrides.
|
||||||
'''
|
# '''
|
||||||
|
#
|
||||||
for field in self._get_fields():
|
# for field in self._get_fields():
|
||||||
value = getattr(ci, field, None)
|
# value = getattr(ci, field, None)
|
||||||
if isinstance(value, dict):
|
# if isinstance(value, dict):
|
||||||
setattr(self, field, value.copy())
|
# setattr(self, field, value.copy())
|
||||||
elif isinstance(value, set):
|
# elif isinstance(value, set):
|
||||||
setattr(self, field, value.copy())
|
# setattr(self, field, value.copy())
|
||||||
elif isinstance(value, list):
|
# elif isinstance(value, list):
|
||||||
setattr(self, field, value[:])
|
# setattr(self, field, value[:])
|
||||||
else:
|
# else:
|
||||||
setattr(self, field, value)
|
# setattr(self, field, value)
|
||||||
|
|
||||||
def set_task_and_host_override(self, task, host):
|
def set_task_and_host_override(self, task, host):
|
||||||
'''
|
'''
|
||||||
|
@ -291,8 +295,7 @@ class ConnectionInformation:
|
||||||
those from the play.
|
those from the play.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
new_info = ConnectionInformation()
|
new_info = self.copy()
|
||||||
new_info.copy(self)
|
|
||||||
|
|
||||||
# loop through a subset of attributes on the task object and set
|
# loop through a subset of attributes on the task object and set
|
||||||
# connection fields based on their values
|
# connection fields based on their values
|
||||||
|
@ -382,17 +385,17 @@ class ConnectionInformation:
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
|
|
||||||
def _get_fields(self):
|
#def _get_fields(self):
|
||||||
return [i for i in self.__dict__.keys() if i[:1] != '_']
|
# return [i for i in self.__dict__.keys() if i[:1] != '_']
|
||||||
|
|
||||||
def post_validate(self, templar):
|
#def post_validate(self, templar):
|
||||||
'''
|
# '''
|
||||||
Finalizes templated values which may be set on this objects fields.
|
# Finalizes templated values which may be set on this objects fields.
|
||||||
'''
|
# '''
|
||||||
|
#
|
||||||
for field in self._get_fields():
|
# for field in self._get_fields():
|
||||||
value = templar.template(getattr(self, field))
|
# value = templar.template(getattr(self, field))
|
||||||
setattr(self, field, value)
|
# setattr(self, field, value)
|
||||||
|
|
||||||
def update_vars(self, variables):
|
def update_vars(self, variables):
|
||||||
'''
|
'''
|
|
@ -34,6 +34,7 @@ from ansible.playbook.block import Block
|
||||||
from ansible.playbook.conditional import Conditional
|
from ansible.playbook.conditional import Conditional
|
||||||
from ansible.playbook.role import Role
|
from ansible.playbook.role import Role
|
||||||
from ansible.playbook.taggable import Taggable
|
from ansible.playbook.taggable import Taggable
|
||||||
|
from ansible.utils.vars import combine_vars
|
||||||
|
|
||||||
__all__ = ['Task']
|
__all__ = ['Task']
|
||||||
|
|
||||||
|
@ -292,22 +293,38 @@ class Task(Base, Conditional, Taggable, Become):
|
||||||
if self._task_include:
|
if self._task_include:
|
||||||
self._task_include.set_loader(loader)
|
self._task_include.set_loader(loader)
|
||||||
|
|
||||||
def _get_parent_attribute(self, attr, extend=False):
|
def _get_parent_attribute(self, attr, extend=False, combine=False):
|
||||||
'''
|
'''
|
||||||
Generic logic to get the attribute or parent attribute for a task value.
|
Generic logic to get the attribute or parent attribute for a task value.
|
||||||
'''
|
'''
|
||||||
value = self._attributes[attr]
|
value = self._attributes[attr]
|
||||||
if self._block and (value is None or extend):
|
if self._block and (value is None or extend or combine):
|
||||||
parent_value = getattr(self._block, attr)
|
parent_value = getattr(self._block, attr)
|
||||||
if extend:
|
if extend:
|
||||||
value = self._extend_value(value, parent_value)
|
value = self._extend_value(value, parent_value)
|
||||||
|
elif combine and isinstance(parent_value, dict) and isinstance(value, dict):
|
||||||
|
value = combine_vars(parent_value, value)
|
||||||
else:
|
else:
|
||||||
value = parent_value
|
value = parent_value
|
||||||
if self._task_include and (value is None or extend):
|
if self._task_include and (value is None or extend or combine):
|
||||||
parent_value = getattr(self._task_include, attr)
|
parent_value = getattr(self._task_include, attr)
|
||||||
if extend:
|
if extend:
|
||||||
value = self._extend_value(value, parent_value)
|
value = self._extend_value(value, parent_value)
|
||||||
|
elif combine:
|
||||||
|
value = combine_vars(parent_value, value)
|
||||||
else:
|
else:
|
||||||
value = parent_value
|
value = parent_value
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
def _get_attr_environment(self):
|
||||||
|
'''
|
||||||
|
Override for the 'tags' getattr fetcher, used from Base.
|
||||||
|
'''
|
||||||
|
environment = self._attributes['tags']
|
||||||
|
if environment is None:
|
||||||
|
environment = dict()
|
||||||
|
|
||||||
|
environment = self._get_parent_attribute('environment', combine=True)
|
||||||
|
|
||||||
|
return environment
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,6 @@ from ansible import constants as C
|
||||||
from ansible.errors import AnsibleError
|
from ansible.errors import AnsibleError
|
||||||
from ansible.executor.module_common import modify_module
|
from ansible.executor.module_common import modify_module
|
||||||
from ansible.parsing.utils.jsonify import jsonify
|
from ansible.parsing.utils.jsonify import jsonify
|
||||||
|
|
||||||
from ansible.utils.debug import debug
|
from ansible.utils.debug import debug
|
||||||
from ansible.utils.unicode import to_bytes
|
from ansible.utils.unicode import to_bytes
|
||||||
|
|
||||||
|
@ -44,10 +43,10 @@ class ActionBase:
|
||||||
action in use.
|
action in use.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def __init__(self, task, connection, connection_info, loader, templar, shared_loader_obj):
|
def __init__(self, task, connection, play_context, loader, templar, shared_loader_obj):
|
||||||
self._task = task
|
self._task = task
|
||||||
self._connection = connection
|
self._connection = connection
|
||||||
self._connection_info = connection_info
|
self._play_context = play_context
|
||||||
self._loader = loader
|
self._loader = loader
|
||||||
self._templar = templar
|
self._templar = templar
|
||||||
self._shared_loader_obj = shared_loader_obj
|
self._shared_loader_obj = shared_loader_obj
|
||||||
|
@ -82,16 +81,11 @@ class ActionBase:
|
||||||
Builds the environment string to be used when executing the remote task.
|
Builds the environment string to be used when executing the remote task.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
enviro = {}
|
if self._task.environment:
|
||||||
|
if type(self._task.environment) != dict:
|
||||||
|
raise errors.AnsibleError("environment must be a dictionary, received %s" % self._task.environment)
|
||||||
|
|
||||||
# FIXME: not sure where this comes from, probably task but maybe also the play?
|
return self._connection._shell.env_prefix(**self._task.environment)
|
||||||
#if self.environment:
|
|
||||||
# enviro = template.template(self.basedir, self.environment, inject, convert_bare=True)
|
|
||||||
# enviro = utils.safe_eval(enviro)
|
|
||||||
# if type(enviro) != dict:
|
|
||||||
# raise errors.AnsibleError("environment must be a dictionary, received %s" % enviro)
|
|
||||||
|
|
||||||
return self._connection._shell.env_prefix(**enviro)
|
|
||||||
|
|
||||||
def _early_needs_tmp_path(self):
|
def _early_needs_tmp_path(self):
|
||||||
'''
|
'''
|
||||||
|
@ -109,7 +103,7 @@ class ActionBase:
|
||||||
if tmp and "tmp" in tmp:
|
if tmp and "tmp" in tmp:
|
||||||
# tmp has already been created
|
# tmp has already been created
|
||||||
return False
|
return False
|
||||||
if not self._connection.__class__.has_pipelining or not C.ANSIBLE_SSH_PIPELINING or C.DEFAULT_KEEP_REMOTE_FILES or self._connection_info.become:
|
if not self._connection.__class__.has_pipelining or not C.ANSIBLE_SSH_PIPELINING or C.DEFAULT_KEEP_REMOTE_FILES or self._play_context.become:
|
||||||
# tmp is necessary to store module source code
|
# tmp is necessary to store module source code
|
||||||
return True
|
return True
|
||||||
if not self._connection.__class__.has_pipelining:
|
if not self._connection.__class__.has_pipelining:
|
||||||
|
@ -131,11 +125,11 @@ class ActionBase:
|
||||||
basefile = 'ansible-tmp-%s-%s' % (time.time(), random.randint(0, 2**48))
|
basefile = 'ansible-tmp-%s-%s' % (time.time(), random.randint(0, 2**48))
|
||||||
use_system_tmp = False
|
use_system_tmp = False
|
||||||
|
|
||||||
if self._connection_info.become and self._connection_info.become_user != 'root':
|
if self._play_context.become and self._play_context.become_user != 'root':
|
||||||
use_system_tmp = True
|
use_system_tmp = True
|
||||||
|
|
||||||
tmp_mode = None
|
tmp_mode = None
|
||||||
if self._connection_info.remote_user != 'root' or self._connection_info.become and self._connection_info.become_user != 'root':
|
if self._play_context.remote_user != 'root' or self._play_context.become and self._play_context.become_user != 'root':
|
||||||
tmp_mode = 'a+rx'
|
tmp_mode = 'a+rx'
|
||||||
|
|
||||||
cmd = self._connection._shell.mkdtemp(basefile, use_system_tmp, tmp_mode)
|
cmd = self._connection._shell.mkdtemp(basefile, use_system_tmp, tmp_mode)
|
||||||
|
@ -149,7 +143,7 @@ class ActionBase:
|
||||||
output = 'Authentication failure.'
|
output = 'Authentication failure.'
|
||||||
elif result['rc'] == 255 and self._connection.transport in ('ssh',):
|
elif result['rc'] == 255 and self._connection.transport in ('ssh',):
|
||||||
|
|
||||||
if self._connection_info.verbosity > 3:
|
if self._play_context.verbosity > 3:
|
||||||
output = 'SSH encountered an unknown error. The output was:\n%s' % (result['stdout']+result['stderr'])
|
output = 'SSH encountered an unknown error. The output was:\n%s' % (result['stdout']+result['stderr'])
|
||||||
else:
|
else:
|
||||||
output = 'SSH encountered an unknown error during the connection. We recommend you re-run the command using -vvvv, which will enable SSH debugging output to help diagnose the issue'
|
output = 'SSH encountered an unknown error during the connection. We recommend you re-run the command using -vvvv, which will enable SSH debugging output to help diagnose the issue'
|
||||||
|
@ -264,8 +258,8 @@ class ActionBase:
|
||||||
split_path = path.split(os.path.sep, 1)
|
split_path = path.split(os.path.sep, 1)
|
||||||
expand_path = split_path[0]
|
expand_path = split_path[0]
|
||||||
if expand_path == '~':
|
if expand_path == '~':
|
||||||
if self._connection_info.become and self._connection_info.become_user:
|
if self._play_context.become and self._play_context.become_user:
|
||||||
expand_path = '~%s' % self._connection_info.become_user
|
expand_path = '~%s' % self._play_context.become_user
|
||||||
|
|
||||||
cmd = self._connection._shell.expand_user(expand_path)
|
cmd = self._connection._shell.expand_user(expand_path)
|
||||||
debug("calling _low_level_execute_command to expand the remote user path")
|
debug("calling _low_level_execute_command to expand the remote user path")
|
||||||
|
@ -314,13 +308,13 @@ class ActionBase:
|
||||||
module_args = self._task.args
|
module_args = self._task.args
|
||||||
|
|
||||||
# set check mode in the module arguments, if required
|
# set check mode in the module arguments, if required
|
||||||
if self._connection_info.check_mode and not self._task.always_run:
|
if self._play_context.check_mode and not self._task.always_run:
|
||||||
if not self._supports_check_mode:
|
if not self._supports_check_mode:
|
||||||
raise AnsibleError("check mode is not supported for this operation")
|
raise AnsibleError("check mode is not supported for this operation")
|
||||||
module_args['_ansible_check_mode'] = True
|
module_args['_ansible_check_mode'] = True
|
||||||
|
|
||||||
# set no log in the module arguments, if required
|
# set no log in the module arguments, if required
|
||||||
if self._connection_info.no_log:
|
if self._play_context.no_log:
|
||||||
module_args['_ansible_no_log'] = True
|
module_args['_ansible_no_log'] = True
|
||||||
|
|
||||||
debug("in _execute_module (%s, %s)" % (module_name, module_args))
|
debug("in _execute_module (%s, %s)" % (module_name, module_args))
|
||||||
|
@ -344,7 +338,7 @@ class ActionBase:
|
||||||
|
|
||||||
environment_string = self._compute_environment_string()
|
environment_string = self._compute_environment_string()
|
||||||
|
|
||||||
if tmp and "tmp" in tmp and self._connection_info.become and self._connection_info.become_user != 'root':
|
if tmp and "tmp" in tmp and self._play_context.become and self._play_context.become_user != 'root':
|
||||||
# deal with possible umask issues once sudo'ed to other user
|
# deal with possible umask issues once sudo'ed to other user
|
||||||
self._remote_chmod(tmp, 'a+r', remote_module_path)
|
self._remote_chmod(tmp, 'a+r', remote_module_path)
|
||||||
|
|
||||||
|
@ -362,7 +356,7 @@ class ActionBase:
|
||||||
|
|
||||||
rm_tmp = None
|
rm_tmp = None
|
||||||
if tmp and "tmp" in tmp and not C.DEFAULT_KEEP_REMOTE_FILES and not persist_files and delete_remote_tmp:
|
if tmp and "tmp" in tmp and not C.DEFAULT_KEEP_REMOTE_FILES and not persist_files and delete_remote_tmp:
|
||||||
if not self._connection_info.become or self._connection_info.become_user == 'root':
|
if not self._play_context.become or self._play_context.become_user == 'root':
|
||||||
# not sudoing or sudoing to root, so can cleanup files in the same step
|
# not sudoing or sudoing to root, so can cleanup files in the same step
|
||||||
rm_tmp = tmp
|
rm_tmp = tmp
|
||||||
|
|
||||||
|
@ -380,7 +374,7 @@ class ActionBase:
|
||||||
debug("_low_level_execute_command returned ok")
|
debug("_low_level_execute_command returned ok")
|
||||||
|
|
||||||
if tmp and "tmp" in tmp and not C.DEFAULT_KEEP_REMOTE_FILES and not persist_files and delete_remote_tmp:
|
if tmp and "tmp" in tmp and not C.DEFAULT_KEEP_REMOTE_FILES and not persist_files and delete_remote_tmp:
|
||||||
if self._connection_info.become and self._connection_info.become_user != 'root':
|
if self._play_context.become and self._play_context.become_user != 'root':
|
||||||
# not sudoing to root, so maybe can't delete files as that other user
|
# not sudoing to root, so maybe can't delete files as that other user
|
||||||
# have to clean up temp files as original user in a second step
|
# have to clean up temp files as original user in a second step
|
||||||
cmd2 = self._connection._shell.remove(tmp, recurse=True)
|
cmd2 = self._connection._shell.remove(tmp, recurse=True)
|
||||||
|
@ -430,7 +424,7 @@ class ActionBase:
|
||||||
return dict(stdout='', stderr='')
|
return dict(stdout='', stderr='')
|
||||||
|
|
||||||
if sudoable:
|
if sudoable:
|
||||||
cmd = self._connection_info.make_become_cmd(cmd, executable=executable)
|
cmd = self._play_context.make_become_cmd(cmd, executable=executable)
|
||||||
|
|
||||||
debug("executing the command %s through the connection" % cmd)
|
debug("executing the command %s through the connection" % cmd)
|
||||||
rc, stdin, stdout, stderr = self._connection.exec_command(cmd, tmp, in_data=in_data, sudoable=sudoable)
|
rc, stdin, stdout, stderr = self._connection.exec_command(cmd, tmp, in_data=in_data, sudoable=sudoable)
|
||||||
|
|
|
@ -31,7 +31,7 @@ class ActionModule(ActionBase):
|
||||||
|
|
||||||
def run(self, tmp=None, task_vars=dict()):
|
def run(self, tmp=None, task_vars=dict()):
|
||||||
|
|
||||||
if self._connection_info.check_mode:
|
if self._play_context.check_mode:
|
||||||
return dict(skipped=True, msg='check mode not supported for this module')
|
return dict(skipped=True, msg='check mode not supported for this module')
|
||||||
|
|
||||||
# Parse out any hostname:port patterns
|
# Parse out any hostname:port patterns
|
||||||
|
|
|
@ -77,7 +77,7 @@ class ActionModule(ActionBase):
|
||||||
|
|
||||||
def run(self, tmp=None, task_vars=dict()):
|
def run(self, tmp=None, task_vars=dict()):
|
||||||
|
|
||||||
if self._connection_info.check_mode:
|
if self._play_context.check_mode:
|
||||||
return dict(skipped=True, msg=("skipped, this module does not support check_mode."))
|
return dict(skipped=True, msg=("skipped, this module does not support check_mode."))
|
||||||
|
|
||||||
src = self._task.args.get('src', None)
|
src = self._task.args.get('src', None)
|
||||||
|
@ -124,7 +124,7 @@ class ActionModule(ActionBase):
|
||||||
xfered = self._transfer_data('src', resultant)
|
xfered = self._transfer_data('src', resultant)
|
||||||
|
|
||||||
# fix file permissions when the copy is done as a different user
|
# fix file permissions when the copy is done as a different user
|
||||||
if self._connection_info.become and self._connection_info.become_user != 'root':
|
if self._play_context.become and self._play_context.become_user != 'root':
|
||||||
self._remote_chmod('a+r', xfered, tmp)
|
self._remote_chmod('a+r', xfered, tmp)
|
||||||
|
|
||||||
# run the copy module
|
# run the copy module
|
||||||
|
|
|
@ -28,7 +28,7 @@ class ActionModule(ActionBase):
|
||||||
def run(self, tmp=None, task_vars=dict()):
|
def run(self, tmp=None, task_vars=dict()):
|
||||||
''' transfer the given module name, plus the async module, then run it '''
|
''' transfer the given module name, plus the async module, then run it '''
|
||||||
|
|
||||||
if self._connection_info.check_mode:
|
if self._play_context.check_mode:
|
||||||
return dict(skipped=True, msg='check mode not supported for this module')
|
return dict(skipped=True, msg='check mode not supported for this module')
|
||||||
|
|
||||||
if not tmp:
|
if not tmp:
|
||||||
|
|
|
@ -179,7 +179,7 @@ class ActionModule(ActionBase):
|
||||||
# diff = {}
|
# diff = {}
|
||||||
diff = {}
|
diff = {}
|
||||||
|
|
||||||
if self._connection_info.check_mode:
|
if self._play_context.check_mode:
|
||||||
self._remove_tempfile_if_content_defined(content, content_tempfile)
|
self._remove_tempfile_if_content_defined(content, content_tempfile)
|
||||||
# FIXME: diff stuff
|
# FIXME: diff stuff
|
||||||
#diffs.append(diff)
|
#diffs.append(diff)
|
||||||
|
@ -199,7 +199,7 @@ class ActionModule(ActionBase):
|
||||||
self._remove_tempfile_if_content_defined(content, content_tempfile)
|
self._remove_tempfile_if_content_defined(content, content_tempfile)
|
||||||
|
|
||||||
# fix file permissions when the copy is done as a different user
|
# fix file permissions when the copy is done as a different user
|
||||||
if self._connection_info.become and self._connection_info.become_user != 'root':
|
if self._play_context.become and self._play_context.become_user != 'root':
|
||||||
self._remote_chmod('a+r', tmp_src, tmp)
|
self._remote_chmod('a+r', tmp_src, tmp)
|
||||||
|
|
||||||
if raw:
|
if raw:
|
||||||
|
|
|
@ -36,7 +36,7 @@ class ActionModule(ActionBase):
|
||||||
def run(self, tmp=None, task_vars=dict()):
|
def run(self, tmp=None, task_vars=dict()):
|
||||||
''' handler for fetch operations '''
|
''' handler for fetch operations '''
|
||||||
|
|
||||||
if self._connection_info.check_mode:
|
if self._play_context.check_mode:
|
||||||
return dict(skipped=True, msg='check mode not (yet) supported for this module')
|
return dict(skipped=True, msg='check mode not (yet) supported for this module')
|
||||||
|
|
||||||
source = self._task.args.get('src', None)
|
source = self._task.args.get('src', None)
|
||||||
|
@ -59,7 +59,7 @@ class ActionModule(ActionBase):
|
||||||
|
|
||||||
# use slurp if sudo and permissions are lacking
|
# use slurp if sudo and permissions are lacking
|
||||||
remote_data = None
|
remote_data = None
|
||||||
if remote_checksum in ('1', '2') or self._connection_info.become:
|
if remote_checksum in ('1', '2') or self._play_context.become:
|
||||||
slurpres = self._execute_module(module_name='slurp', module_args=dict(src=source), task_vars=task_vars, tmp=tmp)
|
slurpres = self._execute_module(module_name='slurp', module_args=dict(src=source), task_vars=task_vars, tmp=tmp)
|
||||||
if slurpres.get('rc') == 0:
|
if slurpres.get('rc') == 0:
|
||||||
if slurpres['encoding'] == 'base64':
|
if slurpres['encoding'] == 'base64':
|
||||||
|
@ -97,7 +97,7 @@ class ActionModule(ActionBase):
|
||||||
if 'inventory_hostname' in task_vars:
|
if 'inventory_hostname' in task_vars:
|
||||||
target_name = task_vars['inventory_hostname']
|
target_name = task_vars['inventory_hostname']
|
||||||
else:
|
else:
|
||||||
target_name = self._connection_info.remote_addr
|
target_name = self._play_context.remote_addr
|
||||||
dest = "%s/%s/%s" % (self._loader.path_dwim(dest), target_name, source_local)
|
dest = "%s/%s/%s" % (self._loader.path_dwim(dest), target_name, source_local)
|
||||||
|
|
||||||
dest = dest.replace("//","/")
|
dest = dest.replace("//","/")
|
||||||
|
|
|
@ -50,8 +50,8 @@ class ActionModule(ActionBase):
|
||||||
tmp_src = self._connection._shell.join_path(tmp, os.path.basename(src))
|
tmp_src = self._connection._shell.join_path(tmp, os.path.basename(src))
|
||||||
self._connection.put_file(src, tmp_src)
|
self._connection.put_file(src, tmp_src)
|
||||||
|
|
||||||
if self._connection_info.become and self._connection_info.become_user != 'root':
|
if self._play_context.become and self._play_context.become_user != 'root':
|
||||||
if not self._connection_info.check_mode:
|
if not self._play_context.check_mode:
|
||||||
self._remote_chmod('a+r', tmp_src, tmp)
|
self._remote_chmod('a+r', tmp_src, tmp)
|
||||||
|
|
||||||
new_module_args = self._task.args.copy()
|
new_module_args = self._task.args.copy()
|
||||||
|
|
|
@ -26,7 +26,7 @@ class ActionModule(ActionBase):
|
||||||
|
|
||||||
def run(self, tmp=None, task_vars=dict()):
|
def run(self, tmp=None, task_vars=dict()):
|
||||||
|
|
||||||
if self._connection_info.check_mode:
|
if self._play_context.check_mode:
|
||||||
# in --check mode, always skip this module execution
|
# in --check mode, always skip this module execution
|
||||||
return dict(skipped=True)
|
return dict(skipped=True)
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ class ActionModule(ActionBase):
|
||||||
def run(self, tmp=None, task_vars=None):
|
def run(self, tmp=None, task_vars=None):
|
||||||
''' handler for file transfer operations '''
|
''' handler for file transfer operations '''
|
||||||
|
|
||||||
if self._connection_info.check_mode:
|
if self._play_context.check_mode:
|
||||||
return dict(skipped=True, msg='check mode not supported for this module')
|
return dict(skipped=True, msg='check mode not supported for this module')
|
||||||
|
|
||||||
if not tmp:
|
if not tmp:
|
||||||
|
@ -73,7 +73,7 @@ class ActionModule(ActionBase):
|
||||||
|
|
||||||
sudoable = True
|
sudoable = True
|
||||||
# set file permissions, more permissive when the copy is done as a different user
|
# set file permissions, more permissive when the copy is done as a different user
|
||||||
if self._connection_info.become and self._connection_info.become_user != 'root':
|
if self._play_context.become and self._play_context.become_user != 'root':
|
||||||
chmod_mode = 'a+rx'
|
chmod_mode = 'a+rx'
|
||||||
sudoable = False
|
sudoable = False
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -52,7 +52,7 @@ class ActionModule(ActionBase):
|
||||||
return path
|
return path
|
||||||
|
|
||||||
def _process_remote(self, host, path, user):
|
def _process_remote(self, host, path, user):
|
||||||
transport = self._connection_info.connection
|
transport = self._play_context.connection
|
||||||
return_data = None
|
return_data = None
|
||||||
if not host in ['127.0.0.1', 'localhost'] or transport != "local":
|
if not host in ['127.0.0.1', 'localhost'] or transport != "local":
|
||||||
if user:
|
if user:
|
||||||
|
@ -71,7 +71,7 @@ class ActionModule(ActionBase):
|
||||||
def run(self, tmp=None, task_vars=dict()):
|
def run(self, tmp=None, task_vars=dict()):
|
||||||
''' generates params and passes them on to the rsync module '''
|
''' generates params and passes them on to the rsync module '''
|
||||||
|
|
||||||
original_transport = task_vars.get('ansible_connection') or self._connection_info.connection
|
original_transport = task_vars.get('ansible_connection') or self._play_context.connection
|
||||||
transport_overridden = False
|
transport_overridden = False
|
||||||
if task_vars.get('delegate_to') is None:
|
if task_vars.get('delegate_to') is None:
|
||||||
task_vars['delegate_to'] = '127.0.0.1'
|
task_vars['delegate_to'] = '127.0.0.1'
|
||||||
|
@ -79,7 +79,7 @@ class ActionModule(ActionBase):
|
||||||
if original_transport != 'local':
|
if original_transport != 'local':
|
||||||
task_vars['ansible_connection'] = 'local'
|
task_vars['ansible_connection'] = 'local'
|
||||||
transport_overridden = True
|
transport_overridden = True
|
||||||
self._connection_info.become = False
|
self._play_context.become = False
|
||||||
|
|
||||||
src = self._task.args.get('src', None)
|
src = self._task.args.get('src', None)
|
||||||
dest = self._task.args.get('dest', None)
|
dest = self._task.args.get('dest', None)
|
||||||
|
@ -130,13 +130,13 @@ class ActionModule(ActionBase):
|
||||||
user = task_vars['hostvars'][conn.delegate].get('ansible_ssh_user')
|
user = task_vars['hostvars'][conn.delegate].get('ansible_ssh_user')
|
||||||
|
|
||||||
if not use_delegate or not user:
|
if not use_delegate or not user:
|
||||||
user = task_vars.get('ansible_ssh_user') or self._connection_info.remote_user
|
user = task_vars.get('ansible_ssh_user') or self._play_context.remote_user
|
||||||
|
|
||||||
if use_delegate:
|
if use_delegate:
|
||||||
# FIXME
|
# FIXME
|
||||||
private_key = task_vars.get('ansible_ssh_private_key_file') or self._connection_info.private_key_file
|
private_key = task_vars.get('ansible_ssh_private_key_file') or self._play_context.private_key_file
|
||||||
else:
|
else:
|
||||||
private_key = task_vars.get('ansible_ssh_private_key_file') or self._connection_info.private_key_file
|
private_key = task_vars.get('ansible_ssh_private_key_file') or self._play_context.private_key_file
|
||||||
|
|
||||||
if private_key is not None:
|
if private_key is not None:
|
||||||
private_key = os.path.expanduser(private_key)
|
private_key = os.path.expanduser(private_key)
|
||||||
|
@ -159,7 +159,7 @@ class ActionModule(ActionBase):
|
||||||
rsync_path = self._task.args.get('rsync_path', None)
|
rsync_path = self._task.args.get('rsync_path', None)
|
||||||
|
|
||||||
# If no rsync_path is set, sudo was originally set, and dest is remote then add 'sudo rsync' argument.
|
# If no rsync_path is set, sudo was originally set, and dest is remote then add 'sudo rsync' argument.
|
||||||
if not rsync_path and transport_overridden and self._connection_info.become and self._connection_info.become_method == 'sudo' and not dest_is_local:
|
if not rsync_path and transport_overridden and self._play_context.become and self._play_context.become_method == 'sudo' and not dest_is_local:
|
||||||
rsync_path = 'sudo rsync'
|
rsync_path = 'sudo rsync'
|
||||||
|
|
||||||
# make sure rsync path is quoted.
|
# make sure rsync path is quoted.
|
||||||
|
|
|
@ -142,7 +142,7 @@ class ActionModule(ActionBase):
|
||||||
xfered = self._transfer_data(self._connection._shell.join_path(tmp, 'source'), resultant)
|
xfered = self._transfer_data(self._connection._shell.join_path(tmp, 'source'), resultant)
|
||||||
|
|
||||||
# fix file permissions when the copy is done as a different user
|
# fix file permissions when the copy is done as a different user
|
||||||
if self._connection_info.become and self._connection_info.become_user != 'root':
|
if self._play_context.become and self._play_context.become_user != 'root':
|
||||||
self._remote_chmod('a+r', xfered, tmp)
|
self._remote_chmod('a+r', xfered, tmp)
|
||||||
|
|
||||||
# run the copy module
|
# run the copy module
|
||||||
|
|
|
@ -78,8 +78,8 @@ class ActionModule(ActionBase):
|
||||||
# handle check mode client side
|
# handle check mode client side
|
||||||
# fix file permissions when the copy is done as a different user
|
# fix file permissions when the copy is done as a different user
|
||||||
if copy:
|
if copy:
|
||||||
if self._connection_info.become and self._connection_info.become_user != 'root':
|
if self._play_context.become and self._play_context.become_user != 'root':
|
||||||
if not self._connection_info.check_mode:
|
if not self._play_context.check_mode:
|
||||||
self._remote_chmod(tmp, 'a+r', tmp_src)
|
self._remote_chmod(tmp, 'a+r', tmp_src)
|
||||||
|
|
||||||
# Build temporary module_args.
|
# Build temporary module_args.
|
||||||
|
|
|
@ -54,7 +54,7 @@ class CallbackBase:
|
||||||
for warning in res['warnings']:
|
for warning in res['warnings']:
|
||||||
self._display.warning(warning)
|
self._display.warning(warning)
|
||||||
|
|
||||||
def set_connection_info(self, conn_info):
|
def set_play_context(self, play_context):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def on_any(self, *args, **kwargs):
|
def on_any(self, *args, **kwargs):
|
||||||
|
|
|
@ -58,14 +58,14 @@ class ConnectionBase(with_metaclass(ABCMeta, object)):
|
||||||
has_pipelining = False
|
has_pipelining = False
|
||||||
become_methods = C.BECOME_METHODS
|
become_methods = C.BECOME_METHODS
|
||||||
|
|
||||||
def __init__(self, connection_info, new_stdin, *args, **kwargs):
|
def __init__(self, play_context, new_stdin, *args, **kwargs):
|
||||||
# All these hasattrs allow subclasses to override these parameters
|
# All these hasattrs allow subclasses to override these parameters
|
||||||
if not hasattr(self, '_connection_info'):
|
if not hasattr(self, '_play_context'):
|
||||||
self._connection_info = connection_info
|
self._play_context = play_context
|
||||||
if not hasattr(self, '_new_stdin'):
|
if not hasattr(self, '_new_stdin'):
|
||||||
self._new_stdin = new_stdin
|
self._new_stdin = new_stdin
|
||||||
if not hasattr(self, '_display'):
|
if not hasattr(self, '_display'):
|
||||||
self._display = Display(verbosity=connection_info.verbosity)
|
self._display = Display(verbosity=play_context.verbosity)
|
||||||
if not hasattr(self, '_connected'):
|
if not hasattr(self, '_connected'):
|
||||||
self._connected = False
|
self._connected = False
|
||||||
|
|
||||||
|
@ -73,8 +73,8 @@ class ConnectionBase(with_metaclass(ABCMeta, object)):
|
||||||
self.prompt = None
|
self.prompt = None
|
||||||
|
|
||||||
# load the shell plugin for this action/connection
|
# load the shell plugin for this action/connection
|
||||||
if connection_info.shell:
|
if play_context.shell:
|
||||||
shell_type = connection_info.shell
|
shell_type = play_context.shell
|
||||||
elif hasattr(self, '_shell_type'):
|
elif hasattr(self, '_shell_type'):
|
||||||
shell_type = getattr(self, '_shell_type')
|
shell_type = getattr(self, '_shell_type')
|
||||||
else:
|
else:
|
||||||
|
@ -87,7 +87,7 @@ class ConnectionBase(with_metaclass(ABCMeta, object)):
|
||||||
def _become_method_supported(self):
|
def _become_method_supported(self):
|
||||||
''' Checks if the current class supports this privilege escalation method '''
|
''' Checks if the current class supports this privilege escalation method '''
|
||||||
|
|
||||||
if self._connection_info.become_method in self.__class__.become_methods:
|
if self._play_context.become_method in self.__class__.become_methods:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
raise AnsibleError("Internal Error: this connection module does not support running commands via %s" % become_method)
|
raise AnsibleError("Internal Error: this connection module does not support running commands via %s" % become_method)
|
||||||
|
@ -113,7 +113,7 @@ class ConnectionBase(with_metaclass(ABCMeta, object)):
|
||||||
"""Connect to the host we've been initialized with"""
|
"""Connect to the host we've been initialized with"""
|
||||||
|
|
||||||
# Check if PE is supported
|
# Check if PE is supported
|
||||||
if self._connection_info.become:
|
if self._play_context.become:
|
||||||
self.__become_method_supported()
|
self.__become_method_supported()
|
||||||
|
|
||||||
@ensure_connect
|
@ensure_connect
|
||||||
|
@ -140,18 +140,18 @@ class ConnectionBase(with_metaclass(ABCMeta, object)):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def check_become_success(self, output):
|
def check_become_success(self, output):
|
||||||
return self._connection_info.success_key in output
|
return self._play_context.success_key in output
|
||||||
|
|
||||||
def check_password_prompt(self, output):
|
def check_password_prompt(self, output):
|
||||||
if self._connection_info.prompt is None:
|
if self._play_context.prompt is None:
|
||||||
return False
|
return False
|
||||||
elif isinstance(self._connection_info.prompt, basestring):
|
elif isinstance(self._play_context.prompt, basestring):
|
||||||
return output.endswith(self._connection_info.prompt)
|
return output.endswith(self._play_context.prompt)
|
||||||
else:
|
else:
|
||||||
return self._connection_info.prompt(output)
|
return self._play_context.prompt(output)
|
||||||
|
|
||||||
def check_incorrect_password(self, output):
|
def check_incorrect_password(self, output):
|
||||||
incorrect_password = gettext.dgettext(self._connection_info.become_method, C.BECOME_ERROR_STRINGS[self._connection_info.become_method])
|
incorrect_password = gettext.dgettext(self._play_context.become_method, C.BECOME_ERROR_STRINGS[self._play_context.become_method])
|
||||||
if incorrect_password in output:
|
if incorrect_password in output:
|
||||||
raise AnsibleError('Incorrect %s password' % self._connection_info.become_method)
|
raise AnsibleError('Incorrect %s password' % self._play_context.become_method)
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ class Connection(ConnectionBase):
|
||||||
''' connect to the local host; nothing to do here '''
|
''' connect to the local host; nothing to do here '''
|
||||||
|
|
||||||
if not self._connected:
|
if not self._connected:
|
||||||
self._display.vvv("ESTABLISH LOCAL CONNECTION FOR USER: {0}".format(self._connection_info.remote_user, host=self._connection_info.remote_addr))
|
self._display.vvv("ESTABLISH LOCAL CONNECTION FOR USER: {0}".format(self._play_context.remote_user, host=self._play_context.remote_addr))
|
||||||
self._connected = True
|
self._connected = True
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ class Connection(ConnectionBase):
|
||||||
raise AnsibleError("Internal Error: this module does not support optimized module pipelining")
|
raise AnsibleError("Internal Error: this module does not support optimized module pipelining")
|
||||||
executable = C.DEFAULT_EXECUTABLE.split()[0] if C.DEFAULT_EXECUTABLE else None
|
executable = C.DEFAULT_EXECUTABLE.split()[0] if C.DEFAULT_EXECUTABLE else None
|
||||||
|
|
||||||
self._display.vvv("{0} EXEC {1}".format(self._connection_info.remote_addr, cmd))
|
self._display.vvv("{0} EXEC {1}".format(self._play_context.remote_addr, cmd))
|
||||||
# FIXME: cwd= needs to be set to the basedir of the playbook
|
# FIXME: cwd= needs to be set to the basedir of the playbook
|
||||||
debug("opening command with Popen()")
|
debug("opening command with Popen()")
|
||||||
p = subprocess.Popen(
|
p = subprocess.Popen(
|
||||||
|
@ -72,13 +72,13 @@ class Connection(ConnectionBase):
|
||||||
)
|
)
|
||||||
debug("done running command with Popen()")
|
debug("done running command with Popen()")
|
||||||
|
|
||||||
if self._connection_info.prompt and self._connection_info.become_pass:
|
if self._play_context.prompt and self._play_context.become_pass:
|
||||||
fcntl.fcntl(p.stdout, fcntl.F_SETFL, fcntl.fcntl(p.stdout, fcntl.F_GETFL) | os.O_NONBLOCK)
|
fcntl.fcntl(p.stdout, fcntl.F_SETFL, fcntl.fcntl(p.stdout, fcntl.F_GETFL) | os.O_NONBLOCK)
|
||||||
fcntl.fcntl(p.stderr, fcntl.F_SETFL, fcntl.fcntl(p.stderr, fcntl.F_GETFL) | os.O_NONBLOCK)
|
fcntl.fcntl(p.stderr, fcntl.F_SETFL, fcntl.fcntl(p.stderr, fcntl.F_GETFL) | os.O_NONBLOCK)
|
||||||
become_output = ''
|
become_output = ''
|
||||||
while not self.check_become_success(become_output) and not self.check_password_prompt(become_output):
|
while not self.check_become_success(become_output) and not self.check_password_prompt(become_output):
|
||||||
|
|
||||||
rfd, wfd, efd = select.select([p.stdout, p.stderr], [], [p.stdout, p.stderr], self._connection_info.timeout)
|
rfd, wfd, efd = select.select([p.stdout, p.stderr], [], [p.stdout, p.stderr], self._play_context.timeout)
|
||||||
if p.stdout in rfd:
|
if p.stdout in rfd:
|
||||||
chunk = p.stdout.read()
|
chunk = p.stdout.read()
|
||||||
elif p.stderr in rfd:
|
elif p.stderr in rfd:
|
||||||
|
@ -91,7 +91,7 @@ class Connection(ConnectionBase):
|
||||||
raise AnsibleError('privilege output closed while waiting for password prompt:\n' + become_output)
|
raise AnsibleError('privilege output closed while waiting for password prompt:\n' + become_output)
|
||||||
become_output += chunk
|
become_output += chunk
|
||||||
if not self.check_become_success(become_output):
|
if not self.check_become_success(become_output):
|
||||||
p.stdin.write(self._connection_info.become_pass + '\n')
|
p.stdin.write(self._play_context.become_pass + '\n')
|
||||||
fcntl.fcntl(p.stdout, fcntl.F_SETFL, fcntl.fcntl(p.stdout, fcntl.F_GETFL) & ~os.O_NONBLOCK)
|
fcntl.fcntl(p.stdout, fcntl.F_SETFL, fcntl.fcntl(p.stdout, fcntl.F_GETFL) & ~os.O_NONBLOCK)
|
||||||
fcntl.fcntl(p.stderr, fcntl.F_SETFL, fcntl.fcntl(p.stderr, fcntl.F_GETFL) & ~os.O_NONBLOCK)
|
fcntl.fcntl(p.stderr, fcntl.F_SETFL, fcntl.fcntl(p.stderr, fcntl.F_GETFL) & ~os.O_NONBLOCK)
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ class Connection(ConnectionBase):
|
||||||
|
|
||||||
super(Connection, self).put_file(in_path, out_path)
|
super(Connection, self).put_file(in_path, out_path)
|
||||||
|
|
||||||
self._display.vvv("{0} PUT {1} TO {2}".format(self._connection_info.remote_addr, in_path, out_path))
|
self._display.vvv("{0} PUT {1} TO {2}".format(self._play_context.remote_addr, in_path, out_path))
|
||||||
if not os.path.exists(in_path):
|
if not os.path.exists(in_path):
|
||||||
raise AnsibleFileNotFound("file or module does not exist: {0}".format(in_path))
|
raise AnsibleFileNotFound("file or module does not exist: {0}".format(in_path))
|
||||||
try:
|
try:
|
||||||
|
@ -124,7 +124,7 @@ class Connection(ConnectionBase):
|
||||||
|
|
||||||
super(Connection, self).fetch_file(in_path, out_path)
|
super(Connection, self).fetch_file(in_path, out_path)
|
||||||
|
|
||||||
self._display.vvv("{0} FETCH {1} TO {2}".format(self._connection_info.remote_addr, in_path, out_path))
|
self._display.vvv("{0} FETCH {1} TO {2}".format(self._play_context.remote_addr, in_path, out_path))
|
||||||
self.put_file(in_path, out_path)
|
self.put_file(in_path, out_path)
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
|
|
|
@ -129,7 +129,7 @@ class Connection(ConnectionBase):
|
||||||
return 'paramiko'
|
return 'paramiko'
|
||||||
|
|
||||||
def _cache_key(self):
|
def _cache_key(self):
|
||||||
return "%s__%s__" % (self._connection_info.remote_addr, self._connection_info.remote_user)
|
return "%s__%s__" % (self._play_context.remote_addr, self._play_context.remote_user)
|
||||||
|
|
||||||
def _connect(self):
|
def _connect(self):
|
||||||
cache_key = self._cache_key()
|
cache_key = self._cache_key()
|
||||||
|
@ -145,8 +145,8 @@ class Connection(ConnectionBase):
|
||||||
if not HAVE_PARAMIKO:
|
if not HAVE_PARAMIKO:
|
||||||
raise AnsibleError("paramiko is not installed")
|
raise AnsibleError("paramiko is not installed")
|
||||||
|
|
||||||
port = self._connection_info.port or 22
|
port = self._play_context.port or 22
|
||||||
self._display.vvv("ESTABLISH CONNECTION FOR USER: %s on PORT %s TO %s" % (self._connection_info.remote_user, port, self._connection_info.remote_addr), host=self._connection_info.remote_addr)
|
self._display.vvv("ESTABLISH CONNECTION FOR USER: %s on PORT %s TO %s" % (self._play_context.remote_user, port, self._play_context.remote_addr), host=self._play_context.remote_addr)
|
||||||
|
|
||||||
ssh = paramiko.SSHClient()
|
ssh = paramiko.SSHClient()
|
||||||
|
|
||||||
|
@ -159,22 +159,22 @@ class Connection(ConnectionBase):
|
||||||
|
|
||||||
allow_agent = True
|
allow_agent = True
|
||||||
|
|
||||||
if self._connection_info.password is not None:
|
if self._play_context.password is not None:
|
||||||
allow_agent = False
|
allow_agent = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
key_filename = None
|
key_filename = None
|
||||||
if self._connection_info.private_key_file:
|
if self._play_context.private_key_file:
|
||||||
key_filename = os.path.expanduser(self._connection_info.private_key_file)
|
key_filename = os.path.expanduser(self._play_context.private_key_file)
|
||||||
|
|
||||||
ssh.connect(
|
ssh.connect(
|
||||||
self._connection_info.remote_addr,
|
self._play_context.remote_addr,
|
||||||
username=self._connection_info.remote_user,
|
username=self._play_context.remote_user,
|
||||||
allow_agent=allow_agent,
|
allow_agent=allow_agent,
|
||||||
look_for_keys=True,
|
look_for_keys=True,
|
||||||
key_filename=key_filename,
|
key_filename=key_filename,
|
||||||
password=self._connection_info.password,
|
password=self._play_context.password,
|
||||||
timeout=self._connection_info.timeout,
|
timeout=self._play_context.timeout,
|
||||||
port=port,
|
port=port,
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -183,7 +183,7 @@ class Connection(ConnectionBase):
|
||||||
raise AnsibleError("paramiko version issue, please upgrade paramiko on the machine running ansible")
|
raise AnsibleError("paramiko version issue, please upgrade paramiko on the machine running ansible")
|
||||||
elif "Private key file is encrypted" in msg:
|
elif "Private key file is encrypted" in msg:
|
||||||
msg = 'ssh %s@%s:%s : %s\nTo connect as a different user, use -u <username>.' % (
|
msg = 'ssh %s@%s:%s : %s\nTo connect as a different user, use -u <username>.' % (
|
||||||
self._connection_info.remote_user, self._connection_info.remote_addr, port, msg)
|
self._play_context.remote_user, self._play_context.remote_addr, port, msg)
|
||||||
raise AnsibleConnectionFailure(msg)
|
raise AnsibleConnectionFailure(msg)
|
||||||
else:
|
else:
|
||||||
raise AnsibleConnectionFailure(msg)
|
raise AnsibleConnectionFailure(msg)
|
||||||
|
@ -215,7 +215,7 @@ class Connection(ConnectionBase):
|
||||||
if C.PARAMIKO_PTY:
|
if C.PARAMIKO_PTY:
|
||||||
chan.get_pty(term=os.getenv('TERM', 'vt100'), width=int(os.getenv('COLUMNS', 0)), height=int(os.getenv('LINES', 0)))
|
chan.get_pty(term=os.getenv('TERM', 'vt100'), width=int(os.getenv('COLUMNS', 0)), height=int(os.getenv('LINES', 0)))
|
||||||
|
|
||||||
self._display.vvv("EXEC %s" % cmd, host=self._connection_info.remote_addr)
|
self._display.vvv("EXEC %s" % cmd, host=self._play_context.remote_addr)
|
||||||
|
|
||||||
no_prompt_out = ''
|
no_prompt_out = ''
|
||||||
no_prompt_err = ''
|
no_prompt_err = ''
|
||||||
|
@ -223,8 +223,8 @@ class Connection(ConnectionBase):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
chan.exec_command(cmd)
|
chan.exec_command(cmd)
|
||||||
if self._connection_info.prompt:
|
if self._play_context.prompt:
|
||||||
if self._connection_info.become and self._connection_info.become_pass:
|
if self._play_context.become and self._play_context.become_pass:
|
||||||
while True:
|
while True:
|
||||||
debug('Waiting for Privilege Escalation input')
|
debug('Waiting for Privilege Escalation input')
|
||||||
if self.check_become_success(become_output) or self.check_password_prompt(become_output):
|
if self.check_become_success(become_output) or self.check_password_prompt(become_output):
|
||||||
|
@ -240,8 +240,8 @@ class Connection(ConnectionBase):
|
||||||
'closed waiting for password prompt')
|
'closed waiting for password prompt')
|
||||||
become_output += chunk
|
become_output += chunk
|
||||||
if not self.check_become_success(become_output):
|
if not self.check_become_success(become_output):
|
||||||
if self._connection_info.become:
|
if self._play_context.become:
|
||||||
chan.sendall(self._connection_info.become_pass + '\n')
|
chan.sendall(self._play_context.become_pass + '\n')
|
||||||
else:
|
else:
|
||||||
no_prompt_out += become_output
|
no_prompt_out += become_output
|
||||||
no_prompt_err += become_output
|
no_prompt_err += become_output
|
||||||
|
@ -258,7 +258,7 @@ class Connection(ConnectionBase):
|
||||||
|
|
||||||
super(Connection, self).put_file(in_path, out_path)
|
super(Connection, self).put_file(in_path, out_path)
|
||||||
|
|
||||||
self._display.vvv("PUT %s TO %s" % (in_path, out_path), host=self._connection_info.remote_addr)
|
self._display.vvv("PUT %s TO %s" % (in_path, out_path), host=self._play_context.remote_addr)
|
||||||
|
|
||||||
if not os.path.exists(in_path):
|
if not os.path.exists(in_path):
|
||||||
raise AnsibleFileNotFound("file or module does not exist: %s" % in_path)
|
raise AnsibleFileNotFound("file or module does not exist: %s" % in_path)
|
||||||
|
@ -275,7 +275,7 @@ class Connection(ConnectionBase):
|
||||||
|
|
||||||
def _connect_sftp(self):
|
def _connect_sftp(self):
|
||||||
|
|
||||||
cache_key = "%s__%s__" % (self._connection_info.remote_addr, self._connection_info.remote_user)
|
cache_key = "%s__%s__" % (self._play_context.remote_addr, self._play_context.remote_user)
|
||||||
if cache_key in SFTP_CONNECTION_CACHE:
|
if cache_key in SFTP_CONNECTION_CACHE:
|
||||||
return SFTP_CONNECTION_CACHE[cache_key]
|
return SFTP_CONNECTION_CACHE[cache_key]
|
||||||
else:
|
else:
|
||||||
|
@ -287,7 +287,7 @@ class Connection(ConnectionBase):
|
||||||
|
|
||||||
super(Connection, self).fetch_file(in_path, out_path)
|
super(Connection, self).fetch_file(in_path, out_path)
|
||||||
|
|
||||||
self._display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self._connection_info.remote_addr)
|
self._display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self._play_context.remote_addr)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.sftp = self._connect_sftp()
|
self.sftp = self._connect_sftp()
|
||||||
|
|
|
@ -60,7 +60,7 @@ class Connection(ConnectionBase):
|
||||||
|
|
||||||
# FIXME: make this work, should be set from connection info
|
# FIXME: make this work, should be set from connection info
|
||||||
self._ipv6 = False
|
self._ipv6 = False
|
||||||
self.host = self._connection_info.remote_addr
|
self.host = self._play_context.remote_addr
|
||||||
if self._ipv6:
|
if self._ipv6:
|
||||||
self.host = '[%s]' % self.host
|
self.host = '[%s]' % self.host
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ class Connection(ConnectionBase):
|
||||||
def _connect(self):
|
def _connect(self):
|
||||||
''' connect to the remote host '''
|
''' connect to the remote host '''
|
||||||
|
|
||||||
self._display.vvv("ESTABLISH SSH CONNECTION FOR USER: {0}".format(self._connection_info.remote_user), host=self._connection_info.remote_addr)
|
self._display.vvv("ESTABLISH SSH CONNECTION FOR USER: {0}".format(self._play_context.remote_user), host=self._play_context.remote_addr)
|
||||||
|
|
||||||
if self._connected:
|
if self._connected:
|
||||||
return self
|
return self
|
||||||
|
@ -104,20 +104,20 @@ class Connection(ConnectionBase):
|
||||||
if not C.HOST_KEY_CHECKING:
|
if not C.HOST_KEY_CHECKING:
|
||||||
self._common_args += ("-o", "StrictHostKeyChecking=no")
|
self._common_args += ("-o", "StrictHostKeyChecking=no")
|
||||||
|
|
||||||
if self._connection_info.port is not None:
|
if self._play_context.port is not None:
|
||||||
self._common_args += ("-o", "Port={0}".format(self._connection_info.port))
|
self._common_args += ("-o", "Port={0}".format(self._play_context.port))
|
||||||
if self._connection_info.private_key_file is not None:
|
if self._play_context.private_key_file is not None:
|
||||||
self._common_args += ("-o", "IdentityFile=\"{0}\"".format(os.path.expanduser(self._connection_info.private_key_file)))
|
self._common_args += ("-o", "IdentityFile=\"{0}\"".format(os.path.expanduser(self._play_context.private_key_file)))
|
||||||
if self._connection_info.password:
|
if self._play_context.password:
|
||||||
self._common_args += ("-o", "GSSAPIAuthentication=no",
|
self._common_args += ("-o", "GSSAPIAuthentication=no",
|
||||||
"-o", "PubkeyAuthentication=no")
|
"-o", "PubkeyAuthentication=no")
|
||||||
else:
|
else:
|
||||||
self._common_args += ("-o", "KbdInteractiveAuthentication=no",
|
self._common_args += ("-o", "KbdInteractiveAuthentication=no",
|
||||||
"-o", "PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey",
|
"-o", "PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey",
|
||||||
"-o", "PasswordAuthentication=no")
|
"-o", "PasswordAuthentication=no")
|
||||||
if self._connection_info.remote_user is not None and self._connection_info.remote_user != pwd.getpwuid(os.geteuid())[0]:
|
if self._play_context.remote_user is not None and self._play_context.remote_user != pwd.getpwuid(os.geteuid())[0]:
|
||||||
self._common_args += ("-o", "User={0}".format(self._connection_info.remote_user))
|
self._common_args += ("-o", "User={0}".format(self._play_context.remote_user))
|
||||||
self._common_args += ("-o", "ConnectTimeout={0}".format(self._connection_info.timeout))
|
self._common_args += ("-o", "ConnectTimeout={0}".format(self._play_context.timeout))
|
||||||
|
|
||||||
self._connected = True
|
self._connected = True
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ class Connection(ConnectionBase):
|
||||||
return (p, stdin)
|
return (p, stdin)
|
||||||
|
|
||||||
def _password_cmd(self):
|
def _password_cmd(self):
|
||||||
if self._connection_info.password:
|
if self._play_context.password:
|
||||||
try:
|
try:
|
||||||
p = subprocess.Popen(["sshpass"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
p = subprocess.Popen(["sshpass"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
p.communicate()
|
p.communicate()
|
||||||
|
@ -154,9 +154,9 @@ class Connection(ConnectionBase):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def _send_password(self):
|
def _send_password(self):
|
||||||
if self._connection_info.password:
|
if self._play_context.password:
|
||||||
os.close(self.rfd)
|
os.close(self.rfd)
|
||||||
os.write(self.wfd, "{0}\n".format(self._connection_info.password))
|
os.write(self.wfd, "{0}\n".format(self._play_context.password))
|
||||||
os.close(self.wfd)
|
os.close(self.wfd)
|
||||||
|
|
||||||
def _communicate(self, p, stdin, indata, sudoable=True):
|
def _communicate(self, p, stdin, indata, sudoable=True):
|
||||||
|
@ -177,11 +177,11 @@ class Connection(ConnectionBase):
|
||||||
rfd, wfd, efd = select.select(rpipes, [], rpipes, 1)
|
rfd, wfd, efd = select.select(rpipes, [], rpipes, 1)
|
||||||
|
|
||||||
# fail early if the become password is wrong
|
# fail early if the become password is wrong
|
||||||
if self._connection_info.become and sudoable:
|
if self._play_context.become and sudoable:
|
||||||
if self._connection_info.become_pass:
|
if self._play_context.become_pass:
|
||||||
self.check_incorrect_password(stdout)
|
self.check_incorrect_password(stdout)
|
||||||
elif self.check_password_prompt(stdout):
|
elif self.check_password_prompt(stdout):
|
||||||
raise AnsibleError('Missing %s password' % self._connection_info.become_method)
|
raise AnsibleError('Missing %s password' % self._play_context.become_method)
|
||||||
|
|
||||||
if p.stderr in rfd:
|
if p.stderr in rfd:
|
||||||
dat = os.read(p.stderr.fileno(), 9000)
|
dat = os.read(p.stderr.fileno(), 9000)
|
||||||
|
@ -335,7 +335,7 @@ class Connection(ConnectionBase):
|
||||||
# inside a tty automatically invokes the python interactive-mode but the modules are not
|
# inside a tty automatically invokes the python interactive-mode but the modules are not
|
||||||
# compatible with the interactive-mode ("unexpected indent" mainly because of empty lines)
|
# compatible with the interactive-mode ("unexpected indent" mainly because of empty lines)
|
||||||
ssh_cmd.append("-tt")
|
ssh_cmd.append("-tt")
|
||||||
if self._connection_info.verbosity > 3:
|
if self._play_context.verbosity > 3:
|
||||||
ssh_cmd.append("-vvv")
|
ssh_cmd.append("-vvv")
|
||||||
else:
|
else:
|
||||||
ssh_cmd.append("-q")
|
ssh_cmd.append("-q")
|
||||||
|
@ -358,7 +358,7 @@ class Connection(ConnectionBase):
|
||||||
no_prompt_out = ''
|
no_prompt_out = ''
|
||||||
no_prompt_err = ''
|
no_prompt_err = ''
|
||||||
|
|
||||||
if self._connection_info.prompt:
|
if self._play_context.prompt:
|
||||||
'''
|
'''
|
||||||
Several cases are handled for privileges with password
|
Several cases are handled for privileges with password
|
||||||
* NOPASSWD (tty & no-tty): detect success_key on stdout
|
* NOPASSWD (tty & no-tty): detect success_key on stdout
|
||||||
|
@ -369,7 +369,7 @@ class Connection(ConnectionBase):
|
||||||
|
|
||||||
debug("Handling privilege escalation password prompt.")
|
debug("Handling privilege escalation password prompt.")
|
||||||
|
|
||||||
if self._connection_info.become and self._connection_info.become_pass:
|
if self._play_context.become and self._play_context.become_pass:
|
||||||
|
|
||||||
fcntl.fcntl(p.stdout, fcntl.F_SETFL, fcntl.fcntl(p.stdout, fcntl.F_GETFL) | os.O_NONBLOCK)
|
fcntl.fcntl(p.stdout, fcntl.F_SETFL, fcntl.fcntl(p.stdout, fcntl.F_GETFL) | os.O_NONBLOCK)
|
||||||
fcntl.fcntl(p.stderr, fcntl.F_SETFL, fcntl.fcntl(p.stderr, fcntl.F_GETFL) | os.O_NONBLOCK)
|
fcntl.fcntl(p.stderr, fcntl.F_SETFL, fcntl.fcntl(p.stderr, fcntl.F_GETFL) | os.O_NONBLOCK)
|
||||||
|
@ -381,7 +381,7 @@ class Connection(ConnectionBase):
|
||||||
if self.check_become_success(become_output) or self.check_password_prompt(become_output):
|
if self.check_become_success(become_output) or self.check_password_prompt(become_output):
|
||||||
break
|
break
|
||||||
|
|
||||||
rfd, wfd, efd = select.select([p.stdout, p.stderr], [], [p.stdout], self._connection_info.timeout)
|
rfd, wfd, efd = select.select([p.stdout, p.stderr], [], [p.stdout], self._play_context.timeout)
|
||||||
if not rfd:
|
if not rfd:
|
||||||
# timeout. wrap up process communication
|
# timeout. wrap up process communication
|
||||||
stdout, stderr = p.communicate()
|
stdout, stderr = p.communicate()
|
||||||
|
@ -401,7 +401,7 @@ class Connection(ConnectionBase):
|
||||||
|
|
||||||
if not self.check_become_success(become_output):
|
if not self.check_become_success(become_output):
|
||||||
debug("Sending privilege escalation password.")
|
debug("Sending privilege escalation password.")
|
||||||
stdin.write(self._connection_info.become_pass + '\n')
|
stdin.write(self._play_context.become_pass + '\n')
|
||||||
else:
|
else:
|
||||||
no_prompt_out = become_output
|
no_prompt_out = become_output
|
||||||
no_prompt_err = become_errput
|
no_prompt_err = become_errput
|
||||||
|
@ -491,7 +491,7 @@ class Connection(ConnectionBase):
|
||||||
if 'ControlMaster' in self._common_args:
|
if 'ControlMaster' in self._common_args:
|
||||||
cmd = ['ssh','-O','stop']
|
cmd = ['ssh','-O','stop']
|
||||||
cmd.extend(self._common_args)
|
cmd.extend(self._common_args)
|
||||||
cmd.append(self._connection_info.remote_addr)
|
cmd.append(self._play_context.remote_addr)
|
||||||
|
|
||||||
p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
stdout, stderr = p.communicate()
|
stdout, stderr = p.communicate()
|
||||||
|
|
|
@ -78,28 +78,28 @@ class Connection(ConnectionBase):
|
||||||
'''
|
'''
|
||||||
Establish a WinRM connection over HTTP/HTTPS.
|
Establish a WinRM connection over HTTP/HTTPS.
|
||||||
'''
|
'''
|
||||||
port = self._connection_info.port or 5986
|
port = self._play_context.port or 5986
|
||||||
self._display.vvv("ESTABLISH WINRM CONNECTION FOR USER: %s on PORT %s TO %s" % \
|
self._display.vvv("ESTABLISH WINRM CONNECTION FOR USER: %s on PORT %s TO %s" % \
|
||||||
(self._connection_info.remote_user, port, self._connection_info.remote_addr), host=self._connection_info.remote_addr)
|
(self._play_context.remote_user, port, self._play_context.remote_addr), host=self._play_context.remote_addr)
|
||||||
netloc = '%s:%d' % (self._connection_info.remote_addr, port)
|
netloc = '%s:%d' % (self._play_context.remote_addr, port)
|
||||||
exc = None
|
exc = None
|
||||||
for transport, scheme in self.transport_schemes['http' if port == 5985 else 'https']:
|
for transport, scheme in self.transport_schemes['http' if port == 5985 else 'https']:
|
||||||
if transport == 'kerberos' and (not HAVE_KERBEROS or not '@' in self._connection_info.remote_user):
|
if transport == 'kerberos' and (not HAVE_KERBEROS or not '@' in self._play_context.remote_user):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if transport == 'kerberos':
|
if transport == 'kerberos':
|
||||||
realm = self._connection_info.remote_user.split('@', 1)[1].strip() or None
|
realm = self._play_context.remote_user.split('@', 1)[1].strip() or None
|
||||||
else:
|
else:
|
||||||
realm = None
|
realm = None
|
||||||
|
|
||||||
endpoint = parse.urlunsplit((scheme, netloc, '/wsman', '', ''))
|
endpoint = parse.urlunsplit((scheme, netloc, '/wsman', '', ''))
|
||||||
|
|
||||||
self._display.vvvvv('WINRM CONNECT: transport=%s endpoint=%s' % (transport, endpoint), host=self._connection_info.remote_addr)
|
self._display.vvvvv('WINRM CONNECT: transport=%s endpoint=%s' % (transport, endpoint), host=self._play_context.remote_addr)
|
||||||
protocol = Protocol(
|
protocol = Protocol(
|
||||||
endpoint,
|
endpoint,
|
||||||
transport=transport,
|
transport=transport,
|
||||||
username=self._connection_info.remote_user,
|
username=self._play_context.remote_user,
|
||||||
password=self._connection_info.password,
|
password=self._play_context.password,
|
||||||
realm=realm
|
realm=realm
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -117,16 +117,16 @@ class Connection(ConnectionBase):
|
||||||
raise AnsibleError("the username/password specified for this server was incorrect")
|
raise AnsibleError("the username/password specified for this server was incorrect")
|
||||||
elif code == 411:
|
elif code == 411:
|
||||||
return protocol
|
return protocol
|
||||||
self._display.vvvvv('WINRM CONNECTION ERROR: %s' % err_msg, host=self._connection_info.remote_addr)
|
self._display.vvvvv('WINRM CONNECTION ERROR: %s' % err_msg, host=self._play_context.remote_addr)
|
||||||
continue
|
continue
|
||||||
if exc:
|
if exc:
|
||||||
raise AnsibleError(str(exc))
|
raise AnsibleError(str(exc))
|
||||||
|
|
||||||
def _winrm_exec(self, command, args=(), from_exec=False):
|
def _winrm_exec(self, command, args=(), from_exec=False):
|
||||||
if from_exec:
|
if from_exec:
|
||||||
self._display.vvvvv("WINRM EXEC %r %r" % (command, args), host=self._connection_info.remote_addr)
|
self._display.vvvvv("WINRM EXEC %r %r" % (command, args), host=self._play_context.remote_addr)
|
||||||
else:
|
else:
|
||||||
self._display.vvvvvv("WINRM EXEC %r %r" % (command, args), host=self._connection_info.remote_addr)
|
self._display.vvvvvv("WINRM EXEC %r %r" % (command, args), host=self._play_context.remote_addr)
|
||||||
if not self.protocol:
|
if not self.protocol:
|
||||||
self.protocol = self._winrm_connect()
|
self.protocol = self._winrm_connect()
|
||||||
if not self.shell_id:
|
if not self.shell_id:
|
||||||
|
@ -136,11 +136,11 @@ class Connection(ConnectionBase):
|
||||||
command_id = self.protocol.run_command(self.shell_id, command, args)
|
command_id = self.protocol.run_command(self.shell_id, command, args)
|
||||||
response = Response(self.protocol.get_command_output(self.shell_id, command_id))
|
response = Response(self.protocol.get_command_output(self.shell_id, command_id))
|
||||||
if from_exec:
|
if from_exec:
|
||||||
self._display.vvvvv('WINRM RESULT %r' % response, host=self._connection_info.remote_addr)
|
self._display.vvvvv('WINRM RESULT %r' % response, host=self._play_context.remote_addr)
|
||||||
else:
|
else:
|
||||||
self._display.vvvvvv('WINRM RESULT %r' % response, host=self._connection_info.remote_addr)
|
self._display.vvvvvv('WINRM RESULT %r' % response, host=self._play_context.remote_addr)
|
||||||
self._display.vvvvvv('WINRM STDOUT %s' % response.std_out, host=self._connection_info.remote_addr)
|
self._display.vvvvvv('WINRM STDOUT %s' % response.std_out, host=self._play_context.remote_addr)
|
||||||
self._display.vvvvvv('WINRM STDERR %s' % response.std_err, host=self._connection_info.remote_addr)
|
self._display.vvvvvv('WINRM STDERR %s' % response.std_err, host=self._play_context.remote_addr)
|
||||||
return response
|
return response
|
||||||
finally:
|
finally:
|
||||||
if command_id:
|
if command_id:
|
||||||
|
@ -159,9 +159,9 @@ class Connection(ConnectionBase):
|
||||||
if '-EncodedCommand' in cmd_parts:
|
if '-EncodedCommand' in cmd_parts:
|
||||||
encoded_cmd = cmd_parts[cmd_parts.index('-EncodedCommand') + 1]
|
encoded_cmd = cmd_parts[cmd_parts.index('-EncodedCommand') + 1]
|
||||||
decoded_cmd = base64.b64decode(encoded_cmd)
|
decoded_cmd = base64.b64decode(encoded_cmd)
|
||||||
self._display.vvv("EXEC %s" % decoded_cmd, host=self._connection_info.remote_addr)
|
self._display.vvv("EXEC %s" % decoded_cmd, host=self._play_context.remote_addr)
|
||||||
else:
|
else:
|
||||||
self._display.vvv("EXEC %s" % cmd, host=self._connection_info.remote_addr)
|
self._display.vvv("EXEC %s" % cmd, host=self._play_context.remote_addr)
|
||||||
# For script/raw support.
|
# For script/raw support.
|
||||||
if cmd_parts and cmd_parts[0].lower().endswith('.ps1'):
|
if cmd_parts and cmd_parts[0].lower().endswith('.ps1'):
|
||||||
script = self._shell._build_file_cmd(cmd_parts, quote_args=False)
|
script = self._shell._build_file_cmd(cmd_parts, quote_args=False)
|
||||||
|
@ -178,7 +178,7 @@ class Connection(ConnectionBase):
|
||||||
def put_file(self, in_path, out_path):
|
def put_file(self, in_path, out_path):
|
||||||
super(Connection, self).put_file(in_path, out_path)
|
super(Connection, self).put_file(in_path, out_path)
|
||||||
|
|
||||||
self._display.vvv("PUT %s TO %s" % (in_path, out_path), host=self._connection_info.remote_addr)
|
self._display.vvv("PUT %s TO %s" % (in_path, out_path), host=self._play_context.remote_addr)
|
||||||
if not os.path.exists(in_path):
|
if not os.path.exists(in_path):
|
||||||
raise AnsibleFileNotFound("file or module does not exist: %s" % in_path)
|
raise AnsibleFileNotFound("file or module does not exist: %s" % in_path)
|
||||||
with open(in_path) as in_file:
|
with open(in_path) as in_file:
|
||||||
|
@ -206,7 +206,7 @@ class Connection(ConnectionBase):
|
||||||
out_path = out_path + '.ps1'
|
out_path = out_path + '.ps1'
|
||||||
b64_data = base64.b64encode(out_data)
|
b64_data = base64.b64encode(out_data)
|
||||||
script = script_template % (self._shell._escape(out_path), offset, b64_data, in_size)
|
script = script_template % (self._shell._escape(out_path), offset, b64_data, in_size)
|
||||||
self._display.vvvvv("WINRM PUT %s to %s (offset=%d size=%d)" % (in_path, out_path, offset, len(out_data)), host=self._connection_info.remote_addr)
|
self._display.vvvvv("WINRM PUT %s to %s (offset=%d size=%d)" % (in_path, out_path, offset, len(out_data)), host=self._play_context.remote_addr)
|
||||||
cmd_parts = self._shell._encode_script(script, as_list=True)
|
cmd_parts = self._shell._encode_script(script, as_list=True)
|
||||||
result = self._winrm_exec(cmd_parts[0], cmd_parts[1:])
|
result = self._winrm_exec(cmd_parts[0], cmd_parts[1:])
|
||||||
if result.status_code != 0:
|
if result.status_code != 0:
|
||||||
|
@ -219,7 +219,7 @@ class Connection(ConnectionBase):
|
||||||
super(Connection, self).fetch_file(in_path, out_path)
|
super(Connection, self).fetch_file(in_path, out_path)
|
||||||
|
|
||||||
out_path = out_path.replace('\\', '/')
|
out_path = out_path.replace('\\', '/')
|
||||||
self._display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self._connection_info.remote_addr)
|
self._display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self._play_context.remote_addr)
|
||||||
buffer_size = 2**19 # 0.5MB chunks
|
buffer_size = 2**19 # 0.5MB chunks
|
||||||
makedirs_safe(os.path.dirname(out_path))
|
makedirs_safe(os.path.dirname(out_path))
|
||||||
out_file = None
|
out_file = None
|
||||||
|
@ -248,7 +248,7 @@ class Connection(ConnectionBase):
|
||||||
Exit 1;
|
Exit 1;
|
||||||
}
|
}
|
||||||
''' % dict(buffer_size=buffer_size, path=self._shell._escape(in_path), offset=offset)
|
''' % dict(buffer_size=buffer_size, path=self._shell._escape(in_path), offset=offset)
|
||||||
self._display.vvvvv("WINRM FETCH %s to %s (offset=%d)" % (in_path, out_path, offset), host=self._connection_info.remote_addr)
|
self._display.vvvvv("WINRM FETCH %s to %s (offset=%d)" % (in_path, out_path, offset), host=self._play_context.remote_addr)
|
||||||
cmd_parts = self._shell._encode_script(script, as_list=True)
|
cmd_parts = self._shell._encode_script(script, as_list=True)
|
||||||
result = self._winrm_exec(cmd_parts[0], cmd_parts[1:])
|
result = self._winrm_exec(cmd_parts[0], cmd_parts[1:])
|
||||||
if result.status_code != 0:
|
if result.status_code != 0:
|
||||||
|
|
|
@ -74,14 +74,14 @@ class StrategyBase:
|
||||||
# outstanding tasks still in queue
|
# outstanding tasks still in queue
|
||||||
self._blocked_hosts = dict()
|
self._blocked_hosts = dict()
|
||||||
|
|
||||||
def run(self, iterator, connection_info, result=True):
|
def run(self, iterator, play_context, result=True):
|
||||||
# save the failed/unreachable hosts, as the run_handlers()
|
# save the failed/unreachable hosts, as the run_handlers()
|
||||||
# method will clear that information during its execution
|
# method will clear that information during its execution
|
||||||
failed_hosts = self._tqm._failed_hosts.keys()
|
failed_hosts = self._tqm._failed_hosts.keys()
|
||||||
unreachable_hosts = self._tqm._unreachable_hosts.keys()
|
unreachable_hosts = self._tqm._unreachable_hosts.keys()
|
||||||
|
|
||||||
debug("running handlers")
|
debug("running handlers")
|
||||||
result &= self.run_handlers(iterator, connection_info)
|
result &= self.run_handlers(iterator, play_context)
|
||||||
|
|
||||||
# now update with the hosts (if any) that failed or were
|
# now update with the hosts (if any) that failed or were
|
||||||
# unreachable during the handler execution phase
|
# unreachable during the handler execution phase
|
||||||
|
@ -117,7 +117,7 @@ class StrategyBase:
|
||||||
new_vars['ansible_failed_hosts'] = self.get_failed_hosts(play)
|
new_vars['ansible_failed_hosts'] = self.get_failed_hosts(play)
|
||||||
return new_vars
|
return new_vars
|
||||||
|
|
||||||
def _queue_task(self, host, task, task_vars, connection_info):
|
def _queue_task(self, host, task, task_vars, play_context):
|
||||||
''' handles queueing the task up to be sent to a worker '''
|
''' handles queueing the task up to be sent to a worker '''
|
||||||
|
|
||||||
debug("entering _queue_task() for %s/%s" % (host, task))
|
debug("entering _queue_task() for %s/%s" % (host, task))
|
||||||
|
@ -136,7 +136,7 @@ class StrategyBase:
|
||||||
# way to share them with the forked processes
|
# way to share them with the forked processes
|
||||||
shared_loader_obj = SharedPluginLoaderObj()
|
shared_loader_obj = SharedPluginLoaderObj()
|
||||||
|
|
||||||
main_q.put((host, task, self._loader.get_basedir(), task_vars, connection_info, shared_loader_obj), block=False)
|
main_q.put((host, task, self._loader.get_basedir(), task_vars, play_context, shared_loader_obj), block=False)
|
||||||
self._pending_results += 1
|
self._pending_results += 1
|
||||||
except (EOFError, IOError, AssertionError) as e:
|
except (EOFError, IOError, AssertionError) as e:
|
||||||
# most likely an abort
|
# most likely an abort
|
||||||
|
@ -406,7 +406,7 @@ class StrategyBase:
|
||||||
|
|
||||||
return block_list
|
return block_list
|
||||||
|
|
||||||
def run_handlers(self, iterator, connection_info):
|
def run_handlers(self, iterator, play_context):
|
||||||
'''
|
'''
|
||||||
Runs handlers on those hosts which have been notified.
|
Runs handlers on those hosts which have been notified.
|
||||||
'''
|
'''
|
||||||
|
@ -427,10 +427,10 @@ class StrategyBase:
|
||||||
# break
|
# break
|
||||||
self._tqm.send_callback('v2_playbook_on_handler_task_start', handler)
|
self._tqm.send_callback('v2_playbook_on_handler_task_start', handler)
|
||||||
for host in self._notified_handlers[handler_name]:
|
for host in self._notified_handlers[handler_name]:
|
||||||
if not handler.has_triggered(host) and (host.name not in self._tqm._failed_hosts or connection_info.force_handlers):
|
if not handler.has_triggered(host) and (host.name not in self._tqm._failed_hosts or play_context.force_handlers):
|
||||||
task_vars = self._variable_manager.get_vars(loader=self._loader, play=iterator._play, host=host, task=handler)
|
task_vars = self._variable_manager.get_vars(loader=self._loader, play=iterator._play, host=host, task=handler)
|
||||||
task_vars = self.add_tqm_variables(task_vars, play=iterator._play)
|
task_vars = self.add_tqm_variables(task_vars, play=iterator._play)
|
||||||
self._queue_task(host, handler, task_vars, connection_info)
|
self._queue_task(host, handler, task_vars, play_context)
|
||||||
#handler.flag_for_host(host)
|
#handler.flag_for_host(host)
|
||||||
self._process_pending_results(iterator)
|
self._process_pending_results(iterator)
|
||||||
self._wait_on_pending_results(iterator)
|
self._wait_on_pending_results(iterator)
|
||||||
|
|
|
@ -26,7 +26,7 @@ from ansible.utils.debug import debug
|
||||||
|
|
||||||
class StrategyModule(StrategyBase):
|
class StrategyModule(StrategyBase):
|
||||||
|
|
||||||
def run(self, iterator, connection_info):
|
def run(self, iterator, play_context):
|
||||||
'''
|
'''
|
||||||
The "free" strategy is a bit more complex, in that it allows tasks to
|
The "free" strategy is a bit more complex, in that it allows tasks to
|
||||||
be sent to hosts as quickly as they can be processed. This means that
|
be sent to hosts as quickly as they can be processed. This means that
|
||||||
|
@ -97,7 +97,7 @@ class StrategyModule(StrategyBase):
|
||||||
debug("'%s' skipped because role has already run" % task)
|
debug("'%s' skipped because role has already run" % task)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if not task.evaluate_tags(connection_info.only_tags, connection_info.skip_tags, task_vars) and task.action != 'setup':
|
if not task.evaluate_tags(play_context.only_tags, play_context.skip_tags, task_vars) and task.action != 'setup':
|
||||||
debug("'%s' failed tag evaluation" % task)
|
debug("'%s' failed tag evaluation" % task)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -111,14 +111,14 @@ class StrategyModule(StrategyBase):
|
||||||
elif meta_action == 'flush_handlers':
|
elif meta_action == 'flush_handlers':
|
||||||
# FIXME: in the 'free' mode, flushing handlers should result in
|
# FIXME: in the 'free' mode, flushing handlers should result in
|
||||||
# only those handlers notified for the host doing the flush
|
# only those handlers notified for the host doing the flush
|
||||||
self.run_handlers(iterator, connection_info)
|
self.run_handlers(iterator, play_context)
|
||||||
else:
|
else:
|
||||||
raise AnsibleError("invalid meta action requested: %s" % meta_action, obj=task._ds)
|
raise AnsibleError("invalid meta action requested: %s" % meta_action, obj=task._ds)
|
||||||
|
|
||||||
self._blocked_hosts[host_name] = False
|
self._blocked_hosts[host_name] = False
|
||||||
else:
|
else:
|
||||||
self._tqm.send_callback('v2_playbook_on_task_start', task, is_conditional=False)
|
self._tqm.send_callback('v2_playbook_on_task_start', task, is_conditional=False)
|
||||||
self._queue_task(host, task, task_vars, connection_info)
|
self._queue_task(host, task, task_vars, play_context)
|
||||||
|
|
||||||
# move on to the next host and make sure we
|
# move on to the next host and make sure we
|
||||||
# haven't gone past the end of our hosts list
|
# haven't gone past the end of our hosts list
|
||||||
|
@ -147,5 +147,5 @@ class StrategyModule(StrategyBase):
|
||||||
|
|
||||||
# run the base class run() method, which executes the cleanup function
|
# run the base class run() method, which executes the cleanup function
|
||||||
# and runs any outstanding handlers which have been triggered
|
# and runs any outstanding handlers which have been triggered
|
||||||
super(StrategyModule, self).run(iterator, connection_info)
|
super(StrategyModule, self).run(iterator, play_context)
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,7 @@ class StrategyModule(StrategyBase):
|
||||||
# return None for all hosts in the list
|
# return None for all hosts in the list
|
||||||
return [(host, None) for host in hosts]
|
return [(host, None) for host in hosts]
|
||||||
|
|
||||||
def run(self, iterator, connection_info):
|
def run(self, iterator, play_context):
|
||||||
'''
|
'''
|
||||||
The linear strategy is simple - get the next task and queue
|
The linear strategy is simple - get the next task and queue
|
||||||
it for all hosts, then wait for the queue to drain before
|
it for all hosts, then wait for the queue to drain before
|
||||||
|
@ -177,7 +177,7 @@ class StrategyModule(StrategyBase):
|
||||||
# FIXME: issue a callback for the noop here?
|
# FIXME: issue a callback for the noop here?
|
||||||
continue
|
continue
|
||||||
elif meta_action == 'flush_handlers':
|
elif meta_action == 'flush_handlers':
|
||||||
self.run_handlers(iterator, connection_info)
|
self.run_handlers(iterator, play_context)
|
||||||
else:
|
else:
|
||||||
raise AnsibleError("invalid meta action requested: %s" % meta_action, obj=task._ds)
|
raise AnsibleError("invalid meta action requested: %s" % meta_action, obj=task._ds)
|
||||||
else:
|
else:
|
||||||
|
@ -194,7 +194,7 @@ class StrategyModule(StrategyBase):
|
||||||
callback_sent = True
|
callback_sent = True
|
||||||
|
|
||||||
self._blocked_hosts[host.get_name()] = True
|
self._blocked_hosts[host.get_name()] = True
|
||||||
self._queue_task(host, task, task_vars, connection_info)
|
self._queue_task(host, task, task_vars, play_context)
|
||||||
|
|
||||||
results = self._process_pending_results(iterator)
|
results = self._process_pending_results(iterator)
|
||||||
host_results.extend(results)
|
host_results.extend(results)
|
||||||
|
@ -245,7 +245,7 @@ class StrategyModule(StrategyBase):
|
||||||
for host in hosts_left:
|
for host in hosts_left:
|
||||||
if host in included_file._hosts:
|
if host in included_file._hosts:
|
||||||
task_vars = self._variable_manager.get_vars(loader=self._loader, play=iterator._play, host=host, task=included_file._task)
|
task_vars = self._variable_manager.get_vars(loader=self._loader, play=iterator._play, host=host, task=included_file._task)
|
||||||
final_block = new_block.filter_tagged_tasks(connection_info, task_vars)
|
final_block = new_block.filter_tagged_tasks(play_context, task_vars)
|
||||||
all_blocks[host].append(final_block)
|
all_blocks[host].append(final_block)
|
||||||
else:
|
else:
|
||||||
all_blocks[host].append(noop_block)
|
all_blocks[host].append(noop_block)
|
||||||
|
@ -262,5 +262,5 @@ class StrategyModule(StrategyBase):
|
||||||
# run the base class run() method, which executes the cleanup function
|
# run the base class run() method, which executes the cleanup function
|
||||||
# and runs any outstanding handlers which have been triggered
|
# and runs any outstanding handlers which have been triggered
|
||||||
|
|
||||||
return super(StrategyModule, self).run(iterator, connection_info, result)
|
return super(StrategyModule, self).run(iterator, play_context, result)
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,8 @@ import multiprocessing
|
||||||
from ansible.inventory import Inventory
|
from ansible.inventory import Inventory
|
||||||
from ansible.inventory.host import Host
|
from ansible.inventory.host import Host
|
||||||
from ansible.playbook.play import Play
|
from ansible.playbook.play import Play
|
||||||
|
from ansible.playbook.play_context import PlayContext
|
||||||
from ansible.playbook.task import Task
|
from ansible.playbook.task import Task
|
||||||
from ansible.executor.connection_info import ConnectionInformation
|
|
||||||
from ansible.executor.task_executor import TaskExecutor
|
from ansible.executor.task_executor import TaskExecutor
|
||||||
from ansible.executor.task_result import TaskResult
|
from ansible.executor.task_result import TaskResult
|
||||||
from ansible.parsing import DataLoader
|
from ansible.parsing import DataLoader
|
||||||
|
@ -144,8 +144,8 @@ inventory = Inventory(host_list='/tmp/med_inventory', loader=loader, variable_ma
|
||||||
hosts = inventory.get_hosts()[:]
|
hosts = inventory.get_hosts()[:]
|
||||||
debug("done loading inventory")
|
debug("done loading inventory")
|
||||||
|
|
||||||
ci = ConnectionInformation()
|
play_context = PlayContext()
|
||||||
ci.connection = 'local'
|
play_context.connection = 'local'
|
||||||
|
|
||||||
for i in range(NUM_TASKS):
|
for i in range(NUM_TASKS):
|
||||||
#for j in range(NUM_HOSTS):
|
#for j in range(NUM_HOSTS):
|
||||||
|
@ -158,7 +158,7 @@ for i in range(NUM_TASKS):
|
||||||
task_vars = dict()
|
task_vars = dict()
|
||||||
new_t = t.copy()
|
new_t = t.copy()
|
||||||
new_t.post_validate(task_vars)
|
new_t.post_validate(task_vars)
|
||||||
send_data((h, t, task_vars, ci))
|
send_data((h, t, task_vars, play_context))
|
||||||
debug("done queuing %s %d" % (h, i))
|
debug("done queuing %s %d" % (h, i))
|
||||||
_process_pending_results()
|
_process_pending_results()
|
||||||
debug("waiting for the results to drain...")
|
debug("waiting for the results to drain...")
|
||||||
|
|
|
@ -1,156 +0,0 @@
|
||||||
# (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com>
|
|
||||||
#
|
|
||||||
# This file is part of Ansible
|
|
||||||
#
|
|
||||||
# Ansible is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# Ansible is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
# Make coding more python3-ish
|
|
||||||
from __future__ import (absolute_import, division, print_function)
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
import pwd
|
|
||||||
import os
|
|
||||||
|
|
||||||
from ansible.compat.tests import unittest
|
|
||||||
from ansible.compat.tests.mock import patch, MagicMock
|
|
||||||
|
|
||||||
from ansible import constants as C
|
|
||||||
from ansible.cli import CLI
|
|
||||||
from ansible.errors import AnsibleError, AnsibleParserError
|
|
||||||
from ansible.executor.connection_info import ConnectionInformation
|
|
||||||
|
|
||||||
from units.mock.loader import DictDataLoader
|
|
||||||
|
|
||||||
class TestConnectionInformation(unittest.TestCase):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self._parser = CLI.base_parser(
|
|
||||||
runas_opts = True,
|
|
||||||
meta_opts = True,
|
|
||||||
runtask_opts = True,
|
|
||||||
vault_opts = True,
|
|
||||||
async_opts = True,
|
|
||||||
connect_opts = True,
|
|
||||||
subset_opts = True,
|
|
||||||
check_opts = True,
|
|
||||||
diff_opts = True,
|
|
||||||
)
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def test_connection_info(self):
|
|
||||||
(options, args) = self._parser.parse_args(['-vv', '--check'])
|
|
||||||
conn_info = ConnectionInformation(options=options)
|
|
||||||
self.assertEqual(conn_info.connection, 'smart')
|
|
||||||
self.assertEqual(conn_info.remote_addr, None)
|
|
||||||
self.assertEqual(conn_info.remote_user, pwd.getpwuid(os.geteuid())[0])
|
|
||||||
self.assertEqual(conn_info.password, '')
|
|
||||||
self.assertEqual(conn_info.port, None)
|
|
||||||
self.assertEqual(conn_info.private_key_file, C.DEFAULT_PRIVATE_KEY_FILE)
|
|
||||||
self.assertEqual(conn_info.timeout, C.DEFAULT_TIMEOUT)
|
|
||||||
self.assertEqual(conn_info.shell, None)
|
|
||||||
self.assertEqual(conn_info.verbosity, 2)
|
|
||||||
self.assertEqual(conn_info.check_mode, True)
|
|
||||||
self.assertEqual(conn_info.no_log, False)
|
|
||||||
|
|
||||||
mock_play = MagicMock()
|
|
||||||
mock_play.connection = 'mock'
|
|
||||||
mock_play.remote_user = 'mock'
|
|
||||||
mock_play.port = 1234
|
|
||||||
mock_play.become = True
|
|
||||||
mock_play.become_method = 'mock'
|
|
||||||
mock_play.become_user = 'mockroot'
|
|
||||||
mock_play.no_log = True
|
|
||||||
mock_play.environment = dict(mock='mockenv')
|
|
||||||
|
|
||||||
conn_info = ConnectionInformation(play=mock_play, options=options)
|
|
||||||
self.assertEqual(conn_info.connection, 'mock')
|
|
||||||
self.assertEqual(conn_info.remote_user, 'mock')
|
|
||||||
self.assertEqual(conn_info.password, '')
|
|
||||||
self.assertEqual(conn_info.port, 1234)
|
|
||||||
self.assertEqual(conn_info.no_log, True)
|
|
||||||
self.assertEqual(conn_info.environment, dict(mock="mockenv"))
|
|
||||||
self.assertEqual(conn_info.become, True)
|
|
||||||
self.assertEqual(conn_info.become_method, "mock")
|
|
||||||
self.assertEqual(conn_info.become_user, "mockroot")
|
|
||||||
|
|
||||||
mock_task = MagicMock()
|
|
||||||
mock_task.connection = 'mocktask'
|
|
||||||
mock_task.remote_user = 'mocktask'
|
|
||||||
mock_task.become = True
|
|
||||||
mock_task.become_method = 'mocktask'
|
|
||||||
mock_task.become_user = 'mocktaskroot'
|
|
||||||
mock_task.become_pass = 'mocktaskpass'
|
|
||||||
mock_task.no_log = False
|
|
||||||
mock_task.environment = dict(mock='mocktaskenv')
|
|
||||||
|
|
||||||
mock_host = MagicMock()
|
|
||||||
mock_host.get_vars.return_value = dict(
|
|
||||||
ansible_connection = 'mock_inventory',
|
|
||||||
ansible_ssh_port = 4321,
|
|
||||||
)
|
|
||||||
|
|
||||||
conn_info = ConnectionInformation(play=mock_play, options=options)
|
|
||||||
conn_info = conn_info.set_task_and_host_override(task=mock_task, host=mock_host)
|
|
||||||
self.assertEqual(conn_info.connection, 'mock_inventory')
|
|
||||||
self.assertEqual(conn_info.remote_user, 'mocktask')
|
|
||||||
self.assertEqual(conn_info.port, 4321)
|
|
||||||
self.assertEqual(conn_info.no_log, False)
|
|
||||||
self.assertEqual(conn_info.environment, dict(mock="mocktaskenv"))
|
|
||||||
self.assertEqual(conn_info.become, True)
|
|
||||||
self.assertEqual(conn_info.become_method, "mocktask")
|
|
||||||
self.assertEqual(conn_info.become_user, "mocktaskroot")
|
|
||||||
self.assertEqual(conn_info.become_pass, "mocktaskpass")
|
|
||||||
|
|
||||||
def test_connection_info_make_become_cmd(self):
|
|
||||||
(options, args) = self._parser.parse_args([])
|
|
||||||
conn_info = ConnectionInformation(options=options)
|
|
||||||
|
|
||||||
default_cmd = "/bin/foo"
|
|
||||||
default_exe = "/bin/bash"
|
|
||||||
sudo_exe = C.DEFAULT_SUDO_EXE
|
|
||||||
sudo_flags = C.DEFAULT_SUDO_FLAGS
|
|
||||||
su_exe = C.DEFAULT_SU_EXE
|
|
||||||
su_flags = C.DEFAULT_SU_FLAGS
|
|
||||||
pbrun_exe = 'pbrun'
|
|
||||||
pbrun_flags = ''
|
|
||||||
pfexec_exe = 'pfexec'
|
|
||||||
pfexec_flags = ''
|
|
||||||
|
|
||||||
cmd = conn_info.make_become_cmd(cmd=default_cmd, executable=default_exe)
|
|
||||||
self.assertEqual(cmd, default_cmd)
|
|
||||||
|
|
||||||
conn_info.become = True
|
|
||||||
conn_info.become_user = 'foo'
|
|
||||||
|
|
||||||
conn_info.become_method = 'sudo'
|
|
||||||
cmd = conn_info.make_become_cmd(cmd=default_cmd, executable="/bin/bash")
|
|
||||||
self.assertEqual(cmd, """%s -c '%s -k && %s %s -S -p "%s" -u %s %s -c '"'"'echo %s; %s'"'"''""" % (default_exe, sudo_exe, sudo_exe, sudo_flags, conn_info.prompt, conn_info.become_user, default_exe, conn_info.success_key, default_cmd))
|
|
||||||
|
|
||||||
conn_info.become_method = 'su'
|
|
||||||
cmd = conn_info.make_become_cmd(cmd=default_cmd, executable="/bin/bash")
|
|
||||||
self.assertEqual(cmd, """%s -c '%s %s -c "%s -c '"'"'echo %s; %s'"'"'"'""" % (default_exe, su_exe, conn_info.become_user, default_exe, conn_info.success_key, default_cmd))
|
|
||||||
|
|
||||||
conn_info.become_method = 'pbrun'
|
|
||||||
cmd = conn_info.make_become_cmd(cmd=default_cmd, executable="/bin/bash")
|
|
||||||
self.assertEqual(cmd, """%s -c '%s -b %s -u %s '"'"'echo %s; %s'"'"''""" % (default_exe, pbrun_exe, pbrun_flags, conn_info.become_user, conn_info.success_key, default_cmd))
|
|
||||||
|
|
||||||
conn_info.become_method = 'pfexec'
|
|
||||||
cmd = conn_info.make_become_cmd(cmd=default_cmd, executable="/bin/bash")
|
|
||||||
self.assertEqual(cmd, """%s -c '%s %s "'"'"'echo %s; %s'"'"'"'""" % (default_exe, pfexec_exe, pfexec_flags, conn_info.success_key, default_cmd))
|
|
||||||
|
|
||||||
conn_info.become_method = 'bad'
|
|
||||||
self.assertRaises(AnsibleError, conn_info.make_become_cmd, cmd=default_cmd, executable="/bin/bash")
|
|
||||||
|
|
|
@ -23,9 +23,9 @@ from ansible.compat.tests import unittest
|
||||||
from ansible.compat.tests.mock import patch, MagicMock
|
from ansible.compat.tests.mock import patch, MagicMock
|
||||||
|
|
||||||
from ansible.errors import AnsibleError, AnsibleParserError
|
from ansible.errors import AnsibleError, AnsibleParserError
|
||||||
from ansible.executor.connection_info import ConnectionInformation
|
|
||||||
from ansible.executor.play_iterator import PlayIterator
|
from ansible.executor.play_iterator import PlayIterator
|
||||||
from ansible.playbook import Playbook
|
from ansible.playbook import Playbook
|
||||||
|
from ansible.playbook.play_context import PlayContext
|
||||||
|
|
||||||
from units.mock.loader import DictDataLoader
|
from units.mock.loader import DictDataLoader
|
||||||
|
|
||||||
|
@ -68,12 +68,12 @@ class TestPlayIterator(unittest.TestCase):
|
||||||
inventory.get_hosts.return_value = hosts
|
inventory.get_hosts.return_value = hosts
|
||||||
inventory.filter_hosts.return_value = hosts
|
inventory.filter_hosts.return_value = hosts
|
||||||
|
|
||||||
connection_info = ConnectionInformation(play=p._entries[0])
|
play_context = PlayContext(play=p._entries[0])
|
||||||
|
|
||||||
itr = PlayIterator(
|
itr = PlayIterator(
|
||||||
inventory=inventory,
|
inventory=inventory,
|
||||||
play=p._entries[0],
|
play=p._entries[0],
|
||||||
connection_info=connection_info,
|
play_context=play_context,
|
||||||
all_vars=dict(),
|
all_vars=dict(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,8 @@ from ansible.compat.tests import unittest
|
||||||
from ansible.compat.tests.mock import patch, MagicMock
|
from ansible.compat.tests.mock import patch, MagicMock
|
||||||
|
|
||||||
from ansible.errors import AnsibleError, AnsibleParserError
|
from ansible.errors import AnsibleError, AnsibleParserError
|
||||||
from ansible.executor.connection_info import ConnectionInformation
|
|
||||||
from ansible.executor.task_executor import TaskExecutor
|
from ansible.executor.task_executor import TaskExecutor
|
||||||
|
from ansible.playbook.play_context import PlayContext
|
||||||
from ansible.plugins import action_loader
|
from ansible.plugins import action_loader
|
||||||
|
|
||||||
from units.mock.loader import DictDataLoader
|
from units.mock.loader import DictDataLoader
|
||||||
|
@ -41,7 +41,7 @@ class TestTaskExecutor(unittest.TestCase):
|
||||||
fake_loader = DictDataLoader({})
|
fake_loader = DictDataLoader({})
|
||||||
mock_host = MagicMock()
|
mock_host = MagicMock()
|
||||||
mock_task = MagicMock()
|
mock_task = MagicMock()
|
||||||
mock_conn_info = MagicMock()
|
mock_play_context = MagicMock()
|
||||||
mock_shared_loader = MagicMock()
|
mock_shared_loader = MagicMock()
|
||||||
new_stdin = None
|
new_stdin = None
|
||||||
job_vars = dict()
|
job_vars = dict()
|
||||||
|
@ -49,7 +49,7 @@ class TestTaskExecutor(unittest.TestCase):
|
||||||
host = mock_host,
|
host = mock_host,
|
||||||
task = mock_task,
|
task = mock_task,
|
||||||
job_vars = job_vars,
|
job_vars = job_vars,
|
||||||
connection_info = mock_conn_info,
|
play_context = mock_play_context,
|
||||||
new_stdin = new_stdin,
|
new_stdin = new_stdin,
|
||||||
loader = fake_loader,
|
loader = fake_loader,
|
||||||
shared_loader_obj = mock_shared_loader,
|
shared_loader_obj = mock_shared_loader,
|
||||||
|
@ -63,7 +63,7 @@ class TestTaskExecutor(unittest.TestCase):
|
||||||
mock_task = MagicMock()
|
mock_task = MagicMock()
|
||||||
mock_task._role._role_path = '/path/to/role/foo'
|
mock_task._role._role_path = '/path/to/role/foo'
|
||||||
|
|
||||||
mock_conn_info = MagicMock()
|
mock_play_context = MagicMock()
|
||||||
|
|
||||||
mock_shared_loader = MagicMock()
|
mock_shared_loader = MagicMock()
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ class TestTaskExecutor(unittest.TestCase):
|
||||||
host = mock_host,
|
host = mock_host,
|
||||||
task = mock_task,
|
task = mock_task,
|
||||||
job_vars = job_vars,
|
job_vars = job_vars,
|
||||||
connection_info = mock_conn_info,
|
play_context = mock_play_context,
|
||||||
new_stdin = new_stdin,
|
new_stdin = new_stdin,
|
||||||
loader = fake_loader,
|
loader = fake_loader,
|
||||||
shared_loader_obj = mock_shared_loader,
|
shared_loader_obj = mock_shared_loader,
|
||||||
|
@ -104,7 +104,7 @@ class TestTaskExecutor(unittest.TestCase):
|
||||||
mock_task.loop = 'items'
|
mock_task.loop = 'items'
|
||||||
mock_task.loop_args = ['a', 'b', 'c']
|
mock_task.loop_args = ['a', 'b', 'c']
|
||||||
|
|
||||||
mock_conn_info = MagicMock()
|
mock_play_context = MagicMock()
|
||||||
|
|
||||||
mock_shared_loader = MagicMock()
|
mock_shared_loader = MagicMock()
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ class TestTaskExecutor(unittest.TestCase):
|
||||||
host = mock_host,
|
host = mock_host,
|
||||||
task = mock_task,
|
task = mock_task,
|
||||||
job_vars = job_vars,
|
job_vars = job_vars,
|
||||||
connection_info = mock_conn_info,
|
play_context = mock_play_context,
|
||||||
new_stdin = new_stdin,
|
new_stdin = new_stdin,
|
||||||
loader = fake_loader,
|
loader = fake_loader,
|
||||||
shared_loader_obj = mock_shared_loader,
|
shared_loader_obj = mock_shared_loader,
|
||||||
|
@ -138,7 +138,7 @@ class TestTaskExecutor(unittest.TestCase):
|
||||||
mock_task = MagicMock()
|
mock_task = MagicMock()
|
||||||
mock_task.copy.side_effect = _copy
|
mock_task.copy.side_effect = _copy
|
||||||
|
|
||||||
mock_conn_info = MagicMock()
|
mock_play_context = MagicMock()
|
||||||
|
|
||||||
mock_shared_loader = MagicMock()
|
mock_shared_loader = MagicMock()
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ class TestTaskExecutor(unittest.TestCase):
|
||||||
host = mock_host,
|
host = mock_host,
|
||||||
task = mock_task,
|
task = mock_task,
|
||||||
job_vars = job_vars,
|
job_vars = job_vars,
|
||||||
connection_info = mock_conn_info,
|
play_context = mock_play_context,
|
||||||
new_stdin = new_stdin,
|
new_stdin = new_stdin,
|
||||||
loader = fake_loader,
|
loader = fake_loader,
|
||||||
shared_loader_obj = mock_shared_loader,
|
shared_loader_obj = mock_shared_loader,
|
||||||
|
@ -180,7 +180,7 @@ class TestTaskExecutor(unittest.TestCase):
|
||||||
mock_task = MagicMock()
|
mock_task = MagicMock()
|
||||||
mock_task.evaluate_conditional.side_effect = _evaluate_conditional
|
mock_task.evaluate_conditional.side_effect = _evaluate_conditional
|
||||||
|
|
||||||
mock_conn_info = MagicMock()
|
mock_play_context = MagicMock()
|
||||||
|
|
||||||
mock_shared_loader = None
|
mock_shared_loader = None
|
||||||
|
|
||||||
|
@ -191,7 +191,7 @@ class TestTaskExecutor(unittest.TestCase):
|
||||||
host = mock_host,
|
host = mock_host,
|
||||||
task = mock_task,
|
task = mock_task,
|
||||||
job_vars = job_vars,
|
job_vars = job_vars,
|
||||||
connection_info = mock_conn_info,
|
play_context = mock_play_context,
|
||||||
new_stdin = new_stdin,
|
new_stdin = new_stdin,
|
||||||
loader = fake_loader,
|
loader = fake_loader,
|
||||||
shared_loader_obj = mock_shared_loader,
|
shared_loader_obj = mock_shared_loader,
|
||||||
|
@ -220,9 +220,9 @@ class TestTaskExecutor(unittest.TestCase):
|
||||||
mock_task.failed_when = None
|
mock_task.failed_when = None
|
||||||
mock_task.post_validate.return_value = None
|
mock_task.post_validate.return_value = None
|
||||||
|
|
||||||
mock_conn_info = MagicMock()
|
mock_play_context = MagicMock()
|
||||||
mock_conn_info.post_validate.return_value = None
|
mock_play_context.post_validate.return_value = None
|
||||||
mock_conn_info.update_vars.return_value = None
|
mock_play_context.update_vars.return_value = None
|
||||||
|
|
||||||
mock_connection = MagicMock()
|
mock_connection = MagicMock()
|
||||||
mock_connection.set_host_overrides.return_value = None
|
mock_connection.set_host_overrides.return_value = None
|
||||||
|
@ -238,7 +238,7 @@ class TestTaskExecutor(unittest.TestCase):
|
||||||
host = mock_host,
|
host = mock_host,
|
||||||
task = mock_task,
|
task = mock_task,
|
||||||
job_vars = job_vars,
|
job_vars = job_vars,
|
||||||
connection_info = mock_conn_info,
|
play_context = mock_play_context,
|
||||||
new_stdin = new_stdin,
|
new_stdin = new_stdin,
|
||||||
loader = fake_loader,
|
loader = fake_loader,
|
||||||
shared_loader_obj = shared_loader,
|
shared_loader_obj = shared_loader,
|
||||||
|
@ -275,7 +275,7 @@ class TestTaskExecutor(unittest.TestCase):
|
||||||
mock_task.async = 3
|
mock_task.async = 3
|
||||||
mock_task.poll = 1
|
mock_task.poll = 1
|
||||||
|
|
||||||
mock_conn_info = MagicMock()
|
mock_play_context = MagicMock()
|
||||||
|
|
||||||
mock_connection = MagicMock()
|
mock_connection = MagicMock()
|
||||||
|
|
||||||
|
@ -289,7 +289,7 @@ class TestTaskExecutor(unittest.TestCase):
|
||||||
host = mock_host,
|
host = mock_host,
|
||||||
task = mock_task,
|
task = mock_task,
|
||||||
job_vars = job_vars,
|
job_vars = job_vars,
|
||||||
connection_info = mock_conn_info,
|
play_context = mock_play_context,
|
||||||
new_stdin = new_stdin,
|
new_stdin = new_stdin,
|
||||||
loader = fake_loader,
|
loader = fake_loader,
|
||||||
shared_loader_obj = shared_loader,
|
shared_loader_obj = shared_loader,
|
||||||
|
|
156
test/units/playbook/test_play_context.py
Normal file
156
test/units/playbook/test_play_context.py
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
# (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com>
|
||||||
|
#
|
||||||
|
# This file is part of Ansible
|
||||||
|
#
|
||||||
|
# Ansible is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# Ansible is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# Make coding more python3-ish
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
import pwd
|
||||||
|
import os
|
||||||
|
|
||||||
|
from ansible.compat.tests import unittest
|
||||||
|
from ansible.compat.tests.mock import patch, MagicMock
|
||||||
|
|
||||||
|
from ansible import constants as C
|
||||||
|
from ansible.cli import CLI
|
||||||
|
from ansible.errors import AnsibleError, AnsibleParserError
|
||||||
|
from ansible.playbook.play_context import PlayContext
|
||||||
|
|
||||||
|
from units.mock.loader import DictDataLoader
|
||||||
|
|
||||||
|
class TestPlayContext(unittest.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self._parser = CLI.base_parser(
|
||||||
|
runas_opts = True,
|
||||||
|
meta_opts = True,
|
||||||
|
runtask_opts = True,
|
||||||
|
vault_opts = True,
|
||||||
|
async_opts = True,
|
||||||
|
connect_opts = True,
|
||||||
|
subset_opts = True,
|
||||||
|
check_opts = True,
|
||||||
|
diff_opts = True,
|
||||||
|
)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_play_context(self):
|
||||||
|
(options, args) = self._parser.parse_args(['-vv', '--check'])
|
||||||
|
play_context = PlayContext(options=options)
|
||||||
|
self.assertEqual(play_context.connection, 'smart')
|
||||||
|
self.assertEqual(play_context.remote_addr, None)
|
||||||
|
self.assertEqual(play_context.remote_user, pwd.getpwuid(os.geteuid())[0])
|
||||||
|
self.assertEqual(play_context.password, '')
|
||||||
|
self.assertEqual(play_context.port, None)
|
||||||
|
self.assertEqual(play_context.private_key_file, C.DEFAULT_PRIVATE_KEY_FILE)
|
||||||
|
self.assertEqual(play_context.timeout, C.DEFAULT_TIMEOUT)
|
||||||
|
self.assertEqual(play_context.shell, None)
|
||||||
|
self.assertEqual(play_context.verbosity, 2)
|
||||||
|
self.assertEqual(play_context.check_mode, True)
|
||||||
|
self.assertEqual(play_context.no_log, False)
|
||||||
|
|
||||||
|
mock_play = MagicMock()
|
||||||
|
mock_play.connection = 'mock'
|
||||||
|
mock_play.remote_user = 'mock'
|
||||||
|
mock_play.port = 1234
|
||||||
|
mock_play.become = True
|
||||||
|
mock_play.become_method = 'mock'
|
||||||
|
mock_play.become_user = 'mockroot'
|
||||||
|
mock_play.no_log = True
|
||||||
|
mock_play.environment = dict(mock='mockenv')
|
||||||
|
|
||||||
|
play_context = PlayContext(play=mock_play, options=options)
|
||||||
|
self.assertEqual(play_context.connection, 'mock')
|
||||||
|
self.assertEqual(play_context.remote_user, 'mock')
|
||||||
|
self.assertEqual(play_context.password, '')
|
||||||
|
self.assertEqual(play_context.port, 1234)
|
||||||
|
self.assertEqual(play_context.no_log, True)
|
||||||
|
self.assertEqual(play_context.environment, dict(mock="mockenv"))
|
||||||
|
self.assertEqual(play_context.become, True)
|
||||||
|
self.assertEqual(play_context.become_method, "mock")
|
||||||
|
self.assertEqual(play_context.become_user, "mockroot")
|
||||||
|
|
||||||
|
mock_task = MagicMock()
|
||||||
|
mock_task.connection = 'mocktask'
|
||||||
|
mock_task.remote_user = 'mocktask'
|
||||||
|
mock_task.become = True
|
||||||
|
mock_task.become_method = 'mocktask'
|
||||||
|
mock_task.become_user = 'mocktaskroot'
|
||||||
|
mock_task.become_pass = 'mocktaskpass'
|
||||||
|
mock_task.no_log = False
|
||||||
|
mock_task.environment = dict(mock='mocktaskenv')
|
||||||
|
|
||||||
|
mock_host = MagicMock()
|
||||||
|
mock_host.get_vars.return_value = dict(
|
||||||
|
ansible_connection = 'mock_inventory',
|
||||||
|
ansible_ssh_port = 4321,
|
||||||
|
)
|
||||||
|
|
||||||
|
play_context = PlayContext(play=mock_play, options=options)
|
||||||
|
play_context = play_context.set_task_and_host_override(task=mock_task, host=mock_host)
|
||||||
|
self.assertEqual(play_context.connection, 'mock_inventory')
|
||||||
|
self.assertEqual(play_context.remote_user, 'mocktask')
|
||||||
|
self.assertEqual(play_context.port, 4321)
|
||||||
|
self.assertEqual(play_context.no_log, False)
|
||||||
|
self.assertEqual(play_context.environment, dict(mock="mocktaskenv"))
|
||||||
|
self.assertEqual(play_context.become, True)
|
||||||
|
self.assertEqual(play_context.become_method, "mocktask")
|
||||||
|
self.assertEqual(play_context.become_user, "mocktaskroot")
|
||||||
|
self.assertEqual(play_context.become_pass, "mocktaskpass")
|
||||||
|
|
||||||
|
def test_play_context_make_become_cmd(self):
|
||||||
|
(options, args) = self._parser.parse_args([])
|
||||||
|
play_context = PlayContext(options=options)
|
||||||
|
|
||||||
|
default_cmd = "/bin/foo"
|
||||||
|
default_exe = "/bin/bash"
|
||||||
|
sudo_exe = C.DEFAULT_SUDO_EXE
|
||||||
|
sudo_flags = C.DEFAULT_SUDO_FLAGS
|
||||||
|
su_exe = C.DEFAULT_SU_EXE
|
||||||
|
su_flags = C.DEFAULT_SU_FLAGS
|
||||||
|
pbrun_exe = 'pbrun'
|
||||||
|
pbrun_flags = ''
|
||||||
|
pfexec_exe = 'pfexec'
|
||||||
|
pfexec_flags = ''
|
||||||
|
|
||||||
|
cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe)
|
||||||
|
self.assertEqual(cmd, default_cmd)
|
||||||
|
|
||||||
|
play_context.become = True
|
||||||
|
play_context.become_user = 'foo'
|
||||||
|
|
||||||
|
play_context.become_method = 'sudo'
|
||||||
|
cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash")
|
||||||
|
self.assertEqual(cmd, """%s -c '%s -k && %s %s -S -p "%s" -u %s %s -c '"'"'echo %s; %s'"'"''""" % (default_exe, sudo_exe, sudo_exe, sudo_flags, play_context.prompt, play_context.become_user, default_exe, play_context.success_key, default_cmd))
|
||||||
|
|
||||||
|
play_context.become_method = 'su'
|
||||||
|
cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash")
|
||||||
|
self.assertEqual(cmd, """%s -c '%s %s -c "%s -c '"'"'echo %s; %s'"'"'"'""" % (default_exe, su_exe, play_context.become_user, default_exe, play_context.success_key, default_cmd))
|
||||||
|
|
||||||
|
play_context.become_method = 'pbrun'
|
||||||
|
cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash")
|
||||||
|
self.assertEqual(cmd, """%s -c '%s -b %s -u %s '"'"'echo %s; %s'"'"''""" % (default_exe, pbrun_exe, pbrun_flags, play_context.become_user, play_context.success_key, default_cmd))
|
||||||
|
|
||||||
|
play_context.become_method = 'pfexec'
|
||||||
|
cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash")
|
||||||
|
self.assertEqual(cmd, """%s -c '%s %s "'"'"'echo %s; %s'"'"'"'""" % (default_exe, pfexec_exe, pfexec_flags, play_context.success_key, default_cmd))
|
||||||
|
|
||||||
|
play_context.become_method = 'bad'
|
||||||
|
self.assertRaises(AnsibleError, play_context.make_become_cmd, cmd=default_cmd, executable="/bin/bash")
|
||||||
|
|
|
@ -22,7 +22,7 @@ __metaclass__ = type
|
||||||
from six import StringIO
|
from six import StringIO
|
||||||
|
|
||||||
from ansible.compat.tests import unittest
|
from ansible.compat.tests import unittest
|
||||||
from ansible.executor.connection_info import ConnectionInformation
|
from ansible.playbook.play_context import PlayContext
|
||||||
|
|
||||||
from ansible.plugins.connections import ConnectionBase
|
from ansible.plugins.connections import ConnectionBase
|
||||||
#from ansible.plugins.connections.accelerate import Connection as AccelerateConnection
|
#from ansible.plugins.connections.accelerate import Connection as AccelerateConnection
|
||||||
|
@ -38,7 +38,7 @@ from ansible.plugins.connections.ssh import Connection as SSHConnection
|
||||||
class TestConnectionBaseClass(unittest.TestCase):
|
class TestConnectionBaseClass(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.conn_info = ConnectionInformation()
|
self.play_context = PlayContext()
|
||||||
self.in_stream = StringIO()
|
self.in_stream = StringIO()
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
|
@ -72,7 +72,7 @@ class TestConnectionBaseClass(unittest.TestCase):
|
||||||
pass
|
pass
|
||||||
def close(self):
|
def close(self):
|
||||||
pass
|
pass
|
||||||
self.assertIsInstance(ConnectionModule3(self.conn_info, self.in_stream), ConnectionModule3)
|
self.assertIsInstance(ConnectionModule3(self.play_context, self.in_stream), ConnectionModule3)
|
||||||
|
|
||||||
# def test_accelerate_connection_module(self):
|
# def test_accelerate_connection_module(self):
|
||||||
# self.assertIsInstance(AccelerateConnection(), AccelerateConnection)
|
# self.assertIsInstance(AccelerateConnection(), AccelerateConnection)
|
||||||
|
@ -90,13 +90,13 @@ class TestConnectionBaseClass(unittest.TestCase):
|
||||||
# self.assertIsInstance(LibvirtLXCConnection(), LibvirtLXCConnection)
|
# self.assertIsInstance(LibvirtLXCConnection(), LibvirtLXCConnection)
|
||||||
|
|
||||||
def test_local_connection_module(self):
|
def test_local_connection_module(self):
|
||||||
self.assertIsInstance(LocalConnection(self.conn_info, self.in_stream), LocalConnection)
|
self.assertIsInstance(LocalConnection(self.play_context, self.in_stream), LocalConnection)
|
||||||
|
|
||||||
def test_paramiko_connection_module(self):
|
def test_paramiko_connection_module(self):
|
||||||
self.assertIsInstance(ParamikoConnection(self.conn_info, self.in_stream), ParamikoConnection)
|
self.assertIsInstance(ParamikoConnection(self.play_context, self.in_stream), ParamikoConnection)
|
||||||
|
|
||||||
def test_ssh_connection_module(self):
|
def test_ssh_connection_module(self):
|
||||||
self.assertIsInstance(SSHConnection(self.conn_info, self.in_stream), SSHConnection)
|
self.assertIsInstance(SSHConnection(self.play_context, self.in_stream), SSHConnection)
|
||||||
|
|
||||||
# def test_winrm_connection_module(self):
|
# def test_winrm_connection_module(self):
|
||||||
# self.assertIsInstance(WinRmConnection(), WinRmConnection)
|
# self.assertIsInstance(WinRmConnection(), WinRmConnection)
|
||||||
|
|
|
@ -53,18 +53,18 @@ class TestStrategyBase(unittest.TestCase):
|
||||||
mock_iterator._play = MagicMock()
|
mock_iterator._play = MagicMock()
|
||||||
mock_iterator._play.handlers = []
|
mock_iterator._play.handlers = []
|
||||||
|
|
||||||
mock_conn_info = MagicMock()
|
mock_play_context = MagicMock()
|
||||||
|
|
||||||
mock_tqm._failed_hosts = dict()
|
mock_tqm._failed_hosts = dict()
|
||||||
mock_tqm._unreachable_hosts = dict()
|
mock_tqm._unreachable_hosts = dict()
|
||||||
strategy_base = StrategyBase(tqm=mock_tqm)
|
strategy_base = StrategyBase(tqm=mock_tqm)
|
||||||
|
|
||||||
self.assertEqual(strategy_base.run(iterator=mock_iterator, connection_info=mock_conn_info), 0)
|
self.assertEqual(strategy_base.run(iterator=mock_iterator, play_context=mock_play_context), 0)
|
||||||
self.assertEqual(strategy_base.run(iterator=mock_iterator, connection_info=mock_conn_info, result=False), 1)
|
self.assertEqual(strategy_base.run(iterator=mock_iterator, play_context=mock_play_context, result=False), 1)
|
||||||
mock_tqm._failed_hosts = dict(host1=True)
|
mock_tqm._failed_hosts = dict(host1=True)
|
||||||
self.assertEqual(strategy_base.run(iterator=mock_iterator, connection_info=mock_conn_info, result=False), 2)
|
self.assertEqual(strategy_base.run(iterator=mock_iterator, play_context=mock_play_context, result=False), 2)
|
||||||
mock_tqm._unreachable_hosts = dict(host1=True)
|
mock_tqm._unreachable_hosts = dict(host1=True)
|
||||||
self.assertEqual(strategy_base.run(iterator=mock_iterator, connection_info=mock_conn_info, result=False), 3)
|
self.assertEqual(strategy_base.run(iterator=mock_iterator, play_context=mock_play_context, result=False), 3)
|
||||||
|
|
||||||
def test_strategy_base_get_hosts(self):
|
def test_strategy_base_get_hosts(self):
|
||||||
mock_hosts = []
|
mock_hosts = []
|
||||||
|
@ -114,17 +114,17 @@ class TestStrategyBase(unittest.TestCase):
|
||||||
strategy_base = StrategyBase(tqm=mock_tqm)
|
strategy_base = StrategyBase(tqm=mock_tqm)
|
||||||
strategy_base._cur_worker = 0
|
strategy_base._cur_worker = 0
|
||||||
strategy_base._pending_results = 0
|
strategy_base._pending_results = 0
|
||||||
strategy_base._queue_task(host=MagicMock(), task=MagicMock(), task_vars=dict(), connection_info=MagicMock())
|
strategy_base._queue_task(host=MagicMock(), task=MagicMock(), task_vars=dict(), play_context=MagicMock())
|
||||||
self.assertEqual(strategy_base._cur_worker, 1)
|
self.assertEqual(strategy_base._cur_worker, 1)
|
||||||
self.assertEqual(strategy_base._pending_results, 1)
|
self.assertEqual(strategy_base._pending_results, 1)
|
||||||
strategy_base._queue_task(host=MagicMock(), task=MagicMock(), task_vars=dict(), connection_info=MagicMock())
|
strategy_base._queue_task(host=MagicMock(), task=MagicMock(), task_vars=dict(), play_context=MagicMock())
|
||||||
self.assertEqual(strategy_base._cur_worker, 2)
|
self.assertEqual(strategy_base._cur_worker, 2)
|
||||||
self.assertEqual(strategy_base._pending_results, 2)
|
self.assertEqual(strategy_base._pending_results, 2)
|
||||||
strategy_base._queue_task(host=MagicMock(), task=MagicMock(), task_vars=dict(), connection_info=MagicMock())
|
strategy_base._queue_task(host=MagicMock(), task=MagicMock(), task_vars=dict(), play_context=MagicMock())
|
||||||
self.assertEqual(strategy_base._cur_worker, 0)
|
self.assertEqual(strategy_base._cur_worker, 0)
|
||||||
self.assertEqual(strategy_base._pending_results, 3)
|
self.assertEqual(strategy_base._pending_results, 3)
|
||||||
workers[0][1].put.side_effect = EOFError
|
workers[0][1].put.side_effect = EOFError
|
||||||
strategy_base._queue_task(host=MagicMock(), task=MagicMock(), task_vars=dict(), connection_info=MagicMock())
|
strategy_base._queue_task(host=MagicMock(), task=MagicMock(), task_vars=dict(), play_context=MagicMock())
|
||||||
self.assertEqual(strategy_base._cur_worker, 1)
|
self.assertEqual(strategy_base._cur_worker, 1)
|
||||||
self.assertEqual(strategy_base._pending_results, 3)
|
self.assertEqual(strategy_base._pending_results, 3)
|
||||||
|
|
||||||
|
@ -326,7 +326,7 @@ class TestStrategyBase(unittest.TestCase):
|
||||||
mock_tqm.get_workers.return_value = workers
|
mock_tqm.get_workers.return_value = workers
|
||||||
mock_tqm.send_callback.return_value = None
|
mock_tqm.send_callback.return_value = None
|
||||||
|
|
||||||
mock_conn_info = MagicMock()
|
mock_play_context = MagicMock()
|
||||||
|
|
||||||
mock_handler_task = MagicMock()
|
mock_handler_task = MagicMock()
|
||||||
mock_handler_task.get_name.return_value = "test handler"
|
mock_handler_task.get_name.return_value = "test handler"
|
||||||
|
@ -357,4 +357,4 @@ class TestStrategyBase(unittest.TestCase):
|
||||||
strategy_base._inventory = mock_inventory
|
strategy_base._inventory = mock_inventory
|
||||||
strategy_base._notified_handlers = {"test handler": [mock_host]}
|
strategy_base._notified_handlers = {"test handler": [mock_host]}
|
||||||
|
|
||||||
result = strategy_base.run_handlers(iterator=mock_iterator, connection_info=mock_conn_info)
|
result = strategy_base.run_handlers(iterator=mock_iterator, play_context=mock_play_context)
|
||||||
|
|
Loading…
Reference in a new issue