pyntcli 0.1.72__py3-none-any.whl → 0.1.74__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/analytics/send.py +32 -17
- pyntcli/auth/login.py +41 -31
- pyntcli/commands/burp.py +125 -38
- pyntcli/commands/command.py +107 -39
- pyntcli/commands/har.py +52 -21
- pyntcli/commands/id_command.py +5 -3
- pyntcli/commands/listen.py +86 -36
- pyntcli/commands/newman.py +81 -33
- pyntcli/commands/postman.py +27 -26
- pyntcli/commands/pynt_cmd.py +27 -13
- pyntcli/commands/root.py +46 -23
- pyntcli/log/log.py +2 -1
- pyntcli/main.py +4 -3
- pyntcli/pynt_docker/pynt_container.py +65 -53
- pyntcli/store/store.py +19 -14
- {pyntcli-0.1.72.dist-info → pyntcli-0.1.74.dist-info}/METADATA +1 -1
- pyntcli-0.1.74.dist-info/RECORD +41 -0
- {pyntcli-0.1.72.dist-info → pyntcli-0.1.74.dist-info}/WHEEL +1 -1
- tests/auth/test_login.py +17 -19
- pyntcli-0.1.72.dist-info/RECORD +0 -41
- {pyntcli-0.1.72.dist-info → pyntcli-0.1.74.dist-info}/entry_points.txt +0 -0
- {pyntcli-0.1.72.dist-info → pyntcli-0.1.74.dist-info}/top_level.txt +0 -0
pyntcli/commands/newman.py
CHANGED
|
@@ -8,32 +8,51 @@ from pyntcli.commands import sub_command, util
|
|
|
8
8
|
from pyntcli.ui import ui_thread
|
|
9
9
|
from pyntcli.ui.progress import PyntProgress
|
|
10
10
|
|
|
11
|
+
|
|
11
12
|
def newman_usage():
|
|
12
|
-
return
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
13
|
+
return (
|
|
14
|
+
ui_thread.PrinterText(
|
|
15
|
+
"Integration with newman, run scan using postman collection from the CLI"
|
|
16
|
+
)
|
|
17
|
+
.with_line("")
|
|
18
|
+
.with_line("Usage:", style=ui_thread.PrinterText.HEADER)
|
|
19
|
+
.with_line("\tpynt newman [OPTIONS]")
|
|
20
|
+
.with_line("")
|
|
21
|
+
.with_line("Options:", style=ui_thread.PrinterText.HEADER)
|
|
22
|
+
.with_line("\t--collection - Postman collection file name")
|
|
23
|
+
.with_line("\t--environment - Postman environment file name")
|
|
24
|
+
.with_line("\t--reporters Output results to json")
|
|
25
|
+
.with_line(
|
|
26
|
+
"\t--host-ca - Path to the CA file in PEM format to enable SSL certificate verification for pynt when running through a VPN."
|
|
27
|
+
)
|
|
28
|
+
.with_line(
|
|
29
|
+
"\t--application-id - Attach the scan to an application, you can find the ID in your applications area at app.pynt.io"
|
|
30
|
+
)
|
|
31
|
+
.with_line(
|
|
32
|
+
"\t--return-error - 'all-findings' (warnings, or errors), 'errors-only', 'never' (default) "
|
|
33
|
+
)
|
|
34
|
+
)
|
|
35
|
+
|
|
23
36
|
|
|
24
37
|
class NewmanSubCommand(sub_command.PyntSubCommand):
|
|
25
38
|
def __init__(self, name) -> None:
|
|
26
39
|
super().__init__(name)
|
|
27
40
|
|
|
28
|
-
def usage(self, *args):
|
|
41
|
+
def usage(self, *args):
|
|
29
42
|
ui_thread.print(newman_usage())
|
|
30
43
|
|
|
31
44
|
def add_cmd(self, parent: argparse._SubParsersAction) -> argparse.ArgumentParser:
|
|
32
45
|
newman_cmd = parent.add_parser(self.name)
|
|
33
|
-
newman_cmd.add_argument("--collection", type=str, required=True)
|
|
34
|
-
newman_cmd.add_argument("--environment", nargs=
|
|
35
|
-
newman_cmd.add_argument(
|
|
36
|
-
|
|
46
|
+
newman_cmd.add_argument("--collection", type=str, required=True)
|
|
47
|
+
newman_cmd.add_argument("--environment", nargs="+", required=False)
|
|
48
|
+
newman_cmd.add_argument(
|
|
49
|
+
"--reporters", action="store_true", default=False, required=False
|
|
50
|
+
)
|
|
51
|
+
newman_cmd.add_argument(
|
|
52
|
+
"--return-error",
|
|
53
|
+
choices=["all-findings", "errors-only", "never"],
|
|
54
|
+
default="never"
|
|
55
|
+
)
|
|
37
56
|
|
|
38
57
|
newman_cmd.print_usage = self.usage
|
|
39
58
|
newman_cmd.print_help = self.usage
|
|
@@ -41,38 +60,67 @@ class NewmanSubCommand(sub_command.PyntSubCommand):
|
|
|
41
60
|
|
|
42
61
|
def run_cmd(self, args: argparse.Namespace):
|
|
43
62
|
port = str(util.find_open_port())
|
|
44
|
-
container = pynt_container.get_container_with_arguments(
|
|
63
|
+
container = pynt_container.get_container_with_arguments(
|
|
64
|
+
args, pynt_container.PyntDockerPort(src=port, dest=port, name="--port")
|
|
65
|
+
)
|
|
45
66
|
|
|
46
|
-
if not os.path.isfile(args.collection):
|
|
47
|
-
ui_thread.print(
|
|
67
|
+
if not os.path.isfile(args.collection):
|
|
68
|
+
ui_thread.print(
|
|
69
|
+
ui_thread.PrinterText(
|
|
70
|
+
"Could not find the provided collection path, please provide with a valid collection path",
|
|
71
|
+
ui_thread.PrinterText.WARNING,
|
|
72
|
+
)
|
|
73
|
+
)
|
|
48
74
|
return
|
|
49
|
-
|
|
75
|
+
|
|
50
76
|
collection_name = os.path.basename(args.collection)
|
|
51
77
|
container.docker_arguments += ["-c", collection_name]
|
|
52
|
-
container.mounts.append(
|
|
53
|
-
|
|
78
|
+
container.mounts.append(
|
|
79
|
+
pynt_container.create_mount(
|
|
80
|
+
os.path.abspath(args.collection), "/etc/pynt/{}".format(collection_name)
|
|
81
|
+
)
|
|
82
|
+
)
|
|
83
|
+
|
|
54
84
|
if "environment" in args and args.environment:
|
|
55
85
|
env_names = []
|
|
56
86
|
for environ in args.environment:
|
|
57
87
|
if not os.path.isfile(environ):
|
|
58
|
-
ui_thread.print(
|
|
88
|
+
ui_thread.print(
|
|
89
|
+
ui_thread.PrinterText(
|
|
90
|
+
f"Could not find the provided environment path: {environ}, please provide with a valid environment path",
|
|
91
|
+
ui_thread.PrinterText.WARNING,
|
|
92
|
+
)
|
|
93
|
+
)
|
|
59
94
|
return
|
|
60
95
|
env_name = os.path.basename(environ)
|
|
61
96
|
env_names.append(env_name)
|
|
62
|
-
container.mounts.append(
|
|
97
|
+
container.mounts.append(
|
|
98
|
+
pynt_container.create_mount(
|
|
99
|
+
os.path.abspath(environ), "/etc/pynt/{}".format(env_name)
|
|
100
|
+
)
|
|
101
|
+
)
|
|
63
102
|
container.docker_arguments += ["-e", ",".join(env_names)]
|
|
64
|
-
|
|
103
|
+
|
|
65
104
|
with util.create_default_file_mounts(args) as m:
|
|
66
105
|
container.mounts += m
|
|
67
|
-
newman_docker = pynt_container.PyntContainer(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
106
|
+
newman_docker = pynt_container.PyntContainer(
|
|
107
|
+
image_name=pynt_container.PYNT_DOCKER_IMAGE,
|
|
108
|
+
tag="latest",
|
|
109
|
+
detach=True,
|
|
110
|
+
base_container=container,
|
|
111
|
+
)
|
|
71
112
|
newman_docker.run()
|
|
72
|
-
|
|
73
|
-
healthcheck = partial(
|
|
113
|
+
|
|
114
|
+
healthcheck = partial(
|
|
115
|
+
util.wait_for_healthcheck, "http://localhost:{}".format(port)
|
|
116
|
+
)
|
|
74
117
|
ui_thread.print_generator(ui_thread.AnsiText.wrap_gen(newman_docker.stdout))
|
|
75
|
-
|
|
76
|
-
with ui_thread.progress(
|
|
118
|
+
|
|
119
|
+
with ui_thread.progress(
|
|
120
|
+
"ws://localhost:{}/progress".format(port),
|
|
121
|
+
healthcheck,
|
|
122
|
+
"scan in progress...",
|
|
123
|
+
100,
|
|
124
|
+
):
|
|
77
125
|
while newman_docker.is_alive():
|
|
78
126
|
time.sleep(1)
|
pyntcli/commands/postman.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import argparse
|
|
2
|
-
import time
|
|
2
|
+
import time
|
|
3
3
|
import websocket
|
|
4
4
|
import webbrowser
|
|
5
5
|
import os
|
|
@@ -14,28 +14,31 @@ from pyntcli.pynt_docker import pynt_container
|
|
|
14
14
|
from pyntcli.ui import ui_thread
|
|
15
15
|
from pyntcli.transport import pynt_requests
|
|
16
16
|
|
|
17
|
+
|
|
17
18
|
class PyntPostmanException(Exception):
|
|
18
19
|
pass
|
|
19
20
|
|
|
21
|
+
|
|
20
22
|
class PyntWebSocketException(PyntPostmanException):
|
|
21
23
|
pass
|
|
22
24
|
|
|
25
|
+
|
|
23
26
|
logger = log.get_logger()
|
|
24
27
|
|
|
28
|
+
|
|
25
29
|
def postman_usage():
|
|
26
30
|
return ui_thread.PrinterText("Integration with postman, run scan from pynt postman collection") \
|
|
27
31
|
.with_line("") \
|
|
28
|
-
.with_line("Usage:",style=ui_thread.PrinterText.HEADER) \
|
|
32
|
+
.with_line("Usage:", style=ui_thread.PrinterText.HEADER) \
|
|
29
33
|
.with_line("\tpynt postman [OPTIONS]") \
|
|
30
34
|
.with_line("") \
|
|
31
|
-
.with_line("Options:",style=ui_thread.PrinterText.HEADER) \
|
|
35
|
+
.with_line("Options:", style=ui_thread.PrinterText.HEADER) \
|
|
32
36
|
.with_line("\t--port - set the port pynt will listen to (DEFAULT: 5001)") \
|
|
33
37
|
.with_line("\t--insecure - use when target uses self signed certificates") \
|
|
34
38
|
.with_line("\t--host-ca - path to the CA file in PEM format to enable SSL certificate verification for pynt when running through a VPN.")
|
|
35
39
|
|
|
36
40
|
|
|
37
|
-
|
|
38
|
-
class PostmanSubCommand(sub_command.PyntSubCommand):
|
|
41
|
+
class PostmanSubCommand(sub_command.PyntSubCommand):
|
|
39
42
|
def __init__(self, name) -> None:
|
|
40
43
|
super().__init__(name)
|
|
41
44
|
self.server_base_url = "http://localhost:{}/api"
|
|
@@ -43,18 +46,17 @@ class PostmanSubCommand(sub_command.PyntSubCommand):
|
|
|
43
46
|
def usage(self, *args):
|
|
44
47
|
ui_thread.print(postman_usage())
|
|
45
48
|
|
|
46
|
-
def add_cmd(self, parent_command: argparse._SubParsersAction) -> argparse.ArgumentParser:
|
|
49
|
+
def add_cmd(self, parent_command: argparse._SubParsersAction) -> argparse.ArgumentParser:
|
|
47
50
|
postman_cmd = parent_command.add_parser(self.name)
|
|
48
51
|
postman_cmd.add_argument("--port", "-p", help="set the port pynt will listen to (DEFAULT: 5001)", type=int, default=5001)
|
|
49
52
|
postman_cmd.print_usage = self.usage
|
|
50
53
|
postman_cmd.print_help = self.usage
|
|
51
54
|
return postman_cmd
|
|
52
|
-
|
|
53
55
|
|
|
54
56
|
def scan_id_generator(self, port):
|
|
55
57
|
try:
|
|
56
58
|
ws = websocket.WebSocket()
|
|
57
|
-
ws.connect("ws://localhost:{}/api/scan_id".format(port))
|
|
59
|
+
ws.connect("ws://localhost:{}/api/scan_id".format(port))
|
|
58
60
|
|
|
59
61
|
while ws.connected:
|
|
60
62
|
scan_id = ws.recv()
|
|
@@ -69,7 +71,7 @@ class PostmanSubCommand(sub_command.PyntSubCommand):
|
|
|
69
71
|
finally:
|
|
70
72
|
ws.close()
|
|
71
73
|
|
|
72
|
-
def get_report(self, port,report_format, scan_id):
|
|
74
|
+
def get_report(self, port, report_format, scan_id):
|
|
73
75
|
while True:
|
|
74
76
|
res = pynt_requests.get(self.server_base_url.format(port) + "/report?format={}".format(report_format), params={"scanId": scan_id})
|
|
75
77
|
if res.status_code == HTTPStatus.OK:
|
|
@@ -79,42 +81,41 @@ class PostmanSubCommand(sub_command.PyntSubCommand):
|
|
|
79
81
|
continue
|
|
80
82
|
if res.status_code == HTTPStatus.BAD_REQUEST:
|
|
81
83
|
return
|
|
82
|
-
if res.status_code == 517:
|
|
84
|
+
if res.status_code == 517: # pynt did not recieve any requests
|
|
83
85
|
ui_thread.print(ui_thread.PrinterText(res.json()["message"], ui_thread.PrinterText.WARNING))
|
|
84
|
-
return
|
|
86
|
+
return
|
|
85
87
|
ui_thread.print("Error in polling for scan report: {}".format(res.text))
|
|
86
|
-
return
|
|
87
|
-
|
|
88
|
+
return
|
|
88
89
|
|
|
89
90
|
def run_cmd(self, args: argparse.Namespace):
|
|
90
|
-
if "application_id" in args and args.application_id:
|
|
91
|
-
ui_thread.print("application-id is not supported in postman integration, use the
|
|
91
|
+
if "application_id" in args and args.application_id:
|
|
92
|
+
ui_thread.print("application-id is not supported in postman integration, use the collection variables to set application id.")
|
|
92
93
|
args.application_id = ""
|
|
93
94
|
|
|
94
|
-
container = pynt_container.get_container_with_arguments(args
|
|
95
|
-
|
|
95
|
+
container = pynt_container.get_container_with_arguments(args, pynt_container.PyntDockerPort("5001", args.port, name="--port"))
|
|
96
|
+
|
|
96
97
|
if util.is_port_in_use(args.port):
|
|
97
98
|
ui_thread.print(ui_thread.PrinterText("Port: {} already in use, please use a different one".format(args.port), ui_thread.PrinterText.WARNING))
|
|
98
99
|
return
|
|
99
100
|
|
|
100
|
-
postman_docker = pynt_container.PyntContainer(image_name=pynt_container.PYNT_DOCKER_IMAGE,
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
101
|
+
postman_docker = pynt_container.PyntContainer(image_name=pynt_container.PYNT_DOCKER_IMAGE,
|
|
102
|
+
tag="postman-latest",
|
|
103
|
+
detach=True,
|
|
104
|
+
base_container=container)
|
|
104
105
|
|
|
105
106
|
postman_docker.run()
|
|
106
|
-
ui_thread.print_generator(postman_docker.stdout)
|
|
107
|
-
|
|
107
|
+
ui_thread.print_generator(postman_docker.stdout)
|
|
108
|
+
|
|
108
109
|
util.wait_for_healthcheck("http://localhost:{}".format(args.port))
|
|
109
110
|
|
|
110
111
|
for scan_id in self.scan_id_generator(args.port):
|
|
111
|
-
html_report = self.get_report(args.port, "html",scan_id)
|
|
112
|
+
html_report = self.get_report(args.port, "html", scan_id)
|
|
112
113
|
html_report_path = os.path.join(tempfile.gettempdir(), "pynt_report_{}.html".format(int(time.time())))
|
|
113
114
|
|
|
114
115
|
if html_report:
|
|
115
|
-
with open(html_report_path, "w") as html_file:
|
|
116
|
+
with open(html_report_path, "w", encoding="utf-8") as html_file:
|
|
116
117
|
html_file.write(html_report)
|
|
117
118
|
webbrowser.open("file://{}".format(html_report_path))
|
|
118
|
-
|
|
119
|
+
|
|
119
120
|
if not postman_docker.is_alive():
|
|
120
121
|
ui_thread.print(ui_thread.PrinterText("Pynt container is not available", ui_thread.PrinterText.WARNING))
|
pyntcli/commands/pynt_cmd.py
CHANGED
|
@@ -5,6 +5,9 @@ from pyntcli.analytics import send as analytics
|
|
|
5
5
|
from pyntcli.transport import pynt_requests
|
|
6
6
|
from pyntcli.ui import ui_thread
|
|
7
7
|
|
|
8
|
+
from requests.exceptions import SSLError, HTTPError
|
|
9
|
+
|
|
10
|
+
|
|
8
11
|
from . import command, listen, postman, root, sub_command, id_command, newman, har, burp
|
|
9
12
|
|
|
10
13
|
avail_sub_commands = [
|
|
@@ -17,29 +20,40 @@ avail_sub_commands = [
|
|
|
17
20
|
burp.BurpCommand("burp"),
|
|
18
21
|
]
|
|
19
22
|
|
|
23
|
+
|
|
20
24
|
class PyntCommandException(Exception):
|
|
21
25
|
pass
|
|
22
26
|
|
|
27
|
+
|
|
23
28
|
class BadArgumentsException(PyntCommandException):
|
|
24
29
|
pass
|
|
25
30
|
|
|
31
|
+
|
|
26
32
|
class NoSuchCommandException(PyntCommandException):
|
|
27
33
|
pass
|
|
28
34
|
|
|
29
35
|
|
|
30
36
|
VERSION_CHECK_URL = "https://d1efigcr4c19qn.cloudfront.net/cli/version"
|
|
31
37
|
|
|
38
|
+
|
|
32
39
|
def check_is_latest_version(current_version):
|
|
33
|
-
res = pynt_requests.get(VERSION_CHECK_URL)
|
|
34
|
-
res.raise_for_status()
|
|
35
40
|
|
|
36
|
-
|
|
41
|
+
try:
|
|
42
|
+
res = pynt_requests.get(VERSION_CHECK_URL)
|
|
43
|
+
res.raise_for_status()
|
|
37
44
|
|
|
38
|
-
|
|
39
|
-
ui_thread.print(ui_thread.PrinterText("""Pynt CLI new version is available, upgrade now with:
|
|
40
|
-
python3 -m pip install --upgrade pyntcli""",ui_thread.PrinterText.WARNING))
|
|
45
|
+
latest_versions = res.text.replace("\n", "")
|
|
41
46
|
|
|
42
|
-
|
|
47
|
+
if current_version != latest_versions:
|
|
48
|
+
ui_thread.print(ui_thread.PrinterText("""Pynt CLI new version is available, upgrade now with:
|
|
49
|
+
python3 -m pip install --upgrade pyntcli""", ui_thread.PrinterText.WARNING))
|
|
50
|
+
except SSLError:
|
|
51
|
+
ui_thread.print(ui_thread.PrinterText("""Error: Unable to check if Pynt CLI version is up-to-date due to VPN/proxy. Run Pynt with --insecure to fix.""", ui_thread.PrinterText.WARNING))
|
|
52
|
+
except HTTPError:
|
|
53
|
+
ui_thread.print("""Unable to check if Pynt CLI version is up-to-date""")
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class PyntCommand:
|
|
43
57
|
def __init__(self) -> None:
|
|
44
58
|
self.base: root.BaseCommand = root.BaseCommand()
|
|
45
59
|
self.sub_commands: Dict[str, sub_command.PyntSubCommand] = {sc.get_name(): sc for sc in avail_sub_commands}
|
|
@@ -50,25 +64,25 @@ class PyntCommand:
|
|
|
50
64
|
for sc in self.sub_commands.values():
|
|
51
65
|
self.base.add_base_arguments(sc.add_cmd(self.base.get_subparser()))
|
|
52
66
|
|
|
53
|
-
def parse_args(self, args_from_cmd: List[str]):
|
|
67
|
+
def parse_args(self, args_from_cmd: List[str]):
|
|
54
68
|
return self.base.cmd().parse_args(args_from_cmd)
|
|
55
69
|
|
|
56
70
|
def run_cmd(self, args: argparse.Namespace):
|
|
57
71
|
if not "command" in args:
|
|
58
72
|
raise BadArgumentsException()
|
|
59
|
-
|
|
60
|
-
command = getattr(args, "command")
|
|
73
|
+
|
|
74
|
+
command = getattr(args, "command")
|
|
61
75
|
if not command in self.sub_commands:
|
|
62
76
|
raise NoSuchCommandException()
|
|
63
|
-
|
|
77
|
+
|
|
64
78
|
if "host_ca" in args and args.host_ca:
|
|
65
79
|
pynt_requests.add_host_ca(args.host_ca)
|
|
66
|
-
|
|
80
|
+
|
|
67
81
|
if "insecure" in args and args.insecure:
|
|
68
82
|
pynt_requests.disable_tls_termination()
|
|
69
83
|
|
|
70
84
|
check_is_latest_version(cli_version)
|
|
71
85
|
analytics.emit(analytics.CLI_START)
|
|
72
|
-
|
|
86
|
+
|
|
73
87
|
self.base.run_cmd(args)
|
|
74
88
|
self.sub_commands[command].run_cmd(args)
|
pyntcli/commands/root.py
CHANGED
|
@@ -4,36 +4,52 @@ import sys
|
|
|
4
4
|
from os import environ
|
|
5
5
|
|
|
6
6
|
from pyntcli.auth import login
|
|
7
|
+
import pyntcli.log.log as log
|
|
7
8
|
from pyntcli.ui import ui_thread
|
|
8
9
|
from pyntcli.analytics import send as analytics
|
|
9
10
|
|
|
11
|
+
|
|
10
12
|
def root_usage():
|
|
11
|
-
return
|
|
12
|
-
.
|
|
13
|
-
.with_line("")
|
|
14
|
-
.with_line("
|
|
15
|
-
.with_line("
|
|
16
|
-
.with_line(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
.with_line("
|
|
13
|
+
return (
|
|
14
|
+
ui_thread.PrinterText("Usage:", style=ui_thread.PrinterText.HEADER)
|
|
15
|
+
.with_line("\tpynt [COMMAND] [OPTIONS]")
|
|
16
|
+
.with_line("")
|
|
17
|
+
.with_line("Commands:", style=ui_thread.PrinterText.HEADER)
|
|
18
|
+
.with_line(
|
|
19
|
+
"\tpostman - integration with postman, run scan from pynt postman collection"
|
|
20
|
+
)
|
|
21
|
+
.with_line("\tnewman - run postman collection from the CLI")
|
|
22
|
+
.with_line("\thar - run scan on static har file")
|
|
23
|
+
.with_line("\tcommand - run scan with a given command")
|
|
24
|
+
.with_line("\tlisten - run scan with a routed traffic")
|
|
25
|
+
.with_line("\tburp - run scan on a burp xml output file")
|
|
26
|
+
.with_line(
|
|
27
|
+
"\tpynt-id - view your pynt-id to use when running pynt in CI pipeline"
|
|
28
|
+
)
|
|
29
|
+
.with_line("")
|
|
30
|
+
.with_line(
|
|
31
|
+
"Run pynt [COMMAND] -h to get help on a specific command",
|
|
32
|
+
style=ui_thread.PrinterText.INFO,
|
|
33
|
+
)
|
|
34
|
+
)
|
|
35
|
+
|
|
20
36
|
|
|
21
37
|
def usage(*args):
|
|
22
38
|
ui_thread.print(root_usage())
|
|
23
39
|
|
|
24
40
|
|
|
25
41
|
def check_cicd_context():
|
|
26
|
-
if environ.get(
|
|
42
|
+
if environ.get("GITHUB_ACTION") is not None:
|
|
27
43
|
analytics.emit(analytics.CICD, {"env": "GitHub"})
|
|
28
44
|
return
|
|
29
|
-
if environ.get(
|
|
45
|
+
if environ.get("GITLAB_USER_ID") is not None:
|
|
30
46
|
analytics.emit(analytics.CICD, {"env": "GitLab"})
|
|
31
47
|
return
|
|
32
|
-
if environ.get(
|
|
48
|
+
if environ.get("JENKINS_HOME") is not None:
|
|
33
49
|
analytics.emit(analytics.CICD, {"env": "Jenkins"})
|
|
34
|
-
|
|
35
50
|
|
|
36
|
-
|
|
51
|
+
|
|
52
|
+
class BaseCommand:
|
|
37
53
|
def __init__(self) -> None:
|
|
38
54
|
self.base: argparse.ArgumentParser = None
|
|
39
55
|
self.subparser: argparse._SubParsersAction = None
|
|
@@ -41,15 +57,21 @@ class BaseCommand():
|
|
|
41
57
|
def cmd(self):
|
|
42
58
|
if self.base:
|
|
43
59
|
return self.base
|
|
44
|
-
|
|
60
|
+
|
|
45
61
|
self.base = argparse.ArgumentParser(prog="pynt")
|
|
46
62
|
self.base.print_usage = usage
|
|
47
63
|
self.base.print_help = usage
|
|
48
|
-
return self.base
|
|
49
|
-
|
|
64
|
+
return self.base
|
|
65
|
+
|
|
50
66
|
def add_base_arguments(self, parser):
|
|
51
|
-
parser.add_argument(
|
|
52
|
-
|
|
67
|
+
parser.add_argument(
|
|
68
|
+
"--insecure",
|
|
69
|
+
default=False,
|
|
70
|
+
required=False,
|
|
71
|
+
action="store_true",
|
|
72
|
+
help="use when target uses self signed certificates",
|
|
73
|
+
)
|
|
74
|
+
parser.add_argument("--dev-flags", type=str, default="", help=argparse.SUPPRESS)
|
|
53
75
|
parser.add_argument("--host-ca", type=str, default="")
|
|
54
76
|
parser.add_argument("--transport-config", type=str, default="")
|
|
55
77
|
parser.add_argument("--application-id", type=str, default="", required=False)
|
|
@@ -58,7 +80,7 @@ class BaseCommand():
|
|
|
58
80
|
def get_subparser(self) -> argparse._SubParsersAction:
|
|
59
81
|
if self.subparser is None:
|
|
60
82
|
self.subparser = self.base.add_subparsers(help="", dest="command")
|
|
61
|
-
|
|
83
|
+
|
|
62
84
|
return self.subparser
|
|
63
85
|
|
|
64
86
|
def run_cmd(self, args: argparse.Namespace):
|
|
@@ -67,11 +89,12 @@ class BaseCommand():
|
|
|
67
89
|
if login.should_login():
|
|
68
90
|
l = login.Login().login()
|
|
69
91
|
else:
|
|
70
|
-
login.refresh_token()
|
|
71
|
-
|
|
92
|
+
login.refresh_token()
|
|
93
|
+
|
|
72
94
|
analytics.emit(analytics.LOGIN_DONE)
|
|
73
95
|
user_id = login.user_id()
|
|
74
96
|
if user_id:
|
|
75
97
|
analytics.set_user_id(user_id)
|
|
98
|
+
log.add_user_details(user_id)
|
|
76
99
|
|
|
77
|
-
check_cicd_context()
|
|
100
|
+
check_cicd_context()
|
pyntcli/log/log.py
CHANGED
pyntcli/main.py
CHANGED
|
@@ -45,6 +45,7 @@ def start_analytics():
|
|
|
45
45
|
user_id = login.user_id()
|
|
46
46
|
if user_id:
|
|
47
47
|
analytics.set_user_id(user_id)
|
|
48
|
+
log.add_user_details(user_id)
|
|
48
49
|
|
|
49
50
|
|
|
50
51
|
def main():
|
|
@@ -63,7 +64,7 @@ def main():
|
|
|
63
64
|
ui_thread.print(ui_thread.PrinterText("Docker was unavailable, please make sure docker is installed and running.", ui_thread.PrinterText.WARNING))
|
|
64
65
|
analytics.emit(analytics.ERROR, {"error": "docker unavailable"})
|
|
65
66
|
except SSLError:
|
|
66
|
-
ui_thread.print(ui_thread.PrinterText("We encountered SSL issues and could not proceed, this may be the cause of a VPN or a Firewall in place.", ui_thread.PrinterText.WARNING))
|
|
67
|
+
ui_thread.print(ui_thread.PrinterText("We encountered SSL issues and could not proceed, this may be the cause of a VPN or a Firewall in place. Run again with --insecure", ui_thread.PrinterText.WARNING))
|
|
67
68
|
except login.Timeout:
|
|
68
69
|
ui_thread.print(ui_thread.PrinterText("Pynt CLI exited due to incomplete registration, please try again.", ui_thread.PrinterText.WARNING))
|
|
69
70
|
analytics.emit(analytics.ERROR, {"error": "login timeout"})
|
|
@@ -71,8 +72,8 @@ def main():
|
|
|
71
72
|
ui_thread.print(ui_thread.PrinterText("Pynt CLI exited due to malformed credentials provided in env vars.", ui_thread.PrinterText.WARNING))
|
|
72
73
|
analytics.emit(analytics.ERROR, {"error": "invalid pynt cli credentials in env vars"})
|
|
73
74
|
except pynt_container.ImageUnavailableException:
|
|
74
|
-
analytics.emit(analytics.ERROR, {"error": "
|
|
75
|
-
|
|
75
|
+
analytics.emit(analytics.ERROR, {"error": "Couldn't pull pynt image and no local image found"})
|
|
76
|
+
ui_thread.print(ui_thread.PrinterText("Error: Couldn't pull pynt image and no local image found.",ui_thread.PrinterText.WARNING))
|
|
76
77
|
except HtmlReportNotCreatedException:
|
|
77
78
|
analytics.emit(analytics.ERROR, {"error": "Html report was not created"})
|
|
78
79
|
pynt_errors.unexpected_error()
|