Giter Site home page Giter Site logo

pagerduty / go-pagerduty Goto Github PK

View Code? Open in Web Editor NEW
284.0 133.0 240.0 804 KB

go client library for PagerDuty v2 API

Home Page: https://v2.developer.pagerduty.com/docs/rest-api

License: Apache License 2.0

Makefile 0.09% Go 99.89% Dockerfile 0.03%
renovate-enabled

go-pagerduty's Introduction

GoDoc Go Report Card License

go-pagerduty

go-pagerduty is a CLI and go client library for the PagerDuty API.

Installation

To add the latest stable version to your project:

go get github.com/PagerDuty/[email protected]

If you instead wish to work with the latest code from main:

go get github.com/PagerDuty/go-pagerduty@latest

Usage

CLI

The CLI requires an authentication token, which can be specified in .pd.yml file in the home directory of the user, or passed as a command-line argument. Example of config file:

---
authtoken: fooBar

Commands

pd command provides a single entrypoint for all the API endpoints, with individual API represented by their own sub commands. For an exhaustive list of sub-commands, try:

pd --help

An example of the service sub-command

pd service list

Client Library

NOTICE: Breaking API Changes in v1.5.0

As part of the v1.5.0 release, we have fixed features that have never worked correctly and require a breaking API change to fix. One example is the issue reported in #232, as well as a handful of other examples within the v1.5.0 milestone.

If you are impacted by a breaking change in this release, you should audit the functionality you depended on as it may not have been working. If you cannot upgrade for some reason, the v1.4.x line of releases should still work. At the time of writing v1.4.3 was the latest, and we intend to backport any critical fixes for the time being.

Example Usage with API Token Authentication

package main

import (
	"context"
	"fmt"

	"github.com/PagerDuty/go-pagerduty"
)

var authtoken = "" // Set your auth token here

func main() {
	ctx := context.Background()
	client := pagerduty.NewClient(authtoken)

	var opts pagerduty.ListEscalationPoliciesOptions
	eps, err := client.ListEscalationPoliciesWithContext(ctx, opts)
	if err != nil {
		panic(err)
	}
	for _, p := range eps.EscalationPolicies {
		fmt.Println(p.Name)
	}
}

The PagerDuty API client also exposes its HTTP client as the HTTPClient field. If you need to use your own HTTP client, for doing things like defining your own transport settings, you can replace the default HTTP client with your own by simply by setting a new value in the HTTPClient field.

package main

import (
	"context"
	"fmt"
	"strings"

	"github.com/PagerDuty/go-pagerduty"
)

func main() {
	ctx := context.Background()
	var opts pagerduty.ListEscalationPoliciesOptions
	clientId := "client_id_goes_here"
	clientSecret := "secret_goes_here"
	scopes := strings.Split("as_account-us.companysubdomain escalation_policies.read", " ")
	scopedOAuthOpts := pagerduty.WithScopedOAuthAppTokenSource(
		pagerduty.NewFileTokenSource(ctx, clientId, clientSecret, scopes, "token.json"),
	)

	client := pagerduty.NewClient("", scopedOAuthOpts)
	eps, err := client.ListEscalationPoliciesWithContext(ctx, opts)
	if err != nil {
		panic(err)
	}
	for _, p := range eps.EscalationPolicies {
		fmt.Println(p.Name)
	}
}

API Error Responses

For cases where your request results in an error from the API, you can use the errors.As() function from the standard library to extract the pagerduty.APIError error value and inspect more details about the error, including the HTTP response code and PagerDuty API Error Code.

package main

import (
	"fmt"
	"github.com/PagerDuty/go-pagerduty"
)

var	authtoken = "" // Set your auth token here

func main() {
	ctx := context.Background()
	client := pagerduty.NewClient(authtoken)
	user, err := client.GetUserWithContext(ctx, "NOTREAL", pagerduty.GetUserOptions{})
	if err != nil {
		var aerr pagerduty.APIError

		if errors.As(err, &aerr) {
			if aerr.RateLimited() {
				fmt.Println("rate limited")
				return
			}

			fmt.Println("unknown status code:", aerr.StatusCode)

			return
		}

		panic(err)
	}
	fmt.Println(user)
}

Extending and Debugging Client

Extending The Client

The *pagerduty.Client has a Do method which allows consumers to wrap the client, and make their own requests to the PagerDuty API. The method signature is similar to that of the http.Client.Do method, except it also includes a bool to incidate whether the API endpoint is authenticated (i.e., the REST API). When the API is authenticated, the client will annotate the request with the appropriate headers to be authenticated by the API.

If the PagerDuty client doesn't natively expose functionality that you wish to use, such as undocumented JSON fields, you can use the Do() method to issue your own request that you can parse the response of.

Likewise, you can use it to issue requests to the API for the purposes of debugging. However, that's not the only mechanism for debugging.

Debugging the Client

The *pagerduty.Client has a method that allows consumers to enable debug functionality, including interception of PagerDuty API responses. This is done by using the SetDebugFlag() method using the pagerduty.DebugFlag unsigned integer type. There are also exported constants to help consumers enable specific debug behaviors.

Capturing Last PagerDuty Response

If you're not getting the response you expect from the PagerDuty Go client, you can enable the DebugCaptureLastResponse debug flag to capture the HTTP responses. You can then use one of the methods to make an API call, and then inspect the API response received. For example:

client := pagerduty.NewClient("example")

client.SetDebugFlag(pagerduty.DebugCaptureLastResponse)

oncalls, err := client.ListOnCallsWithContext(ctx, pagerduty.ListOnCallOptions{})

resp, ok := client.LastAPIResponse()
if ok { // resp is an *http.Response we can inspect
	body, err := httputil.DumpResponse(resp, true)
    // ...
}

Included Packages

webhookv3

Support for V3 of PagerDuty Webhooks is provided via the webhookv3 package. The intent is for this package to provide signature verification and decoding helpers.

Contributing

  1. Fork it ( https://github.com/PagerDuty/go-pagerduty/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

License

Apache 2

go-pagerduty's People

Contributors

afirth avatar atomicules avatar averstappen avatar cerealboy avatar chenrui333 avatar chrisforrette avatar chuckcrawford avatar cluarkhpe avatar dineshba avatar dobs avatar giedriuss avatar goatherder avatar heimweh avatar hsn723 avatar imjaroiswebdev avatar kilianw avatar lfepp avatar luqasn avatar mattstratton avatar melchiormoulin avatar mimato avatar mrzacarias avatar mwhite-ibm avatar nbutton23 avatar ranjib avatar sjeanpierre avatar soullivaneuh avatar stupidscience avatar theckman avatar zonorti avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-pagerduty's Issues

Paging help

Hi,
I need list all incidents in week and I'm over 25 limit. Is easy way how setup in client to get all incidents.

I'm using this:

func GetIncidents(dateFrom string, dateTo string) *pagerduty.ListIncidentsResponse {
	var teamIDs []string
	var timeZone string = "UTC"
	var sortBy string = "incident_number"
	var includes []string
	opts := pagerduty.ListIncidentsOptions{
		TeamIDs:  teamIDs,
		Since:    dateFrom,
		Until:    dateTo,
		TimeZone: timeZone,
		SortBy:   sortBy,
		Includes: includes,
	}
	var c config
	authtoken := c.GetConf().AuthToken
	client := pagerduty.NewClient(authtoken)
	incidentList, err := client.ListIncidents(opts)
	if err != nil {
		panic(err)
	}
	return incidentList
}

but not work over limit 25 (default paging limit in API).

Escalation Policy's repeat_enabled Is Ignored

It doesn't matter if I explicitly set the repeat_enabled flag when making a call to the PagerDuty API for an escalation policy--either way the value is ignored. Also, I don't get a value back for this option when calling the API.

Manage Incident gives error

I am trying to call from golang library with the below code
`incident := Incident{
Id: "PQOWA9O",
Type: "incident_reference",
Status: "acknowledged",
}

opts := ManageIncidentsOptions{
    From: "[email protected]",
}
incidents := []Incident{incident}
err := client.ManageIncidents(incidents, opts)
if err != nil {
    t.Error(err.Error())
}`

But getting below error
pagerduty_test.go:37: Failed call API endpoint. HTTP response code: 400. Error: &{2016 You must specify a user's email address in the "From" header to perform this action []}

Documentation does not match code

The README and repository description states this is a library using your v2 API. Taking a look into the client.go it uses the v1 endpoint so this is in fact not a v2 library…

Also for example CreateOverride does send invalid data according to the specification of the v2 API documentation. Even when patching the data the response code handling is broken…

Please label this as an v1 library or port it to v2.

build error cannot find package

New to go and pagerduty. I'm trying to install go-pagerduty on Ubuntu 18.04. Below are the steps that I performed.

as root
cd /root
apt install golang-go
go get github.com/PagerDuty/go-pagerduty

vi ~/.bashrc
export GOPATH=/root/go

source ~/.bashrc
cd $GOPATH/src/github.com/PagerDuty/go-pagerduty
go build -o $GOPATH/bin/pd command/*

It returned error:

root@ubuntu:~/go/src/github.com/PagerDuty/go-pagerduty# go build -o $GOPATH/bin/pd command/*
command/addon_delete.go:5:2: cannot find package "github.com/Sirupsen/logrus" in any of:
	/usr/lib/go-1.10/src/github.com/Sirupsen/logrus (from $GOROOT)
	/root/go/src/github.com/Sirupsen/logrus (from $GOPATH)
command/ability_check.go:5:2: cannot find package "github.com/mitchellh/cli" in any of:
	/usr/lib/go-1.10/src/github.com/mitchellh/cli (from $GOROOT)
	/root/go/src/github.com/mitchellh/cli (from $GOPATH)
command/meta.go:8:2: cannot find package "github.com/mitchellh/go-homedir" in any of:
	/usr/lib/go-1.10/src/github.com/mitchellh/go-homedir (from $GOROOT)
	/root/go/src/github.com/mitchellh/go-homedir (from $GOPATH)
command/addon_list.go:8:2: cannot find package "gopkg.in/yaml.v2" in any of:
	/usr/lib/go-1.10/src/gopkg.in/yaml.v2 (from $GOROOT)
	/root/go/src/gopkg.in/yaml.v2 (from $GOPATH)
root@ubuntu:~/go/src/github.com/PagerDuty/go-pagerduty# 

Any suggestion how to fix it?

listOverrides result in JSON unmarshall failure

The ListOverride method tries to parse the returned JSON from the API, this is always failing because the first element of the json is a total: x field, where x is an int not an Override. Hence this function can't be used to query the API.

Missing check for error in client.go

Bug description

If this function call returns an error (I accidentally added a newline character to the end of the escalation policy id when called from GetEscalationPolicy), the call in the following line may result in a crash as req.Header may be nil.

However, if nil would be returned in case of an error to GetEscalationPolicy, this defer results in a crash as res.Body will be nil as well.

Expected behaviour

Erroneous input shouldn't result in a crash but the error being returned to the user.

Update logrus imports to github.com/sirupsen/logrus

The logrus owner recently changed the case of their handle (Sirupsen -> sirupsen). This causes issues on case-insensitive filesystems (like in macos), since vendoring both versions of the package results in filepath collisions. The logrus maintainer has stated that they will keep the new name (see sirupsen/logrus#570), so it is up to other packages to update their imports.

Package test coverage is lacking

PagerDuty is a service that we've come to expect to be reliable and trustworthy. It's one of the few services in the world expected to be fully operational if things go sideways with major hosting providers. However, you can only be this way if you test the system to ensure its proper operation. It's why Failure Friday became a core tenet of Engineering at PagerDuty.

I'd like to use this client, and to trust its operation, that doesn't seem possible with the current lack of test coverage. Would it be possible to prioritize some testing of this package to catch bugs?

Custom connection settings

Currently, the Client in this package only allows connections to PagerDuty's live service using the default Go connection settings. It would be extremely useful to me to be able to create a client with custom connection settings. Here are two specific use cases I had in mind:

  1. I would like to be able to use this package in a service that has to go through an HTTP proxy to get to the outside Internet. The standard net/http package lets me set up connections through a proxy via Transport.Proxy. But to make use of this setting, I need a pagerduty.Client that can use an arbitrary *http.Client instead of the default.

  2. I would like to be able to test my code that uses a Client without actually operating on my real PagerDuty account. One way to achieve this goal is to write HTTP server stubs and have the client contact my testing server (e.g., from net/http/httptest). To do that, I need a client that can send its requests to an arbitrary endpoint, not always api.pagerduty.com.

Are there any existing plans that address these needs? I'd be happy to send in a pull request if needed.

Trouble creating an integration

Hello,

I'm trying to create an Events API V1 integration programatically.

My code looks like this:

integration := pagerduty.Integration{Type: "generic_events_api_inbound_integration_reference"}
integration.Type = "generic_events_api_inbound_integration_reference"
eventsAPIV1Integration, err := client.CreateIntegration(service.ID, integration)
if err != nil {
       return "", err
}

I get the following error: FATA[0007] Failed call API endpoint. HTTP response code: 400. Error: &{2001 Invalid Input Provided [Type cannot be empty.]}

If I create the integration by hand in the UI, this code succeeds:

for _, integration := range service.Integrations {
       if integration.Type == "generic_events_api_inbound_integration_reference" {
               eventsAPIV1Integration, err = client.GetIntegration(service.ID, integration.ID, pagerduty.GetIntegrationOptions{})
               if err != nil {
                     return "", err
              }
        }
}

I'm trying to use the same integration.Type: generic_events_api_inbound_integration_reference, but it doesn't seem to work.

failed to create an incident

Here is my code:

        opts := officialPD.CreateIncidentOptions{
                Type: "incident",
                Title: title,
                Service: &service,
                Body: &body,
                EscalationPolicy: &escalationPolicy,
        }
 _, err := client.CreateIncident(INCIDENT_FROM, &opts)

I have the title correctly set.
But I got the error like:

panic: Failed call API endpoint. HTTP response code: 400. Error: &{2001 Invalid Input Provided [Title cannot be empty.]}

Does anyone know what is wrong?

Fix help flag behavior

/bin/pd  schedule override create -h
pd schedule-override create <SERVICE-ID> <FILE> Create a schedule override from json file
ERRO[0000] flag: help requested                         

Priority field should be optional according to API spec

Managing an incident should not require the priority field according to the API spec. It's marked as optional.
However, trying to manage an incident without this field returns:

err="Failed call API endpoint. HTTP response code: 400. Error: &{2001 Invalid Input Provided [Priority id cannot be empty.]}"

Moreover, the incident priority feature is disabled in our Pagerduty.
Can you confirm that's a bug? Kindly asking for help here @mattstratton 🙏

Swallowing API responses

In incident.go, ability.go, addon.go, event.go, and others, the HTTP response is swallowed rather than returned. I don't think it's controversial to suggest that API users might be interested in the API response and they should be the ones deciding whether or not to use the data from the response.

For example, if someone calls pagerduty.Client.ManageIncidents, they might be interested in seeing how many of their incidents were managed, or get the exact time when they were accepted. Without the response, however, there is no way to do that.

Support Event Transformer Code?

Via a support ticket, I was told earlier today that I can add the code for an event transformer via the config property of the integration payload. But the integration object in this API doesn't have a config property, so this library cannot be used.

{
    "integration": {
        "config": {
            "fields": {
                "code": {
                    "value": "// Hello world"
                }
            }
        },
        "name": "Custom Event Transformer",
        "summary": "My Custom Event Transformer",
        "type": "event_transformer_api_inbound_integration",
        "vendor": {
            "id": "PCJ0EFQ",
            "type": "vendor_reference"
        }
    }
}

Publish CLI binaries as releases

Would it be possible to start publishing releases of the CLI to Github releases? go install github.com/PagerDuty/go-pagerduty doesn't install the binary to the $GOPATH/bin and they only way I see to get access to the CLI is to compile it and link it yourself. This would make it really useful for folks using it in CI/CD scripts, for instance.

Problems running freshly built pd utility

I am trying to run the utility but i can't get anything to output aside from the help menu. When running the utility and inspecting the return code, I am getting a 1. This makes me think that I might be hitting this line https://github.com/PagerDuty/go-pagerduty/blob/master/command/main.go#L123 but I don't get any other errors even if I swap stderr with stdout.

My initial impression is that it keeps hitting this help menu because something was wrong with my api key that I tried to pass with -authtoken="MYKEY" and with the alternative ~/.pd.yml. I tested out the escalation policy example was able to get results with the key, so it should be a valid key.

I'll keep digging into the code, but I thought it would be worth creating an issue to track this as well.

Assignment struct has no json conversion

This causes problems for some of the methods. For example, I spent a long time trying to figure out why the ManageIncidents method kept giving this message:

Unable to acknowledge Failed call API endpoint. HTTP response code: 400. Error: &{2001 Invalid Input Provided [Assignee cannot be empty.]}

I can make that change and make a pull request if needed, though it was a simple fix once I figured out what was wrong

Help with incident creation API

This is not specifically an issue with the go-pagerduty package but I was hoping somebody here might be able to help. I'm having trouble getting the incident creation POST endpoint to work.

I've copy pasted the request body found on https://v2.developer.pagerduty.com/docs/incident-creation-api

{
  "incident": {
    "title": "Your desk is on fire!",
    "service": {
      "id": "PW7YESS",
      "type": "service_reference"
    },
    "assignments": [{
      "assignee" : {
    	  "id": "PZUVZZZ",
    	  "type": "user_reference"
      }
    }]
  }
}

I substituted IDs from my team's pagerduty. The response I got back was HTTP 400 with an unhelpful error message

{"error":{"message":"Invalid Input Provided","code":2001,"errors":["params must be a Hash"]}}

Any guidance?

Memory leak because of response body is not closed

There is a memory leak in event.go - func CreateEvent, the closing of the response must take place right after the checking of the error, currently when the response status is not equal to 200, the response body will not be closed - see pull request #65

Possible to create new service and integration together

I'm wondering it it is possible to create a new service and request that a new integration be created simultaneously. Is this possible to do with the REST API or do I have to create an integration first and then reference that from my new service?

ListIncidents() essentially ignores ListIncidentsOptions.Includes parameter

When I call ListIncidents with an option to include the trigger log entry:

	o := pagerduty.ListIncidentsOptions{
		// ...
		Includes: []string{"first_trigger_log_entries"},
	}

I get back Incident structures, which have FirstTriggerLogEntry as APIObject, which is only a reference, not a joined object. As far as I can tell looking at the code and experimenting with curl calls, the actual response does include log entries as expected, they just get dropped by json.Decoder.Decode, because there's nothing for them to deserialize into.

I don't see how this could be addressed by the library user. Can this get fixed internally? Perhaps by introducing an interface{} field to APIObject?

List escalation policy with current on call members using include `current_oncall`

The PagerDuty UI uses the following endpoint to calculate the current oncall list:

https://api.pagerduty.com/api/v1/escalation_policies?include[]=current_oncall&limit=5

This appears to be the only way to get the oncall list with users start and end times. Interestingly using include with current_oncall is not documented

I could not retrieve the same data using https://api-reference.pagerduty.com/#!/On-Calls/get_oncalls

Support V2 events

In order to leverage the new severity feature for PagerDuty events, this must be updated to utilize the v2 of the events api. I'm willing to do most of the work on updating. I'm looking for some guidance on how the maintainers would prefer to approach backward compatibility with the V1 events.

Make a release?

The last release was May 28, 2018. This breaks dep with the defaults.

Mock Client?

In order to be able to write unit tests for a package using this one as a dependency, it would be nice to be able to mock it.

Making the Client into an interface, with a struct implementing everything it does would allow creating additional structs which implement the interface too, to mock the behavior.

Poorly documented, library code broken, please step it up.

This library is surprisingly poorly documented, no examples around at all. I have to dig in the source code, this defeats the whole purpose of having a library and I have no idea the structs represent.

type CreateIncidentOptions struct {
	Type             string        `json:"type"`
	Title            string        `json:"title"`
	Service          *APIReference `json:"service"`
	Priority         *APIReference `json:"priority,omitempty"`
	IncidentKey      string        `json:"incident_key,omitempty"`
	Body             *APIDetails   `json:"body,omitempty"`
	EscalationPolicy *APIReference `json:"escalation_policy,omitempty"`
}

What is an APIReference? or an APIDetail? No examples.

EDIT: Searched in other people's code repos and now get the same error as mentioned in this ticket #165, the fix of which was done eight days ago.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.