Repository: ansible/ansible

Issue:
Meraki_admin doesn’t always use org_id and net_id
##### SUMMARY
`org_id` and `net_id` can be provided to improve playbook execution performance since less lookups are needed. `org_id` and `net_id` should be used within the module, when possible to avoid unnecessarily API calls.

##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
meraki_admin

##### ANSIBLE VERSION
<!--- Paste, BELOW THIS COMMENT, verbatim output from "ansible --version" between quotes below -->
```
ansible 2.7.0.dev0 (meraki/meraki_device 387c37e255) last updated 2018/06/06 20:11:36 (GMT -500)
  config file = None
  configured module search path = ['/Users/kbreit/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/kbreit/Documents/Programming/ansible/lib/ansible
  executable location = /Users/kbreit/Documents/Programming/ansible/bin/ansible
  python version = 3.5.4 (default, Feb 25 2018, 14:56:02) [GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)]
```

##### CONFIGURATION
<!--- If using Ansible 2.4 or above, paste, BELOW THIS COMMENT, the results of "ansible-config dump --only-changed"
Otherwise, mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).-->


Discussion:
Files identified in the description:
* [lib/ansible/modules/network/meraki/meraki_admin.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/network/meraki/meraki_admin.py)

If these files are inaccurate, 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/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @dagwieers
[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/meraki/meraki_admin.py b/lib/ansible/modules/network/meraki/meraki_admin.py
--- a/lib/ansible/modules/network/meraki/meraki_admin.py
+++ b/lib/ansible/modules/network/meraki/meraki_admin.py
@@ -69,24 +69,37 @@
 - name: Query information about all administrators associated to the organization
   meraki_admin:
     auth_key: abc12345
+    org_name: YourOrg
     state: query
   delegate_to: localhost
 
 - name: Query information about a single administrator by name
   meraki_admin:
     auth_key: abc12345
+    org_id: 12345
     state: query
     name: Jane Doe
 
 - name: Query information about a single administrator by email
   meraki_admin:
     auth_key: abc12345
+    org_name: YourOrg
     state: query
     email: jane@doe.com
 
-- name:  new administrator with organization access
+- name: Create new administrator with organization access
   meraki_admin:
     auth_key: abc12345
+    org_name: YourOrg
+    state: present
+    name: Jane Doe
+    orgAccess: read-only
+    email: jane@doe.com
+
+- name: Create new administrator with organization access
+  meraki_admin:
+    auth_key: abc12345
+    org_name: YourOrg
     state: present
     name: Jane Doe
     orgAccess: read-only
@@ -95,6 +108,7 @@
 - name: Create a new administrator with organization access
   meraki_admin:
     auth_key: abc12345
+    org_name: YourOrg
     state: present
     name: Jane Doe
     orgAccess: read-only
@@ -103,6 +117,7 @@
 - name: Revoke access to an organization for an administrator
   meraki_admin:
     auth_key: abc12345
+    org_name: YourOrg
     state: absent
     email: jane@doe.com
 '''
@@ -171,12 +186,11 @@ def get_admins(meraki, org_id):
     return admins
 
 
-def get_admin_id(meraki, org_name, data, name=None, email=None):
+def get_admin_id(meraki, data, name=None, email=None):
     admin_id = None
     for a in data:
         if meraki.params['name'] is not None:
             if meraki.params['name'] == a['name']:
-                # meraki.fail_json(msg='HERE')
                 if admin_id is not None:
                     meraki.fail_json(msg='There are multiple administrators with the same name')
                 else:
@@ -346,18 +360,20 @@ def main():
 
     # manipulate or modify the state as needed (this is going to be the
     # part where your module will do what it needs to do)
-    org_id = meraki.get_org_id(meraki.params['org_name'])
+    org_id = meraki.params['org_id']
+    if not meraki.params['org_id']:
+        org_id = meraki.get_org_id(meraki.params['org_name'])
     if meraki.params['state'] == 'query':
         admins = get_admins(meraki, org_id)
         if not meraki.params['name'] and not meraki.params['email']:  # Return all admins for org
             meraki.result['data'] = admins
         if meraki.params['name'] is not None:  # Return a single admin for org
-            admin_id = get_admin_id(meraki, meraki.params['org_name'], admins, name=meraki.params['name'])
+            admin_id = get_admin_id(meraki, admins, name=meraki.params['name'])
             meraki.result['data'] = admin_id
             admin = get_admin(meraki, admins, admin_id)
             meraki.result['data'] = admin
         elif meraki.params['email'] is not None:
-            admin_id = get_admin_id(meraki, meraki.params['org_name'], admins, email=meraki.params['email'])
+            admin_id = get_admin_id(meraki, admins, email=meraki.params['email'])
             meraki.result['data'] = admin_id
             admin = get_admin(meraki, admins, admin_id)
             meraki.result['data'] = admin
@@ -371,7 +387,6 @@ def main():
             meraki.result['data'] = r
     elif meraki.params['state'] == 'absent':
         admin_id = get_admin_id(meraki,
-                                meraki.params['org_name'],
                                 get_admins(meraki, org_id),
                                 email=meraki.params['email']
                                 )


Test patch:
diff --git a/test/integration/targets/meraki_admin/tasks/main.yml b/test/integration/targets/meraki_admin/tasks/main.yml
--- a/test/integration/targets/meraki_admin/tasks/main.yml
+++ b/test/integration/targets/meraki_admin/tasks/main.yml
@@ -20,6 +20,32 @@
       - create_orgaccess.changed == true
       - 'create_orgaccess.data.name == "Jane Doe"'
 
+- name: Delete recently created administrator
+  meraki_admin:
+    auth_key: '{{auth_key}}'
+    state: absent
+    org_name: '{{test_org_name}}'
+    email: '{{email_prefix}}+janedoe@{{email_domain}}'
+  delegate_to: localhost
+  register: delete_one
+
+- name: Create new administrator with org_id
+  meraki_admin:
+    auth_key: '{{auth_key}}'
+    state: present
+    org_id: '{{test_org_id}}'
+    name: Jane Doe
+    email: '{{email_prefix}}+janedoe@{{email_domain}}'
+    orgAccess: read-only
+  delegate_to: localhost
+  register: create_orgaccess_id
+
+- name: Create new admin assertion
+  assert:
+    that:
+      - create_orgaccess_id.changed == true
+      - 'create_orgaccess_id.data.name == "Jane Doe"'
+
 - name: Create administrator with tags
   meraki_admin:
     auth_key: '{{auth_key}}'