netbox-export-to-google.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. #!/usr/bin/env python
  2. from googleapiclient.discovery import build
  3. from google.auth.transport.requests import Request
  4. from google.oauth2.credentials import Credentials
  5. import pynetbox
  6. import os
  7. import csv
  8. import io
  9. import CLEUCreds # type: ignore
  10. from cleu.config import Config as C # type: ignore
  11. CREDS_FILE = "gs_token.json"
  12. SHEET_ID = "1kKOqbK_y3l6Ume-MSkLg1nTVbw571mcq3EOQw5IWuWQ"
  13. def main() -> None:
  14. """Export NetBox IP address data to a Google Sheet"""
  15. global creds, SHEET_ID
  16. # Connect to NetBox
  17. nb = pynetbox.api(C.NETBOX_SERVER, CLEUCreds.NETBOX_API_TOKEN)
  18. # Get all IP addresses from NetBox
  19. try:
  20. ips = list(nb.ipam.ip_addresses.all())
  21. except Exception as e:
  22. print(f"ERROR: Failed to get IPs from NetBox: {e}")
  23. exit(1)
  24. headers = [
  25. "Address",
  26. "VRF",
  27. "Status",
  28. "Role",
  29. "Tenant",
  30. "Assigned",
  31. "DNS name",
  32. "Description",
  33. "ID",
  34. "Tenant Group",
  35. "NAT (Inside)",
  36. "NAT (Outside)",
  37. "Comments",
  38. "Tags",
  39. "Created",
  40. "Last updated",
  41. "Interface",
  42. "Parent",
  43. "List of additional CNAMEs",
  44. ]
  45. output = io.StringIO()
  46. dict_writer = csv.DictWriter(output, headers)
  47. dict_writer.writeheader()
  48. for ip in ips:
  49. tenant = None
  50. tenant_group = None
  51. if ip.tenant:
  52. ip.tenant.full_details()
  53. tenant = ip.tenant.name
  54. tenant_group = str(ip.tenant.group)
  55. parent = None
  56. if ip.assigned_object:
  57. if ip.assigned_object_type == "virtualization.vminterface":
  58. parent = ip.assigned_object.virtual_machine.name
  59. elif ip.assigned_object_type == "dcim.interface":
  60. parent = ip.assigned_object.device.name
  61. row = {
  62. "Address": ip.address,
  63. "VRF": str(ip.vrf),
  64. "Status": ip.status.label,
  65. "Role": str(ip.role),
  66. "Tenant": tenant,
  67. "Assigned": ip.assigned_object_id,
  68. "DNS name": ip.dns_name,
  69. "Description": ip.description,
  70. "ID": ip.id,
  71. "Tenant Group": tenant_group,
  72. "NAT (Inside)": str(ip.nat_inside),
  73. "NAT (Outside)": str(ip.nat_outside),
  74. "Comments": ip.comments,
  75. "Tags": str(ip.tags),
  76. "Created": str(ip.created),
  77. "Last updated": str(ip.last_updated),
  78. "Interface": str(ip.assigned_object),
  79. "Parent": parent,
  80. "List of additional CNAMEs": ip.custom_fields["CNAMEs"],
  81. }
  82. dict_writer.writerow(row)
  83. output.seek(0)
  84. new_values = []
  85. new_values.append(headers)
  86. dict_reader = csv.DictReader(output)
  87. for row in dict_reader:
  88. r = []
  89. for header in headers:
  90. r.append(row[header])
  91. new_values.append(r)
  92. gs_service = build("sheets", "v4", credentials=creds)
  93. ip_sheet = gs_service.spreadsheets()
  94. ip_result = (
  95. ip_sheet.values().update(spreadsheetId=SHEET_ID, range="IPs!A1:ZZ", body={"values": new_values}, valueInputOption="RAW").execute()
  96. )
  97. print(ip_result)
  98. output.close()
  99. if __name__ == "__main__":
  100. if not os.path.isfile(CREDS_FILE):
  101. print(f"ERROR: Token file {CREDS_FILE} does not exist! Please re-authenticate this app.")
  102. exit(1)
  103. creds = Credentials.from_authorized_user_file(CREDS_FILE, ["https://www.googleapis.com/auth/spreadsheets"])
  104. if not creds.valid:
  105. creds.refresh(Request())
  106. with open(CREDS_FILE, "w") as fd:
  107. fd.write(creds.to_json())
  108. main()