Repository: ansible/ansible

Issue:
eos_user fails when setting privilege on new user
<!---
Verify first that your issue/request is not already reported on GitHub.
Also test if the latest release, and master branch are affected too.
-->

##### ISSUE TYPE
<!--- Pick one below and delete the rest: -->
 - Bug Report


##### COMPONENT NAME
<!--- Name of the module/plugin/task/feature -->
eos_user

##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes below -->
```
ansible 2.4.0.0
  config file = None
  configured module search path = [u'/Users/dt/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python2.7/site-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 2.7.11 (default, Nov 13 2016, 20:35:45) [GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)]
23:14:19 [dt:~/eosplus/cloud-deployment/ansible] develop(+6/-6)+* ±
```

##### CONFIGURATION
<!---
If using Ansible 2.4 or above, paste the results of "ansible-config dump --only-changed"
PARAMIKO_HOST_KEY_AUTO_ADD(env: ANSIBLE_PARAMIKO_HOST_KEY_AUTO_ADD) = True
Otherwise, mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).

-->

##### OS / ENVIRONMENT
<!---
Mention the OS you are running Ansible from, and the OS you are
managing, or say "N/A" for anything that is not platform-specific.
Also mention the specific version of what you are trying to control,
e.g. if this is a network bug the version of firmware on the network device.
-->

##### SUMMARY
<!--- Explain the problem briefly -->
When creating a user with the eos_user module passing a value for the privilege attribute causes the play to fail if the user doesn't already exist

##### STEPS TO REPRODUCE
<!---
For bugs, show exactly how to reproduce the problem, using a minimal test-case.
For new features, show how the feature would be used.
-->

<!--- Paste example playbooks or commands between quotes below -->
```yaml

---
- hosts: mn100
  connection: local
  gather_facts: false

  tasks:
    - name: new user
      eos_user:
        provider: "{{ provider }}"
        name: will_fail
        state: present
        configured_password: test
        update_password: on_create
        privilege: 15
```

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->
The expectation here is that the user will be created with a password and privilege level
##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->
We see the following error message:

on eapi
```
fatal: [mn100]: FAILED! => {
    "changed": false,
    "code": 1000,
    "failed": true,
    "invocation": {
        "module_args": {
            "aggregate": null,
            "auth_pass": null,
            "authorize": false,
            "configured_password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
            "host": "mn100",
            "name": "will_fail",
            "nopassword": null,
            "password": "",
            "port": 443,
            "privilege": 15,
            "provider": {
                "auth_pass": null,
                "authorize": false,
                "host": "mn100",
                "password": "",
                "port": 443,
  1 ---
                "ssh_keyfile": null,
                "timeout": 10,
                "transport": "eapi",
                "use_ssl": true,
                "username": "admin",
                "validate_certs": false
            },
            "purge": false,
            "role": null,
            "ssh_keyfile": null,
            "sshkey": null,
            "state": "present",
            "timeout": 10,
            "transport": "cli",
            "update_password": "on_create",
            "url_password": "",
            "url_username": "admin",
            "use_ssl": true,
            "username": "admin",
            "validate_certs": false
        }
    },
    "msg": "CLI command 3 of 4 'username will_fail privilege 15' failed: could not run command"
```
on cli
```
fatal: [mn100]: FAILED! => {
    "changed": false,
    "commands": [
        "username will_fail privilege 15",
        "username will_fail secret ********"
    ],
    "failed": true,
    "invocation": {
        "module_args": {
            "aggregate": null,
            "auth_pass": null,
            "authorize": null,
            "configured_password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
            "host": "mn100",
            "name": "will_fail",
            "nopassword": null,
            "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
            "port": null,
            "privilege": 15,
            "provider": {
                "auth_pass": null,
                "authorize": null,
                "host": "mn100",
                "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
                "port": null,
                "ssh_keyfile": null,
                "timeout": null,
                "transport": "cli",
                "use_ssl": null,
                "username": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
                "validate_certs": false
            },
            "purge": false,
            "role": null,
            "ssh_keyfile": null,
            "sshkey": null,
            "state": "present",
            "timeout": null,
            "transport": "cli",
            "update_password": "on_create",
            "use_ssl": true,
            "username": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
            "validate_certs": true
        }
    },
    "msg": "username will_fail privilege 15\r\n% Invalid input\r\nmn100...23:21:19#"
```


You can see in the cli version that the commands are coming in the wrong order.  The privilege needs to be set after the user is created. 



Discussion:
cc @privateip @trishnaguha
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->

Resolving patch:
diff --git a/lib/ansible/modules/network/eos/eos_user.py b/lib/ansible/modules/network/eos/eos_user.py
--- a/lib/ansible/modules/network/eos/eos_user.py
+++ b/lib/ansible/modules/network/eos/eos_user.py
@@ -181,16 +181,16 @@ def map_obj_to_commands(updates, module):
             commands.append('no username %s' % want['name'])
             continue
 
+        if needs_update('configured_password'):
+            if update_password == 'always' or not have:
+                add('secret %s' % want['configured_password'])
+
         if needs_update('role'):
             add('role %s' % want['role'])
 
         if needs_update('privilege'):
             add('privilege %s' % want['privilege'])
 
-        if needs_update('configured_password'):
-            if update_password == 'always' or not have:
-                add('secret %s' % want['configured_password'])
-
         if needs_update('sshkey'):
             add('sshkey %s' % want['sshkey'])
 


Test patch:
diff --git a/test/integration/targets/eos_user/tests/cli/basic.yaml b/test/integration/targets/eos_user/tests/cli/basic.yaml
--- a/test/integration/targets/eos_user/tests/cli/basic.yaml
+++ b/test/integration/targets/eos_user/tests/cli/basic.yaml
@@ -5,9 +5,10 @@
       - no username ansibletest1
       - no username ansibletest2
       - no username ansibletest3
+      - no username ansibletest4
     provider: "{{ cli }}"
 
-- name: Create user
+- name: Create user with role
   eos_user:
     name: ansibletest1
     privilege: 15
@@ -22,9 +23,27 @@
     that:
       - 'result.changed == true'
       - '"username" in result.commands[0]'
-      - '"role network-operator" in result.commands[0]'
+      - '"secret" in result.commands[0]'
+      - '"role network-operator" in result.commands[1]'
+      - '"privilege 15" in result.commands[2]'
+
+- name: Create user with priv level and update_password
+  eos_user:
+    name: ansibletest4
+    privilege: 15
+    state: present
+    configured_password: test1
+    authorize: yes
+    update_password: on_create
+    provider: "{{ cli }}"
+  register: result
+
+- assert:
+    that:
+      - 'result.changed == true'
+      - '"username" in result.commands[0]'
+      - '"secret" in result.commands[0]'
       - '"privilege 15" in result.commands[1]'
-      - '"secret" in result.commands[2]'
 
 - name: Collection of users
   eos_user:
@@ -69,4 +88,5 @@
       - no username ansibletest1
       - no username ansibletest2
       - no username ansibletest3
+      - no username ansibletest4
     provider: "{{ cli }}"