__init__.py
244 lines
| 9.4 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() | ||||
dummy_report.error = "ProtocolError: ('Connection aborted.', " \ | ||||
"error(111, 'Connection refused'))" | ||||
dummy_report.total_reports = 4 | ||||
dummy_report.occurences = 4 | ||||
dummy_report2 = ReportGroup() | ||||
dummy_report2.error = "UnboundLocalError: local variable " \ | ||||
"'hits' referenced before assignment" | ||||
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 | ||||
integration_name = request.matchdict['integration'] | ||||
integration = IntegrationBase.by_app_id_and_integration_name( | ||||
resource.resource_id, integration_name) | ||||
if integration: | ||||
dict_config = integration.config | ||||
else: | ||||
dict_config = {} | ||||
self.integration = integration | ||||
self.integration_config = dict_config | ||||
@view_config(route_name='integrations_id', | ||||
request_method="DELETE", | ||||
renderer='json', | ||||
permission='edit') | ||||
def remove_integration(self): | ||||
if self.integration: | ||||
DBSession.delete(self.integration) | ||||
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') | ||||
def test_report_notification(self): | ||||
if not self.integration: | ||||
self.request.session.flash('Integration needs to be configured', | ||||
'warning') | ||||
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)] | ||||
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') | ||||
return True | ||||
@view_config(route_name='integrations_id', | ||||
request_method="POST", | ||||
match_param=['action=test_error_alert'], | ||||
renderer='json', | ||||
permission='edit') | ||||
def test_error_alert(self): | ||||
if not self.integration: | ||||
self.request.session.flash('Integration needs to be configured', | ||||
'warning') | ||||
return False | ||||
resource = self.integration.resource | ||||
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} | ||||
) | ||||
channel = AlertChannelService.by_integration_id(self.integration.id) | ||||
channel.notify_alert(resource=resource, | ||||
event=new_event, | ||||
user=self.request.user, | ||||
request=self.request) | ||||
self.request.session.flash('Notification sent') | ||||
return True | ||||
@view_config(route_name='integrations_id', | ||||
request_method="POST", | ||||
match_param=['action=test_daily_digest'], | ||||
renderer='json', | ||||
permission='edit') | ||||
def test_daily_digest(self): | ||||
if not self.integration: | ||||
self.request.session.flash('Integration needs to be configured', | ||||
'warning') | ||||
return False | ||||
resource = self.integration.resource | ||||
channel = AlertChannelService.by_integration_id(self.integration.id) | ||||
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') | ||||
return True | ||||
@view_config(route_name='integrations_id', | ||||
request_method="POST", | ||||
match_param=['action=test_uptime_alert'], | ||||
renderer='json', | ||||
permission='edit') | ||||
def test_uptime_alert(self): | ||||
if not self.integration: | ||||
self.request.session.flash('Integration needs to be configured', | ||||
'warning') | ||||
return False | ||||
resource = self.integration.resource | ||||
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}) | ||||
channel = AlertChannelService.by_integration_id(self.integration.id) | ||||
channel.notify_uptime_alert(resource=resource, | ||||
event=new_event, | ||||
user=self.request.user, | ||||
request=self.request) | ||||
self.request.session.flash('Notification sent') | ||||
return True | ||||
@view_config(route_name='integrations_id', | ||||
request_method="POST", | ||||
match_param=['action=test_chart_alert'], | ||||
renderer='json', | ||||
permission='edit') | ||||
def test_chart_alert(self): | ||||
if not self.integration: | ||||
self.request.session.flash('Integration needs to be configured', | ||||
'warning') | ||||
return False | ||||
resource = self.integration.resource | ||||
chart_values = { | ||||
"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"}}, | ||||
"start_interval": datetime.utcnow(), | ||||
"resource": 1, | ||||
"chart_name": "Fraud attempts per day", | ||||
"chart_uuid": "some_uuid", | ||||
"step_size": 3600, | ||||
"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()) | ||||
channel = AlertChannelService.by_integration_id(self.integration.id) | ||||
channel.notify_chart_alert(resource=resource, | ||||
event=new_event, | ||||
user=self.request.user, | ||||
request=self.request) | ||||
self.request.session.flash('Notification sent') | ||||
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) | ||||
channel.channel_json_conf = {'security_code': security_code} | ||||
resource.owner.alert_channels.append(channel) | ||||