#!/usr/bin/env python3 """ Script to extract both DPM mappings and device mappings from MCM CSV files Generates two output files: 1. dpm_mapping.txt - DPM names and their IP addresses 2. device_mapping.txt - DPM names with all their devices and device IPs YOU WILL NEED TO HAVE THE MCM CSV FILES IN THE CURRENT DIRECTORY WITH NAME MCM*_COMPLETE.csv """ import csv import glob import os from collections import OrderedDict, defaultdict def extract_mcm_data(): """Extract both DPM and device data from all MCM CSV files""" # Find all MCM CSV files csv_files = glob.glob("MCM*_COMPLETE.csv") csv_files.sort() # Sort to ensure consistent order (MCM01, MCM02, etc.) if not csv_files: print("No MCM*_COMPLETE.csv files found in current directory") return None, None # Dictionary to store MCM -> list of (DPM, DPM_IP) pairs for DPM mapping mcm_dpm_data = OrderedDict() # Dictionary to store MCM -> DPM -> list of (Device_Name, Device_IP) pairs for device mapping mcm_device_data = OrderedDict() total_dpms_processed = 0 total_devices_processed = 0 for csv_file in csv_files: # Extract MCM number from filename (e.g., MCM01_COMPLETE.csv -> MCM01) mcm_name = os.path.splitext(csv_file)[0].replace("_COMPLETE", "") print(f"Processing {csv_file}...") # Set to store unique DPM, DPM_IP combinations for this MCM unique_dpms = set() # Dictionary to store DPM -> list of devices for this MCM dpm_devices = defaultdict(list) try: with open(csv_file, 'r', newline='', encoding='utf-8-sig') as file: # utf-8-sig handles BOM reader = csv.DictReader(file) row_count = 0 device_count = 0 for row in reader: row_count += 1 dpm = row.get('DPM', '').strip() dpm_ip = row.get('DPM_IP', '').strip() device_name = row.get('Name', '').strip() device_ip = row.get('IP', '').strip() # Collect DPM data (for dpm_mapping.txt) if dpm and dpm_ip: unique_dpms.add((dpm, dpm_ip)) # Collect device data (for device_mapping.txt) if dpm and device_name and device_ip: dpm_devices[dpm].append((device_name, device_ip)) device_count += 1 print(f" Processed {row_count} rows, found {device_count} devices") except Exception as e: print(f"Error reading {csv_file}: {e}") continue # Store DPM mapping data mcm_dpm_data[mcm_name] = sorted(list(unique_dpms)) # Store device mapping data (sort DPMs and their devices) sorted_dpm_devices = OrderedDict() for dpm in sorted(dpm_devices.keys()): # Sort devices by IP address (extract IP and convert to sortable format) def ip_sort_key(device_tuple): device_name, device_ip = device_tuple try: # Split IP address and convert to integers for proper sorting ip_parts = device_ip.split('.') return tuple(int(part) for part in ip_parts) except (ValueError, AttributeError): # If IP parsing fails, fall back to string sorting return (999, 999, 999, 999) # Put invalid IPs at the end sorted_devices = sorted(dpm_devices[dpm], key=ip_sort_key) sorted_dpm_devices[dpm] = sorted_devices mcm_device_data[mcm_name] = sorted_dpm_devices # Statistics dpms_in_mcm = len(unique_dpms) devices_in_mcm = sum(len(devices) for devices in sorted_dpm_devices.values()) total_dpms_processed += dpms_in_mcm total_devices_processed += devices_in_mcm print(f" Found {dpms_in_mcm} unique DPMs with {devices_in_mcm} total devices") print(f"\nOverall totals: {total_dpms_processed} DPMs, {total_devices_processed} devices") return mcm_dpm_data, mcm_device_data def write_dpm_mapping(mcm_dpm_data, output_file="dpm_mapping.txt"): """Write the DPM mapping data in the same format as dpm_mapping.txt""" try: with open(output_file, 'w', encoding='utf-8') as file: for mcm_name, dpm_list in mcm_dpm_data.items(): # Write MCM header file.write(f"{mcm_name}\n") # Write DPM entries for dpm, dpm_ip in dpm_list: file.write(f"{dpm}\t{dpm_ip}\n") print(f"DPM mapping written to {output_file}") except Exception as e: print(f"Error writing DPM mapping file: {e}") def write_device_mapping(mcm_device_data, output_file="device_mapping.txt"): """Write the device mapping data in the same format as device_mapping.txt""" try: with open(output_file, 'w', encoding='utf-8') as file: for mcm_name, dpm_devices in mcm_device_data.items(): # Write MCM header file.write(f"{mcm_name}\n") # Write each DPM and its devices for dpm, devices in dpm_devices.items(): # Write DPM header file.write(f"{dpm}\n") # Write device entries for device_name, device_ip in devices: file.write(f"{device_name}\t{device_ip}\n") print(f"Device mapping written to {output_file}") except Exception as e: print(f"Error writing device mapping file: {e}") def main(): """Main function""" print("Extracting MCM mapping data from CSV files...") print("=" * 60) # Extract data from CSV files mcm_dpm_data, mcm_device_data = extract_mcm_data() if not mcm_dpm_data or not mcm_device_data: print("No data extracted. Please check that MCM*_COMPLETE.csv files exist.") return print("\nWriting output files...") print("=" * 60) # Write both output files write_dpm_mapping(mcm_dpm_data) write_device_mapping(mcm_device_data) # Print summary print("\nSummary:") print("=" * 60) total_dpms = 0 total_devices = 0 for mcm_name in mcm_dpm_data.keys(): dpm_count = len(mcm_dpm_data[mcm_name]) device_count = sum(len(devices) for devices in mcm_device_data[mcm_name].values()) total_dpms += dpm_count total_devices += device_count print(f"{mcm_name}: {dpm_count} DPMs, {device_count} devices") print(f"\nTotal: {total_dpms} DPMs with {total_devices} devices across all MCM files") print("\nOutput files generated:") print("- dpm_mapping.txt (DPM names and IP addresses)") print("- device_mapping.txt (DPM devices and their IP addresses)") if __name__ == "__main__": main()