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, )
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])
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, )
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
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}.")
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}.")
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
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, )
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, )
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, )
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.")
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.")
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.")
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))
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}.")
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
def incident_engage_oncall_flow(user_id: str, user_email: str, incident_id: int, action: dict, db_session=None): """Runs the incident engage oncall flow.""" oncall_service_id = action["submission"]["oncall_service_id"] page = action["submission"]["page"] # we load the incident instance incident = incident_service.get(db_session=db_session, incident_id=incident_id) # we resolve the oncall service oncall_service = service_service.get_by_external_id( db_session=db_session, external_id=oncall_service_id) oncall_plugin = plugins.get(oncall_service.type) oncall_email = oncall_plugin.get(service_id=oncall_service_id) # we add the oncall to the incident incident_add_or_reactivate_participant_flow(oncall_email, incident.id, db_session=db_session) # we load the individual individual = individual_service.get_by_email(db_session=db_session, email=user_email) event_service.log( db_session=db_session, source=oncall_plugin.title, description= f"{individual.name} engages oncall service {oncall_service.name}", incident_id=incident.id, ) if page == "Yes": # we page the oncall oncall_plugin.page(oncall_service_id, incident.name, incident.title, incident.description) event_service.log( db_session=db_session, source=oncall_plugin.title, description=f"{oncall_service.name} on-call paged", incident_id=incident.id, )
def 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
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
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
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
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}" )
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.")
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.")
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
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.")
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
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
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)
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