This repository has been archived by the owner on May 5, 2022. It is now read-only.
forked from PagerDuty/go-pagerduty
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tag.go
253 lines (212 loc) · 7.66 KB
/
tag.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
package pagerduty
import (
"context"
"fmt"
"net/http"
"github.com/google/go-querystring/query"
)
// Tag is a way to label user, team and escalation policies in PagerDuty
type Tag struct {
APIObject
Label string `json:"label,omitempty"`
}
// ListTagResponse is the structure used when calling the ListTags API endpoint.
type ListTagResponse struct {
APIListObject
Tags []*Tag `json:"tags"`
}
// ListUserResponse is the structure used to list users assigned a given tag
type ListUserResponse struct {
APIListObject
Users []*APIObject `json:"users,omitempty"`
}
// ListTeamsForTagResponse is the structure used to list teams assigned a given tag
type ListTeamsForTagResponse struct {
APIListObject
Teams []*APIObject `json:"teams,omitempty"`
}
// ListEPResponse is the structure used to list escalation policies assigned a given tag
type ListEPResponse struct {
APIListObject
EscalationPolicies []*APIObject `json:"escalation_policies,omitempty"`
}
// ListTagOptions are the input parameters used when calling the ListTags API endpoint.
type ListTagOptions struct {
APIListObject
Query string `url:"query,omitempty"`
}
// TagAssignments can be applied teams, users and escalation policies
type TagAssignments struct {
Add []*TagAssignment `json:"add,omitempty"`
Remove []*TagAssignment `json:"remove,omitempty"`
}
// TagAssignment is the structure for assigning tags to an entity
type TagAssignment struct {
Type string `json:"type"`
TagID string `json:"id,omitempty"`
Label string `json:"label,omitempty"`
}
// ListTags lists tags of your PagerDuty account, optionally filtered by a search query.
func (c *Client) ListTags(o ListTagOptions) (*ListTagResponse, error) {
return getTagList(context.TODO(), c, "", "", o)
}
// CreateTag creates a new tag.
func (c *Client) CreateTag(t *Tag) (*Tag, *http.Response, error) {
data := make(map[string]*Tag)
data["tag"] = t
resp, err := c.post(context.TODO(), "/tags", data, nil)
return getTagFromResponse(c, resp, err)
}
// DeleteTag removes an existing tag.
func (c *Client) DeleteTag(id string) error {
_, err := c.delete(context.TODO(), "/tags/"+id)
return err
}
// GetTag gets details about an existing tag.
func (c *Client) GetTag(id string) (*Tag, *http.Response, error) {
resp, err := c.get(context.TODO(), "/tags/"+id)
return getTagFromResponse(c, resp, err)
}
// AssignTags adds and removes tag assignments with entities
func (c *Client) AssignTags(e, eid string, a *TagAssignments) (*http.Response, error) {
resp, err := c.post(context.TODO(), "/"+e+"/"+eid+"/change_tags", a, nil)
if err != nil {
return nil, err
}
return resp, nil
}
// GetUsersByTag get related Users for the Tag.
func (c *Client) GetUsersByTag(tid string) (*ListUserResponse, error) {
userResponse := new(ListUserResponse)
users := make([]*APIObject, 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 ListUserResponse
if err := c.decodeJSON(response, &result); err != nil {
return APIListObject{}, err
}
users = append(users, result.Users...)
// 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(context.TODO(), "/tags/"+tid+"/users/", responseHandler); err != nil {
return nil, err
}
userResponse.Users = users
return userResponse, nil
}
// GetTeamsByTag get related Users for the Tag.
func (c *Client) GetTeamsByTag(tid string) (*ListTeamsForTagResponse, error) {
teamsResponse := new(ListTeamsForTagResponse)
teams := make([]*APIObject, 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 ListTeamsForTagResponse
if err := c.decodeJSON(response, &result); err != nil {
return APIListObject{}, err
}
teams = append(teams, result.Teams...)
// 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(context.TODO(), "/tags/"+tid+"/teams/", responseHandler); err != nil {
return nil, err
}
teamsResponse.Teams = teams
return teamsResponse, nil
}
// GetEscalationPoliciesByTag get related Users for the Tag.
func (c *Client) GetEscalationPoliciesByTag(tid string) (*ListEPResponse, error) {
epResponse := new(ListEPResponse)
eps := make([]*APIObject, 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 ListEPResponse
if err := c.decodeJSON(response, &result); err != nil {
return APIListObject{}, err
}
eps = append(eps, result.EscalationPolicies...)
// 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(context.TODO(), "/tags/"+tid+"/escalation_policies/", responseHandler); err != nil {
return nil, err
}
epResponse.EscalationPolicies = eps
return epResponse, nil
}
// GetTagsForEntity Get related tags for Users, Teams or Escalation Policies.
func (c *Client) GetTagsForEntity(e, eid string, o ListTagOptions) (*ListTagResponse, error) {
return getTagList(context.TODO(), c, e, eid, o)
}
func getTagFromResponse(c *Client, resp *http.Response, err error) (*Tag, *http.Response, error) {
if err != nil {
return nil, nil, err
}
var target map[string]Tag
if dErr := c.decodeJSON(resp, &target); dErr != nil {
return nil, nil, fmt.Errorf("Could not decode JSON response: %v", dErr)
}
rootNode := "tag"
t, nodeOK := target[rootNode]
if !nodeOK {
return nil, nil, fmt.Errorf("JSON response does not have %s field", rootNode)
}
return &t, resp, nil
}
// getTagList is a utility function that processes all pages of a ListTagResponse
func getTagList(ctx context.Context, c *Client, e, eid string, o ListTagOptions) (*ListTagResponse, error) {
queryParms, err := query.Values(o)
if err != nil {
return nil, err
}
tagResponse := new(ListTagResponse)
tags := make([]*Tag, 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 ListTagResponse
if err := c.decodeJSON(response, &result); err != nil {
return APIListObject{}, err
}
tags = append(tags, result.Tags...)
// 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
}
path := "/tags"
if e != "" && eid != "" {
path = "/" + e + "/" + eid + "/tags"
}
// Make call to get all pages associated with the base endpoint.
if err := c.pagedGet(ctx, path+queryParms.Encode(), responseHandler); err != nil {
return nil, err
}
tagResponse.Tags = tags
return tagResponse, nil
}