aboutsummaryrefslogtreecommitdiffstats
path: root/switch-snmp
diff options
context:
space:
mode:
Diffstat (limited to 'switch-snmp')
-rw-r--r--switch-snmp/.dockerignore5
-rw-r--r--switch-snmp/Dockerfile4
-rw-r--r--switch-snmp/mikrotik-switches.conf10
-rw-r--r--switch-snmp/mikrotik.py52
-rw-r--r--switch-snmp/omada-switches.conf5
-rw-r--r--switch-snmp/requirements.txt3
-rw-r--r--switch-snmp/switches.py57
7 files changed, 87 insertions, 49 deletions
diff --git a/switch-snmp/.dockerignore b/switch-snmp/.dockerignore
index ea6cd72..662471f 100644
--- a/switch-snmp/.dockerignore
+++ b/switch-snmp/.dockerignore
@@ -1 +1,4 @@
-port-names.conf \ No newline at end of file
+port-names.conf
+*.pem
+*.pub
+
diff --git a/switch-snmp/Dockerfile b/switch-snmp/Dockerfile
index d09e341..4369d61 100644
--- a/switch-snmp/Dockerfile
+++ b/switch-snmp/Dockerfile
@@ -1,4 +1,4 @@
-FROM ubuntu:20.04
+FROM reg.reaweb.uk/cron
ENV TZ=Europe/London
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt-get update -y
@@ -12,6 +12,6 @@ RUN pip3 install -r requirements.txt
RUN rm "privateMibs(20220831).zip"
RUN echo "*/1 * * * * root python3 /app/switches.py > /proc/1/fd/1 2>/proc/1/fd/2" > /etc/crontab
-RUN echo "*/1 * * * * root sh -c 'sleep 30 && python3 /app/switches.py' > /proc/1/fd/1 2>/proc/1/fd/2" >> /etc/crontab
+# RUN echo "*/1 * * * * root sh -c 'sleep 30 && python3 /app/switches.py' > /proc/1/fd/1 2>/proc/1/fd/2" >> /etc/crontab
ENTRYPOINT ["bash"]
CMD ["entrypoint.sh"]
diff --git a/switch-snmp/mikrotik-switches.conf b/switch-snmp/mikrotik-switches.conf
index b777b53..c1a344c 100644
--- a/switch-snmp/mikrotik-switches.conf
+++ b/switch-snmp/mikrotik-switches.conf
@@ -1,9 +1,9 @@
[192.168.69.22]
-ether1 = Modem
-ether2 = 2
-ether3 = EAP110 Wifi
-ether4 = Amazon Firestick
+ether2 = MikroTik CSS610-8G-2S+IN
+ether1 = TP-RP108GE
+ether3 = 3
+ether4 = 4
ether5 = 5
ether6 = 6
ether7 = 7
-ether8 = 8 \ No newline at end of file
+ether8 = 8
diff --git a/switch-snmp/mikrotik.py b/switch-snmp/mikrotik.py
index 29bc797..5c3a88a 100644
--- a/switch-snmp/mikrotik.py
+++ b/switch-snmp/mikrotik.py
@@ -4,15 +4,13 @@ import configparser
import threading
import fabric
import logging
+import socket
import time
import os
import re
-from influxdb_client import InfluxDBClient, Point, WritePrecision
-from influxdb_client.client.write_api import SYNCHRONOUS
-
-logging.basicConfig(
- format = "%(levelname)s\t[%(asctime)s]\t%(message)s",
+logging.basicConfig(
+ format = "%(levelname)s\t[%(asctime)s]\t%(message)s",
level = logging.INFO,
handlers=[
logging.StreamHandler()
@@ -39,9 +37,10 @@ class MikroTikSSHDevice:
return fabric.Connection(
user = self.user,
host = self.host,
- connect_kwargs = {"key_filename": self.ssh_key_path}
+ connect_kwargs = {"key_filename": self.ssh_key_path},
+ connect_timeout = 5
)
-
+
def _poll_four_interfaces(self, four_interfaces):
# only poll four interfaces at the same time since we can only get a certain amount of information through SSH at the same time
self.is_being_polled.set()
@@ -74,7 +73,7 @@ class MikroTikSSHDevice:
# print("Adding %s to off interfaces" % interface_name)
off_interfaces.add(interface_name)
return out
-
+
def get_poe_interfaces(self, interface_names):
out = {}
for four_interfaces in [interface_names[i:i + 4] for i in range(0, len(interface_names), 4)]:
@@ -82,6 +81,9 @@ class MikroTikSSHDevice:
return out
def remove_measurement_type(type_str):
+ if str(type_str).endswith(".0"):
+ return float(type_str)
+
type_str = "".join([s for s in type_str if s.isdigit() or s == "."])
if "." in type_str:
return float(type_str)
@@ -90,8 +92,8 @@ def remove_measurement_type(type_str):
def fields_to_points(fields, switch_host, config):
return [{
- "measurement": "switch_status",
- "tags": {"port": port, "port_name": config.get(switch_host, port), "switch_host": switch_host, "type": "MikroTik"},
+ "measurement": "switch_status",
+ "tags": {"port": port, "port_name": config.get(switch_host, port), "switch_host": switch_host, "type": "MikroTik"},
"fields": {INFLUXDB_MAPPINGS[k]: remove_measurement_type(v) for k, v in values.items() if k in INFLUXDB_MAPPINGS}
} for port, values in fields.items()]
@@ -103,7 +105,7 @@ def get_points():
mikrotik_device = MikroTikSSHDevice(mikrotik_switch, os.path.join(os.path.dirname(__file__), "mikrotik.pem"))
try:
points += fields_to_points(mikrotik_device.get_poe_interfaces(list(mikrotik_switches[mikrotik_switch].keys())), mikrotik_switch, mikrotik_switches)
- except NoValidConnectionsError as e:
+ except (NoValidConnectionsError, TimeoutError, socket.timeout) as e:
logging.error("Could not connect to mikrotik switch @ %s" % mikrotik_switch)
return points
@@ -121,38 +123,12 @@ def print_points(points):
measurement["fields"]["tpPoeVoltage"],
))
-def append(points):
- env_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "config.env")
- if os.path.exists(env_path):
- import dotenv
- dotenv.load_dotenv(dotenv_path = env_path)
- INFLUXDB_HOST = "dns.athome"
- else:
- INFLUXDB_HOST = "influxdb"
-
- influxc = InfluxDBClient(
- url = "http://%s:8086" % INFLUXDB_HOST,
- token = os.environ["DOCKER_INFLUXDB_INIT_ADMIN_TOKEN"],
- org = os.environ["DOCKER_INFLUXDB_INIT_ORG"]
- )
- influxc.ping()
-
- write_api = influxc.write_api(write_options = SYNCHRONOUS)
- write_api.write(
- os.environ["DOCKER_INFLUXDB_INIT_BUCKET"],
- os.environ["DOCKER_INFLUXDB_INIT_ORG"],
- points,
- write_precision = WritePrecision.S
- )
-
if __name__ == "__main__":
if not os.path.exists(os.path.join(os.path.dirname(__file__), "mikrotik-switches.conf")):
raise FileNotFoundError("Couldn't find mikrotik config file")
if not os.path.exists(os.path.join(os.path.dirname(__file__), "mikrotik.pem")):
raise FileNotFoundError("Couldn't find mikrotik public key file")
-
+
import json
points = get_points()
print(json.dumps(points, indent = 4))
- append(points)
-
diff --git a/switch-snmp/omada-switches.conf b/switch-snmp/omada-switches.conf
index 3f3f3f0..a76ff82 100644
--- a/switch-snmp/omada-switches.conf
+++ b/switch-snmp/omada-switches.conf
@@ -1,4 +1,4 @@
-[192.168.69.26]
+[192.168.69.112]
1 = EAP225 Wifi
2 = Tasmota Zigbee
4 = Mikrotik CRS310-8G+2S+
@@ -8,6 +8,7 @@
23 = Modem & ES205G
8 = PiKVM
10 = TL-RP108GE & EAP110
+11 = Type-C POE Charger
22 = Cluster Pi 9
19 = Cluster Pi 5
20 = Cluster Pi 7
@@ -15,4 +16,6 @@
18 = Cluster Pi 6
17 = Cluster Pi 4
9 = Jetson Orin Nano
+12 = Netgate SG-1100
+
diff --git a/switch-snmp/requirements.txt b/switch-snmp/requirements.txt
index aaf744d..aeb5843 100644
--- a/switch-snmp/requirements.txt
+++ b/switch-snmp/requirements.txt
@@ -1,4 +1,5 @@
python-dotenv
influxdb-client
pandas
-fabric \ No newline at end of file
+fabric
+prometheus-client \ No newline at end of file
diff --git a/switch-snmp/switches.py b/switch-snmp/switches.py
index aee56d2..1bc43c2 100644
--- a/switch-snmp/switches.py
+++ b/switch-snmp/switches.py
@@ -1,7 +1,62 @@
+import prometheus_client
import snmpOmada
import mikrotik
+import os
+
+from influxdb_client import InfluxDBClient, Point, WritePrecision
+from influxdb_client.client.write_api import SYNCHRONOUS
+
+def append(points):
+ influxc = InfluxDBClient(
+ url = "http://%s:8086" % INFLUXDB_HOST,
+ token = os.environ["DOCKER_INFLUXDB_INIT_ADMIN_TOKEN"],
+ org = os.environ["DOCKER_INFLUXDB_INIT_ORG"]
+ )
+ influxc.ping()
+
+ for measurement in points:
+ for field in measurement["fields"].keys():
+ try:
+ float(measurement["fields"][field])
+ except ValueError:
+ continue
+ else:
+ switch_power.labels(
+ field = field,
+ type = measurement["tags"]["type"],
+ port = str(measurement["tags"]["port"]),
+ port_name = measurement["tags"]["port_name"],
+ host = measurement["tags"]["switch_host"]
+ ).set(float(measurement["fields"][field]))
+ prometheus_client.push_to_gateway("%s:9091" % PUSHGATEWAY_HOST, job = "switchSNMP", registry = registry)
+
+ write_api = influxc.write_api(write_options = SYNCHRONOUS)
+ write_api.write(
+ os.environ["DOCKER_INFLUXDB_INIT_BUCKET"],
+ os.environ["DOCKER_INFLUXDB_INIT_ORG"],
+ points,
+ write_precision = WritePrecision.S
+ )
if __name__ == "__main__":
+ env_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "config.env")
+ if os.path.exists(env_path):
+ import dotenv
+ dotenv.load_dotenv(dotenv_path = env_path)
+ INFLUXDB_HOST = "dns.athome"
+ PUSHGATEWAY_HOST = "dns.athome"
+ else:
+ INFLUXDB_HOST = "influxdb"
+ PUSHGATEWAY_HOST = "pushgateway"
+
+ registry = prometheus_client.CollectorRegistry()
+ switch_power = prometheus_client.Gauge(
+ "switch_power",
+ "POE switch power usage metrics from Omada and Mikrotik switches, using Omada SNMP names",
+ labelnames = ["field", "type", "port", "port_name", "host"],
+ registry = registry
+ )
+
points = snmpOmada.get_points() + mikrotik.get_points()
mikrotik.print_points(points)
- mikrotik.append(points) \ No newline at end of file
+ append(points)