Repository URL to install this package:
|
Version:
6.0.0 ▾
|
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: (c) 2019, Kevin Breit (@kbreit) <kevin.breit@kevinbreit.net>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {
'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'
}
DOCUMENTATION = r'''
---
module: meraki_management_interface
short_description: Configure Meraki management interfaces
version_added: "1.1.0"
description:
- Allows for configuration of management interfaces on Meraki MX, MS, and MR devices.
notes:
- C(WAN2) parameter is only valid for MX appliances.
- C(wan_enabled) should not be provided for non-MX devies.
options:
state:
description:
- Specifies whether configuration template information should be queried, modified, or deleted.
choices: ['absent', 'query', 'present']
default: query
type: str
org_name:
description:
- Name of organization containing the configuration template.
type: str
org_id:
description:
- ID of organization associated to a configuration template.
type: str
net_name:
description:
- Name of the network to bind or unbind configuration template to.
type: str
net_id:
description:
- ID of the network to bind or unbind configuration template to.
type: str
serial:
description:
- serial number of the device to configure.
type: str
required: true
wan1:
description:
- Management interface details for management interface.
aliases: [mgmt1]
type: dict
suboptions:
wan_enabled:
description:
- States whether the management interface is enabled.
- Only valid for MX devices.
type: str
choices: [disabled, enabled, not configured]
using_static_ip:
description:
- Configures the interface to use static IP or DHCP.
type: bool
static_ip:
description:
- IP address assigned to Management interface.
- Valid only if C(using_static_ip) is C(True).
type: str
static_gateway_ip:
description:
- IP address for default gateway.
- Valid only if C(using_static_ip) is C(True).
type: str
static_subnet_mask:
description:
- Netmask for static IP address.
- Valid only if C(using_static_ip) is C(True).
type: str
static_dns:
description:
- DNS servers to use.
- Allows for a maximum of 2 addresses.
type: list
elements: str
vlan:
description:
- VLAN number to use for the management network.
type: int
wan2:
description:
- Management interface details for management interface.
type: dict
aliases: [mgmt2]
suboptions:
wan_enabled:
description:
- States whether the management interface is enabled.
- Only valid for MX devices.
type: str
choices: [disabled, enabled, not configured]
using_static_ip:
description:
- Configures the interface to use static IP or DHCP.
type: bool
static_ip:
description:
- IP address assigned to Management interface.
- Valid only if C(using_static_ip) is C(True).
type: str
static_gateway_ip:
description:
- IP address for default gateway.
- Valid only if C(using_static_ip) is C(True).
type: str
static_subnet_mask:
description:
- Netmask for static IP address.
- Valid only if C(using_static_ip) is C(True).
type: str
static_dns:
description:
- DNS servers to use.
- Allows for a maximum of 2 addresses.
type: list
elements: str
vlan:
description:
- VLAN number to use for the management network.
type: int
author:
- Kevin Breit (@kbreit)
extends_documentation_fragment: cisco.meraki.meraki
'''
EXAMPLES = r'''
- name: Set WAN2 as static IP
meraki_management_interface:
auth_key: abc123
state: present
org_name: YourOrg
net_id: YourNetId
serial: AAAA-BBBB-CCCC
wan2:
wan_enabled: enabled
using_static_ip: yes
static_ip: 192.168.16.195
static_gateway_ip: 192.168.16.1
static_subnet_mask: 255.255.255.0
static_dns:
- 1.1.1.1
vlan: 1
delegate_to: localhost
- name: Query management information
meraki_management_interface:
auth_key: abc123
state: query
org_name: YourOrg
net_id: YourNetId
serial: AAAA-BBBB-CCCC
delegate_to: localhost
'''
RETURN = r'''
data:
description: Information about queried object.
returned: success
type: complex
contains:
wan1:
description: Management configuration for WAN1 interface
returned: success
type: complex
contains:
wan_enabled:
description: Enabled state of interface
returned: success
type: str
sample: enabled
using_static_ip:
description: Boolean value of whether static IP assignment is used on interface
returned: success
type: bool
sample: True
static_ip:
description: Assigned static IP
returned: only if static IP assignment is used
type: str
sample: 192.0.1.2
static_gateway_ip:
description: Assigned static gateway IP
returned: only if static IP assignment is used
type: str
sample: 192.0.1.1
static_subnet_mask:
description: Assigned netmask for static IP
returned: only if static IP assignment is used
type: str
sample: 255.255.255.0
static_dns:
description: List of DNS IP addresses
returned: only if static IP assignment is used
type: list
sample: ["1.1.1.1"]
vlan:
description: VLAN tag id of management VLAN
returned: success
type: int
sample: 2
wan2:
description: Management configuration for WAN1 interface
returned: success
type: complex
contains:
wan_enabled:
description: Enabled state of interface
returned: success
type: str
sample: enabled
using_static_ip:
description: Boolean value of whether static IP assignment is used on interface
returned: success
type: bool
sample: True
static_ip:
description: Assigned static IP
returned: only if static IP assignment is used
type: str
sample: 192.0.1.2
static_gateway_ip:
description: Assigned static gateway IP
returned: only if static IP assignment is used
type: str
sample: 192.0.1.1
static_subnet_mask:
description: Assigned netmask for static IP
returned: only if static IP assignment is used
type: str
sample: 255.255.255.0
static_dns:
description: List of DNS IP addresses
returned: only if static IP assignment is used
type: list
sample: ["1.1.1.1"]
vlan:
description: VLAN tag id of management VLAN
returned: success
type: int
sample: 2
'''
from ansible.module_utils.basic import AnsibleModule, json
from ansible.module_utils.common.dict_transformations import recursive_diff
from ansible_collections.cisco.meraki.plugins.module_utils.network.meraki.meraki import MerakiModule, meraki_argument_spec
def main():
# define the available arguments/parameters that a user can pass to
# the module
int_arg_spec = dict(wan_enabled=dict(type='str', choices=['enabled', 'disabled', 'not configured']),
using_static_ip=dict(type='bool'),
static_ip=dict(type='str'),
static_gateway_ip=dict(type='str'),
static_subnet_mask=dict(type='str'),
static_dns=dict(type='list', elements='str'),
vlan=dict(type='int'),
)
argument_spec = meraki_argument_spec()
argument_spec.update(state=dict(type='str', choices=['absent', 'query', 'present'], default='query'),
net_name=dict(type='str'),
net_id=dict(type='str'),
serial=dict(type='str', required=True),
wan1=dict(type='dict', default=None, options=int_arg_spec, aliases=['mgmt1']),
wan2=dict(type='dict', default=None, options=int_arg_spec, aliases=['mgmt2']),
)
# the AnsibleModule object will be our abstraction working with Ansible
# this includes instantiation, a couple of common attr would be the
# args/params passed to the execution, as well as if the module
# supports check mode
module = AnsibleModule(argument_spec=argument_spec,
supports_check_mode=True,
)
meraki = MerakiModule(module, function='management_interface')
meraki.params['follow_redirects'] = 'all'
query_urls = {'management_interface': '/devices/{serial}/managementInterface'}
meraki.url_catalog['get_one'].update(query_urls)
if meraki.params['net_id'] and meraki.params['net_name']:
meraki.fail_json('net_id and net_name are mutually exclusive.')
if meraki.params['state'] == 'present':
interfaces = ('wan1', 'wan2')
for interface in interfaces:
if meraki.params[interface] is not None:
if meraki.params[interface]['using_static_ip'] is True:
if len(meraki.params[interface]['static_dns']) > 2:
meraki.fail_json("Maximum number of static DNS addresses is 2.")
payload = dict()
if meraki.params['state'] == 'present':
interfaces = ('wan1', 'wan2')
for interface in interfaces:
if meraki.params[interface] is not None:
wan_int = dict()
if meraki.params[interface]['wan_enabled'] is not None:
wan_int['wanEnabled'] = meraki.params[interface]['wan_enabled']
if meraki.params[interface]['using_static_ip'] is not None:
wan_int['usingStaticIp'] = meraki.params[interface]['using_static_ip']
if meraki.params[interface]['vlan'] is not None:
wan_int['vlan'] = meraki.params[interface]['vlan']
if meraki.params[interface]['using_static_ip'] is True:
wan_int['staticIp'] = meraki.params[interface]['static_ip']
wan_int['staticGatewayIp'] = meraki.params[interface]['static_gateway_ip']
wan_int['staticSubnetMask'] = meraki.params[interface]['static_subnet_mask']
wan_int['staticDns'] = meraki.params[interface]['static_dns']
payload[interface] = wan_int
# 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.params['org_id']
if meraki.params['org_name']:
org_id = meraki.get_org_id(meraki.params['org_name'])
net_id = meraki.params['net_id']
if net_id is None:
nets = meraki.get_nets(org_id=org_id)
net_id = meraki.get_net_id(net_name=meraki.params['net_name'], data=nets)
if meraki.params['state'] == 'query':
path = meraki.construct_path('get_one', net_id=net_id, custom={'serial': meraki.params['serial']})
response = meraki.request(path, method='GET')
if meraki.status == 200:
meraki.result['data'] = response
elif meraki.params['state'] == 'present':
path = meraki.construct_path('get_one', custom={'serial': meraki.params['serial']})
original = meraki.request(path, method='GET')
update_required = False
if 'wan1' in original:
if 'wanEnabled' in original['wan1']:
update_required = meraki.is_update_required(original, payload)
else:
update_required = meraki.is_update_required(original, payload, optional_ignore=['wanEnabled'])
if 'wan2' in original and update_required is False:
if 'wanEnabled' in original['wan2']:
update_required = meraki.is_update_required(original, payload)
else:
update_required = meraki.is_update_required(original, payload, optional_ignore=['wanEnabled'])
if update_required is True:
if meraki.check_mode is True:
diff = recursive_diff(original, payload)
original.update(payload)
meraki.result['diff'] = {'before': diff[0],
'after': diff[1]}
meraki.result['data'] = original
meraki.result['changed'] = True
meraki.exit_json(**meraki.result)
response = meraki.request(path, method='PUT', payload=json.dumps(payload))
if meraki.status == 200:
diff = recursive_diff(original, response)
meraki.result['diff'] = {'before': diff[0],
'after': diff[1]}
meraki.result['data'] = response
meraki.result['changed'] = True
else:
meraki.result['data'] = original
# in the event of a successful module execution, you will want to
# simple AnsibleModule.exit_json(), passing the key/value results
meraki.exit_json(**meraki.result)
if __name__ == '__main__':
main()