Compare commits
No commits in common. "b59a6368c9919fe9ff488c4bae20d530a769241b" and "a2a1384e9d9bdef5b86608bea6278953dabd5289" have entirely different histories.
b59a6368c9
...
a2a1384e9d
11 changed files with 373 additions and 886 deletions
|
@ -1,5 +1,5 @@
|
||||||
[bumpversion]
|
[bumpversion]
|
||||||
current_version = 0.5.1
|
current_version = 0.4.0
|
||||||
commit = True
|
commit = True
|
||||||
tag = True
|
tag = True
|
||||||
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
CHECK_FREQUENCY_SECONDS: default value for --check-frequency-seconds param
|
|
||||||
OPNSENSE_MAIN_HOST: default value for --main-host param
|
|
||||||
OPNSENSE_BACKUP_HOST: default value for --backup-host param
|
|
||||||
OPNSENSE_USERNAME: default value for --opnsense-user param
|
|
||||||
OPNSENSE_PASSWORD: default value for --opnsense-password param
|
|
||||||
OPNSENSE_INTERFACES: default value for --opnsense-interfaces param
|
|
22
Dockerfile
22
Dockerfile
|
@ -1,22 +0,0 @@
|
||||||
FROM python:latest
|
|
||||||
|
|
||||||
#WORKDIR /usr/app/src
|
|
||||||
|
|
||||||
# Install package
|
|
||||||
WORKDIR /code
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
#COPY prometheus-ssh-exporter.py ./
|
|
||||||
#COPY requirements.txt ./
|
|
||||||
|
|
||||||
RUN pip3 install -r requirements.txt
|
|
||||||
|
|
||||||
RUN python -u setup.py install
|
|
||||||
|
|
||||||
# Set this to the port you want to expose
|
|
||||||
EXPOSE 8000
|
|
||||||
|
|
||||||
# Set the -p option to the port you exposed above, defaults to 8000
|
|
||||||
#CMD ["python", "-u", "opnsense-exporter"]
|
|
||||||
#CMD ["sleep", "60"]
|
|
||||||
CMD ["opnsense-exporter"]
|
|
75
README.md
75
README.md
|
@ -26,24 +26,16 @@ This exporter gives following metrics, all metrics received following labels:
|
||||||
|
|
||||||
- `instance`: by default this is set with the hostname where is running this exporter service
|
- `instance`: by default this is set with the hostname where is running this exporter service
|
||||||
- `host`: the host of the OPNSense
|
- `host`: the host of the OPNSense
|
||||||
- `role`: `main` or `backup` to determine the OPNSense server role.
|
|
||||||
|
|
||||||
### Enums
|
### Enums
|
||||||
|
|
||||||
- `opnsense_main_ha_state`: (deprecated) OPNSense HA state of the MAIN server
|
- `opnsense_main_ha_state`: OPNSense HA state of the MAIN server
|
||||||
- `opnsense_backup_ha_state`: (deprecated) OPNSense HA state of the BACKUP server
|
- `opnsense_backup_ha_state`: OPNSense HA state of the BACKUP server
|
||||||
- `opnsense_server_ha_state`: OPNSense HA state, on of following value:
|
|
||||||
- **active**: that OPNSense server is receiving traffic
|
|
||||||
- **hot_standby**: the OPNSense server is ready to be promote as active server
|
|
||||||
- **maintenancemode**: the OPNSense server was turned into maintenance mode
|
|
||||||
- **unavailable**: the OPNSense server wasn't accessible or return unexpected value
|
|
||||||
|
|
||||||
### Gauges
|
### Gauges
|
||||||
|
|
||||||
- `opnsense_active_server_traffic_rate`: Active OPNSense server traffic rate per interfaces bits/s
|
- `opnsense_active_server_bytes_received`: Active OPNSense server bytes received on WAN interface
|
||||||
add following labels:
|
- `opnsense_active_server_bytes_transmitted`: Active OPNSense server bytes transmitted on WAN interface
|
||||||
- **interface**: the interface to export (values given using `--opnsense-interfaces`)
|
|
||||||
- **metric**: the metric name (as today one of `rate_bits_in`, `rate_bits_in`)
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
@ -54,7 +46,6 @@ opnsense-exporter --help
|
||||||
usage: opnsense-exporter [-h] [--check-frequency-seconds FREQUENCY]
|
usage: opnsense-exporter [-h] [--check-frequency-seconds FREQUENCY]
|
||||||
[--main-host MAIN] [--backup-host BACKUP]
|
[--main-host MAIN] [--backup-host BACKUP]
|
||||||
[--opnsense-user USER]
|
[--opnsense-user USER]
|
||||||
[--opnsense-interfaces INTERFACES]
|
|
||||||
[--opnsense-password PASSWORD]
|
[--opnsense-password PASSWORD]
|
||||||
[--prometheus-instance PROM_INSTANCE]
|
[--prometheus-instance PROM_INSTANCE]
|
||||||
|
|
||||||
|
@ -69,24 +60,17 @@ optional arguments:
|
||||||
MAIN OPNsense server that should be in `active`
|
MAIN OPNsense server that should be in `active`
|
||||||
state in normal configuration.
|
state in normal configuration.
|
||||||
--backup-host BACKUP, -b BACKUP
|
--backup-host BACKUP, -b BACKUP
|
||||||
BACKUP OPNsense server that should be `hot_standby`
|
BACKUP OPNsense server that should be
|
||||||
state in normal configuration.
|
`hot_standby` state in normal configuration.
|
||||||
--opnsense-user USER, -u USER
|
--opnsense-user USER, -u USER
|
||||||
OPNsense user. Expect to be the same on MAIN and
|
OPNsense user. Expect to be the same on MAIN and
|
||||||
BACKUP servers
|
BACKUP servers
|
||||||
--opnsense-interfaces INTERFACES, -i INTERFACES
|
|
||||||
OPNsense interfaces (coma separated) list to
|
|
||||||
export trafic rates (bytes/s). An empty string ''
|
|
||||||
means not calling the traffic diagnostic REST API
|
|
||||||
so no `opnsense_active_server_traffic_rate`
|
|
||||||
metric. (default: wan,lan)
|
|
||||||
--opnsense-password PASSWORD, -p PASSWORD
|
--opnsense-password PASSWORD, -p PASSWORD
|
||||||
OPNsense password. Expect to be the same on MAIN
|
OPNsense password. Expect to be the same on MAIN
|
||||||
and BACKUP servers
|
and BACKUP servers
|
||||||
--prometheus-instance PROM_INSTANCE
|
--prometheus-instance PROM_INSTANCE
|
||||||
Exporter Instance name, default value computed with
|
Exporter Instance name, default value computed
|
||||||
hostname where the server is running. Use to set
|
with hostname where the server is running. Use to
|
||||||
the instance label. (default: my-opnsense-prom-exporter-server)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
You can setup env through `.env` file or environment variables with defined as default values
|
You can setup env through `.env` file or environment variables with defined as default values
|
||||||
|
@ -97,52 +81,25 @@ You can setup env through `.env` file or environment variables with defined as d
|
||||||
- **OPNSENSE_BACKUP_HOST**: default value for `--backup-host` param
|
- **OPNSENSE_BACKUP_HOST**: default value for `--backup-host` param
|
||||||
- **OPNSENSE_USERNAME**: default value for `--opnsense-user` param
|
- **OPNSENSE_USERNAME**: default value for `--opnsense-user` param
|
||||||
- **OPNSENSE_PASSWORD**: default value for `--opnsense-password` param
|
- **OPNSENSE_PASSWORD**: default value for `--opnsense-password` param
|
||||||
- **OPNSENSE_INTERFACES**: default value for `--opnsense-interfaces` param
|
|
||||||
|
|
||||||
## Roadmap
|
## Roadmap
|
||||||
|
|
||||||
- allow to change the listening port (today it force using `8000`)
|
- allow to change the listening port (today it force using `8000`)
|
||||||
- allow to configure timeouts using environment variables
|
|
||||||
- improves logging to get a debug mode to understand errors based on unexpected payloads
|
|
||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
### Version 1.0.0 (UNRELEASED)
|
### Version 0.4.0
|
||||||
|
|
||||||
- remove `opnsense_main_ha_state` and `opnsense_backup_ha_state`
|
Higher timeout while getting WAN traffic info
|
||||||
metrics marked as deprecated on version 0.5.0 and replace
|
|
||||||
by `opnsense_server_ha_state` and `role` label
|
|
||||||
- allow empty string interfaces to **not** call diagnostic
|
|
||||||
traffic REST API
|
|
||||||
|
|
||||||
|
### Version 0.3.0
|
||||||
|
|
||||||
### Version 0.5.1 (2023-09-04)
|
Use proper method to compute WAN traffic
|
||||||
|
|
||||||
- FIX `opnsense_server_ha_state` calls were not
|
### Version 0.2.0
|
||||||
implemented
|
|
||||||
|
|
||||||
### Version 0.5.0 (2023-09-04)
|
Setup automatic release from gitlab while pushing new tag
|
||||||
|
|
||||||
- add role label in metrics
|
### Version 0.1.0
|
||||||
- all to configure supervised interfaces using `--opnsense-interfaces`
|
|
||||||
- replace `active_server_bytes_received` and
|
|
||||||
`active_server_bytes_transmitted` by
|
|
||||||
`opnsense_active_server_traffic_rate`
|
|
||||||
- add `opnsense_server_ha_state` and mark `opnsense_main_ha_state`
|
|
||||||
and `opnsense_backup_ha_state` as deprecated.
|
|
||||||
|
|
||||||
### Version 0.4.0 (2023-09-02)
|
Initial version
|
||||||
|
|
||||||
- Higher timeout while getting WAN traffic info
|
|
||||||
|
|
||||||
### Version 0.3.0 (2023-09-02)
|
|
||||||
|
|
||||||
- Use proper method to compute WAN traffic
|
|
||||||
|
|
||||||
### Version 0.2.0 (2023-09-01)
|
|
||||||
|
|
||||||
- Setup automatic release from gitlab while pushing new tag
|
|
||||||
|
|
||||||
### Version 0.1.0 (2023-09-01)
|
|
||||||
|
|
||||||
- Initial version
|
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
version: '3.4'
|
|
||||||
|
|
||||||
services:
|
|
||||||
opnsense-exporter:
|
|
||||||
image: opnsense-exporter
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: ./Dockerfile
|
|
||||||
restart: always
|
|
||||||
container_name: opnsense-exporter
|
|
||||||
#network_mode: "host"
|
|
||||||
ports:
|
|
||||||
- 8000:8000
|
|
||||||
env_file:
|
|
||||||
- .env
|
|
||||||
logging:
|
|
||||||
driver: "json-file"
|
|
||||||
options:
|
|
||||||
max-file: "3"
|
|
||||||
max-size: 10m
|
|
|
@ -1,5 +1,4 @@
|
||||||
import logging
|
import logging
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from requests import RequestException
|
from requests import RequestException
|
||||||
|
@ -7,68 +6,16 @@ from requests import RequestException
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class OPNSenseHAState(Enum):
|
|
||||||
ACTIVE = "active"
|
|
||||||
HOT_STANDBY = "hot_standby"
|
|
||||||
UNAVAILABLE = "unavailable"
|
|
||||||
MAINTENANCE_MODE = "maintenancemode"
|
|
||||||
|
|
||||||
|
|
||||||
class OPNSenseTrafficMetric(Enum):
|
|
||||||
IN = "rate_bits_in"
|
|
||||||
OUT = "rate_bits_out"
|
|
||||||
|
|
||||||
|
|
||||||
class OPNSenseTraffic:
|
|
||||||
interface: str = None
|
|
||||||
metric: OPNSenseTrafficMetric = None
|
|
||||||
value: int = 0
|
|
||||||
|
|
||||||
def __init__(self, interface: str, metric: OPNSenseTrafficMetric, value: int = 0):
|
|
||||||
self.value = value
|
|
||||||
self.interface = interface
|
|
||||||
self.metric = metric
|
|
||||||
|
|
||||||
@property
|
|
||||||
def labels(self):
|
|
||||||
return {"metric": self.metric.value, "interface": self.interface}
|
|
||||||
|
|
||||||
def __eq__(self, opn_traffic):
|
|
||||||
"""Used by unittest to assert expected values"""
|
|
||||||
return (
|
|
||||||
self.interface == opn_traffic.interface
|
|
||||||
and self.metric == opn_traffic.metric
|
|
||||||
and self.value == opn_traffic.value
|
|
||||||
)
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return f"{self.interface} - {self.metric} = {self.value}"
|
|
||||||
|
|
||||||
|
|
||||||
class OPNSenseRole(Enum):
|
|
||||||
MAIN = "main"
|
|
||||||
BACKUP = "backup"
|
|
||||||
|
|
||||||
|
|
||||||
class OPNSenseAPI:
|
class OPNSenseAPI:
|
||||||
host: str = None
|
host: str = None
|
||||||
login: str = None
|
login: str = None
|
||||||
password: str = None
|
password: str = None
|
||||||
role: OPNSenseRole = None
|
|
||||||
|
|
||||||
def __init__(self, role, host, login, password):
|
def __init__(self, host, login, password):
|
||||||
self.role = role
|
|
||||||
self.host = host
|
self.host = host
|
||||||
self.login = login
|
self.login = login
|
||||||
self.password = password
|
self.password = password
|
||||||
|
|
||||||
@property
|
|
||||||
def labels(self):
|
|
||||||
return {
|
|
||||||
"host": self.host,
|
|
||||||
"role": self.role.value,
|
|
||||||
}
|
|
||||||
|
|
||||||
def prepare_url(self, path):
|
def prepare_url(self, path):
|
||||||
return f"https://{self.host}{path}"
|
return f"https://{self.host}{path}"
|
||||||
|
|
||||||
|
@ -84,46 +31,41 @@ class OPNSenseAPI:
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
return response.json()
|
return response.json()
|
||||||
|
|
||||||
def get_interface_vip_status(self) -> OPNSenseHAState:
|
def get_interface_vip_status(self):
|
||||||
try:
|
try:
|
||||||
data = self.get("/api/diagnostics/interface/get_vip_status/")
|
data = self.get("/api/diagnostics/interface/get_vip_status/")
|
||||||
except RequestException as ex:
|
except RequestException as ex:
|
||||||
logger.error(
|
logger.error(
|
||||||
"Get VIP STATUS on %s failed with the following error %r", self.host, ex
|
"Get VIP STATUS on %s failed with the following error %r", self.host, ex
|
||||||
)
|
)
|
||||||
return OPNSenseHAState.UNAVAILABLE
|
return "unavailable"
|
||||||
if data["carp"]["maintenancemode"]:
|
if data["carp"]["maintenancemode"]:
|
||||||
return OPNSenseHAState.MAINTENANCE_MODE
|
return "maintenancemode"
|
||||||
is_active = all([row["status"] == "MASTER" for row in data["rows"]])
|
is_active = all([row["status"] == "MASTER" for row in data["rows"]])
|
||||||
if is_active:
|
if is_active:
|
||||||
return OPNSenseHAState.ACTIVE
|
return "active"
|
||||||
is_backup = all([row["status"] == "BACKUP" for row in data["rows"]])
|
is_backup = all([row["status"] == "BACKUP" for row in data["rows"]])
|
||||||
if is_backup:
|
if is_backup:
|
||||||
return OPNSenseHAState.HOT_STANDBY
|
return "hot_standby"
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"this host %s is no active nor backup received payload %s", self.host, data
|
"this host %s is no active nor backup received payload %s", self.host, data
|
||||||
)
|
)
|
||||||
return OPNSenseHAState.UNAVAILABLE
|
return "unavailable"
|
||||||
|
|
||||||
def get_traffic(self, interfaces):
|
def get_wan_trafic(self):
|
||||||
if not interfaces:
|
|
||||||
return []
|
|
||||||
try:
|
try:
|
||||||
data = self.get(f"/api/diagnostics/traffic/top/{interfaces}", timeout=15)
|
data = self.get("/api/diagnostics/traffic/top/wan", timeout=15)
|
||||||
except RequestException as ex:
|
except RequestException as ex:
|
||||||
logger.error(
|
logger.error(
|
||||||
"Get diagnostics traffic on %s interface(s) for %s host failed with the following error %r",
|
"Get diagnostics traffic on WAN interface for %s host failed with the following error %r",
|
||||||
interfaces,
|
|
||||||
self.host,
|
self.host,
|
||||||
ex,
|
ex,
|
||||||
)
|
)
|
||||||
return []
|
return None, None
|
||||||
traffics = []
|
|
||||||
for interface in interfaces.split(","):
|
received = 0
|
||||||
traffic_in = OPNSenseTraffic(interface, OPNSenseTrafficMetric.IN)
|
transmitted = 0
|
||||||
traffic_out = OPNSenseTraffic(interface, OPNSenseTrafficMetric.OUT)
|
for record in data["wan"]["records"]:
|
||||||
for record in data.get(interface, {}).get("records", []):
|
received += record["rate_bits_in"]
|
||||||
traffic_in.value += record.get(OPNSenseTrafficMetric.IN.value, 0)
|
transmitted += record["rate_bits_out"]
|
||||||
traffic_out.value += record.get(OPNSenseTrafficMetric.OUT.value, 0)
|
return received, transmitted
|
||||||
traffics.extend([traffic_in, traffic_out])
|
|
||||||
return traffics
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import argparse
|
import argparse
|
||||||
import logging
|
|
||||||
import os
|
import os
|
||||||
import socket
|
import socket
|
||||||
import time
|
import time
|
||||||
|
@ -7,85 +6,84 @@ import time
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
from prometheus_client import Enum, Gauge, start_http_server
|
from prometheus_client import Enum, Gauge, start_http_server
|
||||||
|
|
||||||
from opnsense_exporter.opnsense_api import OPNSenseAPI, OPNSenseHAState, OPNSenseRole
|
from opnsense_exporter.opnsense_api import OPNSenseAPI
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
HA_STATES = [enum.value for enum in list(OPNSenseHAState)]
|
HA_STATES = ["active", "hot_standby", "unavailable", "maintenancemode"]
|
||||||
|
main_ha_state = Enum(
|
||||||
|
"opnsense_main_ha_state",
|
||||||
opnsense_server_ha_state = Enum(
|
"OPNSense HA state of the MAIN server",
|
||||||
"opnsense_server_ha_state",
|
|
||||||
"OPNSense server HA state",
|
|
||||||
[
|
[
|
||||||
"instance",
|
"instance",
|
||||||
"host",
|
"host",
|
||||||
"role",
|
|
||||||
],
|
],
|
||||||
states=HA_STATES,
|
states=HA_STATES,
|
||||||
)
|
)
|
||||||
|
backup_ha_state = Enum(
|
||||||
opnsense_active_server_traffic_rate = Gauge(
|
"opnsense_backup_ha_state",
|
||||||
"opnsense_active_server_traffic_rate",
|
"OPNSense HA state of the BACKUP server",
|
||||||
"Active OPNSense server bytes in/out per interface",
|
[
|
||||||
|
"instance",
|
||||||
|
"host",
|
||||||
|
],
|
||||||
|
states=HA_STATES,
|
||||||
|
)
|
||||||
|
active_server_bytes_received = Gauge(
|
||||||
|
"opnsense_active_server_bytes_received",
|
||||||
|
"Active OPNSense server bytes received on WAN interface",
|
||||||
|
[
|
||||||
|
"instance",
|
||||||
|
"host",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
active_server_bytes_transmitted = Gauge(
|
||||||
|
"opnsense_active_server_bytes_transmitted",
|
||||||
|
"Active OPNSense server bytes transmitted on WAN interface",
|
||||||
[
|
[
|
||||||
"instance",
|
"instance",
|
||||||
"host",
|
"host",
|
||||||
"role",
|
|
||||||
"interface",
|
|
||||||
"metric",
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class OPNSensePrometheusExporter:
|
def process_requests(main, backup, exporter_instance: str = ""):
|
||||||
def __init__(
|
"""A dummy function that takes some time."""
|
||||||
self,
|
main_state = main.get_interface_vip_status()
|
||||||
|
backup_sate = backup.get_interface_vip_status()
|
||||||
|
main_ha_state.labels(instance=exporter_instance, host=main.host).state(main_state)
|
||||||
|
backup_ha_state.labels(instance=exporter_instance, host=backup.host).state(
|
||||||
|
backup_sate
|
||||||
|
)
|
||||||
|
active_opnsense = None
|
||||||
|
if main_state == "active":
|
||||||
|
active_opnsense = main
|
||||||
|
if backup_sate == "active":
|
||||||
|
active_opnsense = backup
|
||||||
|
if active_opnsense:
|
||||||
|
bytes_received, bytes_transmitted = active_opnsense.get_wan_trafic()
|
||||||
|
if bytes_received or bytes_received == 0:
|
||||||
|
active_server_bytes_received.labels(
|
||||||
|
instance=exporter_instance, host=active_opnsense.host
|
||||||
|
).set(bytes_received)
|
||||||
|
if bytes_transmitted or bytes_transmitted == 0:
|
||||||
|
active_server_bytes_transmitted.labels(
|
||||||
|
instance=exporter_instance, host=active_opnsense.host
|
||||||
|
).set(bytes_transmitted)
|
||||||
|
|
||||||
|
|
||||||
|
def start_server(
|
||||||
main: OPNSenseAPI,
|
main: OPNSenseAPI,
|
||||||
backup: OPNSenseAPI,
|
backup: OPNSenseAPI,
|
||||||
interfaces,
|
|
||||||
exporter_instance: str = "",
|
|
||||||
check_frequency: int = 1,
|
check_frequency: int = 1,
|
||||||
):
|
exporter_instance: str = "",
|
||||||
self.main = main
|
):
|
||||||
self.backup = backup
|
|
||||||
self.interfaces = interfaces
|
|
||||||
self.exporter_instance = exporter_instance
|
|
||||||
self.check_frequency = check_frequency
|
|
||||||
|
|
||||||
def process_requests(self):
|
|
||||||
"""A dummy function that takes some time."""
|
|
||||||
main_state = self.main.get_interface_vip_status()
|
|
||||||
backup_sate = self.backup.get_interface_vip_status()
|
|
||||||
opnsense_server_ha_state.labels(
|
|
||||||
instance=self.exporter_instance, **self.main.labels
|
|
||||||
).state(main_state.value)
|
|
||||||
opnsense_server_ha_state.labels(
|
|
||||||
instance=self.exporter_instance, **self.backup.labels
|
|
||||||
).state(backup_sate.value)
|
|
||||||
active_opnsense = None
|
|
||||||
if main_state == OPNSenseHAState.ACTIVE:
|
|
||||||
active_opnsense = self.main
|
|
||||||
if backup_sate == OPNSenseHAState.ACTIVE:
|
|
||||||
active_opnsense = self.backup
|
|
||||||
if active_opnsense:
|
|
||||||
for traffic in active_opnsense.get_traffic(self.interfaces):
|
|
||||||
if traffic.value:
|
|
||||||
opnsense_active_server_traffic_rate.labels(
|
|
||||||
instance=self.exporter_instance,
|
|
||||||
**active_opnsense.labels,
|
|
||||||
**traffic.labels
|
|
||||||
).set(traffic.value)
|
|
||||||
|
|
||||||
def start_server(self, port=8000):
|
|
||||||
# Start up the server to expose the metrics.
|
# Start up the server to expose the metrics.
|
||||||
start_http_server(port)
|
start_http_server(8000)
|
||||||
logger.info("listen port %s", port)
|
|
||||||
# Generate some requests.
|
# Generate some requests.
|
||||||
while True:
|
while True:
|
||||||
self.process_requests()
|
process_requests(main, backup, exporter_instance=exporter_instance)
|
||||||
time.sleep(self.check_frequency)
|
time.sleep(check_frequency)
|
||||||
|
|
||||||
|
|
||||||
def run():
|
def run():
|
||||||
|
@ -125,16 +123,6 @@ def run():
|
||||||
default=os.environ.get("OPNSENSE_USERNAME", None),
|
default=os.environ.get("OPNSENSE_USERNAME", None),
|
||||||
help="OPNsense user. Expect to be the same on MAIN and BACKUP servers",
|
help="OPNsense user. Expect to be the same on MAIN and BACKUP servers",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
|
||||||
"--opnsense-interfaces",
|
|
||||||
"-i",
|
|
||||||
type=str,
|
|
||||||
dest="interfaces",
|
|
||||||
default=os.environ.get("OPNSENSE_INTERFACES", "wan,lan"),
|
|
||||||
help="OPNsense interfaces (coma separated) list to export trafic rates (bytes/s). "
|
|
||||||
"An empty string '' means not calling the traffic diagnostic REST API so no "
|
|
||||||
"`opnsense_active_server_traffic_rate` metric.",
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--opnsense-password",
|
"--opnsense-password",
|
||||||
"-p",
|
"-p",
|
||||||
|
@ -155,19 +143,9 @@ def run():
|
||||||
)
|
)
|
||||||
|
|
||||||
arguments = parser.parse_args()
|
arguments = parser.parse_args()
|
||||||
|
start_server(
|
||||||
server = OPNSensePrometheusExporter(
|
OPNSenseAPI(arguments.main, arguments.user, arguments.password),
|
||||||
OPNSenseAPI(
|
OPNSenseAPI(arguments.backup, arguments.user, arguments.password),
|
||||||
OPNSenseRole.MAIN, arguments.main, arguments.user, arguments.password
|
|
||||||
),
|
|
||||||
OPNSenseAPI(
|
|
||||||
OPNSenseRole.BACKUP, arguments.backup, arguments.user, arguments.password
|
|
||||||
),
|
|
||||||
arguments.interfaces,
|
|
||||||
check_frequency=arguments.frequency,
|
check_frequency=arguments.frequency,
|
||||||
exporter_instance=arguments.prom_instance,
|
exporter_instance=arguments.prom_instance,
|
||||||
)
|
)
|
||||||
server.start_server()
|
|
||||||
|
|
||||||
# return the server instance mainly for test purpose
|
|
||||||
return server
|
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -3,7 +3,7 @@ from urllib.parse import urlparse
|
||||||
|
|
||||||
from setuptools import find_packages, setup
|
from setuptools import find_packages, setup
|
||||||
|
|
||||||
version = "0.5.1"
|
version = "0.4.0"
|
||||||
HERE = pathlib.Path(__file__).parent
|
HERE = pathlib.Path(__file__).parent
|
||||||
|
|
||||||
|
|
||||||
|
|
454
tests/common.py
454
tests/common.py
|
@ -47,158 +47,126 @@ def generate_get_vip_status_paylaod(state_wan, state_lan, maintenance_mode):
|
||||||
|
|
||||||
|
|
||||||
def generate_diagnostics_traffic_interface_paylaod():
|
def generate_diagnostics_traffic_interface_paylaod():
|
||||||
# wan - rate_bits_in: 101026
|
|
||||||
# wan - rate_bits_out: 86020
|
|
||||||
# lan - rate_bits_in: 188490
|
|
||||||
# lan - rate_bits_out: 952
|
|
||||||
|
|
||||||
return json.dumps(
|
return json.dumps(
|
||||||
{
|
{
|
||||||
"wan": {
|
"wan": {
|
||||||
"records": [
|
"records": [
|
||||||
{
|
{
|
||||||
"address": "0.1.2.3",
|
"address": "0.1.2.3",
|
||||||
"rate_bits_in": 62300,
|
"rate_bits_in": 15300,
|
||||||
"rate_bits_out": 66100,
|
"rate_bits_out": 1720,
|
||||||
"rate_bits": 128400,
|
"rate_bits": 17020,
|
||||||
"cumulative_bytes_in": 15600,
|
"cumulative_bytes_in": 3830,
|
||||||
"cumulative_bytes_out": 16500,
|
"cumulative_bytes_out": 441,
|
||||||
"cumulative_bytes": 32100,
|
"cumulative_bytes": 4271,
|
||||||
"tags": [],
|
"tags": [],
|
||||||
"details": [
|
"details": [
|
||||||
{
|
{
|
||||||
"address": "0.1.2.3",
|
"address": "0.1.2.3",
|
||||||
"rate": "62.3Kb",
|
"rate": "15.3Kb",
|
||||||
"rate_bits": 62300,
|
"rate_bits": 15300,
|
||||||
"cumulative": "15.6KB",
|
"cumulative": "3.83KB",
|
||||||
"cumulative_bytes": 15600,
|
"cumulative_bytes": 3830,
|
||||||
"tags": ["local"],
|
"tags": ["local"],
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"rname": "fake rname value",
|
"rname": "fake value",
|
||||||
"rate_in": "62.3 kb",
|
"rate_in": "15.3 kb",
|
||||||
"rate_out": "66.1 kb",
|
"rate_out": "1.72 kb",
|
||||||
"rate": "128.4 kb",
|
"rate": "17.02 kb",
|
||||||
"cumulative_in": "15.6 kb",
|
"cumulative_in": "3.83 kb",
|
||||||
"cumulative_out": "16.5 kb",
|
"cumulative_out": "441.0 b",
|
||||||
"cumulative": "32.1 kb",
|
"cumulative": "4.27 kb",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"address": "0.1.2.3",
|
"address": "0.1.2.3",
|
||||||
"rate_bits_in": 36200,
|
"rate_bits_in": 4470,
|
||||||
"rate_bits_out": 16100,
|
"rate_bits_out": 7290,
|
||||||
"rate_bits": 52300,
|
"rate_bits": 11760,
|
||||||
"cumulative_bytes_in": 9060,
|
"cumulative_bytes_in": 1120,
|
||||||
"cumulative_bytes_out": 4020,
|
"cumulative_bytes_out": 1820,
|
||||||
"cumulative_bytes": 13080,
|
"cumulative_bytes": 2940,
|
||||||
"tags": [],
|
"tags": [],
|
||||||
"details": [
|
"details": [
|
||||||
{
|
{
|
||||||
"address": "0.1.2.3",
|
"address": "0.1.2.3",
|
||||||
"rate": "36.2Kb",
|
"rate": "4.47Kb",
|
||||||
"rate_bits": 36200,
|
"rate_bits": 4470,
|
||||||
"cumulative": "9.06KB",
|
"cumulative": "1.12KB",
|
||||||
"cumulative_bytes": 9060,
|
"cumulative_bytes": 1120,
|
||||||
"tags": ["local"],
|
"tags": ["local"],
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"rname": "fake rname value",
|
"rname": "fake value",
|
||||||
"rate_in": "36.2 kb",
|
"rate_in": "4.47 kb",
|
||||||
"rate_out": "16.1 kb",
|
"rate_out": "7.29 kb",
|
||||||
"rate": "52.3 kb",
|
"rate": "11.76 kb",
|
||||||
"cumulative_in": "9.06 kb",
|
"cumulative_in": "1.12 kb",
|
||||||
"cumulative_out": "4.02 kb",
|
"cumulative_out": "1.82 kb",
|
||||||
"cumulative": "13.08 kb",
|
"cumulative": "2.94 kb",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"address": "0.1.2.3",
|
"address": "0.1.2.3",
|
||||||
"rate_bits_in": 1790,
|
"rate_bits_in": 272,
|
||||||
"rate_bits_out": 1520,
|
|
||||||
"rate_bits": 3310,
|
|
||||||
"cumulative_bytes_in": 459,
|
|
||||||
"cumulative_bytes_out": 389,
|
|
||||||
"cumulative_bytes": 848,
|
|
||||||
"tags": [],
|
|
||||||
"details": [
|
|
||||||
{
|
|
||||||
"address": "0.1.2.3",
|
|
||||||
"rate": "1.79Kb",
|
|
||||||
"rate_bits": 1790,
|
|
||||||
"cumulative": "459B",
|
|
||||||
"cumulative_bytes": 459,
|
|
||||||
"tags": ["local"],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"rname": "fake rname value",
|
|
||||||
"rate_in": "1.79 kb",
|
|
||||||
"rate_out": "1.52 kb",
|
|
||||||
"rate": "3.31 kb",
|
|
||||||
"cumulative_in": "459.0 b",
|
|
||||||
"cumulative_out": "389.0 b",
|
|
||||||
"cumulative": "848.0 b",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"address": "0.1.2.3",
|
|
||||||
"rate_bits_in": 512,
|
|
||||||
"rate_bits_out": 1580,
|
|
||||||
"rate_bits": 2092,
|
|
||||||
"cumulative_bytes_in": 128,
|
|
||||||
"cumulative_bytes_out": 405,
|
|
||||||
"cumulative_bytes": 533,
|
|
||||||
"tags": [],
|
|
||||||
"details": [
|
|
||||||
{
|
|
||||||
"address": "0.1.2.3",
|
|
||||||
"rate": "512b",
|
|
||||||
"rate_bits": 512,
|
|
||||||
"cumulative": "128B",
|
|
||||||
"cumulative_bytes": 128,
|
|
||||||
"tags": ["local"],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"rname": "fake rname value",
|
|
||||||
"rate_in": "512.0 b",
|
|
||||||
"rate_out": "1.58 kb",
|
|
||||||
"rate": "2.09 kb",
|
|
||||||
"cumulative_in": "128.0 b",
|
|
||||||
"cumulative_out": "405.0 b",
|
|
||||||
"cumulative": "533.0 b",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"address": "0.1.2.3",
|
|
||||||
"rate_bits_in": 0,
|
|
||||||
"rate_bits_out": 448,
|
|
||||||
"rate_bits": 448,
|
|
||||||
"cumulative_bytes_in": 0,
|
|
||||||
"cumulative_bytes_out": 112,
|
|
||||||
"cumulative_bytes": 112,
|
|
||||||
"tags": [],
|
|
||||||
"details": [
|
|
||||||
{
|
|
||||||
"address": "0.1.2.3",
|
|
||||||
"rate": "0b",
|
|
||||||
"rate_bits": 0,
|
|
||||||
"cumulative": "0B",
|
|
||||||
"cumulative_bytes": 0,
|
|
||||||
"tags": ["local"],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"rname": "fake rname value",
|
|
||||||
"rate_in": "0.0 b",
|
|
||||||
"rate_out": "448.0 b",
|
|
||||||
"rate": "448.0 b",
|
|
||||||
"cumulative_in": "0.0 b",
|
|
||||||
"cumulative_out": "112.0 b",
|
|
||||||
"cumulative": "112.0 b",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"address": "0.1.2.3",
|
|
||||||
"rate_bits_in": 0,
|
|
||||||
"rate_bits_out": 272,
|
"rate_bits_out": 272,
|
||||||
"rate_bits": 272,
|
"rate_bits": 544,
|
||||||
"cumulative_bytes_in": 0,
|
"cumulative_bytes_in": 68,
|
||||||
"cumulative_bytes_out": 68,
|
"cumulative_bytes_out": 68,
|
||||||
|
"cumulative_bytes": 136,
|
||||||
|
"tags": [],
|
||||||
|
"details": [
|
||||||
|
{
|
||||||
|
"address": "0.1.2.3",
|
||||||
|
"rate": "272b",
|
||||||
|
"rate_bits": 272,
|
||||||
|
"cumulative": "68B",
|
||||||
"cumulative_bytes": 68,
|
"cumulative_bytes": 68,
|
||||||
|
"tags": ["local"],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rname": "fake value",
|
||||||
|
"rate_in": "272.0 b",
|
||||||
|
"rate_out": "272.0 b",
|
||||||
|
"rate": "544.0 b",
|
||||||
|
"cumulative_in": "68.0 b",
|
||||||
|
"cumulative_out": "68.0 b",
|
||||||
|
"cumulative": "136.0 b",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0.1.2.3",
|
||||||
|
"rate_bits_in": 272,
|
||||||
|
"rate_bits_out": 272,
|
||||||
|
"rate_bits": 544,
|
||||||
|
"cumulative_bytes_in": 68,
|
||||||
|
"cumulative_bytes_out": 68,
|
||||||
|
"cumulative_bytes": 136,
|
||||||
|
"tags": [],
|
||||||
|
"details": [
|
||||||
|
{
|
||||||
|
"address": "0.1.2.3",
|
||||||
|
"rate": "272b",
|
||||||
|
"rate_bits": 272,
|
||||||
|
"cumulative": "68B",
|
||||||
|
"cumulative_bytes": 68,
|
||||||
|
"tags": ["local"],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rname": "fake value",
|
||||||
|
"rate_in": "272.0 b",
|
||||||
|
"rate_out": "272.0 b",
|
||||||
|
"rate": "544.0 b",
|
||||||
|
"cumulative_in": "68.0 b",
|
||||||
|
"cumulative_out": "68.0 b",
|
||||||
|
"cumulative": "136.0 b",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0.1.2.3",
|
||||||
|
"rate_bits_in": 0,
|
||||||
|
"rate_bits_out": 480,
|
||||||
|
"rate_bits": 480,
|
||||||
|
"cumulative_bytes_in": 0,
|
||||||
|
"cumulative_bytes_out": 120,
|
||||||
|
"cumulative_bytes": 120,
|
||||||
"tags": [],
|
"tags": [],
|
||||||
"details": [
|
"details": [
|
||||||
{
|
{
|
||||||
|
@ -208,15 +176,23 @@ def generate_diagnostics_traffic_interface_paylaod():
|
||||||
"cumulative": "0B",
|
"cumulative": "0B",
|
||||||
"cumulative_bytes": 0,
|
"cumulative_bytes": 0,
|
||||||
"tags": ["local"],
|
"tags": ["local"],
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
"address": "0.1.2.3",
|
||||||
|
"rate": "0b",
|
||||||
|
"rate_bits": 0,
|
||||||
|
"cumulative": "0B",
|
||||||
|
"cumulative_bytes": 0,
|
||||||
|
"tags": ["local"],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
"rname": "fake rname value",
|
"rname": "fake value",
|
||||||
"rate_in": "0.0 b",
|
"rate_in": "0.0 b",
|
||||||
"rate_out": "272.0 b",
|
"rate_out": "480.0 b",
|
||||||
"rate": "272.0 b",
|
"rate": "480.0 b",
|
||||||
"cumulative_in": "0.0 b",
|
"cumulative_in": "0.0 b",
|
||||||
"cumulative_out": "68.0 b",
|
"cumulative_out": "120.0 b",
|
||||||
"cumulative": "68.0 b",
|
"cumulative": "120.0 b",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"address": "0.1.2.3",
|
"address": "0.1.2.3",
|
||||||
|
@ -237,7 +213,7 @@ def generate_diagnostics_traffic_interface_paylaod():
|
||||||
"tags": ["local"],
|
"tags": ["local"],
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"rname": "fake rname value",
|
"rname": "fake value",
|
||||||
"rate_in": "224.0 b",
|
"rate_in": "224.0 b",
|
||||||
"rate_out": "0.0 b",
|
"rate_out": "0.0 b",
|
||||||
"rate": "224.0 b",
|
"rate": "224.0 b",
|
||||||
|
@ -247,224 +223,6 @@ def generate_diagnostics_traffic_interface_paylaod():
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
},
|
|
||||||
"lan": {
|
|
||||||
"records": [
|
|
||||||
{
|
|
||||||
"address": "0.1.2.3",
|
|
||||||
"rate_bits_in": 65200,
|
|
||||||
"rate_bits_out": 0,
|
|
||||||
"rate_bits": 65200,
|
|
||||||
"cumulative_bytes_in": 16270,
|
|
||||||
"cumulative_bytes_out": 0,
|
|
||||||
"cumulative_bytes": 16270,
|
|
||||||
"tags": [],
|
|
||||||
"details": [
|
|
||||||
{
|
|
||||||
"address": "0.1.2.3",
|
|
||||||
"rate": "45.3Kb",
|
|
||||||
"rate_bits": 45300,
|
|
||||||
"cumulative": "11.3KB",
|
|
||||||
"cumulative_bytes": 11300,
|
|
||||||
"tags": ["private"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"address": "0.1.2.3",
|
|
||||||
"rate": "19.9Kb",
|
|
||||||
"rate_bits": 19900,
|
|
||||||
"cumulative": "4.97KB",
|
|
||||||
"cumulative_bytes": 4970,
|
|
||||||
"tags": ["private"],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"rname": "fake rname value",
|
|
||||||
"rate_in": "65.2 kb",
|
|
||||||
"rate_out": "0.0 b",
|
|
||||||
"rate": "65.2 kb",
|
|
||||||
"cumulative_in": "16.27 kb",
|
|
||||||
"cumulative_out": "0.0 b",
|
|
||||||
"cumulative": "16.27 kb",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"address": "0.1.2.3",
|
|
||||||
"rate_bits_in": 47900,
|
|
||||||
"rate_bits_out": 0,
|
|
||||||
"rate_bits": 47900,
|
|
||||||
"cumulative_bytes_in": 12000,
|
|
||||||
"cumulative_bytes_out": 0,
|
|
||||||
"cumulative_bytes": 12000,
|
|
||||||
"tags": ["private"],
|
|
||||||
"details": [
|
|
||||||
{
|
|
||||||
"address": "0.1.2.3",
|
|
||||||
"rate": "47.9Kb",
|
|
||||||
"rate_bits": 47900,
|
|
||||||
"cumulative": "12.0KB",
|
|
||||||
"cumulative_bytes": 12000,
|
|
||||||
"tags": [],
|
|
||||||
}
|
}
|
||||||
],
|
|
||||||
"rname": "fake rname value",
|
|
||||||
"rate_in": "47.9 kb",
|
|
||||||
"rate_out": "0.0 b",
|
|
||||||
"rate": "47.9 kb",
|
|
||||||
"cumulative_in": "12.0 kb",
|
|
||||||
"cumulative_out": "0.0 b",
|
|
||||||
"cumulative": "12.0 kb",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"address": "0.1.2.3",
|
|
||||||
"rate_bits_in": 36200,
|
|
||||||
"rate_bits_out": 0,
|
|
||||||
"rate_bits": 36200,
|
|
||||||
"cumulative_bytes_in": 9060,
|
|
||||||
"cumulative_bytes_out": 0,
|
|
||||||
"cumulative_bytes": 9060,
|
|
||||||
"tags": [],
|
|
||||||
"details": [
|
|
||||||
{
|
|
||||||
"address": "0.1.2.3",
|
|
||||||
"rate": "36.2Kb",
|
|
||||||
"rate_bits": 36200,
|
|
||||||
"cumulative": "9.06KB",
|
|
||||||
"cumulative_bytes": 9060,
|
|
||||||
"tags": ["private"],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"rname": "fake rname value",
|
|
||||||
"rate_in": "36.2 kb",
|
|
||||||
"rate_out": "0.0 b",
|
|
||||||
"rate": "36.2 kb",
|
|
||||||
"cumulative_in": "9.06 kb",
|
|
||||||
"cumulative_out": "0.0 b",
|
|
||||||
"cumulative": "9.06 kb",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"address": "0.1.2.3",
|
|
||||||
"rate_bits_in": 19200,
|
|
||||||
"rate_bits_out": 0,
|
|
||||||
"rate_bits": 19200,
|
|
||||||
"cumulative_bytes_in": 4814,
|
|
||||||
"cumulative_bytes_out": 0,
|
|
||||||
"cumulative_bytes": 4814,
|
|
||||||
"tags": ["private"],
|
|
||||||
"details": [
|
|
||||||
{
|
|
||||||
"address": "0.1.2.3",
|
|
||||||
"rate": "16.1Kb",
|
|
||||||
"rate_bits": 16100,
|
|
||||||
"cumulative": "4.02KB",
|
|
||||||
"cumulative_bytes": 4020,
|
|
||||||
"tags": [],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"address": "0.1.2.3",
|
|
||||||
"rate": "1.58Kb",
|
|
||||||
"rate_bits": 1580,
|
|
||||||
"cumulative": "405B",
|
|
||||||
"cumulative_bytes": 405,
|
|
||||||
"tags": [],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"address": "0.1.2.3",
|
|
||||||
"rate": "1.52Kb",
|
|
||||||
"rate_bits": 1520,
|
|
||||||
"cumulative": "389B",
|
|
||||||
"cumulative_bytes": 389,
|
|
||||||
"tags": [],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"rname": "fake rname value",
|
|
||||||
"rate_in": "19.2 kb",
|
|
||||||
"rate_out": "0.0 b",
|
|
||||||
"rate": "19.2 kb",
|
|
||||||
"cumulative_in": "4.81 kb",
|
|
||||||
"cumulative_out": "0.0 b",
|
|
||||||
"cumulative": "4.81 kb",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"address": "0.1.2.3",
|
|
||||||
"rate_bits_in": 18200,
|
|
||||||
"rate_bits_out": 0,
|
|
||||||
"rate_bits": 18200,
|
|
||||||
"cumulative_bytes_in": 4550,
|
|
||||||
"cumulative_bytes_out": 0,
|
|
||||||
"cumulative_bytes": 4550,
|
|
||||||
"tags": ["private"],
|
|
||||||
"details": [
|
|
||||||
{
|
|
||||||
"address": "0.1.2.3",
|
|
||||||
"rate": "18.2Kb",
|
|
||||||
"rate_bits": 18200,
|
|
||||||
"cumulative": "4.55KB",
|
|
||||||
"cumulative_bytes": 4550,
|
|
||||||
"tags": [],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"rname": "fake rname value",
|
|
||||||
"rate_in": "18.2 kb",
|
|
||||||
"rate_out": "0.0 b",
|
|
||||||
"rate": "18.2 kb",
|
|
||||||
"cumulative_in": "4.55 kb",
|
|
||||||
"cumulative_out": "0.0 b",
|
|
||||||
"cumulative": "4.55 kb",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"address": "0.1.2.3",
|
|
||||||
"rate_bits_in": 1790,
|
|
||||||
"rate_bits_out": 0,
|
|
||||||
"rate_bits": 1790,
|
|
||||||
"cumulative_bytes_in": 459,
|
|
||||||
"cumulative_bytes_out": 0,
|
|
||||||
"cumulative_bytes": 459,
|
|
||||||
"tags": [],
|
|
||||||
"details": [
|
|
||||||
{
|
|
||||||
"address": "0.1.2.3",
|
|
||||||
"rate": "1.79Kb",
|
|
||||||
"rate_bits": 1790,
|
|
||||||
"cumulative": "459B",
|
|
||||||
"cumulative_bytes": 459,
|
|
||||||
"tags": ["private"],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"rname": "fake rname value",
|
|
||||||
"rate_in": "1.79 kb",
|
|
||||||
"rate_out": "0.0 b",
|
|
||||||
"rate": "1.79 kb",
|
|
||||||
"cumulative_in": "459.0 b",
|
|
||||||
"cumulative_out": "0.0 b",
|
|
||||||
"cumulative": "459.0 b",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"address": "0.1.2.3",
|
|
||||||
"rate_bits_in": 0,
|
|
||||||
"rate_bits_out": 952,
|
|
||||||
"rate_bits": 952,
|
|
||||||
"cumulative_bytes_in": 0,
|
|
||||||
"cumulative_bytes_out": 238,
|
|
||||||
"cumulative_bytes": 238,
|
|
||||||
"tags": ["private"],
|
|
||||||
"details": [
|
|
||||||
{
|
|
||||||
"address": "0.1.2.3",
|
|
||||||
"rate": "0b",
|
|
||||||
"rate_bits": 0,
|
|
||||||
"cumulative": "0B",
|
|
||||||
"cumulative_bytes": 0,
|
|
||||||
"tags": ["private"],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"rname": "fake rname value",
|
|
||||||
"rate_in": "0.0 b",
|
|
||||||
"rate_out": "952.0 b",
|
|
||||||
"rate": "952.0 b",
|
|
||||||
"cumulative_in": "0.0 b",
|
|
||||||
"cumulative_out": "238.0 b",
|
|
||||||
"cumulative": "238.0 b",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"status": "ok",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
import responses
|
import responses
|
||||||
|
|
||||||
from opnsense_exporter.opnsense_api import (
|
from opnsense_exporter.opnsense_api import OPNSenseAPI
|
||||||
OPNSenseAPI,
|
|
||||||
OPNSenseRole,
|
|
||||||
OPNSenseTraffic,
|
|
||||||
OPNSenseTrafficMetric,
|
|
||||||
)
|
|
||||||
|
|
||||||
from .common import (
|
from .common import (
|
||||||
BACKUP_HOST,
|
|
||||||
LOGIN,
|
LOGIN,
|
||||||
MAIN_HOST,
|
MAIN_HOST,
|
||||||
PASSWORD,
|
PASSWORD,
|
||||||
|
@ -26,10 +20,7 @@ def test_get_interface_vip_status_active():
|
||||||
)
|
)
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
OPNSenseAPI(OPNSenseRole.MAIN, MAIN_HOST, LOGIN, PASSWORD)
|
OPNSenseAPI(MAIN_HOST, LOGIN, PASSWORD).get_interface_vip_status() == "active"
|
||||||
.get_interface_vip_status()
|
|
||||||
.value
|
|
||||||
== "active"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,9 +33,7 @@ def test_get_interface_vip_status_backup():
|
||||||
)
|
)
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
OPNSenseAPI(OPNSenseRole.MAIN, MAIN_HOST, LOGIN, PASSWORD)
|
OPNSenseAPI(MAIN_HOST, LOGIN, PASSWORD).get_interface_vip_status()
|
||||||
.get_interface_vip_status()
|
|
||||||
.value
|
|
||||||
== "hot_standby"
|
== "hot_standby"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -58,9 +47,7 @@ def test_get_interface_vip_status_mainteance_mode():
|
||||||
)
|
)
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
OPNSenseAPI(OPNSenseRole.MAIN, MAIN_HOST, LOGIN, PASSWORD)
|
OPNSenseAPI(MAIN_HOST, LOGIN, PASSWORD).get_interface_vip_status()
|
||||||
.get_interface_vip_status()
|
|
||||||
.value
|
|
||||||
== "maintenancemode"
|
== "maintenancemode"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -73,9 +60,7 @@ def test_get_interface_vip_status_unavailable_weird_case():
|
||||||
body=generate_get_vip_status_paylaod("MASTER", "BACKUP", False),
|
body=generate_get_vip_status_paylaod("MASTER", "BACKUP", False),
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
OPNSenseAPI(OPNSenseRole.MAIN, MAIN_HOST, LOGIN, PASSWORD)
|
OPNSenseAPI(MAIN_HOST, LOGIN, PASSWORD).get_interface_vip_status()
|
||||||
.get_interface_vip_status()
|
|
||||||
.value
|
|
||||||
== "unavailable"
|
== "unavailable"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -89,65 +74,33 @@ def test_get_interface_vip_status_unavailable_rest_api_error():
|
||||||
status=404,
|
status=404,
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
OPNSenseAPI(OPNSenseRole.MAIN, MAIN_HOST, LOGIN, PASSWORD)
|
OPNSenseAPI(MAIN_HOST, LOGIN, PASSWORD).get_interface_vip_status()
|
||||||
.get_interface_vip_status()
|
|
||||||
.value
|
|
||||||
== "unavailable"
|
== "unavailable"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@responses.activate
|
@responses.activate
|
||||||
def test_get_traffic():
|
def test_get_wan_traffic():
|
||||||
responses.add(
|
responses.add(
|
||||||
responses.GET,
|
responses.GET,
|
||||||
f"https://{MAIN_HOST}/api/diagnostics/traffic/top/wan,lan",
|
f"https://{MAIN_HOST}/api/diagnostics/traffic/top/wan",
|
||||||
body=generate_diagnostics_traffic_interface_paylaod(),
|
body=generate_diagnostics_traffic_interface_paylaod(),
|
||||||
)
|
)
|
||||||
assert OPNSenseAPI(OPNSenseRole.MAIN, MAIN_HOST, LOGIN, PASSWORD).get_traffic(
|
assert OPNSenseAPI(MAIN_HOST, LOGIN, PASSWORD).get_wan_trafic() == (
|
||||||
"wan,lan"
|
20538,
|
||||||
) == [
|
10034,
|
||||||
OPNSenseTraffic("wan", OPNSenseTrafficMetric.IN, value=101026),
|
)
|
||||||
OPNSenseTraffic("wan", OPNSenseTrafficMetric.OUT, value=86020),
|
|
||||||
OPNSenseTraffic("lan", OPNSenseTrafficMetric.IN, value=188490),
|
|
||||||
OPNSenseTraffic("lan", OPNSenseTrafficMetric.OUT, value=952),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
@responses.activate
|
@responses.activate
|
||||||
def test_get_traffic_none():
|
def test_get_wan_traffic_none():
|
||||||
responses.add(
|
responses.add(
|
||||||
responses.GET,
|
responses.GET,
|
||||||
f"https://{MAIN_HOST}/api/diagnostics/traffic/top/test-not-found",
|
f"https://{MAIN_HOST}/api/diagnostics/traffic/top/wan",
|
||||||
json={"error": "not found"},
|
json={"error": "not found"},
|
||||||
status=404,
|
status=404,
|
||||||
)
|
)
|
||||||
assert (
|
assert OPNSenseAPI(MAIN_HOST, LOGIN, PASSWORD).get_wan_trafic() == (
|
||||||
OPNSenseAPI(OPNSenseRole.MAIN, MAIN_HOST, LOGIN, PASSWORD).get_traffic(
|
None,
|
||||||
"test-not-found"
|
None,
|
||||||
)
|
)
|
||||||
== []
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_traffic_empty_string():
|
|
||||||
rsp = responses.add(
|
|
||||||
responses.GET,
|
|
||||||
f"https://{MAIN_HOST}/api/diagnostics/traffic/top/",
|
|
||||||
json={"not": "called"},
|
|
||||||
)
|
|
||||||
assert (
|
|
||||||
OPNSenseAPI(OPNSenseRole.MAIN, MAIN_HOST, LOGIN, PASSWORD).get_traffic("") == []
|
|
||||||
)
|
|
||||||
assert rsp.call_count == 0
|
|
||||||
|
|
||||||
|
|
||||||
def test_labels():
|
|
||||||
assert OPNSenseAPI(OPNSenseRole.MAIN, MAIN_HOST, LOGIN, PASSWORD).labels == {
|
|
||||||
"role": "main",
|
|
||||||
"host": MAIN_HOST,
|
|
||||||
}
|
|
||||||
assert OPNSenseAPI(OPNSenseRole.BACKUP, BACKUP_HOST, LOGIN, PASSWORD).labels == {
|
|
||||||
"role": "backup",
|
|
||||||
"host": BACKUP_HOST,
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
from typing import List
|
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
import responses
|
import responses
|
||||||
|
|
||||||
from opnsense_exporter.opnsense_api import OPNSenseAPI, OPNSenseRole
|
from opnsense_exporter.opnsense_api import OPNSenseAPI
|
||||||
from opnsense_exporter.server import OPNSensePrometheusExporter, run
|
from opnsense_exporter.server import process_requests, run
|
||||||
|
|
||||||
from .common import (
|
from .common import (
|
||||||
BACKUP_HOST,
|
BACKUP_HOST,
|
||||||
|
@ -18,57 +17,31 @@ from .common import (
|
||||||
|
|
||||||
class FakePromMetric:
|
class FakePromMetric:
|
||||||
_labels = {}
|
_labels = {}
|
||||||
_labels_calls = None
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self._labels = {}
|
|
||||||
self._labels_calls = []
|
|
||||||
|
|
||||||
@property
|
|
||||||
def count_labels_calls(self) -> int:
|
|
||||||
return len(self._labels_calls)
|
|
||||||
|
|
||||||
def labels(self, *args, **kwargs):
|
def labels(self, *args, **kwargs):
|
||||||
self._labels = kwargs
|
self._labels = kwargs
|
||||||
self._labels_calls.append(kwargs)
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
class FakePromEnum(FakePromMetric):
|
class FakePromEnum(FakePromMetric):
|
||||||
_state: str = None
|
_state = None
|
||||||
_state_calls: List[str] = []
|
count_state_calls = 0
|
||||||
|
|
||||||
def __init__(self):
|
def state(self, state):
|
||||||
super().__init__()
|
self.count_state_calls += 1
|
||||||
self._state_calls = []
|
|
||||||
|
|
||||||
@property
|
|
||||||
def count_state_calls(self) -> int:
|
|
||||||
return len(self._state_calls)
|
|
||||||
|
|
||||||
def state(self, state: str):
|
|
||||||
self._state = state
|
self._state = state
|
||||||
self._state_calls.append(state)
|
|
||||||
|
|
||||||
|
|
||||||
class FakePromGauge(FakePromMetric):
|
class FakePromGauge(FakePromMetric):
|
||||||
_value: int = None
|
value = None
|
||||||
_set_calls: List[int] = []
|
count_set_calls = 0
|
||||||
|
|
||||||
def __init__(self):
|
def set(self, value):
|
||||||
super().__init__()
|
self.count_set_calls += 1
|
||||||
self._set_calls = []
|
self.value = value
|
||||||
|
|
||||||
@property
|
|
||||||
def count_set_calls(self) -> int:
|
|
||||||
return len(self._set_calls)
|
|
||||||
|
|
||||||
def set(self, value: int):
|
|
||||||
self._value = value
|
|
||||||
self._set_calls.append(value)
|
|
||||||
|
|
||||||
|
|
||||||
@mock.patch("opnsense_exporter.server.OPNSensePrometheusExporter.start_server")
|
@mock.patch("opnsense_exporter.server.start_server")
|
||||||
def test_parser(server_mock):
|
def test_parser(server_mock):
|
||||||
with mock.patch(
|
with mock.patch(
|
||||||
"sys.argv",
|
"sys.argv",
|
||||||
|
@ -84,25 +57,20 @@ def test_parser(server_mock):
|
||||||
"user-test",
|
"user-test",
|
||||||
"-p",
|
"-p",
|
||||||
"pwd-test",
|
"pwd-test",
|
||||||
"-i",
|
|
||||||
"efg,hij",
|
|
||||||
"--prometheus-instance",
|
"--prometheus-instance",
|
||||||
"server-hostname-instance",
|
"server-hostname-instance",
|
||||||
],
|
],
|
||||||
):
|
):
|
||||||
server = run()
|
run()
|
||||||
server_mock.assert_called_once()
|
server_mock.assert_called_once()
|
||||||
|
main, bck = server_mock.call_args.args
|
||||||
assert server.main.role == OPNSenseRole.MAIN
|
assert main.login == "user-test"
|
||||||
assert server.main.host == "main.host"
|
assert bck.login == "user-test"
|
||||||
assert server.main.login == "user-test"
|
assert main.password == "pwd-test"
|
||||||
assert server.main.password == "pwd-test"
|
assert bck.password == "pwd-test"
|
||||||
assert server.backup.role == OPNSenseRole.BACKUP
|
assert main.host == "main.host"
|
||||||
assert server.backup.host == "backup.host"
|
assert bck.host == "backup.host"
|
||||||
assert server.backup.login == "user-test"
|
assert server_mock.call_args.kwargs["check_frequency"] == 15
|
||||||
assert server.backup.password == "pwd-test"
|
|
||||||
assert server.check_frequency == 15
|
|
||||||
assert server.interfaces == "efg,hij"
|
|
||||||
|
|
||||||
|
|
||||||
@responses.activate
|
@responses.activate
|
||||||
|
@ -123,56 +91,49 @@ def test_process_requests():
|
||||||
body=generate_diagnostics_traffic_interface_paylaod(),
|
body=generate_diagnostics_traffic_interface_paylaod(),
|
||||||
)
|
)
|
||||||
|
|
||||||
opnsense_server_ha_state_mock = FakePromEnum()
|
main_ha_state_mock = FakePromEnum()
|
||||||
opnsense_active_server_traffic_rate_mock = FakePromGauge()
|
backup_ha_state_mock = FakePromEnum()
|
||||||
|
active_server_bytes_received_mock = FakePromGauge()
|
||||||
|
active_server_bytes_transmitted_mock = FakePromGauge()
|
||||||
|
|
||||||
|
with mock.patch("opnsense_exporter.server.main_ha_state", new=main_ha_state_mock):
|
||||||
with mock.patch(
|
with mock.patch(
|
||||||
"opnsense_exporter.server.opnsense_server_ha_state",
|
"opnsense_exporter.server.backup_ha_state", new=backup_ha_state_mock
|
||||||
new=opnsense_server_ha_state_mock,
|
|
||||||
):
|
):
|
||||||
with mock.patch(
|
with mock.patch(
|
||||||
"opnsense_exporter.server.opnsense_active_server_traffic_rate",
|
"opnsense_exporter.server.active_server_bytes_received",
|
||||||
new=opnsense_active_server_traffic_rate_mock,
|
new=active_server_bytes_received_mock,
|
||||||
):
|
):
|
||||||
OPNSensePrometheusExporter(
|
with mock.patch(
|
||||||
OPNSenseAPI(OPNSenseRole.MAIN, MAIN_HOST, LOGIN, PASSWORD),
|
"opnsense_exporter.server.active_server_bytes_transmitted",
|
||||||
OPNSenseAPI(OPNSenseRole.BACKUP, BACKUP_HOST, LOGIN, PASSWORD),
|
new=active_server_bytes_transmitted_mock,
|
||||||
"wan",
|
):
|
||||||
).process_requests()
|
process_requests(
|
||||||
|
OPNSenseAPI(MAIN_HOST, LOGIN, PASSWORD),
|
||||||
|
OPNSenseAPI(BACKUP_HOST, LOGIN, PASSWORD),
|
||||||
|
)
|
||||||
|
|
||||||
assert opnsense_server_ha_state_mock.count_state_calls == 2
|
assert main_ha_state_mock._state == "active"
|
||||||
assert opnsense_server_ha_state_mock._labels_calls == [
|
assert main_ha_state_mock.count_state_calls == 1
|
||||||
{
|
assert main_ha_state_mock._labels == {"instance": "", "host": MAIN_HOST}
|
||||||
"instance": "",
|
|
||||||
"host": MAIN_HOST,
|
|
||||||
"role": "main",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"instance": "",
|
|
||||||
"host": BACKUP_HOST,
|
|
||||||
"role": "backup",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
assert opnsense_server_ha_state_mock._state_calls == ["active", "hot_standby"]
|
|
||||||
|
|
||||||
assert opnsense_active_server_traffic_rate_mock.count_set_calls == 2
|
assert backup_ha_state_mock._state == "hot_standby"
|
||||||
assert opnsense_active_server_traffic_rate_mock._labels_calls == [
|
assert backup_ha_state_mock.count_state_calls == 1
|
||||||
{
|
assert backup_ha_state_mock._labels == {"instance": "", "host": BACKUP_HOST}
|
||||||
|
|
||||||
|
assert active_server_bytes_received_mock.value == 20538
|
||||||
|
assert active_server_bytes_received_mock.count_set_calls == 1
|
||||||
|
assert active_server_bytes_received_mock._labels == {
|
||||||
"instance": "",
|
"instance": "",
|
||||||
"host": MAIN_HOST,
|
"host": MAIN_HOST,
|
||||||
"role": "main",
|
}
|
||||||
"interface": "wan",
|
|
||||||
"metric": "rate_bits_in",
|
assert active_server_bytes_transmitted_mock.value == 10034
|
||||||
},
|
assert active_server_bytes_transmitted_mock.count_set_calls == 1
|
||||||
{
|
assert active_server_bytes_transmitted_mock._labels == {
|
||||||
"instance": "",
|
"instance": "",
|
||||||
"host": MAIN_HOST,
|
"host": MAIN_HOST,
|
||||||
"role": "main",
|
}
|
||||||
"interface": "wan",
|
|
||||||
"metric": "rate_bits_out",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
assert opnsense_active_server_traffic_rate_mock._set_calls == [101026, 86020]
|
|
||||||
|
|
||||||
|
|
||||||
@responses.activate
|
@responses.activate
|
||||||
|
@ -193,56 +154,48 @@ def test_process_requests_backup_active():
|
||||||
body=generate_diagnostics_traffic_interface_paylaod(),
|
body=generate_diagnostics_traffic_interface_paylaod(),
|
||||||
)
|
)
|
||||||
|
|
||||||
opnsense_server_ha_state_mock = FakePromEnum()
|
main_ha_state_mock = FakePromEnum()
|
||||||
opnsense_active_server_traffic_rate_mock = FakePromGauge()
|
backup_ha_state_mock = FakePromEnum()
|
||||||
|
active_server_bytes_received_mock = FakePromGauge()
|
||||||
|
active_server_bytes_transmitted_mock = FakePromGauge()
|
||||||
|
|
||||||
|
with mock.patch("opnsense_exporter.server.main_ha_state", new=main_ha_state_mock):
|
||||||
with mock.patch(
|
with mock.patch(
|
||||||
"opnsense_exporter.server.opnsense_server_ha_state",
|
"opnsense_exporter.server.backup_ha_state", new=backup_ha_state_mock
|
||||||
new=opnsense_server_ha_state_mock,
|
|
||||||
):
|
):
|
||||||
with mock.patch(
|
with mock.patch(
|
||||||
"opnsense_exporter.server.opnsense_active_server_traffic_rate",
|
"opnsense_exporter.server.active_server_bytes_received",
|
||||||
new=opnsense_active_server_traffic_rate_mock,
|
new=active_server_bytes_received_mock,
|
||||||
):
|
):
|
||||||
OPNSensePrometheusExporter(
|
with mock.patch(
|
||||||
OPNSenseAPI(OPNSenseRole.MAIN, MAIN_HOST, LOGIN, PASSWORD),
|
"opnsense_exporter.server.active_server_bytes_transmitted",
|
||||||
OPNSenseAPI(OPNSenseRole.BACKUP, BACKUP_HOST, LOGIN, PASSWORD),
|
new=active_server_bytes_transmitted_mock,
|
||||||
"wan",
|
):
|
||||||
).process_requests()
|
process_requests(
|
||||||
|
OPNSenseAPI(MAIN_HOST, LOGIN, PASSWORD),
|
||||||
|
OPNSenseAPI(BACKUP_HOST, LOGIN, PASSWORD),
|
||||||
|
)
|
||||||
|
assert main_ha_state_mock._state == "maintenancemode"
|
||||||
|
assert main_ha_state_mock.count_state_calls == 1
|
||||||
|
assert main_ha_state_mock._labels == {"instance": "", "host": MAIN_HOST}
|
||||||
|
|
||||||
assert opnsense_server_ha_state_mock.count_state_calls == 2
|
assert backup_ha_state_mock._state == "active"
|
||||||
assert opnsense_server_ha_state_mock._labels_calls == [
|
assert backup_ha_state_mock.count_state_calls == 1
|
||||||
{
|
assert backup_ha_state_mock._labels == {"instance": "", "host": BACKUP_HOST}
|
||||||
"instance": "",
|
|
||||||
"host": MAIN_HOST,
|
|
||||||
"role": "main",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"instance": "",
|
|
||||||
"host": BACKUP_HOST,
|
|
||||||
"role": "backup",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
assert opnsense_server_ha_state_mock._state_calls == ["maintenancemode", "active"]
|
|
||||||
|
|
||||||
assert opnsense_active_server_traffic_rate_mock.count_set_calls == 2
|
assert active_server_bytes_received_mock.value == 20538
|
||||||
opnsense_active_server_traffic_rate_mock._labels_calls == [
|
assert active_server_bytes_received_mock.count_set_calls == 1
|
||||||
{
|
assert active_server_bytes_received_mock._labels == {
|
||||||
"instance": "",
|
"instance": "",
|
||||||
"host": BACKUP_HOST,
|
"host": BACKUP_HOST,
|
||||||
"role": "backup",
|
}
|
||||||
"interface": "wan",
|
|
||||||
"metric": "rate_bits_in",
|
assert active_server_bytes_transmitted_mock.value == 10034
|
||||||
},
|
assert active_server_bytes_transmitted_mock.count_set_calls == 1
|
||||||
{
|
assert active_server_bytes_transmitted_mock._labels == {
|
||||||
"instance": "",
|
"instance": "",
|
||||||
"host": BACKUP_HOST,
|
"host": BACKUP_HOST,
|
||||||
"role": "backup",
|
}
|
||||||
"interface": "wan",
|
|
||||||
"metric": "rate_bits_out",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
assert opnsense_active_server_traffic_rate_mock._set_calls == [101026, 86020]
|
|
||||||
|
|
||||||
|
|
||||||
@responses.activate
|
@responses.activate
|
||||||
|
@ -264,42 +217,38 @@ def test_process_no_active():
|
||||||
body=generate_diagnostics_traffic_interface_paylaod(),
|
body=generate_diagnostics_traffic_interface_paylaod(),
|
||||||
)
|
)
|
||||||
|
|
||||||
opnsense_server_ha_state_mock = FakePromEnum()
|
main_ha_state_mock = FakePromEnum()
|
||||||
opnsense_active_server_traffic_rate_mock = FakePromGauge()
|
backup_ha_state_mock = FakePromEnum()
|
||||||
|
active_server_bytes_received_mock = FakePromGauge()
|
||||||
|
active_server_bytes_transmitted_mock = FakePromGauge()
|
||||||
|
|
||||||
|
with mock.patch("opnsense_exporter.server.main_ha_state", new=main_ha_state_mock):
|
||||||
with mock.patch(
|
with mock.patch(
|
||||||
"opnsense_exporter.server.opnsense_server_ha_state",
|
"opnsense_exporter.server.backup_ha_state", new=backup_ha_state_mock
|
||||||
new=opnsense_server_ha_state_mock,
|
|
||||||
):
|
):
|
||||||
with mock.patch(
|
with mock.patch(
|
||||||
"opnsense_exporter.server.opnsense_active_server_traffic_rate",
|
"opnsense_exporter.server.active_server_bytes_received",
|
||||||
new=opnsense_active_server_traffic_rate_mock,
|
new=active_server_bytes_received_mock,
|
||||||
):
|
):
|
||||||
OPNSensePrometheusExporter(
|
with mock.patch(
|
||||||
OPNSenseAPI(OPNSenseRole.MAIN, MAIN_HOST, LOGIN, PASSWORD),
|
"opnsense_exporter.server.active_server_bytes_transmitted",
|
||||||
OPNSenseAPI(OPNSenseRole.BACKUP, BACKUP_HOST, LOGIN, PASSWORD),
|
new=active_server_bytes_transmitted_mock,
|
||||||
"wan",
|
):
|
||||||
).process_requests()
|
process_requests(
|
||||||
|
OPNSenseAPI(MAIN_HOST, LOGIN, PASSWORD),
|
||||||
|
OPNSenseAPI(BACKUP_HOST, LOGIN, PASSWORD),
|
||||||
|
)
|
||||||
|
|
||||||
assert opnsense_server_ha_state_mock.count_state_calls == 2
|
assert main_ha_state_mock._state == "maintenancemode"
|
||||||
assert opnsense_server_ha_state_mock._labels_calls == [
|
assert main_ha_state_mock.count_state_calls == 1
|
||||||
{
|
assert main_ha_state_mock._labels == {"instance": "", "host": MAIN_HOST}
|
||||||
"instance": "",
|
|
||||||
"host": MAIN_HOST,
|
|
||||||
"role": "main",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"instance": "",
|
|
||||||
"host": BACKUP_HOST,
|
|
||||||
"role": "backup",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
assert opnsense_server_ha_state_mock._state_calls == [
|
|
||||||
"maintenancemode",
|
|
||||||
"unavailable",
|
|
||||||
]
|
|
||||||
|
|
||||||
assert opnsense_active_server_traffic_rate_mock.count_set_calls == 0
|
assert backup_ha_state_mock._state == "unavailable"
|
||||||
|
assert backup_ha_state_mock.count_state_calls == 1
|
||||||
|
assert backup_ha_state_mock._labels == {"instance": "", "host": BACKUP_HOST}
|
||||||
|
|
||||||
|
assert active_server_bytes_received_mock.count_set_calls == 0
|
||||||
|
assert active_server_bytes_transmitted_mock.count_set_calls == 0
|
||||||
|
|
||||||
|
|
||||||
@responses.activate
|
@responses.activate
|
||||||
|
@ -321,36 +270,34 @@ def test_process_with_falsy_value():
|
||||||
status=404,
|
status=404,
|
||||||
)
|
)
|
||||||
|
|
||||||
opnsense_server_ha_state_mock = FakePromEnum()
|
main_ha_state_mock = FakePromEnum()
|
||||||
opnsense_active_server_traffic_rate_mock = FakePromGauge()
|
backup_ha_state_mock = FakePromEnum()
|
||||||
|
active_server_bytes_received_mock = FakePromGauge()
|
||||||
|
active_server_bytes_transmitted_mock = FakePromGauge()
|
||||||
|
|
||||||
|
with mock.patch("opnsense_exporter.server.main_ha_state", new=main_ha_state_mock):
|
||||||
with mock.patch(
|
with mock.patch(
|
||||||
"opnsense_exporter.server.opnsense_server_ha_state",
|
"opnsense_exporter.server.backup_ha_state", new=backup_ha_state_mock
|
||||||
new=opnsense_server_ha_state_mock,
|
|
||||||
):
|
):
|
||||||
with mock.patch(
|
with mock.patch(
|
||||||
"opnsense_exporter.server.opnsense_active_server_traffic_rate",
|
"opnsense_exporter.server.active_server_bytes_received",
|
||||||
new=opnsense_active_server_traffic_rate_mock,
|
new=active_server_bytes_received_mock,
|
||||||
):
|
):
|
||||||
OPNSensePrometheusExporter(
|
with mock.patch(
|
||||||
OPNSenseAPI(OPNSenseRole.MAIN, MAIN_HOST, LOGIN, PASSWORD),
|
"opnsense_exporter.server.active_server_bytes_transmitted",
|
||||||
OPNSenseAPI(OPNSenseRole.BACKUP, BACKUP_HOST, LOGIN, PASSWORD),
|
new=active_server_bytes_transmitted_mock,
|
||||||
"wan",
|
):
|
||||||
).process_requests()
|
process_requests(
|
||||||
|
OPNSenseAPI(MAIN_HOST, LOGIN, PASSWORD),
|
||||||
|
OPNSenseAPI(BACKUP_HOST, LOGIN, PASSWORD),
|
||||||
|
)
|
||||||
|
assert main_ha_state_mock._state == "active"
|
||||||
|
assert main_ha_state_mock.count_state_calls == 1
|
||||||
|
assert main_ha_state_mock._labels == {"instance": "", "host": MAIN_HOST}
|
||||||
|
|
||||||
assert opnsense_server_ha_state_mock.count_state_calls == 2
|
assert backup_ha_state_mock.count_state_calls == 1
|
||||||
assert opnsense_server_ha_state_mock._labels_calls == [
|
assert backup_ha_state_mock._state == "hot_standby"
|
||||||
{
|
assert backup_ha_state_mock._labels == {"instance": "", "host": BACKUP_HOST}
|
||||||
"instance": "",
|
|
||||||
"host": MAIN_HOST,
|
|
||||||
"role": "main",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"instance": "",
|
|
||||||
"host": BACKUP_HOST,
|
|
||||||
"role": "backup",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
assert opnsense_server_ha_state_mock._state_calls == ["active", "hot_standby"]
|
|
||||||
|
|
||||||
assert opnsense_active_server_traffic_rate_mock.count_set_calls == 0
|
assert active_server_bytes_received_mock.count_set_calls == 0
|
||||||
|
assert active_server_bytes_transmitted_mock.count_set_calls == 0
|
||||||
|
|
Loading…
Reference in a new issue