Exemple #1
0
def update_impact(incident: Incident, user_id: str, message: str):
    # Easy case. No impact currently and one has been provided
    if message and not incident.impact:
        incident.impact = message
        incident.save()
        return True, f"{IMPACT_UPDATED_TITLE}{message}"

    # Either no new impact has been provided, or one already exists
    msg = block_kit.Message()
    msg.add_block(
        block_kit.Section(
            block_id="update",
            text=block_kit.Text(
                f"{CURRENT_TITLE}{incident.impact or NO_IMPACT_TEXT}"),
            accessory=block_kit.Button(CHANGE_BUTTON_TEXT,
                                       UPDATE_CURRENT_IMPACT_ACTION,
                                       value=incident.pk),
        ))

    # if the user has supplied a message, provide the option for them to set it without
    # retyping in the dialog
    if message:
        msg.add_block(
            block_kit.Section(
                block_id=PROPOSED_MESSAGE_BLOCK_ID,
                text=block_kit.Text(f"{PROPOSED_TITLE}{message}"),
                accessory=block_kit.Button(ACCEPT_PROPOSED_TEXT,
                                           SET_NEW_IMPACT_ACTION,
                                           value=incident.pk),
            ))

    comms_channel = CommsChannel.objects.get(incident=incident)
    msg.send(comms_channel.channel_id)
    return True, None
Exemple #2
0
def set_incident_lead(incident: Incident, user_id: str, message: str):
    assignee = reference_to_id(message) or user_id
    name = settings.SLACK_CLIENT.get_user_profile(assignee)['name']
    user = GetOrCreateSlackExternalUser(external_id=assignee,
                                        display_name=name)
    incident.lead = user
    incident.save()
    return True, None
Exemple #3
0
def set_incident_lead(incident: Incident, user_id: str, message: str):
    assignee = reference_to_id(message) or user_id
    name = get_user_profile(assignee)["name"]
    user, _ = ExternalUser.objects.get_or_create_slack(external_id=assignee,
                                                       display_name=name)
    incident.lead = user
    incident.save()
    return True, None
Exemple #4
0
def set_severity(incident: Incident, user_id: str, message: str):
    for sev_id, sev_name in Incident.SEVERITIES:
        # look for sev name (e.g. critical) or sev id (1)
        if (sev_name in message) or (sev_id in message):
            incident.severity = sev_id
            incident.save()
            return True, None

    return False, None
Exemple #5
0
def set_severity(incident: Incident, user_id: str, message: str):
    for sev_id, sev_name in Incident.SEVERITIES:
        # look for sev name (e.g. critical) or sev id (1)
        if (sev_name in message.lower()) or (sev_id in message.lower()):
            incident.severity = sev_id
            incident.save()
            return add_status_update(
                incident, user_id,
                'Severity updated to ' + incident.severity_text())

    return False, None
Exemple #6
0
def set_incident_lead(incident: Incident, user_id: str, message: str):
    assignee = get_user_profile_by_name(message)

    name = assignee['name']
    print(name)
    user, _ = ExternalUser.objects.get_or_create_slack(
        external_id=assignee['id'], display_name=name)
    incident.lead = user
    incident.save()
    return add_status_update(incident, user_id,
                             'New lead is ' + incident.lead.full_name)
Exemple #7
0
def close_incident(incident: Incident, user_id: str, message: str):
    comms_channel = CommsChannel.objects.get(incident=incident)

    if incident.is_closed():
        comms_channel.post_in_channel(
            f"This incident was already closed at {incident.end_time.strftime('%Y-%m-%d %H:%M:%S')}"
        )
        return True, None

    incident.end_time = datetime.now()
    incident.save()

    comms_channel.post_in_channel(f"This incident has been closed! 📖 -> 📕")

    return True, None
Exemple #8
0
def set_duration(incident: Incident, user_id: str, message: str):
    duration = incident.duration()

    comms_channel = CommsChannel.objects.get(incident=incident)
    comms_channel.post_in_channel(f"The incident has been running for {duration}")

    return True, None
def remind_close_incident(incident: Incident):
    try:
        comms_channel = CommsChannel.objects.get(incident=incident)
        if not incident.is_closed():
            comms_channel.post_in_channel(
                ":timer_clock: This incident has been running a long time.  Can it be closed now?  Remember to pin important messages in order to create the timeline."
            )
    except CommsChannel.DoesNotExist:
        pass
Exemple #10
0
def remind_update_status(incident: Incident):

    try:
        comms_channel = CommsChannel.objects.get(incident=incident)
        if not incident.is_closed():
            user_to_notify = incident.lead or incident.reporter
            comms_channel.post_in_channel(
                f":timer_clock: <@{user_to_notify.external_id}>, this incident has been running a long time."
                " Have you updated the proper notification channels? Remember to notify status updates in twitter and status page"
            )
    except CommsChannel.DoesNotExist:
        pass
def remind_close_incident(incident: Incident):

    # Only remind on weekdays (weekday returns an ordinal indexed from 0 on Monday)
    if datetime.now().weekday() in (5, 6):
        return

    try:
        comms_channel = CommsChannel.objects.get(incident=incident)
        if not incident.is_closed():
            user_to_notify = incident.lead or incident.reporter
            comms_channel.post_in_channel(
                f":timer_clock: <@{user_to_notify.external_id}>, this incident has been running a long time."
                " Can it be closed now? Remember to pin important messages in order to create the timeline."
            )
    except CommsChannel.DoesNotExist:
        pass
Exemple #12
0
def create_zoom(incident: Incident, user_id: str, message: str):
    try:
        m = incident.zoom_meeting()
    except ObjectDoesNotExist:
        m = Meeting.objects.create_meeting(incident)
        # Update the headline post here too
        h = HeadlinePost.objects.get(incident=incident)
        h.zoom_meeting = m
        h.save()
        h.update_in_slack()

    comms_channel = CommsChannel.objects.get(incident=incident)
    comms_channel.post_in_channel(
        f"You can join the zoom meeting here {m.weblink} with password `{m.challenge}`"
    )

    return True, None
Exemple #13
0
def prompt_incident_report(sender, instance: Incident, **kwargs):
    """
    Prompt incident lead to complete a report when an incident is closed.
    """

    try:
        prev_state = Incident.objects.get(pk=instance.pk)
    except Incident.DoesNotExist:
        # Incident hasn't been saved yet, nothing to do here.
        return

    if instance.is_closed() and not prev_state.is_closed():
        user_to_notify = instance.lead or instance.reporter
        doc_url = urljoin(
            settings.SITE_URL,
            reverse('incident_doc', kwargs={'incident_id': instance.pk})
        )
        settings.SLACK_CLIENT.send_message(
            user_to_notify.external_id, f"👋 Don't forget to fill out an incident report here: {doc_url}")
Exemple #14
0
def prompt_incident_report(sender, instance: Incident, **kwargs):
    """
    Prompt incident lead to complete a report when an incident is closed.
    """

    try:
        prev_state = Incident.objects.get(pk=instance.pk)
    except Incident.DoesNotExist:
        # Incident hasn't been saved yet, nothing to do here.
        return

    if instance.is_closed() and not prev_state.is_closed():
        user_to_notify = instance.lead or instance.reporter
        doc_url = urljoin(
            settings.SITE_URL,
            reverse("incident_doc", kwargs={"incident_id": instance.pk}),
        )
        settings.SLACK_CLIENT.send_message(
            user_to_notify.external_id,
            f"👋 Don't forget to fill out an incident report <https://signal-ai.getoutline.com/doc/incident-logbook-wL5JK4hyTr|on the wiki>. The <{doc_url}|incident doc> may help with that.",
        )
Exemple #15
0
def remind_update(incident: Incident):
    update = StatusUpdate.objects.filter(
        incident=incident).order_by("timestamp").first()
    if update is not None:
        if update.timestamp < datetime.datetime.now() - datetime.timedelta(
                minutes=60):
            logger.info("The last update was over 1h ago")
            try:
                comms_channel = CommsChannel.objects.get(incident=incident)
                if not incident.is_closed():
                    user_to_notify = incident.lead
                    settings.SLACK_CLIENT.send_ephemeral_message(
                        comms_channel.channel_id,
                        user_to_notify.external_id,
                        "The last update was over 1h ago. To provide a new update use the command:\n `/%s update [text]`"
                        % settings.SLACK_SLASH_COMMAND,
                    )
            except CommsChannel.DoesNotExist:
                pass

        else:
            logger.info("The last update is not older than 60 minutes")
Exemple #16
0
def update_impact(incident: Incident, user_id: str, message: str):
    incident.impact = message
    incident.save()
    return True, None
Exemple #17
0
def update_summary(incident: Incident, user_id: str, message: str):
    incident.summary = message
    incident.save()
    return True, None
Exemple #18
0
def mitigate_incident(incident: Incident, user_id: str, message: str):
    incident.mitigated = True
    incident.save()
    return add_status_update(incident, user_id,
                             'Status changed to Mitigated - ' + message)