Skip to content

Instantly share code, notes, and snippets.

@mstarkman
Created December 18, 2020 15:47
Show Gist options
  • Save mstarkman/36f0b59a0f72d2c194839e9690993e87 to your computer and use it in GitHub Desktop.
Save mstarkman/36f0b59a0f72d2c194839e9690993e87 to your computer and use it in GitHub Desktop.
class PublicAPI::V1::Incidents < PublicAPI::V1::AuthedEndpoints
Entity = PublicAPI::V1::IncidentEntity
PaginatedEntity = PublicAPI::V1::DynamicPaginationEntity.for(Entity)
namespace :incidents do
desc 'Retrieve incidents', success: PaginatedEntity
params do
use :pagination
optional :environments, type: String, documentation: { desc: 'A comma separated list of environment IDs' }
optional :teams, type: String, documentation: { desc: 'A comma separated list of team IDs' }
optional :services, type: String, documentation: { desc: 'A comma separated list of service IDs' }
optional :status, type: String, documentation: { desc: 'Incident status' }
optional :start_date, type: Date, documentation: { desc: 'The start date to return incidents from' }
optional :end_date, type: Date, documentation: { desc: 'The end date to return incidents from' }
optional :query, type: String, documentation: { desc: 'A text query for an incident that searches on name, summary, and desciption' }
optional :saved_search_id, type: String, documentation: { desc: 'The id of a previously saved search.' }
optional :severities, type: String, documentation: { desc: 'A text value of severity' }
optional :severity_not_set, type: Boolean, documentation: { desc: 'Flag for including incidents where severity has not been set' }
optional :current_milestones, type: String, documentation: { desc: 'A comma separated list of current milestones' }
end
get do
if !params.empty?
EventTracker.track_incidents_search(actor: current_actor, account: current_account, properties: { params: params })
end
feature_flag_enabled = ::FeatureFlags.enabled?(FeatureFlags::API_INCIDENTS_LITE_REQUEST, current_actor)
use_lite_entity = params.delete(:lite) == "true" && feature_flag_enabled
FireHydrant::Tracing::Tracer.set_tag(:use_lite_entity, use_lite_entity, on_root_span: true)
reader = IncidentReader.new(current_organization, params, **actor_and_account)
if use_lite_entity
reader.for_incident_lite_api_index!
else
reader.for_incident_api_index!
end
present reader, with: PaginatedEntity, use_lite_entity: use_lite_entity
end
desc 'Create an incident' do
success Entity
end
params do
requires :name, type: String, documentation: { in: 'body' }
optional :summary, type: String, documentation: { in: 'body' }
optional :description, type: String, documentation: { in: 'body' }
optional :severity, type: String, documentation: { in: 'body' }
optional :severity_condition_id, type: String, documentation: { in: 'body' } # TODO (cleanup): Probably should remove this as we have mulitple impacts now
optional :severity_impact_id, type: String, documentation: { in: 'body' } # TODO (cleanup): Probably should remove this as we have mulitple impacts now
optional :alert_ids, type: Array[String], documentation: { in: 'body', desc: 'List of alert IDs that this incident should be associated to' }
optional :labels, documentation: { type: "object", in: 'body', additionalProperties: { type: 'string' } }
optional :runbook_ids, type: Array[String], documentation: { in: 'body', desc: 'List of ids of Runbooks to attach to this incident. Foregoes any conditions these runbooks may have guarding automatic attachment.'}
# TODO: Add impacts array here
end
post do
creator = Incidents::IncidentCreator.new(current_organization, **actor_and_account)
result = creator.create(params)
# if result.success?
# present result.object, with: Entity
# else
# status result.http_status_code
present PublicAPI::V1::Error.new(detail: "could not create incident", messages: ["I can haz errors"]), with: PublicAPI::V1::ErrorEntity
# end
end
route_param :incident_id do
params { requires :incident_id, type: String }
helpers do
def current_incident
@current_incident ||= current_organization.incidents.find(params[:incident_id])
end
end
desc 'Retrieve an incident', success: Entity
get do
present current_incident, with: Entity
end
desc 'Update an incident', success: Entity
params do
requires :incident_id, type: String
optional :name, type: String, documentation: { in: 'body' }
optional :summary, type: String, documentation: { in: 'body' }
optional :description, type: String, documentation: { in: 'body' }
optional :severity, type: String, documentation: { in: 'body' }
optional :severity_condition_id, type: String, documentation: { in: 'body' }
optional :severity_impact_id, type: String, documentation: { in: 'body' }
end
patch do
updater = ::Incidents::IncidentUpdater.new(current_incident, **actor_and_account)
result = updater.update(params)
if result.success?
present current_incident, with: Entity
else
error!({ error: "invalid update", messages: result.errors.full_messages }, 422)
end
end
desc I18n.t('api.incidents.delete.description'), summary: I18n.t('api.incidents.delete.summary'), success: Entity
params do
requires :incident_id, type: String
end
delete do
destroyer = ::Incidents::IncidentDestroyer.new(current_incident, **actor_and_account)
result = destroyer.destroy
handle_result(result, Entity, 'api.incidents.delete.error.detail')
end
desc 'Resolve an active incident', success: Entity
put 'resolve' do
resolver = ::Incidents::IncidentResolver.new(current_incident, **actor_and_account)
result = resolver.resolve
if result.success?
present current_incident.reload, with: Entity
else
error!({ error: "could not close incident", messages: result.errors }, 409)
end
end
get "/channel" do
channel = Integrations::Slack::IncidentChannel.find_by(incident: current_incident, account_id: current_account.id)
if channel.present?
present channel.to_incident_channel, with: ::PublicAPI::V1::Incidents::ChannelEntity
else
error!({ error: 'no channel for incident' }, 404)
end
end
mount ::PublicAPI::V1::IncidentImpact
mount ::PublicAPI::V1::Incidents::RelatedChangeEvents
mount ::PublicAPI::V1::Incidents::Tasks
mount ::PublicAPI::V1::Incidents::Alerts
mount ::PublicAPI::V1::Incidents::ActionItems
mount ::PublicAPI::V1::Incidents::StatusPages
mount ::PublicAPI::V1::Incidents::Milestones
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment