Repository: ansible/ansible-modules-core

Issue:
Synchronize: a problem with a non-standard ssh port
##### ISSUE TYPE

<!--- Pick one below and delete the rest: -->
- Bug Report
##### COMPONENT NAME

<!--- Name of the plugin/module/task -->

synchronize
##### ANSIBLE VERSION

```
<!--- Paste verbatim output from “ansible --version” between quotes -->
ansible 2.1.0.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides
```
##### CONFIGURATION

<!---
Mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).
-->

[defaults]
vault_password_file=.vault_pass.txt
##### OS / ENVIRONMENT

<!---
Mention the OS you are running Ansible from, and the OS you are
managing, or say “N/A” for anything that is not platform-specific.
-->

Ubuntu 16.04
##### SUMMARY

<!--- Explain the problem briefly -->

I have the following option in my /etc/ssh/ssh_config : 

```
 Port 2222
```

I want to sync some directory to a machine that has this address: 10.0.3.188:22.

I get an error 

```
 ssh: connect to host 10.0.3.188 port 2222: Connection refused
```

This [code](https://github.com/ansible/ansible-modules-core/blob/c52f475c64372042daab4ebc0660a2782b71d10d/files/synchronize.py#L414-L417) is responsible for this behavior. Why don't set port explicitly whatever its value is?



Discussion:
@dvarrazzo are you using the `dest_port` param here or are you expecting the module to have a feature that recognizes the a src/dest is a remote and has a port in the URI?

I'm using the following simple code

```
- synchronize:
    dest_port: 22
    src: "{{build_dir}}"
    dest: /tmp
```

I'm expecting that this `dest_port` will be used when connecting to a remote.
But instead of it, the port from /etc/ssh/ssh_config is in use (I have specified there Port 2222).
So I get `Connection refused` error.

Hum. OK. I think I understand what's going on. Either the module has to parse the ssh_config to get the Port in the event its not 22 like in your case or the logic needs to be simplified to use 22 even if its already the default and is unnecessary. I'm leading towards the latter here.


Resolving patch:
diff --git a/files/synchronize.py b/files/synchronize.py
--- a/files/synchronize.py
+++ b/files/synchronize.py
@@ -35,7 +35,7 @@
   dest_port:
     description:
       - Port number for ssh on the destination host. Prior to ansible 2.0, the ansible_ssh_port inventory var took precedence over this value.
-    default: Value of ansible_ssh_port for this host, remote_port config setting, or 22 if none of those are set
+    default: Value of ansible_ssh_port for this host, remote_port config setting, or the value from ssh client configuration if none of those are set
     version_added: "1.5"
   mode:
     description:
@@ -281,7 +281,7 @@ def main():
         argument_spec = dict(
             src = dict(required=True),
             dest = dict(required=True),
-            dest_port = dict(default=22, type='int'),
+            dest_port = dict(default=None, type='int'),
             delete = dict(default='no', type='bool'),
             private_key = dict(default=None),
             rsync_path = dict(default=None),
@@ -411,10 +411,13 @@ def main():
         module.fail_json(msg='either src or dest must be a localhost', rc=1)
 
     if not source.startswith('"rsync://') and not dest.startswith('"rsync://'):
-        if dest_port != 22:
+        # If the user specified a port value
+        # Note:  The action plugin takes care of setting this to a port from
+        # inventory if the user didn't specify an explict dest_port
+        if dest_port is not None:
             cmd += " --rsh 'ssh %s %s -o Port=%s'" % (private_key, ssh_opts, dest_port)
         else:
-            cmd += " --rsh 'ssh %s %s'" % (private_key, ssh_opts)  # need ssh param
+            cmd += " --rsh 'ssh %s %s'" % (private_key, ssh_opts)
 
     if rsync_path:
         cmd = cmd + " --rsync-path=%s" % (rsync_path)


Test patch: