add-vlans.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #!/usr/bin/env python
  2. from elemental_utils import ElementalNetbox
  3. from elemental_utils.utils import check_environment
  4. import csv
  5. import argparse
  6. import sys
  7. from typing import List, Dict
  8. def get_vlan_list(file: str) -> List[Dict]:
  9. """
  10. Given a CSV file input, provide a list of VLAN dicts.
  11. """
  12. REQ_FIELDS = 6
  13. vlans = []
  14. with open(file, encoding="utf8") as csvin:
  15. csvin = csv.reader(csvin)
  16. for rnum, row in enumerate(csvin):
  17. if row[0].startswith(";"):
  18. continue
  19. if len(row) < REQ_FIELDS:
  20. raise ValueError(f"Invalid number of fields for row {rnum}. Must be {REQ_FIELDS} fields but is {len(row)}")
  21. if not row[0].isnumeric():
  22. raise ValueError(f"Invalid VLAN ID on row {rnum}: {row[0]}")
  23. vlan_id = int(row[0])
  24. if vlan_id < 1 or vlan_id > 4094:
  25. raise ValueError(f"Invalid VLAN ID on row {rnum}. Should be between 1 and 4094.")
  26. if row[2] != "" and row[3] != "":
  27. raise ValueError(f"Cannot specify both a site and a group on row {rnum}")
  28. vlan_data = {
  29. "id": vlan_id,
  30. "name": row[1],
  31. "site": row[2],
  32. "group": row[3],
  33. "tenant": row[4],
  34. "description": row[5],
  35. }
  36. vlans.append(vlan_data)
  37. return vlans
  38. def main():
  39. parser = argparse.ArgumentParser(prog=sys.argv[0], description="Add VLANs to NetBox")
  40. parser.add_argument("--file", "-f", metavar="<input CSV file>", help="Path to the input CSV file", required=True)
  41. args = parser.parse_args()
  42. enb = ElementalNetbox(None, None, ignore_tls=True)
  43. try:
  44. vlans = get_vlan_list(args.file)
  45. except Exception as e:
  46. print(f"Failed to load VLAN list: {e}.")
  47. exit(1)
  48. for vlan in vlans:
  49. if vlan["site"] != "":
  50. nb_vlan = enb.ipam.vlans.get(vid=vlan["id"], site=vlan["site"])
  51. vlan_site = {"slug": vlan["site"]}
  52. vlan_group = None
  53. else:
  54. nb_vlan = enb.ipam.vlans.get(vid=vlan["id"], group=vlan["group"])
  55. vlan_site = None
  56. vlan_group = {"slug": vlan["group"]}
  57. vlan_data = {
  58. "vid": vlan["id"],
  59. "name": vlan["name"],
  60. "site": vlan_site,
  61. "group": vlan_group,
  62. "tenant": {"slug": vlan["tenant"]},
  63. "description": vlan["description"],
  64. }
  65. if not nb_vlan:
  66. print(f"Creating VLAN {vlan['id']} with parameters {vlan_data}")
  67. try:
  68. nb_vlan = enb.ipam.vlans.create(**vlan_data)
  69. except Exception as e:
  70. print(f"Failed to create VLAN {vlan['id']}: {e}")
  71. continue
  72. print(f"Updating VLAN {vlan['id']} with parameters {vlan_data}")
  73. nb_vlan.name = vlan["name"]
  74. nb_vlan.site = vlan_site
  75. nb_vlan.group = vlan_group
  76. nb_vlan.tenant = {"slug": vlan["tenant"]}
  77. nb_vlan.descrption = vlan["description"]
  78. try:
  79. nb_vlan.save()
  80. except Exception as e:
  81. print(f"Failed to update VLAN {vlan['id']}: {e}")
  82. if __name__ == "__main__":
  83. main()