diff --git a/v2/ansible/executor/connection_info.py b/v2/ansible/executor/connection_info.py index 165cd1245fb..19c8b130c72 100644 --- a/v2/ansible/executor/connection_info.py +++ b/v2/ansible/executor/connection_info.py @@ -38,34 +38,40 @@ class ConnectionInformation: connection/authentication information. ''' - def __init__(self, play=None, options=None): - # FIXME: implement the new methodology here for supporting - # various different auth escalation methods (becomes, etc.) + def __init__(self, play=None, options=None, passwords=None): - self.connection = C.DEFAULT_TRANSPORT + if passwords is None: + passwords = {} + + # connection + self.connection = None self.remote_addr = None - self.remote_user = 'root' - self.password = '' - self.port = 22 + self.remote_user = None + self.password = passwords.get('conn_pass','') + self.port = None self.private_key_file = None + + # privilege escalation + self.become = None + self.become_method = None + self.become_user = None + self.become_pass = passwords.get('become_pass','') + + # general flags (should we move out?) self.verbosity = 0 self.only_tags = set() self.skip_tags = set() - - # privilege escalation - self.become = False - self.become_method = C.DEFAULT_BECOME_METHOD - self.become_user = '' - self.become_pass = '' - self.no_log = False self.check_mode = False + #TODO: just pull options setup to above? + # set options before play to allow play to override them + if options: + self.set_options(options) + if play: self.set_play(play) - if options: - self.set_options(options) def __repr__(self): value = "CONNECTION INFO:\n" @@ -84,12 +90,18 @@ class ConnectionInformation: if play.connection: self.connection = play.connection - self.remote_user = play.remote_user - self.password = '' - self.port = int(play.port) if play.port else 22 - self.become = play.become - self.become_method = play.become_method - self.become_user = play.become_user + if play.remote_user: + self.remote_user = play.remote_user + + if play.port: + self.port = int(play.port) + + if play.become is not None: + self.become = play.become + if play.become_method: + self.become_method = play.become_method + if play.become_user: + self.become_user = play.become_user self.become_pass = play.become_pass # non connection related @@ -103,15 +115,30 @@ class ConnectionInformation: higher precedence than those set on the play or host. ''' - # FIXME: set other values from options here? - - self.verbosity = options.verbosity if options.connection: self.connection = options.connection + self.remote_user = options.remote_user + #if 'port' in options and options.port is not None: + # self.port = options.port + self.private_key_file = None + + # privilege escalation + self.become = options.become + self.become_method = options.become_method + self.become_user = options.become_user + self.become_pass = '' + + # general flags (should we move out?) + if options.verbosity: + self.verbosity = options.verbosity + #if options.no_log: + # self.no_log = boolean(options.no_log) if options.check: self.check_mode = boolean(options.check) + + # get the tag info from options, converting a comma-separated list # of values into a proper list if need be. We check to see if the # options have the attribute, as it is not always added via the CLI diff --git a/v2/ansible/executor/playbook_executor.py b/v2/ansible/executor/playbook_executor.py index 6504fddfc82..40c0798b003 100644 --- a/v2/ansible/executor/playbook_executor.py +++ b/v2/ansible/executor/playbook_executor.py @@ -36,18 +36,19 @@ class PlaybookExecutor: basis for bin/ansible-playbook operation. ''' - def __init__(self, playbooks, inventory, variable_manager, loader, display, options): + def __init__(self, playbooks, inventory, variable_manager, loader, display, options, conn_pass, become_pass): self._playbooks = playbooks self._inventory = inventory self._variable_manager = variable_manager self._loader = loader self._display = display self._options = options + self.passwords = {'conn_pass': conn_pass, 'become_pass': become_pass} if options.listhosts or options.listtasks or options.listtags: self._tqm = None else: - self._tqm = TaskQueueManager(inventory=inventory, callback='default', variable_manager=variable_manager, loader=loader, display=display, options=options) + self._tqm = TaskQueueManager(inventory=inventory, callback='default', variable_manager=variable_manager, loader=loader, display=display, options=options, passwords=self.passwords) def run(self): diff --git a/v2/ansible/executor/task_queue_manager.py b/v2/ansible/executor/task_queue_manager.py index d0354786da9..026726b3d8e 100644 --- a/v2/ansible/executor/task_queue_manager.py +++ b/v2/ansible/executor/task_queue_manager.py @@ -48,7 +48,7 @@ class TaskQueueManager: which dispatches the Play's tasks to hosts. ''' - def __init__(self, inventory, callback, variable_manager, loader, display, options): + def __init__(self, inventory, callback, variable_manager, loader, display, options, passwords): self._inventory = inventory self._variable_manager = variable_manager @@ -56,6 +56,7 @@ class TaskQueueManager: self._display = display self._options = options self._stats = AggregateStats() + self.passwords = passwords # a special flag to help us exit cleanly self._terminated = False @@ -144,7 +145,7 @@ class TaskQueueManager: new_play = play.copy() new_play.post_validate(all_vars, fail_on_undefined=False) - connection_info = ConnectionInformation(new_play, self._options) + connection_info = ConnectionInformation(new_play, self._options, self.passwords) for callback_plugin in self._callback_plugins: if hasattr(callback_plugin, 'set_connection_info'): callback_plugin.set_connection_info(connection_info) diff --git a/v2/ansible/playbook/play.py b/v2/ansible/playbook/play.py index eeabfce062a..33fd5efd9fa 100644 --- a/v2/ansible/playbook/play.py +++ b/v2/ansible/playbook/play.py @@ -61,7 +61,7 @@ class Play(Base, Taggable, Become): _hosts = FieldAttribute(isa='list', default=[], required=True) _name = FieldAttribute(isa='string', default='') _port = FieldAttribute(isa='int', default=22) - _remote_user = FieldAttribute(isa='string', default='root') + _remote_user = FieldAttribute(isa='string') # Variable Attributes _vars = FieldAttribute(isa='dict', default=dict()) diff --git a/v2/ansible/plugins/action/__init__.py b/v2/ansible/plugins/action/__init__.py index 2d258dd5250..2f56c4df582 100644 --- a/v2/ansible/plugins/action/__init__.py +++ b/v2/ansible/plugins/action/__init__.py @@ -415,7 +415,11 @@ class ActionBase: # FIXME: in error situations, the stdout may not contain valid data, so we # should check for bad rc codes better to catch this here if 'stdout' in res and res['stdout'].strip(): - data = json.loads(self._filter_leading_non_json_lines(res['stdout'])) + try: + data = json.loads(self._filter_leading_non_json_lines(res['stdout'])) + except ValueError: + # not valid json, lets try to capture error + data = {'traceback': res['stdout']} if 'parsed' in data and data['parsed'] == False: data['msg'] += res['stderr'] # pre-split stdout into lines, if stdout is in the data and there diff --git a/v2/ansible/plugins/connections/local.py b/v2/ansible/plugins/connections/local.py index c847ee79d5d..31d0b296e4a 100644 --- a/v2/ansible/plugins/connections/local.py +++ b/v2/ansible/plugins/connections/local.py @@ -37,6 +37,9 @@ class Connection(ConnectionBase): def connect(self, port=None): ''' connect to the local host; nothing to do here ''' + + self._display.vvv("ESTABLISH LOCAL CONNECTION FOR USER: %s" % self._connection_info.remote_user, host=self._connection_info.remote_addr) + return self def exec_command(self, cmd, tmp_path, executable='/bin/sh', in_data=None): diff --git a/v2/ansible/plugins/connections/ssh.py b/v2/ansible/plugins/connections/ssh.py index e233a704f98..e59311ead96 100644 --- a/v2/ansible/plugins/connections/ssh.py +++ b/v2/ansible/plugins/connections/ssh.py @@ -57,7 +57,7 @@ class Connection(ConnectionBase): def connect(self): ''' connect to the remote host ''' - self._display.vvv("ESTABLISH CONNECTION FOR USER: %s" % self._connection_info.remote_user, host=self._connection_info.remote_addr) + self._display.vvv("ESTABLISH SSH CONNECTION FOR USER: %s" % self._connection_info.remote_user, host=self._connection_info.remote_addr) self._common_args = [] extra_args = C.ANSIBLE_SSH_ARGS @@ -99,7 +99,7 @@ class Connection(ConnectionBase): self._common_args += ["-o", "KbdInteractiveAuthentication=no", "-o", "PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey", "-o", "PasswordAuthentication=no"] - if self._connection_info.remote_user != pwd.getpwuid(os.geteuid())[0]: + if self._connection_info.remote_user is not None and self._connection_info.remote_user != pwd.getpwuid(os.geteuid())[0]: self._common_args += ["-o", "User="+self._connection_info.remote_user] # FIXME: figure out where this goes #self._common_args += ["-o", "ConnectTimeout=%d" % self.runner.timeout] diff --git a/v2/bin/ansible b/v2/bin/ansible index 7d2f01bc5c5..9b3ccd38be6 100755 --- a/v2/bin/ansible +++ b/v2/bin/ansible @@ -93,6 +93,7 @@ class Cli(object): normalize_become_options(options) (sshpass, becomepass, vault_pass) = ask_passwords(options) + passwords = { 'conn_pass': sshpass, 'become_pass': becomepass } if options.vault_password_file: # read vault_pass from a file @@ -138,7 +139,7 @@ class Cli(object): # now create a task queue manager to execute the play try: display = Display() - tqm = TaskQueueManager(inventory=inventory, callback='minimal', variable_manager=variable_manager, loader=loader, display=display, options=options) + tqm = TaskQueueManager(inventory=inventory, callback='minimal', variable_manager=variable_manager, loader=loader, display=display, options=options, passwords=passwords) result = tqm.run(play) tqm.cleanup() except AnsibleError: diff --git a/v2/bin/ansible-playbook b/v2/bin/ansible-playbook index 79c2eed785d..000a0b74c7a 100755 --- a/v2/bin/ansible-playbook +++ b/v2/bin/ansible-playbook @@ -127,7 +127,7 @@ def main(display, args): raise errors.AnsibleError("Specified --limit does not match any hosts") # create the playbook executor, which manages running the plays via a task queue manager - pbex = PlaybookExecutor(playbooks=args, inventory=inventory, variable_manager=variable_manager, loader=loader, display=display, options=options) + pbex = PlaybookExecutor(playbooks=args, inventory=inventory, variable_manager=variable_manager, loader=loader, display=display, options=options, conn_pass=sshpass, become_pass=becomepass) results = pbex.run()