pyntcli 0.1.109__py3-none-any.whl → 0.1.111__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.
- pyntcli/__init__.py +1 -1
- pyntcli/commands/burp.py +4 -0
- pyntcli/commands/util.py +3 -1
- pyntcli/pynt_docker/pynt_container.py +20 -15
- pyntcli/transport/pynt_requests.py +5 -0
- {pyntcli-0.1.109.dist-info → pyntcli-0.1.111.dist-info}/METADATA +1 -2
- {pyntcli-0.1.109.dist-info → pyntcli-0.1.111.dist-info}/RECORD +10 -10
- {pyntcli-0.1.109.dist-info → pyntcli-0.1.111.dist-info}/WHEEL +1 -1
- {pyntcli-0.1.109.dist-info → pyntcli-0.1.111.dist-info}/entry_points.txt +0 -0
- {pyntcli-0.1.109.dist-info → pyntcli-0.1.111.dist-info}/top_level.txt +0 -0
pyntcli/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.1.
|
|
1
|
+
__version__ = "0.1.111"
|
pyntcli/commands/burp.py
CHANGED
|
@@ -51,9 +51,11 @@ def decode_request(item) -> str:
|
|
|
51
51
|
return base64.b64decode(item["request"]["#text"]).decode(encoding)
|
|
52
52
|
except UnicodeDecodeError as e:
|
|
53
53
|
error = e
|
|
54
|
+
ui_thread.print_verbose(f"Error decoding request: {e}, skipping...")
|
|
54
55
|
continue
|
|
55
56
|
except Exception as e:
|
|
56
57
|
error = e
|
|
58
|
+
ui_thread.print_verbose(f"Error decoding request: {e}, breaking...")
|
|
57
59
|
break
|
|
58
60
|
|
|
59
61
|
ui_thread.print(
|
|
@@ -94,6 +96,8 @@ def replay_req(item, proxy_port):
|
|
|
94
96
|
headers[key] = value
|
|
95
97
|
|
|
96
98
|
body = decoded_req.split("\r\n\r\n")[1]
|
|
99
|
+
if body:
|
|
100
|
+
body = body.encode("utf-8")
|
|
97
101
|
resp = pynt_requests.request_from_xml(
|
|
98
102
|
method=method,
|
|
99
103
|
url=url,
|
pyntcli/commands/util.py
CHANGED
|
@@ -10,7 +10,7 @@ import pyntcli.store.store as store
|
|
|
10
10
|
|
|
11
11
|
from pyntcli.commands.static_file_extensions import STATIC_FILE_EXTENSIONS
|
|
12
12
|
from pyntcli.pynt_docker import pynt_container
|
|
13
|
-
from pyntcli.ui import report
|
|
13
|
+
from pyntcli.ui import report, ui_thread
|
|
14
14
|
from pyntcli.transport import pynt_requests
|
|
15
15
|
|
|
16
16
|
logger = log.get_logger()
|
|
@@ -37,6 +37,7 @@ GOT_INITIAL_HEALTHCHECK_MESSAGE = "Got initial pynt server health check"
|
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
def wait_for_healthcheck(address):
|
|
40
|
+
ui_thread.print_verbose("Waiting for healthcheck...")
|
|
40
41
|
start = time.time()
|
|
41
42
|
while start + HEALTHCHECK_TIMEOUT > time.time():
|
|
42
43
|
try:
|
|
@@ -49,6 +50,7 @@ def wait_for_healthcheck(address):
|
|
|
49
50
|
time.sleep(HEALTHCHECK_INTERVAL)
|
|
50
51
|
|
|
51
52
|
logger.debug("Health check timed out!")
|
|
53
|
+
ui_thread.print_verbose(f"Request to {address}/healthcheck timed out")
|
|
52
54
|
raise TimeoutError()
|
|
53
55
|
|
|
54
56
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import platform
|
|
2
|
+
import shutil
|
|
2
3
|
import subprocess
|
|
3
4
|
import os
|
|
4
5
|
import json
|
|
@@ -216,7 +217,8 @@ class PyntContainerNative:
|
|
|
216
217
|
|
|
217
218
|
self.fetch_and_validate_image()
|
|
218
219
|
args = self.config.docker_arguments if self.config.docker_arguments else None
|
|
219
|
-
|
|
220
|
+
docker_exec = shutil.which("docker")
|
|
221
|
+
docker_command = [docker_exec, "run", "--rm", "-d", "--name", self.container_name]
|
|
220
222
|
|
|
221
223
|
mounts = []
|
|
222
224
|
for mount in self.config.mounts:
|
|
@@ -224,7 +226,7 @@ class PyntContainerNative:
|
|
|
224
226
|
|
|
225
227
|
env_vars = []
|
|
226
228
|
for key, value in self.config.env_vars.items():
|
|
227
|
-
env_vars.extend(
|
|
229
|
+
env_vars.extend(["-e", f"{key}={value}"])
|
|
228
230
|
|
|
229
231
|
if is_network_host():
|
|
230
232
|
ports_exposure = ["--network=host"]
|
|
@@ -239,10 +241,11 @@ class PyntContainerNative:
|
|
|
239
241
|
docker_command += [f"{self.config.image.name}"]
|
|
240
242
|
docker_command += args
|
|
241
243
|
|
|
242
|
-
command
|
|
243
|
-
|
|
244
|
+
ui_thread.print_verbose(f"Running command (contains sensitive user secrets, do not paste outside this machine!):\n"
|
|
245
|
+
f"#########################\n {' '.join(docker_command)}\n#########################\n")
|
|
246
|
+
|
|
244
247
|
PyntContainerRegistry.instance().register_container(self)
|
|
245
|
-
process = subprocess.Popen(
|
|
248
|
+
process = subprocess.Popen(docker_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
|
|
246
249
|
stdout, stderr = process.communicate()
|
|
247
250
|
|
|
248
251
|
if stderr:
|
|
@@ -251,6 +254,7 @@ class PyntContainerNative:
|
|
|
251
254
|
container_id = stdout.strip()
|
|
252
255
|
|
|
253
256
|
if process.returncode and process.returncode != 0:
|
|
257
|
+
ui_thread.print_verbose(f"Unable to perform docker run command, return code: {process.returncode}")
|
|
254
258
|
raise DockerNativeUnavailableException(f"Unable to perform docker run command, return code: {process.returncode}")
|
|
255
259
|
|
|
256
260
|
# Start log streaming in a separate thread
|
|
@@ -304,12 +308,14 @@ class PyntContainerNative:
|
|
|
304
308
|
ui_thread.print(ui_thread.PrinterText("Pulling latest docker image", ui_thread.PrinterText.INFO))
|
|
305
309
|
pull_command = ['docker', 'pull', self.config.image.name]
|
|
306
310
|
get_image_command = ['docker', 'images', '-q', f'{self.config.image.name}']
|
|
311
|
+
ui_thread.print_verbose(f"Docker pull command:\n{' '.join(pull_command)}")
|
|
307
312
|
pull_process = subprocess.Popen(pull_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
308
313
|
_, pull_stderr = pull_process.communicate()
|
|
309
314
|
get_process = subprocess.Popen(get_image_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
310
315
|
get_stdout, _ = get_process.communicate()
|
|
311
316
|
local_image_id = get_stdout.decode('utf-8')
|
|
312
317
|
if self.config.image.is_self_managed and local_image_id:
|
|
318
|
+
ui_thread.print_verbose(f"Using local image {local_image_id}")
|
|
313
319
|
return local_image_id.strip()
|
|
314
320
|
elif local_image_id == "":
|
|
315
321
|
ui_thread.print(ui_thread.PrinterText(f"Error: the image {self.config.image.name} not found",
|
|
@@ -321,6 +327,9 @@ class PyntContainerNative:
|
|
|
321
327
|
|
|
322
328
|
if pull_process.returncode != 0:
|
|
323
329
|
raise ImageUnavailableException("Failed to pull image")
|
|
330
|
+
|
|
331
|
+
ui_thread.print_verbose("Image pulled successfully")
|
|
332
|
+
|
|
324
333
|
except Exception as e:
|
|
325
334
|
raise ImageUnavailableException(f"An error occurred: {str(e)}")
|
|
326
335
|
|
|
@@ -330,22 +339,16 @@ class PyntContainerNative:
|
|
|
330
339
|
self.kill_other_instances(report_to_user=False)
|
|
331
340
|
self.running = False
|
|
332
341
|
|
|
333
|
-
def adapt_run_command(self, docker_command=[]):
|
|
334
|
-
if self.system == "windows":
|
|
335
|
-
return ' '.join(docker_command)
|
|
336
|
-
return docker_command
|
|
337
|
-
|
|
338
|
-
def adapt_environment_variable_partial(self, key, value):
|
|
339
|
-
if self.system == "windows":
|
|
340
|
-
return ["-e", f"{key}={json.dumps(value)}"]
|
|
341
|
-
return ["-e", f"{key}={value}"]
|
|
342
|
-
|
|
343
342
|
def pre_run_validation(self, port):
|
|
344
343
|
self.kill_other_instances()
|
|
345
344
|
|
|
345
|
+
ui_thread.print_verbose("Checking if port is in use")
|
|
346
346
|
if container_utils.is_port_in_use(int(port)):
|
|
347
|
+
ui_thread.print_verbose(f"Port {port} is in use")
|
|
347
348
|
raise PortInUseException(port)
|
|
348
349
|
|
|
350
|
+
ui_thread.print_verbose("Port is not in use")
|
|
351
|
+
|
|
349
352
|
|
|
350
353
|
class PyntContainerRegistry:
|
|
351
354
|
_instance = None
|
|
@@ -361,8 +364,10 @@ class PyntContainerRegistry:
|
|
|
361
364
|
return PyntContainerRegistry._instance
|
|
362
365
|
|
|
363
366
|
def register_container(self, c: PyntContainerNative):
|
|
367
|
+
ui_thread.print_verbose("Registering container")
|
|
364
368
|
self.containers.append(c)
|
|
365
369
|
|
|
366
370
|
def stop_all_containers(self):
|
|
371
|
+
ui_thread.print_verbose("Stopping all containers")
|
|
367
372
|
for c in self.containers:
|
|
368
373
|
c.stop()
|
|
@@ -5,6 +5,8 @@ import pem
|
|
|
5
5
|
import certifi
|
|
6
6
|
import tempfile
|
|
7
7
|
|
|
8
|
+
from pyntcli.ui import ui_thread
|
|
9
|
+
|
|
8
10
|
|
|
9
11
|
class HostCaException(Exception):
|
|
10
12
|
pass
|
|
@@ -71,3 +73,6 @@ def request_from_xml(method, url, proxies=None, data=None, **kwargs):
|
|
|
71
73
|
return url
|
|
72
74
|
except requests.exceptions.TooManyRedirects as e:
|
|
73
75
|
return "Too many redirects for {}".format(url)
|
|
76
|
+
except Exception as e:
|
|
77
|
+
ui_thread.print_verbose(f"Failed to send request to {url} - {e}")
|
|
78
|
+
raise e
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pyntcli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.111
|
|
4
4
|
Summary: Command line utility to handle all of Pynt's different integrations
|
|
5
5
|
Author-email: Pynt-io <support@pynt.io>
|
|
6
6
|
Project-URL: Homepage, https://pynt.io
|
|
@@ -12,4 +12,3 @@ Requires-Dist: certifi>=2017.4.17
|
|
|
12
12
|
Requires-Dist: websocket-client
|
|
13
13
|
Requires-Dist: xmltodict
|
|
14
14
|
Requires-Dist: timedinput==0.1.1
|
|
15
|
-
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
ignoreTests/conftest.py,sha256=gToq5K74GtgeGQXjFvXSzMaE6axBYxAzcFG5XJPOXjI,427
|
|
2
2
|
ignoreTests/auth/login.py,sha256=KFlzWhXBAuwdi7GXf16gCB3ya94LQG2wjcSChE149rQ,3798
|
|
3
3
|
ignoreTests/store/cred_store.py,sha256=_7-917EtNC9eKEumO2_lt-7KuDmCwOZFaowCm7DbA_A,254
|
|
4
|
-
pyntcli/__init__.py,sha256=
|
|
4
|
+
pyntcli/__init__.py,sha256=lrG5YEJvZGvdRdN0nHdBVYBbeJk9t0y5VzK8HCgSUHk,24
|
|
5
5
|
pyntcli/main.py,sha256=RD0W2_0ogYBCXubo-YewxHYkiIXxNv6NkZOh3n1VujE,5964
|
|
6
6
|
pyntcli/analytics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
7
|
pyntcli/analytics/send.py,sha256=0hJ0WJNFHLqyohtRr_xOg5WEXzxHrUOlcePPg-k65Hk,3846
|
|
8
8
|
pyntcli/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
9
|
pyntcli/auth/login.py,sha256=TljsRXbEkNI1YUrKm5mlTw4YiecYScYUsit8Z8vstss,5228
|
|
10
10
|
pyntcli/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
-
pyntcli/commands/burp.py,sha256=
|
|
11
|
+
pyntcli/commands/burp.py,sha256=c3bqAAbrXdiy5aZlUQCWk3qhF_UjuZI_EOfWXJZzjgc,14102
|
|
12
12
|
pyntcli/commands/command.py,sha256=mMf1_bU7IFbE54FN3S3FuPODjHSSSu8aHzHJX-MgEFA,10832
|
|
13
13
|
pyntcli/commands/har.py,sha256=v6yWTuxPpXLlEi3yJ7gUDhFFGJZSpNQ3ehl2oaZJ-wc,4202
|
|
14
14
|
pyntcli/commands/id_command.py,sha256=UBEgMIpm4vauTCsKyixltiGUolNg_OfHEJvJ_i5BpJY,943
|
|
@@ -20,18 +20,18 @@ pyntcli/commands/root.py,sha256=UtGky7LfbfQ6mELHoNJcdHznFrUVBlhXI47_8QdApfc,4068
|
|
|
20
20
|
pyntcli/commands/static_file_extensions.py,sha256=PZJb02BI-64tbU-j3rdCNsXzTh7gkIDGxGKbKNw3h5k,1995
|
|
21
21
|
pyntcli/commands/sub_command.py,sha256=GF3-rE_qk2L4jGPFqHLm9SdGINmu3EakhjJTFyWjRms,374
|
|
22
22
|
pyntcli/commands/template.py,sha256=KocIH1T7occrrjaWJQaKKGgGWrU1bieTKEJbhFw3KLI,7976
|
|
23
|
-
pyntcli/commands/util.py,sha256=
|
|
23
|
+
pyntcli/commands/util.py,sha256=ev06aUlJ9tCSw1eAGVIsGlVVY4u0H6AJG9b5MB_bAzs,4594
|
|
24
24
|
pyntcli/log/__init__.py,sha256=cOGwOYzMoshEbZiiasBGkj6wF0SBu3Jdpl-AuakDesw,19
|
|
25
25
|
pyntcli/log/log.py,sha256=YXCvcCzuhQ5QUT2L02uQEdN_lTCzLEuet4OnLuEnjlM,112
|
|
26
26
|
pyntcli/pynt_docker/__init__.py,sha256=PQIOVxc7XXtMLfEX7ojgwf_Z3mmTllO3ZvzUZTPOxQY,30
|
|
27
27
|
pyntcli/pynt_docker/container_utils.py,sha256=_Onn7loInzyJAG2-Uk6CGpsuRyelmUFHOvtJj4Uzi9A,175
|
|
28
|
-
pyntcli/pynt_docker/pynt_container.py,sha256=
|
|
28
|
+
pyntcli/pynt_docker/pynt_container.py,sha256=3rp9Z9q6pAM6RYuhVIn5f6l0G9tz4j4LRr616-kzLTE,13734
|
|
29
29
|
pyntcli/store/__init__.py,sha256=1fP8cEAQCF_myja3gnhHH9FEqtBiOJ-2aBmUXSKBdFA,41
|
|
30
30
|
pyntcli/store/json_connector.py,sha256=UGs3uORw3iyn0YJ8kzab-veEZToA6d-ByXYuqEleWsA,560
|
|
31
31
|
pyntcli/store/store.py,sha256=Kl_HT9FJFdKlAH7SwAt3g4-bW-r-1ve_u13OPggQai0,2529
|
|
32
32
|
pyntcli/store/store_connector.py,sha256=w4LzcpRZesUZL1f63RmLlWEFRtJ6Y6rcS6PkkGtO4MA,357
|
|
33
33
|
pyntcli/transport/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
34
|
-
pyntcli/transport/pynt_requests.py,sha256=
|
|
34
|
+
pyntcli/transport/pynt_requests.py,sha256=gOPwBpPj6qIymDRFNgcQmwoI5Rqs4GMk4pfBvaCBeTo,1870
|
|
35
35
|
pyntcli/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
36
36
|
pyntcli/ui/progress.py,sha256=RrnO_jJNunoyupylakmWmHOEPw3lh99OHpKBzL6OBiE,1008
|
|
37
37
|
pyntcli/ui/prompt.py,sha256=tK3BFYvgT7ZgSrsN5ASkltcsbhy8tOdNfEjRyCjOk6Q,1570
|
|
@@ -40,8 +40,8 @@ pyntcli/ui/report.py,sha256=W-icPSZrGLOubXgam0LpOvHLl_aZg9Zx9qIkL8Ym5PE,1930
|
|
|
40
40
|
pyntcli/ui/ui_thread.py,sha256=XUBgLpYQjVhrilU-ofw7VSXgTiwneSdTxm61EvC3x4Q,5091
|
|
41
41
|
tests/test_utils.py,sha256=t5fTQUk1U_Js6iMxcGYGqt4C-crzOJ0CqCKtLkRtUi0,2050
|
|
42
42
|
tests/commands/test_pynt_cmd.py,sha256=BjGFCFACcSziLrNA6_27t6TjSmvdu54wx9njwLpRSJY,8379
|
|
43
|
-
pyntcli-0.1.
|
|
44
|
-
pyntcli-0.1.
|
|
45
|
-
pyntcli-0.1.
|
|
46
|
-
pyntcli-0.1.
|
|
47
|
-
pyntcli-0.1.
|
|
43
|
+
pyntcli-0.1.111.dist-info/METADATA,sha256=UFWXUEgPkYiQljEHLS2poC0J19AjL9W-GFFDkibWJoE,427
|
|
44
|
+
pyntcli-0.1.111.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
|
45
|
+
pyntcli-0.1.111.dist-info/entry_points.txt,sha256=kcGmqAxXDttNk2EPRcqunc_LTVp61gzakz0v-GEE2SY,43
|
|
46
|
+
pyntcli-0.1.111.dist-info/top_level.txt,sha256=64XSgBzSpgwjYjEKHZE7q3JH2a816zEeyZBXfJi3AKI,42
|
|
47
|
+
pyntcli-0.1.111.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|