diff --git a/test_inventory_keys.py b/test_inventory_keys.py index cd16cc7..3feb01b 100644 --- a/test_inventory_keys.py +++ b/test_inventory_keys.py @@ -5,7 +5,7 @@ from wif2ansible.inventory import generate_inventory class TestInventoryKeys(unittest.TestCase): def test_inventory_keys_are_hostnames(self): # Create a server with Ref, Hostname, IP - s1 = Server(reference="SERVER_REF_01", hostname="server01", ip_address="192.168.1.10", platform="windows") + s1 = Server(reference="SERVER_REF_01", hostname="server01", ip_addresses=["192.168.1.10"], platform="windows") # Create a flow matching this server f1 = Flow(flow_id="1", source_ip="192.168.1.10", destination_ip="10.0.0.1", ports=[80]) @@ -18,12 +18,12 @@ class TestInventoryKeys(unittest.TestCase): # Verify stricture hosts = inventory['all']['hosts'] - # Key should be REFERENCE "SERVER_REF_01" (or hostname/ip fallback) - self.assertIn("SERVER_REF_01", hosts) + # Key should be HOSTNAME "server01" (prioritized over Ref) + self.assertIn("server01", hosts) self.assertNotIn("192.168.1.10", hosts) # Check variables - host_vars = hosts["SERVER_REF_01"] + host_vars = hosts["server01"] self.assertEqual(host_vars['ansible_host'], "192.168.1.10") self.assertEqual(host_vars['ansible_connection'], "winrm") diff --git a/wif2ansible/excel_reader.py b/wif2ansible/excel_reader.py index be59dcb..7bc546e 100644 --- a/wif2ansible/excel_reader.py +++ b/wif2ansible/excel_reader.py @@ -120,27 +120,24 @@ def read_servers(filename: str) -> Dict[str, Server]: plat = get_val(plat_idx) or 'unknown' # Parse Management IP + # Support multiple IPs ip_raw = get_val(ip_idx) - ip_addr = None + ip_list = [] if ip_raw: - ips = parse_ip(ip_raw) - if ips: - ip_addr = ips[0] + ip_list = parse_ip(ip_raw) # Parse Production IP prod_ip_raw = get_val(prod_ip_idx) - prod_ip_addr = None + prod_ip_list = [] if prod_ip_raw: - ips = parse_ip(prod_ip_raw) - if ips: - prod_ip_addr = ips[0] + prod_ip_list = parse_ip(prod_ip_raw) s = Server( reference=ref, hostname=final_hostname, platform=plat, - ip_address=ip_addr, - production_ip=prod_ip_addr + ip_addresses=ip_list, + production_ips=prod_ip_list ) servers[ref] = s diff --git a/wif2ansible/inventory.py b/wif2ansible/inventory.py index 0d82b95..6f4f700 100644 --- a/wif2ansible/inventory.py +++ b/wif2ansible/inventory.py @@ -18,10 +18,14 @@ def generate_inventory(servers: Dict[str, Server], flows: List[Flow]) -> Dict[st ip_to_server = {} for s in servers.values(): - if s.ip_address: - ip_to_server[s.ip_address] = s - if s.production_ip: - ip_to_server[s.production_ip] = s + # Index all Management IPs + for ip in s.ip_addresses: + ip_to_server[ip] = s + + # Index all Production IPs + for ip in s.production_ips: + ip_to_server[ip] = s + # Also index by reference/hostname for DNS matches if s.reference: ip_to_server[s.reference.lower()] = s @@ -62,7 +66,7 @@ def generate_inventory(servers: Dict[str, Server], flows: List[Flow]) -> Dict[st # Prepare host entry if new # We use the Hostname (from Server Name col) -> Reference (cleaned) -> IP match - host_key = server.hostname or server.reference or server.ip_address + host_key = server.hostname or server.reference or server.primary_ip if host_key not in inventory_hosts: host_vars = server.get_ansible_vars() diff --git a/wif2ansible/models.py b/wif2ansible/models.py index ef7ea6a..5d048de 100644 --- a/wif2ansible/models.py +++ b/wif2ansible/models.py @@ -5,8 +5,19 @@ from typing import List, Dict, Optional, Any class Server: reference: str hostname: str # This might be same as reference - ip_address: Optional[str] = None - production_ip: Optional[str] = None + # Support multiple IPs per field (lists) + ip_addresses: List[str] = field(default_factory=list) + production_ips: List[str] = field(default_factory=list) + + # helper for compatibility/primary IP + @property + def primary_ip(self) -> Optional[str]: + return self.ip_addresses[0] if self.ip_addresses else None + + @property + def primary_prod_ip(self) -> Optional[str]: + return self.production_ips[0] if self.production_ips else None + platform: str = 'unknown' # e.g. 'Windows', 'Linux' def get_ansible_vars(self) -> Dict[str, Any]: @@ -23,8 +34,8 @@ class Server: # Default ssh is usually fine, but being explicit doesn't hurt pass - if self.ip_address: - vars['ansible_host'] = self.ip_address + if self.primary_ip: + vars['ansible_host'] = self.primary_ip return vars