1#!/usr/bin/python 2# -*- coding: utf-8 -*- 3 4# (c) 2017, Ansible by Red Hat, inc 5# 6# This file is part of Ansible by Red Hat 7# 8# Ansible is free software: you can redistribute it and/or modify 9# it under the terms of the GNU General Public License as published by 10# the Free Software Foundation, either version 3 of the License, or 11# (at your option) any later version. 12# 13# Ansible is distributed in the hope that it will be useful, 14# but WITHOUT ANY WARRANTY; without even the implied warranty of 15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16# GNU General Public License for more details. 17# 18# You should have received a copy of the GNU General Public License 19# along with Ansible. If not, see <http://www.gnu.org/licenses/>. 20# 21 22 23ANSIBLE_METADATA = {'metadata_version': '1.1', 24 'status': ['deprecated'], 25 'supported_by': 'network'} 26 27 28DOCUMENTATION = """ 29--- 30module: vyos_lldp_interface 31version_added: "2.4" 32author: "Ricardo Carrillo Cruz (@rcarrillocruz)" 33short_description: Manage LLDP interfaces configuration on VyOS network devices 34description: 35 - This module provides declarative management of LLDP interfaces 36 configuration on VyOS network devices. 37deprecated: 38 removed_in: '2.13' 39 alternative: vyos_lldp_interfaces 40 why: Updated modules released with more functionality. 41notes: 42 - Tested against VYOS 1.1.7 43options: 44 name: 45 description: 46 - Name of the interface LLDP should be configured on. 47 type: str 48 aggregate: 49 description: List of interfaces LLDP should be configured on. 50 type: list 51 state: 52 description: 53 - State of the LLDP configuration. 54 default: present 55 choices: ['present', 'absent', 'enabled', 'disabled'] 56 type: str 57extends_documentation_fragment: vyos 58""" 59 60EXAMPLES = """ 61- name: Enable LLDP on eth1 62 net_lldp_interface: 63 state: present 64 65- name: Enable LLDP on specific interfaces 66 net_lldp_interface: 67 interfaces: 68 - eth1 69 - eth2 70 state: present 71 72- name: Disable LLDP globally 73 net_lldp_interface: 74 state: disabled 75 76- name: Create aggregate of LLDP interface configurations 77 vyos_lldp_interface: 78 aggregate: 79 - name: eth1 80 - name: eth2 81 state: present 82 83- name: Delete aggregate of LLDP interface configurations 84 vyos_lldp_interface: 85 aggregate: 86 - name: eth1 87 - name: eth2 88 state: absent 89""" 90 91RETURN = """ 92commands: 93 description: The list of configuration mode commands to send to the device 94 returned: always, except for the platforms that use Netconf transport to manage the device. 95 type: list 96 sample: 97 - set service lldp eth1 98 - set service lldp eth2 disable 99""" 100 101 102from copy import deepcopy 103 104from ansible.module_utils.basic import AnsibleModule 105from ansible.module_utils.network.common.utils import remove_default_spec 106from ansible.module_utils.network.vyos.vyos import get_config, load_config 107from ansible.module_utils.network.vyos.vyos import vyos_argument_spec 108 109 110def search_obj_in_list(name, lst): 111 for o in lst: 112 if o['name'] == name: 113 return o 114 115 return None 116 117 118def map_obj_to_commands(updates, module): 119 commands = list() 120 want, have = updates 121 122 for w in want: 123 name = w['name'] 124 state = w['state'] 125 126 obj_in_have = search_obj_in_list(name, have) 127 128 if state == 'absent' and obj_in_have: 129 commands.append('delete service lldp interface ' + name) 130 elif state in ('present', 'enabled'): 131 if not obj_in_have: 132 commands.append('set service lldp interface ' + name) 133 elif obj_in_have and obj_in_have['state'] == 'disabled' and state == 'enabled': 134 commands.append('delete service lldp interface ' + name + ' disable') 135 elif state == 'disabled': 136 if not obj_in_have: 137 commands.append('set service lldp interface ' + name) 138 commands.append('set service lldp interface ' + name + ' disable') 139 elif obj_in_have and obj_in_have['state'] != 'disabled': 140 commands.append('set service lldp interface ' + name + ' disable') 141 142 return commands 143 144 145def map_config_to_obj(module): 146 obj = [] 147 config = get_config(module).splitlines() 148 149 output = [c for c in config if c.startswith("set service lldp interface")] 150 151 for i in output: 152 splitted_line = i.split() 153 154 if len(splitted_line) > 5: 155 new_obj = {'name': splitted_line[4]} 156 157 if splitted_line[5] == "'disable'": 158 new_obj['state'] = 'disabled' 159 else: 160 new_obj = {'name': splitted_line[4][1:-1]} 161 new_obj['state'] = 'present' 162 163 obj.append(new_obj) 164 165 return obj 166 167 168def map_params_to_obj(module): 169 obj = [] 170 171 aggregate = module.params.get('aggregate') 172 if aggregate: 173 for item in aggregate: 174 for key in item: 175 if item.get(key) is None: 176 item[key] = module.params[key] 177 178 obj.append(item.copy()) 179 else: 180 obj.append({'name': module.params['name'], 'state': module.params['state']}) 181 182 return obj 183 184 185def main(): 186 """ main entry point for module execution 187 """ 188 element_spec = dict( 189 name=dict(), 190 state=dict(default='present', 191 choices=['present', 'absent', 192 'enabled', 'disabled']) 193 ) 194 195 aggregate_spec = deepcopy(element_spec) 196 aggregate_spec['name'] = dict(required=True) 197 198 # remove default in aggregate spec, to handle common arguments 199 remove_default_spec(aggregate_spec) 200 201 argument_spec = dict( 202 aggregate=dict(type='list', elements='dict', options=aggregate_spec), 203 ) 204 205 argument_spec.update(element_spec) 206 argument_spec.update(vyos_argument_spec) 207 208 required_one_of = [['name', 'aggregate']] 209 mutually_exclusive = [['name', 'aggregate']] 210 211 module = AnsibleModule(argument_spec=argument_spec, 212 required_one_of=required_one_of, 213 mutually_exclusive=mutually_exclusive, 214 supports_check_mode=True) 215 216 warnings = list() 217 218 result = {'changed': False} 219 220 if warnings: 221 result['warnings'] = warnings 222 223 want = map_params_to_obj(module) 224 have = map_config_to_obj(module) 225 226 commands = map_obj_to_commands((want, have), module) 227 result['commands'] = commands 228 229 if commands: 230 commit = not module.check_mode 231 load_config(module, commands, commit=commit) 232 result['changed'] = True 233 234 module.exit_json(**result) 235 236 237if __name__ == '__main__': 238 main() 239