pyntcli 0.1.73__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.
@@ -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: #pynt did not recieve any requests
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 request body in the start scan request")
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 ,pynt_container.PyntDockerPort("5001", args.port, name="--port"))
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
- tag="postman-latest",
102
- detach=True,
103
- base_container=container)
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
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))
@@ -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
- latest_versions = res.text.replace("\n","")
41
+ try:
42
+ res = pynt_requests.get(VERSION_CHECK_URL)
43
+ res.raise_for_status()
37
44
 
38
- if current_version != latest_versions:
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
- class PyntCommand:
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,6 +4,7 @@ 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
 
@@ -94,5 +95,6 @@ class BaseCommand:
94
95
  user_id = login.user_id()
95
96
  if user_id:
96
97
  analytics.set_user_id(user_id)
98
+ log.add_user_details(user_id)
97
99
 
98
100
  check_cicd_context()
pyntcli/log/log.py CHANGED
@@ -15,7 +15,8 @@ LOGGING = {
15
15
  'level': 'DEBUG',
16
16
  'token': "KOfjdWTcZXmjAwAOslpFYwhLpDzFTfJl",
17
17
  'logs_drain_timeout': 5,
18
- 'url': 'https://listener.logz.io:8071'
18
+ 'url': 'https://listener.logz.io:8071',
19
+ 'retries_no': 1,
19
20
  }
20
21
  },
21
22
  'loggers': {
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": "Couldnt pull pynt image and no local image found"})
75
- pynt_errors.unexpected_error()
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()
@@ -9,19 +9,23 @@ import base64
9
9
  from pyntcli.ui import ui_thread
10
10
  from pyntcli.analytics import send as analytics
11
11
  from pyntcli.store import CredStore
12
- from pyntcli.auth.login import PYNT_CREDENTIALS , PYNT_SAAS, PYNT_BUCKET_NAME,PYNT_PARAM1, PYNT_PARAM2
12
+ from pyntcli.auth.login import PYNT_ID, PYNT_SAAS, PYNT_BUCKET_NAME, PYNT_PARAM1, PYNT_PARAM2
13
13
 
14
14
  PYNT_DOCKER_IMAGE = "ghcr.io/pynt-io/pynt"
15
15
 
16
+
16
17
  def create_mount(src, destination, mount_type="bind"):
17
18
  return Mount(target=destination, source=src, type=mount_type)
18
19
 
20
+
19
21
  class DockerNotAvailableException(Exception):
20
22
  pass
21
23
 
24
+
22
25
  class ImageUnavailableException(Exception):
23
26
  pass
24
27
 
28
+
25
29
  def get_docker_type():
26
30
  try:
27
31
  c = docker.from_env()
@@ -30,29 +34,31 @@ def get_docker_type():
30
34
  analytics.deferred_emit(analytics.DOCKER_PLATFORM, platform)
31
35
  if platform and platform.get("Name"):
32
36
  return platform.get("Name")
33
-
37
+
34
38
  return ""
35
39
 
36
40
  except DockerException:
37
41
  raise DockerNotAvailableException()
38
- except Exception: #TODO: This is since windows is not behaving nice
42
+ except Exception: # TODO: This is since windows is not behaving nice
39
43
  raise DockerNotAvailableException()
40
44
 
41
45
 
42
46
  class PyntBaseConatiner():
43
- def __init__(self,docker_type,docker_arguments,mounts, environment={}) -> None:
47
+ def __init__(self, docker_type, docker_arguments, mounts, environment={}) -> None:
44
48
  self.docker_type = docker_type
45
49
  self.docker_arguments = docker_arguments
46
50
  self.mounts = mounts
47
51
  self.environment = environment
48
52
 
53
+
49
54
  class PyntDockerPort:
50
55
  def __init__(self, src, dest, name) -> None:
51
56
  self.src = src
52
57
  self.dest = dest
53
58
  self.name = name
54
59
 
55
- def get_container_with_arguments(args: argparse.Namespace , *port_args: PyntDockerPort) -> PyntBaseConatiner:
60
+
61
+ def get_container_with_arguments(args: argparse.Namespace, *port_args: PyntDockerPort) -> PyntBaseConatiner:
56
62
  docker_arguments = []
57
63
  if "desktop" in get_docker_type().lower():
58
64
  ports = {}
@@ -61,22 +67,22 @@ def get_container_with_arguments(args: argparse.Namespace , *port_args: PyntDock
61
67
  docker_type = PyntDockerDesktopContainer(ports=ports)
62
68
  else:
63
69
  docker_type = PyntNativeContainer(network="host")
64
- for p in port_args:
70
+ for p in port_args:
65
71
  docker_arguments.append(p.name)
66
72
  docker_arguments.append(str(p.dest))
67
-
73
+
68
74
  if "insecure" in args and args.insecure:
69
75
  docker_arguments.append("--insecure")
70
-
71
- if "application_id" in args and args.application_id:
72
- docker_arguments += ["--application-id",args.application_id]
73
76
 
74
- if "proxy" in args and args.proxy:
75
- docker_arguments += ["--proxy",args.proxy]
77
+ if "application_id" in args and args.application_id:
78
+ docker_arguments += ["--application-id", args.application_id]
76
79
 
77
- if "dev_flags" in args:
80
+ if "proxy" in args and args.proxy:
81
+ docker_arguments += ["--proxy", args.proxy]
82
+
83
+ if "dev_flags" in args:
78
84
  docker_arguments += args.dev_flags.split(" ")
79
-
85
+
80
86
  mounts = []
81
87
  if "host_ca" in args and args.host_ca:
82
88
  ca_name = os.path.basename(args.host_ca)
@@ -87,38 +93,41 @@ def get_container_with_arguments(args: argparse.Namespace , *port_args: PyntDock
87
93
  tc_name = os.path.basename(args.transport_config)
88
94
  docker_arguments += ["--transport-config", tc_name]
89
95
  mounts.append(create_mount(os.path.abspath(args.transport_config), "/etc/pynt/{}".format(tc_name)))
90
-
91
- env = {PYNT_CREDENTIALS:CredStore().get_access_token(), "PYNT_SAAS_URL": PYNT_SAAS}
96
+
97
+ env = {PYNT_ID: CredStore().get_tokens(), "PYNT_SAAS_URL": PYNT_SAAS}
92
98
  if user_set_all_variables():
93
99
  add_env_variables(env)
94
100
  return PyntBaseConatiner(docker_type, docker_arguments, mounts, env)
95
-
101
+
102
+
96
103
  def _container_image_from_tag(tag: str) -> str:
97
- if ":" in tag:
104
+ if ":" in tag:
98
105
  return tag.split(":")[0]
99
106
 
100
107
  return tag
101
108
 
109
+
102
110
  def user_set_all_variables():
103
- return all([PYNT_BUCKET_NAME, PYNT_PARAM1, PYNT_PARAM2])
104
-
111
+ return all([PYNT_BUCKET_NAME, PYNT_PARAM1, PYNT_PARAM2])
112
+
113
+
105
114
  def add_env_variables(env: dict):
106
- env["PYNT_BUCKET_NAME"] = PYNT_BUCKET_NAME
107
- env["PYNT_PARAM1"] = base64.b64encode(PYNT_PARAM1.encode('utf-8'))
108
- env["PYNT_PARAM2"] = base64.b64encode(PYNT_PARAM2.encode('utf-8'))
109
-
115
+ env["PYNT_BUCKET_NAME"] = PYNT_BUCKET_NAME
116
+ env["PYNT_PARAM1"] = base64.b64encode(PYNT_PARAM1.encode('utf-8'))
117
+ env["PYNT_PARAM2"] = base64.b64encode(PYNT_PARAM2.encode('utf-8'))
118
+
119
+
110
120
  class PyntContainer():
111
121
  def __init__(self, image_name, tag, detach, base_container: PyntBaseConatiner) -> None:
112
122
  self.docker_client: docker.DockerClient = None
113
123
  self.image = image_name if not os.environ.get("IMAGE") else os.environ.get("IMAGE")
114
124
  self.tag = tag if not os.environ.get("TAG") else os.environ.get("TAG")
115
125
  self.detach = detach
116
- self.stdout = None
126
+ self.stdout = None
117
127
  self.running = False
118
128
  self.container_name = ""
119
129
  self.base_container = base_container
120
130
 
121
-
122
131
  def _create_docker_client(self):
123
132
  self.docker_client = docker.from_env()
124
133
  pat = os.environ.get("DOCKER_PASSWORD")
@@ -126,28 +135,28 @@ class PyntContainer():
126
135
  registry = os.environ.get("DOCKER_REGISTRY")
127
136
  if pat and username and registry:
128
137
  self.docker_client.login(username=username, password=pat, registry=registry)
129
-
138
+
130
139
  def _is_docker_image_up_to_date(self, image):
131
140
  return True
132
-
141
+
133
142
  def _handle_outdated_docker_image(self, image):
134
143
  return image
135
-
144
+
136
145
  def kill_other_instances(self):
137
146
  for c in self.docker_client.containers.list():
138
147
  if len(c.image.tags) and _container_image_from_tag(c.image.tags[0]) == self.image:
139
148
  c.kill()
140
-
149
+
141
150
  def stop(self):
142
151
  if not self.running:
143
- return
152
+ return
144
153
 
145
154
  self.kill_other_instances()
146
155
 
147
156
  self.docker_client.close()
148
157
  self.docker_client = None
149
158
  self.running = False
150
-
159
+
151
160
  def is_alive(self):
152
161
  if not self.docker_client or not self.container_name:
153
162
  return False
@@ -155,47 +164,48 @@ class PyntContainer():
155
164
  l = self.docker_client.containers.list(filters={"name": self.container_name})
156
165
  if len(l) != 1:
157
166
  return False
158
-
167
+
159
168
  return l[0].status == "running"
160
-
169
+
161
170
  def pull_image(self):
162
171
  try:
163
172
  return self.docker_client.images.pull(self.image, tag=self.tag)
164
173
  except APIError as e:
165
- analytics.emit(analytics.ERROR,{"error": "Unable to pull image from ghcr: {}".format(e)})
174
+ analytics.emit(analytics.ERROR, {"error": "Unable to pull image from ghcr: {}".format(e)})
175
+ ui_thread.print(ui_thread.PrinterText("Error: Docker unable to pull latest Pynt image due to VPN/proxy. If using a mirror for Docker images, visit docs.pynt.io for help.", ui_thread.PrinterText.WARNING))
166
176
  return None
167
177
 
168
178
  def get_image(self):
169
179
  try:
170
180
  image = self.pull_image()
171
181
  if not image:
172
- image = self.docker_client.images.get('{}:{}'.format(self.image,self.tag))
182
+ ui_thread.print(ui_thread.PrinterText("Trying to get pynt local image", ui_thread.PrinterText.INFO))
183
+ image = self.docker_client.images.get('{}:{}'.format(self.image, self.tag))
173
184
  return image
174
185
  except ImageNotFound:
175
186
  raise ImageUnavailableException()
176
187
 
177
- def run(self):
188
+ def run(self):
178
189
  if not self.docker_client:
179
190
  self._create_docker_client()
180
-
191
+
181
192
  self.running = True
182
193
  self.kill_other_instances()
183
194
 
184
195
  ui_thread.print(ui_thread.PrinterText("Pulling latest docker", ui_thread.PrinterText.INFO))
185
196
  image = self.get_image()
186
197
  ui_thread.print(ui_thread.PrinterText("Docker pull done", ui_thread.PrinterText.INFO))
187
-
198
+
188
199
  args = self.base_container.docker_arguments if self.base_container.docker_arguments else None
189
-
190
200
 
191
201
  run_arguments = {
192
- "image":image,
193
- "detach":self.detach,
194
- "mounts":self.base_container.mounts,
195
- "environment": self.base_container.environment,
196
- "stream": True,
197
- "remove": True,
198
- "command": args
202
+ "image": image,
203
+ "detach": self.detach,
204
+ "mounts": self.base_container.mounts,
205
+ "environment": self.base_container.environment,
206
+ "stream": True,
207
+ "remove": True,
208
+ "command": args
199
209
  }
200
210
 
201
211
  run_arguments.update(self.base_container.docker_type.get_argumets())
@@ -206,13 +216,15 @@ class PyntContainer():
206
216
 
207
217
  PyntContainerRegistery.instance().register_container(self)
208
218
 
219
+
209
220
  class PyntDockerDesktopContainer():
210
221
  def __init__(self, ports) -> None:
211
222
  self.ports = ports
212
-
223
+
213
224
  def get_argumets(self):
214
225
  return {"ports": self.ports} if self.ports else {}
215
-
226
+
227
+
216
228
  class PyntNativeContainer():
217
229
  def __init__(self, network) -> None:
218
230
  self.network = network
@@ -230,13 +242,13 @@ class PyntContainerRegistery():
230
242
  @staticmethod
231
243
  def instance():
232
244
  if not PyntContainerRegistery._instance:
233
- PyntContainerRegistery._instance = PyntContainerRegistery()
245
+ PyntContainerRegistery._instance = PyntContainerRegistery()
234
246
 
235
247
  return PyntContainerRegistery._instance
236
248
 
237
249
  def register_container(self, c: PyntContainer):
238
- self.containers.append(c)
239
-
250
+ self.containers.append(c)
251
+
240
252
  def stop_all_containers(self):
241
- for c in self.containers:
253
+ for c in self.containers:
242
254
  c.stop()
pyntcli/store/store.py CHANGED
@@ -1,25 +1,25 @@
1
- from typing import Type
2
- import os
3
- import platform
1
+ from typing import Type
2
+ import os
4
3
 
5
4
  from .json_connector import JsonStoreConnector
6
5
  from .store_connector import StoreConnector
7
6
 
7
+
8
8
  class Store():
9
- def __init__(self, file_location: str, connector_type: Type[StoreConnector]) -> None :
9
+ def __init__(self, file_location: str, connector_type: Type[StoreConnector]) -> None:
10
10
  self.file_location = file_location
11
- self.connector:StoreConnector = None
11
+ self.connector: StoreConnector = None
12
12
  self._file = None
13
13
  self._connector_tpye = connector_type
14
-
14
+
15
15
  def _get_file_data(self):
16
- if self.connector:
17
- return
16
+ if self.connector:
17
+ return
18
18
 
19
19
  dirname = os.path.dirname(self.file_location)
20
20
  if not os.path.exists(dirname):
21
21
  os.makedirs(dirname)
22
-
22
+
23
23
  if not os.path.exists(self.file_location):
24
24
  with open(self.file_location, "w") as f:
25
25
  self.connector = self._connector_tpye(self._connector_tpye.default_value())
@@ -35,24 +35,29 @@ class Store():
35
35
  def put(self, key, value):
36
36
  self._get_file_data()
37
37
  self.connector.put(key, value)
38
-
38
+
39
39
  def get_path(self):
40
40
  return self.file_location
41
41
 
42
42
  def __enter__(self):
43
43
  self._get_file_data()
44
- return self
44
+ return self
45
45
 
46
- def __exit__(self, type, value, traceback):
46
+ def __exit__(self, type, value, traceback):
47
47
  with open(self.file_location, "w") as f:
48
48
  f.write(self.connector.dump())
49
49
 
50
+
50
51
  class CredStore(Store):
51
52
  def __init__(self) -> None:
52
53
  dir = ".pynt"
53
54
  super().__init__(file_location=os.path.join(os.path.expanduser("~"), dir, "creds.json"),
54
55
  connector_type=JsonStoreConnector)
55
-
56
+
56
57
  def get_access_token(self):
57
58
  return self.get("token")["access_token"]
58
-
59
+
60
+ def get_tokens(self):
61
+ all_tokens = self.get("token")
62
+ token_to_json_string = '{"token":'+str(all_tokens).replace("\'", "\"")+"}"
63
+ return token_to_json_string
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyntcli
3
- Version: 0.1.73
3
+ Version: 0.1.74
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