__init__.py
266 lines
| 8.6 KiB
| text/x-python
|
PythonLexer
r0 | # -*- coding: utf-8 -*- | |||
r112 | # Copyright 2010 - 2017 RhodeCode GmbH and the AppEnlight project authors | |||
r0 | # | |||
r112 | # Licensed under the Apache License, Version 2.0 (the "License"); | |||
# you may not use this file except in compliance with the License. | ||||
# You may obtain a copy of the License at | ||||
r0 | # | |||
r112 | # http://www.apache.org/licenses/LICENSE-2.0 | |||
r0 | # | |||
r112 | # Unless required by applicable law or agreed to in writing, software | |||
# distributed under the License is distributed on an "AS IS" BASIS, | ||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
# See the License for the specific language governing permissions and | ||||
# limitations under the License. | ||||
r0 | ||||
import logging | ||||
import random | ||||
from datetime import datetime | ||||
from pyramid.httpexceptions import HTTPFound | ||||
from pyramid.view import view_config | ||||
from appenlight.models import DBSession | ||||
from appenlight.models.event import Event | ||||
from appenlight.models.integrations import IntegrationBase | ||||
from appenlight.models.alert_channel import AlertChannel | ||||
from appenlight.models.report_group import ReportGroup | ||||
from appenlight.models.services.alert_channel import AlertChannelService | ||||
from appenlight.lib import generate_random_string | ||||
log = logging.getLogger(__name__) | ||||
dummy_report = ReportGroup() | ||||
r153 | dummy_report.error = ( | |||
"ProtocolError: ('Connection aborted.', " "error(111, 'Connection refused'))" | ||||
) | ||||
r0 | dummy_report.total_reports = 4 | |||
dummy_report.occurences = 4 | ||||
dummy_report2 = ReportGroup() | ||||
r153 | dummy_report2.error = ( | |||
"UnboundLocalError: local variable " "'hits' referenced before assignment" | ||||
) | ||||
r0 | dummy_report2.total_reports = 8 | |||
dummy_report2.occurences = 8 | ||||
dummy_reports = [(4, dummy_report), (8, dummy_report2)] | ||||
class IntegrationView(object): | ||||
""" | ||||
Base class for 3rd party integrations setup views | ||||
""" | ||||
def __init__(self, request): | ||||
self.request = request | ||||
resource = self.request.context.resource | ||||
r153 | integration_name = request.matchdict["integration"] | |||
r0 | integration = IntegrationBase.by_app_id_and_integration_name( | |||
r153 | resource.resource_id, integration_name | |||
) | ||||
r0 | if integration: | |||
dict_config = integration.config | ||||
else: | ||||
dict_config = {} | ||||
self.integration = integration | ||||
self.integration_config = dict_config | ||||
r153 | @view_config( | |||
route_name="integrations_id", | ||||
request_method="DELETE", | ||||
renderer="json", | ||||
permission="edit", | ||||
) | ||||
r0 | def remove_integration(self): | |||
if self.integration: | ||||
DBSession.delete(self.integration) | ||||
r153 | self.request.session.flash("Integration removed") | |||
return "" | ||||
@view_config( | ||||
route_name="integrations_id", | ||||
request_method="POST", | ||||
match_param=["action=test_report_notification"], | ||||
renderer="json", | ||||
permission="edit", | ||||
) | ||||
r0 | def test_report_notification(self): | |||
if not self.integration: | ||||
r153 | self.request.session.flash("Integration needs to be configured", "warning") | |||
r0 | return False | |||
resource = self.integration.resource | ||||
channel = AlertChannelService.by_integration_id(self.integration.id) | ||||
if random.random() < 0.5: | ||||
confirmed_reports = dummy_reports | ||||
else: | ||||
confirmed_reports = [random.choice(dummy_reports)] | ||||
r153 | channel.notify_reports( | |||
resource=resource, | ||||
user=self.request.user, | ||||
request=self.request, | ||||
since_when=datetime.utcnow(), | ||||
reports=confirmed_reports, | ||||
) | ||||
self.request.session.flash("Report notification sent") | ||||
r0 | return True | |||
r153 | @view_config( | |||
route_name="integrations_id", | ||||
request_method="POST", | ||||
match_param=["action=test_error_alert"], | ||||
renderer="json", | ||||
permission="edit", | ||||
) | ||||
r0 | def test_error_alert(self): | |||
if not self.integration: | ||||
r153 | self.request.session.flash("Integration needs to be configured", "warning") | |||
r0 | return False | |||
resource = self.integration.resource | ||||
r153 | event_name = random.choice(("error_report_alert", "slow_report_alert")) | |||
new_event = Event( | ||||
resource_id=resource.resource_id, | ||||
event_type=Event.types[event_name], | ||||
start_date=datetime.utcnow(), | ||||
status=Event.statuses["active"], | ||||
values={"reports": random.randint(11, 99), "threshold": 10}, | ||||
) | ||||
r0 | ||||
channel = AlertChannelService.by_integration_id(self.integration.id) | ||||
r153 | channel.notify_alert( | |||
resource=resource, | ||||
event=new_event, | ||||
user=self.request.user, | ||||
request=self.request, | ||||
) | ||||
self.request.session.flash("Notification sent") | ||||
r0 | return True | |||
r153 | @view_config( | |||
route_name="integrations_id", | ||||
request_method="POST", | ||||
match_param=["action=test_daily_digest"], | ||||
renderer="json", | ||||
permission="edit", | ||||
) | ||||
r0 | def test_daily_digest(self): | |||
if not self.integration: | ||||
r153 | self.request.session.flash("Integration needs to be configured", "warning") | |||
r0 | return False | |||
resource = self.integration.resource | ||||
channel = AlertChannelService.by_integration_id(self.integration.id) | ||||
r153 | channel.send_digest( | |||
resource=resource, | ||||
user=self.request.user, | ||||
request=self.request, | ||||
since_when=datetime.utcnow(), | ||||
reports=dummy_reports, | ||||
) | ||||
self.request.session.flash("Notification sent") | ||||
r0 | return True | |||
r153 | @view_config( | |||
route_name="integrations_id", | ||||
request_method="POST", | ||||
match_param=["action=test_uptime_alert"], | ||||
renderer="json", | ||||
permission="edit", | ||||
) | ||||
r0 | def test_uptime_alert(self): | |||
if not self.integration: | ||||
r153 | self.request.session.flash("Integration needs to be configured", "warning") | |||
r0 | return False | |||
resource = self.integration.resource | ||||
r153 | new_event = Event( | |||
resource_id=resource.resource_id, | ||||
event_type=Event.types["uptime_alert"], | ||||
start_date=datetime.utcnow(), | ||||
status=Event.statuses["active"], | ||||
values={"status_code": 500, "tries": 2, "response_time": 0}, | ||||
) | ||||
r0 | ||||
channel = AlertChannelService.by_integration_id(self.integration.id) | ||||
r153 | channel.notify_uptime_alert( | |||
resource=resource, | ||||
event=new_event, | ||||
user=self.request.user, | ||||
request=self.request, | ||||
) | ||||
self.request.session.flash("Notification sent") | ||||
r0 | return True | |||
r153 | @view_config( | |||
route_name="integrations_id", | ||||
request_method="POST", | ||||
match_param=["action=test_chart_alert"], | ||||
renderer="json", | ||||
permission="edit", | ||||
) | ||||
r0 | def test_chart_alert(self): | |||
if not self.integration: | ||||
r153 | self.request.session.flash("Integration needs to be configured", "warning") | |||
r0 | return False | |||
resource = self.integration.resource | ||||
chart_values = { | ||||
r153 | "matched_rule": {"name": "Fraud attempt limit"}, | |||
"matched_step_values": { | ||||
"labels": {"0_1": {"human_label": "Attempts sum"}}, | ||||
"values": {"0_1": random.randint(11, 55), "key": "2015-12-16T15:49:00"}, | ||||
}, | ||||
r0 | "start_interval": datetime.utcnow(), | |||
"resource": 1, | ||||
"chart_name": "Fraud attempts per day", | ||||
"chart_uuid": "some_uuid", | ||||
"step_size": 3600, | ||||
r153 | "action_name": "Notify excessive fraud attempts", | |||
} | ||||
new_event = Event( | ||||
resource_id=resource.resource_id, | ||||
event_type=Event.types["chart_alert"], | ||||
status=Event.statuses["active"], | ||||
values=chart_values, | ||||
target_uuid="some_uuid", | ||||
start_date=datetime.utcnow(), | ||||
) | ||||
r0 | ||||
channel = AlertChannelService.by_integration_id(self.integration.id) | ||||
r153 | channel.notify_chart_alert( | |||
resource=resource, | ||||
event=new_event, | ||||
user=self.request.user, | ||||
request=self.request, | ||||
) | ||||
self.request.session.flash("Notification sent") | ||||
r0 | return True | |||
def create_missing_channel(self, resource, channel_name): | ||||
""" | ||||
Recreates alert channel for the owner of integration | ||||
""" | ||||
if self.integration: | ||||
if not self.integration.channel: | ||||
channel = AlertChannel() | ||||
channel.channel_name = channel_name | ||||
channel.channel_validated = True | ||||
channel.channel_value = resource.resource_id | ||||
channel.integration_id = self.integration.id | ||||
security_code = generate_random_string(10) | ||||
r153 | channel.channel_json_conf = {"security_code": security_code} | |||
r0 | resource.owner.alert_channels.append(channel) | |||