def index(): links = [] for rule in current_app.url_map.iter_rules(): links.append({ "rel": rule.endpoint, "href": absolute_url(rule.rule), "method": ','.join([m for m in rule.methods if m not in ['HEAD', 'OPTIONS']]) }) return jsonify(status="ok", uri=absolute_url(), data={'description':'Alerta API'}, links=sorted(links, key=lambda k: k["href"]))
def send_confirmation(user, hash): msg = MIMEMultipart('related') msg['Subject'] = "[Alerta] Please verify your email '%s'" % user.email msg['From'] = current_app.config['MAIL_FROM'] msg['To'] = user.email msg.preamble = "[Alerta] Please verify your email '%s'" % user.email text = 'Hello {name}!\n\n' \ 'Please verify your email address is {email} by clicking on the link below:\n\n' \ '{url}\n\n' \ 'You\'re receiving this email because you recently created a new Alerta account.' \ ' If this wasn\'t you, please ignore this email.'.format( name=user.name, email=user.email, url=absolute_url('/auth/confirm/' + hash)) msg_text = MIMEText(text, 'plain', 'utf-8') msg.attach(msg_text) try: mx = smtplib.SMTP(current_app.config['SMTP_HOST'], current_app.config['SMTP_PORT']) if current_app.config['DEBUG']: mx.set_debuglevel(True) mx.ehlo() mx.starttls() mx.login(current_app.config['MAIL_FROM'], current_app.config['SMTP_PASSWORD']) mx.sendmail(current_app.config['MAIL_FROM'], [user.email], msg.as_string()) mx.close() except smtplib.SMTPException as e: logging.error('Failed to send email : %s', str(e)) except (socket.error, socket.herror, socket.gaierror) as e: logging.error('Mail server connection error: %s', str(e)) return except Exception as e: logging.error('Unhandled exception: %s', str(e))
def get_topn_flapping(self, query=None, group='event', topn=100): query = query or Query() select = """ WITH topn AS (SELECT * FROM alerts WHERE {where}) SELECT topn.event, COUNT(1) as count, SUM(duplicate_count) AS duplicate_count, array_agg(DISTINCT environment) AS environments, array_agg(DISTINCT svc) AS services, array_agg(DISTINCT ARRAY[topn.id, resource]) AS resources FROM topn, UNNEST (service) svc, UNNEST (history) hist WHERE hist.type='severity' GROUP BY topn.{group} ORDER BY count DESC """.format(where=query.where, group=group) return [{ 'count': t.count, 'duplicateCount': t.duplicate_count, 'environments': t.environments, 'services': t.services, 'event': t.event, 'resources': [{ 'id': r[0], 'resource': r[1], 'href': absolute_url('/alert/%s' % r[0]) } for r in t.resources] } for t in self._fetchall(select, query.vars, limit=topn)]
def serialize(self): data = { 'id': self.id, 'href': absolute_url('/alert/' + self.id), 'resource': self.resource, 'event': self.event, 'environment': self.environment, 'service': self.service, 'group': self.group, 'text': self.text, 'tags': self.tags, 'attributes': self.attributes, 'origin': self.origin, 'updateTime': self.update_time, 'type': self.change_type, 'customer': self.customer } if self.severity: data['severity'] = self.severity data['value'] = self.value if self.status: data['status'] = self.status return data
def serialize(self): return { 'id': self.id, 'href': absolute_url('/perm/' + self.id), 'match': self.match, 'scopes': self.scopes }
def serialize(self): data = { 'id': self.id, 'href': absolute_url('/alert/' + self.id), 'resource': self.resource, 'event': self.event, 'environment': self.environment, 'service': self.service, 'group': self.group, 'text': self.text, 'tags': self.tags, 'attributes': self.attributes, 'origin': self.origin, 'updateTime': self.update_time, 'type': self.event_type, 'customer': self.customer } if self.severity: data['severity'] = self.severity data['value'] = self.value if self.status: data['status'] = self.status return data
def serialize(self): return { 'id': self.id, 'href': absolute_url('/alert/' + self.id), 'resource': self.resource, 'event': self.event, 'environment': self.environment, 'severity': self.severity, 'correlate': self.correlate, 'status': self.status, 'service': self.service, 'group': self.group, 'value': self.value, 'text': self.text, 'tags': self.tags, 'attributes': self.attributes, 'origin': self.origin, 'type': self.event_type, 'createTime': self.create_time, 'timeout': self.timeout, 'rawData': self.raw_data, 'customer': self.customer, 'duplicateCount': self.duplicate_count, 'repeat': self.repeat, 'previousSeverity': self.previous_severity, 'trendIndication': self.trend_indication, 'receiveTime': self.receive_time, 'lastReceiveId': self.last_receive_id, 'lastReceiveTime': self.last_receive_time, 'history': [h.serialize for h in self.history] }
def get_topn_standing(self, query=None, group="event", topn=10): query = query or Query() select = """ WITH topn AS (SELECT * FROM alerts WHERE {where}) SELECT topn.event, COUNT(1) as count, SUM(duplicate_count) AS duplicate_count, SUM(last_receive_time - create_time) as life_time, array_agg(DISTINCT environment) AS environments, array_agg(DISTINCT svc) AS services, array_agg(DISTINCT ARRAY[topn.id, resource]) AS resources FROM topn, UNNEST (service) svc, UNNEST (history) hist WHERE hist.type='severity' GROUP BY topn.{group} ORDER BY life_time DESC """.format(where=query.where, group=group) return [{ "count": t.count, "duplicateCount": t.duplicate_count, "environments": t.environments, "services": t.services, "event": t.event, "resources": [{ "id": r[0], "resource": r[1], "href": absolute_url('/alert/%s' % r[0]) } for r in t.resources] } for t in self._fetchall(select, query.vars, limit=topn)]
def serialize(self): return { 'id': self.id, 'href': absolute_url('/alert/' + self.id), 'resource': self.resource, 'event': self.event, 'environment': self.environment, 'severity': self.severity, 'correlate': self.correlate, 'status': self.status, 'service': self.service, 'group': self.group, 'value': self.value, 'text': self.text, 'tags': self.tags, 'attributes': self.attributes, 'origin': self.origin, 'type': self.event_type, 'createTime': self.create_time, 'timeout': self.timeout, 'rawData': self.raw_data, 'customer': self.customer, 'duplicateCount': self.duplicate_count, 'repeat': self.repeat, 'previousSeverity': self.previous_severity, 'trendIndication': self.trend_indication, 'receiveTime': self.receive_time, 'lastReceiveId': self.last_receive_id, 'lastReceiveTime': self.last_receive_time, 'history': [h.serialize for h in self.history] }
def serialize(self): return { 'id': self.id, 'href': absolute_url('/customer/' + self.id), 'match': self.match, 'customer': self.customer }
def get_topn_count(self, query=None, group="event", topn=10): query = query or Query() select = """ SELECT event, COUNT(1) as count, SUM(duplicate_count) AS duplicate_count, array_agg(DISTINCT environment) AS environments, array_agg(DISTINCT svc) AS services, array_agg(DISTINCT ARRAY[id, resource]) AS resources FROM alerts, UNNEST (service) svc WHERE {where} GROUP BY {group} ORDER BY count DESC """.format(where=query.where, group=group) return [{ "count": t.count, "duplicateCount": t.duplicate_count, "environments": t.environments, "services": t.services, "%s" % group: t.event, "resources": [{ "id": r[0], "resource": r[1], "href": absolute_url('/alert/%s' % r[0]) } for r in t.resources] } for t in self._fetchall(select, query.vars, limit=topn)]
def saml_client(): saml2_config_default = { 'entityid': absolute_url(), 'service': { 'sp': { 'endpoints': { 'assertion_consumer_service': [ (absolute_url('/auth/saml'), saml2.BINDING_HTTP_POST) ] } } } } spConfig().load(deepmerge(saml2_config_default, current_app.config['SAML2_CONFIG'])) return saml2.client.Saml2Client(config=spConfig())
def create_blackout(): try: blackout = Blackout.parse(request.json) except Exception as e: raise ApiError(str(e), 400) if 'admin' in g.scopes or 'admin:blackouts' in g.scopes: blackout.user = blackout.user or g.user else: blackout.user = g.user blackout.customer = assign_customer(wanted=blackout.customer, permission='admin:blackouts') try: blackout = blackout.create() except Exception as e: raise ApiError(str(e), 500) if blackout: return jsonify(status="ok", id=blackout.id, blackout=blackout.serialize), 201, { 'Location': absolute_url('/blackout/' + blackout.id) } else: raise ApiError("insert blackout failed", 500)
def saml_client(): saml2_config_default = { 'entityid': absolute_url(), 'service': { 'sp': { 'endpoints': { 'assertion_consumer_service': [ (absolute_url('/auth/saml'), saml2.BINDING_HTTP_POST) ] } } } } spConfig().load(deepmerge(saml2_config_default, current_app.config['SAML2_CONFIG'])) return saml2.client.Saml2Client(config=spConfig())
def serialize(self): return { 'id': self.id, 'href': absolute_url('/perm/' + self.id), 'match': self.match, 'scopes': self.scopes }
def get_topn_flapping(self, query=None, group="event", topn=10): query = query or Query() select = """ SELECT alerts.event, COUNT(1) as count, SUM(duplicate_count) AS duplicate_count, array_agg(DISTINCT environment) AS environments, array_agg(DISTINCT svc) AS services, array_agg(DISTINCT ARRAY[alerts.id, resource]) AS resources FROM alerts, UNNEST (service) svc, UNNEST (history) hist WHERE hist.type='severity' AND {where} GROUP BY alerts.event ORDER BY count DESC """.format(where=query.where) return [{ "count": t.count, "duplicateCount": t.duplicate_count, "environments": t.environments, "event": t.event, "resources": [{ "id": r[0], "resource": r[1], "href": absolute_url('/alert/%s' % r[0]) } for r in t.resources] } for t in self._fetchall(select, query.vars, limit=topn)]
def get_saml2_config(): config = saml2.config.Config() default_config = { 'entityid': absolute_url(), 'service': { 'sp': { 'endpoints': { 'assertion_consumer_service': [(absolute_url('/auth/saml'), saml2.BINDING_HTTP_POST)] } } } } config.load(deepmerge(default_config, current_app.config['SAML2_CONFIG'])) return config
def send_confirmation(user, hash): smtp_host = current_app.config['SMTP_HOST'] smtp_port = current_app.config['SMTP_PORT'] mail_localhost = current_app.config['MAIL_LOCALHOST'] ssl_key_file = current_app.config['SSL_KEY_FILE'] ssl_cert_file = current_app.config['SSL_CERT_FILE'] mail_from = current_app.config['MAIL_FROM'] smtp_username = current_app.config.get('SMTP_USERNAME', mail_from) smtp_password = current_app.config['SMTP_PASSWORD'] msg = MIMEMultipart('related') msg['Subject'] = "[Alerta] Please verify your email '%s'" % user.email msg['From'] = mail_from msg['To'] = user.email msg.preamble = "[Alerta] Please verify your email '%s'" % user.email text = 'Hello {name}!\n\n' \ 'Please verify your email address is {email} by clicking on the link below:\n\n' \ '{url}\n\n' \ 'You\'re receiving this email because you recently created a new Alerta account.' \ ' If this wasn\'t you, please ignore this email.'.format( name=user.name, email=user.email, url=absolute_url('/auth/confirm/' + hash) ) msg_text = MIMEText(text, 'plain', 'utf-8') msg.attach(msg_text) try: if current_app.config['SMTP_USE_SSL']: mx = smtplib.SMTP_SSL(smtp_host, smtp_port, local_hostname=mail_localhost, keyfile=ssl_key_file, certfile=ssl_cert_file) else: mx = smtplib.SMTP(smtp_host, smtp_port, local_hostname=mail_localhost) if current_app.config['DEBUG']: mx.set_debuglevel(True) mx.ehlo() if current_app.config['SMTP_STARTTLS']: mx.starttls() if smtp_password: mx.login(smtp_username, smtp_password) mx.sendmail(mail_from, [user.email], msg.as_string()) mx.close() except smtplib.SMTPException as e: logging.error('Failed to send email : %s', str(e)) except (socket.error, socket.herror, socket.gaierror) as e: logging.error('Mail server connection error: %s', str(e)) return except Exception as e: logging.error('Unhandled exception: %s', str(e))
def send_confirmation(user, hash): smtp_host = current_app.config['SMTP_HOST'] smtp_port = current_app.config['SMTP_PORT'] mail_localhost = current_app.config['MAIL_LOCALHOST'] ssl_key_file = current_app.config['SSL_KEY_FILE'] ssl_cert_file = current_app.config['SSL_CERT_FILE'] mail_from = current_app.config['MAIL_FROM'] smtp_username = current_app.config.get('SMTP_USERNAME', mail_from) smtp_password = current_app.config['SMTP_PASSWORD'] msg = MIMEMultipart('related') msg['Subject'] = "[Alerta] Please verify your email '%s'" % user.email msg['From'] = mail_from msg['To'] = user.email msg.preamble = "[Alerta] Please verify your email '%s'" % user.email text = 'Hello {name}!\n\n' \ 'Please verify your email address is {email} by clicking on the link below:\n\n' \ '{url}\n\n' \ 'You\'re receiving this email because you recently created a new Alerta account.' \ ' If this wasn\'t you, please ignore this email.'.format( name=user.name, email=user.email, url=absolute_url('/auth/confirm/' + hash) ) msg_text = MIMEText(text, 'plain', 'utf-8') msg.attach(msg_text) try: if current_app.config['SMTP_USE_SSL']: mx = smtplib.SMTP_SSL(smtp_host, smtp_port, local_hostname=mail_localhost, keyfile=ssl_key_file, certfile=ssl_cert_file) else: mx = smtplib.SMTP(smtp_host, smtp_port, local_hostname=mail_localhost) if current_app.config['DEBUG']: mx.set_debuglevel(True) mx.ehlo() if current_app.config['SMTP_STARTTLS']: mx.starttls() if smtp_password: mx.login(smtp_username, smtp_password) mx.sendmail(mail_from, [user.email], msg.as_string()) mx.close() except smtplib.SMTPException as e: logging.error('Failed to send email : %s', str(e)) except (socket.error, socket.herror, socket.gaierror) as e: logging.error('Mail server connection error: %s', str(e)) return except Exception as e: logging.error('Unhandled exception: %s', str(e))
def serialize(self): return { 'id': self.id, 'href': absolute_url('/alert/' + self.id), 'event': self.event, 'severity': self.severity, 'status': self.status, 'value': self.value, 'text': self.text, 'type': self.change_type, 'updateTime': self.update_time }
def serialize(self): return { 'id': self.id, 'href': absolute_url('/alert/' + self.id), 'event': self.event, 'severity': self.severity, 'status': self.status, 'value': self.value, 'text': self.text, 'type': self.change_type, 'updateTime': self.update_time }
def serialize(self): return { 'id': self.id, 'key': self.key, 'href': absolute_url('/key/' + self.key), 'user': self.user, 'scopes': self.scopes, 'type': self.type, 'text': self.text, 'expireTime': self.expire_time, 'count': self.count, 'lastUsedTime': self.last_used_time, 'customer': self.customer }
def serialize(self): return { 'id': self.id, 'key': self.key, 'href': absolute_url('/key/' + self.key), 'user': self.user, 'scopes': self.scopes, 'type': self.type, 'text': self.text, 'expireTime': self.expire_time, 'count': self.count, 'lastUsedTime': self.last_used_time, 'customer': self.customer }
def serialize(self): return { 'id': self.id, 'href': absolute_url('/heartbeat/' + self.id), 'origin': self.origin, 'tags': self.tags, 'type': self.event_type, 'createTime': self.create_time, 'timeout': self.timeout, 'receiveTime': self.receive_time, 'customer': self.customer, 'latency': self.latency, 'since': self.since, 'status': self.status }
def serialize(self): return { 'id': self.id, 'href': absolute_url('/heartbeat/' + self.id), 'origin': self.origin, 'tags': self.tags, 'type': self.event_type, 'createTime': self.create_time, 'timeout': self.timeout, 'receiveTime': self.receive_time, 'customer': self.customer, 'latency': self.latency, 'since': self.since, 'status': self.status }
def serialize(self): return { 'id': self.id, 'href': absolute_url('/user/' + self.id), 'name': self.name, 'email': self.email, 'domain': self.domain, 'provider': 'basic', 'status': self.status, 'roles': self.roles, 'attributes': self.attributes, 'createTime': self.create_time, 'lastLogin': self.last_login, 'text': self.text, 'updateTime': self.update_time, 'email_verified': self.email_verified or False }
def serialize(self): return { 'id': self.id, 'href': absolute_url('/user/' + self.id), 'name': self.name, 'email': self.email, 'domain': self.domain, 'provider': 'basic', 'status': self.status, 'roles': self.roles, 'attributes': self.attributes, 'createTime': self.create_time, 'lastLogin': self.last_login, 'text': self.text, 'updateTime': self.update_time, 'email_verified': self.email_verified or False }
def serialize(self): return { 'id': self.id, 'href': absolute_url('/blackout/' + self.id), 'priority': self.priority, 'environment': self.environment, 'service': self.service, 'resource': self.resource, 'event': self.event, 'group': self.group, 'tags': self.tags, 'customer': self.customer, 'startTime': self.start_time, 'endTime': self.end_time, 'duration': self.duration, 'status': self.status, 'remaining': self.remaining }
def serialize(self): return { 'id': self.id, 'href': absolute_url('/blackout/' + self.id), 'priority': self.priority, 'environment': self.environment, 'service': self.service, 'resource': self.resource, 'event': self.event, 'group': self.group, 'tags': self.tags, 'customer': self.customer, 'startTime': self.start_time, 'endTime': self.end_time, 'duration': self.duration, 'status': self.status, 'remaining': self.remaining }
def get_topn_flapping(self, query=None, group="event", topn=10): query = query or Query() select = """ SELECT alerts.event, COUNT(1) as count, SUM(duplicate_count) AS duplicate_count, array_agg(DISTINCT environment) AS environments, array_agg(DISTINCT svc) AS services, array_agg(DISTINCT ARRAY[alerts.id, resource]) AS resources FROM alerts, UNNEST (service) svc, UNNEST (history) hist WHERE hist.type='severity' AND {where} GROUP BY alerts.event ORDER BY count DESC """.format(where=query.where) return [ { "count": t.count, "duplicateCount": t.duplicate_count, "environments": t.environments, "event": t.event, "resources": [{"id": r[0], "resource": r[1], "href": absolute_url('/alert/%s' % r[0])} for r in t.resources] } for t in self._fetchall(select, query.vars, limit=topn) ]
def build_slack_response(alert, action, user, data): response = json.loads(data['payload']).get('original_message', {}) actions = ['watch', 'unwatch'] message = (u"User {user} is {action}ing alert {alert}" if action in actions else u"The status of alert {alert} is {status} now!").format( alert=alert.get_id(short=True), status=alert.status.capitalize(), action=action, user=user) attachment_response = { "fallback": message, "pretext": "Action done!", "color": "#808080", "title": message, "title_link": absolute_url('/alert/' + alert.id) } # clear interactive buttons and add new attachment as response of action if action not in actions: attachments = response.get('attachments', []) for attachment in attachments: attachment.pop('actions', None) attachments.append(attachment_response) response['attachments'] = attachments return response # update the interactive button of all actions next_action = actions[(actions.index(action) + 1) % len(actions)] for attachment in response.get('attachments', []): for attached_action in attachment.get('actions', []): if action == attached_action.get('value'): attached_action.update({ 'name': next_action, 'value': next_action, 'text': next_action.capitalize() }) return response
def config(): return jsonify({ 'endpoint': absolute_url().rstrip('/'), # FIXME - shouldn't need to rstrip() 'auth_required': current_app.config['AUTH_REQUIRED'], 'customer_views': current_app.config['CUSTOMER_VIEWS'], 'provider': current_app.config['AUTH_PROVIDER'], 'signup_enabled': current_app.config['SIGNUP_ENABLED'], 'client_id': current_app.config['OAUTH2_CLIENT_ID'], 'github_url': current_app.config['GITHUB_URL'], 'gitlab_url': current_app.config['GITLAB_URL'], 'keycloak_url': current_app.config['KEYCLOAK_URL'], 'keycloak_realm': current_app.config['KEYCLOAK_REALM'], 'pingfederate_url': current_app.config['PINGFEDERATE_URL'], 'colors': current_app.config['COLOR_MAP'], 'severity': current_app.config['SEVERITY_MAP'], 'dates': { 'shortTime': 'shortTime', # 1:39 PM 'mediumDate': 'medium', # Apr 26, 2016 1:39:44 PM 'longDate': 'EEEE, MMMM d, yyyy h:mm:ss.sss a (Z)' # Tuesday, April 26, 2016 1:39:43.987 PM (+0100) }, 'audio': {}, # not supported yet 'tracking_id': current_app.config['GOOGLE_TRACKING_ID'], 'refresh_interval': current_app.config['AUTO_REFRESH_INTERVAL'] })
def create_blackout(): try: blackout = Blackout.parse(request.json) except Exception as e: raise ApiError(str(e), 400) if g.get('customer', None): blackout.customer = g.get('customer') try: blackout = blackout.create() except Exception as e: raise ApiError(str(e), 500) if blackout: return jsonify(status="ok", id=blackout.id, blackout=blackout.serialize), 201, { 'Location': absolute_url('/blackout/' + blackout.id) } else: raise ApiError("insert blackout failed", 500)
def build_slack_response(alert, action, user, data): response = json.loads(data['payload']).get('original_message', {}) actions = ['watch', 'unwatch'] message = ( u"User {user} is {action}ing alert {alert}" if action in actions else u"The status of alert {alert} is {status} now!").format( alert=alert.get_id(short=True), status=alert.status.capitalize(), action=action, user=user ) attachment_response = { "fallback": message, "pretext": "Action done!", "color": "#808080", "title": message, "title_link": absolute_url('/alert/' + alert.id) } # clear interactive buttons and add new attachment as response of action if action not in actions: attachments = response.get('attachments', []) for attachment in attachments: attachment.pop('actions', None) attachments.append(attachment_response) response['attachments'] = attachments return response # update the interactive button of all actions next_action = actions[(actions.index(action) + 1) % len(actions)] for attachment in response.get('attachments', []): for attached_action in attachment.get('actions', []): if action == attached_action.get('value'): attached_action.update({ 'name': next_action, 'value': next_action, 'text': next_action.capitalize() }) return response
def create_blackout(): try: blackout = Blackout.parse(request.json) except Exception as e: raise ApiError(str(e), 400) if g.get('customer', None): blackout.customer = g.get('customer') try: blackout = blackout.create() except Exception as e: raise ApiError(str(e), 500) if blackout: return jsonify(status="ok", id=blackout.id, blackout=blackout.serialize), 201, {'Location': absolute_url('/blackout/' + blackout.id)} else: raise ApiError("insert blackout failed", 500)