1#!/usr/local/bin/python3.8 2# 3# Copyright: Ansible Project 4# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 6from __future__ import absolute_import, division, print_function 7__metaclass__ = type 8 9DOCUMENTATION = ''' 10--- 11module: onyx_protocol 12author: "Samer Deeb (@samerd)" 13short_description: Enables/Disables protocols on Mellanox ONYX network devices 14description: 15 - This module provides a mechanism for enabling and disabling protocols 16 Mellanox on ONYX network devices. 17notes: 18 - Tested on ONYX 3.6.4000 19options: 20 mlag: 21 description: MLAG protocol 22 choices: ['enabled', 'disabled'] 23 magp: 24 description: MAGP protocol 25 choices: ['enabled', 'disabled'] 26 spanning_tree: 27 description: Spanning Tree support 28 choices: ['enabled', 'disabled'] 29 dcb_pfc: 30 description: DCB priority flow control 31 choices: ['enabled', 'disabled'] 32 igmp_snooping: 33 description: IP IGMP snooping 34 choices: ['enabled', 'disabled'] 35 lacp: 36 description: LACP protocol 37 choices: ['enabled', 'disabled'] 38 ip_l3: 39 description: IP L3 support 40 choices: ['enabled', 'disabled'] 41 ip_routing: 42 description: IP routing support 43 choices: ['enabled', 'disabled'] 44 lldp: 45 description: LLDP protocol 46 choices: ['enabled', 'disabled'] 47 bgp: 48 description: BGP protocol 49 choices: ['enabled', 'disabled'] 50 ospf: 51 description: OSPF protocol 52 choices: ['enabled', 'disabled'] 53 nve: 54 description: nve protocol 55 choices: ['enabled', 'disabled'] 56 bfd: 57 description: bfd protocol 58 choices: ['enabled', 'disabled'] 59 version_added: '0.2.0' 60''' 61 62EXAMPLES = """ 63- name: Enable protocols for MLAG 64 onyx_protocol: 65 lacp: enabled 66 spanning_tree: disabled 67 ip_routing: enabled 68 mlag: enabled 69 dcb_pfc: enabled 70""" 71 72RETURN = """ 73commands: 74 description: The list of configuration mode commands to send to the device. 75 returned: always 76 type: list 77 sample: 78 - no spanning-tree 79 - protocol mlag 80""" 81 82from ansible.module_utils.basic import AnsibleModule 83from ansible.module_utils.six import iteritems 84 85from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule 86from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd 87 88 89class OnyxProtocolModule(BaseOnyxModule): 90 91 PROTOCOL_MAPPING = dict( 92 mlag=dict(name="mlag", enable="protocol mlag", 93 disable="no protocol mlag"), 94 magp=dict(name="magp", enable="protocol magp", 95 disable="no protocol magp"), 96 spanning_tree=dict(name="spanning-tree", enable="spanning-tree", 97 disable="no spanning-tree"), 98 dcb_pfc=dict(name="priority-flow-control", 99 enable="dcb priority-flow-control enable force", 100 disable="no dcb priority-flow-control enable force"), 101 igmp_snooping=dict(name="igmp-snooping", enable="ip igmp snooping", 102 disable="no ip igmp snooping"), 103 lacp=dict(name="lacp", enable="lacp", disable="no lacp"), 104 ip_l3=dict(name="IP L3", enable="ip l3", 105 disable="no ip l3"), 106 ip_routing=dict(name="IP routing", enable="ip routing", 107 disable="no ip routing"), 108 lldp=dict(name="lldp", enable="lldp", disable="no lldp"), 109 bgp=dict(name="bgp", enable="protocol bgp", disable="no protocol bgp"), 110 ospf=dict(name="ospf", enable="protocol ospf", 111 disable="no protocol ospf"), 112 nve=dict(name="nve", enable="protocol nve", 113 disable="no protocol nve"), 114 bfd=dict(name="bfd", enable="protocol bfd", 115 disable="no protocol bfd"), 116 ) 117 118 @classmethod 119 def _get_element_spec(cls): 120 element_spec = dict() 121 for protocol in cls.PROTOCOL_MAPPING: 122 element_spec[protocol] = dict(choices=['enabled', 'disabled']) 123 return element_spec 124 125 def init_module(self): 126 """ Ansible module initialization 127 """ 128 element_spec = self._get_element_spec() 129 argument_spec = dict() 130 argument_spec.update(element_spec) 131 self._module = AnsibleModule( 132 argument_spec=argument_spec, 133 supports_check_mode=True 134 ) 135 136 def get_required_config(self): 137 self._required_config = dict() 138 module_params = self._module.params 139 for key, val in iteritems(module_params): 140 if key in self.PROTOCOL_MAPPING and val is not None: 141 self._required_config[key] = val 142 143 def _get_protocols(self): 144 return show_cmd(self._module, "show protocols") 145 146 def _get_ip_routing(self): 147 return show_cmd(self._module, 'show ip routing | include "IP routing"', 148 json_fmt=False) 149 150 def load_current_config(self): 151 self._current_config = dict() 152 protocols_config = self._get_protocols() 153 if not protocols_config: 154 protocols_config = dict() 155 ip_config = self._get_ip_routing() 156 if ip_config: 157 lines = ip_config.split('\n') 158 for line in lines: 159 line = line.strip() 160 line_attr = line.split(':') 161 if len(line_attr) == 2: 162 attr = line_attr[0].strip() 163 val = line_attr[1].strip() 164 protocols_config[attr] = val 165 for protocol, protocol_metadata in iteritems(self.PROTOCOL_MAPPING): 166 protocol_json_attr = protocol_metadata['name'] 167 val = protocols_config.get(protocol_json_attr, 'disabled') 168 if val not in ('enabled', 'disabled'): 169 val = 'enabled' 170 self._current_config[protocol] = val 171 172 def generate_commands(self): 173 for protocol, req_val in iteritems(self._required_config): 174 protocol_metadata = self.PROTOCOL_MAPPING[protocol] 175 curr_val = self._current_config.get(protocol, 'disabled') 176 if curr_val != req_val: 177 if req_val == 'disabled': 178 command = protocol_metadata['disable'] 179 else: 180 command = protocol_metadata['enable'] 181 self._commands.append(command) 182 183 184def main(): 185 """ main entry point for module execution 186 """ 187 OnyxProtocolModule.main() 188 189 190if __name__ == '__main__': 191 main() 192