Skip to content
Snippets Groups Projects
Verified Commit 903472c1 authored by Carolina Fernandez's avatar Carolina Fernandez Committed by Karel van Klink
Browse files

Apply 6f8260ab

parent f0f0113c
No related branches found
No related tags found
1 merge request!126Add iBGP workflow and LibreNMS client
{
"GENERAL": {
"public_hostname": "https://gap.geant.org"
"public_hostname": "https://gap.geant.org",
"environment": "lab"
},
"NETBOX": {
"api": "https://127.0.0.1:8000",
......@@ -45,6 +46,30 @@
"dns_view": "default"
}
},
"MONITORING": {
"LIBRENMS": {
"endpoint": "https://librenms.test.gap.geant.org/",
"token": "<token>",
"DEVICE_GROUPS": {
"routers_lab": "lab_routers",
"routers_prod": "prod_routers"
}
},
"SNMP": {
"version": "v2c",
"V2": {
"community": "librenms-community"
},
"V3": {
"authlevel": "AuthPriv",
"authname": "librenms",
"authpass": "<password1>",
"authalgo": "sha",
"cryptopass": "<password2>",
"cryptoalgo": "aes"
}
}
},
"PROVISIONING_PROXY": {
"scheme": "https",
"api_base": "localhost:44444",
......
"""
The LibreNMS module interacts with the LibreNMS instance when
- Creating a device.
- Validating the input of a device.
- Terminating a device.
"""
import json
import logging
import requests
from gso import settings
logger = logging.getLogger(__name__)
class CfgStruct(object):
pass
def _get_cfg():
"""
Internal function to retrieve all needed configuration.
"""
oss = settings.load_oss_params()
cfg = CfgStruct()
# Hack for later ease: 1st setattr will fill in the inner's dict
setattr(cfg, "_hack", "")
# Update inner dict
cfg.__dict__.update(oss.MONITORING)
assert cfg.__dict__ is not None
# Add parameters on-the-fly
cfg.headers = {"X-Auth-Token": cfg.LIBRENMS.token}
sep = "/"
if cfg.LIBRENMS.endpoint.endswith("/"):
sep = ""
cfg.base_url = f"{cfg.LIBRENMS.endpoint}{sep}api/v0"
cfg.url_devices = f"{cfg.base_url}/devices"
cfg.url_switches = f"{cfg.base_url}/devicegroups/switches"
cfg.device_groups = cfg.LIBRENMS.DEVICE_GROUPS
cfg.environment = oss.GENERAL.environment
if cfg.environment.startswith("lab"):
cfg_dg_rtr_lab = cfg.device_groups.routers_lab
cfg.url_routers = f"{cfg.base_url}/devicegroups/{cfg_dg_rtr_lab}"
elif cfg.environment.startswith("prod"):
cfg_dg_rtr_prod = cfg.device_groups.routers_prod
cfg.url_routers = f"{cfg.base_url}/devicegroups/{cfg_dg_rtr_prod}"
return cfg
def validate_device(fqdn: str):
"""
Function that validates the existence of a device in LibreNMS.
:param FQDN of the device to validate.
"""
CFG = _get_cfg()
# Validate existence
nms_result = requests.get(
CFG.url_devices, headers=CFG.headers)
assert nms_result is not None
device_id = list(map(
lambda x: x.get("device_id"),
filter(lambda x: x.get("hostname") == fqdn,
nms_result.json().get("devices"))))
if len(device_id) != 1 or device_id[0] is None:
error_msg = f"Device with FQDN={fqdn} is not registered in LibreNMS"
print(error_msg)
raise AssertionError(error_msg)
# Validate correctness
device_id = device_id[0]
url_device = f"{CFG.url_devices}/{device_id}"
logger.debug(f"Connecting to URL: {url_device}"
f"with headers: {CFG.headers}")
nms_result = requests.get(
url_device, headers=CFG.headers)
logger.debug(f"LibreNMS response={nms_result.content}")
if nms_result.status_code != 200:
print(nms_result.content)
raise AssertionError(nms_result.content)
# nms_dev_sysname = nms_result.json().get("sysName")
nms_dev_hostname = nms_result.json().get("devices")[0].get("hostname")
if fqdn != nms_dev_hostname:
error_msg = f"Device with FQDN={fqdn} may not be correctly "\
f"registered in LibreNMS (expected FQDN: {nms_dev_hostname})"
print(error_msg)
raise AssertionError(error_msg)
def register_device(fqdn: str):
"""
Function that registers a new device in LibreNMS.
:param FQDN of the device to register.
"""
CFG = _get_cfg()
logger.debug(f"Registering FQDN={fqdn} in LibreNMS")
device_data = {
"display": fqdn,
"hostname": fqdn,
"sysName": fqdn,
# "override_icmp_disable": "true",
# IMPORTANT: uncomment if testing with FQDNs that are not reachable
# from LibreNMS (e.g. ContainerLab routers)
# "force_add": "true"
}
if CFG.SNMP.version == "v2c":
device_data.update({
"community": CFG.SNMP.V2.community
})
elif CFG.SNMP.version == "v3":
for key in [
"authlevel", "authname", "authpass", "authalgo",
"cryptopass", "cryptoalgo"]:
device_data.update({key: getattr(CFG.SNMP.V3, key)})
logger.debug(f"Connecting to URL: {CFG.url_devices}"
f"with headers: {CFG.headers} and"
f"payload: {device_data}")
nms_result = requests.post(
CFG.url_devices, headers=CFG.headers,
data=json.dumps(device_data))
logger.debug(f"LibreNMS response={nms_result.content}")
if nms_result.status_code != 200:
print(nms_result.content)
raise AssertionError(nms_result.content)
def deregister_device(fqdn: str):
"""
Function that reregisters a device from LibreNMS.
:param FQDN of the device to deregister.
"""
CFG = _get_cfg()
logger.debug(f"Deregistering FQDN={fqdn} from LibreNMS")
nms_result = requests.get(
CFG.url_devices, headers=CFG.headers)
assert nms_result is not None
device_id = list(map(
lambda x: x.get("device_id"),
filter(lambda x: x.get("hostname") == fqdn,
nms_result.json().get("devices"))))
if len(device_id) != 1:
return
device_id = device_id[0]
# https://docs.librenms.org/API/Devices/#endpoint-categories
device_data = {
"field": "disabled",
"data": "1"
}
url_device = f"{CFG.url_devices}/{device_id}"
logger.debug(f"Connecting to URL: {url_device}"
f"with headers: {CFG.headers} and"
f"payload: {device_data}")
nms_result = requests.patch(
url_device, headers=CFG.headers,
data=json.dumps(device_data))
logger.debug(f"LibreNMS response={nms_result.content}")
# Fail silently if device was not registered
if nms_result.status_code != 200:
print(nms_result.content)
......@@ -21,6 +21,8 @@ class GeneralParams(BaseSettings):
public_hostname: str
"""The hostname that :term:`GSO` is publicly served at, used for building the callback URL that the provisioning
proxy uses."""
environment: str
"""The environment in which :term:`GSO` runs."""
class CeleryParams(BaseSettings):
......@@ -94,6 +96,59 @@ class IPAMParams(BaseSettings):
LT_IAS: ServiceNetworkParams
class MonitoringLibreNMSDevGroupsParams(BaseSettings):
"""
Parameters related to LibreNMS device groups.
"""
routers_lab: str
routers_prod: str
class MonitoringSNMPV2Params(BaseSettings):
"""
Parameters related to SNMPv2.
"""
community: str
class MonitoringSNMPV3Params(BaseSettings):
"""
Parameters related to SNMPv3.
"""
authlevel: str
authname: str
authpass: str
authalgo: str
cryptopass: str
cryptoalgo: str
class MonitoringSNMPParams(BaseSettings):
"""
Parameters related to SNMP.
"""
version: str
V2: MonitoringSNMPV2Params
V3: MonitoringSNMPV3Params
class MonitoringLibreNMSParams(BaseSettings):
"""
Parameters related to LibreNMS.
"""
endpoint: str
token: str
DEVICE_GROUPS: MonitoringLibreNMSDevGroupsParams
class MonitoringParams(BaseSettings):
"""
Parameters related to the monitoring.
"""
LIBRENMS: MonitoringLibreNMSParams
SNMP: MonitoringSNMPParams
class ProvisioningProxyParams(BaseSettings):
"""Parameters for the provisioning proxy."""
......@@ -118,6 +173,7 @@ class OSSParams(BaseSettings):
GENERAL: GeneralParams
IPAM: IPAMParams
NETBOX: NetBoxParams
MONITORING: MonitoringParams
PROVISIONING_PROXY: ProvisioningProxyParams
CELERY: CeleryParams
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment