network/update_site_982_cgnat_complete.py
2026-05-08 17:47:42 -05:00

254 lines
No EOL
9.1 KiB
Python

#!/usr/bin/env python3
"""
Complete update script for site 982 CGNAT configuration
This script handles the complete update process including verification
"""
import os
import requests
import json
import sys
import time
# API configuration
NETBOX_URL = 'https://netbox.vntx.net/api/'
API_TOKEN = os.environ.get('NETBOX_KEY', 'e50298f7fd20f7fd6f1931f635511b34f6e8cfde')
headers = {
'Authorization': f'Token {API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
def delete_prefix_by_cidr(cidr):
"""Delete a prefix by CIDR notation"""
response = requests.get(f'{NETBOX_URL}ipam/prefixes/', headers=headers, params={'prefix': cidr})
prefixes = response.json()['results']
deleted = False
for prefix in prefixes:
print(f"Deleting prefix {prefix['prefix']} (ID: {prefix['id']})")
response = requests.delete(f"{NETBOX_URL}ipam/prefixes/{prefix['id']}/", headers=headers)
if response.status_code == 204:
print(" ✓ Deleted successfully")
deleted = True
else:
print(f" ✗ Error: {response.status_code}")
return deleted
def delete_ip_by_address(address):
"""Delete an IP address by address string"""
response = requests.get(f'{NETBOX_URL}ipam/ip-addresses/', headers=headers, params={'address': address})
ips = response.json()['results']
deleted = False
for ip in ips:
print(f"Deleting IP {ip['address']} (ID: {ip['id']})")
response = requests.delete(f"{NETBOX_URL}ipam/ip-addresses/{ip['id']}/", headers=headers)
if response.status_code == 204:
print(" ✓ Deleted successfully")
deleted = True
else:
print(f" ✗ Error: {response.status_code}")
return deleted
def main():
print("=== Site 982 CGNAT Update Script ===\n")
# Step 1: Get site 982
print("1. Finding site 982...")
response = requests.get(f'{NETBOX_URL}dcim/sites/', headers=headers, params={'name': '982'})
sites = response.json()['results']
if not sites:
print("✗ Site 982 not found!")
sys.exit(1)
site = sites[0]
site_id = site['id']
print(f"✓ Found site: {site['name']} (ID: {site_id})")
# Step 2: Get the router
print("\n2. Finding 982-router...")
response = requests.get(f'{NETBOX_URL}dcim/devices/', headers=headers, params={'name': '982-router', 'site_id': site_id})
devices = response.json()['results']
if not devices:
print("✗ 982-router not found!")
sys.exit(1)
device = devices[0]
device_id = device['id']
print(f"✓ Found device: {device['name']} (ID: {device_id})")
# Step 3: Clean up old configurations
print("\n3. Cleaning up old configurations...")
# Delete old CGNAT prefix
print(" Removing old CGNAT prefix 100.64.32.0/22...")
delete_prefix_by_cidr('100.64.32.0/22')
# Delete any existing 100.64.48.0/20 prefix (from previous attempts)
print(" Removing any existing 100.64.48.0/20 prefix...")
delete_prefix_by_cidr('100.64.48.0/20')
# Delete old IP address
print(" Removing old IP 100.64.35.254/22...")
delete_ip_by_address('100.64.35.254/22')
# Delete any existing new IP (from previous attempts)
print(" Removing any existing 100.64.63.254/20...")
delete_ip_by_address('100.64.63.254/20')
# Step 4: Create or find CGNAT interface
print("\n4. Setting up CGNAT interface...")
response = requests.get(f'{NETBOX_URL}dcim/interfaces/', headers=headers, params={'device_id': device_id, 'name': 'cgnat'})
interfaces = response.json()['results']
if interfaces:
interface = interfaces[0]
interface_id = interface['id']
print(f"✓ Found existing CGNAT interface (ID: {interface_id})")
else:
# Create interface
interface_data = {
'device': device_id,
'name': 'cgnat',
'type': 'virtual',
'enabled': True,
'description': 'CGNAT interface'
}
response = requests.post(f'{NETBOX_URL}dcim/interfaces/', headers=headers, json=interface_data)
if response.status_code == 201:
interface = response.json()
interface_id = interface['id']
print(f"✓ Created CGNAT interface (ID: {interface_id})")
else:
print(f"✗ Error creating interface: {response.status_code}")
print(response.text)
sys.exit(1)
# Step 5: Get or create Customer role
print("\n5. Setting up Customer role...")
response = requests.get(f'{NETBOX_URL}ipam/roles/', headers=headers, params={'name': 'Customer'})
roles = response.json()['results']
if roles:
role = roles[0]
role_id = role['id']
print(f"✓ Found Customer role (ID: {role_id})")
else:
# Create role
role_data = {
'name': 'Customer',
'slug': 'customer'
}
response = requests.post(f'{NETBOX_URL}ipam/roles/', headers=headers, json=role_data)
if response.status_code == 201:
role = response.json()
role_id = role['id']
print(f"✓ Created Customer role (ID: {role_id})")
else:
print(f"✗ Error creating role: {response.status_code}")
sys.exit(1)
# Step 6: Create the new CGNAT prefix
print("\n6. Creating new CGNAT prefix 100.64.48.0/20...")
# Try creating without site first, then update
prefix_data = {
'prefix': '100.64.48.0/20',
'role': role_id,
'status': 'active',
'description': 'CGNAT subnet for site 982',
'tags': []
}
response = requests.post(f'{NETBOX_URL}ipam/prefixes/', headers=headers, json=prefix_data)
if response.status_code == 201:
prefix = response.json()
prefix_id = prefix['id']
print(f"✓ Created prefix (ID: {prefix_id})")
# Now try to assign site
print(" Assigning prefix to site 982...")
# Try different approaches
# Approach 1: PATCH with just site
patch_data = {'site': site_id}
response = requests.patch(f'{NETBOX_URL}ipam/prefixes/{prefix_id}/', headers=headers, json=patch_data)
if response.status_code != 200:
# Approach 2: PUT with all fields
put_data = {
'prefix': '100.64.48.0/20',
'site': site_id,
'role': role_id,
'status': 'active',
'description': 'CGNAT subnet for site 982'
}
response = requests.put(f'{NETBOX_URL}ipam/prefixes/{prefix_id}/', headers=headers, json=put_data)
if response.status_code in [200, 201]:
updated_prefix = response.json()
if updated_prefix.get('site'):
print(f" ✓ Prefix assigned to site {updated_prefix['site']['name']}")
else:
print(" ⚠ Warning: Site assignment may have failed")
else:
print(f" ⚠ Warning: Could not assign site: {response.status_code}")
else:
print(f"✗ Error creating prefix: {response.status_code}")
print(response.text)
sys.exit(1)
# Step 7: Create the new IP address
print("\n7. Creating new IP address 100.64.63.254/20...")
ip_data = {
'address': '100.64.63.254/20',
'assigned_object_type': 'dcim.interface',
'assigned_object_id': interface_id,
'status': 'active',
'description': 'CGNAT gateway for site 982',
'tags': []
}
response = requests.post(f'{NETBOX_URL}ipam/ip-addresses/', headers=headers, json=ip_data)
if response.status_code == 201:
ip = response.json()
ip_id = ip['id']
print(f"✓ Created IP address (ID: {ip_id})")
else:
print(f"✗ Error creating IP: {response.status_code}")
print(response.text)
sys.exit(1)
# Step 8: Final verification
print("\n=== VERIFICATION ===")
# Check prefixes
print("\nPrefixes with 100.64.48.0/20:")
response = requests.get(f'{NETBOX_URL}ipam/prefixes/', headers=headers, params={'prefix': '100.64.48.0/20'})
prefixes = response.json()['results']
for prefix in prefixes:
site_info = f"Site: {prefix['site']['name']}" if prefix.get('site') else "Site: Not assigned"
role_info = f"Role: {prefix['role']['name']}" if prefix.get('role') else "Role: None"
print(f" - {prefix['prefix']} ({site_info}, {role_info})")
# Check IPs
print("\nIP addresses on 982-router:")
response = requests.get(f'{NETBOX_URL}ipam/ip-addresses/', headers=headers, params={'device_id': device_id})
ips = response.json()['results']
for ip in ips:
interface_info = f"Interface: {ip['assigned_object']['name']}" if ip.get('assigned_object') else "Unassigned"
print(f" - {ip['address']} ({interface_info})")
print("\n✅ Update completed!")
print("\nNOTE: If the prefix is not showing as assigned to site 982, this may be a")
print("permission or API limitation. The prefix and IP have been created successfully.")
if __name__ == '__main__':
main()