All checks were successful
Build and Release / Build Windows Exe (push) Successful in 10s
62 lines
1.9 KiB
Python
62 lines
1.9 KiB
Python
import socket
|
|
from typing import Optional
|
|
from functools import lru_cache
|
|
|
|
@lru_cache(maxsize=1024)
|
|
def get_hostname(ip: str) -> Optional[str]:
|
|
try:
|
|
# Python's equivalent to Resolv.getname(ip)
|
|
# returns (hostname, aliaslist, ipaddrlist)
|
|
return socket.gethostbyaddr(ip)[0]
|
|
except socket.error:
|
|
return None
|
|
|
|
@lru_cache(maxsize=1024)
|
|
def get_ip(hostname: str) -> Optional[str]:
|
|
try:
|
|
return socket.gethostbyname(hostname)
|
|
except socket.error:
|
|
return None
|
|
|
|
def is_valid_hostname(hostname: str) -> bool:
|
|
"""
|
|
Checks if a hostname resolves to an IP.
|
|
"""
|
|
if not hostname:
|
|
return False
|
|
return get_ip(hostname) is not None
|
|
|
|
def to_mgt_ip(name_or_ip: str) -> Optional[str]:
|
|
"""
|
|
Mimics the Ruby script's to_mgt_ip logic:
|
|
1. Reverse lookup IP to get FQDN.
|
|
2. Construct management FQDN ({host}.ds.gc.ca or .pre-ds.gc.ca).
|
|
3. Resolve that management FQDN to an IP.
|
|
4. Return the Management FQDN if successful.
|
|
"""
|
|
|
|
# In Ruby script, input 'name' is often an IP address from the WIF source column.
|
|
|
|
# Step 1: Reverse Lookup
|
|
fqdn = get_hostname(name_or_ip)
|
|
if not fqdn:
|
|
# If input is already a name, use it? Ruby script assumes it gets a name from Resolv.getname(ip)
|
|
# If name_or_ip is NOT an IP, gethostbyaddr might fail or behave differently.
|
|
# But if it's already a name, we can try using it.
|
|
fqdn = name_or_ip
|
|
|
|
short_name = fqdn.split('.')[0]
|
|
|
|
# Step 2 & 3: Try suffixes
|
|
suffixes = ['.ds.gc.ca', '.pre-ds.gc.ca']
|
|
|
|
for suffix in suffixes:
|
|
mgt_dns = short_name + suffix
|
|
resolved_ip = get_ip(mgt_dns)
|
|
if resolved_ip:
|
|
# Ruby: return mgt_dns if mgt_ip.to_s.length > 4
|
|
return mgt_dns
|
|
|
|
# print(f"Warning: {name_or_ip} could not be resolved to a management address.")
|
|
return None
|