tool-to-librenms.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #!/usr/local/bin/python3
  2. #
  3. # Copyright (c) 2017-2020 Joe Clarke <jclarke@cisco.com>
  4. # All rights reserved.
  5. #
  6. # Redistribution and use in source and binary forms, with or without
  7. # modification, are permitted provided that the following conditions
  8. # are met:
  9. # 1. Redistributions of source code must retain the above copyright
  10. # notice, this list of conditions and the following disclaimer.
  11. # 2. Redistributions in binary form must reproduce the above copyright
  12. # notice, this list of conditions and the following disclaimer in the
  13. # documentation and/or other materials provided with the distribution.
  14. #
  15. # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  16. # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18. # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  19. # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20. # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  21. # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  22. # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  23. # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  24. # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  25. # SUCH DAMAGE.
  26. from __future__ import print_function
  27. import requests
  28. from requests.packages.urllib3.exceptions import InsecureRequestWarning
  29. requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
  30. import json
  31. import sys
  32. import time
  33. import os
  34. from subprocess import Popen, PIPE, run
  35. import shlex
  36. from sparker import Sparker
  37. import pprint
  38. import re
  39. import socket
  40. import CLEUCreds
  41. from cleu.config import Config as C
  42. CACHE_FILE = "/home/jclarke/monitored_devs.json"
  43. def get_devs():
  44. url = "http://{}/get/switches/json".format(C.TOOL)
  45. devs = []
  46. response = requests.request("GET", url)
  47. code = 200
  48. code = response.status_code
  49. if code == 200:
  50. j = response.json()
  51. for dev in j:
  52. if dev["IPAddress"] == "0.0.0.0" or not dev["Reachable"]:
  53. continue
  54. if not re.search(r"^0", dev["Hostname"]):
  55. continue
  56. if (
  57. re.search(r".*CORE.*", dev["Hostname"], flags=re.I)
  58. or re.search(r".*MDF.*", dev["Hostname"], flags=re.I)
  59. or re.search(r"-x\d{2}-", dev["Hostname"], flags=re.I)
  60. ):
  61. continue
  62. devs.append(dev)
  63. return devs
  64. def delete_device(dev):
  65. res = run(shlex.split("ssh -2 {} /usr/local/www/librenms/delhost.php {}".format(C.MONITORING, dev)), capture_output=True)
  66. return res
  67. if __name__ == "__main__":
  68. devs = {}
  69. force = False
  70. changed_devs = False
  71. if len(sys.argv) == 2:
  72. if sys.argv[1] == "-f":
  73. force = True
  74. try:
  75. fd = open(CACHE_FILE, "r")
  76. devs = json.load(fd)
  77. fd.close()
  78. except Exception as e:
  79. print("Failed to open {}: {}".format(CACHE_FILE, e))
  80. tdevs = get_devs()
  81. i = 0
  82. for tdev in tdevs:
  83. i += 1
  84. if tdev["AssetTag"] in list(devs.keys()) and devs[tdev["AssetTag"]] != tdev["Hostname"]:
  85. print("=== Deleting device {} from LibreNMS ({} / {}) ===".format(tdev["Hostname"], i, len(tdevs)))
  86. res = delete_device(devs[tdev["AssetTag"]])
  87. if res.returncode != 0:
  88. print(
  89. "\n\n***WARNING: Failed to remove LibreNMS device for {}: out='{}', err='{}'".format(
  90. devs[tdev["AssetTag"]], res.stdout.decode("utf-8").strip(), res.stderr.decode("utf-8").strip()
  91. )
  92. )
  93. print("=== DONE. ===")
  94. changed_devs = True
  95. del devs[tdev["AssetTag"]]
  96. time.sleep(3)
  97. if tdev["AssetTag"] not in list(devs.keys()) or force:
  98. if force:
  99. print("=== Deleting device {} from LibreNMS ({} / {}) ===".format(tdev["Hostname"], i, len(tdevs)))
  100. res = delete_device(tdev["Hostname"])
  101. if res.returncode != 0:
  102. print(
  103. "\n\n***WARNING: Failed to remove LibreNMS device {}: out='{}', err='{}'".format(
  104. tdev["Hostname"], res.stdout.decode("utf-8").strip(), res.stderr.decode("utf-8").strip()
  105. )
  106. )
  107. print("=== DONE. ===")
  108. time.sleep(3)
  109. url = "https://librenms." + C.DNS_DOMAIN + "/api/v0/inventory/" + tdev["Hostname"]
  110. try:
  111. response = requests.request("GET", url, headers={"X-Auth-Token": CLEUCreds.LIBRENMS_TOKEN}, verify=False)
  112. response.raise_for_status()
  113. devs[tdev["AssetTag"]] = tdev["Hostname"]
  114. changed_devs = True
  115. continue
  116. except Exception as e:
  117. if not response or response.status_code != 400:
  118. text = ""
  119. if response:
  120. text = response.text
  121. print("Error retrieving device status from LibreNMS: {}".format(response.text))
  122. print("=== Adding device {} to LibreNMS ({} / {}) ===".format(tdev["Hostname"], i, len(tdevs)))
  123. res = run(
  124. shlex.split(
  125. "ssh -2 {} /usr/local/www/librenms/addhost.php {} ap v3 CLEUR {} {} sha des".format(
  126. C.MONITORING, tdev["Hostname"], CLEUCreds.SNMP_AUTH_PASS, CLEUCreds.SNMP_PRIV_PASS
  127. )
  128. ),
  129. capture_output=True,
  130. )
  131. if res.returncode != 0:
  132. print(
  133. "\n\n***ERROR: Failed to add {} to LibreNMS: out='{}', err='{}'".format(
  134. tdev["Hostname"], res.stdout.decode("utf-8").strip(), res.stderr.decode("utf-8").strip()
  135. )
  136. )
  137. continue
  138. print("=== DONE. ===")
  139. changed_devs = True
  140. devs[tdev["AssetTag"]] = tdev["Hostname"]
  141. if changed_devs:
  142. fd = open(CACHE_FILE, "w")
  143. json.dump(devs, fd)
  144. fd.close()