Repository: ansible-collections/community.general

Issue:
Instead of adding a new host into the ssh config, existing host gets updated
### Summary

While using the `community.general.ssh_config` plugin, if new host hame is the part of the already existed host (not fully matched, but the existing host name contains the new host name), then new host is not added to the config, but existing one gets updated with the new config. 

### Issue Type

Bug Report

### Component Name

`community.general.ssh_config` plugin

### Ansible Version

```console (paste below)
$ ansible --version
ansible 2.10.2
  config file = ansible.cfg
  configured module search path = ['~/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = ~/venvs/ansible/lib/python3.8/site-packages/ansible
  executable location = ~/venvs/ansible/bin/ansible
  python version = 3.8.6 (default, Oct  9 2020, 06:03:53) [Clang 10.0.1 (clang-1001.0.46.3)]
```


### Configuration

```console (paste below)
$ ansible-config dump --only-changed
DEFAULT_BECOME(~/ansible.cfg) = False
DEFAULT_BECOME_ASK_PASS(~/ansible.cfg) = False
DEFAULT_BECOME_METHOD(~/ansible.cfg) = sudo
DEFAULT_BECOME_USER(~/ansible.cfg) = root
DEFAULT_FORKS(~/ansible.cfg) = 20
DEFAULT_HOST_LIST(~/ansible.cfg) = ['~/inventory']
DEFAULT_REMOTE_USER(~/ansible.cfg) = user
HOST_KEY_CHECKING(~/ansible.cfg) = False
INTERPRETER_PYTHON(~/ansible.cfg) = /usr/bin/python
```


### OS / Environment

ProductName:    Mac OS X
ProductVersion: 10.14.6

### Steps to Reproduce

Run the next playbook:
<!--- Paste example playbooks or commands between quotes below -->
```yaml (paste below)
- name: Set up ssh config
  hosts: all
  vars:
    config:
      - host: host_prod_west
        hostname: host_prod_west.com
        identity_file: /Users/user/.ssh/west-private-key
      - host: host_prod
        hostname: host_prod.com
        identity_file: /Users/user/.ssh/new-private-key
  tasks:
    - name: Add a hosts
      community.general.ssh_config:
        group: staff
        user: "{{ ansible_user }}"
        host: "{{ item.host }}"
        hostname: "{{ item.hostname }}"
        identity_file: "{{ item.identity_file }}"
        state: present
      loop: "{{config}}"
```


### Expected Results

I expected to get the next config file:

```console
Host host_prod_west
    identityfile /Users/user/.ssh/west-private-key
    hostname host_prod_west.com

Host host_prod
    identityfile /Users/user/.ssh/new-private-key
    hostname host_prod.com
```

### Actual Results

Instead of adding a new host, the first host got updated with new 

```console (paste below)
Host host_prod_west
    identityfile /Users/user/.ssh/new-private-key
    hostname host_prod.com
```

Ansible output logs:
```console
changed: [managed.node] => (item={'host': 'host_prod_west', 'hostname': 'host_prod_west.com', 'identity_file': '/Users/user/.ssh/west-private-key'}) => {"ansible_loop_var": "item", "changed": true, "hosts_added": ["host_prod_west"], "hosts_change_diff": [], "hosts_changed": [], "hosts_removed": [], "item": {"host": "host_prod_west", "hostname": "host_prod_west.com", "identity_file": "/Users/user/.ssh/west-private-key"}}
changed: [managed.node] => (item={'host': 'host_prod', 'hostname': 'host_prod.com', 'identity_file': '/Users/user/.ssh/new-private-key'}) => {"ansible_loop_var": "item", "changed": true, "hosts_added": [], "hosts_change_diff": [{"host_prod_west": {"new": {"hostname": "host_prod.com", "identityfile": "/Users/user/.ssh/new-private-key"}, "old": {"hostname": "host_prod.com", "identityfile": "/Users/user/.ssh/new-private-key"}}}], "hosts_changed": ["host_prod_west"], "hosts_removed": [], "item": {"host": "host_prod", "hostname": "host_prod.com", "identity_file": "/Users/user/.ssh/new-private-key"}}
```

### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct


Discussion:
Files identified in the description:
None

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
!component = plugins/modules/system/ssh_config.py
Files identified in the description:
* [``](https://github.com/ansible-collections/community.general/blob/master/)

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
Thanks for reporting @drenout ! I intend to take a look in the next days but if you (or anyone else) wants fix the problem, we will be more than happy to review a PR for it. Cheers!
!component=plugins/modules/system/ssh_config.py

(no spaces around the equal sign now, sigh)
Files identified in the description:
* [`plugins/modules/system/ssh_config.py`](https://github.com/ansible-collections/community.general/blob/master/plugins/modules/system/ssh_config.py)

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @Akasurde @gaqzi
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
Thanks for the quick response @russoz ! Will try to fix the bug and publish the PR
@russoz Almost noon here in the Middle-Earth with the hobbits, so I sometimes get to the tickets sooner than the folks elsewhere :-)

Let us know if you need help. There is also an IRC channel (but got to keep an eye on changes because of this on-going freenode snafu).
Cheers!

Resolving patch:
diff --git a/plugins/modules/system/ssh_config.py b/plugins/modules/system/ssh_config.py
--- a/plugins/modules/system/ssh_config.py
+++ b/plugins/modules/system/ssh_config.py
@@ -209,6 +209,8 @@ def ensure_state(self):
         hosts_removed = []
         hosts_added = []
 
+        hosts_result = [host for host in hosts_result if host['host'] == self.host]
+
         if hosts_result:
             for host in hosts_result:
                 if state == 'absent':


Test patch:
diff --git a/tests/integration/targets/ssh_config/tasks/main.yml b/tests/integration/targets/ssh_config/tasks/main.yml
--- a/tests/integration/targets/ssh_config/tasks/main.yml
+++ b/tests/integration/targets/ssh_config/tasks/main.yml
@@ -183,3 +183,39 @@
     that:
       - not mut_ex.changed
       - "'parameters are mutually exclusive' in mut_ex.msg"
+
+- name: Add a full name host
+  community.general.ssh_config:
+    ssh_config_file: "{{ ssh_config_test }}"
+    host: "full_name"
+    hostname: full_name.com
+    identity_file: '{{ ssh_private_key }}'
+    port: '2223'
+    state: present
+  register: full_name
+
+- name: Check if changes are made
+  assert:
+    that:
+      - full_name is changed
+      - full_name.hosts_added == ["full_name"]
+      - full_name.hosts_changed == []
+      - full_name.hosts_removed == []
+
+- name: Add a host with name which is contained in full name host
+  community.general.ssh_config:
+    ssh_config_file: "{{ ssh_config_test }}"
+    host: "full"
+    hostname: full.com
+    identity_file: '{{ ssh_private_key }}'
+    port: '2223'
+    state: present
+  register: short_name
+
+- name: Check that short name host is added and full name host is not updated
+  assert:
+    that:
+      - short_name is changed
+      - short_name.hosts_added == ["full"]
+      - short_name.hosts_changed == []
+      - short_name.hosts_removed == []