Repository: ansible-collections/community.general

Issue:
IdentitiesOnly for ssh_config
### Summary

Could you please support the Attribute `IdentitiesOnly`?

### Issue Type

Feature Idea

### Component Name

ssh_config

### Additional Information

```yaml (paste below)
- name: Another SSH Host Configuration
  community.general.ssh_config:
    user: "myniceusername"
    host: "dings.bums.com 192.168.42.23"
    hostname: "192.168.42.23"
    identity_file: "~/.ssh/ed25519_irish.pub"
    identities_only: yes
    state: present
```


### Code of Conduct

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


Discussion:
Files identified in the description:
* [`plugins/modules/system/ssh_config.py`](https://github.com/ansible-collections/community.general/blob/main/plugins/modules/system/ssh_config.py)

If these files are incorrect, 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/devel/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @Akasurde @gaqzi
[click here for bot help](https://github.com/ansible/ansibullbot/blob/devel/ISSUE_HELP.md)
<!--- boilerplate: notify --->
Files identified in the description:
* [`plugins/modules/ssh_config.py`](https://github.com/ansible-collections/community.general/blob/main/plugins/modules/ssh_config.py)

If these files are incorrect, 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/devel/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
From my dupe issue #6801:

---

When multiple ssh keys are defined for a host, one quickly runs into connection problems.

The solution is to use `IdentitiesOnly` in `~/.ssh/config`, e.g.
```ini
Host github1
    Hostname github.com
    User git
    IdentityFile /home/me/.ssh/id_rsa_github_1
    IdentitiesOnly yes                           # <-----------------
Host github2
    Hostname github.com
    User git
    IdentityFile /home/me/.ssh/id_rsa_github_2
    IdentitiesOnly yes                           # <-----------------
```
But the [`community.general.ssh_config`](https://docs.ansible.com/ansible/latest/collections/community/general/ssh_config_module.html) does not expose an equivalent parameter.

Please consider adding one (with default false)? Then we could do this:
```yml
- community.general.ssh_config:
    user: me
    host: github1
    hostname: github.com
    identity_file: /home/me/.ssh/id_rsa_github_1
    identities_only: true                         # <------------------- default false
- community.general.ssh_config:
    user: me
    host: github2
    hostname: github.com
    identity_file: /home/me/.ssh/id_rsa_github_2
    identities_only: true                         # <------------------- default false
```

From `$ man ssh_config`:
```
IdentitiesOnly
        Specifies that ssh(1) should only use the configured authentica‐
        tion identity and certificate files (either the default files, or
        those explicitly configured in the ssh_config files or passed on
        the ssh(1) command-line), even if ssh-agent(1) or a
        PKCS11Provider or SecurityKeyProvider offers more identities.
        The argument to this keyword must be yes or no (the default).
        This option is intended for situations where ssh-agent offers
        many different identities.
```


Resolving patch:
diff --git a/plugins/modules/ssh_config.py b/plugins/modules/ssh_config.py
--- a/plugins/modules/ssh_config.py
+++ b/plugins/modules/ssh_config.py
@@ -72,6 +72,15 @@
         when connecting to this host.
       - File need to exist and have mode V(0600) to be valid.
     type: path
+  identities_only:
+    description:
+      - Specifies that SSH should only use the configured authentication
+        identity and certificate files (either the default files, or
+        those explicitly configured in the C(ssh_config) files or passed on
+        the ssh command-line), even if ssh-agent or a PKCS11Provider or
+        SecurityKeyProvider offers more identities.
+    type: bool
+    version_added: 8.2.0
   user_known_hosts_file:
     description:
       - Sets the user known hosts file option.
@@ -245,6 +254,7 @@ def ensure_state(self):
             hostname=self.params.get('hostname'),
             port=self.params.get('port'),
             identity_file=self.params.get('identity_file'),
+            identities_only=convert_bool(self.params.get('identities_only')),
             user=self.params.get('remote_user'),
             strict_host_key_checking=self.params.get('strict_host_key_checking'),
             user_known_hosts_file=self.params.get('user_known_hosts_file'),
@@ -342,6 +352,7 @@ def main():
             hostname=dict(type='str'),
             host_key_algorithms=dict(type='str', no_log=False),
             identity_file=dict(type='path'),
+            identities_only=dict(type='bool'),
             port=dict(type='str'),
             proxycommand=dict(type='str', default=None),
             proxyjump=dict(type='str', default=None),


Test patch:
diff --git a/tests/integration/targets/ssh_config/tasks/options.yml b/tests/integration/targets/ssh_config/tasks/options.yml
--- a/tests/integration/targets/ssh_config/tasks/options.yml
+++ b/tests/integration/targets/ssh_config/tasks/options.yml
@@ -16,6 +16,7 @@
     proxycommand: "ssh jumphost.example.com -W %h:%p"
     forward_agent: true
     host_key_algorithms: "+ssh-rsa"
+    identities_only: true
     controlmaster: "auto"
     controlpath: "~/.ssh/sockets/%r@%h-%p"
     controlpersist: yes
@@ -48,6 +49,7 @@
     proxycommand: "ssh jumphost.example.com -W %h:%p"
     forward_agent: true
     host_key_algorithms: "+ssh-rsa"
+    identities_only: true
     controlmaster: "auto"
     controlpath: "~/.ssh/sockets/%r@%h-%p"
     controlpersist: yes
@@ -69,6 +71,7 @@
     proxycommand: "ssh jumphost.example.com -W %h:%p"
     forward_agent: true
     host_key_algorithms: "+ssh-rsa"
+    identities_only: true
     controlmaster: "auto"
     controlpath: "~/.ssh/sockets/%r@%h-%p"
     controlpersist: yes
@@ -94,6 +97,7 @@
       - "'proxycommand ssh jumphost.example.com -W %h:%p' in slurp_ssh_config['content'] | b64decode"
       - "'forwardagent yes' in slurp_ssh_config['content'] | b64decode"
       - "'hostkeyalgorithms +ssh-rsa' in slurp_ssh_config['content'] | b64decode"
+      - "'identitiesonly yes' in slurp_ssh_config['content'] | b64decode"
       - "'controlmaster auto' in slurp_ssh_config['content'] | b64decode"
       - "'controlpath ~/.ssh/sockets/%r@%h-%p' in slurp_ssh_config['content'] | b64decode"
       - "'controlpersist yes' in slurp_ssh_config['content'] | b64decode"
@@ -105,6 +109,7 @@
     proxycommand: "ssh new-jumphost.example.com -W %h:%p"
     forward_agent: false
     host_key_algorithms: "+ssh-ed25519"
+    identities_only: false
     controlmaster: no
     controlpath: "~/.ssh/new-sockets/%r@%h-%p"
     controlpersist: "600"
@@ -128,6 +133,7 @@
     proxycommand: "ssh new-jumphost.example.com -W %h:%p"
     forward_agent: false
     host_key_algorithms: "+ssh-ed25519"
+    identities_only: false
     controlmaster: no
     controlpath: "~/.ssh/new-sockets/%r@%h-%p"
     controlpersist: "600"
@@ -154,6 +160,7 @@
       - "'proxycommand ssh new-jumphost.example.com -W %h:%p' in slurp_ssh_config['content'] | b64decode"
       - "'forwardagent no' in slurp_ssh_config['content'] | b64decode"
       - "'hostkeyalgorithms +ssh-ed25519' in slurp_ssh_config['content'] | b64decode"
+      - "'identitiesonly no' in slurp_ssh_config['content'] | b64decode"
       - "'controlmaster no' in slurp_ssh_config['content'] | b64decode"
       - "'controlpath ~/.ssh/new-sockets/%r@%h-%p' in slurp_ssh_config['content'] | b64decode"
       - "'controlpersist 600' in slurp_ssh_config['content'] | b64decode"
@@ -185,6 +192,7 @@
       - "'proxycommand ssh new-jumphost.example.com -W %h:%p' in slurp_ssh_config['content'] | b64decode"
       - "'forwardagent no' in slurp_ssh_config['content'] | b64decode"
       - "'hostkeyalgorithms +ssh-ed25519' in slurp_ssh_config['content'] | b64decode"
+      - "'identitiesonly no' in slurp_ssh_config['content'] | b64decode"
       - "'controlmaster no' in slurp_ssh_config['content'] | b64decode"
       - "'controlpath ~/.ssh/new-sockets/%r@%h-%p' in slurp_ssh_config['content'] | b64decode"
       - "'controlpersist 600' in slurp_ssh_config['content'] | b64decode"
@@ -234,6 +242,7 @@
       - "'proxycommand ssh new-jumphost.example.com -W %h:%p' not in slurp_ssh_config['content'] | b64decode"
       - "'forwardagent no' not in slurp_ssh_config['content'] | b64decode"
       - "'hostkeyalgorithms +ssh-ed25519' not in slurp_ssh_config['content'] | b64decode"
+      - "'identitiesonly no' not in slurp_ssh_config['content'] | b64decode"
       - "'controlmaster auto' not in slurp_ssh_config['content'] | b64decode"
       - "'controlpath ~/.ssh/sockets/%r@%h-%p' not in slurp_ssh_config['content'] | b64decode"
       - "'controlpersist yes' not in slurp_ssh_config['content'] | b64decode"
@@ -253,6 +262,7 @@
     proxyjump: "jumphost.example.com"
     forward_agent: true
     host_key_algorithms: "+ssh-rsa"
+    identities_only: true
     controlmaster: "auto"
     controlpath: "~/.ssh/sockets/%r@%h-%p"
     controlpersist: yes
@@ -285,6 +295,7 @@
     proxyjump: "jumphost.example.com"
     forward_agent: true
     host_key_algorithms: "+ssh-rsa"
+    identities_only: true
     controlmaster: "auto"
     controlpath: "~/.ssh/sockets/%r@%h-%p"
     controlpersist: yes
@@ -306,6 +317,7 @@
     proxyjump: "jumphost.example.com"
     forward_agent: true
     host_key_algorithms: "+ssh-rsa"
+    identities_only: true
     controlmaster: "auto"
     controlpath: "~/.ssh/sockets/%r@%h-%p"
     controlpersist: yes
@@ -331,6 +343,7 @@
       - "'proxyjump jumphost.example.com' in slurp_ssh_config['content'] | b64decode"
       - "'forwardagent yes' in slurp_ssh_config['content'] | b64decode"
       - "'hostkeyalgorithms +ssh-rsa' in slurp_ssh_config['content'] | b64decode"
+      - "'identitiesonly yes' in slurp_ssh_config['content'] | b64decode"
       - "'controlmaster auto' in slurp_ssh_config['content'] | b64decode"
       - "'controlpath ~/.ssh/sockets/%r@%h-%p' in slurp_ssh_config['content'] | b64decode"
       - "'controlpersist yes' in slurp_ssh_config['content'] | b64decode"
@@ -342,6 +355,7 @@
     proxyjump: "new-jumphost.example.com"
     forward_agent: false
     host_key_algorithms: "+ssh-ed25519"
+    identities_only: false
     controlmaster: no
     controlpath: "~/.ssh/new-sockets/%r@%h-%p"
     controlpersist: "600"
@@ -365,6 +379,7 @@
     proxyjump: "new-jumphost.example.com"
     forward_agent: false
     host_key_algorithms: "+ssh-ed25519"
+    identities_only: false
     controlmaster: no
     controlpath: "~/.ssh/new-sockets/%r@%h-%p"
     controlpersist: "600"
@@ -391,6 +406,7 @@
       - "'proxyjump new-jumphost.example.com' in slurp_ssh_config['content'] | b64decode"
       - "'forwardagent no' in slurp_ssh_config['content'] | b64decode"
       - "'hostkeyalgorithms +ssh-ed25519' in slurp_ssh_config['content'] | b64decode"
+      - "'identitiesonly no' in slurp_ssh_config['content'] | b64decode"
       - "'controlmaster no' in slurp_ssh_config['content'] | b64decode"
       - "'controlpath ~/.ssh/new-sockets/%r@%h-%p' in slurp_ssh_config['content'] | b64decode"
       - "'controlpersist 600' in slurp_ssh_config['content'] | b64decode"
@@ -422,6 +438,7 @@
       - "'proxyjump new-jumphost.example.com' in slurp_ssh_config['content'] | b64decode"
       - "'forwardagent no' in slurp_ssh_config['content'] | b64decode"
       - "'hostkeyalgorithms +ssh-ed25519' in slurp_ssh_config['content'] | b64decode"
+      - "'identitiesonly no' in slurp_ssh_config['content'] | b64decode"
       - "'controlmaster no' in slurp_ssh_config['content'] | b64decode"
       - "'controlpath ~/.ssh/new-sockets/%r@%h-%p' in slurp_ssh_config['content'] | b64decode"
       - "'controlpersist 600' in slurp_ssh_config['content'] | b64decode"
@@ -471,6 +488,7 @@
       - "'proxyjump new-jumphost.example.com' not in slurp_ssh_config['content'] | b64decode"
       - "'forwardagent no' not in slurp_ssh_config['content'] | b64decode"
       - "'hostkeyalgorithms +ssh-ed25519' not in slurp_ssh_config['content'] | b64decode"
+      - "'identitiesonly no' not in slurp_ssh_config['content'] | b64decode"
       - "'controlmaster auto' not in slurp_ssh_config['content'] | b64decode"
       - "'controlpath ~/.ssh/sockets/%r@%h-%p' not in slurp_ssh_config['content'] | b64decode"
       - "'controlpersist yes' not in slurp_ssh_config['content'] | b64decode"