Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 2.5.5 #184

Merged
merged 26 commits into from
Apr 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
569d31a
Merge pull request #166 from idealista/hotfix/162
Feb 10, 2020
7ffd669
Bump pyyaml from 3.13 to 5.1
dependabot[bot] Feb 10, 2020
f03bf47
Fixed typo
pierrediancourt Feb 15, 2020
ba00898
Fix typo
pierrediancourt Feb 15, 2020
8bb7b1f
Merge pull request #168 from pierrediancourt/develop
dortegau Apr 4, 2020
ba6102a
Merge branch 'develop' into dependabot/pip/pyyaml-5.1
dortegau Apr 4, 2020
32bcf3e
#175 Using multi-stage build to create prom2teams image
dortegau Apr 11, 2020
eb2135f
#175 Using multi-stage build to create prom2teams image (CHANGELOG)
dortegau Apr 11, 2020
3f448d2
#177 Fixing unit tests when using Python <= 3.6
dortegau Apr 12, 2020
af3c460
#177 Fixing unit tests when using Python <= 3.6
dortegau Apr 12, 2020
fe3602a
#177 Fixing unit tests when using Python <= 3.6
dortegau Apr 12, 2020
4270038
Merge pull request #156 from idealista/dependabot/pip/pyyaml-5.1
dortegau Apr 12, 2020
e282d2d
#158 Fixing Travis Badge and reordering TOC
dortegau Apr 12, 2020
d10a7db
Merge branch 'develop' into bugs/177
dortegau Apr 13, 2020
0df2919
Merge pull request #178 from idealista/bugs/177
dortegau Apr 13, 2020
b51a2bf
Merge branch 'develop' into bugs/158
dortegau Apr 13, 2020
8a4f752
Merge branch 'develop' into features/175
dortegau Apr 13, 2020
e87fc50
Update CHANGELOG.md
dortegau Apr 13, 2020
a09dd3a
Merge pull request #179 from idealista/bugs/158
dortegau Apr 13, 2020
d860460
Merge branch 'develop' into features/175
dortegau Apr 13, 2020
4732a5e
Merge pull request #176 from idealista/features/175
dortegau Apr 13, 2020
c520f35
#182 fix dependances versions and Dockerfile
Apr 29, 2020
591ca9c
#182 updated changelog
Apr 29, 2020
7ef299f
Merge pull request #183 from idealista/bugs/182
dortegau Apr 29, 2020
013516b
Updated changelog for release
Apr 29, 2020
73c9d09
Updated setup.py for release; fix changelog
Apr 29, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ Enhancement suggestions are tracked as [GitHub issues](https://guides.github.com
### Pull Requests

* Fill in [the required template](PULL_REQUEST_TEMPLATE.md)
* Any pull request should has **idealista:develop** as base branch.
* Any pull request should have **idealista:develop** as base branch.

### Changelog

Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ This project adheres to [Semantic Versioning](http://semver.org/) and [Keep a ch

## [Unreleased](https://github.com/idealista/prom2teams/tree/develop)

## [2.5.5](https://github.com/idealista/prom2teams/tree/2.5.5)
[Full Changelog](https://github.com/idealista/prom2teams/compare/2.5.4...2.5.5)
## Changed
- *[#175](https://github.com/idealista/prom2teams/issues/175) Building docker image using multi-stage build feature* @dortegau

## Fixed
- *[#158](https://github.com/idealista/prom2teams/issues/158) Fixing Travis Badge (pointing to master branch) and reordering TOC* @dortegau
- *[#177](https://github.com/idealista/prom2teams/issues/177) Fixing unit tests when using Python <= 3.6* @dortegau
- *[#182](https://github.com/idealista/prom2teams/issues/182) Fix dependances versions; yaml-dev in docker container; updated pyyaml package* @ftsao

## [2.5.4](https://github.com/idealista/prom2teams/tree/2.5.4)
[Full Changelog](https://github.com/idealista/prom2teams/compare/2.5.3...2.5.4)
## Fixed
Expand Down
33 changes: 15 additions & 18 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,32 +1,29 @@
FROM python:3.5-alpine

LABEL maintainer="labs@idealista.com"

EXPOSE 8089

RUN apk add gcc libc-dev linux-headers --no-cache

WORKDIR /opt/prom2teams

COPY ./docker/ \
LICENSE \
FROM python:3.5-alpine AS builder
WORKDIR /prom2teams
COPY LICENSE \
MANIFEST.in \
README.md \
requirements.txt \
setup.py \
./
COPY prom2teams/ prom2teams
COPY bin/ bin
RUN apk add gcc libc-dev yaml-dev linux-headers --no-cache \
&& python setup.py bdist_wheel

COPY ./bin bin
COPY ./prom2teams prom2teams

RUN python setup.py install

FROM python:3.5-alpine
LABEL maintainer="labs@idealista.com"
EXPOSE 8089
WORKDIR /opt/prom2teams
COPY docker/rootfs .
COPY --from=builder /prom2teams/dist .
RUN apk add gcc libc-dev yaml-dev linux-headers --no-cache \
&& pip install prom2teams*.whl
ENV PROM2TEAMS_PORT="8089" \
PROM2TEAMS_HOST="0.0.0.0" \
PROM2TEAMS_LOGLEVEL="INFO" \
PROM2TEAMS_CONNECTOR="" \
PROM2TEAMS_GROUP_ALERTS_BY="" \
APP_CONFIG_FILE="/opt/prom2teams/config.ini" \
PROM2TEAMS_PROMETHEUS_METRICS="true"

ENTRYPOINT ["sh", "prom2teams_start.sh"]
67 changes: 36 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
![Logo](https://raw.githubusercontent.com/idealista/prom2teams/master/logo.gif)

[![Build Status](https://travis-ci.org/idealista/prom2teams.png)](https://travis-ci.org/idealista/prom2teams)
[![Build Status](https://travis-ci.org/idealista/prom2teams.svg?branch=master)](https://travis-ci.org/idealista/prom2teams)
[![Docker Build Status](https://img.shields.io/docker/build/idealista/prom2teams.svg)](https://hub.docker.com/r/idealista/prom2teams/)
[![Docker Hub Pulls](https://img.shields.io/docker/pulls/idealista/prom2teams.svg)](https://hub.docker.com/r/idealista/prom2teams/)
[![Docker Automated build](https://img.shields.io/docker/automated/idealista/prom2teams.svg)](https://hub.docker.com/r/idealista/prom2teams/)

# prom2teams

<img src="https://raw.githubusercontent.com/idealista/prom2teams/master/assets/example.png" alt="Alert example" style="width: 600px;"/>
Expand All @@ -14,9 +14,13 @@
- [Prerequisities](#prerequisites)
- [Installing](#installing)
- [Usage](#usage)
- [Docker Image](#docker-image)
- [Helm Chart](#helm-chart)
- [Config file](#config-file)
- [Configuring Prometheus](#configuring-prometheus)
- [Templating](#templating)
- [Documentation](#documentation)
- [Swagger UI](#swagger-ui)
- [Testing](#testing)
- [Built With](#built-with)
- [Versioning](#versioning)
Expand Down Expand Up @@ -61,12 +65,29 @@ $ prom2teams
```
**Note:** Grouping alerts works since v2.2.1

### Prom2teams Prometheus metrics
### Docker image

Prom2teams uses Flask and, to have the service monitored, we use @rycus66's [Prometheus Flask Exporter](https://github.com/rycus86/prometheus_flask_exporter). This will enable an endpoint in `/metrics` where you could find interesting metrics to monitor such as number of responses with a certain status. To enable this endpoint, just either:
Every new Prom2teams release, a new Docker image is built in our [Dockerhub](https://hub.docker.com/r/idealista/prom2teams). We strongly recommend you to use the images with the version tag, though it will be possible to use them without it.

- Use the `--enablemetrics` or `-m` flag when launching prom2teams.
- Set the environment variable `PROM2TEAMS_PROMETHEUS_METRICS=true`.
There are two things you need to bear in mind when creating a Prom2teams container:

- The connector URL must be passed as the environment variable `PROM2TEAMS_CONNECTOR`
- In case you want to group alerts, you need to pass the field as the environment variable `PROM2TEAMS_GROUP_ALERTS_BY`
- You need to map container's Prom2teams port to one on your host.

So a sample Docker run command would be:

```bash
$ docker run -it -d -e PROM2TEAMS_GROUP_ALERTS_BY=FIELD_YOU_WANT_TO_GROUP_BY -e PROM2TEAMS_CONNECTOR="CONNECTOR_URL" -p 8089:8089 idealista/prom2teams:VERSION
```

#### Provide custom config file

If you prefer to use your own config file, you just need to provide it as a Docker volume to the container and map it to `/opt/prom2teams/config.ini`. Sample:

```bash
$ docker run -it -d -v pathToTheLocalConfigFile:/opt/prom2teams/config.ini -p 8089:8089 idealista/prom2teams:VERSION
```

### Helm chart

Expand Down Expand Up @@ -116,30 +137,6 @@ The following table lists the configurable parameters of the Prom2teams chart an
| `prom2teams.templatepath` | Custom Template path (files/teams.j2) | `/opt/prom2teams/helmconfig/teams.j2`
| `prom2teams.config` | Config (specific to Helm) | `/opt/prom2teams/helmconfig/config.ini`

### Docker image

Every new Prom2teams release, a new Docker image is built in our [Dockerhub](https://hub.docker.com/r/idealista/prom2teams). We strongly recommend you to use the images with the version tag, though it will be possible to use them without it.

There are two things you need to bear in mind when creating a Prom2teams container:

- The connector URL must be passed as the environment variable `PROM2TEAMS_CONNECTOR`
- In case you want to group alerts, you need to pass the field as the environment variable `PROM2TEAMS_GROUP_ALERTS_BY`
- You need to map container's Prom2teams port to one on your host.

So a sample Docker run command would be:

```bash
$ docker run -it -d -e PROM2TEAMS_GROUP_ALERTS_BY=FIELD_YOU_WANT_TO_GROUP_BY -e PROM2TEAMS_CONNECTOR="CONNECTOR_URL" -p 8089:8089 idealista/prom2teams:VERSION
```

#### Provide custom config file

If you prefer to use your own config file, you just need to provide it as a Docker volume to the container and map it to `/opt/prom2teams/config.ini`. Sample:

```bash
$ docker run -it -d -v pathToTheLocalConfigFile:/opt/prom2teams/config.ini -p 8089:8089 idealista/prom2teams:VERSION
```

### Production

For production environments you should prefer using a WSGI server. [uWSGI](https://uwsgi-docs.readthedocs.io/en/latest/)
Expand Down Expand Up @@ -223,6 +220,13 @@ The url is formed by the host and port defined in the previous step.
url: 0.0.0.0:8089/v2/<Connector1>
```

### Prom2teams Prometheus metrics

Prom2teams uses Flask and, to have the service monitored, we use @rycus66's [Prometheus Flask Exporter](https://github.com/rycus86/prometheus_flask_exporter). This will enable an endpoint in `/metrics` where you could find interesting metrics to monitor such as number of responses with a certain status. To enable this endpoint, just either:

- Use the `--enablemetrics` or `-m` flag when launching prom2teams.
- Set the environment variable `PROM2TEAMS_PROMETHEUS_METRICS=true`.

### Templating

prom2teams provides a [default template](prom2teams/resources/templates/teams.j2) built with [Jinja2](http://jinja.pocoo.org/docs/2.10/) to render messages in Microsoft Teams. This template could be overrided using the 'templatepath' argument ('--templatepath <Jinja2 template file path>') during the application start.
Expand All @@ -232,7 +236,8 @@ If such a field is not included a default value of 'unknown' is assigned.

All non-mandatory labels not in excluded list are injected in `extra_labels` key. All non-mandatory annotations not in excluded list are injected in `extra_annotations` key.

#### Swagger UI
## Documentation
### Swagger UI

Accessing to `<Host>:<Port>` (e.g. `localhost:8089`) in a web browser shows the API v1 documentation.

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion prom2teams/app/teams_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def post(teams_webhook_url, message):
exception_msg = 'Error performing request to: {}.\n' \
' Returned status code: {}.\n' \
' Returned data: {}\n' \
' Sended message: {}\n'
' Sent message: {}\n'
raise MicrosoftTeamsRequestException(exception_msg.format(teams_webhook_url,
str(response.status_code),
str(response.text),
Expand Down
6 changes: 0 additions & 6 deletions prom2teams/teams/alarm_mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,6 @@
from collections import defaultdict


def map_alarm_to_json(alarm):
schema = TeamsAlarmSchema()
result = schema.dump(alarm)
return result


def map_prom_alerts_to_teams_alarms(alerts):
alerts = group_alerts(alerts, 'status')
teams_alarms = []
Expand Down
6 changes: 5 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ flask-restplus==0.12.1
marshmallow==3.0.0rc6
jinja2==2.10.1
Flask==1.0.2
pyyaml==3.13
pyyaml==5.1
uwsgi==2.0.16
prometheus_flask_exporter==0.9.0
werkzeug==0.16.1
DeepDiff==4.3.0
zipp==1.2.0
MarkupSafe==1.1.1
pyrsistent==0.16.0
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@


setup(name='prom2teams',
version='2.5.4',
version='2.5.5',
description='Project that redirects Prometheus Alert Manager '
'notifications to Microsoft Teams',
long_description=readme,
Expand Down
File renamed without changes.
18 changes: 9 additions & 9 deletions tests/test_app_configuration.py
Original file line number Diff line number Diff line change
@@ -1,46 +1,48 @@
import unittest
import os

from prom2teams.app import configuration
from prom2teams.app import exceptions


class TestServer(unittest.TestCase):
TEST_CONFIG_FILES_PATH = 'tests/data/'
TEST_CONFIG_FILES_PATH = './tests/data/'
DEFAULT_CONFIG_RELATIVE_PATH = './prom2teams/config.ini'

def test_get_config_with_invalid_path(self):
invalid_relative_path = self.TEST_CONFIG_FILES_PATH + 'invalid_path'
invalid_relative_path = os.path.join(self.TEST_CONFIG_FILES_PATH, 'invalid_path')
self.assertRaises(FileNotFoundError, configuration._config_provided, invalid_relative_path)

def test_get_config_without_required_keys_should_raise_exception(self):
empty_config_relative_path = self.TEST_CONFIG_FILES_PATH + 'empty_config.ini'
empty_config_relative_path = os.path.join(self.TEST_CONFIG_FILES_PATH, 'empty_config.ini')

self.assertRaises(exceptions.MissingConnectorConfigKeyException, configuration._config_provided,
empty_config_relative_path)

def test_get_config_without_override(self):
provided_config_relative_path = self.TEST_CONFIG_FILES_PATH + 'without_overriding_defaults.ini'
provided_config_relative_path = os.path.join(self.TEST_CONFIG_FILES_PATH, 'not_overriding_defaults.ini')
config = configuration._config_provided(provided_config_relative_path)

self.assertTrue(config.get('Microsoft Teams', 'Connector'))

def test_get_config_overriding_defaults(self):
provided_config_relative_path = self.TEST_CONFIG_FILES_PATH + 'overriding_defaults.ini'
provided_config_relative_path = os.path.join(self.TEST_CONFIG_FILES_PATH, 'overriding_defaults.ini')
config = configuration._config_provided(provided_config_relative_path)

self.assertEqual(config.get('HTTP Server', 'Host'), '1.1.1.1')
self.assertEqual(config.get('HTTP Server', 'Port'), '9089')
self.assertTrue(config.get('Microsoft Teams', 'Connector'))

def test_connectors_configured(self):
provided_config_relative_path = self.TEST_CONFIG_FILES_PATH + 'multiple_connectors_config.ini'
provided_config_relative_path = os.path.join(self.TEST_CONFIG_FILES_PATH, 'multiple_connectors_config.ini')
config = configuration._config_provided(provided_config_relative_path)

self.assertEqual(config['Microsoft Teams']['connector1'], 'teams_webhook_url')
self.assertEqual(config['Microsoft Teams']['connector2'], 'another_teams_webhook_url')
self.assertEqual(config['Microsoft Teams']['connector3'], 'definitely_another_teams_webhook_url')

def test_get_config_for_all_fields(self):
provided_config_relative_path = self.TEST_CONFIG_FILES_PATH + 'all_fields.ini'
provided_config_relative_path = os.path.join(self.TEST_CONFIG_FILES_PATH, 'all_fields.ini')
config = configuration._config_provided(provided_config_relative_path)

self.assertEqual(config.get('HTTP Server', 'Host'), '1.1.1.1')
Expand All @@ -51,7 +53,5 @@ def test_get_config_for_all_fields(self):
self.assertEqual(config.get('Template', 'Path'), 'jinja2/template/path')
self.assertEqual(config.get('Group Alerts', 'Field'), 'name')



if __name__ == '__main__':
unittest.main()
Loading