Repository: ansible-collections/community.general

Issue:
gitlab_deploy_key in check mode deletes the deploy key
### Summary

When I run task `community.general.gitlab_deploy_key` in a playbook with `--check --diff` mode after the deploy key has been added I would expect it to do no action.

Instead, running in `--check` mode **removes** the deploy key from the Gitlab project (!).

### Issue Type

Bug Report

### Component Name

gitlab_deploy_key

### Ansible Version

```console
$ ansible --version
ansible [core 2.11.5]
  config file = /Users/myuser/git/auto/ansible.cfg
  configured module search path = ['/Users/myuser/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/myuser/git/auto/.venv/lib/python3.9/site-packages/ansible
  ansible collection location = /Users/myuser/git/auto/galaxy-roles
  executable location = /Users/myuser/git/auto/.venv/bin/ansible
  python version = 3.9.7 (default, Oct 13 2021, 06:45:31) [Clang 13.0.0 (clang-1300.0.29.3)]
  jinja version = 3.0.1
  libyaml = True
$ pip freeze | grep ansible
ansible==4.2.0
ansible-compat==0.5.0
ansible-core==2.11.5
ansible-lint==4.3.7
```


### Community.general Version

```console
ansible-galaxy collection list community.general

# /Users/myuser/git/auto/galaxy-roles/ansible_collections
Collection        Version
----------------- -------
community.general 3.8.0

# /Users/myuser/git/auto/.venv/lib/python3.9/site-packages/ansible_collections
Collection        Version
----------------- -------
community.general 3.3.0
```

Verified with both 3.3.0 and 3.8.0


### Configuration

```console (paste below)
ansible-config dump --only-changed
ANSIBLE_COW_SELECTION(/Users/myuser/git/auto/ansible.cfg) = stegosaurus
ANSIBLE_FORCE_COLOR(/Users/myuser/git/auto/ansible.cfg) = True
ANSIBLE_NOCOWS(/Users/myuser/git/auto/ansible.cfg) = True
COLLECTIONS_PATHS(/Users/myuser/git/auto/ansible.cfg) = ['/Users/myuser/git/auto/galaxy-roles']
DEFAULT_FORKS(/Users/myuser/git/auto/ansible.cfg) = 20
DEFAULT_GATHER_TIMEOUT(/Users/myuser/git/auto/ansible.cfg) = 30
DEFAULT_HOST_LIST(/Users/myuser/git/auto/ansible.cfg) = ['/Users/myuser/git/auto/inventory/all.yml']
DEFAULT_LOAD_CALLBACK_PLUGINS(/Users/myuser/git/auto/ansible.cfg) = False
DEFAULT_LOG_PATH(/Users/myuser/git/auto/ansible.cfg) = /Users/myuser/git/auto/log_ansible.txt
DEFAULT_MANAGED_STR(/Users/myuser/git/auto/ansible.cfg) = This file is being managed with Ansible. Do NOT update it manually.
DEFAULT_ROLES_PATH(/Users/myuser/git/auto/ansible.cfg) = ['/Users/myuser/git/auto/galaxy-roles', '/Users/myuser/git/auto/roles']
DEFAULT_STDOUT_CALLBACK(/Users/myuser/git/auto/ansible.cfg) = yaml
DEFAULT_TIMEOUT(/Users/myuser/git/auto/ansible.cfg) = 30
DEFAULT_TRANSPORT(/Users/myuser/git/auto/ansible.cfg) = ssh
DEFAULT_VAULT_PASSWORD_FILE(env: ANSIBLE_VAULT_PASSWORD_FILE) = /Users/myuser/.ansible-vault-pass
DISPLAY_SKIPPED_HOSTS(env: ANSIBLE_DISPLAY_SKIPPED_HOSTS) = True
HOST_KEY_CHECKING(/Users/myuser/git/auto/ansible.cfg) = False
INTERPRETER_PYTHON(/Users/myuser/git/auto/ansible.cfg) = /usr/bin/python3
INVENTORY_ENABLED(/Users/myuser/git/auto/ansible.cfg) = ['auto', 'vmware_vm_inventory', 'yaml', 'host_list']

```


### OS / Environment

MacOS BigSur

```console
$ uname -r -s
Darwin 20.6.0
```

### Steps to Reproduce

<!--- Paste example playbooks or commands between quotes below -->

Ran with:

```
$ ansible-playbook myplaybook.yml --ask-become-pass --diff --check
```

Something along the lines of (extracted from a private Ansible role):
```yaml
- name: Setup the key
  hosts: myhost
  vars:
    my_token: "foobartokenREDACTED"
  become: true
  tasks:
    - name: Generate SSH key pair
      community.crypto.openssh_keypair:
        comment: "myuser@{{ inventory_hostname }}"
        size: 4096
        type: rsa
        owner: "myuser"
        group: "mygroup"
        path: "~myuser/.ssh/id_rsa"
      register: ssh_keys
    - name: Add the deploy key to Gitlab repo
      delegate_to: localhost
      become: false
      community.general.gitlab_deploy_key:
        api_url: "gitlab.example.com"
        api_token: "{{ my_token }}"
        project: "foo/bar"
        title: "added by Ansible"
        state: present
        key: "{{ ssh_keys.public_key }}"
```


### Expected Results

no action - it's check mode

### Actual Results

* task is marked as "changed"
* SSH deploy key is **removed** from the Gitlab project
* inspecting the logs on Gitlab side shows (slightly redacted to hide the secrets):

```console (paste below)
gitlab-rails/production.log:Started DELETE "/api/v4/projects/867/deploy_keys/398" for 192.168.1.2 at 2021-10-27 10:22:03 +0100
nginx/gitlab_access.log:192.168.1.2 - myuser [27/Oct/2021:10:22:03 +0100] "DELETE /api/v4/projects/867/deploy_keys/398 HTTP/1.1" 204 0 "" "python-gitlab/2.10.1" -
```


### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct
gitlab_deploy_key in check mode deletes the deploy key
### Summary

When I run task `community.general.gitlab_deploy_key` in a playbook with `--check --diff` mode after the deploy key has been added I would expect it to do no action.

Instead, running in `--check` mode **removes** the deploy key from the Gitlab project (!).

### Issue Type

Bug Report

### Component Name

gitlab_deploy_key

### Ansible Version

```console
$ ansible --version
ansible [core 2.11.5]
  config file = /Users/myuser/git/auto/ansible.cfg
  configured module search path = ['/Users/myuser/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/myuser/git/auto/.venv/lib/python3.9/site-packages/ansible
  ansible collection location = /Users/myuser/git/auto/galaxy-roles
  executable location = /Users/myuser/git/auto/.venv/bin/ansible
  python version = 3.9.7 (default, Oct 13 2021, 06:45:31) [Clang 13.0.0 (clang-1300.0.29.3)]
  jinja version = 3.0.1
  libyaml = True
$ pip freeze | grep ansible
ansible==4.2.0
ansible-compat==0.5.0
ansible-core==2.11.5
ansible-lint==4.3.7
```


### Community.general Version

```console
ansible-galaxy collection list community.general

# /Users/myuser/git/auto/galaxy-roles/ansible_collections
Collection        Version
----------------- -------
community.general 3.8.0

# /Users/myuser/git/auto/.venv/lib/python3.9/site-packages/ansible_collections
Collection        Version
----------------- -------
community.general 3.3.0
```

Verified with both 3.3.0 and 3.8.0


### Configuration

```console (paste below)
ansible-config dump --only-changed
ANSIBLE_COW_SELECTION(/Users/myuser/git/auto/ansible.cfg) = stegosaurus
ANSIBLE_FORCE_COLOR(/Users/myuser/git/auto/ansible.cfg) = True
ANSIBLE_NOCOWS(/Users/myuser/git/auto/ansible.cfg) = True
COLLECTIONS_PATHS(/Users/myuser/git/auto/ansible.cfg) = ['/Users/myuser/git/auto/galaxy-roles']
DEFAULT_FORKS(/Users/myuser/git/auto/ansible.cfg) = 20
DEFAULT_GATHER_TIMEOUT(/Users/myuser/git/auto/ansible.cfg) = 30
DEFAULT_HOST_LIST(/Users/myuser/git/auto/ansible.cfg) = ['/Users/myuser/git/auto/inventory/all.yml']
DEFAULT_LOAD_CALLBACK_PLUGINS(/Users/myuser/git/auto/ansible.cfg) = False
DEFAULT_LOG_PATH(/Users/myuser/git/auto/ansible.cfg) = /Users/myuser/git/auto/log_ansible.txt
DEFAULT_MANAGED_STR(/Users/myuser/git/auto/ansible.cfg) = This file is being managed with Ansible. Do NOT update it manually.
DEFAULT_ROLES_PATH(/Users/myuser/git/auto/ansible.cfg) = ['/Users/myuser/git/auto/galaxy-roles', '/Users/myuser/git/auto/roles']
DEFAULT_STDOUT_CALLBACK(/Users/myuser/git/auto/ansible.cfg) = yaml
DEFAULT_TIMEOUT(/Users/myuser/git/auto/ansible.cfg) = 30
DEFAULT_TRANSPORT(/Users/myuser/git/auto/ansible.cfg) = ssh
DEFAULT_VAULT_PASSWORD_FILE(env: ANSIBLE_VAULT_PASSWORD_FILE) = /Users/myuser/.ansible-vault-pass
DISPLAY_SKIPPED_HOSTS(env: ANSIBLE_DISPLAY_SKIPPED_HOSTS) = True
HOST_KEY_CHECKING(/Users/myuser/git/auto/ansible.cfg) = False
INTERPRETER_PYTHON(/Users/myuser/git/auto/ansible.cfg) = /usr/bin/python3
INVENTORY_ENABLED(/Users/myuser/git/auto/ansible.cfg) = ['auto', 'vmware_vm_inventory', 'yaml', 'host_list']

```


### OS / Environment

MacOS BigSur

```console
$ uname -r -s
Darwin 20.6.0
```

### Steps to Reproduce

<!--- Paste example playbooks or commands between quotes below -->

Ran with:

```
$ ansible-playbook myplaybook.yml --ask-become-pass --diff --check
```

Something along the lines of (extracted from a private Ansible role):
```yaml
- name: Setup the key
  hosts: myhost
  vars:
    my_token: "foobartokenREDACTED"
  become: true
  tasks:
    - name: Generate SSH key pair
      community.crypto.openssh_keypair:
        comment: "myuser@{{ inventory_hostname }}"
        size: 4096
        type: rsa
        owner: "myuser"
        group: "mygroup"
        path: "~myuser/.ssh/id_rsa"
      register: ssh_keys
    - name: Add the deploy key to Gitlab repo
      delegate_to: localhost
      become: false
      community.general.gitlab_deploy_key:
        api_url: "gitlab.example.com"
        api_token: "{{ my_token }}"
        project: "foo/bar"
        title: "added by Ansible"
        state: present
        key: "{{ ssh_keys.public_key }}"
```


### Expected Results

no action - it's check mode

### Actual Results

* task is marked as "changed"
* SSH deploy key is **removed** from the Gitlab project
* inspecting the logs on Gitlab side shows (slightly redacted to hide the secrets):

```console (paste below)
gitlab-rails/production.log:Started DELETE "/api/v4/projects/867/deploy_keys/398" for 192.168.1.2 at 2021-10-27 10:22:03 +0100
nginx/gitlab_access.log:192.168.1.2 - myuser [27/Oct/2021:10:22:03 +0100] "DELETE /api/v4/projects/867/deploy_keys/398 HTTP/1.1" 204 0 "" "python-gitlab/2.10.1" -
```


### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct


Discussion:
Files identified in the description:
* [`plugins/modules/source_control/gitlab/gitlab_deploy_key.py`](https://github.com/ansible-collections/community.general/blob/main/plugins/modules/source_control/gitlab/gitlab_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 @Lunik @Shaps @dj-wasabi @marwatk @metanovii @scodeman @waheedi @zanssa
[click here for bot help](https://github.com/ansible/ansibullbot/blob/devel/ISSUE_HELP.md)
<!--- boilerplate: notify --->
The bug is here: https://github.com/ansible-collections/community.general/blob/stable-3/plugins/modules/source_control/gitlab/gitlab_deploy_key.py#L152 This needs to be guarded in `if not self._module.check_mode:`.
When looking at code:

https://github.com/ansible-collections/community.general/blob/a362879ff6bd280e01616133f4135aaf837453b9/plugins/modules/source_control/gitlab/gitlab_deploy_key.py#L151

the original key seems to be removed regardless of `check mode` whenever it doesn't match the value (and because playbook is ran in `--check` mode, there is indeed a mismatch).

Feel free to create a PR to fix this (on `main` branch, with a [changelog fragment](https://docs.ansible.com/ansible/devel/community/development_process.html#changelogs-how-to)) if you have time :)
@felixfontein Thanks, giving it a try! :) 

https://github.com/ansible-collections/community.general/pull/3622
Files identified in the description:
* [`plugins/modules/source_control/gitlab/gitlab_deploy_key.py`](https://github.com/ansible-collections/community.general/blob/main/plugins/modules/source_control/gitlab/gitlab_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 @Lunik @Shaps @dj-wasabi @marwatk @metanovii @scodeman @waheedi @zanssa
[click here for bot help](https://github.com/ansible/ansibullbot/blob/devel/ISSUE_HELP.md)
<!--- boilerplate: notify --->
The bug is here: https://github.com/ansible-collections/community.general/blob/stable-3/plugins/modules/source_control/gitlab/gitlab_deploy_key.py#L152 This needs to be guarded in `if not self._module.check_mode:`.
When looking at code:

https://github.com/ansible-collections/community.general/blob/a362879ff6bd280e01616133f4135aaf837453b9/plugins/modules/source_control/gitlab/gitlab_deploy_key.py#L151

the original key seems to be removed regardless of `check mode` whenever it doesn't match the value (and because playbook is ran in `--check` mode, there is indeed a mismatch).

Feel free to create a PR to fix this (on `main` branch, with a [changelog fragment](https://docs.ansible.com/ansible/devel/community/development_process.html#changelogs-how-to)) if you have time :)
@felixfontein Thanks, giving it a try! :) 

https://github.com/ansible-collections/community.general/pull/3622

Resolving patch:
diff --git a/plugins/modules/source_control/gitlab/gitlab_deploy_key.py b/plugins/modules/source_control/gitlab/gitlab_deploy_key.py
--- a/plugins/modules/source_control/gitlab/gitlab_deploy_key.py
+++ b/plugins/modules/source_control/gitlab/gitlab_deploy_key.py
@@ -149,7 +149,8 @@ def createOrUpdateDeployKey(self, project, key_title, key_key, options):
         #   GitLab REST API, so for that case we need to delete and
         #   than recreate the key
         if self.deployKeyObject and self.deployKeyObject.key != key_key:
-            self.deployKeyObject.delete()
+            if not self._module.check_mode:
+                self.deployKeyObject.delete()
             self.deployKeyObject = None
 
         # Because we have already call existsDeployKey in main()


Test patch: