Skip to content

Commit

Permalink
Update team.go to accept a context.Context and add role support
Browse files Browse the repository at this point in the history
Replaces #262

Updates #267
  • Loading branch information
theckman committed Mar 8, 2021
1 parent 1a0c44e commit 6586127
Showing 1 changed file with 135 additions and 24 deletions.
159 changes: 135 additions & 24 deletions team.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,82 +27,176 @@ type ListTeamOptions struct {
Query string `url:"query,omitempty"`
}

// ListTeams lists teams of your PagerDuty account, optionally filtered by a search query.
// ListTeams lists teams of your PagerDuty account, optionally filtered by a
// search query. It's recommended to use ListTeamsWithContext instead.
func (c *Client) ListTeams(o ListTeamOptions) (*ListTeamResponse, error) {
return c.ListTeamsWithContext(context.Background(), o)
}

// ListTeamsWithContext lists teams of your PagerDuty account, optionally
// filtered by a search query.
func (c *Client) ListTeamsWithContext(ctx context.Context, o ListTeamOptions) (*ListTeamResponse, error) {
v, err := query.Values(o)
if err != nil {
return nil, err
}

resp, err := c.get(context.TODO(), "/teams?"+v.Encode())
resp, err := c.get(ctx, "/teams?"+v.Encode())
if err != nil {
return nil, err
}

var result ListTeamResponse
return &result, c.decodeJSON(resp, &result)
if err = c.decodeJSON(resp, &result); err != nil {
return nil, err
}

return &result, nil
}

// CreateTeam creates a new team.
// CreateTeam creates a new team. It's recommended to use CreateTeamWithContext
// instead.
func (c *Client) CreateTeam(t *Team) (*Team, error) {
resp, err := c.post(context.TODO(), "/teams", t, nil)
return c.CreateTeamWithContext(context.Background(), t)
}

// CreateTeamWithContext creates a new team.
func (c *Client) CreateTeamWithContext(ctx context.Context, t *Team) (*Team, error) {
resp, err := c.post(ctx, "/teams", t, nil)
return getTeamFromResponse(c, resp, err)
}

// DeleteTeam removes an existing team.
// DeleteTeam removes an existing team. It's recommended to use
// DeleteTeamWithContext instead.
func (c *Client) DeleteTeam(id string) error {
_, err := c.delete(context.TODO(), "/teams/"+id)
return c.DeleteTeamWithContext(context.Background(), id)
}

// DeleteTeamWithContext removes an existing team.
func (c *Client) DeleteTeamWithContext(ctx context.Context, id string) error {
_, err := c.delete(ctx, "/teams/"+id)
return err
}

// GetTeam gets details about an existing team.
// GetTeam gets details about an existing team. It's recommended to use
// GetTeamWithContext instead.
func (c *Client) GetTeam(id string) (*Team, error) {
resp, err := c.get(context.TODO(), "/teams/"+id)
return c.GetTeamWithContext(context.Background(), id)
}

// GetTeamWithContext gets details about an existing team.
func (c *Client) GetTeamWithContext(ctx context.Context, id string) (*Team, error) {
resp, err := c.get(ctx, "/teams/"+id)
return getTeamFromResponse(c, resp, err)
}

// UpdateTeam updates an existing team.
// UpdateTeam updates an existing team. It's recommended to use
// UpdateTeamWithContext instead.
func (c *Client) UpdateTeam(id string, t *Team) (*Team, error) {
resp, err := c.put(context.TODO(), "/teams/"+id, t, nil)
return c.UpdateTeamWithContext(context.Background(), id, t)
}

// UpdateTeamWithContext updates an existing team.
func (c *Client) UpdateTeamWithContext(ctx context.Context, id string, t *Team) (*Team, error) {
resp, err := c.put(ctx, "/teams/"+id, t, nil)
return getTeamFromResponse(c, resp, err)
}

// RemoveEscalationPolicyFromTeam removes an escalation policy from a team.
// RemoveEscalationPolicyFromTeam removes an escalation policy from a team. It's
// recommended to use RemoveEscalationPolicyFromTeamWithContext instead.
func (c *Client) RemoveEscalationPolicyFromTeam(teamID, epID string) error {
_, err := c.delete(context.TODO(), "/teams/"+teamID+"/escalation_policies/"+epID)
return c.RemoveEscalationPolicyFromTeamWithContext(context.Background(), teamID, epID)
}

// RemoveEscalationPolicyFromTeamWithContext removes an escalation policy from a team.
func (c *Client) RemoveEscalationPolicyFromTeamWithContext(ctx context.Context, teamID, epID string) error {
_, err := c.delete(ctx, "/teams/"+teamID+"/escalation_policies/"+epID)
return err
}

// AddEscalationPolicyToTeam adds an escalation policy to a team.
// AddEscalationPolicyToTeam adds an escalation policy to a team. It's
// recommended to use AddEscalationPolicyToTeamWithContext instead.
func (c *Client) AddEscalationPolicyToTeam(teamID, epID string) error {
_, err := c.put(context.TODO(), "/teams/"+teamID+"/escalation_policies/"+epID, nil, nil)
return c.AddEscalationPolicyToTeamWithContext(context.Background(), teamID, epID)
}

// AddEscalationPolicyToTeamWithContext adds an escalation policy to a team.
func (c *Client) AddEscalationPolicyToTeamWithContext(ctx context.Context, teamID, epID string) error {
_, err := c.put(ctx, "/teams/"+teamID+"/escalation_policies/"+epID, nil, nil)
return err
}

// RemoveUserFromTeam removes a user from a team.
// RemoveUserFromTeam removes a user from a team. It's recommended to use
// RemoveUserFromTeamWithContext instead.
func (c *Client) RemoveUserFromTeam(teamID, userID string) error {
_, err := c.delete(context.TODO(), "/teams/"+teamID+"/users/"+userID)
return c.RemoveUserFromTeamWithContext(context.Background(), teamID, userID)
}

// RemoveUserFromTeamWithContext removes a user from a team.
func (c *Client) RemoveUserFromTeamWithContext(ctx context.Context, teamID, userID string) error {
_, err := c.delete(ctx, "/teams/"+teamID+"/users/"+userID)
return err
}

// AddUserToTeam adds a user to a team.
func (c *Client) AddUserToTeam(teamID, userID string) error {
_, err := c.put(context.TODO(), "/teams/"+teamID+"/users/"+userID, nil, nil)
return c.AddUserToTeamWithContext(context.Background(), AddUserToTeamOptions{TeamID: teamID, UserID: userID})
}

// TeamUserRole is a named type to represent the different Team Roles supported
// by PagerDuty when adding a user to a team.
//
// For more info: https://support.pagerduty.com/docs/advanced-permissions#team-roles
type TeamUserRole string

const (
// TeamUserRoleObserver is the obesrver team role, which generally provides
// read-only access. They gain responder-level permissions on an incident if
// one is assigned to them.
TeamUserRoleObserver TeamUserRole = "observer"

// TeamUserRoleResponder is the responder team role, and they are given the
// same permissions as the observer plus the ability to respond to
// incidents, trigger incidents, and manage overrides.
TeamUserRoleResponder TeamUserRole = "responder"

// TeamUserRoleManager is the manager team role, and they are given the same
// permissions as the responder plus the ability to edit and delete the
// different resources owned by the team.
TeamUserRoleManager TeamUserRole = "manager"
)

// AddUserToTeamOptions is an option struct for the AddUserToTeamWithContext
// method.
type AddUserToTeamOptions struct {
TeamID string `json:"-"`
UserID string `json:"-"`
Role TeamUserRole `json:"role,omitempty"`
}

// AddUserToTeamWithContext adds a user to a team.
func (c *Client) AddUserToTeamWithContext(ctx context.Context, o AddUserToTeamOptions) error {
_, err := c.put(ctx, "/teams/"+o.TeamID+"/users/"+o.UserID, o, nil)
return err
}

func getTeamFromResponse(c *Client, resp *http.Response, err error) (*Team, error) {
if err != nil {
return nil, err
}

var target map[string]Team
if dErr := c.decodeJSON(resp, &target); dErr != nil {
return nil, fmt.Errorf("Could not decode JSON response: %v", dErr)
}
rootNode := "team"

const rootNode = "team"

t, nodeOK := target[rootNode]
if !nodeOK {
return nil, fmt.Errorf("JSON response does not have %s field", rootNode)
}

return &t, nil
}

Expand All @@ -126,23 +220,40 @@ type ListMembersResponse struct {
}

// ListMembers gets the first page of users associated with the specified team.
// It's recommended to use ListMembersWithContext instead.
func (c *Client) ListMembers(teamID string, o ListMembersOptions) (*ListMembersResponse, error) {
return c.ListMembersWithContext(context.Background(), teamID, o)
}

// ListMembersWithContext gets the first page of users associated with the specified team.
func (c *Client) ListMembersWithContext(ctx context.Context, teamID string, o ListMembersOptions) (*ListMembersResponse, error) {
v, err := query.Values(o)
if err != nil {
return nil, err
}

resp, err := c.get(context.TODO(), "/teams/"+teamID+"/members?"+v.Encode())
resp, err := c.get(ctx, "/teams/"+teamID+"/members?"+v.Encode())
if err != nil {
return nil, err
}

var result ListMembersResponse
return &result, c.decodeJSON(resp, &result)
if err = c.decodeJSON(resp, &result); err != nil {
return nil, err
}

return &result, nil
}

// ListAllMembers gets all members associated with the specified team.
// ListAllMembers gets all members associated with the specified team. It's
// recommended to use ListMembersPaginated instead.
func (c *Client) ListAllMembers(teamID string) ([]Member, error) {
members := make([]Member, 0)
return c.ListMembersPaginated(context.Background(), teamID)
}

// ListMembersPaginated gets all members associated with the specified team.
func (c *Client) ListMembersPaginated(ctx context.Context, teamID string) ([]Member, error) {
var members []Member

// Create a handler closure capable of parsing data from the members endpoint
// and appending resultant members to the return slice.
Expand All @@ -164,7 +275,7 @@ func (c *Client) ListAllMembers(teamID string) ([]Member, error) {
}

// Make call to get all pages associated with the base endpoint.
if err := c.pagedGet(context.TODO(), "/teams/"+teamID+"/members", responseHandler); err != nil {
if err := c.pagedGet(ctx, "/teams/"+teamID+"/members", responseHandler); err != nil {
return nil, err
}

Expand Down

0 comments on commit 6586127

Please sign in to comment.