defectdojo-cli2 0.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- defectdojo_cli2/__init__.py +7 -0
- defectdojo_cli2/__main__.py +45 -0
- defectdojo_cli2/engagements.py +373 -0
- defectdojo_cli2/findings.py +745 -0
- defectdojo_cli2/tests.py +442 -0
- defectdojo_cli2/util.py +28 -0
- defectdojo_cli2-0.0.0.dist-info/AUTHORS +1 -0
- defectdojo_cli2-0.0.0.dist-info/LICENSE +21 -0
- defectdojo_cli2-0.0.0.dist-info/METADATA +20 -0
- defectdojo_cli2-0.0.0.dist-info/RECORD +14 -0
- defectdojo_cli2-0.0.0.dist-info/WHEEL +5 -0
- defectdojo_cli2-0.0.0.dist-info/entry_points.txt +2 -0
- defectdojo_cli2-0.0.0.dist-info/pbr.json +1 -0
- defectdojo_cli2-0.0.0.dist-info/top_level.txt +1 -0
defectdojo_cli2/tests.py
ADDED
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
import json
|
|
3
|
+
import sys
|
|
4
|
+
import argparse
|
|
5
|
+
import requests
|
|
6
|
+
from unittest.mock import PropertyMock
|
|
7
|
+
from tabulate import tabulate
|
|
8
|
+
from defectdojo_cli2.util import Util
|
|
9
|
+
|
|
10
|
+
class Tests(object):
|
|
11
|
+
def parse_cli_args(self):
|
|
12
|
+
parser = argparse.ArgumentParser(
|
|
13
|
+
description='Perform <sub_command> related to tests on DefectDojo',
|
|
14
|
+
usage='''defectdojo tests <sub_command> [<args>]
|
|
15
|
+
|
|
16
|
+
You can use the following sub_commands:
|
|
17
|
+
create Create a test
|
|
18
|
+
list List tests
|
|
19
|
+
update Update a test
|
|
20
|
+
''')
|
|
21
|
+
parser.add_argument(
|
|
22
|
+
'sub_command',
|
|
23
|
+
help='Sub_command to run'
|
|
24
|
+
)
|
|
25
|
+
# Get sub_command
|
|
26
|
+
args = parser.parse_args(sys.argv[2:3])
|
|
27
|
+
# Use dispatch pattern to invoke method with same name (that starts with _)
|
|
28
|
+
getattr(self, '_'+args.sub_command)()
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def list(self, url, api_key, test_id=None, title=None, engagement_id=None,
|
|
32
|
+
test_type=None, tag=None, limit=None, **kwargs):
|
|
33
|
+
# Create parameters to be requested
|
|
34
|
+
request_params = dict()
|
|
35
|
+
API_URL = url+'/api/v2'
|
|
36
|
+
TESTS_URL = API_URL+'/tests/'
|
|
37
|
+
if test_id is not None:
|
|
38
|
+
request_params['id'] = test_id
|
|
39
|
+
if title is not None:
|
|
40
|
+
request_params['title'] = title
|
|
41
|
+
if engagement_id is not None:
|
|
42
|
+
request_params['engagement'] = engagement_id
|
|
43
|
+
if test_type is not None:
|
|
44
|
+
# In order to filter test_type we need to get its ID via API
|
|
45
|
+
if type(test_type) is int:
|
|
46
|
+
test_type_id = test_type
|
|
47
|
+
else:
|
|
48
|
+
temp_params = dict()
|
|
49
|
+
temp_params['name'] = test_type
|
|
50
|
+
# Make a get request to /test_types passing the test_type as parameter
|
|
51
|
+
temp_response = Util().request_apiv2('GET', API_URL+'/test_types/', api_key, params=temp_params)
|
|
52
|
+
# Tranform the above response in json and get the id
|
|
53
|
+
test_type_id = json.loads(temp_response.text)['results'][0]['id']
|
|
54
|
+
# Add to request_params
|
|
55
|
+
request_params['test_type'] = test_type_id
|
|
56
|
+
if tag is not None:
|
|
57
|
+
if type(tag) is list:
|
|
58
|
+
request_params['tags'] = ','.join(tag)
|
|
59
|
+
else:
|
|
60
|
+
request_params['tags'] = tag
|
|
61
|
+
if limit is not None:
|
|
62
|
+
request_params['limit'] = limit
|
|
63
|
+
else:
|
|
64
|
+
# Make a request to API getting only one test to retrieve the total amount of tests
|
|
65
|
+
temp_params = request_params.copy()
|
|
66
|
+
temp_params['url'] = url
|
|
67
|
+
temp_params['api_key'] = api_key
|
|
68
|
+
temp_params['limit'] = 1
|
|
69
|
+
temp_response = self.list(**temp_params)
|
|
70
|
+
limit = int(json.loads(temp_response.text)['count'])
|
|
71
|
+
request_params['limit'] = limit
|
|
72
|
+
|
|
73
|
+
# Make request
|
|
74
|
+
response = Util().request_apiv2('GET', TESTS_URL, api_key, params=request_params)
|
|
75
|
+
return response
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _list(self):
|
|
79
|
+
# Read user-supplied arguments
|
|
80
|
+
parser = argparse.ArgumentParser(description='List tests stored on DefectDojo',
|
|
81
|
+
usage='defectdojo tests list [<args>]')
|
|
82
|
+
optional = parser._action_groups.pop()
|
|
83
|
+
required = parser.add_argument_group('required arguments')
|
|
84
|
+
required.add_argument(
|
|
85
|
+
'--url',
|
|
86
|
+
help='DefectDojo URL', required=True
|
|
87
|
+
)
|
|
88
|
+
required.add_argument(
|
|
89
|
+
'--api_key',
|
|
90
|
+
help='API v2 Key', required=True
|
|
91
|
+
)
|
|
92
|
+
optional.add_argument(
|
|
93
|
+
'--id',
|
|
94
|
+
help='Get tests with this id'
|
|
95
|
+
)
|
|
96
|
+
optional.add_argument(
|
|
97
|
+
'--test_type',
|
|
98
|
+
help='Filter by test type'
|
|
99
|
+
)
|
|
100
|
+
optional.add_argument(
|
|
101
|
+
'--title', help='Filter by test title'
|
|
102
|
+
)
|
|
103
|
+
optional.add_argument(
|
|
104
|
+
'--engagement_id',
|
|
105
|
+
help='Filter by engagement'
|
|
106
|
+
)
|
|
107
|
+
optional.add_argument(
|
|
108
|
+
'--tag',
|
|
109
|
+
help='Test tag (can be used multiple times)', action='append'
|
|
110
|
+
)
|
|
111
|
+
optional.add_argument(
|
|
112
|
+
'--limit',
|
|
113
|
+
help='Number of results to return (by default it gets all the tests)'
|
|
114
|
+
)
|
|
115
|
+
optional.set_defaults(active=None, valid=None, scope=None)
|
|
116
|
+
parser._action_groups.append(optional)
|
|
117
|
+
# Parse out arguments ignoring the first three (because we're inside a sub-command)
|
|
118
|
+
args = vars(parser.parse_args(sys.argv[3:]))
|
|
119
|
+
|
|
120
|
+
# Adjust args
|
|
121
|
+
if args['id'] is not None:
|
|
122
|
+
# Rename key from 'id' to 'test_id' to match the argument of self.list
|
|
123
|
+
args['test_id'] = args.pop('id')
|
|
124
|
+
|
|
125
|
+
# Get tests
|
|
126
|
+
response = self.list(**args)
|
|
127
|
+
|
|
128
|
+
# Pretty print JSON response
|
|
129
|
+
Util().default_output(response, sucess_status_code=200)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def get_test_type_by_tags(self, url, api_key, tags, tags_operator, engagement_id=None):
|
|
133
|
+
# First make a request to API getting all test types with the tags we're looking for
|
|
134
|
+
request_params = dict()
|
|
135
|
+
request_params['url'] = url
|
|
136
|
+
request_params['api_key'] = api_key
|
|
137
|
+
if engagement_id:
|
|
138
|
+
request_params['engagement_id'] = engagement_id
|
|
139
|
+
|
|
140
|
+
if tags_operator == 'union': # Default behaviour
|
|
141
|
+
request_params['tag'] = tags
|
|
142
|
+
response = self.list(**request_params)
|
|
143
|
+
# Parse output
|
|
144
|
+
json_out = json.loads(response.text)
|
|
145
|
+
results = json_out['results']
|
|
146
|
+
# Create set of all test types from the tag
|
|
147
|
+
test_type_set = set()
|
|
148
|
+
for test in results:
|
|
149
|
+
test_type_set.add(test['test_type_name'])
|
|
150
|
+
# Transform set to list
|
|
151
|
+
test_type_list = list(test_type_set)
|
|
152
|
+
|
|
153
|
+
elif tags_operator == 'intersect':
|
|
154
|
+
test_type_list_of_sets = list()
|
|
155
|
+
for tag in tags:
|
|
156
|
+
request_params['tag'] = tag
|
|
157
|
+
response = self.list(**request_params)
|
|
158
|
+
# Parse output
|
|
159
|
+
json_out = json.loads(response.text)
|
|
160
|
+
results = json_out['results']
|
|
161
|
+
# Create set of all test types from the tag
|
|
162
|
+
test_type_set = set()
|
|
163
|
+
for test in results:
|
|
164
|
+
test_type_set.add(test['test_type'])
|
|
165
|
+
# Add set of test_type to list
|
|
166
|
+
test_type_list_of_sets.append(test_type_set)
|
|
167
|
+
|
|
168
|
+
# Get intersection between all sets
|
|
169
|
+
test_type_intersection = test_type_list_of_sets[0]
|
|
170
|
+
for test_type_set in test_type_list_of_sets[1:]:
|
|
171
|
+
test_type_intersection.intersection_update(test_type_set)
|
|
172
|
+
test_type_list = test_type_intersection
|
|
173
|
+
|
|
174
|
+
return list(test_type_list)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def update(self, url, api_key, test_id, title=None, desc=None,
|
|
178
|
+
start_date=None, end_date=None, version=None, build_id=None,
|
|
179
|
+
commit_hash=None, branch_tag=None, lead_id=None, test_type=None,
|
|
180
|
+
environment=None, **kwargs):
|
|
181
|
+
# Prepare JSON data to be send
|
|
182
|
+
request_json = dict()
|
|
183
|
+
API_URL = url+'/api/v2'
|
|
184
|
+
TESTS_URL = API_URL+'/tests/'
|
|
185
|
+
TESTS_ID_URL = TESTS_URL+test_id+'/'
|
|
186
|
+
if title:
|
|
187
|
+
request_json['title'] = title
|
|
188
|
+
if desc:
|
|
189
|
+
request_json['description'] = desc
|
|
190
|
+
if start_date:
|
|
191
|
+
request_json['target_start'] = start_date
|
|
192
|
+
if end_date:
|
|
193
|
+
request_json['target_end'] = end_date
|
|
194
|
+
if version:
|
|
195
|
+
request_json['version'] = version
|
|
196
|
+
if build_id:
|
|
197
|
+
request_json['build_id'] = build_id
|
|
198
|
+
if commit_hash:
|
|
199
|
+
request_json['commit_hash'] = commit_hash
|
|
200
|
+
if branch_tag:
|
|
201
|
+
request_json['branch_tag'] = branch_tag
|
|
202
|
+
if lead_id:
|
|
203
|
+
request_json['lead'] = lead_id
|
|
204
|
+
if test_type:
|
|
205
|
+
request_json['test_type'] = test_type
|
|
206
|
+
if environment:
|
|
207
|
+
request_json['enviroment'] = enviroment
|
|
208
|
+
request_json = json.dumps(request_json)
|
|
209
|
+
|
|
210
|
+
# Make the request
|
|
211
|
+
response = Util().request_apiv2('PATCH', TESTS_ID_URL, api_key, data=request_json)
|
|
212
|
+
return response
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def _update(self):
|
|
216
|
+
# Read user-supplied arguments
|
|
217
|
+
parser = argparse.ArgumentParser(description='Update a test on DefectDojo',
|
|
218
|
+
usage='defectdojo tests update TEST_ID [<args>]')
|
|
219
|
+
optional = parser._action_groups.pop()
|
|
220
|
+
required = parser.add_argument_group('required arguments')
|
|
221
|
+
|
|
222
|
+
parser.add_argument(
|
|
223
|
+
'test_id', help='ID of the test to be updated'
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
required.add_argument(
|
|
227
|
+
'--url', help='DefectDojo URL', required=True
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
required.add_argument(
|
|
231
|
+
'--api_key', help='API v2 Key', required=True
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
optional.add_argument(
|
|
235
|
+
'--title', help='Test title'
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
optional.add_argument(
|
|
239
|
+
'--desc', help='Test description', metavar='DESCRIPTION'
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
optional.add_argument(
|
|
243
|
+
'--start_date', help='Test starting date', metavar='YYYY-MM-DD'
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
optional.add_argument(
|
|
247
|
+
'--end_date', help='Test ending date', metavar='YYYY-MM-DD'
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
optional.add_argument(
|
|
251
|
+
'--version', help='Test version'
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
optional.add_argument(
|
|
255
|
+
'--build_id', help='Test build ID'
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
optional.add_argument(
|
|
259
|
+
'--commit_hash', help='Test commit hash'
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
optional.add_argument(
|
|
263
|
+
'--test_type', help='Test type'
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
optional.add_argument(
|
|
267
|
+
'--environment', help='Test environment'
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
optional.add_argument(
|
|
271
|
+
'--branch_tag',
|
|
272
|
+
help='Tag or branch of the product the engagement tested',
|
|
273
|
+
metavar='TAG_OR_BRANCH'
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
optional.add_argument(
|
|
277
|
+
'--lead_id', help='ID of the user responsible for this test'
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
parser._action_groups.append(optional)
|
|
281
|
+
# Parse out arguments ignoring the first three (because we're inside a sub_command)
|
|
282
|
+
args = vars(parser.parse_args(sys.argv[3:]))
|
|
283
|
+
|
|
284
|
+
# Update engagement
|
|
285
|
+
response = self.update(**args)
|
|
286
|
+
|
|
287
|
+
# Pretty print JSON response
|
|
288
|
+
Util().default_output(response, sucess_status_code=200)
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def _create(self):
|
|
292
|
+
# Read user-supplied arguments
|
|
293
|
+
parser = argparse.ArgumentParser(description='Create a test on DefectDojo',
|
|
294
|
+
usage='defectdojo tests create [<args>]')
|
|
295
|
+
optional = parser._action_groups.pop()
|
|
296
|
+
required = parser.add_argument_group('required arguments')
|
|
297
|
+
|
|
298
|
+
parser.add_argument(
|
|
299
|
+
'--engagement_id',
|
|
300
|
+
help='ID of the engagement where the test will be created',
|
|
301
|
+
required=True
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
required.add_argument(
|
|
305
|
+
'--url', help='DefectDojo URL', required=True
|
|
306
|
+
)
|
|
307
|
+
|
|
308
|
+
required.add_argument(
|
|
309
|
+
'--api_key', help='API v2 Key', required=True
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
optional.add_argument(
|
|
313
|
+
'--title', help='Test title'
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
optional.add_argument(
|
|
317
|
+
'--desc', help='Test description', metavar='DESCRIPTION'
|
|
318
|
+
)
|
|
319
|
+
|
|
320
|
+
optional.add_argument(
|
|
321
|
+
'--start_date', help='Test starting date (default = TODAY)',
|
|
322
|
+
metavar='YYYY-MM-DDThh:mm[:ss[.uuuuuu]][+HH:MM|-HH:MM|Z]',
|
|
323
|
+
default=datetime.now().strftime('%Y-%m-%dT%H:%M')
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
optional.add_argument(
|
|
327
|
+
'--end_date', help='Test ending date (default = TODAY)',
|
|
328
|
+
metavar='YYYY-MM-DDThh:mm[:ss[.uuuuuu]][+HH:MM|-HH:MM|Z]',
|
|
329
|
+
default=datetime.now().strftime('%Y-%m-%dT%H:%M')
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
optional.add_argument(
|
|
333
|
+
'--version', help='Test version'
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
optional.add_argument(
|
|
337
|
+
'--build_id', help='Test build ID'
|
|
338
|
+
)
|
|
339
|
+
|
|
340
|
+
optional.add_argument(
|
|
341
|
+
'--commit_hash', help='Test commit hash'
|
|
342
|
+
)
|
|
343
|
+
|
|
344
|
+
optional.add_argument(
|
|
345
|
+
'--test_type', help='Test type'
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
optional.add_argument(
|
|
349
|
+
'--env', help='Test environment'
|
|
350
|
+
)
|
|
351
|
+
|
|
352
|
+
optional.add_argument(
|
|
353
|
+
'--branch_tag',
|
|
354
|
+
help='Tag or branch of the product the engagement tested',
|
|
355
|
+
metavar='TAG_OR_BRANCH'
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
optional.add_argument(
|
|
359
|
+
'--lead_id', help='ID of the user responsible for this test'
|
|
360
|
+
)
|
|
361
|
+
|
|
362
|
+
optional.add_argument(
|
|
363
|
+
'--tag',
|
|
364
|
+
help='Test tag (can be used multiple times)', action='append'
|
|
365
|
+
)
|
|
366
|
+
|
|
367
|
+
parser._action_groups.append(optional)
|
|
368
|
+
# Parse out arguments ignoring the first three (because we're inside a sub_command)
|
|
369
|
+
args = vars(parser.parse_args(sys.argv[3:]))
|
|
370
|
+
|
|
371
|
+
# Create test
|
|
372
|
+
response = self.create(**args)
|
|
373
|
+
|
|
374
|
+
# Pretty print JSON response
|
|
375
|
+
Util().default_output(response, sucess_status_code=200)
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
def create(self, url, api_key, engagement_id, title=None, desc=None,
|
|
379
|
+
start_date=None, end_date=None, version=None, build_id=None,
|
|
380
|
+
commit_hash=None, branch_tag=None, lead_id=None, test_type=None,
|
|
381
|
+
env=None, tag=None, **kwargs):
|
|
382
|
+
# Prepare JSON data to be send
|
|
383
|
+
request_json = dict()
|
|
384
|
+
API_URL = url+'/api/v2'
|
|
385
|
+
TESTS_URL = API_URL+'/tests/'
|
|
386
|
+
if engagement_id:
|
|
387
|
+
request_json['engagement'] = engagement_id
|
|
388
|
+
if title:
|
|
389
|
+
request_json['title'] = title
|
|
390
|
+
if desc:
|
|
391
|
+
request_json['description'] = desc
|
|
392
|
+
if start_date:
|
|
393
|
+
request_json['target_start'] = start_date
|
|
394
|
+
if end_date:
|
|
395
|
+
request_json['target_end'] = end_date
|
|
396
|
+
if version:
|
|
397
|
+
request_json['version'] = version
|
|
398
|
+
if build_id:
|
|
399
|
+
request_json['build_id'] = build_id
|
|
400
|
+
if commit_hash:
|
|
401
|
+
request_json['commit_hash'] = commit_hash
|
|
402
|
+
if branch_tag:
|
|
403
|
+
request_json['branch_tag'] = branch_tag
|
|
404
|
+
if lead_id:
|
|
405
|
+
request_json['lead'] = lead_id
|
|
406
|
+
if test_type:
|
|
407
|
+
# Get test_type ID via API
|
|
408
|
+
if type(test_type) is int:
|
|
409
|
+
test_type_id = test_type
|
|
410
|
+
else:
|
|
411
|
+
temp_params = dict()
|
|
412
|
+
temp_params['name'] = test_type
|
|
413
|
+
# Make a get request to /test_types passing the test_type as parameter
|
|
414
|
+
temp_response = Util().request_apiv2('GET', API_URL+'/test_types/', api_key, params=temp_params)
|
|
415
|
+
# Tranform the above response in json and get the id
|
|
416
|
+
test_type_id = json.loads(temp_response.text)['results'][0]['id']
|
|
417
|
+
# Add to request_params
|
|
418
|
+
request_json['test_type'] = test_type_id
|
|
419
|
+
if env:
|
|
420
|
+
# Get environment ID via API
|
|
421
|
+
if type(env) is int:
|
|
422
|
+
env_id = env
|
|
423
|
+
else:
|
|
424
|
+
# Make a get request to /development_environments passing the environment as parameter
|
|
425
|
+
temp_response = Util().request_apiv2('GET', API_URL+'/development_environments/', api_key)
|
|
426
|
+
# Tranform the above response in json and get the results list
|
|
427
|
+
results = json.loads(temp_response.text)['results']
|
|
428
|
+
for result in results:
|
|
429
|
+
if result['name'] == env:
|
|
430
|
+
env_id = result['id']
|
|
431
|
+
# Add to request_params
|
|
432
|
+
try:
|
|
433
|
+
request_json['environment'] = env_id
|
|
434
|
+
except:
|
|
435
|
+
raise Exception("Environment does not exists")
|
|
436
|
+
if tag:
|
|
437
|
+
request_json['tags'] = tag
|
|
438
|
+
request_json = json.dumps(request_json)
|
|
439
|
+
|
|
440
|
+
# Make the request
|
|
441
|
+
response = Util().request_apiv2('POST', TESTS_URL, api_key, data=request_json)
|
|
442
|
+
return response
|
defectdojo_cli2/util.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
import json
|
|
3
|
+
import requests
|
|
4
|
+
|
|
5
|
+
class Util(object):
|
|
6
|
+
# Generic method for all HTTP requests
|
|
7
|
+
# IMPORTANT: The url must end with '/', otherwise some requests will not work
|
|
8
|
+
def request_apiv2(self, http_method, url, api_key, params=dict(), data=None, files=None, verify=True):
|
|
9
|
+
headers = dict()
|
|
10
|
+
headers['Authorization'] = 'Token '+api_key
|
|
11
|
+
if not files:
|
|
12
|
+
headers['Accept'] = 'application/json'
|
|
13
|
+
headers['Content-Type'] = 'application/json'
|
|
14
|
+
|
|
15
|
+
response = requests.request(method=http_method, url=url, params=params, data=data,
|
|
16
|
+
files=files, headers=headers, verify=verify)
|
|
17
|
+
return response
|
|
18
|
+
|
|
19
|
+
# Pretty print JSON response exiting with a sucess if the response status code is the same as the 'sucess_status_code' argument
|
|
20
|
+
def default_output(self, response, sucess_status_code):
|
|
21
|
+
json_out = json.loads(response.text)
|
|
22
|
+
pretty_json_out = json.dumps(json_out, indent=4)
|
|
23
|
+
print(pretty_json_out)
|
|
24
|
+
|
|
25
|
+
if response.status_code == sucess_status_code: # Sucess
|
|
26
|
+
exit(0)
|
|
27
|
+
else: # Failure
|
|
28
|
+
exit(1)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Mikke Schirén <mikke.schiren@digitalist.com>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 Luiz Paulo S. Monteiro
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: defectdojo_cli2
|
|
3
|
+
Version: 0.0.0
|
|
4
|
+
Summary: CLI Wrapper for DefectDojo using APIv2
|
|
5
|
+
Author: Mikke Schirén
|
|
6
|
+
Author-email: mikke.schiren@digitalist.com
|
|
7
|
+
License: MIT
|
|
8
|
+
Project-URL: Source Code, https://github.com/adiffpirate/defectdojo-cli
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Requires-Python: >=3.6
|
|
14
|
+
Description-Content-Type: text/markdown; charset=UTF-8
|
|
15
|
+
License-File: LICENSE
|
|
16
|
+
License-File: AUTHORS
|
|
17
|
+
Requires-Dist: requests
|
|
18
|
+
Requires-Dist: tabulate
|
|
19
|
+
|
|
20
|
+
CLI Wrapper for DefectDojo using APIv2
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
defectdojo_cli2/__init__.py,sha256=JbD7ZW-KtxTstXcKGx6F-n9bEWgrwUDlybuHIGhEtVU,232
|
|
2
|
+
defectdojo_cli2/__main__.py,sha256=XUgZl8I0zs_iwYKew7nwtTTLdnByarys-uMcS9iRveY,1742
|
|
3
|
+
defectdojo_cli2/engagements.py,sha256=9kHX-w74WpwJ3ODYX2V8_TyAJSw7tX5q8TzAmkmd7-Y,17822
|
|
4
|
+
defectdojo_cli2/findings.py,sha256=cK7timytONz_LUy7A_duTW-tWhb9DjYj_SxIgtNKJMU,32536
|
|
5
|
+
defectdojo_cli2/tests.py,sha256=0s0nDO9NWg1xc2nAkUNaMAbL2DlCztsbAFd2hk2Fnq8,15851
|
|
6
|
+
defectdojo_cli2/util.py,sha256=vduvJuSEd-PwnWb-2CAiKw6-sSM8VHnt8PBIqkI2nLk,1170
|
|
7
|
+
defectdojo_cli2-0.0.0.dist-info/AUTHORS,sha256=jK29bi89ROKe63nbIlD-VgN7yGNa4Y1HWfceJL7G23k,46
|
|
8
|
+
defectdojo_cli2-0.0.0.dist-info/LICENSE,sha256=0C0p47gxd5AvvurK7eWHMISKVc4M2IVP0dLx2hBS63w,1079
|
|
9
|
+
defectdojo_cli2-0.0.0.dist-info/METADATA,sha256=bx-GJKZyP7bmHi8c_VygoqNGaWKb4W3T19kWjUiAFH8,665
|
|
10
|
+
defectdojo_cli2-0.0.0.dist-info/WHEEL,sha256=Wyh-_nZ0DJYolHNn1_hMa4lM7uDedD_RGVwbmTjyItk,91
|
|
11
|
+
defectdojo_cli2-0.0.0.dist-info/entry_points.txt,sha256=zyn3k9-gOB8BpQNt73Ov12-d5IMBjyp8kyTJrzRuxPs,61
|
|
12
|
+
defectdojo_cli2-0.0.0.dist-info/pbr.json,sha256=Sn_IE1ZidhVtRKZnl2fJcYh2E3Vu14p-5UuRVZXrauU,47
|
|
13
|
+
defectdojo_cli2-0.0.0.dist-info/top_level.txt,sha256=I9c-IBBwLH0PFmm2dbkhPPWHjx4PXDUdtGNm7rGXgBg,16
|
|
14
|
+
defectdojo_cli2-0.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"git_version": "a29c0da", "is_release": false}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
defectdojo_cli2
|