Skip to content

Commit

Permalink
Merge pull request #228 from PagerDuty/business-services
Browse files Browse the repository at this point in the history
adding business_service and service_dependency
  • Loading branch information
Scott McAllister authored Jun 15, 2020
2 parents 2467624 + 23cbde2 commit ac15509
Show file tree
Hide file tree
Showing 5 changed files with 499 additions and 1 deletion.
127 changes: 127 additions & 0 deletions business_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package pagerduty

import (
"fmt"
"net/http"

"github.com/google/go-querystring/query"
)

// BusinessService represents a business service.
type BusinessService struct {
ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Type string `json:"type,omitempty"`
Summary string `json:"summary,omitempty"`
Self string `json:"self,omitempty"`
PointOfContact string `json:"point_of_contact,omitempty"`
HTMLUrl string `json:"html_url,omitempty"`
Description string `json:"description,omitempty"`
Team *BusinessServiceTeam `json:"team,omitempty"`
}

// BusinessServiceTeam represents a team object in a business service
type BusinessServiceTeam struct {
ID string `json:"id,omitempty"`
Type string `json:"type,omitempty"`
Self string `json:"self,omitempty"`
}

// BusinessServicePayload represents payload with a business service object
type BusinessServicePayload struct {
BusinessService *BusinessService `json:"business_service,omitempty"`
}

// ListBusinessServicesResponse represents a list response of business services.
type ListBusinessServicesResponse struct {
Total uint `json:"total,omitempty"`
BusinessServices []*BusinessService `json:"business_services,omitempty"`
Offset uint `json:"offset,omitempty"`
More bool `json:"more,omitempty"`
Limit uint `json:"limit,omitempty"`
}

// ListBusinessServiceOptions is the data structure used when calling the ListBusinessServices API endpoint.
type ListBusinessServiceOptions struct {
APIListObject
}

// ListBusinessServices lists existing business services.
func (c *Client) ListBusinessServices(o ListBusinessServiceOptions) (*ListBusinessServicesResponse, error) {
queryParms, err := query.Values(o)
if err != nil {
return nil, err
}
businessServiceResponse := new(ListBusinessServicesResponse)
businessServices := make([]*BusinessService, 0)

// Create a handler closure capable of parsing data from the business_services endpoint
// and appending resultant business_services to the return slice.
responseHandler := func(response *http.Response) (APIListObject, error) {
var result ListBusinessServicesResponse
if err := c.decodeJSON(response, &result); err != nil {
return APIListObject{}, err
}

businessServices = append(businessServices, result.BusinessServices...)

// Return stats on the current page. Caller can use this information to
// adjust for requesting additional pages.
return APIListObject{
More: result.More,
Offset: result.Offset,
Limit: result.Limit,
}, nil
}

// Make call to get all pages associated with the base endpoint.
if err := c.pagedGet("/business_services"+queryParms.Encode(), responseHandler); err != nil {
return nil, err
}
businessServiceResponse.BusinessServices = businessServices

return businessServiceResponse, nil
}

// CreateBusinessService creates a new business service.
func (c *Client) CreateBusinessService(b *BusinessService) (*BusinessService, *http.Response, error) {
data := make(map[string]*BusinessService)
data["business_service"] = b
resp, err := c.post("/business_services", data, nil)
return getBusinessServiceFromResponse(c, resp, err)
}

// GetBusinessService gets details about a business service.
func (c *Client) GetBusinessService(ID string) (*BusinessService, *http.Response, error) {
resp, err := c.get("/business_services/" + ID)
return getBusinessServiceFromResponse(c, resp, err)
}

// DeleteBusinessService deletes a business_service.
func (c *Client) DeleteBusinessService(ID string) error {
_, err := c.delete("/business_services/" + ID)
return err
}

// UpdateBusinessService updates a business_service.
func (c *Client) UpdateBusinessService(b *BusinessService) (*BusinessService, *http.Response, error) {
v := make(map[string]*BusinessService)
v["business_service"] = b
resp, err := c.put("/business_services/"+b.ID, v, nil)
return getBusinessServiceFromResponse(c, resp, err)
}

func getBusinessServiceFromResponse(c *Client, resp *http.Response, err error) (*BusinessService, *http.Response, error) {
if err != nil {
return nil, nil, err
}
var target map[string]BusinessService
if dErr := c.decodeJSON(resp, &target); dErr != nil {
return nil, nil, fmt.Errorf("Could not decode JSON response: %v", dErr)
}
t, nodeOK := target["business_service"]
if !nodeOK {
return nil, nil, fmt.Errorf("JSON response does not have business_service field")
}
return &t, resp, nil
}
135 changes: 135 additions & 0 deletions business_service_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package pagerduty

import (
"net/http"
"testing"
)

// List BusinessServices
func TestBusinessService_List(t *testing.T) {
setup()
defer teardown()

mux.HandleFunc("/business_services/", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
w.Write([]byte(`{"business_services": [{"id": "1"}]}`))
})

var listObj = APIListObject{Limit: 0, Offset: 0, More: false, Total: 0}
var client = &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient}
var opts = ListBusinessServiceOptions{
APIListObject: listObj,
}
res, err := client.ListBusinessServices(opts)
if err != nil {
t.Fatal(err)
}
want := &ListBusinessServicesResponse{
BusinessServices: []*BusinessService{
{
ID: "1",
},
},
}

testEqual(t, want, res)
}

// Create BusinessService
func TestBusinessService_Create(t *testing.T) {
setup()
defer teardown()

mux.HandleFunc("/business_services", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
w.Write([]byte(`{"business_service": {"id": "1", "name": "foo"}}`))
})

var client = &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient}
input := &BusinessService{
Name: "foo",
}
res, _, err := client.CreateBusinessService(input)

want := &BusinessService{
ID: "1",
Name: "foo",
}

if err != nil {
t.Fatal(err)
}
testEqual(t, want, res)
}

// Get BusinessService
func TestBusinessService_Get(t *testing.T) {
setup()
defer teardown()

mux.HandleFunc("/business_services/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
w.Write([]byte(`{"business_service": {"id": "1", "name":"foo"}}`))
})

var client = &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient}
ruleSetID := "1"

res, _, err := client.GetBusinessService(ruleSetID)

want := &BusinessService{
ID: "1",
Name: "foo",
}

if err != nil {
t.Fatal(err)
}
testEqual(t, want, res)
}

// Update BusinessService
func TestBusinessService_Update(t *testing.T) {
setup()
defer teardown()

mux.HandleFunc("/business_services/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PUT")
w.Write([]byte(`{"business_service": {"id": "1", "name":"foo"}}`))
})

var client = &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient}
input := &BusinessService{
ID: "1",
Name: "foo",
}
res, _, err := client.UpdateBusinessService(input)

want := &BusinessService{
ID: "1",
Name: "foo",
}

if err != nil {
t.Fatal(err)
}
testEqual(t, want, res)
}

// Delete BusinessService
func TestBusinessService_Delete(t *testing.T) {
setup()
defer teardown()

mux.HandleFunc("/business_services/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
})

var client = &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient}
ID := "1"
err := client.DeleteBusinessService(ID)

if err != nil {
t.Fatal(err)
}
}
2 changes: 1 addition & 1 deletion ruleset.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ func (c *Client) CreateRuleset(r *Ruleset) (*Ruleset, *http.Response, error) {
return getRulesetFromResponse(c, resp, err)
}

// DeleteRuleset deletes a user.
// DeleteRuleset deletes a ruleset.
func (c *Client) DeleteRuleset(id string) error {
_, err := c.delete("/rulesets/" + id)
return err
Expand Down
68 changes: 68 additions & 0 deletions service_dependency.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package pagerduty

import (
"net/http"
)

// ServiceDependency represents a relationship between a business and technical service
type ServiceDependency struct {
ID string `json:"id,omitempty"`
Type string `json:"type,omitempty"`
SupportingService *ServiceObj `json:"supporting_service,omitempty"`
DependentService *ServiceObj `json:"dependent_service,omitempty"`
}

// ServiceObj represents a service object in service relationship
type ServiceObj struct {
ID string `json:"id,omitempty"`
Type string `json:"type,omitempty"`
}

// ListServiceDependencies represents a list of dependencies for a service
type ListServiceDependencies struct {
Relationships []*ServiceDependency `json:"relationships,omitempty"`
}

// ListBusinessServiceDependencies lists dependencies of a business service.
func (c *Client) ListBusinessServiceDependencies(businessServiceID string) (*ListServiceDependencies, *http.Response, error) {
resp, err := c.get("/service_dependencies/business_services/" + businessServiceID)
if err != nil {
return nil, nil, err
}
var result ListServiceDependencies
return &result, resp, c.decodeJSON(resp, &result)
}

// ListTechnicalServiceDependencies lists dependencies of a technical service.
func (c *Client) ListTechnicalServiceDependencies(serviceID string) (*ListServiceDependencies, *http.Response, error) {
resp, err := c.get("/service_dependencies/technical_services/" + serviceID)
if err != nil {
return nil, nil, err
}
var result ListServiceDependencies
return &result, resp, c.decodeJSON(resp, &result)
}

// AssociateServiceDependencies Create new dependencies between two services.
func (c *Client) AssociateServiceDependencies(dependencies *ListServiceDependencies) (*ListServiceDependencies, *http.Response, error) {
data := make(map[string]*ListServiceDependencies)
data["relationships"] = dependencies
resp, err := c.post("/service_dependencies/associate", data, nil)
if err != nil {
return nil, nil, err
}
var result ListServiceDependencies
return &result, resp, c.decodeJSON(resp, &result)
}

// DisassociateServiceDependencies Disassociate dependencies between two services.
func (c *Client) DisassociateServiceDependencies(dependencies *ListServiceDependencies) (*ListServiceDependencies, *http.Response, error) {
data := make(map[string]*ListServiceDependencies)
data["relationships"] = dependencies
resp, err := c.post("/service_dependencies/disassociate", data, nil)
if err != nil {
return nil, nil, err
}
var result ListServiceDependencies
return &result, resp, c.decodeJSON(resp, &result)
}
Loading

0 comments on commit ac15509

Please sign in to comment.