-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathtc.py
executable file
·355 lines (266 loc) · 12.3 KB
/
tc.py
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
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
"""
RESTful api definition: http://${TeamCity}/guestAuth/app/rest/application.wadl
"""
import json
import urllib2
import base64
from datetime import datetime, timedelta
class TeamCityRESTApiClient:
def __init__(self, username, password, server, port):
self.TC_REST_URL = "http://%s:%d/httpAuth/app/rest/" % (server, port)
self.userpass = '%s:%s' % (username, password)
self.locators = {}
self.parameters = {}
# count:<number> - serve only the specified number of builds
def set_count(self, count):
"""
:param count:
:return:
"""
self.parameters['count'] = count
return self
# running:<true/false/any> - limit the builds by running flag.
def set_running(self, running):
self.locators['running'] = running
return self
# buildType:(<buildTypeLocator>) - only the builds of the specified build configuration
def set_build_type(self, bt):
self.locators['buildType'] = bt
return self
# tags:<tags> - ","(comma) -delimited list of build tags (only builds containing all the specified tags are returned)
def set_tags(self, tags):
self.locators['tags'] = tags
return self
# status:<SUCCESS/FAILURE/ERROR> - list the builds with the specified status only
def set_status(self, status):
self.locators['status'] = status
return self
# user:(<userLocator>) - limit the builds to only those triggered by user specified
def set_user(self, user):
self.locators['user'] = user
return self
# personal:<true/false/any> - limit the builds by personal flag.
def set_personal(self, personal):
self.locators['personal'] = personal
return self
# canceled:<true/false/any> - limit the builds by canceled flag.
def set_canceled(self, canceled):
self.locators['canceled'] = canceled
return self
# pinned:<true/false/any> - limit the builds by pinned flag.
def set_pinned(self, pinned):
self.locators['pinned'] = pinned
return self
# branch:<branch locator> - since TeamCity 7.1 limit the builds by branch. <branch locator> can be branch name (displayed in UI, or "(name:<name>,default:<true/false/any>,unspecified:<true/false/any>,branched:<true/false/any>)". If not specified, only builds from default branch are returned.
def set_branch(self, branch):
self.locators['branch'] = branch
return self
# agentName:<name> - agent name to return only builds ran on the agent with name specified
def set_agent_name(self, agent_name):
self.locators['agentName'] = agent_name
return self
# sinceBuild:(<buildLocator>) - limit the list of builds only to those after the one specified
def set_since_build(self, since_build):
self.locators['sinceBuild'] = since_build
return self
# sinceDate:<date> - limit the list of builds only to those started after the date specified. The date should in the same format as dates returned by REST API.
def set_since_date(self, minutes):
minutes_delta = timedelta(minutes=minutes)
minutes_ago = datetime.now() - minutes_delta
# Hardcoding NY time zone here... Assumes machines is on the same timezone
self.locators['sinceDate'] = minutes_ago.strftime('%Y%m%dT%H%M%S') + '-0500'
return self
# start:<number> - list the builds from the list starting from the position specified (zero-based)
def set_start(self, start):
self.parameters['start'] = start
return self
# lookupLimit:<number> - since TeamCity 7.0 limit processing to the latest N builds only. If none of the latest N builds match other specified criteria of the build locator, 404 response is returned.
def set_lookup_limit(self, lookup_limit):
self.locators['lookupLimit'] = lookup_limit
return self
def set_tc_server(self, url, port):
self.TC_REST_URL = "http://%s:%s/httpAuth/app/rest/" % (url, port)
return self
def set_resource(self, resource):
self.resource = self.TC_REST_URL + resource
return self
def compose_resource_path(self):
"""
Creates the URL by appending the resource, locators, and arguments in the appropriate places.
:return: the well-built URL to make the request with.
"""
full_resource_url = self.resource
if self.locators:
locators = 'locator=' + ','.join([
"%s:%s" % (k, v)
for k, v in self.locators.iteritems()
])
else:
locators = ''
get_args = '&'.join([locators] + [
'%s=%s' % (k, v)
for k, v in self.parameters.iteritems()
])
if get_args:
full_resource_url = full_resource_url + '?' + get_args
return full_resource_url
def get_from_server(self):
"""
Makes a request to the TeamCity server pointed to by this instance of the Client.
Uses httpAuth and accepts a JSON return.
Then it creates a Python dictionary by loading in the JSON.
:return: the Python dictionary which represents the JSON response.
"""
full_resource_url = self.compose_resource_path()
req = urllib2.Request(full_resource_url)
base64string = base64.encodestring(self.userpass).replace('\n', '')
req.add_header("Authorization", "Basic %s" % base64string)
req.add_header('Accept', 'application/json')
response = urllib2.urlopen(req)
res = response.read()
data = json.loads(res)
response.close()
return data
def get_server_info(self):
"""
Gets server info of the TeamCity server pointed to by this instance of the Client.
:return: an instance of the Client with `resource = <url>/server`.
"""
return self.set_resource('server')
def get_all_plugins(self):
"""
Gets all plugins in the TeamCity server pointed to by this instance of the Client.
:return: an instance of the Client with `resource = <url>/server/plugins`.
"""
return self.set_resource('server/plugins')
def get_all_builds(self, start=0, count=100):
"""
Gets all builds in the TeamCity server pointed to by this instance of the Client.
This can be very large since it is historic data. Therefore the count can be limited.
:param start: what build number to start from
:param count: how many builds to return
:return: an instance of the Client with `resource = <url>/builds/?start=<start>&count=<count>`.
"""
self.set_start(start)
self.set_count(count)
return self.set_resource('builds/')
def get_all_builds_by_build_type_id(self, btId, start=0, count=100):
"""
Gets all builds of a build type build type id `btId`.
This can be very large since it is historic data. Therefore the count can be limited.
:param btId: the build type to get builds from, in the format bt[0-9]+
:param start: what build number to start from
:param count: how many builds to return
:return: an instance of the Client with `resource = <url>/buildTypes/id:<btId>/builds/?start=<start>&count=<count>`.
"""
self.set_count(count)
self.set_start(start)
return self.set_resource('buildTypes/id:%s/builds/' % (btId))
def get_build_by_build_id(self, bId):
"""
Gets a build with build ID `bId`.
:param bId: the build to get, in the format [0-9]+
:return: an instance of the Client with `resource = <url>/builds/id:<bId>`.
"""
return self.set_resource('builds/id:%s' % bId)
def get_all_changes(self):
"""
Gets all changes made in the TeamCity server pointed to by this instance of the Client.
:return: an instance of the Client with `resource = <url>/changes`.
"""
return self.set_resource('changes')
def get_change_by_change_id(self, cId):
"""
Gets a particular change with change ID `cId`.
:param cId: the change to get, in the format [0-9]+
:return: an instance of the Client with `resource = <url>/changes/id:<cId>`.
"""
return self.set_resource('changes/id:%s' % cId)
def get_changes_by_build_id(self, bId):
"""
Gets changes in a build for a build ID `bId`.
:param bId: the build to get changes of in the format [0-9]+
:return: an instance of the Client with `resource = <url>/changes/build:id:<bId>`.
"""
self.parameters['build'] = 'id:%s' % (bId)
return self.set_resource('changes')
def get_all_build_types(self):
"""
Gets all build types in the TeamCity server pointed to by this instance of the Client.
:return: an instance of the Client with `resource = <url>/buildTypes`.
"""
return self.set_resource('buildTypes')
def get_build_type(self, btId):
"""
Gets details for a build type with id `btId`.
:param btId: the build type to get, in format bt[0-9]+
:return: an instance of the Client with `resource = <url>/buildTypes/id:<btId>`
"""
return self.set_resource('buildTypes/id:%s' % btId)
def get_all_projects(self):
"""
Gets all projects in the TeamCity server pointed to by this instance of the Client.
:return: an instance of the Client with `resource = <url>/projects`
"""
return self.set_resource('projects')
def get_project_by_project_id(self, pId):
"""
Gets details for a project with ID `pId`.
:param pId: the project ID to get, in format project[0-9]+
:return: an instance of the Client with `resource = <url>/projects/id:<pId>`
"""
return self.set_resource('projects/id:%s' % pId)
def get_agents(self):
"""
Gets all agents in the TeamCity server pointed to by this instance of the Client.
:return: an instance of the Client with `resource = <url>/agents`
"""
return self.set_resource('agents')
def get_agent_by_agent_id(self, aId):
"""
Gets details for an agent with ID `aId`.
:param aId: the agent ID to get, in format [0-9]+
:return: an instance of the Client with `resource = <url>/agents/id:<aId>`
"""
return self.set_resource('agents/id:%d' % aId)
def get_build_statistics_by_build_id(self, bId):
"""
Gets statistics for a build with ID `bId`.
Statistics include `BuildDuration`, `FailedTestCount`, `TimeSpentInQueue`, and more.
:param bId: the build ID to get, in format [0-9]+
:return: an instance of the Client with `resource = <url>/builds/id:<bId>/statistics`
"""
return self.set_resource('builds/id:%s/statistics' % bId)
def get_build_tags_by_build_id(self, bId):
"""
Gets tags for a build with ID `bId`.
:param bId: the build ID to get, in format [0-9]+
:return: an instance of the Client with `resource = <url>/builds/id:<bId>/tags`
"""
return self.set_resource('builds/id:%s/tags' % bId)
def get_all_vcs_roots(self):
"""
Gets all VCS roots in the TeamCity server pointed to by this instance of the Client.
:return: an instance of the Client with `resource = <url>/vcs-roots`
"""
return self.set_resource('vcs-roots')
def get_vcs_root_by_vcs_root_id(self, vrId):
"""
Gets a VCS root with the specified ID `vrId`.
:param vrId: the VCS root to get
:return: an instance of the Client with `resource = <url>/vcs-roots/id:<vrId>`
"""
return self.set_resource('vcs-roots/id:%s' % vrId)
def get_all_users(self):
"""
Gets all users in the TeamCity server pointed to by this instance of the Client.
:return: an instance of the Client with `resource = <url>/users`
"""
return self.set_resource('users')
def get_user_by_username(self, username):
"""
Gets user details for a given username.
:param username: the username to get details for.
:return: an instance of the Client with `resource = <url>/users/username:<username>`
"""
return self.set_resource('users/username:%s' % username)