Пример #1
0
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,
        )
Пример #2
0
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
Пример #3
0
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)
Пример #4
0
 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
         },
     )
Пример #5
0
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
Пример #6
0
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,
        )
Пример #7
0
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)
Пример #8
0
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)
Пример #9
0
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
Пример #10
0
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)