Repository: ansible/ansible

Issue:
Meraki modules should accept configuration template as name
##### SUMMARY
Configuration templates are used the same way as networks. The `net_name` parameter specifies a network name but it should also be able to accept a configuration template.

##### ISSUE TYPE
 - Feature Idea

##### COMPONENT NAME
meraki

##### ANSIBLE VERSION
<!--- Paste, BELOW THIS COMMENT, verbatim output from "ansible --version" between quotes below -->
```
ansible 2.7.0.dev0 (meraki/config_template_use e99434510d) last updated 2018/07/04 22:15:59 (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)]

```



Discussion:
Files identified in the description:
* [lib/ansible/module_utils/network/meraki/__init__.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/module_utils/network/meraki/__init__.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 @Qalthos @dagwieers @ganeshrn @gdpak @gundalow @privateip @rcarrillocruz @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/module_utils/network/meraki/meraki.py b/lib/ansible/module_utils/network/meraki/meraki.py
--- a/lib/ansible/module_utils/network/meraki/meraki.py
+++ b/lib/ansible/module_utils/network/meraki/meraki.py
@@ -206,6 +206,9 @@ def get_nets(self, org_name=None, org_id=None):
         if self.status != 200:
             self.fail_json(msg='Network lookup failed')
         self.nets = self.request(path, method='GET')
+        templates = self.get_config_templates(org_id)
+        for t in templates:
+            self.nets.append(t)
         return self.nets
 
     def get_net(self, org_name, net_name, data=None):
@@ -236,6 +239,19 @@ def get_net_id(self, org_name=None, net_name=None, data=None):
                 return n['id']
         self.fail_json(msg='No network found with the name {0}'.format(net_name))
 
+    def get_config_templates(self, org_id):
+        path = self.construct_path('get_all', function='configTemplates', org_id=org_id)
+        response = self.request(path, 'GET')
+        if self.status != 200:
+            self.fail_json(msg='Unable to get configuration templates')
+        return response
+
+    def get_template_id(self, name, data):
+        for template in data:
+            if name == template['name']:
+                return template['id']
+        self.fail_json(msg='No configuration template named {0} found'.format(name))
+
     def construct_path(self, action, function=None, org_id=None, net_id=None, org_name=None):
         """Build a path from the URL catalog.
 
diff --git a/lib/ansible/modules/network/meraki/meraki_vlan.py b/lib/ansible/modules/network/meraki/meraki_vlan.py
--- a/lib/ansible/modules/network/meraki/meraki_vlan.py
+++ b/lib/ansible/modules/network/meraki/meraki_vlan.py
@@ -31,8 +31,11 @@
       default: query
     net_name:
       description:
-      - Name of network which VLAN is or should be in.
+      - Name of network which VLAN is in or should be in.
       aliases: [network]
+    net_id:
+      description:
+      - ID of network which VLAN is in or should be in.
     vlan_id:
       description:
       - ID number of VLAN.
@@ -200,6 +203,7 @@ def main():
     argument_spec = meraki_argument_spec()
     argument_spec.update(state=dict(type='str', choices=['absent', 'present', 'query'], default='query'),
                          net_name=dict(type='str', aliases=['network']),
+                         net_id=dict(type='str'),
                          vlan_id=dict(type='int'),
                          name=dict(type='str', aliases=['vlan_name']),
                          subnet=dict(type='str'),
@@ -243,7 +247,10 @@ def main():
 
     payload = None
 
-    nets = temp_get_nets(meraki, meraki.params['org_name'])
+    org_id = meraki.params['org_id']
+    if org_id is None:
+        org_id = meraki.get_org_id(meraki.params['org_name'])
+    nets = meraki.get_nets(org_id=org_id)
     net_id = None
     if meraki.params['net_name']:
         net_id = meraki.get_net_id(net_name=meraki.params['net_name'], data=nets)


Test patch:
diff --git a/test/integration/targets/meraki_network/tasks/main.yml b/test/integration/targets/meraki_network/tasks/main.yml
--- a/test/integration/targets/meraki_network/tasks/main.yml
+++ b/test/integration/targets/meraki_network/tasks/main.yml
@@ -169,6 +169,15 @@
     delegate_to: localhost
     register: net_query_all
       
+  - name: Query a configuration template
+    meraki_network:
+      auth_key: '{{auth_key}}'
+      state: query
+      org_name: '{{test_org_name}}'
+      net_name: '{{test_template_name}}'
+    delegate_to: localhost
+    register: query_config_template
+
   - name: Query one network
     meraki_network:
       auth_key: '{{ auth_key }}'
@@ -182,6 +191,7 @@
     assert:
       that:
         - 'net_query_one.data.name == "IntTestNetworkSwitch"'
+        - 'query_config_template.data.name == "DevConfigTemplate"'
         
 
 #############################################################################
diff --git a/test/integration/targets/meraki_vlan/tasks/main.yml b/test/integration/targets/meraki_vlan/tasks/main.yml
--- a/test/integration/targets/meraki_vlan/tasks/main.yml
+++ b/test/integration/targets/meraki_vlan/tasks/main.yml
@@ -66,6 +66,24 @@
         - create_vlan.data.id == 2
         - create_vlan.changed == True
 
+  - name: Create VLAN in template configuration
+    meraki_vlan:
+      auth_key: '{{auth_key}}'
+      state: present
+      org_name: '{{test_org_name}}'
+      net_name: '{{test_template_name}}'
+      vlan_id: 2
+      name: TestVLAN
+      subnet: 192.168.250.0/24
+      appliance_ip: 192.168.250.1
+    delegate_to: localhost
+    register: create_vlan_template
+
+  - assert:
+      that:
+        - create_vlan_template.data.id == 2
+        - create_vlan_template.changed == True
+
   - name: Update VLAN
     meraki_vlan:
       auth_key: '{{auth_key}}'
@@ -305,3 +323,16 @@
 
   - debug:
       msg: '{{delete_vlan}}'
+
+  - name: Delete VLAN using template ID
+    meraki_vlan:
+      auth_key: '{{auth_key}}'
+      state: absent
+      org_name: '{{test_org_name}}'
+      net_id: '{{test_template_id}}'
+      vlan_id: 2
+    delegate_to: localhost
+    register: delete_vlan_template
+
+  - debug:
+      msg: '{{delete_vlan_template}}'