diff --git a/examples/playbooks/intro_example.yml b/examples/playbooks/intro_example.yml index 1fb31d2688..7ee6fe7991 100644 --- a/examples/playbooks/intro_example.yml +++ b/examples/playbooks/intro_example.yml @@ -9,6 +9,7 @@ - hosts: all user: root + port: 3000 # could have also have done: # user: mdehaan diff --git a/lib/ansible/connection.py b/lib/ansible/connection.py index 2abeac60bf..1af307a232 100755 --- a/lib/ansible/connection.py +++ b/lib/ansible/connection.py @@ -45,12 +45,12 @@ class Connection(object): self.runner = runner self.transport = transport - def connect(self, host): + def connect(self, host, port=None): conn = None if self.transport == 'local' and self._LOCALHOSTRE.search(host): - conn = LocalConnection(self.runner, host) + conn = LocalConnection(self.runner, host, None) elif self.transport == 'paramiko': - conn = ParamikoConnection(self.runner, host) + conn = ParamikoConnection(self.runner, host, port) if conn is None: raise Exception("unsupported connection type") return conn.connect() @@ -64,10 +64,13 @@ class Connection(object): class ParamikoConnection(object): ''' SSH based connections with Paramiko ''' - def __init__(self, runner, host): + def __init__(self, runner, host, port=None): self.ssh = None self.runner = runner self.host = host + self.port = port + if port is None: + self.port = self.runner.remote_port def _get_conn(self): ssh = paramiko.SSHClient() @@ -75,9 +78,13 @@ class ParamikoConnection(object): try: ssh.connect( - self.host, username=self.runner.remote_user, - allow_agent=True, look_for_keys=True, password=self.runner.remote_pass, - timeout=self.runner.timeout, port=self.runner.remote_port + self.host, + username=self.runner.remote_user, + allow_agent=True, + look_for_keys=True, + password=self.runner.remote_pass, + timeout=self.runner.timeout, + port=self.port ) except Exception, e: if str(e).find("PID check failed") != -1: @@ -183,7 +190,7 @@ class LocalConnection(object): self.runner = runner self.host = host - def connect(self): + def connect(self, port=None): ''' connect to the local host; nothing to do here ''' return self diff --git a/lib/ansible/playbook.py b/lib/ansible/playbook.py index c18e60c741..c5c843c9fd 100755 --- a/lib/ansible/playbook.py +++ b/lib/ansible/playbook.py @@ -304,18 +304,21 @@ class PlayBook(object): # ***************************************************** def _run_module(self, pattern, module, args, vars, remote_user, - async_seconds, async_poll_interval, only_if, sudo, transport): + async_seconds, async_poll_interval, only_if, sudo, transport, port): ''' run a particular module step in a playbook ''' hosts = [ h for h in self.inventory.list_hosts() if (h not in self.stats.failures) and (h not in self.stats.dark)] self.inventory.restrict_to(hosts) + if port is None: + port=self.remote_port + runner = ansible.runner.Runner( pattern=pattern, inventory=self.inventory, module_name=module, module_args=args, forks=self.forks, remote_pass=self.remote_pass, module_path=self.module_path, timeout=self.timeout, remote_user=remote_user, - remote_port=self.remote_port, module_vars=vars, + remote_port=port, module_vars=vars, setup_cache=SETUP_CACHE, basedir=self.basedir, conditional=only_if, callbacks=self.runner_callbacks, extra_vars=self.extra_vars, debug=self.debug, sudo=sudo, @@ -333,7 +336,7 @@ class PlayBook(object): # ***************************************************** def _run_task(self, pattern=None, task=None, - remote_user=None, handlers=None, conditional=False, sudo=False, transport=None): + remote_user=None, handlers=None, conditional=False, sudo=False, transport=None, port=None): ''' run a single task in the playbook and recursively run any subtasks. ''' # load the module name and parameters from the task entry @@ -365,7 +368,7 @@ class PlayBook(object): # run the task in parallel results = self._run_module(pattern, module_name, module_args, module_vars, remote_user, async_seconds, - async_poll_interval, only_if, sudo, transport) + async_poll_interval, only_if, sudo, transport, port) self.stats.compute(results) @@ -483,7 +486,7 @@ class PlayBook(object): module_args=vars, inventory=self.inventory, forks=self.forks, module_path=self.module_path, timeout=self.timeout, remote_user=user, - remote_pass=self.remote_pass, remote_port=self.remote_port, + remote_pass=self.remote_pass, remote_port=port, setup_cache=SETUP_CACHE, callbacks=self.runner_callbacks, sudo=sudo, debug=self.debug, transport=transport, sudo_pass=self.sudo_pass, is_playbook=True @@ -546,7 +549,8 @@ class PlayBook(object): handlers=handlers, remote_user=user, sudo=sudo, - transport=transport + transport=transport, + port=port ) # handlers only run on certain nodes, they are flagged by _flag_handlers @@ -566,7 +570,8 @@ class PlayBook(object): conditional=True, remote_user=user, sudo=sudo, - transport=transport + transport=transport, + port=port ) self.inventory.lift_restriction() diff --git a/lib/ansible/runner.py b/lib/ansible/runner.py index 186feb3478..d5d844bc12 100755 --- a/lib/ansible/runner.py +++ b/lib/ansible/runner.py @@ -68,16 +68,32 @@ def _executor_hook(job_queue, result_queue): class Runner(object): - def __init__(self, host_list=C.DEFAULT_HOST_LIST, module_path=C.DEFAULT_MODULE_PATH, - module_name=C.DEFAULT_MODULE_NAME, module_args=C.DEFAULT_MODULE_ARGS, - forks=C.DEFAULT_FORKS, timeout=C.DEFAULT_TIMEOUT, pattern=C.DEFAULT_PATTERN, - remote_user=C.DEFAULT_REMOTE_USER, remote_pass=C.DEFAULT_REMOTE_PASS, - sudo_pass=C.DEFAULT_SUDO_PASS, remote_port=C.DEFAULT_REMOTE_PORT, background=0, - basedir=None, setup_cache=None, transport=C.DEFAULT_TRANSPORT, - conditional='True', groups={}, callbacks=None, verbose=False, - debug=False, sudo=False, extra_vars=None, - module_vars=None, is_playbook=False, inventory=None): - + def __init__(self, + host_list=C.DEFAULT_HOST_LIST, + module_path=C.DEFAULT_MODULE_PATH, + module_name=C.DEFAULT_MODULE_NAME, + module_args=C.DEFAULT_MODULE_ARGS, + forks=C.DEFAULT_FORKS, + timeout=C.DEFAULT_TIMEOUT, + pattern=C.DEFAULT_PATTERN, + remote_user=C.DEFAULT_REMOTE_USER, + remote_pass=C.DEFAULT_REMOTE_PASS, + remote_port=C.DEFAULT_REMOTE_PORT, + sudo_pass=C.DEFAULT_SUDO_PASS, + background=0, + basedir=None, + setup_cache=None, + transport=C.DEFAULT_TRANSPORT, + conditional='True', + groups={}, + callbacks=None, + verbose=False, + debug=False, + sudo=False, + extra_vars=None, + module_vars=None, + is_playbook=False, + inventory=None): if setup_cache is None: setup_cache = {} if basedir is None: @@ -132,25 +148,16 @@ class Runner(object): @classmethod def parse_hosts(cls, host_list, override_hosts=None, extra_vars=None): ''' parse the host inventory file, returns (hosts, groups) ''' + if override_hosts is None: inventory = ansible.inventory.Inventory(host_list, extra_vars) else: - inventory = ansible.inventory.Inventory(override_hosts) + inventory = ansible.inventory.Inventory(override_hosts, extra_vars) return inventory.host_list, inventory.groups # ***************************************************** - def _connect(self, host): - ''' connects to a host, returns (is_successful, connection_object OR traceback_string) ''' - - try: - return [ True, self.connector.connect(host) ] - except errors.AnsibleConnectionFailed, e: - return [ False, "FAILED: %s" % str(e) ] - - # ***************************************************** - def _return_from_module(self, conn, host, result, err, executed=None): ''' helper function to handle JSON parsing of results ''' @@ -510,10 +517,15 @@ class Runner(object): def _executor_internal(self, host): ''' callback executed in parallel for each host. returns (hostname, connected_ok, extra) ''' - ok, conn = self._connect(host) - if not ok: - return [ host, False, conn , None] - + host_variables = self.inventory.get_variables(host, self.extra_vars) + port = host_variables.get('ansible_ssh_port', self.remote_port) + + conn = None + try: + conn = self.connector.connect(host, port) + except errors.AnsibleConnectionFailed, e: + return [ host, False, "FAILED: %s" % str(e), None ] + cache = self.setup_cache.get(host, {}) module_name = utils.template(self.module_name, cache)