Repository: ansible-collections/community.general

Issue:
`community.general.github_deploy_key` fails on force, if no SSH key exists to override
### Summary

When I try to add a deploy key with the option `force: true` and there is no (matching) key set on the repository, the task fails. 
When using `force: false` on first run and setting to `force: true` afterwards, it works.

### Issue Type

Bug Report

### Component Name

github_deploy_key

### Ansible Version

```console (paste below)
$ ansible --version
ansible [core 2.14.1]
  config file = None
  configured module search path = ['/Users/philipp/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/Cellar/ansible/7.1.0/libexec/lib/python3.11/site-packages/ansible
  ansible collection location = /Users/philipp/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.11.1 (main, Dec 23 2022, 09:39:26) [Clang 14.0.0 (clang-1400.0.29.202)] (/usr/local/Cellar/ansible/7.1.0/libexec/bin/python3.11)
  jinja version = 3.1.2
  libyaml = True
```


### Community.general Version

```console (paste below)
$ ansible-galaxy collection list community.general
# /Users/philipp/.ansible/collections/ansible_collections
Collection        Version
----------------- -------
community.general 6.3.0  

# /usr/local/Cellar/ansible/7.1.0/libexec/lib/python3.11/site-packages/ansible_collections
Collection        Version
----------------- -------
community.general 6.1.0  
```

(also tested with 6.2.0 and 6.1.0)


### Configuration

```console (paste below)
$ ansible-config dump --only-changed
CONFIG_FILE() = None
```


### OS / Environment

MacOS

### Steps to Reproduce

<!--- Paste example playbooks or commands between quotes below -->
```yaml (paste below)
---
- name: Add deploy key to GitHub repo
  hosts: all
  vars:
    repo_owner: "..."
    repo_name: "..."
    ssh_key_str: "..."
    github_token: "..."

  tasks:

    - name: Add new read-only deploy key to GitHub
      community.general.github_deploy_key:
        owner: "{{repo_owner}}"
        repo: "{{repo_name}}"
        name: "ansible-deploy-key"
        key: "{{ssh_key_str}}"
        read_only: true
        force: true
        token: "{{github_token}}"
```


### Expected Results

I expect, that the task does not fail with `force` set to `true`, even if there is no deploy key added to the repository so far.

### Actual Results

```console (paste below)
Traceback (most recent call last):
  File "/root/.ansible/tmp/ansible-tmp-1675154445.252015-8599-252924341828508/AnsiballZ_github_deploy_key.py", line 107, in <module>
    _ansiballz_main()
  File "/root/.ansible/tmp/ansible-tmp-1675154445.252015-8599-252924341828508/AnsiballZ_github_deploy_key.py", line 99, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File "/root/.ansible/tmp/ansible-tmp-1675154445.252015-8599-252924341828508/AnsiballZ_github_deploy_key.py", line 47, in invoke_module
    runpy.run_module(mod_name='ansible_collections.community.general.plugins.modules.github_deploy_key', init_globals=dict(_module_fqn='ansible_collections.community.general.plugins.modules.github_deploy_key', _modlib_path=modlib_path),
  File "/usr/lib/python3.10/runpy.py", line 224, in run_module
    return _run_module_code(code, init_globals, run_name, mod_spec)
  File "/usr/lib/python3.10/runpy.py", line 96, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "/usr/lib/python3.10/runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "/tmp/ansible_community.general.github_deploy_key_payload_tlt_njm5/ansible_community.general.github_deploy_key_payload.zip/ansible_collections/community/general/plugins/modules/github_deploy_key.py", line 340, in <module>
  File "/tmp/ansible_community.general.github_deploy_key_payload_tlt_njm5/ansible_community.general.github_deploy_key_payload.zip/ansible_collections/community/general/plugins/modules/github_deploy_key.py", line 328, in main
  File "/tmp/ansible_community.general.github_deploy_key_payload_tlt_njm5/ansible_community.general.github_deploy_key_payload.zip/ansible_collections/community/general/plugins/modules/github_deploy_key.py", line 231, in get_existing_key
  File "/tmp/ansible_community.general.github_deploy_key_payload_tlt_njm5/ansible_community.general.github_deploy_key_payload.zip/ansible_collections/community/general/plugins/modules/github_deploy_key.py", line 223, in paginate
KeyError: 'link'
```
https://github.com/ansible-collections/community.general/blob/868699dc5f8ecfbf007681419dfe07b0c5db0ac2/plugins/modules/github_deploy_key.py#L223


### Code of Conduct

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


Discussion:
Files identified in the description:
* [`plugins/modules/github_deploy_key.py`](https://github.com/ansible-collections/community.general/blob/main/plugins/modules/github_deploy_key.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 @bincyber @stpierre
[click here for bot help](https://github.com/ansible/ansibullbot/blob/devel/ISSUE_HELP.md)
<!--- boilerplate: notify --->
Hello to all,

We are facing the same problem. Are there any updates on this issue? As we try to automatically insert/remove ssh keys for argocd repo access, using force: false is not really an option. The deploy keys in github must be in sync with the ones ansible has created and which are inserted into argocd's configuration.

Best regards,
Manuel
I also encountered this issue; it's actually unrelated to the use of `force`, the bug is with the pagination code.

If there's at least one deploy key present, but not enough to trigger pagination, the module fails with a `KeyError` on line 230, as the key `link` isn't present in the response info. A simple modification of
`info.get('link', '')` fixes the issue, confirmed by using a local module.

I'll open a PR Now

Resolving patch:
diff --git a/plugins/modules/github_deploy_key.py b/plugins/modules/github_deploy_key.py
--- a/plugins/modules/github_deploy_key.py
+++ b/plugins/modules/github_deploy_key.py
@@ -227,7 +227,7 @@ def paginate(self, url):
                 yield self.module.from_json(resp.read())
 
                 links = {}
-                for x, y in findall(r'<([^>]+)>;\s*rel="(\w+)"', info["link"]):
+                for x, y in findall(r'<([^>]+)>;\s*rel="(\w+)"', info.get("link", '')):
                     links[y] = x
 
                 url = links.get('next')


Test patch: