Skip to content

Commit

Permalink
Enable pip installs and Cachito compatibility (#9)
Browse files Browse the repository at this point in the history
* Add setup.py for pip compatibility

This allows prometheus_webhook_snmp to be installed using pip install.

* Add requirements and build requirements, all with locked versions

Cachito requires locking all versions to work. It is also generally a good thing to do.

* Dockerfile: install with pip instead of RPMs
  • Loading branch information
compi-migui authored Jan 27, 2022
1 parent b4e9844 commit 321afe1
Show file tree
Hide file tree
Showing 9 changed files with 364 additions and 130 deletions.
36 changes: 29 additions & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,32 @@
FROM quay.io/centos/centos:centos8
FROM quay.io/centos/centos:stream8

RUN dnf -y install centos-release-opstools && \
dnf -y install python3-cherrypy python3-PyYAML python3-pysnmp \
python3-dateutil python3-click git \
prometheus-webhook-snmp \
python3-prometheus_client procps-ng lsof && dnf clean all
RUN INSTALL_PKGS="\
procps-ng \
telnet \
lsof \
python3 \
python3-devel \
gcc \
" && \
dnf -y --setopt=tsflags=nodocs --setopt=skip_missing_names_on_install=False install $INSTALL_PKGS && \
dnf -y clean all

COPY . /source/app
WORKDIR /source/app

RUN alternatives --set python /usr/bin/python3 && \
python -m pip install --upgrade setuptools pip && \
python -m pip install wheel && \
python -m pip install -r requirements-build.txt && \
python -m pip install . && \
python -m pip freeze

# Cleanup
RUN UNINSTALL_PKGS="\
gcc \
" && \
dnf remove -y $UNINSTALL_PKGS && \
dnf -y clean all

ENV SNMP_COMMUNITY="public"
ENV SNMP_PORT=162
Expand All @@ -15,4 +37,4 @@ ENV ALERT_OID_LABEL="oid"

EXPOSE 9099

CMD ["sh", "-c", "/usr/bin/prometheus-webhook-snmp --debug --snmp-port=$SNMP_PORT --snmp-host=$SNMP_HOST --snmp-community=$SNMP_COMMUNITY --alert-oid-label=$ALERT_OID_LABEL run"]
CMD ["sh", "-c", "/usr/local/bin/prometheus-webhook-snmp --debug --snmp-port=$SNMP_PORT --snmp-host=$SNMP_HOST --snmp-community=$SNMP_COMMUNITY --alert-oid-label=$ALERT_OID_LABEL run"]
10 changes: 10 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
include CHANGELOG.md
include LICENSE
include README.md

recursive-exclude tests *
recursive-exclude tmp *
recursive-exclude debian *
recursive-exclude .github *
recursive-exclude * __pycache__
recursive-exclude * *.py[co]
122 changes: 3 additions & 119 deletions prometheus-webhook-snmp
Original file line number Diff line number Diff line change
@@ -1,124 +1,8 @@
#!/usr/bin/python3
import datetime
import logging
#!/usr/bin/env python
import sys

import click

from prometheus_webhook_snmp import utils


__version__ = "1.5"


pass_context = click.make_pass_decorator(utils.Context, ensure=True)


@click.group(help='Prometheus Alertmanager receiver that translates '
'notifications into SNMP v2c traps.')
@click.option('--debug',
is_flag=True,
help='Enable debug output.')
@click.option('--snmp-host',
help='The host (IPv4, IPv6 or FQDN) of the SNMP trap receiver.')
@click.option('--snmp-port',
help='The port of the SNMP trap receiver.',
type=int)
@click.option('--snmp-community',
help='The SNMP community string.')
@click.option('--snmp-retries',
help='Maximum number of request retries.',
type=int)
@click.option('--snmp-timeout',
help='Response timeout in seconds.',
type=int)
@click.option('--alert-oid-label',
help='The label where to find the OID.')
@click.option('--trap-oid-prefix',
help='The OID prefix for trap variable bindings.')
@click.option('--trap-default-oid',
help='The trap OID if none is found in the Prometheus alert labels.')
@click.option('--trap-default-severity',
help='The trap severity if none is found in the Prometheus alert labels.')
@click.version_option(__version__, message="%(version)s")
@pass_context
def cli(ctx, debug, snmp_host, snmp_port, snmp_community, snmp_retries,
snmp_timeout, alert_oid_label, trap_oid_prefix, trap_default_oid,
trap_default_severity):
ctx.config.load(click.get_current_context().info_name)
ctx.config['debug'] = True if debug else None
ctx.config['snmp_host'] = snmp_host
ctx.config['snmp_port'] = snmp_port
ctx.config['snmp_community'] = snmp_community
ctx.config['snmp_retries'] = snmp_retries
ctx.config['snmp_timeout'] = snmp_timeout
ctx.config['alert_oid_label'] = alert_oid_label
ctx.config['trap_default_oid'] = trap_default_oid
ctx.config['trap_default_severity'] = trap_default_severity
ctx.config['trap_oid_prefix'] = trap_oid_prefix

if ctx.config['debug']:
logging.basicConfig(level=logging.DEBUG)

return 0


@cli.command(name='run', help='Start the HTTP server.')
@click.option('--host',
help='Host to use.')
@click.option('--port',
help='Port to listen for Prometheus Alertmanager notifications.',
type=int)
@click.option('--metrics',
is_flag=True,
help='Provide Prometheus metrics from this receiver.')
@pass_context
def run(ctx, host, port, metrics):
ctx.config['host'] = host
ctx.config['port'] = port
ctx.config['metrics'] = True if metrics else None
ctx.config.dump()
utils.run_http_server(ctx)
sys.exit(0)


@cli.command(name='test', help='Trigger a SNMP trap.')
@pass_context
def test(ctx):
ctx.config.dump()
trap_data = utils.parse_notification(ctx.config, {
'receiver': 'bar',
'status': 'firing',
'alerts': [{
'status': 'firing',
'labels': {
'alertname': 'load_0',
'instance': 'localhost:9100',
'job': 'node-exporter',
'severity': 'info',
'foo': 'bar',
'xyz': 'abc'
},
'annotations': {
'description': 'localhost:9100 of job node-exporter load is over 0!',
'summary': 'Instance localhost:9100 load is over 0!'
},
'startsAt': datetime.datetime.utcnow().isoformat() + 'Z',
'endsAt': '0001-01-01T00:00:00Z',
'generatorURL': 'http://foo:9090/graph?...'
}],
'groupLabels': {},
'commonLabels': {},
'commonAnnotations': {},
'externalURL': '',
'version': '4',
'groupKey': '{}:{}'
})
if trap_data is not None:
for data in trap_data:
utils.send_snmp_trap(ctx.config, data)
sys.exit(0)
from prometheus_webhook_snmp import prometheus_webhook_snmp


if __name__ == "__main__":
sys.exit(cli()) # pylint: disable=no-value-for-parameter
sys.exit(prometheus_webhook_snmp.cli()) # pylint: disable=no-value-for-parameter
124 changes: 124 additions & 0 deletions prometheus_webhook_snmp/prometheus_webhook_snmp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#!/usr/bin/python3
import datetime
import logging
import sys

import click

from prometheus_webhook_snmp import utils


__version__ = "1.5"


pass_context = click.make_pass_decorator(utils.Context, ensure=True)


@click.group(help='Prometheus Alertmanager receiver that translates '
'notifications into SNMP v2c traps.')
@click.option('--debug',
is_flag=True,
help='Enable debug output.')
@click.option('--snmp-host',
help='The host (IPv4, IPv6 or FQDN) of the SNMP trap receiver.')
@click.option('--snmp-port',
help='The port of the SNMP trap receiver.',
type=int)
@click.option('--snmp-community',
help='The SNMP community string.')
@click.option('--snmp-retries',
help='Maximum number of request retries.',
type=int)
@click.option('--snmp-timeout',
help='Response timeout in seconds.',
type=int)
@click.option('--alert-oid-label',
help='The label where to find the OID.')
@click.option('--trap-oid-prefix',
help='The OID prefix for trap variable bindings.')
@click.option('--trap-default-oid',
help='The trap OID if none is found in the Prometheus alert labels.')
@click.option('--trap-default-severity',
help='The trap severity if none is found in the Prometheus alert labels.')
@click.version_option(__version__, message="%(version)s")
@pass_context
def cli(ctx, debug, snmp_host, snmp_port, snmp_community, snmp_retries,
snmp_timeout, alert_oid_label, trap_oid_prefix, trap_default_oid,
trap_default_severity):
ctx.config.load(click.get_current_context().info_name)
ctx.config['debug'] = True if debug else None
ctx.config['snmp_host'] = snmp_host
ctx.config['snmp_port'] = snmp_port
ctx.config['snmp_community'] = snmp_community
ctx.config['snmp_retries'] = snmp_retries
ctx.config['snmp_timeout'] = snmp_timeout
ctx.config['alert_oid_label'] = alert_oid_label
ctx.config['trap_default_oid'] = trap_default_oid
ctx.config['trap_default_severity'] = trap_default_severity
ctx.config['trap_oid_prefix'] = trap_oid_prefix

if ctx.config['debug']:
logging.basicConfig(level=logging.DEBUG)

return 0


@cli.command(name='run', help='Start the HTTP server.')
@click.option('--host',
help='Host to use.')
@click.option('--port',
help='Port to listen for Prometheus Alertmanager notifications.',
type=int)
@click.option('--metrics',
is_flag=True,
help='Provide Prometheus metrics from this receiver.')
@pass_context
def run(ctx, host, port, metrics):
ctx.config['host'] = host
ctx.config['port'] = port
ctx.config['metrics'] = True if metrics else None
ctx.config.dump()
utils.run_http_server(ctx)
sys.exit(0)


@cli.command(name='test', help='Trigger a SNMP trap.')
@pass_context
def test(ctx):
ctx.config.dump()
trap_data = utils.parse_notification(ctx.config, {
'receiver': 'bar',
'status': 'firing',
'alerts': [{
'status': 'firing',
'labels': {
'alertname': 'load_0',
'instance': 'localhost:9100',
'job': 'node-exporter',
'severity': 'info',
'foo': 'bar',
'xyz': 'abc'
},
'annotations': {
'description': 'localhost:9100 of job node-exporter load is over 0!',
'summary': 'Instance localhost:9100 load is over 0!'
},
'startsAt': datetime.datetime.utcnow().isoformat() + 'Z',
'endsAt': '0001-01-01T00:00:00Z',
'generatorURL': 'http://foo:9090/graph?...'
}],
'groupLabels': {},
'commonLabels': {},
'commonAnnotations': {},
'externalURL': '',
'version': '4',
'groupKey': '{}:{}'
})
if trap_data is not None:
for data in trap_data:
utils.send_snmp_trap(ctx.config, data)
sys.exit(0)


if __name__ == "__main__":
sys.exit(cli()) # pylint: disable=no-value-for-parameter
18 changes: 18 additions & 0 deletions requirements-build.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by pip_find_builddeps.py on May 19 2021 12:57:26
Cython
setuptools
setuptools-scm
setuptools>=30.3.0
setuptools>=34.4
setuptools>=40.0
setuptools>=40.6.0
setuptools>=40.8.0
setuptools>=42
setuptools>=45
setuptools_scm
setuptools_scm<6.0,>=3.3.1
setuptools_scm>=1.15
setuptools_scm[toml]>=3.4.1
setuptools_scm_git_archive>=1.0
toml
wheel
26 changes: 26 additions & 0 deletions requirements-build.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#
# This file is autogenerated by pip-compile
# To update, run:
#
# pip-compile --allow-unsafe --output-file=requirements-build.txt requirements-build.in
#
pip==21.1.1
# for Cachito debugging
cython==0.29.23
# via -r requirements-build.in
setuptools-scm-git-archive==1.1
# via -r requirements-build.in
setuptools-scm[toml]==5.0.2
# via -r requirements-build.in
toml==0.10.2
# via
# -r requirements-build.in
# setuptools-scm
wheel==0.36.2
# via -r requirements-build.in

# The following packages are considered to be unsafe in a requirements file:
setuptools==56.2.0
# via
# -r requirements-build.in
# setuptools-scm
11 changes: 11 additions & 0 deletions requirements.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
CherryPy==18.1.1
Click==7.0
PyYAML==5.4
mock==3.0.5
prometheus_client==0.6.0
pyfakefs==3.5.8
pylint==2.3.1
pysnmp==4.4.8
pytest==4.4.0
pytest-runner==5.3.1
python-dateutil==2.8.0
Loading

0 comments on commit 321afe1

Please sign in to comment.