示例#1
0
def delete_conference(job: Job, db_session: SessionLocal):
    """Deletes the conference."""
    conference = conference_service.get_by_job_id(db_session=db_session,
                                                  job_id=job.id)
    p = plugins.get(INCIDENT_PLUGIN_CONFERENCE_SLUG)
    p.delete(conference.conference_id)

    event_service.log(
        db_session=db_session,
        source=p.job_code,
        description="Job conference deleted",
        job_id=job.id,
    )
示例#2
0
def add_participant_to_tactical_group(user_email: str,
                                      job_id: int,
                                      db_session=None):
    """Adds participant to the tactical group."""
    # we get the tactical group
    tactical_group = group_service.get_by_job_id_and_resource_type(
        db_session=db_session,
        job_id=job_id,
        resource_type=INCIDENT_RESOURCE_TACTICAL_GROUP,
    )

    p = plugins.get(INCIDENT_PLUGIN_GROUP_SLUG)
    p.add(tactical_group.code, [user_email])
示例#3
0
def archive_job_artifacts(job: Job, db_session: SessionLocal):
    """Archives artifacts in the job storage."""
    p = plugins.get(INCIDENT_PLUGIN_STORAGE_SLUG)
    p.archive(
        source_team_drive_id=job.storage.resource_id,
        dest_team_drive_id=INCIDENT_STORAGE_ARCHIVAL_FOLDER_ID,
        folder_name=job.name,
    )
    event_service.log(
        db_session=db_session,
        source=p.job_code,
        description="Job artifacts archived",
        job_id=job.id,
    )
示例#4
0
def get_or_create(*, db_session, email: str, **kwargs) -> IndividualContact:
    contact = get_by_email(db_session=db_session, email=email)

    if not contact:
        contact_plugin = plugins.get(INCIDENT_PLUGIN_CONTACT_SLUG)
        individual_info = contact_plugin.get(email)
        kwargs["email"] = individual_info["email"]
        kwargs["name"] = individual_info["fullname"]
        kwargs["weblink"] = individual_info["weblink"]
        individual_contact = IndividualContactCreate(**kwargs)
        contact = create(db_session=db_session,
                         individual_contact_in=individual_contact)

    return contact
示例#5
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 send the ephemeral message
    convo_plugin = plugins.get(INCIDENT_PLUGIN_CONVERSATION_SLUG)

    message_kwargs = {
        "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.incident_document.weblink,
        "storage_weblink": incident.storage.weblink,
        "ticket_weblink": incident.ticket.weblink,
        "conference_weblink": incident.conference.weblink,
        "conference_challenge": incident.conference.conference_challenge,
    }

    faq_doc = document_service.get_incident_faq_document(db_session=db_session)
    if faq_doc:
        message_kwargs.update({"faq_weblink": faq_doc.weblink})

    conversation_reference = document_service.get_conversation_reference_document(
        db_session=db_session)
    if conversation_reference:
        message_kwargs.update({
            "conversation_commands_reference_document_weblink":
            conversation_reference.weblink
        })

    convo_plugin.send_ephemeral(
        incident.conversation.channel_id,
        participant_email,
        "Incident Welcome Message",
        INCIDENT_PARTICIPANT_WELCOME_MESSAGE,
        MessageType.incident_participant_welcome,
        **message_kwargs,
    )

    log.debug(f"Welcome ephemeral message sent to {participant_email}.")
示例#6
0
def send_welcome_email_to_participant(participant_email: str, incident_id: int,
                                      db_session: SessionLocal):
    """Sends a welcome email 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,
    )

    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,
        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 email sent to {participant_email}.")
示例#7
0
async def db_session_middleware(request: Request, call_next):
    request_id = str(uuid1())

    # we create a per-request id such that we can ensure that our session is scoped for a particular request.
    # see: https://github.com/tiangolo/fastapi/issues/726
    ctx_token = _request_id_ctx_var.set(request_id)
    # path_params = get_path_params_from_request(request)

    # if this call is organization specific set the correct search path
    # organization_slug = path_params.get("organization")

    auth_plugin = plugins.get(DISPATCH_AUTHENTICATION_PROVIDER_SLUG)
    login_info = auth_plugin.get_current_user_data(request)
    organization_slug = login_info.get("org_code") if login_info else None

    if organization_slug:
        # request.state.organization = organization_slug
        schema = f"dispatch_organization_{organization_slug}"
        # validate slug exists
        schema_names = inspect(engine).get_schema_names()
        if schema in schema_names:
            # add correct schema mapping depending on the request
            schema_engine = engine.execution_options(
                schema_translate_map={
                    None: schema,
                }
            )
        else:
            return JSONResponse(
                status_code=status.HTTP_403_FORBIDDEN,
                content={"detail": [{"msg": "Forbidden"}]},
            )
    else:
        # add correct schema mapping depending on the request
        # can we set some default here?
        request.state.organization = "default"
        schema_engine = engine.execution_options(
            schema_translate_map={
                None: "dispatch_organization_default",
            }
        )
    try:
        session = scoped_session(sessionmaker(bind=schema_engine), scopefunc=get_request_id)
        request.state.auth_db = session()
        response = await call_next(request)
    finally:
        request.state.auth_db.close()

    _request_id_ctx_var.reset(ctx_token)
    return response
示例#8
0
def archive_incident_artifacts(incident: Incident, db_session: SessionLocal):
    """Archives artifacts in the incident storage."""
    p = plugins.get(INCIDENT_PLUGIN_STORAGE_SLUG)
    p.archive(
        source_team_drive_id=incident.storage.resource_id,
        dest_team_drive_id=INCIDENT_STORAGE_ARCHIVAL_FOLDER_ID,
        folder_name=incident.name,
    )
    event_service.log(
        db_session=db_session,
        source=p.title,
        description="Incident artifacts archived",
        incident_id=incident.id,
    )
示例#9
0
def delete_conference(incident: Incident, db_session: SessionLocal):
    """Deletes the conference."""
    conference = conference_service.get_by_incident_id(
        db_session=db_session, incident_id=incident.id
    )
    p = plugins.get(INCIDENT_PLUGIN_CONFERENCE_SLUG)
    p.delete(conference.conference_id)

    event_service.log(
        db_session=db_session,
        source=p.title,
        description="Incident conference deleted",
        incident_id=incident.id,
    )
示例#10
0
def send_task_notification(conversation_id, notification_type, assignees,
                           description, weblink):
    """Sends a task notification."""
    # 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(
        conversation_id,
        notification_text,
        notification_type,
        task_assignees=assignees,
        task_description=description,
        task_weblink=weblink,
    )
示例#11
0
def send_incident_commander_readded_notification(incident: Incident):
    """Sends a notification about re-adding the incident commander to the conversation."""
    notification_text = "Incident Notification"
    notification_type = MessageType.incident_notification

    convo_plugin = plugins.get(INCIDENT_PLUGIN_CONVERSATION_SLUG)
    convo_plugin.send(
        incident.conversation.channel_id,
        notification_text,
        INCIDENT_COMMANDER_READDED_NOTIFICATION,
        notification_type,
        commander_fullname=incident.commander.name,
    )

    log.debug(f"Incident commander readded notification sent.")
示例#12
0
def send_incident_review_document_notification(conversation_id: str, review_document_weblink: str):
    """Sends the review document notification."""
    notification_text = "Incident Notification"
    notification_type = MessageType.incident_notification

    convo_plugin = plugins.get(INCIDENT_PLUGIN_CONVERSATION_SLUG)
    convo_plugin.send(
        conversation_id,
        notification_text,
        [INCIDENT_REVIEW_DOCUMENT],
        notification_type,
        review_document_weblink=review_document_weblink,
    )

    log.debug("Incident review document notification sent.")
示例#13
0
def send_incident_resources_ephemeral_message_to_participant(
        user_id: str, incident_id: int, db_session: SessionLocal):
    """Sends the list of incident resources to the participant via an ephemeral message."""
    # we load the incident instance
    incident = incident_service.get(db_session=db_session,
                                    incident_id=incident_id)

    message_kwargs = {
        "commander_fullname": incident.commander.name,
        "commander_weblink": incident.commander.weblink,
        "document_weblink": incident.incident_document.weblink,
        "storage_weblink": incident.storage.weblink,
        "ticket_weblink": incident.ticket.weblink,
        "conference_weblink": incident.conference.weblink,
        "conference_challenge": incident.conference.conference_challenge,
    }

    if incident.incident_review_document:
        message_kwargs.update({
            "review_document_weblink":
            incident.incident_review_document.weblink
        })

    faq_doc = document_service.get_incident_faq_document(db_session=db_session)
    if faq_doc:
        message_kwargs.update({"faq_weblink": faq_doc.weblink})

    conversation_reference = document_service.get_conversation_reference_document(
        db_session=db_session)
    if conversation_reference:
        message_kwargs.update({
            "conversation_commands_reference_document_weblink":
            conversation_reference.weblink
        })

    # 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,
        **message_kwargs,
    )

    log.debug(
        f"List of incident resources sent to {user_id} via ephemeral message.")
示例#14
0
def get_current_user(*, db_session: Session = Depends(get_db), request: Request) -> DispatchUser:
    """Attempts to get the current user depending on the configured authentication provider."""
    if DISPATCH_AUTHENTICATION_PROVIDER_SLUG:
        auth_plugin = plugins.get(DISPATCH_AUTHENTICATION_PROVIDER_SLUG)
        user_email = auth_plugin.get_current_user(request)
    else:
        log.debug("No authentication provider. Default user will be used")
        user_email = DISPATCH_AUTHENTICATION_DEFAULT_USER

    if not user_email:
        log.exception(
            f"Unable to determine user email based on configured auth provider or no default auth user email defined. Provider: {DISPATCH_AUTHENTICATION_PROVIDER_SLUG}"
        )
        raise credentials_exception

    return get_or_create(db_session=db_session, user_in=UserRegister(email=user_email))
示例#15
0
def send_incident_suggested_reading_messages(
    incident: Incident, items: list, participant_email: str
):
    """Sends a suggested reading message to a participant."""
    if items:
        convo_plugin = plugins.get(INCIDENT_PLUGIN_CONVERSATION_SLUG)
        convo_plugin.send_ephemeral(
            incident.conversation.channel_id,
            participant_email,
            "Suggested Reading",
            [INCIDENT_PARTICIPANT_SUGGESTED_READING_ITEM],
            MessageType.incident_participant_suggested_reading,
            items=items,
        )

        log.debug(f"Suggested reading ephemeral message sent to {participant_email}.")
示例#16
0
def remove_participant(user_email: str, incident_id: int,
                       db_session: SessionLocal):
    """Removes a participant."""
    # We load the incident
    incident = incident_service.get(db_session=db_session,
                                    incident_id=incident_id)

    # We get information about the individual
    contact_plugin = plugins.get(INCIDENT_PLUGIN_CONTACT_SLUG)
    individual_info = contact_plugin.get(user_email)
    individual_fullname = individual_info["fullname"]

    log.debug(
        f"Removing {individual_fullname} from incident {incident.name}...")

    participant = get_by_incident_id_and_email(db_session=db_session,
                                               incident_id=incident_id,
                                               email=user_email)

    if not participant:
        log.debug(
            f"Can't remove {individual_fullname}. They're not an active participant of incident {incident.name}."
        )
        return False

    # We mark the participant as inactive
    participant.is_active = False

    # We make the participant renounce to their active roles
    participant_active_roles = participant_role_service.get_all_active_roles(
        db_session=db_session, participant_id=participant.id)
    for participant_active_role in participant_active_roles:
        participant_role_service.renounce_role(
            db_session=db_session, participant_role=participant_active_role)

    # We add and commit the changes
    db_session.add(participant)
    db_session.commit()

    event_service.log(
        db_session=db_session,
        source="Dispatch Core App",
        description=f"{participant.individual.name} removed from incident",
        incident_id=incident_id,
    )

    return True
示例#17
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,
        )
示例#18
0
def create_collaboration_documents(incident: Incident,
                                   db_session: SessionLocal):
    """Create external collaboration document."""
    p = plugins.get(INCIDENT_PLUGIN_STORAGE_SLUG)

    document_name = f"{incident.name} - Incident Document"

    # TODO can we make move and copy in one api call? (kglisson)
    document = p.copy_file(
        incident.storage.resource_id,
        incident.incident_type.template_document.resource_id,
        document_name,
    )
    p.move_file(incident.storage.resource_id, document["id"])

    # NOTE this should be optional
    if INCIDENT_DOCUMENT_INVESTIGATION_SHEET_ID:
        sheet_name = f"{incident.name} - Incident Tracking Sheet"
        sheet = p.copy_file(incident.storage.resource_id,
                            INCIDENT_DOCUMENT_INVESTIGATION_SHEET_ID,
                            sheet_name)
        p.move_file(incident.storage.resource_id, sheet["id"])

    p.create_file(incident.storage.resource_id, "logs")
    p.create_file(incident.storage.resource_id, "screengrabs")

    # TODO this logic should probably be pushed down into the plugins i.e. making them return
    # the fields we expect instead of re-mapping. (kglisson)
    document.update({
        "name": document_name,
        "resource_type": INCIDENT_RESOURCE_INVESTIGATION_DOCUMENT,
        "resource_id": document["id"],
    })
    sheet.update({
        "name": sheet_name,
        "resource_type": INCIDENT_RESOURCE_INVESTIGATION_SHEET,
        "resource_id": sheet["id"],
    })

    event_service.log(
        db_session=db_session,
        source=p.title,
        description="Incident investigation document and sheet created",
        incident_id=incident.id,
    )

    return document, sheet
示例#19
0
def reactivate_participant(user_email: str, incident_id: int,
                           db_session: SessionLocal):
    """Reactivates a participant."""
    # We load the incident
    incident = incident_service.get(db_session=db_session,
                                    incident_id=incident_id)

    # We get information about the individual
    contact_plugin = plugins.get(INCIDENT_PLUGIN_CONTACT_SLUG)
    individual_info = contact_plugin.get(user_email)
    individual_fullname = individual_info["fullname"]

    log.debug(
        f"Reactivating {individual_fullname} on incident {incident.name}...")

    participant = get_by_incident_id_and_email(db_session=db_session,
                                               incident_id=incident_id,
                                               email=user_email)

    if not participant:
        log.debug(
            f"{individual_fullname} is not an inactive participant of incident {incident.name}."
        )
        return False

    # We mark the participant as active
    participant.is_active = True

    # We create a role for the participant
    participant_role_in = ParticipantRoleCreate(
        role=ParticipantRoleType.participant)
    participant_role = participant_role_service.create(
        db_session=db_session, participant_role_in=participant_role_in)
    participant.participant_roles.append(participant_role)

    # We add and commit the changes
    db_session.add(participant)
    db_session.commit()

    event_service.log(
        db_session=db_session,
        source="Dispatch Core App",
        description=f"{individual_fullname} reactivated",
        incident_id=incident_id,
    )

    return True
示例#20
0
def create_conference(incident: Incident, participants: List[str], db_session: SessionLocal):
    """Create external conference room."""
    p = plugins.get(INCIDENT_PLUGIN_CONFERENCE_SLUG)
    conference = p.create(incident.name, participants=participants)

    conference.update(
        {"resource_type": INCIDENT_PLUGIN_CONFERENCE_SLUG, "resource_id": conference["id"]}
    )

    event_service.log(
        db_session=db_session,
        source=p.title,
        description="Incident conference created",
        incident_id=incident.id,
    )

    return conference
示例#21
0
def remove_planning_plugin(user_email: str, service_id: int, db_session: SessionLocal):
    """Removes a planning_plugin."""
    # We load the service
    service = service_service.get(db_session=db_session, service_id=service_id)

    # We get information about the plugin
    contact_plugin = plugins.get(INCIDENT_PLUGIN_CONTACT_SLUG)
    plugin_info = contact_plugin.get(user_email)
    plugin_fullname = plugin_info["fullname"]

    log.debug(f"Removing {plugin_fullname} from service {service.name}...")

    planning_plugin = get_by_service_id_and_email(
        db_session=db_session, service_id=service_id, code=user_email
    )

    if not planning_plugin:
        log.debug(
            f"Can't remove {plugin_fullname}. They're not an active planning_plugin of service {service.name}."
        )
        return False

    # We mark the planning_plugin as inactive
    planning_plugin.is_active = False

    # We make the planning_plugin renounce to their active roles
    planning_plugin_active_roles = planning_plugin_role_service.get_all_active_roles(
        db_session=db_session, planning_plugin_id=planning_plugin.id
    )
    for planning_plugin_active_role in planning_plugin_active_roles:
        planning_plugin_role_service.renounce_role(
            db_session=db_session, planning_plugin_role=planning_plugin_active_role
        )

    # We add and commit the changes
    db_session.add(planning_plugin)
    db_session.commit()

    event_service.log(
        db_session=db_session,
        source="Dispatch Core App",
        description=f"{planning_plugin.plugin.name} removed from service",
        service_id=service_id,
    )

    return True
示例#22
0
def add_participant_to_tactical_group(user_email: str,
                                      incident_id: int,
                                      db_session=None):
    """Adds participant to the tactical group."""
    # we get the tactical group
    tactical_group = get_group(
        db_session=db_session,
        incident_id=incident_id,
        resource_type=INCIDENT_RESOURCE_TACTICAL_GROUP,
    )

    p = plugins.get(INCIDENT_PLUGIN_GROUP_SLUG)
    p.add(tactical_group.email, [user_email])

    log.debug(
        f"{user_email} has been added to tactical group {tactical_group.email}"
    )
示例#23
0
def send_incident_resources_ephemeral_message_to_participant(
        user_id: str, incident_id: int, db_session: SessionLocal):
    """Sends the list of incident resources to the participant via an ephemeral message."""
    # 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,
        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,
        conversation_commands_reference_document_weblink=
        incident_conversation_commands_reference_document.weblink,
        conference_weblink=incident.conference.weblink,
    )

    log.debug(
        f"List of incident resources sent to {user_id} via ephemeral message.")
示例#24
0
def incident_active_flow(incident_id: int, command: Optional[dict] = None, db_session=None):
    """Runs the incident active flow."""
    # we load the incident instance
    incident = incident_service.get(db_session=db_session, incident_id=incident_id)

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

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

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

    # we update the status of the external ticket
    update_incident_ticket(
        incident.ticket.resource_id,
        incident_type=incident.incident_type.name,
        status=IncidentStatus.active.lower(),
    )

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

    # we update the conversation topic
    set_conversation_topic(incident)

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

    log.debug("We have sent the incident active notifications.")
示例#25
0
def create_conversation(incident: Incident, participants: List[str], db_session: SessionLocal):
    """Create external communication conversation."""
    # we create the conversation
    p = plugins.get(INCIDENT_PLUGIN_CONVERSATION_SLUG)
    conversation = p.create(incident.name, participants)

    conversation.update(
        {"resource_type": INCIDENT_PLUGIN_CONVERSATION_SLUG, "resource_id": conversation["name"]}
    )

    event_service.log(
        db_session=db_session,
        source=p.title,
        description="Incident conversation created",
        incident_id=incident.id,
    )

    return conversation
示例#26
0
def send_incident_commander_readded_notification(incident_id: int, db_session: SessionLocal):
    """Sends a notification about re-adding the incident commander to the conversation."""
    notification_text = "Incident Notification"
    notification_type = MessageType.incident_notification

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

    convo_plugin = plugins.get(INCIDENT_PLUGIN_CONVERSATION_SLUG)
    convo_plugin.send(
        incident.conversation.channel_id,
        notification_text,
        INCIDENT_COMMANDER_READDED_NOTIFICATION,
        notification_type,
        commander_fullname=incident.commander.name,
    )

    log.debug("Incident commander readded notification sent.")
示例#27
0
def get_job_participants(job: Job, db_session: SessionLocal):
    """Get additional job participants based on priority, type, and description."""
    p = plugins.get(INCIDENT_PLUGIN_PARTICIPANT_RESOLVER_SLUG)
    workers, team_contacts = p.get(
        job.job_type,
        job.job_priority,
        job.description,
        db_session=db_session,
    )

    event_service.log(
        db_session=db_session,
        source=p.job_code,
        description="Job participants resolved",
        job_id=job.id,
    )

    return workers, team_contacts
示例#28
0
def get_incident_participants(incident: Incident, db_session: SessionLocal):
    """Get additional incident participants based on priority, type, and description."""
    p = plugins.get(INCIDENT_PLUGIN_PARTICIPANT_RESOLVER_SLUG)
    individual_contacts, team_contacts = p.get(
        incident.incident_type,
        incident.incident_priority,
        incident.description,
        db_session=db_session,
    )

    event_service.log(
        db_session=db_session,
        source=p.title,
        description="Incident participants resolved",
        incident_id=incident.id,
    )

    return individual_contacts, team_contacts
示例#29
0
def update_task_status(user_id: str,
                       user_email: str,
                       incident_id: int,
                       action: dict,
                       db_session=None):
    """Updates a task based on user input."""
    action_type, external_task_id = action["actions"][0]["value"].split("-")

    resolve = True
    if action_type == "reopen":
        resolve = False

    # we only update the external task allowing syncing to care of propagation to dispatch
    task = task_service.get_by_resource_id(db_session=db_session,
                                           resource_id=external_task_id)

    # avoid external calls if we are already in the desired state
    if resolve and task.status == TaskStatus.resolved:
        message = "Task is already resolved."
        dispatch_slack_service.send_ephemeral_message(
            slack_client, action["container"]["channel_id"], user_id, message)
        return

    if not resolve and task.status == TaskStatus.open:
        message = "Task is already open."
        dispatch_slack_service.send_ephemeral_message(
            slack_client, action["container"]["channel_id"], user_id, message)
        return

    # we don't currently have a good way to get the correct file_id (we don't store a task <-> relationship)
    # lets try in both the incident doc and PIR doc
    drive_task_plugin = plugins.get(INCIDENT_PLUGIN_TASK_SLUG)

    try:
        file_id = task.incident.incident_document.resource_id
        drive_task_plugin.update(file_id, external_task_id, resolved=resolve)
    except Exception:
        file_id = task.incident.incident_review_document.resource_id
        drive_task_plugin.update(file_id, external_task_id, resolved=resolve)

    status = "resolved" if task.status == TaskStatus.open else "re-opened"
    message = f"Task successfully {status}."
    dispatch_slack_service.send_ephemeral_message(
        slack_client, action["container"]["channel_id"], user_id, message)
示例#30
0
def reactivate_planning_plugin(user_email: str, service_id: int, db_session: SessionLocal):
    """Reactivates a planning_plugin."""
    # We load the service
    service = service_service.get(db_session=db_session, service_id=service_id)

    # We get information about the plugin
    contact_plugin = plugins.get(INCIDENT_PLUGIN_CONTACT_SLUG)
    plugin_info = contact_plugin.get(user_email)
    plugin_fullname = plugin_info["fullname"]

    log.debug(f"Reactivating {plugin_fullname} on service {service.name}...")

    planning_plugin = get_by_service_id_and_email(
        db_session=db_session, service_id=service_id, code=user_email
    )

    if not planning_plugin:
        log.debug(
            f"{plugin_fullname} is not an inactive planning_plugin of service {service.name}."
        )
        return False

    # We mark the planning_plugin as active
    planning_plugin.is_active = True

    # We create a role for the planning_plugin
    planning_plugin_role_in = ServicePluginRoleCreate(role=ServicePluginRoleType.planning_plugin)
    planning_plugin_role = planning_plugin_role_service.create(
        db_session=db_session, planning_plugin_role_in=planning_plugin_role_in
    )
    planning_plugin.planning_plugin_role.append(planning_plugin_role)

    # We add and commit the changes
    db_session.add(planning_plugin)
    db_session.commit()

    event_service.log(
        db_session=db_session,
        source="Dispatch Core App",
        description=f"{plugin_fullname} reactivated",
        service_id=service_id,
    )

    return True