init
This commit is contained in:
commit
135a9dd01d
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
.venv
|
||||
__pycache__
|
||||
config/config.yaml
|
||||
config/text_template.tpl
|
1
.python-version
Normal file
1
.python-version
Normal file
@ -0,0 +1 @@
|
||||
system
|
35
.vscode/launch.json
vendored
Normal file
35
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name":"Python: Flask Migration",
|
||||
"type":"python",
|
||||
"request":"launch",
|
||||
"module":"flask",
|
||||
"env":{
|
||||
"FLASK_APP":"app.migrate",
|
||||
"FLASK_ENV":"development",
|
||||
"FLASK_DEBUG":"0"
|
||||
},
|
||||
"args":["db", "migrate"],
|
||||
"jinja":false
|
||||
},
|
||||
{
|
||||
"name": "Python: Flask",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"module": "flask",
|
||||
"env": {
|
||||
"FLASK_APP": "app",
|
||||
"FLASK_ENV": "development",
|
||||
"FLASK_DEBUG": "1"
|
||||
},
|
||||
"args": [
|
||||
"run",
|
||||
"--no-debugger",
|
||||
"--no-reload"
|
||||
],
|
||||
"jinja": true
|
||||
}
|
||||
]
|
||||
}
|
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"python.defaultInterpreterPath": "venv/bin/python3"
|
||||
}
|
3
app/__init__.py
Normal file
3
app/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
from app.app import app
|
||||
from views import *
|
||||
from views.apis import *
|
4
app/api.py
Normal file
4
app/api.py
Normal file
@ -0,0 +1,4 @@
|
||||
from .app import app
|
||||
from flask_restful import Api
|
||||
|
||||
api = Api(app)
|
24
app/app.py
Normal file
24
app/app.py
Normal file
@ -0,0 +1,24 @@
|
||||
import yaml
|
||||
|
||||
from flask import Flask
|
||||
from utils.json_encoder import JSONEncoder
|
||||
from os.path import dirname, abspath, join
|
||||
|
||||
class Config():
|
||||
pass
|
||||
|
||||
with open('config/config.yaml', 'r') as f:
|
||||
config_yaml = yaml.safe_load(f)
|
||||
|
||||
config = Config()
|
||||
for k, v in config_yaml.items():
|
||||
setattr(config, k, v)
|
||||
|
||||
app = Flask(__name__,
|
||||
root_path=join(dirname(abspath(__file__)), '..'))
|
||||
app.config.from_object(config)
|
||||
|
||||
app.json_encoder = JSONEncoder
|
||||
app.config['RESTFUL_JSON'] = {
|
||||
'cls': app.json_encoder
|
||||
}
|
8
config/config_example.yaml
Normal file
8
config/config_example.yaml
Normal file
@ -0,0 +1,8 @@
|
||||
bark_api: http://bark-server.default:8080/push
|
||||
title:
|
||||
firing: Homeserver 告警发生
|
||||
resolved: Homeserver 告警解除
|
||||
default: Homeserver
|
||||
to:
|
||||
- 'token'
|
||||
template_file: text_template.tpl
|
22
config/text_template_example.tpl
Normal file
22
config/text_template_example.tpl
Normal file
@ -0,0 +1,22 @@
|
||||
{%- for alert in alerts -%}
|
||||
{%- if alert.status == 'firing' -%}
|
||||
告警发生:
|
||||
告警时间:{{alert.startsAt}}
|
||||
{% if alert.labels.instance -%}涉及实例:{{alert.labels.instance}}{%- endif %}
|
||||
{% if alert.labels.device -%}涉及设备:{{alert.labels.device}}{%- endif %}
|
||||
告警名称:{{alert.labels.alertname}}
|
||||
严重性:{{alert.labels.severity}}
|
||||
详情:{{alert.annotations.summary}}
|
||||
{% if alert.annotations.value -%}告警数据:{{alert.annotations.value}}{%- endif %}
|
||||
{%- else -%}
|
||||
告警恢复:
|
||||
告警时间:{{alert.startsAt}}
|
||||
恢复时间:{{alert.endsAt}}
|
||||
{% if alert.labels.instance -%}涉及实例:{{alert.labels.instance}}{%- endif %}
|
||||
{% if alert.labels.device -%}涉及设备:{{alert.labels.device}}{%- endif %}
|
||||
告警名称:{{alert.labels.alertname}}
|
||||
严重性:{{alert.labels.severity}}
|
||||
详情:{{alert.annotations.summary}}
|
||||
{% if alert.annotations.value -%}告警数据:{{alert.annotations.value}}{%- endif %}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
0
utils/__init__.py
Normal file
0
utils/__init__.py
Normal file
11
utils/error_handler.py
Normal file
11
utils/error_handler.py
Normal file
@ -0,0 +1,11 @@
|
||||
import traceback
|
||||
from app import app
|
||||
|
||||
|
||||
def error_handler(e):
|
||||
app.logger.warning(e, traceback.format_exc())
|
||||
return {
|
||||
'success': False,
|
||||
'message': 'Error: {0}'.format(str(e)),
|
||||
'data': None
|
||||
}, 500
|
18
utils/json_encoder.py
Normal file
18
utils/json_encoder.py
Normal file
@ -0,0 +1,18 @@
|
||||
from flask.json import JSONEncoder
|
||||
import datetime
|
||||
import decimal
|
||||
|
||||
|
||||
class JSONEncoder(JSONEncoder):
|
||||
def default(self, obj):
|
||||
try:
|
||||
if isinstance(obj, datetime.datetime):
|
||||
return obj.strftime('%Y-%m-%d %H:%M:%S')
|
||||
elif isinstance(obj, decimal.Decimal):
|
||||
return float(obj)
|
||||
iterable = iter(obj)
|
||||
except TypeError:
|
||||
pass
|
||||
else:
|
||||
return list(iterable)
|
||||
return JSONEncoder.default(self, obj)
|
1
views/__init__.py
Normal file
1
views/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
__all__ = ['apis']
|
1
views/apis/__init__.py
Normal file
1
views/apis/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
__all__ = ['bark_service', 'health']
|
66
views/apis/bark_service.py
Normal file
66
views/apis/bark_service.py
Normal file
@ -0,0 +1,66 @@
|
||||
from flask import request
|
||||
from flask_restful import Resource
|
||||
from utils.error_handler import error_handler
|
||||
from app.app import app
|
||||
from app.api import api
|
||||
from munch import Munch
|
||||
import requests
|
||||
|
||||
class BarkResource(Resource):
|
||||
def post(self):
|
||||
try:
|
||||
data = Munch.fromDict(request.get_json(silent=True))
|
||||
app.logger.debug(data)
|
||||
config = Munch.fromDict(app.config)
|
||||
content = {
|
||||
'title': config.title.firing if data.status == 'firing' else config.title.resolved if data.status == 'resolved' else config.title.default,
|
||||
'category': 'category'
|
||||
}
|
||||
|
||||
# TODO: alertmanager message to bark content.
|
||||
'''
|
||||
{
|
||||
"version": "4",
|
||||
"groupKey": <string>, // key identifying the group of alerts (e.g. to deduplicate)
|
||||
"truncatedAlerts": <int>, // how many alerts have been truncated due to "max_alerts"
|
||||
"status": "<resolved|firing>",
|
||||
"receiver": <string>,
|
||||
"groupLabels": <object>,
|
||||
"commonLabels": <object>,
|
||||
"commonAnnotations": <object>,
|
||||
"externalURL": <string>, // backlink to the Alertmanager.
|
||||
"alerts": [
|
||||
{
|
||||
"status": "<resolved|firing>",
|
||||
"labels": <object>,
|
||||
"annotations": <object>,
|
||||
"startsAt": "<rfc3339>",
|
||||
"endsAt": "<rfc3339>",
|
||||
"generatorURL": <string>, // identifies the entity that caused the alert
|
||||
"fingerprint": <string> // fingerprint to identify the alert
|
||||
},
|
||||
...
|
||||
]
|
||||
}
|
||||
'''
|
||||
content.body = app.jinja_environment.get_template(config.template_file).render(data)
|
||||
app.logger.debug(content.body)
|
||||
for to in config.to:
|
||||
content['device_key'] = to
|
||||
response = requests.post(
|
||||
url = config.bark_api,
|
||||
headers = {
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
},
|
||||
data=content
|
||||
)
|
||||
app.logger.info(response)
|
||||
return {
|
||||
'success': True,
|
||||
'message': '',
|
||||
'data': {},
|
||||
}
|
||||
except Exception as e:
|
||||
return error_handler(e)
|
||||
|
||||
api.add_resource(BarkResource, '/api/send')
|
12
views/apis/health.py
Normal file
12
views/apis/health.py
Normal file
@ -0,0 +1,12 @@
|
||||
from flask_restful import Resource
|
||||
from app.api import api
|
||||
|
||||
class HealthResource(Resource):
|
||||
def get(self):
|
||||
return {
|
||||
'success': True,
|
||||
'message': '',
|
||||
'data': {},
|
||||
}
|
||||
|
||||
api.add_resource(HealthResource, '/health')
|
Loading…
Reference in New Issue
Block a user