Server IP : 85.214.239.14 / Your IP : 18.191.126.111 Web Server : Apache/2.4.62 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Tue Jan 9 19:45:01 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.18 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, MySQL : OFF | cURL : OFF | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /lib/python3/dist-packages/ansible_collections/dellemc/os10/plugins/modules/ |
Upload File : |
#!/usr/bin/python # -*- coding: utf-8 -*- # 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) __copyright__ = "(c) 2020 Dell Inc. or its subsidiaries. All rights reserved." __metaclass__ = type DOCUMENTATION = ''' module: vlt_validate author: "Senthil Kumar Ganesan (@skg-net)" short_description: Validate the vlt info, raise an error if peer is not in up state description: - Troubleshoot the show vlt info and raise an error if peer is not up. options: show_vlt: description: - show vlt output type: 'list' required: True show_system_network_summary: description: - show system summary output type: 'list' required: True intended_vlt_pairs: description: - intended vlt pair intput to verify with actual type: 'list' required: True ''' EXAMPLES = ''' Copy below YAML into a playbook (e.g. play.yml) and run as follows: #$ ansible-playbook -i inv play.yml name: show system Configuration hosts: localhost connection: local gather_facts: False tasks: - name: "Get Dell EMC OS10 Show run vlt" os10_command: commands: - command: "show running-configuration vlt | grep vlt-domain" provider: "{{ hostvars[item].cli }}" with_items: "{{ groups['all'] }}" register: show_run_vlt - set_fact: output_vlt: "{{ output_vlt|default([])+ [{'host': item.invocation.module_args.provider.host, 'inv_name': item.item, 'stdout_show_vlt': item.stdout.0}] }}" loop: "{{ show_run_vlt.results }}" - debug: var=output_vlt - name: "Get Dell EMC OS10 Show vlt info" os10_command: commands: - command: "show vlt {{ item.stdout_show_vlt.split()[1] }} | display-xml" provider: "{{ hostvars[item.inv_name].cli }}" with_items: "{{ output_vlt }}" register: show_vlt - set_fact: vlt_out: "{{ vlt_out|default([])+ [{'host': item.invocation.module_args.provider.host, 'inv_name': item.item, 'show_vlt_stdout': item.stdout.0}] }}" loop: "{{ show_vlt.results }}" register: vlt_output - name: call lib to convert vlt info from xml to dict format base_xml_to_dict: cli_responses: "{{ item.show_vlt_stdout }}" with_items: - "{{ vlt_out }}" register: vlt_dict_output - name: "Get Dell EMC OS10 Show system" import_role: name: os10_fabric_summary register: show_system_network_summary - name: call lib to process vlt_validate: show_vlt : "{{ vlt_dict_output.results }}" show_system_network_summary: "{{ show_system_network_summary.msg.results }}" intended_vlt_pairs: "{{ intended_vlt_pairs }}" register: show_vlt_info ''' from ansible.module_utils.basic import AnsibleModule from ansible.module_utils._text import to_native from collections import OrderedDict import traceback class VltValidation(object): def __init__(self): self.module = AnsibleModule(argument_spec=self.get_fields()) self.show_vlt = self.module.params['show_vlt'] self.show_system_network_summary = self.module.params['show_system_network_summary'] self.intended_vlt_pairs = self.module.params['intended_vlt_pairs'] self.exit_msg = OrderedDict() def get_fields(self): spec_fields = { 'show_vlt': { 'type': 'list', 'required': True }, 'show_system_network_summary': { 'type': 'list', 'required': True }, 'intended_vlt_pairs': { 'type': 'list', 'required': True } } return spec_fields # get switch inv name from mac def get_switch_inv_name_from_mac(self, mac): inv_name = None for show_system in self.show_system_network_summary: if (str.lower(show_system["node-mac"])) == (str.lower(mac)): inv_name = show_system.get("inv_name") break return inv_name def validate_vlt_pairs(self, actual_vlt_dict): final_out = list() intended_vlt_list = self.intended_vlt_pairs for intended_vlt in intended_vlt_list: intended_primary = intended_vlt.get("primary") intended_secondary = intended_vlt.get("secondary") actual_vlt = actual_vlt_dict.get(intended_primary) temp_dict = {} if actual_vlt is not None: actual_secondary = actual_vlt.get("secondary") secondary_status = actual_vlt.get("secondary_status") if actual_secondary is not None and intended_secondary != actual_secondary: temp_dict["error_type"] = "secondary_mismatch" temp_dict["intended_primary"] = intended_primary temp_dict["intended_secondary"] = intended_secondary temp_dict["secondary"] = actual_secondary reason = "config mismatch as {0} is expected, but the actual secondary is {1} " .format( intended_secondary, actual_secondary) temp_dict["possible_reason"] = reason final_out.append(temp_dict) else: if actual_secondary is None: temp_dict["intended_primary"] = intended_primary temp_dict["intended_secondary"] = intended_secondary temp_dict["error_type"] = "peer_missing" reason = "peer info is not configured or peer interface is down" temp_dict["possible_reason"] = reason final_out.append(temp_dict) elif intended_secondary == actual_secondary and secondary_status != "up": temp_dict["intended_primary"] = intended_primary temp_dict["intended_secondary"] = intended_secondary temp_dict["secondary"] = actual_secondary temp_dict["error_type"] = "peer_down" reason = "peer interface is down" temp_dict["possible_reason"] = reason final_out.append(temp_dict) else: temp_dict["intended_primary"] = intended_primary temp_dict["intended_secondary"] = intended_secondary temp_dict["error_type"] = "vlt_config_missing" temp_dict["possible_reason"] = "vlt is not configured" final_out.append(temp_dict) return final_out def parse_vlt_output(self): show_vlt_dict = {} for show_list in self.show_vlt: source_switch = None item = show_list.get("item") if item is not None: inv_info = item.get("inv_name") source_switch = inv_info.get("inv_name") msg = show_list.get("msg") if msg is not None: result = msg.get("result") for sub_result in result: vlt_dict = {} rpc_reply = sub_result.get("rpc-reply") data = rpc_reply.get("data") if data is not None: topo_oper_data = data.get("topology-oper-data") if topo_oper_data is not None: vlt_domain = topo_oper_data.get("vlt-domain") if vlt_domain is not None: local_info = vlt_domain.get("local-info") if local_info is not None: local_role = local_info.get("role") vlt_dict[local_role] = source_switch local_mac = local_info.get("system-mac") vlt_dict[local_role + "_mac"] = local_mac peer_info = vlt_domain.get("peer-info") if peer_info is not None: peer_mac = peer_info.get("system-mac") peer_switch = self.get_switch_inv_name_from_mac( peer_mac) peer_role = peer_info.get("role") vlt_dict[peer_role] = peer_switch vlt_dict[peer_role + "_mac"] = peer_mac peer_status = peer_info.get("peer-status") vlt_dict[peer_role + "_status"] = peer_status if bool(vlt_dict): primary_switch = vlt_dict.get("primary") vlt_data = show_vlt_dict.get(primary_switch) if vlt_data is None: # update database specific to primary, it helps # to avoid to skip duplicate data show_vlt_dict[primary_switch] = vlt_dict return show_vlt_dict def perform_action(self): try: actual_vlt_dict = self.parse_vlt_output() final_out = self.validate_vlt_pairs(actual_vlt_dict) self.exit_msg.update({"results": final_out}) self.module.exit_json(changed=False, msg=self.exit_msg) except Exception as e: self.module.fail_json( msg=to_native(e), exception=traceback.format_exc()) def main(): module_instance = VltValidation() module_instance.perform_action() if __name__ == '__main__': main()