Commit b81912db authored by Matthew Smith's avatar Matthew Smith
Browse files

different vars for netbox and grafana from icinga NotificationCommand object

update docstrings
fiddle with panel_id allocation
parent 62a401e6
...@@ -19,6 +19,19 @@ The minimum required for enhanced emails to function is Icinga2. ...@@ -19,6 +19,19 @@ The minimum required for enhanced emails to function is Icinga2.
_Or you can apply notifications your own way, `enhance-mail-notification.py` and `enhance-mail-command.conf` contain the basics_ _Or you can apply notifications your own way, `enhance-mail-notification.py` and `enhance-mail-command.conf` contain the basics_
### Grafana
There is 1 optional environment variables in the enhanced-mail-command.conf host and service objects, if it is set on the
icinga2 host object it will override the icingaweb2 grafana module ini panelid and default host panel id to lookup in Grafana.
GRAFANAPANELID = "$host.vars.grafana_panelid$"
### Netbox
There are 2 optional environment variables in the enhanced-mail-command.conf host and service objects, if they are set on the
icinga2 host object they will override the hostname and hostip address to lookup in Netbox
NETBOXHOSTNAME = "$host.vars.netbox_host_name$"
NETBOXHOSTIP = "$host.vars.netbox_host_ip$"
## Enhancements ## Enhancements
Grafana and Netbox have classes, which handle most of the work dealing with those services, in an attempt to keep the code to Grafana and Netbox have classes, which handle most of the work dealing with those services, in an attempt to keep the code to
manage data from these services in one place. These classes return values that are used in the content of the emails, they manage data from these services in one place. These classes return values that are used in the content of the emails, they
......
...@@ -14,10 +14,11 @@ object NotificationCommand "enhanced-mail-host-notification" { ...@@ -14,10 +14,11 @@ object NotificationCommand "enhanced-mail-host-notification" {
NOTIFICATIONAUTHORNAME = "$notification.author$" NOTIFICATIONAUTHORNAME = "$notification.author$"
NOTIFICATIONCOMMENT = "$notification.comment$" NOTIFICATIONCOMMENT = "$notification.comment$"
USEREMAIL = "$user.email$" USEREMAIL = "$user.email$"
// Custom ENV variables
PERFDATA = "$host.perfdata$" PERFDATA = "$host.perfdata$"
NETBOXHOSTNAME = "$host.vars.host_url$" // Optional ENV variables
NETBOXPANELID = "$host.vars.panel_url$" NETBOXHOSTNAME = "$host.vars.netbox_host_name$"
NETBOXHOSTIP = "$host.vars.netbox_host_ip$"
GRAFANAPANELID = "$host.vars.grafana_panelid$"
} }
} }
...@@ -38,9 +39,10 @@ object NotificationCommand "enhanced-mail-service-notification" { ...@@ -38,9 +39,10 @@ object NotificationCommand "enhanced-mail-service-notification" {
NOTIFICATIONAUTHORNAME = "$notification.author$" NOTIFICATIONAUTHORNAME = "$notification.author$"
NOTIFICATIONCOMMENT = "$notification.comment$" NOTIFICATIONCOMMENT = "$notification.comment$"
USEREMAIL = "$user.email$" USEREMAIL = "$user.email$"
// Custom ENV variables
PERFDATA = "$service.perfdata$" PERFDATA = "$service.perfdata$"
NETBOXHOSTNAME = "$host.vars.host_url$" // Optional ENV variables
PANELURL = "$service.vars.panel_url$" NETBOXHOSTNAME = "$host.vars.netbox_host_name$"
NETBOXHOSTIP = "$host.vars.netbox_host_ip$"
GRAFANAPANELID = "$host.vars.grafana_panelid$"
} }
} }
...@@ -86,10 +86,13 @@ if netbox_host_name == '': ...@@ -86,10 +86,13 @@ if netbox_host_name == '':
# If the env is set but empty # If the env is set but empty
netbox_host_name = host_alias netbox_host_name = host_alias
grafana_host_panel_id = os.getenv('NETBOXPANELID', GRAFANADEFAULTHOSTPANELID) netbox_host_ip = os.getenv('NETBOXHOSTIP', host_address)
if grafana_host_panel_id == '': if netbox_host_name == '':
# If the env is set but empty # If the env is set but empty
grafana_host_panel_id = GRAFANADEFAULTHOSTPANELID netbox_host_name = host_address
grafana_host_name = host_alias
grafana_panel_id = os.getenv('GRAFANAPANELID', None)
# If the host_address is set to nothing use the alias # If the host_address is set to nothing use the alias
if not host_address: if not host_address:
...@@ -117,7 +120,9 @@ if DEBUG: ...@@ -117,7 +120,9 @@ if DEBUG:
f.write('\nexport USEREMAIL="{}"'.format(email_to)) f.write('\nexport USEREMAIL="{}"'.format(email_to))
f.write('\nexport PERFDATA="{}"'.format(performance_data)) f.write('\nexport PERFDATA="{}"'.format(performance_data))
f.write('\nexport NETBOXHOSTNAME="{}"'.format(netbox_host_name)) f.write('\nexport NETBOXHOSTNAME="{}"'.format(netbox_host_name))
f.write('\nexport NETBOXPANELID="{}"'.format(grafana_host_panel_id)) f.write('\nexport NETBOXHOSTIP="{}"'.format(netbox_host_ip))
f.write('\nexport GRAFANAHOSTNAME="{}"'.format(grafana_host_name))
f.write('\nexport GRAFANAPANELID="{}"'.format(grafana_panel_id))
f.write("\n") f.write("\n")
f.write("\n/etc/icinga2/scripts/enhanced-mail-notification.py") f.write("\n/etc/icinga2/scripts/enhanced-mail-notification.py")
f.close() f.close()
...@@ -144,14 +149,19 @@ class Netbox: ...@@ -144,14 +149,19 @@ class Netbox:
self.__parse() self.__parse()
def __parse(self): def __parse(self):
nb_device = self.__searchData(NETBOXBASE + '/api' + NETBOXPATHDEVICES + '/?name=' + host_alias) """ Search netbox for
nb_vm = self.__searchData(NETBOXBASE + '/api' + NETBOXPATHVMS + '/?name=' + host_alias)
nb_ip = self.__searchData(NETBOXBASE + '/api' + NETBOXPATHIPS + '/?address=' + host_address) :return:
"""
nb_device = self.__searchData(NETBOXBASE + '/api' + NETBOXPATHDEVICES + '/?name=' + netbox_host_name)
nb_vm = self.__searchData(NETBOXBASE + '/api' + NETBOXPATHVMS + '/?name=' + netbox_host_name)
nb_host_ip = self.__searchData(NETBOXBASE + '/api' + NETBOXPATHIPS + '/?address=' + netbox_host_name)
nb_address_ip = self.__searchData(NETBOXBASE + '/api' + NETBOXPATHIPS + '/?address=' + netbox_host_ip)
if DEBUG: if DEBUG:
print(json.dumps(nb_device, indent=4, sort_keys=True)) print(json.dumps(nb_device, indent=4, sort_keys=True))
print(json.dumps(nb_vm, indent=5, sort_keys=True)) print(json.dumps(nb_vm, indent=5, sort_keys=True))
print(json.dumps(nb_ip, indent=4, sort_keys=True)) print(json.dumps(nb_address_ip, indent=4, sort_keys=True))
if nb_device and not nb_vm: if nb_device and not nb_vm:
self.host = nb_device self.host = nb_device
...@@ -164,9 +174,12 @@ class Netbox: ...@@ -164,9 +174,12 @@ class Netbox:
else: else:
print("Found no device's or vm's that match") print("Found no device's or vm's that match")
if nb_ip: if nb_host_ip:
self.ip = nb_ip self.ip = nb_host_ip
self.ip_url = "{}/{}/".format(NETBOXBASE + NETBOXPATHIPS, nb_ip['id']) self.ip_url = "{}/{}/".format(NETBOXBASE + NETBOXPATHIPS, nb_host_ip['id'])
elif nb_address_ip:
self.ip = nb_address_ip
self.ip_url = "{}/{}/".format(NETBOXBASE + NETBOXPATHIPS, nb_address_ip['id'])
def __getServerData(self, url): def __getServerData(self, url):
headers = {'Accept': 'application/json'} headers = {'Accept': 'application/json'}
...@@ -205,16 +218,15 @@ class Netbox: ...@@ -205,16 +218,15 @@ class Netbox:
def addRow(self, title, obj, key1, key2=None): def addRow(self, title, obj, key1, key2=None):
"""Generate html row containing title and value from key(s) in object """Generate html row containing title and value from key(s) in object
Arguments: Arguments:
title {str} -- Title for the row :arg title: str : Title for the row
obj {dict} -- netbox dict that we are parsing :arg obj : dict : netbox dict that we are parsing
key1 {str} -- key to get value for :arg key1 : str : key to get value for
Keyword Arguments: Keyword Arguments:
key2 {str} -- sub key to get value for (default: {None}) :arg key2 : str : sub key to get value for (default: None)
Returns: :return: str : html row if keys exist else empty string
str -- html row if keys exist else empty string
""" """
val = self.__getVal(obj, key1, key2) val = self.__getVal(obj, key1, key2)
if val: if val:
...@@ -228,15 +240,14 @@ class Netbox: ...@@ -228,15 +240,14 @@ class Netbox:
assumes the last key contains a key value == url assumes the last key contains a key value == url
Arguments: Arguments:
title {str} -- Title for the row :arg title: str : Title for the row
obj {dict} -- netbox dict that we are parsing :arg obj : dict : netbox dict that we are parsing
key1 {str} -- key to get value for :arg key1 : str : key to get value for
Keyword Arguments: Keyword Arguments:
key2 {str} -- sub key to get value for (default: {None}) :arg key2 : str : sub key to get value for (default: None)
Returns: :return: str : html row if keys exist else empty
str -- html row if keys exist else empty
""" """
val = self.__getVal(obj, key1, key2) val = self.__getVal(obj, key1, key2)
if val: if val:
...@@ -247,8 +258,7 @@ class Netbox: ...@@ -247,8 +258,7 @@ class Netbox:
class Grafana: class Grafana:
""" """Grafana object that parses icingaweb2 grafana module (optional) and data from the grafana api
Grafana object that parses icingaweb2 grafana module (optional) and data from the grafana api
all ivars are intialized as empty and filled if valid data is found for each type all ivars are intialized as empty and filled if valid data is found for each type
:ivar png_url: str: url to the png for the GRAFANABASE, netbox_host_name and panelid :ivar png_url: str: url to the png for the GRAFANABASE, netbox_host_name and panelid
...@@ -259,6 +269,10 @@ class Grafana: ...@@ -259,6 +269,10 @@ class Grafana:
:ivar __icingaweb2_ini: ConfigParser.read object : contains the icingaweb2 grafana module ini settings for the GRAFANAICINGAWEB2INI :ivar __icingaweb2_ini: ConfigParser.read object : contains the icingaweb2 grafana module ini settings for the GRAFANAICINGAWEB2INI
""" """
def __init__(self): def __init__(self):
"""Get best panelid depending on service or host state then attempt to build urls and get png
panelid prioritizes environment var over ini file of default host value
"""
self.png_url = '' self.png_url = ''
self.page_url = '' self.page_url = ''
self.png = None self.png = None
...@@ -268,15 +282,24 @@ class Grafana: ...@@ -268,15 +282,24 @@ class Grafana:
if os.path.exists(GRAFANAICINGAWEB2INI): if os.path.exists(GRAFANAICINGAWEB2INI):
self.__parseIcingaweb2INI() self.__parseIcingaweb2INI()
if service_state: if service_state:
self.panelID = self.__getPanelID(service_display_name, service_name, service_command) if grafana_panel_id:
self.panelID = grafana_panel_id
elif os.path.exists(GRAFANAICINGAWEB2INI):
self.__parseIcingaweb2INI()
self.panelID = self.__getINIPanelID(service_display_name, service_name, service_command)
else:
print("Unable to get panel id for service from environment var GRAFANAPANELID [{0}] or from the icingaweb2 grafana module ini file {1}".format(grafana_panel_id, GRAFANAICINGAWEB2INI))
if host_state: elif host_state:
self.panelID = grafana_host_panel_id if grafana_panel_id:
self.panelID = grafana_panel_id
else:
self.panelID = GRAFANADEFAULTHOSTPANELID
if self.panelID and GRAFANABASE: if self.panelID and GRAFANABASE:
self.png_url = GRAFANABASE + '/render/dashboard-solo/db/' + GRAFANADASHBOARD + '?panelId=' + self.panelID + '&' + GRAFANAVARHOST + '=' + netbox_host_name + '&theme=' + GRAFANATHEME + '&width=' + WIDTH + '&height=' + HEIGHT self.png_url = GRAFANABASE + '/render/dashboard-solo/db/' + GRAFANADASHBOARD + '?panelId=' + self.panelID + '&' + GRAFANAVARHOST + '=' + grafana_host_name + '&theme=' + GRAFANATHEME + '&width=' + WIDTH + '&height=' + HEIGHT
self.page_url = GRAFANABASE + '/dashboard/db/' + GRAFANADASHBOARD + '?fullscreen&panelId=' + self.panelID + '&' + GRAFANAVARHOST + '=' + netbox_host_name self.page_url = GRAFANABASE + '/dashboard/db/' + GRAFANADASHBOARD + '?fullscreen&panelId=' + self.panelID + '&' + GRAFANAVARHOST + '=' + grafana_host_name
self.png = self.__getPNG() self.png = self.__getPNG()
def __parseIcingaweb2INI(self): def __parseIcingaweb2INI(self):
...@@ -303,7 +326,7 @@ class Grafana: ...@@ -303,7 +326,7 @@ class Grafana:
response = None response = None
return response return response
def __searchSections(self, display_name, name, command): def __searchINISections(self, display_name, name, command):
pattern = None pattern = None
if display_name: if display_name:
pattern = re.compile(display_name) pattern = re.compile(display_name)
...@@ -331,8 +354,8 @@ class Grafana: ...@@ -331,8 +354,8 @@ class Grafana:
print("\nGrafana section: {}".format(section)) print("\nGrafana section: {}".format(section))
return section return section
def __getPanelID(self, display_name, name, command): def __getINIPanelID(self, display_name, name, command):
section = self.__searchSections(display_name, name, command) section = self.__searchINISections(display_name, name, command)
panel_id = None panel_id = None
if section: if section:
panel_id = self.__icingaweb2_ini.get(section, 'panelId').replace('"', '') panel_id = self.__icingaweb2_ini.get(section, 'panelId').replace('"', '')
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment