From 3af7d04a9a5e74cc43c4d62852747a33037a2ff6 Mon Sep 17 00:00:00 2001 From: PCoder Date: Tue, 13 Aug 2019 12:00:19 +0530 Subject: [PATCH 1/9] #6430: add customers-list feature --- ungleich | 2 ++ ungleich_pay.py | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 ungleich_pay.py diff --git a/ungleich b/ungleich index dc99669..5433491 100755 --- a/ungleich +++ b/ungleich @@ -8,6 +8,7 @@ from ungleich_account import Account_Create from ungleich_weather import ungleichWeather from ungleich_ssh_key import SSHKey from ungleich_config import Ungleich_Config +from ungleich_pay import ungleichPay VERSION = "0.0.4" @@ -22,6 +23,7 @@ class ungleichCLI(object): config = Ungleich_Config(self.parser, self.parser_parents) SSHKey(self.parser, self.parser_parents) ungleichWeather(self.parser, self.parser_parents) + ungleichPay(self.parser, self.parser_parents) def _init_parser(self): self.parser = {} diff --git a/ungleich_pay.py b/ungleich_pay.py new file mode 100644 index 0000000..623880e --- /dev/null +++ b/ungleich_pay.py @@ -0,0 +1,36 @@ +import urllib.request +import json + +UNGLEICH_PAY_SERVER_URL = "https://pay.ungleich.ch" + + +class ungleichPay(object): + def __init__(self, parser, parents): + self.parser = parser + + self.parser['customers-list'] = self.parser['sub'].add_parser( + 'customers-list', + help="List customers who have an active VM at ungleich", + parents=[parents]) + self.parser['username'].add_argument('--username', required=True) + self.parser['realm'].add_argument('--realm', required=True) + self.parser['token'].add_argument( + '--token', required=True, + help="A valid token obtained from ungleich" + ) + self.parser['customers-list'].set_defaults(func=self.customers_list) + + def customers_list(self, args): + customers_list_endpoint = "/customers-list" + request_url = UNGLEICH_PAY_SERVER_URL + customers_list_endpoint + req = urllib.request.Request(url=request_url, + method='GET', + headers={ + "username": args.username, + "realm": args.realm, + "token": args.token, + "Accept": "application/json" + }) + response = urllib.request.urlopen(req) + response_json = json.loads(response.read().decode('utf-8')) + print(response_json.data) From 66a27d435f2bb8aea97ea2875bf6ded190f267c3 Mon Sep 17 00:00:00 2001 From: PCoder Date: Tue, 13 Aug 2019 13:03:59 +0530 Subject: [PATCH 2/9] Allow ungleich_pay_server parameter to be passed by the user --- ungleich_pay.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ungleich_pay.py b/ungleich_pay.py index 623880e..64ee68c 100644 --- a/ungleich_pay.py +++ b/ungleich_pay.py @@ -18,11 +18,18 @@ class ungleichPay(object): '--token', required=True, help="A valid token obtained from ungleich" ) + self.parser['ungleich_pay_server'].add_argument( + '--ungleich-pay-server', required=False, + help="A valid ungleich pay server url" + ) self.parser['customers-list'].set_defaults(func=self.customers_list) def customers_list(self, args): customers_list_endpoint = "/customers-list" - request_url = UNGLEICH_PAY_SERVER_URL + customers_list_endpoint + if args.ungleich_pay_server: + request_url = args.ungleich_pay_server + customers_list_endpoint + else: + request_url = UNGLEICH_PAY_SERVER_URL + customers_list_endpoint req = urllib.request.Request(url=request_url, method='GET', headers={ From 5b3bb106779820f1af29250b71317701463cabff Mon Sep 17 00:00:00 2001 From: PCoder Date: Tue, 13 Aug 2019 13:26:55 +0530 Subject: [PATCH 3/9] Fix arguments for issue and fix missing endpoint trailing slash --- ungleich_pay.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ungleich_pay.py b/ungleich_pay.py index 64ee68c..d800433 100644 --- a/ungleich_pay.py +++ b/ungleich_pay.py @@ -12,20 +12,20 @@ class ungleichPay(object): 'customers-list', help="List customers who have an active VM at ungleich", parents=[parents]) - self.parser['username'].add_argument('--username', required=True) - self.parser['realm'].add_argument('--realm', required=True) - self.parser['token'].add_argument( + self.parser['customers-list'].add_argument('--username', required=True) + self.parser['customers-list'].add_argument('--realm', required=True) + self.parser['customers-list'].add_argument( '--token', required=True, help="A valid token obtained from ungleich" ) - self.parser['ungleich_pay_server'].add_argument( + self.parser['customers-list'].add_argument( '--ungleich-pay-server', required=False, help="A valid ungleich pay server url" ) self.parser['customers-list'].set_defaults(func=self.customers_list) def customers_list(self, args): - customers_list_endpoint = "/customers-list" + customers_list_endpoint = "/customers-list/" if args.ungleich_pay_server: request_url = args.ungleich_pay_server + customers_list_endpoint else: From 1b8c8793f0a5785cffb5fc355e868aec37a45955 Mon Sep 17 00:00:00 2001 From: PCoder Date: Tue, 13 Aug 2019 14:47:32 +0530 Subject: [PATCH 4/9] Update .gitignore: ignroe .idea folder --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c18dd8d..2483976 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ +.idea/ __pycache__/ From 3e6d535a74654e7842d1189792e4c96395d1b99c Mon Sep 17 00:00:00 2001 From: PCoder Date: Tue, 13 Aug 2019 14:48:50 +0530 Subject: [PATCH 5/9] Replace token with seed and obtain token from seed + fix bug Bug = getting data from dict --- ungleich_pay.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/ungleich_pay.py b/ungleich_pay.py index d800433..b5fb711 100644 --- a/ungleich_pay.py +++ b/ungleich_pay.py @@ -1,5 +1,6 @@ import urllib.request import json +from pyotp import TOTP UNGLEICH_PAY_SERVER_URL = "https://pay.ungleich.ch" @@ -15,8 +16,12 @@ class ungleichPay(object): self.parser['customers-list'].add_argument('--username', required=True) self.parser['customers-list'].add_argument('--realm', required=True) self.parser['customers-list'].add_argument( - '--token', required=True, - help="A valid token obtained from ungleich" + '--seed', required=True, + help="A valid seed obtained from ungleich" + ) + self.parser['customers-list'].add_argument( + '--email', required=True, + help="Email associated with the username" ) self.parser['customers-list'].add_argument( '--ungleich-pay-server', required=False, @@ -30,14 +35,16 @@ class ungleichPay(object): request_url = args.ungleich_pay_server + customers_list_endpoint else: request_url = UNGLEICH_PAY_SERVER_URL + customers_list_endpoint + print(f"request_url={request_url}") req = urllib.request.Request(url=request_url, method='GET', headers={ + "email": args.email, "username": args.username, "realm": args.realm, - "token": args.token, + "token": TOTP(args.seed).now(), "Accept": "application/json" }) response = urllib.request.urlopen(req) response_json = json.loads(response.read().decode('utf-8')) - print(response_json.data) + print(response_json["data"]) From c3c9ba4a72dd3a7560791692b7918c7148409919 Mon Sep 17 00:00:00 2001 From: PCoder Date: Tue, 13 Aug 2019 14:59:12 +0530 Subject: [PATCH 6/9] Show error message elegantly --- ungleich_pay.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ungleich_pay.py b/ungleich_pay.py index b5fb711..bfdcc6b 100644 --- a/ungleich_pay.py +++ b/ungleich_pay.py @@ -1,5 +1,6 @@ import urllib.request import json +import sys from pyotp import TOTP UNGLEICH_PAY_SERVER_URL = "https://pay.ungleich.ch" @@ -45,6 +46,13 @@ class ungleichPay(object): "token": TOTP(args.seed).now(), "Accept": "application/json" }) - response = urllib.request.urlopen(req) + try: + response = urllib.request.urlopen(req) + except urllib.error.HTTPError as err: + print(str(err)) + sys.exit(1) + except urllib.error.URLError as uerr: + print(str(uerr)) + sys.exit(2) response_json = json.loads(response.read().decode('utf-8')) print(response_json["data"]) From 0b838b0172ed7777185d6148cfb47bd44ccecd96 Mon Sep 17 00:00:00 2001 From: PCoder Date: Tue, 20 Aug 2019 11:50:27 +0530 Subject: [PATCH 7/9] #6430: display response nicely in tabular format --- ungleich_pay.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ungleich_pay.py b/ungleich_pay.py index bfdcc6b..c236396 100644 --- a/ungleich_pay.py +++ b/ungleich_pay.py @@ -2,6 +2,7 @@ import urllib.request import json import sys from pyotp import TOTP +from tabulate import tabulate UNGLEICH_PAY_SERVER_URL = "https://pay.ungleich.ch" @@ -55,4 +56,11 @@ class ungleichPay(object): print(str(uerr)) sys.exit(2) response_json = json.loads(response.read().decode('utf-8')) - print(response_json["data"]) + if (response_json['response'] == 'success'): + data = response_json["data"] + rows = [(x['email'], x['vm_count']) for x in data] + headers = ["email", "vm_count"] + print(tabulate(rows, headers)) + else: + print("An error occurred.") + print(response_json["message"]) From fc9dbe9e57c6137da1763b854670a5bafb41df0b Mon Sep 17 00:00:00 2001 From: PCoder Date: Tue, 20 Aug 2019 13:52:12 +0530 Subject: [PATCH 8/9] Fix multiple packages error + add tabulate Traceback (most recent call last): File "/usr/lib/python3.7/site-packages/pipenv/project.py", line 527, in _parse_pipfile return tomlkit.parse(contents) File "/usr/lib/python3.7/site-packages/pipenv/vendor/tomlkit/api.py", line 49, in parse return Parser(string).parse() File "/usr/lib/python3.7/site-packages/pipenv/vendor/tomlkit/parser.py", line 152, in parse body.append(key, value) File "/usr/lib/python3.7/site-packages/pipenv/vendor/tomlkit/container.py", line 129, in append raise KeyAlreadyPresent(key) tomlkit.exceptions.KeyAlreadyPresent: Key "packages" already exists. During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/usr/bin/pipenv", line 11, in load_entry_point('pipenv==2018.11.15.dev0', 'console_scripts', 'pipenv')() File "/usr/lib/python3.7/site-packages/pipenv/vendor/click/core.py", line 764, in __call__ return self.main(*args, **kwargs) File "/usr/lib/python3.7/site-packages/pipenv/vendor/click/core.py", line 717, in main rv = self.invoke(ctx) File "/usr/lib/python3.7/site-packages/pipenv/vendor/click/core.py", line 1137, in invoke return _process_result(sub_ctx.command.invoke(sub_ctx)) File "/usr/lib/python3.7/site-packages/pipenv/vendor/click/core.py", line 956, in invoke return ctx.invoke(self.callback, **ctx.params) File "/usr/lib/python3.7/site-packages/pipenv/vendor/click/core.py", line 555, in invoke return callback(*args, **kwargs) File "/usr/lib/python3.7/site-packages/pipenv/vendor/click/decorators.py", line 64, in new_func return ctx.invoke(f, obj, *args, **kwargs) File "/usr/lib/python3.7/site-packages/pipenv/vendor/click/core.py", line 555, in invoke return callback(*args, **kwargs) File "/usr/lib/python3.7/site-packages/pipenv/vendor/click/decorators.py", line 17, in new_func return f(get_current_context(), *args, **kwargs) File "/usr/lib/python3.7/site-packages/pipenv/cli/command.py", line 254, in install editable_packages=state.installstate.editables, File "/usr/lib/python3.7/site-packages/pipenv/core.py", line 1741, in do_install pypi_mirror=pypi_mirror, File "/usr/lib/python3.7/site-packages/pipenv/core.py", line 578, in ensure_project if project.required_python_version: File "/usr/lib/python3.7/site-packages/pipenv/project.py", line 243, in required_python_version required = self.parsed_pipfile.get("requires", {}).get( File "/usr/lib/python3.7/site-packages/pipenv/project.py", line 509, in parsed_pipfile parsed = self._parse_pipfile(contents) File "/usr/lib/python3.7/site-packages/pipenv/project.py", line 531, in _parse_pipfile return toml.loads(contents) File "/usr/lib/python3.7/site-packages/pipenv/vendor/toml/decoder.py", line 425, in loads original, pos) toml.decoder.TomlDecodeError: What? packages already exists?{'source': [{'url': 'https://pypi.python.org/simple', 'verify_ssl': True, 'name': 'pypi'}], 'packages': {'requests': '*', 'pyotp': '*'}, 'dev-packages': {}, 'requires': {'python_version': '3.7'}} (line 15 column 1 char 173) --- Pipfile | 6 ++---- Pipfile.lock | 25 ++++++++++++++++++++----- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/Pipfile b/Pipfile index 4790553..1804491 100644 --- a/Pipfile +++ b/Pipfile @@ -6,12 +6,10 @@ name = "pypi" [packages] requests = "*" pyotp = "*" +apixu = {git = "https://github.com/apixu/apixu-python.git",ref = "master"} +tabulate = "*" [dev-packages] [requires] python_version = "3.7" - -[packages.apixu] -git = "https://github.com/apixu/apixu-python.git" -ref = "master" diff --git a/Pipfile.lock b/Pipfile.lock index 2ffc179..8543da1 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "ca9c2522bf07f03d1588afe76e9f6fc73bc1efec20d4f155d82b709efaf14a56" + "sha256": "b6d5bcc7b985514e125b8217b8d9f9467b2fc357f4760cd5e83bf0c115b37ea2" }, "pipfile-spec": 6, "requires": { @@ -18,14 +18,14 @@ "default": { "apixu": { "git": "https://github.com/apixu/apixu-python.git", - "ref": "master" + "ref": "370216999346d5caf7f8dc6724b5766dcc6da25d" }, "certifi": { "hashes": [ - "sha256:59b7658e26ca9c7339e00f8f4636cdfe59d34fa37b9b04f6f9e9926b3cece1a5", - "sha256:b26104d6835d1f5e49452a26eb2ff87fe7090b89dfcaee5ea2212697e1e1d7ae" + "sha256:046832c04d4e752f37383b628bc601a7ea7211496b4638f6514d0e5b9acc4939", + "sha256:945e3ba63a0b9f577b1395204e13c3a231f9bc0223888be653286534e5873695" ], - "version": "==2019.3.9" + "version": "==2019.6.16" }, "chardet": { "hashes": [ @@ -41,6 +41,14 @@ ], "version": "==2.8" }, + "pyotp": { + "hashes": [ + "sha256:c88f37fd47541a580b744b42136f387cdad481b560ef410c0d85c957eb2a2bc0", + "sha256:fc537e8acd985c5cbf51e11b7d53c42276fee017a73aec7c07380695671ca1a1" + ], + "index": "pypi", + "version": "==2.3.0" + }, "requests": { "hashes": [ "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", @@ -49,6 +57,13 @@ "index": "pypi", "version": "==2.22.0" }, + "tabulate": { + "hashes": [ + "sha256:8af07a39377cee1103a5c8b3330a421c2d99b9141e9cc5ddd2e3263fea416943" + ], + "index": "pypi", + "version": "==0.8.3" + }, "urllib3": { "hashes": [ "sha256:b246607a25ac80bedac05c6f282e3cdaf3afb65420fd024ac94435cabe6e18d1", From 7698db24ced17ad203248b4c4e729c1ce4873686 Mon Sep 17 00:00:00 2001 From: PCoder Date: Tue, 20 Aug 2019 15:12:36 +0530 Subject: [PATCH 9/9] Also print total vm count + make result clearer --- ungleich_pay.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ungleich_pay.py b/ungleich_pay.py index c236396..9705640 100644 --- a/ungleich_pay.py +++ b/ungleich_pay.py @@ -59,8 +59,14 @@ class ungleichPay(object): if (response_json['response'] == 'success'): data = response_json["data"] rows = [(x['email'], x['vm_count']) for x in data] - headers = ["email", "vm_count"] + headers = ["customer", "vm_count"] + print("---") print(tabulate(rows, headers)) + print("---") + vm_count = 0 + for x in data: + vm_count += x['vm_count'] + print("Total vm_count = {}".format(vm_count)) else: print("An error occurred.") print(response_json["message"])