1#!/usr/bin/python 2# -*- coding: utf-8 -*- 3 4# (c) 2017, Ansible by Red Hat, inc 5# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 6 7from __future__ import absolute_import, division, print_function 8__metaclass__ = type 9 10 11ANSIBLE_METADATA = {'metadata_version': '1.1', 12 'status': ['deprecated'], 13 'supported_by': 'network'} 14 15 16DOCUMENTATION = """ 17--- 18module: junos_l3_interface 19version_added: "2.4" 20author: "Ganesh Nalawade (@ganeshrn)" 21short_description: Manage L3 interfaces on Juniper JUNOS network devices 22description: 23 - This module provides declarative management of L3 interfaces 24 on Juniper JUNOS network devices. 25deprecated: 26 removed_in: "2.13" 27 why: Updated modules released with more functionality 28 alternative: Use M(junos_l3_interfaces) instead. 29options: 30 name: 31 description: 32 - Name of the L3 interface. 33 ipv4: 34 description: 35 - IPv4 of the L3 interface. 36 ipv6: 37 description: 38 - IPv6 of the L3 interface. 39 unit: 40 description: 41 - Logical interface number. 42 default: 0 43 filter_input: 44 description: 45 - The name of input filter. 46 version_added: "2.8" 47 filter_output: 48 description: 49 - The name of output filter. 50 version_added: "2.8" 51 filter6_input: 52 description: 53 - The name of input filter for ipv6. 54 version_added: "2.8" 55 filter6_output: 56 description: 57 - The name of output filter for ipv6. 58 version_added: "2.8" 59 aggregate: 60 description: List of L3 interfaces definitions 61 state: 62 description: 63 - State of the L3 interface configuration. 64 default: present 65 choices: ['present', 'absent'] 66 active: 67 description: 68 - Specifies whether or not the configuration is active or deactivated 69 default: True 70 type: bool 71requirements: 72 - ncclient (>=v0.5.2) 73notes: 74 - This module requires the netconf system service be enabled on 75 the remote device being managed. 76 - Tested against vSRX JUNOS version 15.1X49-D15.4, vqfx-10000 JUNOS Version 15.1X53-D60.4. 77 - Recommended connection is C(netconf). See L(the Junos OS Platform Options,../network/user_guide/platform_junos.html). 78 - This module also works with C(local) connections for legacy playbooks. 79extends_documentation_fragment: junos 80""" 81 82EXAMPLES = """ 83- name: Set ge-0/0/1 IPv4 address 84 junos_l3_interface: 85 name: ge-0/0/1 86 ipv4: 192.168.0.1 87 88- name: Remove ge-0/0/1 IPv4 address 89 junos_l3_interface: 90 name: ge-0/0/1 91 state: absent 92 93- name: Set ipv4 address using aggregate 94 junos_l3_interface: 95 aggregate: 96 - name: ge-0/0/1 97 ipv4: 192.0.2.1 98 - name: ge-0/0/2 99 ipv4: 192.0.2.2 100 ipv6: fd5d:12c9:2201:2::2 101 102- name: Delete ipv4 address using aggregate 103 junos_l3_interface: 104 aggregate: 105 - name: ge-0/0/1 106 ipv4: 192.0.2.1 107 - name: ge-0/0/2 108 ipv4: 192.0.2.2 109 state: absent 110""" 111 112RETURN = """ 113diff: 114 description: Configuration difference before and after applying change. 115 returned: when configuration is changed and diff option is enabled. 116 type: str 117 sample: > 118 [edit interfaces ge-0/0/1 unit 0 family inet] 119 + address 192.0.2.1/32; 120 [edit interfaces ge-0/0/1 unit 0 family inet6] 121 + address fd5d:12c9:2201:1::1/128; 122""" 123import collections 124 125from copy import deepcopy 126 127from ansible.module_utils.basic import AnsibleModule 128from ansible.module_utils.network.common.utils import remove_default_spec 129from ansible.module_utils.network.junos.junos import junos_argument_spec, tostring 130from ansible.module_utils.network.junos.junos import load_config, map_params_to_obj, map_obj_to_ele 131from ansible.module_utils.network.junos.junos import commit_configuration, discard_changes, locked_config, to_param_list 132 133USE_PERSISTENT_CONNECTION = True 134 135 136def main(): 137 """ main entry point for module execution 138 """ 139 element_spec = dict( 140 name=dict(), 141 ipv4=dict(), 142 ipv6=dict(), 143 filter_input=dict(), 144 filter_output=dict(), 145 filter6_input=dict(), 146 filter6_output=dict(), 147 unit=dict(default=0, type='int'), 148 state=dict(default='present', choices=['present', 'absent']), 149 active=dict(default=True, type='bool') 150 ) 151 152 aggregate_spec = deepcopy(element_spec) 153 aggregate_spec['name'] = dict(required=True) 154 155 # remove default in aggregate spec, to handle common arguments 156 remove_default_spec(aggregate_spec) 157 158 argument_spec = dict( 159 aggregate=dict(type='list', elements='dict', options=aggregate_spec), 160 ) 161 162 argument_spec.update(element_spec) 163 argument_spec.update(junos_argument_spec) 164 165 required_one_of = [['name', 'aggregate']] 166 mutually_exclusive = [['name', 'aggregate']] 167 168 module = AnsibleModule(argument_spec=argument_spec, 169 supports_check_mode=True, 170 mutually_exclusive=mutually_exclusive, 171 required_one_of=required_one_of) 172 173 warnings = list() 174 result = {'changed': False} 175 176 if warnings: 177 result['warnings'] = warnings 178 179 top = 'interfaces/interface' 180 181 param_to_xpath_map = collections.OrderedDict() 182 param_to_xpath_map.update([ 183 ('name', {'xpath': 'name', 'parent_attrib': False, 'is_key': True}), 184 ('unit', {'xpath': 'name', 'top': 'unit', 'parent_attrib': False, 'is_key': True}), 185 ('ipv4', {'xpath': 'inet/address/name', 'top': 'unit/family', 'is_key': True}), 186 ('ipv6', {'xpath': 'inet6/address/name', 'top': 'unit/family', 'is_key': True}), 187 ('filter_input', {'xpath': 'inet/filter/input', 'top': 'unit/family'}), 188 ('filter_output', {'xpath': 'inet/filter/output', 'top': 'unit/family'}), 189 ('filter6_input', {'xpath': 'inet6/filter/input', 'top': 'unit/family'}), 190 ('filter6_output', {'xpath': 'inet6/filter/output', 'top': 'unit/family'}), 191 ]) 192 193 params = to_param_list(module) 194 195 requests = list() 196 for param in params: 197 # if key doesn't exist in the item, get it from module.params 198 for key in param: 199 if param.get(key) is None: 200 param[key] = module.params[key] 201 202 item = param.copy() 203 if not item['ipv4'] and not item['ipv6']: 204 module.fail_json(msg="one of the following is required: ipv4,ipv6") 205 206 want = map_params_to_obj(module, param_to_xpath_map, param=item) 207 requests.append(map_obj_to_ele(module, want, top, param=item)) 208 209 diff = None 210 with locked_config(module): 211 for req in requests: 212 diff = load_config(module, tostring(req), warnings, action='merge') 213 214 commit = not module.check_mode 215 if diff: 216 if commit: 217 commit_configuration(module) 218 else: 219 discard_changes(module) 220 result['changed'] = True 221 222 if module._diff: 223 result['diff'] = {'prepared': diff} 224 225 module.exit_json(**result) 226 227 228if __name__ == "__main__": 229 main() 230