def handle_reaction_added_event( user_email: str, incident_id: int, event: dict = None, db_session=None ): """Handles an event where a reaction is added to a message.""" reaction = event.event.reaction if reaction == SLACK_TIMELINE_EVENT_REACTION: conversation_id = event.event.item.channel message_ts = event.event.item.ts message_ts_utc = datetime.datetime.utcfromtimestamp(float(message_ts)) # we fetch the message information response = dispatch_slack_service.list_conversation_messages( slack_client, conversation_id, latest=message_ts, limit=1, inclusive=1 ) message_text = response["messages"][0]["text"] message_sender_id = response["messages"][0]["user"] # we fetch the individual who sent the message message_sender_email = get_user_email(client=slack_client, user_id=message_sender_id) individual = individual_service.get_by_email( db_session=db_session, email=message_sender_email ) convo_plugin = plugins.get(INCIDENT_PLUGIN_CONVERSATION_SLUG) # we log the event event_service.log( db_session=db_session, source=convo_plugin.title, description=f'"{message_text}," said {individual.name}', incident_id=incident_id, individual_id=individual.id, started_at=message_ts_utc, )
def test_get_or_create(session, individual_contact): from dispatch.individual.service import create, get_by_email from dispatch.individual.models import IndividualContactCreate contact = get_by_email(db_session=session, email=individual_contact.email) if not contact: name = "Joe Smith" title = "Engineer" email = "*****@*****.**" mobile_phone = "111-111-1111" office_phone = "111-111-1111" weblink = "https://www.example.com/" individual_contact_in = IndividualContactCreate( name=name, title=title, email=email, mobile_phone=mobile_phone, office_phone=office_phone, weblink=weblink, ) individual_contact = create( db_session=session, individual_contact_in=individual_contact_in) contact = create(db_session=session, individual_contact_in=individual_contact_in) assert contact
def incident_update_flow( user_email: str, incident_id: int, previous_incident: IncidentRead, notify=True, db_session=None ): """Runs the incident update flow.""" # we load the incident instance incident = incident_service.get(db_session=db_session, incident_id=incident_id) # we load the individual individual = individual_service.get_by_email(db_session=db_session, email=user_email) # run whatever flows we need status_flow_dispatcher( incident, incident.status, previous_incident.status.value, db_session=db_session ) conversation_topic_dispatcher(incident, previous_incident, individual, db_session=db_session) # we update the external ticket update_external_incident_ticket(incident, db_session) # add new folks to the incident if appropriate resolve_incident_participants(incident, db_session) if notify: send_incident_update_notifications(incident, previous_incident, db_session)
def get(self, email, db_session=None): return getattr( individual_service.get_by_email(db_session=db_session, email=email), "__dict__", { "email": email, "fullname": email }, )
def incident_engage_oncall_flow( user_email: str, incident_id: int, oncall_service_id: str, page=None, db_session=None ): """Runs the incident engage oncall flow.""" # we load the incident instance incident = incident_service.get(db_session=db_session, incident_id=incident_id) # we resolve the oncall service oncall_service = service_service.get_by_external_id( db_session=db_session, external_id=oncall_service_id ) # we get the active oncall plugin oncall_plugin = plugin_service.get_active(db_session=db_session, plugin_type="oncall") if oncall_plugin: if oncall_plugin.slug != oncall_service.type: log.warning( f"Unable to engage the oncall. Oncall plugin enabled not of type {oncall_plugin.slug}." ) return None, None else: log.warning("Unable to engage the oncall. No oncall plugins enabled.") return None, None oncall_email = oncall_plugin.instance.get(service_id=oncall_service_id) # we add the oncall to the incident incident_add_or_reactivate_participant_flow(oncall_email, incident.id, db_session=db_session) # we load the individual individual = individual_service.get_by_email(db_session=db_session, email=oncall_email) event_service.log( db_session=db_session, source=oncall_plugin.title, description=f"{individual.name} engages oncall service {oncall_service.name}", incident_id=incident.id, ) if page == "Yes": # we page the oncall oncall_plugin.instance.page( oncall_service_id, incident.name, incident.title, incident.description ) event_service.log( db_session=db_session, source=oncall_plugin.title, description=f"{oncall_service.name} on-call paged", incident_id=incident.id, ) return individual, oncall_service
def incident_engage_oncall_flow(user_id: str, user_email: str, incident_id: int, action: dict, db_session=None): """Runs the incident engage oncall flow.""" oncall_service_id = action["submission"]["oncall_service_id"] page = action["submission"]["page"] # we load the incident instance incident = incident_service.get(db_session=db_session, incident_id=incident_id) # we resolve the oncall service oncall_service = service_service.get_by_external_id( db_session=db_session, external_id=oncall_service_id) oncall_plugin = plugins.get(oncall_service.type) oncall_email = oncall_plugin.get(service_id=oncall_service_id) # we add the oncall to the incident incident_add_or_reactivate_participant_flow(oncall_email, incident.id, db_session=db_session) # we load the individual individual = individual_service.get_by_email(db_session=db_session, email=user_email) event_service.log( db_session=db_session, source=oncall_plugin.title, description= f"{individual.name} engages oncall service {oncall_service.name}", incident_id=incident.id, ) if page == "Yes": # we page the oncall oncall_plugin.page(oncall_service_id, incident.name, incident.title, incident.description) event_service.log( db_session=db_session, source=oncall_plugin.title, description=f"{oncall_service.name} on-call paged", incident_id=incident.id, )
def incident_update_flow( user_email: str, incident_id: int, previous_incident: IncidentRead, notify=True, db_session=None ): """Runs the incident update flow.""" # we load the incident instance incident = incident_service.get(db_session=db_session, incident_id=incident_id) # we load the individual individual = individual_service.get_by_email(db_session=db_session, email=user_email) # run whatever flows we need status_flow_dispatcher( incident, incident.status, previous_incident.status.value, db_session=db_session ) conversation_topic_dispatcher(incident, previous_incident, individual, db_session=db_session) # we update the external ticket update_external_incident_ticket(incident, db_session) # add new folks to the incident if appropriate # we only have to do this for teams as new members will be added to tactical # groups on incident join individual_participants, team_participants = get_incident_participants(incident, db_session) for individual, service in individual_participants: incident_add_or_reactivate_participant_flow( individual.email, incident.id, service=service, db_session=db_session ) # we add the team distributions lists to the notifications group group_plugin = plugin_service.get_active(db_session=db_session, plugin_type="participant-group") if group_plugin: team_participant_emails = [x.email for x in team_participants] group_plugin.instance.add(incident.notifications_group.email, team_participant_emails) if notify: send_incident_update_notifications(incident, previous_incident, db_session)
def incident_update_flow( user_email: str, incident_id: int, previous_incident: IncidentRead, notify=True, db_session=None ): """Runs the incident update flow.""" # we load the incident instance incident = incident_service.get(db_session=db_session, incident_id=incident_id) # we load the individual individual = individual_service.get_by_email(db_session=db_session, email=user_email) conversation_topic_change = False if previous_incident.title != incident.title: event_service.log( db_session=db_session, source="Incident Participant", description=f'{individual.name} changed the incident title to "{incident.title}"', incident_id=incident.id, individual_id=individual.id, ) if previous_incident.description != incident.description: event_service.log( db_session=db_session, source="Incident Participant", description=f"{individual.name} changed the incident description", details={"description": incident.description}, incident_id=incident.id, individual_id=individual.id, ) if previous_incident.incident_type.name != incident.incident_type.name: conversation_topic_change = True event_service.log( db_session=db_session, source="Incident Participant", description=f"{individual.name} changed the incident type to {incident.incident_type.name}", incident_id=incident.id, individual_id=individual.id, ) if previous_incident.incident_priority.name != incident.incident_priority.name: conversation_topic_change = True event_service.log( db_session=db_session, source="Incident Participant", description=f"{individual.name} changed the incident priority to {incident.incident_priority.name}", incident_id=incident.id, individual_id=individual.id, ) if previous_incident.status.value != incident.status: conversation_topic_change = True event_service.log( db_session=db_session, source="Incident Participant", description=f"{individual.name} marked the incident as {incident.status}", incident_id=incident.id, individual_id=individual.id, ) if conversation_topic_change: if incident.status != IncidentStatus.closed: set_conversation_topic(incident, db_session) if notify: send_incident_update_notifications(incident, previous_incident, db_session) # we update the external ticket update_external_incident_ticket(incident, db_session) log.debug(f"Updated the external ticket {incident.ticket.resource_id}.") # get the incident participants based on incident type and priority individual_participants, team_participants = get_incident_participants(incident, db_session) # lets not attempt to add new participants for non-active incidents (it's confusing) if incident.status == IncidentStatus.active: # we add the individuals as incident participants for individual in individual_participants: incident_add_or_reactivate_participant_flow( individual.email, incident.id, db_session=db_session ) team_participant_emails = [x.email for x in team_participants] # we add the team distributions lists to the notifications group group_plugin = plugin_service.get_active(db_session=db_session, plugin_type="participant-group") if group_plugin: group_plugin.instance.add(incident.notifications_group.email, team_participant_emails) if previous_incident.status.value != incident.status: if incident.status == IncidentStatus.active: incident_active_flow(incident_id=incident.id, db_session=db_session) elif incident.status == IncidentStatus.stable: incident_stable_flow(incident_id=incident.id, db_session=db_session) elif incident.status == IncidentStatus.closed: if previous_incident.status.value == IncidentStatus.active: incident_stable_flow(incident_id=incident.id, db_session=db_session) incident_closed_flow(incident_id=incident.id, db_session=db_session)
def test_get_by_email(session, individual_contact): from dispatch.individual.service import get_by_email t_individual_contact = get_by_email(db_session=session, email=individual_contact.email) assert t_individual_contact.email == individual_contact.email
def incident_update_flow(user_email: str, incident_id: int, previous_incident: IncidentRead, notify=True, db_session=None): """Runs the incident update flow.""" conversation_topic_change = False # we load the incident instance incident = incident_service.get(db_session=db_session, incident_id=incident_id) # we load the individual individual = individual_service.get_by_email(db_session=db_session, email=user_email) if previous_incident.title != incident.title: event_service.log( db_session=db_session, source="Incident Participant", description= f'{individual.name} changed the incident title to "{incident.title}"', incident_id=incident.id, individual_id=individual.id, ) if previous_incident.description != incident.description: event_service.log( db_session=db_session, source="Incident Participant", description=f"{individual.name} changed the incident description", details={"description": incident.description}, incident_id=incident.id, individual_id=individual.id, ) if previous_incident.incident_type.name != incident.incident_type.name: conversation_topic_change = True event_service.log( db_session=db_session, source="Incident Participant", description= f"{individual.name} changed the incident type to {incident.incident_type.name}", incident_id=incident.id, individual_id=individual.id, ) if previous_incident.incident_priority.name != incident.incident_priority.name: conversation_topic_change = True event_service.log( db_session=db_session, source="Incident Participant", description= f"{individual.name} changed the incident priority to {incident.incident_priority.name}", incident_id=incident.id, individual_id=individual.id, ) if previous_incident.status.value != incident.status: conversation_topic_change = True event_service.log( db_session=db_session, source="Incident Participant", description= f"{individual.name} marked the incident as {incident.status}", incident_id=incident.id, individual_id=individual.id, ) if conversation_topic_change: # we update the conversation topic set_conversation_topic(incident) if notify: send_incident_update_notifications(incident, previous_incident) # we get the incident document incident_document = get_document( db_session=db_session, incident_id=incident_id, resource_type=INCIDENT_RESOURCE_INVESTIGATION_DOCUMENT, ) # we update the external ticket update_incident_ticket( db_session, incident.ticket.resource_id, title=incident.title, description=incident.description, incident_type=incident.incident_type.name, priority=incident.incident_priority.name, commander_email=incident.commander.email, conversation_weblink=incident.conversation.weblink, conference_weblink=incident.conference.weblink, document_weblink=incident_document.weblink, storage_weblink=incident.storage.weblink, visibility=incident.visibility, ) log.debug(f"Updated the external ticket {incident.ticket.resource_id}.") # get the incident participants based on incident type and priority individual_participants, team_participants = get_incident_participants( incident, db_session) # lets not attempt to add new participants for non-active incidents (it's confusing) if incident.status == IncidentStatus.active: # we add the individuals as incident participants for individual in individual_participants: incident_add_or_reactivate_participant_flow(individual.email, incident.id, db_session=db_session) # we get the notification group notification_group = group_service.get_by_incident_id_and_resource_type( db_session=db_session, incident_id=incident.id, resource_type=INCIDENT_RESOURCE_NOTIFICATIONS_GROUP, ) team_participant_emails = [x.email for x in team_participants] # we add the team distributions lists to the notifications group group_plugin = plugins.get(INCIDENT_PLUGIN_GROUP_SLUG) group_plugin.add(notification_group.email, team_participant_emails) if previous_incident.status.value != incident.status: if incident.status == IncidentStatus.active: incident_active_flow(incident_id=incident.id, db_session=db_session) elif incident.status == IncidentStatus.stable: incident_stable_flow(incident_id=incident.id, db_session=db_session) elif incident.status == IncidentStatus.closed: if previous_incident.status.value == IncidentStatus.active: incident_stable_flow(incident_id=incident.id, db_session=db_session) incident_closed_flow(incident_id=incident.id, db_session=db_session)