Repository: ansible/ansible-modules-core

Issue:
User module does not add groups
##### ISSUE TYPE
- Feature Idea
- ~~Bug Report~~
##### COMPONENT NAME

user module
##### ANSIBLE VERSION

```
ansible 2.1.2.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides
```
##### OS / ENVIRONMENT

Linux
##### SUMMARY

The `groups`argument for the `user` module is not parsed properly in this [line](https://github.com/diego-treitos/ansible-modules-core/blob/devel/system/user.py#L521).
The final group name has the format `'sftpjail']`. 
Error example:

```
fatal: [anstest]: FAILED! => {"changed": false, "failed": true, "msg": "Group  'sftpjail'] does not exist"
```
##### STEPS TO REPRODUCE

Just use the `user` module with the `groups` argument adding at least 2 groups (although it may fail with only 1).

```
- name: Create os user
  user:
      name: john
      password: smith
      shell: /usr/bin/rssh
      home: /path/to/jail
      group: john
      groups:
        - sshgroup
        - sftpjail
```
##### EXPECTED RESULTS

User created and added to groups
##### ACTUAL RESULTS

```
fatal: [anstest]: FAILED! => {"changed": false, "failed": true, "msg": "Group  'sftpjail'] does not exist"
```
##### COMMENTS

I think this is an important regression as it affects an important core module. It would be great to have a fix asap.



Discussion:
<!-- @diego-treitos: Thanks for filing this bug report! -->

@ansible ping, this issue is waiting for your response.
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)

<!--- boilerplate: issue_bug_new --->

You are incorrectly assuming you can pass a list to groups, when the description clearly asks for a 'comma delimited string'. 

This is not a bug, but reclassifying as feature request as it should easily be able to accept an actual list as input also.

Thanks for the clarification. You are right, I should be passing a comma-separated list instead of a YAML list, which feels a bit counterintuitive.

However, changing now this behaviour would probably cause a lot of trouble to people using the already stablished syntax (after all it is a pretty basic feature) so surely it should be left as it is now.

No, changing the spec to require a list will work with both transparently.

Sorry but I dont get you here. I was already specifying a list and it was not working.
Even applying my PR, it wouldnt be fully transparent as if somebody specify a comma-separated list starting or ending with `'` or `"` (which are not valid characters for groups) these would be removed by the code I posted when it should crash.
In other words, with the code in the PR, if you use  `groups=test',test2`, the user will be added to groups `test`and `test2`, while it should actually crash due to the wrong syntax in `test'`group.


Resolving patch:
diff --git a/system/user.py b/system/user.py
--- a/system/user.py
+++ b/system/user.py
@@ -61,9 +61,10 @@
     groups:
         required: false
         description:
-            - Puts the user in this comma-delimited list of groups. When set to
-              the empty string ('groups='), the user is removed from all groups
-              except the primary group.
+            - Puts the user in  list of groups. When set to the empty string ('groups='),
+              the user is removed from all groups except the primary group.
+            - Before version 2.3, the only input format allowed was a 'comma separated string',
+              now it should be able to accept YAML lists also.
     append:
         required: false
         default: "no"
@@ -262,7 +263,7 @@ def __init__(self, module):
         self.non_unique  = module.params['non_unique']
         self.seuser     = module.params['seuser']
         self.group      = module.params['group']
-        self.groups     = module.params['groups']
+        self.groups     = ','.join(module.params['groups'])
         self.comment    = module.params['comment']
         self.shell      = module.params['shell']
         self.password   = module.params['password']
@@ -2080,7 +2081,7 @@ def main():
             uid=dict(default=None, type='str'),
             non_unique=dict(default='no', type='bool'),
             group=dict(default=None, type='str'),
-            groups=dict(default=None, type='str'),
+            groups=dict(default=None, type='list'),
             comment=dict(default=None, type='str'),
             home=dict(default=None, type='path'),
             shell=dict(default=None, type='str'),


Test patch: