Repository: ansible-collections/community.general

Issue:
gitlab_user: add support to block user account
##### SUMMARY

The gitlab_user module currently supports only two states; present and absent. The python-gitlab package has the ability to also block a user account. Deleting a user is not always desired as all projects owned by that user will be also permanently removed from GitLab too. It would be nice to add a new state of blocked where the user account is blocked instead of deleted.

Original Ansible issue: https://github.com/ansible/ansible/issues/61754
Original Ansible PR: https://github.com/ansible/ansible/pull/61864
Updated Ansible PR: https://github.com/ansible/ansible/pull/66273

##### ISSUE TYPE

- Feature Idea

##### COMPONENT NAME

- gitlab_user

##### ADDITIONAL INFORMATION

Sample usage:

```yaml
- name: Block user account
  gitlab_user:
    server_url: example.gitlab.com
    api_token:  kFCjRgwa/WriXncb7ews6A
    username: mjeco
    email: ""
    name: ""
    password: ""
    state: blocked
```



Discussion:

Resolving patch:
diff --git a/plugins/modules/source_control/gitlab/gitlab_user.py b/plugins/modules/source_control/gitlab/gitlab_user.py
--- a/plugins/modules/source_control/gitlab/gitlab_user.py
+++ b/plugins/modules/source_control/gitlab/gitlab_user.py
@@ -15,10 +15,11 @@
 DOCUMENTATION = '''
 ---
 module: gitlab_user
-short_description: Creates/updates/deletes GitLab Users
+short_description: Creates/updates/deletes/blocks/unblocks GitLab Users
 description:
   - When the user does not exist in GitLab, it will be created.
   - When the user does exists and state=absent, the user will be deleted.
+  - When the user does exists and state=blocked, the user will be blocked.
   - When changes are made to user, the user will be updated.
 notes:
   - From Ansible 2.10 and onwards, name, email and password are optional while deleting the user.
@@ -85,11 +86,11 @@
     choices: ["guest", "reporter", "developer", "master", "maintainer", "owner"]
   state:
     description:
-      - create or delete group.
-      - Possible values are present and absent.
+      - create, delete or block a user.
+      - Possible values are present, absent, blocked, and unblocked.
     default: present
     type: str
-    choices: ["present", "absent"]
+    choices: ["present", "absent", "blocked", "unblocked"]
   confirm:
     description:
       - Require confirmation.
@@ -133,6 +134,24 @@
     group: super_group/mon_group
     access_level: owner
   delegate_to: localhost
+
+- name: "Block GitLab User"
+  gitlab_user:
+    api_url: https://gitlab.example.com/
+    api_token: "{{ access_token }}"
+    validate_certs: False
+    username: myusername
+    state: blocked
+  delegate_to: localhost
+
+- name: "Unblock GitLab User"
+  gitlab_user:
+    api_url: https://gitlab.example.com/
+    api_token: "{{ access_token }}"
+    validate_certs: False
+    username: myusername
+    state: unblocked
+  delegate_to: localhost
 '''
 
 RETURN = '''
@@ -383,6 +402,13 @@ def existsUser(self, username):
             return True
         return False
 
+    '''
+    @param username Username of the user
+    '''
+    def isActive(self, username):
+        user = self.findUser(username)
+        return user.attributes['state'] == 'active'
+
     def deleteUser(self):
         if self._module.check_mode:
             return True
@@ -391,13 +417,29 @@ def deleteUser(self):
 
         return user.delete()
 
+    def blockUser(self):
+        if self._module.check_mode:
+            return True
+
+        user = self.userObject
+
+        return user.block()
+
+    def unblockUser(self):
+        if self._module.check_mode:
+            return True
+
+        user = self.userObject
+
+        return user.unblock()
+
 
 def main():
     argument_spec = basic_auth_argument_spec()
     argument_spec.update(dict(
         api_token=dict(type='str', no_log=True),
         name=dict(type='str'),
-        state=dict(type='str', default="present", choices=["absent", "present"]),
+        state=dict(type='str', default="present", choices=["absent", "present", "blocked", "unblocked"]),
         username=dict(type='str', required=True),
         password=dict(type='str', no_log=True),
         email=dict(type='str'),
@@ -448,6 +490,7 @@ def main():
 
     gitlab_user = GitLabUser(module, gitlab_instance)
     user_exists = gitlab_user.existsUser(user_username)
+    user_is_active = gitlab_user.isActive(user_username)
 
     if state == 'absent':
         if user_exists:
@@ -456,6 +499,20 @@ def main():
         else:
             module.exit_json(changed=False, msg="User deleted or does not exists")
 
+    if state == 'blocked':
+        if user_exists and user_is_active:
+            gitlab_user.blockUser()
+            module.exit_json(changed=True, msg="Successfully blocked user %s" % user_username)
+        else:
+            module.exit_json(changed=False, msg="User already blocked or does not exists")
+
+    if state == 'unblocked':
+        if user_exists and not user_is_active:
+            gitlab_user.unblockUser()
+            module.exit_json(changed=True, msg="Successfully unblocked user %s" % user_username)
+        else:
+            module.exit_json(changed=False, msg="User is not blocked or does not exists")
+
     if state == 'present':
         if gitlab_user.createOrUpdateUser(user_username, {
                                           "name": user_name,


Test patch: