incident

package module
v0.0.0-...-e26982f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 25, 2023 License: MIT Imports: 14 Imported by: 6

README

go-incident: Go client library for Incident.io

GoDoc

Go client library for accessing the Incident.io API.

Installation

go-incident is compatible with modern Go releases in module mode, with Go installed:

go get github.com/andygrunwald/go-incident

will resolve and add the package to the current development module, along with its dependencies.

Alternatively the same can be achieved if you use import in a package:

import "github.com/andygrunwald/go-incident"

and run go get without parameters.

Finally, to use the top-of-trunk version of this repo, use the following command:

go get github.com/andygrunwald/go-incident@main

Usage

import "github.com/andygrunwald/go-incident"

Construct a new Incident.io client, then use the various services on the client to access different parts of the Incident.io API. For example:

apiKey := "<my-secret-api-key>"
client := incident.NewClient(apiKey, nil)

// List all incidents for your organisation.
incidents, response, err := client.Incidents.List(context.Background(), nil)

Some API methods have optional parameters that can be passed. For example:

apiKey := "<my-secret-api-key>"
client := incident.NewClient(apiKey, nil)

// List only closed incidents for your organisation in page chunks of 5.
opt := &incident.IncidentsListOptions{
    PageSize: 5,
    Status: []string{
        incident.IncidentStatusClosed,
    },
}
incidents, response, err := client.Incidents.List(context.Background(), opt)

The services of a client divide the API into logical chunks and correspond to the structure of the Incident.io API documentation .

NOTE: Using the context package, one can easily pass cancelation signals and deadlines to various services of the client for handling a request. In case there is no context available, then context.Background() can be used as a starting point.

For more sample code snippets, head over to the example directory.

Authentication

For all requests made to the incident.io API, you'll need an API key. Right now, there is no public incident.io API.

To create an API key, head to the incident dashboard and visit API keys.

The API key will be passed as the first argument, when constructing a new client:

apiKey := "<my-secret-api-key>"
client := incident.NewClient(apiKey, nil)
Errors

Errors provided by the Incident.io API will be mapped to the ErrorResponse type and can be investigated further:

// Do a API call ...
if err != nil {
    if responseErr, ok := err.(*incident.ErrorResponse); ok {
        // Do something with responseErr, like printing
        fmt.Printf("%+v", responseErr.Type)
    }
}

All error details provided by the API are available. See Making requests > Errors in the Incident.ip API docs for more details.

Pagination

Some requests support pagination. Pagination options are described in the options per API call once supported. The returned data contains a PaginationMeta struct with paging information.

apiKey := "<my-secret-api-key>"
client := incident.NewClient(apiKey, nil)

opt := &incident.IncidentsListOptions{
    PageSize: 5,
}

// Get all pages of incidents
var allIncidents []incident.Incident
for {
    incidents, _, err := client.Incidents.List(context.Background(), opt)
    if err != nil {
        panic(err)
    }
    allIncidents = append(allIncidents, incidents.Incidents...)

    // Calculate if there is a next page
    if incidents.PaginationMeta.TotalRecordCount == int64(len(allIncidents)) {
        break
    }
    opt.After = incidents.Incidents[len(incidents.Incidents)-1].Id
}

Contributing

I would like to cover the entire Incident.io API and contributions are of course always welcome. The calling pattern is pretty well established, so adding new methods is relatively straightforward.

Inspired by

The structure, code and documentation of this project is inspired by google/go-github.

License

This library is distributed under the MIT License found in the LICENSE file.

Documentation

Index

Constants

View Source
const (
	// Custom Field Types
	CustomFieldTypeLink         = "link"
	CustomFieldTypeMultiSelect  = "multi_select"
	CustomFieldTypeNumeric      = "numeric"
	CustomFieldTypeSingleSelect = "single_select"
	CustomFieldTypeText         = "text"

	// User Roles
	UserRoleAdministrator = "administrator"
	UserRoleOwner         = "owner"
	UserRoleResponder     = "responder"
	UserRoleViewer        = "viewer"

	// Incident Roles
	IncidentRoleCustom = "custom"
	IncidentRoleLead   = "lead"

	// Incident Status
	IncidentStatusClosed        = "closed"
	IncidentStatusDeclined      = "declined"
	IncidentStatusFixing        = "fixing"
	IncidentStatusInvestigating = "investigating"
	IncidentStatusMonitoring    = "monitoring"
	IncidentStatusTriage        = "triage"

	// Incident Type
	IncidentTypeReal     = "real"
	IncidentTypeTest     = "test"
	IncidentTypeTutorial = "tutorial"

	// Incident Visbility
	IncidentVisibilityPrivate = "private"
	IncidentVisibilityPublic  = "public"

	// External Issue Reference Provider
	ExternalIssueReferenceProviderClubhouse  = "clubhouse"
	ExternalIssueReferenceProviderGithub     = "github"
	ExternalIssueReferenceProviderJira       = "jira"
	ExternalIssueReferenceProviderJiraServer = "jira_server"
	ExternalIssueReferenceProviderLinear     = "linear"

	// Action Status
	ActionStatusCompleted   = "completed"
	ActionStatusDeleted     = "deleted"
	ActionStatusNotDoing    = "not_doing"
	ActionStatusOutstanding = "outstanding"
)

Variables

This section is empty.

Functions

func CheckResponse

func CheckResponse(r *http.Response) error

CheckResponse checks the API response for errors, and returns them if present. A response is considered an error if it has a status code outside the 200 range or equal to 202 Accepted. API error responses are expected to have response body, and a JSON response body that maps to ErrorResponse.

Types

type APIKey

type APIKey struct {
	// Unique identifier for this API key
	Id string `json:"id"`

	// The name of the API key, for the user's reference
	Name string `json:"name"`
}

type Action

type Action struct {
	// When the action was completed
	CompletedAt time.Time `json:"completed_at,omitempty"`

	// When the action was created
	CreatedAt time.Time `json:"created_at"`

	// Description of the action
	Description            string                  `json:"description"`
	ExternalIssueReference *ExternalIssueReference `json:"external_issue_reference,omitempty"`

	// Whether an action is marked as follow-up
	FollowUp bool `json:"follow_up"`

	// Unique identifier for the action
	Id string `json:"id"`

	// Unique identifier of the incident the action belongs to
	IncidentId string `json:"incident_id"`

	// Status of the action
	Status string `json:"status"`

	// When the action was last updated
	UpdatedAt time.Time `json:"updated_at"`

	// Assignee of the action
	Assignee *User `json:"assignee,omitempty"`
}

type ActionResponse

type ActionResponse struct {
	Action Action `json:"action"`
}

type ActionsList

type ActionsList struct {
	Actions []Action `json:"actions"`
}

type ActionsListOptions

type ActionsListOptions struct {
	// Find actions related to this incident
	IncidentId string `url:"incident_id,omitempty"`

	// Filter to actions marked as being follow up actions
	IsFollowUp bool `url:"is_follow_up,omitempty"`

	// Filter to actions from incidents of the given mode.
	// If not set, only actions from real incidents are returned
	// Enum: "real" "test" "tutorial"
	IncidentMode string `url:"incident_mode,omitempty"`
}

type ActionsService

type ActionsService service

ActionsService handles communication with the actions related methods of the Incident.io API.

API docs: https://api-docs.incident.io/#tag/Actions

func (*ActionsService) Get

Get returns a single action.

id represents the unique identifier for the action

API docs: https://api-docs.incident.io/#operation/Actions_Show

func (*ActionsService) List

List list all actions for an organisation.

API docs: https://api-docs.incident.io/#operation/Actions_List

type Actor

type Actor struct {
	ApiKey *APIKey `json:"api_key,omitempty"`
	User   *User   `json:"user,omitempty"`
}

type Client

type Client struct {

	// Base URL for API requests.
	// We only have a cloud version of the Incident.io API.
	// However, we export it in case some companies run a Incident.io compatible API version.
	// BaseURL should always be specified with a trailing slash.
	BaseURL *url.URL

	// User agent used when communicating with the Incident.io API.
	UserAgent string

	// Services used for talking to different parts of the Incident.io API.
	Actions       *ActionsService
	CustomFields  *CustomFieldsService
	Severities    *SeveritiesService
	IncidentRoles *IncidentRolesService
	Incidents     *IncidentsService
	// contains filtered or unexported fields
}

A Client manages communication with the Incident.io API.

func NewClient

func NewClient(apiKey string, httpClient *http.Client) *Client

NewClient returns a new Incident.io API client. All endpoints require authentication, the apiKey should be set. If a nil httpClient is provided, a new http.Client will be used.

func (*Client) BareDo

func (c *Client) BareDo(ctx context.Context, req *http.Request) (*Response, error)

BareDo sends an API request and lets you handle the api response. If an error or API error occurs, the error will contain more information. Otherwise you are supposed to read and close the response's Body.

The provided ctx must be non-nil, if it is nil an error is returned. If it is canceled or times out, ctx.Err() will be returned.

func (*Client) Client

func (c *Client) Client() *http.Client

Client returns the http.Client used by this Incident.io client.

func (*Client) Do

func (c *Client) Do(ctx context.Context, req *http.Request, v interface{}) (*Response, error)

Do sends an API request and returns the API response. The API response is JSON decoded and stored in the value pointed to by v, or returned as an error if an API error has occurred. If v implements the io.Writer interface, the raw response body will be written to v, without attempting to first decode it. If v is nil, and no error hapens, the response is returned as is.

The provided ctx must be non-nil, if it is nil an error is returned. If it is canceled or times out, ctx.Err() will be returned.

func (*Client) NewRequest

func (c *Client) NewRequest(method, urlStr string, body interface{}) (*http.Request, error)

NewRequest creates an API request. A relative URL can be provided in urlStr, in which case it is resolved relative to the BaseURL of the Client. Relative URLs should always be specified without a preceding slash. If specified, the value pointed to by body is JSON encoded and included as the request body.

type CustomField

type CustomField struct {
	// When the action was created
	CreatedAt time.Time `json:"created_at"`

	// Description of the custom field
	Description string `json:"description"`

	// Type of custom field
	FieldType string `json:"field_type"`

	// Unique identifier for the custom field
	Id string `json:"id"`

	// Human readable name for the custom field
	Name string `json:"name"`

	// What options are available for this custom field, if this field has options
	Options []CustomFieldOption `json:"options"`

	// Whether a custom field should be required in the incident close modal
	RequireBeforeClosure bool `json:"require_before_closure"`

	// Whether a custom field should be required in the incident creation modal
	RequireBeforeCreation bool `json:"require_before_creation"`

	// Whether a custom field should be shown in the incident close modal
	ShowBeforeClosure bool `json:"show_before_closure"`

	// Whether a custom field should be shown in the incident creation modal
	ShowBeforeCreation bool `json:"show_before_creation"`

	// When the action was last updated
	UpdatedAt time.Time `json:"updated_at"`
}

type CustomFieldEntry

type CustomFieldEntry struct {
	CustomField CustomFieldTypeInfo `json:"custom_field"`

	// List of custom field values set on this entry
	Values []CustomFieldValue `json:"values"`
}

type CustomFieldOption

type CustomFieldOption struct {
	// ID of the custom field this option belongs to
	CustomFieldId string `json:"custom_field_id"`

	// Unique identifier for the custom field option
	Id string `json:"id"`

	// Sort key used to order the custom field options correctly
	SortKey int64 `json:"sort_key"`

	// Human readable name for the custom field option
	Value string `json:"value"`
}

type CustomFieldResponse

type CustomFieldResponse struct {
	CustomField CustomField `json:"custom_field"`
}

type CustomFieldTypeInfo

type CustomFieldTypeInfo struct {
	// Description of the custom field
	Description string `json:"description"`

	// Type of custom field
	FieldType string `json:"field_type"`

	// Unique identifier for the custom field
	Id string `json:"id"`

	// Human readable name for the custom field
	Name string `json:"name"`

	// What options are available for this custom field, if this field has options
	Options []CustomFieldOption `json:"options"`
}

type CustomFieldValue

type CustomFieldValue struct {
	// Link value
	ValueLink string `json:"value_link,omitempty"`

	// Numeric value
	ValueNumeric string             `json:"value_numeric,omitempty"`
	ValueOption  *CustomFieldOption `json:"value_option,omitempty"`

	// Text value
	ValueText string `json:"value_text,omitempty"`
}

type CustomFieldsList

type CustomFieldsList struct {
	CustomFields []CustomField `json:"custom_fields"`
}

type CustomFieldsService

type CustomFieldsService service

CustomFieldsService handles communication with the custom field related methods of the Incident.io API.

API docs: https://api-docs.incident.io/#tag/Custom-Fields

func (*CustomFieldsService) Get

Get returns a single custom field.

id represents the unique identifier for the custom field

API docs: https://api-docs.incident.io/#operation/Custom%20Fields_Show

func (*CustomFieldsService) List

List list all custom fields for an organisation.

API docs: https://api-docs.incident.io/#operation/Custom%20Fields_List

type Error

type Error struct {
	// validation error code
	Code string `json:"code"`
	// Message describing the error.
	Message string      `json:"message"`
	Source  ErrorSource `json:"source"`
}

An Error reports more details on an individual error in an ErrorResponse.

API docs: https://api-docs.incident.io/#section/Making-requests/Errors

func (*Error) Error

func (e *Error) Error() string

type ErrorResponse

type ErrorResponse struct {
	// HTTP response that caused this error
	Response *http.Response

	// References the type of error
	Type string `json:"type"`
	// Contains the HTTP status
	Status int `json:"status"`
	// Request ID that can be provided to incident.io support to help debug questions with your API request
	RequestID string `json:"request_id"`

	// A list of individual errors, which go into detail about why the error occurred
	Errors []Error `json:"errors"`
}

An ErrorResponse reports one or more errors caused by an API request.

API docs: https://api-docs.incident.io/#section/Making-requests/Errors

func (*ErrorResponse) Error

func (r *ErrorResponse) Error() string

type ErrorSource

type ErrorSource struct {
	Field string `json:"field"`
}

type ExternalIssueReference

type ExternalIssueReference struct {
	// Human readable ID for the issue
	IssueName string `json:"issue_name"`

	// URL linking directly to the action in the issue tracker
	IssuePermalink string `json:"issue_permalink"`

	// ID of the issue tracker provider
	Provider string `json:"provider"`
}

type Incident

type Incident struct {
	// The call URL attached to this incident
	CallUrl string `json:"call_url,omitempty"`

	// When the incident was created
	CreatedAt time.Time `json:"created_at"`

	// Custom field entries for this incident
	CustomFieldEntries []CustomFieldEntry `json:"custom_field_entries"`

	// Unique identifier for the incident
	Id string `json:"id"`

	// A list of who is assigned to each role for this incident
	IncidentRoleAssignments []IncidentRoleAssignment `json:"incident_role_assignments"`

	// Explanation of the incident
	Name string `json:"name"`

	// Description of the incident
	PostmortemDocumentUrl string `json:"postmortem_document_url,omitempty"`

	// Reference to this incident, as displayed across the product
	Reference string   `json:"reference"`
	Creator   Actor    `json:"creator"`
	Severity  Severity `json:"severity"`

	// ID of the Slack channel in the organisation Slack workspace
	SlackChannelId string `json:"slack_channel_id"`

	// Name of the slack channel
	SlackChannelName string `json:"slack_channel_name,omitempty"`

	// Current status of the incident
	Status string `json:"status"`

	// Detailed description of the incident
	Summary string `json:"summary,omitempty"`

	// Incident lifecycle events and when they last occurred
	Timestamps *[]IncidentTimestamp `json:"timestamps,omitempty"`

	// Whether the incident is real, a test, or a tutorial
	Type string `json:"type"`

	// When the incident was last updated
	UpdatedAt time.Time `json:"updated_at"`

	// Whether the incident is public or private
	Visibility string `json:"visibility"`
}

type IncidentResponse

type IncidentResponse struct {
	Incident Incident `json:"incident"`
}

type IncidentRole

type IncidentRole struct {
	// When the action was created
	CreatedAt time.Time `json:"created_at"`

	// Describes the purpose of the role
	Description string `json:"description"`

	// Unique identifier for the role
	Id string `json:"id"`

	// Provided to whoever is nominated for the role
	Instructions string `json:"instructions"`

	// Human readable name of the incident role
	Name string `json:"name"`

	// Whether incident require this role to be set
	Required bool `json:"required"`

	// Type of incident role
	RoleType string `json:"role_type"`

	// Short human readable name for Slack
	Shortform string `json:"shortform"`

	// When the action was last updated
	UpdatedAt time.Time `json:"updated_at"`
}

type IncidentRoleAssignment

type IncidentRoleAssignment struct {
	Assignee *User        `json:"assignee,omitempty"`
	Role     IncidentRole `json:"role"`
}

type IncidentRoleResponse

type IncidentRoleResponse struct {
	IncidentRole IncidentRole `json:"incident_role"`
}

type IncidentRolesList

type IncidentRolesList struct {
	IncidentRoles []IncidentRole `json:"incident_roles"`
}

type IncidentRolesService

type IncidentRolesService service

IncidentRolesService handles communication with the incident roles related methods of the Incident.io API.

API docs: https://api-docs.incident.io/#tag/Incident-Roles

func (*IncidentRolesService) Get

Get returns a single incident role.

id represents the unique identifier for the incident role

API docs: https://api-docs.incident.io/#operation/Incident%20Roles_Show

func (*IncidentRolesService) List

List list all incident roles for an organisation.

API docs: https://api-docs.incident.io/#operation/Incident%20Roles_List

type IncidentTimestamp

type IncidentTimestamp struct {
	// When this last occurred, if it did
	LastOccurredAt time.Time `json:"last_occurred_at,omitempty"`

	// Name of the lifecycle event
	Name string `json:"name"`
}

type IncidentsList

type IncidentsList struct {
	Incidents      []Incident      `json:"incidents"`
	PaginationMeta *PaginationMeta `json:"pagination_meta,omitempty"`
}

type IncidentsListOptions

type IncidentsListOptions struct {
	// Number of records to return
	PageSize int `url:"page_size,omitempty"`

	// An incident's ID. This endpoint will return a list of incidents created after this incident.
	After string `url:"after,omitempty"`

	// Filter for incidents in these statuses
	Status []string `url:"status,omitempty"`
}

IncidentsListOptions defines parameters for IncidentsService.List.

type IncidentsService

type IncidentsService service

IncidentsService handles communication with the incident related methods of the Incident.io API.

API docs: https://api-docs.incident.io/#tag/Incidents

func (*IncidentsService) Get

Get returns a single incident.

id represents the unique identifier for the incident

API docs: https://api-docs.incident.io/#operation/Incidents_Show

func (*IncidentsService) List

List list all incidents for an organisation.

API docs: https://api-docs.incident.io/#operation/Incidents_List

type PaginationMeta

type PaginationMeta struct {
	// If provided, were records after a particular ID
	After string `json:"after,omitempty"`

	// What was the maximum number of results requested
	PageSize int64 `json:"page_size"`

	// How many matching records were there in total
	TotalRecordCount int64 `json:"total_record_count"`
}

type Response

type Response struct {
	*http.Response
}

Response is a Incident.io API response. This wraps the standard http.Response returned from Incident.io. Right now, it only covers the native http response. We wrap it to enable future extension like providing convenient access to things like pagination information.

type SeveritiesList

type SeveritiesList struct {
	Severities []Severity `json:"severities"`
}

type SeveritiesService

type SeveritiesService service

SeveritiesService handles communication with the severity related methods of the Incident.io API.

API docs: https://api-docs.incident.io/#tag/Severities

func (*SeveritiesService) Get

Get returns a single incident severity.

id represents the unique identifier for the severity

API docs: https://api-docs.incident.io/#operation/Severities_Show

func (*SeveritiesService) List

List list all incident severities for an organisation.

API docs: https://api-docs.incident.io/#operation/Severities_List

type Severity

type Severity struct {
	// When the action was created
	CreatedAt time.Time `json:"created_at"`

	// Description of the severity
	Description string `json:"description"`

	// Unique identifier of the severity
	Id string `json:"id"`

	// Human readable name of the severity
	Name string `json:"name"`

	// Rank to help sort severities (lower numbers are less severe)
	Rank int64 `json:"rank"`

	// When the action was last updated
	UpdatedAt time.Time `json:"updated_at"`
}

type SeverityResponse

type SeverityResponse struct {
	Severity Severity `json:"severity"`
}

type User

type User struct {
	// Unique identifier of the user
	Id string `json:"id"`

	// Name of the user
	Name string `json:"name"`

	// Role of the user
	Role string `json:"role"`

	// Email of the user
	Email string `json:"email"`

	// Slack User ID of the user
	SlackUserID string `json:"slack_user_id"`
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL