Esempio n. 1
0
def send_welcome_email_to_participant(participant_email: str,
                                      incident: Incident,
                                      db_session: SessionLocal):
    """Sends a welcome email to the participant."""
    # we get the incident documents
    incident_document = get_document(
        db_session=db_session,
        incident_id=incident.id,
        resource_type=INCIDENT_RESOURCE_INVESTIGATION_DOCUMENT,
    )

    incident_faq = get_document(
        db_session=db_session,
        incident_id=incident.id,
        resource_type=INCIDENT_RESOURCE_FAQ_DOCUMENT,
    )

    email_plugin = plugins.get(INCIDENT_PLUGIN_EMAIL_SLUG)
    email_plugin.send(
        participant_email,
        INCIDENT_PARTICIPANT_WELCOME_MESSAGE,
        MessageType.incident_participant_welcome,
        name=incident.name,
        title=incident.title,
        status=incident.status,
        priority=incident.incident_priority.name,
        commander_fullname=incident.commander.name,
        commander_weblink=incident.commander.weblink,
        document_weblink=incident_document.weblink,
        storage_weblink=incident.storage.weblink,
        ticket_weblink=incident.ticket.weblink,
        faq_weblink=incident_faq.weblink,
    )

    log.debug(f"Welcome email sent to {participant_email}.")
Esempio n. 2
0
def send_incident_resources_ephemeral_message_to_participant(
        user_id: str, incident: Incident, db_session: SessionLocal):
    """Sends the list of incident resources to the participant via an ephemeral message."""
    # we get the incident documents
    incident_document = get_document(
        db_session=db_session,
        incident_id=incident.id,
        resource_type=INCIDENT_RESOURCE_INVESTIGATION_DOCUMENT,
    )

    incident_faq = get_document(
        db_session=db_session,
        incident_id=incident.id,
        resource_type=INCIDENT_RESOURCE_FAQ_DOCUMENT,
    )

    # we send the ephemeral message
    convo_plugin = plugins.get(INCIDENT_PLUGIN_CONVERSATION_SLUG)
    convo_plugin.send_ephemeral(
        incident.conversation.channel_id,
        user_id,
        "Incident Resources Message",
        INCIDENT_RESOURCES_MESSAGE,
        MessageType.incident_resources_message,
        commander_fullname=incident.commander.name,
        commander_weblink=incident.commander.weblink,
        document_weblink=incident_document.weblink,
        storage_weblink=incident.storage.weblink,
        faq_weblink=incident_faq.weblink,
    )

    log.debug(
        f"List of incident resources sent to {user_id} via ephemeral message.")
Esempio n. 3
0
def send_incident_status_notifications(incident: Incident,
                                       db_session: SessionLocal):
    """Sends incident status notifications to conversations and distribution lists."""
    notification_text = "Incident Notification"
    notification_type = MessageType.incident_notification
    message_template = INCIDENT_NOTIFICATION

    # we get the incident documents
    incident_document = get_document(
        db_session=db_session,
        incident_id=incident.id,
        resource_type=INCIDENT_RESOURCE_INVESTIGATION_DOCUMENT,
    )

    incident_faq = get_document(db_session=db_session,
                                incident_id=incident.id,
                                resource_type=INCIDENT_RESOURCE_FAQ_DOCUMENT)

    # we send status notifications to conversations
    convo_plugin = plugins.get(INCIDENT_PLUGIN_CONVERSATION_SLUG)
    for conversation in INCIDENT_NOTIFICATION_CONVERSATIONS:
        convo_plugin.send(
            conversation,
            notification_text,
            message_template,
            notification_type,
            name=incident.name,
            title=incident.title,
            status=incident.status,
            priority=incident.incident_priority.name,
            commander_fullname=incident.commander.name,
            commander_weblink=incident.commander.weblink,
            document_weblink=incident_document.weblink,
            storage_weblink=incident.storage.weblink,
            ticket_weblink=incident.ticket.weblink,
            faq_weblink=incident_faq.weblink,
            incident_id=incident.id,
        )

    # we send status notifications to distribution lists
    email_plugin = plugins.get(INCIDENT_PLUGIN_EMAIL_SLUG)
    for distro in INCIDENT_NOTIFICATION_DISTRIBUTION_LISTS:
        email_plugin.send(
            distro,
            message_template,
            notification_type,
            name=incident.name,
            title=incident.title,
            status=incident.status,
            priority=incident.incident_priority.name,
            commander_fullname=incident.commander.name,
            commander_weblink=incident.commander.weblink,
            document_weblink=incident_document.weblink,
            storage_weblink=incident.storage.weblink,
            ticket_weblink=incident.ticket.weblink,
            faq_weblink=incident_faq.weblink,
            incident_id=incident.id,
        )

    log.debug(f"Incident status notifications sent.")
Esempio n. 4
0
def send_welcome_ephemeral_message_to_participant(participant_email: str,
                                                  incident_id: int,
                                                  db_session: SessionLocal):
    """Sends an ephemeral message to the participant."""
    # we load the incident instance
    incident = incident_service.get(db_session=db_session,
                                    incident_id=incident_id)

    # we get the incident documents
    incident_document = get_document(
        db_session=db_session,
        incident_id=incident_id,
        resource_type=INCIDENT_RESOURCE_INVESTIGATION_DOCUMENT,
    )

    incident_faq = get_document(db_session=db_session,
                                incident_id=incident_id,
                                resource_type=INCIDENT_RESOURCE_FAQ_DOCUMENT)

    incident_conversation_commands_reference_document = get_document(
        db_session=db_session,
        incident_id=incident_id,
        resource_type=
        INCIDENT_RESOURCE_CONVERSATION_COMMANDS_REFERENCE_DOCUMENT,
    )

    # we send the ephemeral message
    convo_plugin = plugins.get(INCIDENT_PLUGIN_CONVERSATION_SLUG)
    convo_plugin.send_ephemeral(
        incident.conversation.channel_id,
        participant_email,
        "Incident Welcome Message",
        INCIDENT_PARTICIPANT_WELCOME_MESSAGE,
        MessageType.incident_participant_welcome,
        name=incident.name,
        title=incident.title,
        status=incident.status,
        type=incident.incident_type.name,
        type_description=incident.incident_type.description,
        priority=incident.incident_priority.name,
        priority_description=incident.incident_priority.description,
        commander_fullname=incident.commander.name,
        commander_weblink=incident.commander.weblink,
        document_weblink=incident_document.weblink,
        storage_weblink=incident.storage.weblink,
        ticket_weblink=incident.ticket.weblink,
        faq_weblink=incident_faq.weblink,
        conference_weblink=incident.conference.weblink,
        conference_challenge=incident.conference.conference_challenge,
        conversation_commands_reference_document_weblink=
        incident_conversation_commands_reference_document.weblink,
    )

    log.debug(f"Welcome ephemeral message sent to {participant_email}.")
Esempio n. 5
0
def sync_tasks(db_session, incidents, notify: bool = False):
    """Syncs tasks and sends update notifications to incident channels."""
    drive_task_plugin = plugins.get(INCIDENT_PLUGIN_TASK_SLUG)
    for incident in incidents:
        for doc_type in [
                INCIDENT_RESOURCE_INVESTIGATION_DOCUMENT,
                INCIDENT_RESOURCE_INCIDENT_REVIEW_DOCUMENT,
        ]:
            try:
                # we get the document object
                document = get_document(db_session=db_session,
                                        incident_id=incident.id,
                                        resource_type=doc_type)

                if not document:
                    # the document may have not been created yet (e.g. incident review document)
                    break

                # we get the list of tasks in the document
                tasks = drive_task_plugin.list(file_id=document.resource_id)

                for task in tasks:
                    # we get the task information
                    try:
                        create_or_update_task(db_session,
                                              incident,
                                              task["task"],
                                              notify=notify)
                    except Exception as e:
                        log.exception(e)
                        sentry_sdk.capture_exception(e)
            except Exception as e:
                log.exception(e)
                sentry_sdk.capture_exception(e)
Esempio n. 6
0
def sync_tasks(db_session, incidents, notify: bool = False):
    """Syncs tasks and sends update notifications to incident channels."""
    for incident in incidents:
        drive_task_plugin = plugin_service.get_active_instance(
            db_session=db_session,
            project_id=incident.project.id,
            plugin_type="task")

        if not drive_task_plugin:
            log.warning(
                f"Skipping task sync no task plugin enabled. IncidentId: {incident.id}"
            )
            continue

        for doc_type in [
                INCIDENT_RESOURCE_INVESTIGATION_DOCUMENT,
                INCIDENT_RESOURCE_INCIDENT_REVIEW_DOCUMENT,
        ]:
            try:
                # we get the document object
                document = get_document(db_session=db_session,
                                        incident_id=incident.id,
                                        resource_type=doc_type)

                if not document:
                    # the document may have not been created yet (e.g. incident review document)
                    break

                # we get the list of tasks in the document
                tasks = drive_task_plugin.instance.list(
                    file_id=document.resource_id)

                for task in tasks:
                    # we get the task information
                    try:
                        create_or_update_task(db_session,
                                              incident,
                                              task["task"],
                                              notify=notify,
                                              sync_external=False)
                    except Exception as e:
                        log.exception(e)
            except Exception as e:
                log.exception(e)
Esempio n. 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."""
    conversation_topic_change = False

    # we load the incident instance
    incident = incident_service.get(db_session=db_session,
                                    incident_id=incident_id)

    if previous_incident.incident_type.name != incident.incident_type.name:
        conversation_topic_change = True

    if previous_incident.incident_priority.name != incident.incident_priority.name:
        conversation_topic_change = True

    if previous_incident.status.value != incident.status:
        conversation_topic_change = True

    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(
        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)
Esempio n. 8
0
def incident_stable_flow(incident_id: int,
                         command: Optional[dict] = None,
                         db_session=None):
    """Runs the incident stable flow."""
    # we load the incident instance
    incident = incident_service.get(db_session=db_session,
                                    incident_id=incident_id)

    # we set the stable time
    incident.stable_at = datetime.utcnow()

    # we remind the incident commander to write a status report
    send_incident_status_report_reminder(incident)

    # we update the incident cost
    incident_cost = incident_service.calculate_cost(incident_id, db_session)

    # we update the external ticket
    update_incident_ticket(incident.ticket.resource_id,
                           status=IncidentStatus.stable.lower(),
                           cost=incident_cost)

    incident_review_document = get_document(
        db_session=db_session,
        incident_id=incident.id,
        resource_type=INCIDENT_RESOURCE_INCIDENT_REVIEW_DOCUMENT,
    )

    if not incident_review_document:
        storage_plugin = plugins.get(INCIDENT_PLUGIN_STORAGE_SLUG)

        # we create a copy of the incident review document template and we move it to the incident storage
        incident_review_document_name = f"{incident.name} - Post Incident Review Document"
        incident_review_document = storage_plugin.copy_file(
            team_drive_id=incident.storage.resource_id,
            file_id=INCIDENT_STORAGE_INCIDENT_REVIEW_FILE_ID,
            name=incident_review_document_name,
        )

        incident_review_document.update({
            "name":
            incident_review_document_name,
            "resource_type":
            INCIDENT_RESOURCE_INCIDENT_REVIEW_DOCUMENT,
        })

        storage_plugin.move_file(
            new_team_drive_id=incident.storage.resource_id,
            file_id=incident_review_document["id"])

        event_service.log(
            db_session=db_session,
            source=storage_plugin.title,
            description="Incident review document added to storage",
            incident_id=incident.id,
        )

        document_in = DocumentCreate(
            name=incident_review_document["name"],
            resource_id=incident_review_document["id"],
            resource_type=incident_review_document["resource_type"],
            weblink=incident_review_document["weblink"],
        )
        incident.documents.append(
            document_service.create(db_session=db_session,
                                    document_in=document_in))

        event_service.log(
            db_session=db_session,
            source="Dispatch Core App",
            description="Incident review document added to incident",
            incident_id=incident.id,
        )

        # we get the incident investigation and faq documents
        incident_document = get_document(
            db_session=db_session,
            incident_id=incident_id,
            resource_type=INCIDENT_RESOURCE_INVESTIGATION_DOCUMENT,
        )

        # we update the incident review document
        update_document(
            incident_review_document["id"],
            incident.name,
            incident.incident_priority.name,
            incident.status,
            incident.incident_type.name,
            incident.title,
            incident.description,
            incident.commander.name,
            incident.conversation.weblink,
            incident_document.weblink,
            incident.storage.weblink,
            incident.ticket.weblink,
        )

        # we send a notification about the incident review document to the conversation
        send_incident_review_document_notification(
            incident.conversation.channel_id,
            incident_review_document["weblink"])

    db_session.add(incident)
    db_session.commit()

    event_service.log(
        db_session=db_session,
        source="Dispatch Core App",
        description=f"Incident marked as {incident.status}",
        incident_id=incident.id,
    )
Esempio n. 9
0
def incident_assign_role_flow(assigner_email: str,
                              incident_id: int,
                              assignee_email: str,
                              assignee_role: str,
                              db_session=None):
    """Runs the incident participant role assignment flow."""
    # we resolve the assigner and assignee's contact information
    contact_plugin = plugins.get(INCIDENT_PLUGIN_CONTACT_SLUG)
    assigner_contact_info = contact_plugin.get(assigner_email)
    assignee_contact_info = contact_plugin.get(assignee_email)

    # we load the incident instance
    incident = incident_service.get(db_session=db_session,
                                    incident_id=incident_id)

    # we get the participant object for the assignee
    assignee_participant = participant_service.get_by_incident_id_and_email(
        db_session=db_session,
        incident_id=incident.id,
        email=assignee_contact_info["email"])

    if not assignee_participant:
        # The assignee is not a participant. We add them to the incident
        incident_add_or_reactivate_participant_flow(assignee_email,
                                                    incident.id,
                                                    db_session=db_session)

    # we run the participant assign role flow
    result = participant_role_flows.assign_role_flow(incident.id,
                                                     assignee_contact_info,
                                                     assignee_role, db_session)

    if result == "assignee_has_role":
        # NOTE: This is disabled until we can determine the source of the caller
        # we let the assigner know that the assignee already has this role
        # send_incident_participant_has_role_ephemeral_message(
        #    assigner_email, assignee_contact_info, assignee_role, incident
        # )
        return

    if result == "role_not_assigned":
        # NOTE: This is disabled until we can determine the source of the caller
        # we let the assigner know that we were not able to assign the role
        # send_incident_participant_role_not_assigned_ephemeral_message(
        #    assigner_email, assignee_contact_info, assignee_role, incident
        # )
        return

    if assignee_role != ParticipantRoleType.participant:
        # we send a notification to the incident conversation
        send_incident_new_role_assigned_notification(assigner_contact_info,
                                                     assignee_contact_info,
                                                     assignee_role, incident)

    if assignee_role == ParticipantRoleType.incident_commander:
        # we update the conversation topic
        set_conversation_topic(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(
            incident.ticket.resource_id,
            description=incident.description,
            incident_type=incident.incident_type.name,
            commander_email=incident.commander.email,
            conversation_weblink=incident.conversation.weblink,
            document_weblink=incident_document.weblink,
            storage_weblink=incident.storage.weblink,
            visibility=incident.visibility,
            conference_weblink=incident.conference.weblink,
        )
Esempio n. 10
0
def incident_edit_flow(user_email: str,
                       incident_id: int,
                       action: dict,
                       db_session=None):
    """Runs the incident edit flow."""
    notify = action["submission"]["notify"]
    incident_title = action["submission"]["title"]
    incident_description = action["submission"]["description"]
    incident_type = action["submission"]["type"]
    incident_priority = action["submission"]["priority"]
    incident_visibility = action["submission"]["visibility"]

    conversation_topic_change = False

    # we load the incident instance
    incident = incident_service.get(db_session=db_session,
                                    incident_id=incident_id)

    # we update the incident title
    incident.title = incident_title
    log.debug(f"Updated the incident title to {incident_title}.")

    # we update the incident description
    incident.description = incident_description
    log.debug(f"Updated the incident description to {incident_description}.")

    if incident_type != incident.incident_type.name:
        # we update the incident type
        incident_type_obj = incident_type_service.get_by_name(
            db_session=db_session, name=incident_type)
        incident.incident_type_id = incident_type_obj.id

        log.debug(f"Updated the incident type to {incident_type}.")

        conversation_topic_change = True

    if incident_priority != incident.incident_priority.name:
        # we update the incident priority
        incident_priority_obj = incident_priority_service.get_by_name(
            db_session=db_session, name=incident_priority)
        incident.incident_priority_id = incident_priority_obj.id

        log.debug(f"Updated the incident priority to {incident_priority}.")

        conversation_topic_change = True

    if incident_visibility != incident.visibility:
        # we update the incident visibility
        incident.visibility = incident_visibility

        log.debug(f"Updated the incident visibility to {incident_visibility}.")

    if notify == "Yes":
        send_incident_change_notifications(incident, incident_title,
                                           incident_type, incident_priority)

    # we commit the changes to the incident
    db_session.add(incident)
    db_session.commit()

    if conversation_topic_change:
        # we update the conversation topic
        set_conversation_topic(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(
        incident.ticket.resource_id,
        title=incident.title,
        description=incident.description,
        incident_type=incident_type,
        priority=incident_priority,
        commander_email=incident.commander.email,
        conversation_weblink=incident.conversation.weblink,
        document_weblink=incident_document.weblink,
        storage_weblink=incident.storage.weblink,
    )

    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(
        db_session, incident.incident_type, incident.incident_priority,
        incident.description)

    # 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 tactical group
    notification_group = get_group(
        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)

    log.debug(f"Resolved and added new participants to the incident.")
Esempio n. 11
0
def incident_stable_flow(incident_id: int,
                         command: Optional[dict] = None,
                         db_session=None):
    """Runs the incident stable flow."""
    # we load the incident instance
    incident = incident_service.get(db_session=db_session,
                                    incident_id=incident_id)

    if incident.status == IncidentStatus.stable:
        if command:
            convo_plugin = plugins.get(INCIDENT_PLUGIN_CONVERSATION_SLUG)
            convo_plugin.send_ephemeral(
                command["channel_id"],
                command["user_id"],
                "Incident Already Stable Notification",
                blocks=[{
                    "type": "section",
                    "text": {
                        "type":
                        "plain_text",
                        "text":
                        "The incident is already stable. Aborting command...",
                    },
                }],
            )
            return

    # we update the status of the incident
    update_incident_status(db_session=db_session,
                           incident=incident,
                           status=IncidentStatus.stable)

    log.debug(
        f"We have updated the status of the incident to {IncidentStatus.stable}."
    )

    # we update the incident cost
    incident_cost = incident_service.calculate_cost(incident_id, db_session)

    log.debug(f"We have updated the cost of the incident.")

    # we update the external ticket
    update_incident_ticket(
        incident.ticket.resource_id,
        incident_type=incident.incident_type.name,
        status=IncidentStatus.stable.lower(),
        cost=incident_cost,
    )

    log.debug(
        f"We have updated the status of the external ticket to {IncidentStatus.stable}."
    )

    # we update the conversation topic
    set_conversation_topic(incident)

    incident_review_document = get_document(
        db_session=db_session,
        incident_id=incident.id,
        resource_type=INCIDENT_RESOURCE_INCIDENT_REVIEW_DOCUMENT,
    )

    if not incident_review_document:
        storage_plugin = plugins.get(INCIDENT_PLUGIN_STORAGE_SLUG)

        # we create a copy of the incident review document template and we move it to the incident storage
        incident_review_document_name = f"{incident.name} - Post Incident Review Document"
        incident_review_document = storage_plugin.copy_file(
            team_drive_id=incident.storage.resource_id,
            file_id=INCIDENT_STORAGE_INCIDENT_REVIEW_FILE_ID,
            name=incident_review_document_name,
        )

        incident_review_document.update({
            "name":
            incident_review_document_name,
            "resource_type":
            INCIDENT_RESOURCE_INCIDENT_REVIEW_DOCUMENT,
        })

        storage_plugin.move_file(
            new_team_drive_id=incident.storage.resource_id,
            file_id=incident_review_document["id"])

        log.debug(
            "We have added the incident review document in the incident storage."
        )

        document_in = DocumentCreate(
            name=incident_review_document["name"],
            resource_id=incident_review_document["id"],
            resource_type=incident_review_document["resource_type"],
            weblink=incident_review_document["weblink"],
        )
        incident.documents.append(
            document_service.create(db_session=db_session,
                                    document_in=document_in))

        db_session.add(incident)
        db_session.commit()

        log.debug(
            "We have added the incident review document to the incident.")

        # we get the incident investigation and faq documents
        incident_document = get_document(
            db_session=db_session,
            incident_id=incident_id,
            resource_type=INCIDENT_RESOURCE_INVESTIGATION_DOCUMENT,
        )

        # we update the incident review document
        update_document(
            incident_review_document["id"],
            incident.name,
            incident.incident_priority.name,
            incident.status,
            incident.title,
            incident.description,
            incident.commander.name,
            incident.conversation.weblink,
            incident_document.weblink,
            incident.storage.weblink,
            incident.ticket.weblink,
        )

        log.debug("We have updated the incident review document.")

        # we send a notification about the incident review document to the conversation
        send_incident_review_document_notification(
            incident.conversation.channel_id,
            incident_review_document["weblink"])

        log.debug(
            "We have sent a notification about the incident review document to the conversation."
        )

    # we send the stable notifications
    send_incident_status_notifications(incident, db_session)

    log.debug("We have sent the incident stable notifications.")
Esempio n. 12
0
def sync_tasks(db_session=None):
    """Syncs incident tasks."""
    # we get all active and stable incidents
    active_incidents = incident_service.get_all_by_status(
        db_session=db_session, status=IncidentStatus.active)
    stable_incidents = incident_service.get_all_by_status(
        db_session=db_session, status=IncidentStatus.stable)
    incidents = active_incidents + stable_incidents

    # we create an instance of the drive task plugin
    drive_task_plugin = plugins.get(INCIDENT_PLUGIN_TASK_SLUG)

    for incident in incidents:
        for doc_type in [
                INCIDENT_RESOURCE_INVESTIGATION_DOCUMENT,
                INCIDENT_RESOURCE_INCIDENT_REVIEW_DOCUMENT,
        ]:
            # we get the document object
            document = get_document(db_session=db_session,
                                    incident_id=incident.id,
                                    resource_type=doc_type)

            if not document:
                # the document may have not been created yet (e.g. incident review document)
                break

            # we get the list of tasks in the document
            tasks = drive_task_plugin.list(file_id=document.resource_id)

            for t in tasks:
                # we get the task information
                creator = t["task"]["owner"]
                assignees = ", ".join(t["task"]["assignees"])
                description = t["task"]["description"][0]
                status = TaskStatus.open if not t["task"][
                    "status"] else TaskStatus.resolved
                resource_id = t["task"]["id"]
                weblink = t["task"]["web_link"]

                incident_task = task_service.get_by_resource_id(
                    db_session=db_session, resource_id=t["task"]["id"])
                if incident_task:
                    if status == TaskStatus.open:
                        # we don't need to take any actions if the status of the task in the collaboration doc is open
                        break
                    else:
                        if incident_task.status == TaskStatus.resolved:
                            # we don't need to take any actions if the task has already been marked as resolved in the database
                            break
                        else:
                            # we mark the task as resolved in the database
                            incident_task.status = TaskStatus.resolved
                            db_session.add(incident_task)
                            db_session.commit()

                            # we send a notification to the incident conversation
                            notification_text = "Incident Notification"
                            notification_type = "incident-notification"
                            convo_plugin = plugins.get(
                                INCIDENT_PLUGIN_CONVERSATION_SLUG)
                            convo_plugin.send(
                                incident.conversation.channel_id,
                                notification_text,
                                INCIDENT_TASK_RESOLVED_NOTIFICATION,
                                notification_type,
                                task_assignees=assignees,
                                task_description=description,
                                task_weblink=weblink,
                            )
                else:
                    # we add the task to the incident
                    task = task_service.create(
                        db_session=db_session,
                        creator=creator,
                        assignees=assignees,
                        description=description,
                        status=status,
                        resource_id=resource_id,
                        resource_type=INCIDENT_RESOURCE_INCIDENT_TASK,
                        weblink=weblink,
                    )
                    incident.tasks.append(task)
                    db_session.add(incident)
                    db_session.commit()

                    # we send a notification to the incident conversation
                    notification_text = "Incident Notification"
                    notification_type = "incident-notification"
                    convo_plugin = plugins.get(
                        INCIDENT_PLUGIN_CONVERSATION_SLUG)
                    convo_plugin.send(
                        incident.conversation.channel_id,
                        notification_text,
                        INCIDENT_TASK_NEW_NOTIFICATION,
                        notification_type,
                        task_assignees=assignees,
                        task_description=description,
                        task_weblink=weblink,
                    )