From 1bdb5ab72cbe88462a7f4eac90c82335be9b5bc5 Mon Sep 17 00:00:00 2001 From: Hirotaka Wakabayashi Date: Thu, 26 Sep 2024 14:06:03 +0900 Subject: [PATCH] Release 1.0.2 --- HISTORY.rst | 10 + MANIFEST.in | 1 - Makefile | 5 +- docs/locale/ja/LC_MESSAGES/history.po | 24 +- docs/locale/ja/LC_MESSAGES/k2hr3client.po | 24 +- pyproject.toml | 12 +- src/k2hr3client/__init__.py | 2 +- src/k2hr3client/acr.py | 2 +- src/k2hr3client/api.py | 4 +- src/k2hr3client/examples/create_role.py | 299 ++++++++++++++++++ .../examples}/example_resource.txt | 0 src/k2hr3client/examples/get_registerpath.py | 189 +++++++++++ .../k2hr3client/examples}/identity_api.py | 37 ++- .../k2hr3client/examples}/registerpath.py | 12 +- .../k2hr3client/examples}/token_api.py | 24 +- src/k2hr3client/policy.py | 69 +++- src/k2hr3client/resource.py | 15 +- src/k2hr3client/role.py | 169 +++++++--- src/k2hr3client/tenant.py | 2 +- src/tests/test_policy.py | 22 +- src/tests/test_role.py | 46 +-- 21 files changed, 826 insertions(+), 142 deletions(-) create mode 100644 src/k2hr3client/examples/create_role.py rename {examples => src/k2hr3client/examples}/example_resource.txt (100%) create mode 100644 src/k2hr3client/examples/get_registerpath.py rename {examples => src/k2hr3client/examples}/identity_api.py (71%) rename {examples => src/k2hr3client/examples}/registerpath.py (95%) rename {examples => src/k2hr3client/examples}/token_api.py (76%) diff --git a/HISTORY.rst b/HISTORY.rst index 488319e..9d9cfc6 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -2,6 +2,16 @@ History ======= +1.0.2 (2024-09-26) +------------------- + +* Fixes lint errors + +1.0.1 (2024-09-25) +------------------- + +* Fixes resource API bugs + 1.0.0 (2024-08-28) ------------------- diff --git a/MANIFEST.in b/MANIFEST.in index b44b033..e59b177 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -5,7 +5,6 @@ include LICENSE include README.rst recursive-include k2hr3client * -recursive-include tests * recursive-exclude * __pycache__ recursive-exclude * *.py[co] diff --git a/Makefile b/Makefile index fc4de19..75fa85f 100644 --- a/Makefile +++ b/Makefile @@ -138,13 +138,12 @@ dist: clean version ## builds source and wheel package @echo 'source ' ${SOURCE_VERSION} @echo 'history ' ${HISTORY_VERSION} @if test "${SOURCE_VERSION}" = "${HISTORY_VERSION}" ; then \ - python3 setup.py sdist ; \ - python3 setup.py bdist_wheel ; \ + python3 -m build ; \ ls -l dist ; \ fi install: clean ## install the package to the active Python's site-packages - python3 setup.py install + python3 -m pip install . # # Local variables: diff --git a/docs/locale/ja/LC_MESSAGES/history.po b/docs/locale/ja/LC_MESSAGES/history.po index 22287a7..d8f666e 100644 --- a/docs/locale/ja/LC_MESSAGES/history.po +++ b/docs/locale/ja/LC_MESSAGES/history.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: k2hr3client \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-09-01 13:58+0900\n" +"POT-Creation-Date: 2024-09-26 10:42+0900\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: ja\n" @@ -26,18 +26,34 @@ msgid "History" msgstr "歴史" #: ../../../HISTORY.rst:6 -msgid "1.0.0 (2024-08-28)" +msgid "1.0.2 (2024-09-26)" msgstr "" #: ../../../HISTORY.rst:8 +msgid "Fixes lint errors" +msgstr "静的解析ツールのエラーを修正" + +#: ../../../HISTORY.rst:11 +msgid "1.0.1 (2024-09-25)" +msgstr "" + +#: ../../../HISTORY.rst:13 +msgid "Fixes resource API bugs" +msgstr "Resource APIの不具合を修正" + +#: ../../../HISTORY.rst:16 +msgid "1.0.0 (2024-08-28)" +msgstr "" + +#: ../../../HISTORY.rst:18 msgid "Supports the other APIs" msgstr "他のAPIをサポート" -#: ../../../HISTORY.rst:11 +#: ../../../HISTORY.rst:21 msgid "0.0.1 (2020-08-28)" msgstr "" -#: ../../../HISTORY.rst:13 +#: ../../../HISTORY.rst:23 msgid "Supports Token, Resource, Policy and Role API" msgstr "トークン、リソース、ポリシーおよびロールAPIをサポート" diff --git a/docs/locale/ja/LC_MESSAGES/k2hr3client.po b/docs/locale/ja/LC_MESSAGES/k2hr3client.po index 9374b20..8aadf57 100644 --- a/docs/locale/ja/LC_MESSAGES/k2hr3client.po +++ b/docs/locale/ja/LC_MESSAGES/k2hr3client.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: k2hr3client \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-09-01 13:58+0900\n" +"POT-Creation-Date: 2024-09-26 10:42+0900\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: ja\n" @@ -217,7 +217,8 @@ msgid "K2hr3Http sends a http/https request to the K2hr3 WebAPI." msgstr "K2HR3 WebAPIにHTTP/HTTPSリクエストを送信する" #: k2hr3client.http.K2hr3Http:3 of -msgid "Most oif the members are set by setter methods only one time." +#, fuzzy +msgid "Most of the members are set by setter methods only one time." msgstr "ほとんどのメンバーは一度だけセットされます" #: k2hr3client.http.K2hr3Http.DELETE:1 of @@ -654,3 +655,22 @@ msgstr "" msgid "Module contents" msgstr "" +#: k2hr3client.get_version:1 of +#, fuzzy +msgid "Return a version of the package." +msgstr "APIバージョン文字列を返す" + +#: ../../k2hr3client.rst +#, fuzzy +msgid "Returns" +msgstr "データを返す" + +#: k2hr3client.get_version:3 of +msgid "version" +msgstr "バージョン" + +#: ../../k2hr3client.rst +#, fuzzy +msgid "Return type" +msgstr "データを返す" + diff --git a/pyproject.toml b/pyproject.toml index 75f1f29..354d21a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = [ "setuptools>=61.0", "wheel" ] +requires = [ "setuptools" ] build-backend = "setuptools.build_meta" [project] @@ -37,6 +37,16 @@ Repository = "https://github.com/yahoojapan/k2hr3client_python.git" "Bug Tracker" = "https://github.com/yahoojapan/k2hr3client_python/issues" Changelog = "https://github.com/yahoojapan/k2hr3client_python/blob/master/HISTORY.rst" +[tool.setuptools] +include-package-data = true + +[tool.setuptools.package-data] +"*" = ["*.txt"] + +[tool.setuptools.packages.find] +exclude = ["tests*"] +where = ["src"] + [tool.tox] legacy_tox_ini = """ [tox] diff --git a/src/k2hr3client/__init__.py b/src/k2hr3client/__init__.py index d558221..ac401b5 100644 --- a/src/k2hr3client/__init__.py +++ b/src/k2hr3client/__init__.py @@ -22,7 +22,7 @@ """K2HR3 Python Client of Token API.""" __author__ = 'Hirotaka Wakabayashi ' -__version__ = '1.0.0' +__version__ = '1.0.2' import sys diff --git a/src/k2hr3client/acr.py b/src/k2hr3client/acr.py index d639c61..9ec0b50 100644 --- a/src/k2hr3client/acr.py +++ b/src/k2hr3client/acr.py @@ -115,7 +115,7 @@ def show_credential_details(self): self.api_id = 2 return self - def get_available_resources(self, + def get_available_resources(self, # pylint: disable=R0917 cip: Optional[str] = None, cport: Optional[str] = None, crole: Optional[str] = None, diff --git a/src/k2hr3client/api.py b/src/k2hr3client/api.py index 61aea88..385b264 100644 --- a/src/k2hr3client/api.py +++ b/src/k2hr3client/api.py @@ -155,9 +155,9 @@ class K2hr3Api(abc.ABC): # pylint: disable=too-many-instance-attributes DEFAULT_VERSION = "v1" - def __init__(self, basepath: str, params: Optional[str] = None, + def __init__(self, basepath: str, params: Optional[str] = None, # pylint: disable=R0917 # noqa hdrs: Optional[dict] = None, body: Optional[str] = None, - version: str = DEFAULT_VERSION) -> None: # noqa + version: str = DEFAULT_VERSION) -> None: # noqa """Init the K2hr3 API members. :raise K2hr3Exception: if the val is invalid. diff --git a/src/k2hr3client/examples/create_role.py b/src/k2hr3client/examples/create_role.py new file mode 100644 index 0000000..5a0a61e --- /dev/null +++ b/src/k2hr3client/examples/create_role.py @@ -0,0 +1,299 @@ +# -*- coding: utf-8 -*- +# +# K2HDKC DBaaS based on Trove +# +# Copyright 2020 Yahoo Japan Corporation +# Copyright 2024 LY Corporation +# +# K2HDKC DBaaS is a Database as a Service compatible with Trove which +# is DBaaS for OpenStack. +# Using K2HR3 as backend and incorporating it into Trove to provide +# DBaaS functionality. K2HDKC, K2HR3, CHMPX and K2HASH are components +# provided as AntPickax. +# +# For the full copyright and license information, please view +# the license file that was distributed with this source code. +# +# AUTHOR: Hirotaka Wakabayashi +# CREATE: Mon Sep 14 2020 +# REVISION: +# +# +"""K2HR3 Python Client of Resource API.""" + +from __future__ import (absolute_import, division, print_function, + unicode_literals) +import argparse +import json +import os +import sys +from pathlib import Path +import urllib.parse +import urllib.request + +here = os.path.dirname(__file__) +src_dir = os.path.join(here, '..') +if os.path.exists(src_dir): + sys.path.append(src_dir) + +import k2hr3client # type: ignore # pylint: disable=import-error, wrong-import-position # noqa +from k2hr3client.http import K2hr3Http # type: ignore # pylint: disable=import-error, wrong-import-position # noqa +from k2hr3client.token import K2hr3Token # type: ignore # pylint: disable=import-error, wrong-import-position # noqa +from k2hr3client.resource import K2hr3Resource # type: ignore # pylint: disable=import-error, wrong-import-position # noqa +from k2hr3client.policy import K2hr3Policy # type: ignore # pylint: disable=import-error, wrong-import-position # noqa +from k2hr3client.role import K2hr3Role # type: ignore # pylint: disable=import-error, wrong-import-position # noqa + +IDENTITY_V3_PASSWORD_AUTH_JSON_DATA = """ +{ + "auth": { + "identity": { + "methods": [ + "password" + ], + "password": { + "user": { + "name": "admin", + "domain": { + "name": "Default" + }, + "password": "devstacker" + } + } } + } +} +""" + +IDENTITY_V3_TOKEN_AUTH_JSON_DATA = """ +{ + "auth": { + "identity": { + "methods": [ + "token" + ], + "token": { + "id": "" + } + }, + "scope": { + "project": { + "domain": { + "id": "default" + }, + "name": "" + } + } + } +} +""" + + +def get_scoped_token_id(url, user, password, project): + """Get a scoped token id from openstack identity.""" + # unscoped token-id + # https://docs.openstack.org/api-ref/identity/v3/index.html#password-authentication-with-unscoped-authorization + python_data = json.loads(IDENTITY_V3_PASSWORD_AUTH_JSON_DATA) + python_data['auth']['identity']['password']['user']['name'] = user + python_data['auth']['identity']['password']['user']['password'] = password + headers = { + 'User-Agent': 'hiwkby-sample', + 'Content-Type': 'application/json' + } + req = urllib.request.Request(url, + json.dumps(python_data).encode('ascii'), + headers, + method="POST") + with urllib.request.urlopen(req) as res: + unscoped_token_id = dict(res.info()).get('X-Subject-Token') + print('unscoped_token_id:[{}]'.format(unscoped_token_id)) + + # scoped token-id + # https://docs.openstack.org/api-ref/identity/v3/index.html?expanded=#token-authentication-with-scoped-authorization + python_data = json.loads(IDENTITY_V3_TOKEN_AUTH_JSON_DATA) + python_data['auth']['identity']['token']['id'] = unscoped_token_id + python_data['auth']['scope']['project']['name'] = project + headers = { + 'User-Agent': 'hiwkby-sample', + 'Content-Type': 'application/json' + } + req = urllib.request.Request(url, + json.dumps(python_data).encode('ascii'), + headers, + method="POST") + with urllib.request.urlopen(req) as res: + scoped_token_id = dict(res.info()).get('X-Subject-Token') + print('scoped_token_id:[{}]'.format(scoped_token_id)) + return scoped_token_id + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='k2hr3 token api example') + parser.add_argument( + '--url', + dest='url', + default='http://127.0.0.1/identity/v3/auth/tokens', + help='identity api url. ex) http://127.0.0.1/identity/v3/auth/tokens') + parser.add_argument('--user', + dest='user', + default='demo', + help='openstack user') + parser.add_argument('--password', + dest='password', + default='password', + help='openstack user password') + parser.add_argument('--project', + dest='project', + default='demo', + help='openstack project') + parser.add_argument('--k2hr3_url', + dest='k2hr3_url', + default='http://localhost:18080', + help='k2hr3 api url') + parser.add_argument('--resource', + dest='resource', + default='k2hdkccluster', + help='resource name') + parser.add_argument('--policy', + dest='policy', + default='k2hdkccluster', + help='policy name') + parser.add_argument('--role', + dest='role', + default='k2hdkccluster', + help='k2hr3 rolename') + + args = parser.parse_args() + + # 1. Gets a openstack token id from openstack identity server + openstack_token = get_scoped_token_id(args.url, args.user, args.password, + args.project) + + # 2. Gets a k2hr3 token from the openstack token + k2hr3_token = K2hr3Token(args.project, openstack_token) + http = K2hr3Http(args.k2hr3_url) + http.POST(k2hr3_token.create()) + + # 3. Makes a new k2hr3 resource + k2hr3_resource = K2hr3Resource(k2hr3_token.token) + init_py = Path(k2hr3client.__file__) + txt_file = init_py.parent.joinpath('examples', + 'example_resource.txt') + http.POST( + k2hr3_resource.create_conf_resource( + name=args.resource, + data_type='string', + data=Path(txt_file), + tenant=args.project, + cluster_name=args.resource, + keys={ + "cluster-name": args.resource, + "chmpx-server-port": "8020", + "chmpx-server-ctlport": "8021", + "chmpx-slave-ctlport": "8031" + }, + alias=[] + ) + ) + + # debug + # print(k2hr3_resource.resp.body) + # sys.exit(0) + + # 3.1. Makes a new k2hr3 resource for server + k2hr3_resource_server = K2hr3Resource(k2hr3_token.token) + http.POST( + k2hr3_resource_server.create_conf_resource( + tenant=args.project, + cluster_name=args.resource, + name="/".join([args.resource, "server"]), + data_type='string', + data="", + keys={"chmpx-mode": "SERVER", + "k2hr3-init-packages": "", + "k2hr3-init-packagecloud-packages": "", + "k2hr3-init-systemd-packages": ""}, + alias=[] + ) + ) + + # 3.2. Makes a new k2hr3 resource for slave + k2hr3_resource_slave = K2hr3Resource(k2hr3_token.token) + http.POST( + k2hr3_resource_slave.create_conf_resource( + tenant=args.project, + cluster_name=args.resource, + name="/".join([args.resource, "slave"]), + data_type='string', + data="", + keys={"chmpx-mode": "SLAVE", + "k2hr3-init-packages": "", + "k2hr3-init-packagecloud-packages": "", + "k2hr3-init-systemd-packages": "", + "k2hdkc-dbaas-add-user": 1}, + alias=[] + ) + ) + + # debug + # print(k2hr3_resource_slave.resp.body) + # sys.exit(0) + + # 4. Makes a new k2hr3 policy for the resource + k2hr3_policy = K2hr3Policy(k2hr3_token.token) + SERVER_RESOURCE_PATH = "yrn:yahoo:::{}:resource:{}/server".format( + args.project, args.resource) + SLAVE_RESOURCE_PATH = "yrn:yahoo:::{}:resource:{}/slave".format( + args.project, args.resource) + http.POST( + k2hr3_policy.create( + name=args.policy, + effect='allow', + action=['yrn:yahoo::::action:read'], + resource=[SERVER_RESOURCE_PATH, SLAVE_RESOURCE_PATH], + condition=None, + alias=[] + ) + ) + + # debug + # print(k2hr3_policy.resp.body) + # sys.exit(0) + + # 5. Makes a new k2hr3 role for the policy + POLICY_PATH = "yrn:yahoo:::{}:policy:{}".format(args.project, args.policy) + k2hr3_role = K2hr3Role(k2hr3_token.token) + http.POST( + k2hr3_role.create( + name=args.role, + policies=[POLICY_PATH], + alias=[] + ) + ) + server_role = K2hr3Role(k2hr3_token.token) + http.POST( + server_role.create( + name="/".join([args.role, "server"]), + policies=[], + alias=[] + ) + ) + slave_role = K2hr3Role(k2hr3_token.token) + http.POST( + slave_role.create( + name="/".join([args.role, "slave"]), + policies=[], + alias=[] + ) + ) + + # debug + # print(slave_role.resp.body) + # sys.exit(0) + +# +# Local variables: +# tab-width: 4 +# c-basic-offset: 4 +# End: +# vim600: expandtab sw=4 ts=4 fdm=marker +# vim<600: expandtab sw=4 ts=4 +# diff --git a/examples/example_resource.txt b/src/k2hr3client/examples/example_resource.txt similarity index 100% rename from examples/example_resource.txt rename to src/k2hr3client/examples/example_resource.txt diff --git a/src/k2hr3client/examples/get_registerpath.py b/src/k2hr3client/examples/get_registerpath.py new file mode 100644 index 0000000..0b1e9de --- /dev/null +++ b/src/k2hr3client/examples/get_registerpath.py @@ -0,0 +1,189 @@ +# -*- coding: utf-8 -*- +# +# K2HDKC DBaaS based on Trove +# +# Copyright 2020 Yahoo Japan Corporation +# Copyright 2024 LY Corporation +# +# K2HDKC DBaaS is a Database as a Service compatible with Trove which +# is DBaaS for OpenStack. +# Using K2HR3 as backend and incorporating it into Trove to provide +# DBaaS functionality. K2HDKC, K2HR3, CHMPX and K2HASH are components +# provided as AntPickax. +# +# For the full copyright and license information, please view +# the license file that was distributed with this source code. +# +# AUTHOR: Hirotaka Wakabayashi +# CREATE: Mon Sep 14 2020 +# REVISION: +# +# +"""K2HR3 Python Client of Token API.""" + +from __future__ import (absolute_import, division, print_function, + unicode_literals) +import argparse +import os +import sys +import json +import urllib.parse +import urllib.request + +here = os.path.dirname(__file__) +src_dir = os.path.join(here, '..') +if os.path.exists(src_dir): + sys.path.append(src_dir) + +from k2hr3client.http import K2hr3Http # type: ignore # pylint: disable=import-error, wrong-import-position # noqa +from k2hr3client.token import K2hr3Token # type: ignore # pylint: disable=import-error, wrong-import-position # noqa +from k2hr3client.token import K2hr3RoleToken # pylint: disable=import-error, wrong-import-position # noqa +from k2hr3client.token import K2hr3RoleTokenList # pylint: disable=import-error, wrong-import-position # noqa + +IDENTITY_V3_PASSWORD_AUTH_JSON_DATA = """ +{ + "auth": { + "identity": { + "methods": [ + "password" + ], + "password": { + "user": { + "name": "admin", + "domain": { + "name": "Default" + }, + "password": "devstacker" + } + } } + } +} +""" + +IDENTITY_V3_TOKEN_AUTH_JSON_DATA = """ +{ + "auth": { + "identity": { + "methods": [ + "token" + ], + "token": { + "id": "" + } + }, + "scope": { + "project": { + "domain": { + "id": "default" + }, + "name": "" + } + } + } +} +""" + + +def get_scoped_token_id(url, user, password, project): + """Get a scoped token id from openstack identity.""" + # unscoped token-id + # https://docs.openstack.org/api-ref/identity/v3/index.html#password-authentication-with-unscoped-authorization + python_data = json.loads(IDENTITY_V3_PASSWORD_AUTH_JSON_DATA) + python_data['auth']['identity']['password']['user']['name'] = user + python_data['auth']['identity']['password']['user']['password'] = password + headers = { + 'User-Agent': 'hiwkby-sample', + 'Content-Type': 'application/json' + } + req = urllib.request.Request(url, + json.dumps(python_data).encode('ascii'), + headers, + method="POST") + with urllib.request.urlopen(req) as res: + unscoped_token_id = dict(res.info()).get('X-Subject-Token') + # print('unscoped_token_id:[{}]'.format(unscoped_token_id)) + + # scoped token-id + # https://docs.openstack.org/api-ref/identity/v3/index.html?expanded=#token-authentication-with-scoped-authorization + python_data = json.loads(IDENTITY_V3_TOKEN_AUTH_JSON_DATA) + python_data['auth']['identity']['token']['id'] = unscoped_token_id + python_data['auth']['scope']['project']['name'] = project + headers = { + 'User-Agent': 'hiwkby-sample', + 'Content-Type': 'application/json' + } + req = urllib.request.Request(url, + json.dumps(python_data).encode('ascii'), + headers, + method="POST") + with urllib.request.urlopen(req) as res: + scoped_token_id = dict(res.info()).get('X-Subject-Token') + # print('scoped_token_id:[{}]'.format(scoped_token_id)) + return scoped_token_id + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='k2hr3 token api example') + parser.add_argument( + '--url', + dest='url', + default='http://127.0.0.1/identity/v3/auth/tokens', + help='identity api url. ex) http://127.0.0.1/identity/v3/auth/tokens') + parser.add_argument('--user', + dest='user', + default='demo', + help='openstack user') + parser.add_argument('--password', + dest='password', + default='password', + help='openstack user password') + parser.add_argument('--project', + dest='project', + default='demo', + help='openstack project') + parser.add_argument('--k2hr3_url', + dest='k2hr3_url', + default='http://localhost:18080', + help='k2hr3 api url') + parser.add_argument('--role', + dest='role', + default='k2hdkccluster', + help='k2hr3 rolename') + args = parser.parse_args() + + # 1. Gets a openstack token id from openstack identity server + openstack_token = get_scoped_token_id(args.url, args.user, args.password, + args.project) + + # 2. Gets a k2hr3 token from the openstack token + k2hr3_token = K2hr3Token(args.project, openstack_token) + http = K2hr3Http(args.k2hr3_url) + http.POST(k2hr3_token.create()) + + # 3. Gets a k2hr3 role token from the k2hr3 token + k2hr3_role_token = K2hr3RoleToken(k2hr3_token.token, + role=args.role, + expire=0) + http.GET(k2hr3_role_token) + roletoken = k2hr3_role_token.token + print("roletoken {}".format(roletoken)) + + # 4. Gets a k2hr3 role token list from the k2hr3 token + k2hr3_role_token_list = K2hr3RoleTokenList(k2hr3_token.token, + role=args.role, + expand=True) + http.GET(k2hr3_role_token_list) + + # 4. Gets the registerpath of the k2hr3 role token + registerpath = k2hr3_role_token_list.registerpath(roletoken) + print("{}".format(registerpath)) + sys.exit(0) + +# +# Local variables: +# tab-width: 4 +# c-basic-offset: 4 +# End: +# vim600: expandtab sw=4 ts=4 fdm=marker +# vim<600: expandtab sw=4 ts=4 +# diff --git a/examples/identity_api.py b/src/k2hr3client/examples/identity_api.py similarity index 71% rename from examples/identity_api.py rename to src/k2hr3client/examples/identity_api.py index a089fe7..c4c819b 100644 --- a/examples/identity_api.py +++ b/src/k2hr3client/examples/identity_api.py @@ -10,7 +10,7 @@ # Using K2HR3 as backend and incorporating it into Trove to provide # DBaaS functionality. K2HDKC, K2HR3, CHMPX and K2HASH are components # provided as AntPickax. -# +# # For the full copyright and license information, please view # the license file that was distributed with this source code. # @@ -80,22 +80,28 @@ if __name__ == '__main__': parser = argparse.ArgumentParser(description='k2hr3 token api example') - parser.add_argument('--url', dest='url', default='http://127.0.0.1/identity/v3/auth/tokens', - help='identity api url. ex) http://127.0.0.1/identity/v3/auth/tokens') - parser.add_argument('--user', dest='user', default='demo', help='openstack user') + parser.add_argument('--url', dest='url', + default='http://127.0.0.1/identity/v3/auth/tokens', + help='ex) http://127.0.0.1/identity/v3/auth/tokens') + parser.add_argument('--user', dest='user', + default='demo', help='openstack user') parser.add_argument('--password', dest='password', default='password', help='openstack user password') - parser.add_argument('--project', dest='project', default='demo', help='openstack project') + parser.add_argument('--project', + dest='project', + default='demo', + help='openstack project') args = parser.parse_args() # unscoped token-id # https://docs.openstack.org/api-ref/identity/v3/index.html#password-authentication-with-unscoped-authorization url = args.url - python_data = json.loads(IDENTITY_V3_PASSWORD_AUTH_JSON_DATA) - python_data['auth']['identity']['password']['user']['name'] = args.user - python_data['auth']['identity']['password']['user']['password'] = args.password - headers = {'User-Agent': 'hiwkby-sample', 'Content-Type': 'application/json'} - req = urllib.request.Request(url, json.dumps(python_data).encode('ascii'), + pydata = json.loads(IDENTITY_V3_PASSWORD_AUTH_JSON_DATA) + pydata['auth']['identity']['password']['user']['name'] = args.user + pydata['auth']['identity']['password']['user']['password'] = args.password + headers = {'User-Agent': 'hiwkby-sample', + 'Content-Type': 'application/json'} + req = urllib.request.Request(url, json.dumps(pydata).encode('ascii'), headers, method="POST") with urllib.request.urlopen(req) as res: unscoped_token_id = dict(res.info()).get('X-Subject-Token') @@ -104,11 +110,12 @@ # scoped token-id # https://docs.openstack.org/api-ref/identity/v3/index.html?expanded=#token-authentication-with-scoped-authorization my_project_name = args.project - python_data = json.loads(IDENTITY_V3_TOKEN_AUTH_JSON_DATA) - python_data['auth']['identity']['token']['id'] = unscoped_token_id - python_data['auth']['scope']['project']['name'] = my_project_name - headers = {'User-Agent': 'hiwkby-sample', 'Content-Type': 'application/json'} - req = urllib.request.Request(url, json.dumps(python_data).encode('ascii'), + pydata = json.loads(IDENTITY_V3_TOKEN_AUTH_JSON_DATA) + pydata['auth']['identity']['token']['id'] = unscoped_token_id + pydata['auth']['scope']['project']['name'] = my_project_name + headers = {'User-Agent': 'hiwkby-sample', + 'Content-Type': 'application/json'} + req = urllib.request.Request(url, json.dumps(pydata).encode('ascii'), headers, method="POST") with urllib.request.urlopen(req) as res: scoped_token_id = dict(res.info()).get('X-Subject-Token') diff --git a/examples/registerpath.py b/src/k2hr3client/examples/registerpath.py similarity index 95% rename from examples/registerpath.py rename to src/k2hr3client/examples/registerpath.py index ad44566..63926a4 100644 --- a/examples/registerpath.py +++ b/src/k2hr3client/examples/registerpath.py @@ -35,10 +35,10 @@ if os.path.exists(src_dir): sys.path.append(src_dir) -from k2hr3client.http import K2hr3Http # type: ignore # pylint: disable=import-error, wrong-import-position -from k2hr3client.token import K2hr3Token # type: ignore # pylint: disable=import-error, wrong-import-position -from k2hr3client.token import K2hr3RoleToken # pylint: disable=import-error, wrong-import-position -from k2hr3client.token import K2hr3RoleTokenList # pylint: disable=import-error, wrong-import-position +from k2hr3client.http import K2hr3Http # type: ignore # pylint: disable=import-error, wrong-import-position # noqa +from k2hr3client.token import K2hr3Token # type: ignore # pylint: disable=import-error, wrong-import-position # noqa +from k2hr3client.token import K2hr3RoleToken # pylint: disable=import-error, wrong-import-position # noqa +from k2hr3client.token import K2hr3RoleTokenList # pylint: disable=import-error, wrong-import-position # noqa IDENTITY_V3_PASSWORD_AUTH_JSON_DATA = """ { @@ -85,7 +85,7 @@ def get_scoped_token_id(url, user, password, project): - """ get a scoped token id from openstack identity. """ + """Get a scoped token id from openstack identity.""" # unscoped token-id # https://docs.openstack.org/api-ref/identity/v3/index.html#password-authentication-with-unscoped-authorization python_data = json.loads(IDENTITY_V3_PASSWORD_AUTH_JSON_DATA) @@ -174,7 +174,7 @@ def get_scoped_token_id(url, user, password, project): expand=True) http.GET(k2hr3_role_token_list) - # 4. Gets the registerpath of the k2hr3 role token using the k2hr3 role token + # 4. Gets the registerpath of the k2hr3 role token registerpath = k2hr3_role_token_list.registerpath(roletoken) print("{}".format(registerpath)) sys.exit(0) diff --git a/examples/token_api.py b/src/k2hr3client/examples/token_api.py similarity index 76% rename from examples/token_api.py rename to src/k2hr3client/examples/token_api.py index e0f8fa7..84c38d6 100644 --- a/examples/token_api.py +++ b/src/k2hr3client/examples/token_api.py @@ -32,17 +32,25 @@ if os.path.exists(src_dir): sys.path.append(src_dir) -from k2hr3client.http import K2hr3Http # type: ignore # pylint: disable=import-error, wrong-import-position -from k2hr3client.token import K2hr3Token # type: ignore # pylint: disable=import-error, wrong-import-position -from k2hr3client.token import K2hr3RoleToken # pylint: disable=import-error, wrong-import-position -from k2hr3client.token import K2hr3RoleTokenList # pylint: disable=import-error, wrong-import-position +from k2hr3client.http import K2hr3Http # type: ignore # pylint: disable=import-error, wrong-import-position # noqa +from k2hr3client.token import K2hr3Token # type: ignore # pylint: disable=import-error, wrong-import-position # noqa +from k2hr3client.token import K2hr3RoleToken # pylint: disable=import-error, wrong-import-position # noqa +from k2hr3client.token import K2hr3RoleTokenList # pylint: disable=import-error, wrong-import-position # noqa if __name__ == '__main__': parser = argparse.ArgumentParser(description='k2hr3 token api example') - parser.add_argument('--url', dest='url', default='http://localhost:18080/v1', + parser.add_argument('--url', + dest='url', + default='http://localhost:18080/v1', help='k2hr3 api url') - parser.add_argument('--project', dest='project', default='demo', help='openstack project') - parser.add_argument('--token', dest='token', default='foobar', help='openstack token') + parser.add_argument('--project', + dest='project', + default='demo', + help='openstack project') + parser.add_argument('--token', + dest='token', + default='foobar', + help='openstack token') args = parser.parse_args() # 1. Gets a k2hr3 token from the openstack token @@ -68,7 +76,7 @@ ) http.GET(k2hr3_role_token_list) - # 4. Gets the registerpath of the k2hr3 role token using the k2hr3 role token + # 4. Gets the registerpath of the k2hr3 role token registerpath = k2hr3_role_token_list.registerpath(roletoken) print("registerpath {}".format(registerpath)) sys.exit(0) diff --git a/src/k2hr3client/policy.py b/src/k2hr3client/policy.py index e06dd55..0bd88e5 100644 --- a/src/k2hr3client/policy.py +++ b/src/k2hr3client/policy.py @@ -42,7 +42,7 @@ RESOURCE_PATH = "yrn:yahoo:::demo:resource:test_resource" myhttp.POST( mypolicy.create( - policy_name="test_policy", + name="test_policy", effect="allow", action=['yrn:yahoo::::action:read'], resource=[RESOURCE_PATH], @@ -57,6 +57,7 @@ import json import logging from typing import List, Optional +import warnings from k2hr3client.api import K2hr3Api, K2hr3HTTPMethod @@ -103,7 +104,7 @@ def __init__(self, r3token: str) -> None: self.body = None self.urlparams = None # attributes that are unique to this class - self.policy_name = None + self.name = None self.effect = None self.action = None self.resource = None @@ -115,53 +116,87 @@ def __init__(self, r3token: str) -> None: # ---- POST/PUT ---- # POST http(s)://API SERVER:PORT/v1/policy # PUT http(s)://API SERVER:PORT/v1/policy?urlarg - def create(self, policy_name: str, effect: str, + def create(self, name: str, effect: str, # pylint: disable=R0917 action: Optional[List[str]], resource: Optional[List[str]] = None, condition: Optional[str] = None, - alias: Optional[List[str]] = None): + alias: Optional[List[str]] = None, + policy_name: Optional[str] = None): """Create policies.""" self.api_id = 1 # must to process a request further - self.policy_name = policy_name # type: ignore + self.name = name # type: ignore self.effect = effect # type: ignore self.action = action # type: ignore # optionals self.resource = resource # type: ignore self.condition = condition # type: ignore self.alias = alias # type: ignore + if name is None and policy_name is not None: + warnings.warn( + "The 'policy_name' parameter to 'create' " + "is deprecated and slated for removal in " + "k2hr3client-1.1.0", + DeprecationWarning, + stacklevel=1) + self.name = policy_name return self # ---- GET ---- # GET http(s)://API SERVER:PORT/v1/policy/\ # policy path or yrn full policy path{?service=service name} # noqa - def get(self, policy_name: str, service: str): + def get(self, name: str, service: str, policy_name: Optional[str] = None): """Get policies.""" self.api_id = 3 - self.policy_name = policy_name # type: ignore + self.name = name # type: ignore self.service = service # type: ignore + if name is None and policy_name is not None: + warnings.warn( + "The 'policy_name' parameter to 'create' " + "is deprecated and slated for removal in " + "k2hr3client-1.1.0", + DeprecationWarning, + stacklevel=1) + self.name = policy_name return self # ---- HEAD ---- # HEAD http(s)://API SERVER:PORT/v1/policy/yrn full policy path?urlarg - def validate(self, policy_name: str, tenant: str, resource: str, - action: str, service: Optional[str] = None): + def validate(self, name: str, tenant: str, resource: str, # pylint: disable=R0917 # noqa + action: str, service: Optional[str] = None, + policy_name: Optional[str] = None): """Validate policies.""" self.api_id = 4 - self.policy_name = policy_name # type: ignore + self.name = name # type: ignore self.tenant = tenant # type: ignore self.resource = resource # type: ignore self.action = action # type: ignore # optionals self.service = service # type: ignore + if name is None and policy_name is not None: + warnings.warn( + "The 'policy_name' parameter to 'create' " + "is deprecated and slated for removal in " + "k2hr3client-1.1.0", + DeprecationWarning, + stacklevel=1) + self.name = policy_name return self # ---- DELETE ---- # DELETE http(s)://API SERVER:PORT/v1/policy/policy path or yrn full policy path # noqa - def delete(self, policy_name: str): + def delete(self, name: str, policy_name: Optional[str] = None): """Delete policies.""" self.api_id = 5 - self.policy_name = policy_name # type: ignore + self.name = name # type: ignore + if name is None and policy_name is not None: + warnings.warn( + "The 'policy_name' parameter to 'create' " + "is deprecated and slated for removal in " + "k2hr3client-1.1.0", + DeprecationWarning, + stacklevel=1) + self.name = policy_name return self def __repr__(self) -> str: @@ -196,7 +231,7 @@ def _api_path(self, method: K2hr3HTTPMethod) -> Optional[str]: if method == K2hr3HTTPMethod.POST: if self.api_id == 1: python_data = json.loads(_POLICY_API_CREATE_POLICY) - python_data['policy']['name'] = self.policy_name + python_data['policy']['name'] = self.name python_data['policy']['effect'] = self.effect python_data['policy']['action'] = self.action python_data['policy']['resource'] = self.resource @@ -206,7 +241,7 @@ def _api_path(self, method: K2hr3HTTPMethod) -> Optional[str]: if method == K2hr3HTTPMethod.PUT: if self.api_id == 1: self.urlparams = json.dumps({ - 'name': self.policy_name, + 'name': self.name, 'effect': self.effect, 'action': self.action, 'resource': self.resource, @@ -218,7 +253,7 @@ def _api_path(self, method: K2hr3HTTPMethod) -> Optional[str]: self.urlparams = json.dumps({ 'service': self.service }) - return f'{self.version}/{self.basepath}/{self.policy_name}' + return f'{self.version}/{self.basepath}/{self.name}' if method == K2hr3HTTPMethod.HEAD: if self.api_id == 4: self.urlparams = json.dumps({ @@ -227,10 +262,10 @@ def _api_path(self, method: K2hr3HTTPMethod) -> Optional[str]: 'action': self.action, 'service': self.service }) - return f'{self.version}/{self.basepath}/{self.policy_name}' + return f'{self.version}/{self.basepath}/{self.name}' if method == K2hr3HTTPMethod.DELETE: if self.api_id == 5: - return f'{self.version}/{self.basepath}/{self.policy_name}' + return f'{self.version}/{self.basepath}/{self.name}' return None # diff --git a/src/k2hr3client/resource.py b/src/k2hr3client/resource.py index 9d020e2..a2d97bb 100644 --- a/src/k2hr3client/resource.py +++ b/src/k2hr3client/resource.py @@ -64,6 +64,7 @@ from typing import Optional, Any +import k2hr3client from k2hr3client.api import K2hr3Api, K2hr3HTTPMethod from k2hr3client.exception import K2hr3Exception @@ -114,7 +115,7 @@ class K2hr3Resource(K2hr3Api): # pylint: disable=too-many-instance-attributes def __init__(self, r3token: Optional[str] = None, roletoken: Optional[str] = None, - resource_path: Optional[str] = None) -> None: # pylint: disable=too-many-arguments # noqa + resource_path: Optional[str] = None) -> None: """Init the members.""" super().__init__("resource") self.r3token = r3token @@ -176,7 +177,7 @@ def __init__(self, r3token: Optional[str] = None, # data=resource data # keys=json key value object # - def create_conf_resource(self, name: str, data_type: str, data: Any, + def create_conf_resource(self, name: str, data_type: str, data: Any, # pylint: disable=R0917 # noqa tenant: str, cluster_name: str, keys: Optional[dict], alias: Optional[list] = None): @@ -254,7 +255,7 @@ def validate(self, data_type: str, keys: Optional[dict], self.service = service # type: ignore return self - def validate_with_notoken(self, port: str, cuk: str, role: str, + def validate_with_notoken(self, port: str, cuk: str, role: str, # pylint: disable=R0917 # noqa data_type: str, keys: Optional[dict], service: Optional[str] = None): """Validate the resource without tokens.""" @@ -302,7 +303,7 @@ def delete_with_roletoken(self, data_type: str, self.keys = keys # type: ignore return self - def delete_with_notoken(self, port: str, cuk: str, role: str, + def delete_with_notoken(self, port: str, cuk: str, role: str, # pylint: disable=R0917 # noqa data_type: str, keys: Optional[dict]): """Delete the resource without token.""" self.api_id = 9 @@ -344,8 +345,10 @@ def _set_data(self, val: Any, projectname: str, clustername: str) -> None: f'path must be a regular file, not {val}') # NOTE(hiwakaba): val must not be an arbitrary value. # for backward compat, the resource template is used. - val = "/opt/stack/k2hdkc_dbaas/utils/python-k2hr3client/examples/example_resource.txt" # noqa # pylint: disable=line-too-long - with val.open() as f: # pylint: disable=no-member + k2hr3client_init_py = Path(k2hr3client.__file__) + val = k2hr3client_init_py.parent.joinpath('examples', + 'example_resource.txt') + with val.open(encoding='utf-8') as f: # pylint: disable=no-member line_len = 0 for line in iter(f.readline, ''): # 3. replace TROVE_K2HDKC_CLUSTER_NAME with clustername diff --git a/src/k2hr3client/role.py b/src/k2hr3client/role.py index 399999d..1e4d0b2 100644 --- a/src/k2hr3client/role.py +++ b/src/k2hr3client/role.py @@ -41,7 +41,7 @@ myrole = K2hr3Role(mytoken.token) myhttp.POST( myrole.create( - role_name = "test_role", + name = "test_role", policies = ['yrn:yahoo:::demo:policy:test_policy'], alias = [] ) @@ -54,6 +54,7 @@ import json import logging from typing import List, Optional +import warnings from k2hr3client.api import K2hr3Api, K2hr3HTTPMethod @@ -121,7 +122,7 @@ class K2hr3RoleHost: # pylint disable=too-few-public-methods NOTE(hiwakaba): This class exists only for backward compatibility. """ - def __init__(self, host: str, port: str, cuk: str, extra: str, tag: str, + def __init__(self, host: str, port: str, cuk: str, extra: str, tag: str, # pylint: disable=R0917 # noqa inboundip: str, outboundip: str): """Init the members.""" self.host = host @@ -189,7 +190,7 @@ def __init__(self, r3token: str, token_type=K2hr3TokenType.SCOPED_TOKEN): self.body = None self.urlparams = None # attributes that are unique to this class - self.role_name = None + self.name = None self.policies = None self.alias = None self.host = None @@ -207,52 +208,88 @@ def __init__(self, r3token: str, token_type=K2hr3TokenType.SCOPED_TOKEN): # POST http(s)://API SERVER:PORT/v1/role # PUT http(s)://API SERVER:PORT/v1/role?urlarg - def create(self, role_name: str, policies: List[str], alias: List[str]): + def create(self, name: str, policies: List[str], alias: List[str], + role_name: Optional[str] = None): """Create tokens.""" self.api_id = 1 - self.role_name = role_name # type: ignore + self.name = name # type: ignore self.policies = policies # type: ignore self.alias = alias # type: ignore + if name is None and role_name is not None: + warnings.warn( + "The 'role_name' parameter to 'create' " + "is deprecated and slated for removal in " + "k2hr3client-1.1.0", + DeprecationWarning, + stacklevel=1) + self.name = role_name return self # POST(Add HOST to ROLE) # http(s)://API SERVER:PORT/v1/role/role path # http(s)://API SERVER:PORT/v1/role/yrn full path to role - def add_member(self, role_name: str, host: str, - clear_hostname: bool, clear_ips: str): + def add_member(self, name: str, host: str, # pylint: disable=R0917 + clear_hostname: bool, clear_ips: str, + role_name: Optional[str] = None): """Add a member to the role.""" self.api_id = 3 - self.role_name = role_name # type: ignore + self.name = name # type: ignore self.host = host # type: ignore self.clear_hostname = clear_hostname # type: ignore self.clear_ips = clear_ips # type: ignore + if name is None and role_name is not None: + warnings.warn( + "The 'role_name' parameter to 'create' " + "is deprecated and slated for removal in " + "k2hr3client-1.1.0", + DeprecationWarning, + stacklevel=1) + self.name = role_name return self - def add_members(self, role_name: str, hosts: str, - clear_hostname: bool, clear_ips: str): + def add_members(self, name: str, hosts: str, # pylint: disable=R0917 + clear_hostname: bool, clear_ips: str, + role_name: Optional[str] = None): """Add members to the role.""" self.api_id = 4 - self.role_name = role_name # type: ignore + self.name = name # type: ignore self.hosts = hosts # type: ignore self.clear_hostname = clear_hostname # type: ignore self.clear_ips = clear_ips # type: ignore + if name is None and role_name is not None: + warnings.warn( + "The 'role_name' parameter to 'create' " + "is deprecated and slated for removal in " + "k2hr3client-1.1.0", + DeprecationWarning, + stacklevel=1) + self.name = role_name return self # PUT(Add HOST to ROLE) # http(s)://API SERVER:PORT/v1/role/role path?urlarg # http(s)://API SERVER:PORT/v1/role/yrn full path to role?urlarg - def add_member_with_roletoken(self, role_name: str, port: str, cuk: str, + def add_member_with_roletoken(self, name: str, port: str, cuk: str, # pylint: disable=R0917 # noqa extra: str, tag: str, - inboundip: str, outboundip: str): + inboundip: str, outboundip: str, + role_name: Optional[str] = None): """Add members to the role without roletoken.""" self.api_id = 5 - self.role_name = role_name # type: ignore + self.name = name # type: ignore self.port = port # type: ignore self.cuk = cuk # type: ignore self.extra = extra # type: ignore self.tag = tag # type: ignore self.inboundip = inboundip # type: ignore self.outboundip = outboundip # type: ignore + if name is None and role_name is not None: + warnings.warn( + "The 'role_name' parameter to 'create' " + "is deprecated and slated for removal in " + "k2hr3client-1.1.0", + DeprecationWarning, + stacklevel=1) + self.name = role_name return self # GET(Create ROLE Token) @@ -260,47 +297,90 @@ def add_member_with_roletoken(self, role_name: str, port: str, cuk: str, # GET(Show ROLE details) # http(s)://API SERVER:PORT/v1/role/role path or yrn full role path?urlarg - def get(self, role_name: str, expand: bool = True): + def get(self, name: str, expand: bool = True, + role_name: Optional[str] = None): """Show role details.""" self.api_id = 6 - self.role_name = role_name # type: ignore + self.name = name # type: ignore self.expand = expand # type: ignore + if name is None and role_name is not None: + warnings.warn( + "The 'role_name' parameter to 'create' " + "is deprecated and slated for removal in " + "k2hr3client-1.1.0", + DeprecationWarning, + stacklevel=1) + self.name = role_name return self # GET (Role Token List) # http(s)://APISERVER:PORT/v1/role/token/list/role path or yrn full role path # noqa - def get_token_list(self, role_name: str, expand: bool = True): + def get_token_list(self, name: str, expand: bool = True, + role_name: Optional[str] = None): """Show token list.""" self.api_id = 7 - self.role_name = role_name # type: ignore + self.name = name # type: ignore self.expand = expand # type: ignore + if name is None and role_name is not None: + warnings.warn( + "The 'role_name' parameter to 'create' " + "is deprecated and slated for removal in " + "k2hr3client-1.1.0", + DeprecationWarning, + stacklevel=1) + self.name = role_name return self # HEAD(Validate ROLE) # http(s)://API SERVER:PORT/v1/role/role path or yrn full role path - def validate_role(self, role_name: str): + def validate_role(self, name: str, role_name: Optional[str] = None): """Validate role.""" self.api_id = 8 - self.role_name = role_name # type: ignore + self.name = name # type: ignore + if name is None and role_name is not None: + warnings.warn( + "The 'role_name' parameter to 'create' " + "is deprecated and slated for removal in " + "k2hr3client-1.1.0", + DeprecationWarning, + stacklevel=1) + self.name = role_name return self # DELETE(Delete ROLE) # http(s)://API SERVER:PORT/v1/role/role path or yrn full role path?urlarg - def delete(self, role_name: str): + def delete(self, name: str, role_name: Optional[str] = None): """Delete role.""" self.api_id = 9 - self.role_name = role_name # type: ignore + self.name = name # type: ignore + if name is None and role_name is not None: + warnings.warn( + "The 'role_name' parameter to 'create' " + "is deprecated and slated for removal in " + "k2hr3client-1.1.0", + DeprecationWarning, + stacklevel=1) + self.name = role_name return self # DELETE(Hostname/IP address deletion-role specification) # http(s)://API SERVER:PORT/v1/role/role path or yrn full role path - def delete_member(self, role_name: str, host: str, port: str, cuk: str): + def delete_member(self, name: str, host: str, port: str, cuk: str, # pylint: disable=R0917 # noqa + role_name: Optional[str] = None): """Delete host.""" self.api_id = 10 - self.role_name = role_name # type: ignore + self.name = name # type: ignore self.host = host # type: ignore self.port = port # type: ignore self.cuk = cuk # type: ignore + if name is None and role_name is not None: + warnings.warn( + "The 'role_name' parameter to 'create' " + "is deprecated and slated for removal in " + "k2hr3client-1.1.0", + DeprecationWarning, + stacklevel=1) + self.name = role_name return self # DELETE(Hostname/IP address deletion - Role not specified) @@ -312,12 +392,21 @@ def delete_member_wo_roletoken(self, cuk: str): # DELETE (RoleToken deletion - Role specified) # http(s)://API SERVER:PORT/v1/role/role path or yrn full role path - def delete_roletoken(self, role_name: str, port: str, cuk: str): + def delete_roletoken(self, name: str, port: str, cuk: str, + role_name: Optional[str] = None): """Delete roletoken.""" self.api_id = 12 - self.role_name = role_name # type: ignore + self.name = name # type: ignore self.port = port # type: ignore self.cuk = cuk # type: ignore + if name is None and role_name is not None: + warnings.warn( + "The 'role_name' parameter to 'create' " + "is deprecated and slated for removal in " + "k2hr3client-1.1.0", + DeprecationWarning, + stacklevel=1) + self.name = role_name return self # DELETE(Delete RoleToken - Role not specified) @@ -357,7 +446,7 @@ def _api_path(self, method: K2hr3HTTPMethod) -> Optional[str]: # pylint: disable if method == K2hr3HTTPMethod.POST: if self.api_id == 1: python_data = json.loads(_ROLE_API_CREATE_ROLE) - python_data['role']['name'] = self.role_name + python_data['role']['name'] = self.name python_data['role']['policies'] = self.policies python_data['role']['alias'] = self.alias self.body = json.dumps(python_data) @@ -374,13 +463,13 @@ def _api_path(self, method: K2hr3HTTPMethod) -> Optional[str]: # pylint: disable python_data['host']['outboundip'] = self.host.outboundip # type: ignore[attr-defined] # noqa # pylint: disable=line-too-long self.body = json.dumps(python_data) # http(s)://API SERVER:PORT/v1/role/role path - return f'{self.version}/{self.basepath}/{self.role_name}' + return f'{self.version}/{self.basepath}/{self.name}' # elif (self.api_id == 4): # python_data = json.loads(_ROLE_API_ADD_MEMBERS) # # TODO(hiwakaba) Not implemented # self.body = json.dumps(python_data) # # http(s)://API SERVER:PORT/v1/role/role path - # return f'{self.basepath}/{self.role_name}' + # return f'{self.basepath}/{self.name}' if self.api_id == 5: python_data = json.loads(_ROLE_API_ADD_MEMBER_USING_ROLETOKEN) python_data['host']['port'] = self.host.port # type: ignore[attr-defined] # noqa @@ -391,11 +480,11 @@ def _api_path(self, method: K2hr3HTTPMethod) -> Optional[str]: # pylint: disable python_data['host']['outboundip'] = self.host.outboundip # type: ignore[attr-defined] # noqa # pylint: disable=line-too-long self.body = json.dumps(python_data) # http(s)://API SERVER:PORT/v1/role/role path - return f'{self.version}/{self.basepath}/{self.role_name}' + return f'{self.version}/{self.basepath}/{self.name}' if method == K2hr3HTTPMethod.PUT: if self.api_id == 1: self.urlparams = json.dumps({ - 'name': self.role_name, + 'name': self.name, 'policies': self.policies, 'alias': self.alias }) @@ -412,13 +501,13 @@ def _api_path(self, method: K2hr3HTTPMethod) -> Optional[str]: # pylint: disable 'outboundip': self.host.outboundip # type: ignore[attr-defined] # noqa }) # http(s)://API SERVER:PORT/v1/role/role path - return f'{self.version}/{self.basepath}/{self.role_name}' + return f'{self.version}/{self.basepath}/{self.name}' if self.api_id == 4: # TODO(hiwakaba) Not implemented self.urlparams = json.dumps({ }) # http(s)://API SERVER:PORT/v1/role/role path - return f'{self.version}/{self.basepath}/{self.role_name}' + return f'{self.version}/{self.basepath}/{self.name}' if self.api_id == 5: self.urlparams = json.dumps({ 'port': self.port, @@ -429,7 +518,7 @@ def _api_path(self, method: K2hr3HTTPMethod) -> Optional[str]: # pylint: disable 'outboundip': self.outboundip }) # http(s)://API SERVER:PORT/v1/role/role path - return f'{self.version}/{self.basepath}/{self.role_name}' + return f'{self.version}/{self.basepath}/{self.name}' if method == K2hr3HTTPMethod.GET: if self.api_id == 6: self.urlparams = json.dumps({ @@ -437,26 +526,26 @@ def _api_path(self, method: K2hr3HTTPMethod) -> Optional[str]: # pylint: disable }) # GET(Show ROLE details) # http(s)://API SERVER:PORT/v1/role/role path or yrn full role path?urlarg # noqa - return f'{self.version}/{self.basepath}/{self.role_name}' + return f'{self.version}/{self.basepath}/{self.name}' if self.api_id == 7: self.urlparams = json.dumps({ 'expand': self.expand }) # http(s)://APISERVER:PORT/v1/role/token/list/role path or yrn full role path # noqa return f'{self.version}/{self.basepath}/token/list/' \ - f'{self.role_name}' + f'{self.name}' if method == K2hr3HTTPMethod.HEAD: if self.api_id == 8: # HEAD(Validate ROLE) # http(s)://API SERVER:PORT/v1/role/role path or yrn full role path # noqa - return f'{self.version}/{self.basepath}/{self.role_name}' + return f'{self.version}/{self.basepath}/{self.name}' if method == K2hr3HTTPMethod.DELETE: if self.api_id == 9: # DELETE(Delete ROLE) # http(s)://API SERVER:PORT/v1/role/role path or yrn full role path?urlarg # noqa - return f'{self.version}/{self.basepath}/{self.role_name}' + return f'{self.version}/{self.basepath}/{self.name}' if self.api_id == 10: # DELETE(Hostname/IP address deletion-role specification) # http(s)://API SERVER:PORT/v1/role/role path or yrn full role path # noqa @@ -465,7 +554,7 @@ def _api_path(self, method: K2hr3HTTPMethod) -> Optional[str]: # pylint: disable 'port': self.port, 'cuk': self.cuk }) - return f'{self.version}/{self.basepath}/{self.role_name}' + return f'{self.version}/{self.basepath}/{self.name}' if self.api_id == 11: # DELETE(Hostname/IP address deletion-role specification) # http(s)://API SERVER:PORT/v1/role/role path or yrn full role path # noqa @@ -480,7 +569,7 @@ def _api_path(self, method: K2hr3HTTPMethod) -> Optional[str]: # pylint: disable 'port': self.port, 'cuk': self.cuk }) - return f'{self.version}/{self.basepath}/{self.role_name}' + return f'{self.version}/{self.basepath}/{self.name}' if self.api_id == 13: # DELETE(Delete RoleToken - Role not specified) # http(s)://API SERVER:PORT/v1/role/token/role token string diff --git a/src/k2hr3client/tenant.py b/src/k2hr3client/tenant.py index cb01d3c..56fb757 100644 --- a/src/k2hr3client/tenant.py +++ b/src/k2hr3client/tenant.py @@ -141,7 +141,7 @@ def create(self, tenant_name: str, users: Optional[List[str]], # } # } # PUT (Update) http(s)://API SERVER:PORT/v1/tenant/tenant name?id=tenant id # noqa - def modify(self, tenant_name: str, tenant_id: int, + def modify(self, tenant_name: str, tenant_id: int, # pylint: disable=R0917 users: Optional[List[str]], desc: Optional[str], display: Optional[str]): """Update the K2HR3 cluster Local Tenant(TENANT).""" diff --git a/src/tests/test_policy.py b/src/tests/test_policy.py index f593250..8da28d2 100644 --- a/src/tests/test_policy.py +++ b/src/tests/test_policy.py @@ -47,7 +47,7 @@ def setUp(self): RESOURCE_PATH = "yrn:yahoo:::demo:resource:my_resource" self.token = "token" self.service = "testservice" - self.policy_name = "testpolicy" + self.name = "testpolicy" self.tenant = "demo" self.effect = 'allow' self.action = ['yrn:yahoo::::action:read'] @@ -79,7 +79,7 @@ def test_policy_create_policy_using_post(self, mock_HTTP_REQUEST_METHOD): } self.assertEqual(mypolicy.headers, headers) mypolicy.create( - self.policy_name, self.effect, self.action, + self.name, self.effect, self.action, self.resource, self.condition, self.alias) httpreq = khttp.K2hr3Http(self.base_url) @@ -98,7 +98,7 @@ def test_policy_create_policy_using_post(self, mock_HTTP_REQUEST_METHOD): # 4. assert Request body import json python_data = json.loads(kpolicy._POLICY_API_CREATE_POLICY) - python_data['policy']['name'] = self.policy_name + python_data['policy']['name'] = self.name python_data['policy']['effect'] = self.effect python_data['policy']['action'] = self.action python_data['policy']['resource'] = self.resource @@ -117,7 +117,7 @@ def test_policy_create_policy_using_put(self, mock_HTTP_REQUEST_METHOD): } self.assertEqual(mypolicy.headers, headers) mypolicy.create( - self.policy_name, self.effect, self.action, + self.name, self.effect, self.action, self.resource, self.condition, self.alias) httpreq = khttp.K2hr3Http(self.base_url) @@ -127,7 +127,7 @@ def test_policy_create_policy_using_put(self, mock_HTTP_REQUEST_METHOD): self.assertEqual(httpreq.url, f"{self.base_url}/v1/policy") # 2. assert URL params s_s_urlparams = { - 'name': self.policy_name, + 'name': self.name, 'effect': self.effect, 'action': self.action, 'resource': self.resource, @@ -155,13 +155,13 @@ def test_policy_get_using_get(self, mock_HTTP_REQUEST_METHOD): 'x-auth-token': 'U=token' } self.assertEqual(mypolicy.headers, headers) - mypolicy.get(self.policy_name, self.service) + mypolicy.get(self.name, self.service) httpreq = khttp.K2hr3Http(self.base_url) self.assertTrue(httpreq.GET(mypolicy)) # 1. assert URL - self.assertEqual(httpreq.url, f"{self.base_url}/v1/policy/{self.policy_name}") # noqa + self.assertEqual(httpreq.url, f"{self.base_url}/v1/policy/{self.name}") # noqa # 2. assert URL params s_s_urlparams = { 'service': self.service @@ -189,7 +189,7 @@ def test_policy_validate_using_head(self, mock_HTTP_REQUEST_METHOD): } self.assertEqual(mypolicy.headers, headers) mypolicy.validate( - self.policy_name, self.tenant, self.resource, self.action, + self.name, self.tenant, self.resource, self.action, self.service ) @@ -197,7 +197,7 @@ def test_policy_validate_using_head(self, mock_HTTP_REQUEST_METHOD): self.assertTrue(httpreq.HEAD(mypolicy)) # 1. assert URL - self.assertEqual(httpreq.url, f"{self.base_url}/v1/policy/{self.policy_name}") # noqa + self.assertEqual(httpreq.url, f"{self.base_url}/v1/policy/{self.name}") # noqa # 2. assert URL params s_s_urlparams = { 'tenant': self.tenant, @@ -227,13 +227,13 @@ def test_policy_delete_using_delete(self, mock_HTTP_REQUEST_METHOD): 'x-auth-token': 'U=token' } self.assertEqual(mypolicy.headers, headers) - mypolicy.delete(self.policy_name) + mypolicy.delete(self.name) httpreq = khttp.K2hr3Http(self.base_url) self.assertTrue(httpreq.DELETE(mypolicy)) # 1. assert URL - self.assertEqual(httpreq.url, f"{self.base_url}/v1/policy/{self.policy_name}") # noqa + self.assertEqual(httpreq.url, f"{self.base_url}/v1/policy/{self.name}") # noqa # 2. assert URL params self.assertEqual(httpreq.urlparams, None) # 3. assert Request headers diff --git a/src/tests/test_role.py b/src/tests/test_role.py index b20daec..ed610e5 100644 --- a/src/tests/test_role.py +++ b/src/tests/test_role.py @@ -45,7 +45,7 @@ def setUp(self): """Sets up a test case.""" self.base_url = "http://127.0.0.1:18080" self.token = "testtoken" - self.role_name = "testrole" + self.name = "testrole" POLICY_PATH = "yrn:yahoo:::demo:policy:my_policy" self.policies = [POLICY_PATH] self.alias = [] @@ -81,7 +81,7 @@ def test_role_create_role_using_post(self, mock_HTTP_REQUEST_METHOD): 'x-auth-token': 'U=testtoken' } self.assertEqual(myrole.headers, headers) - myrole.create(self.role_name, self.policies, self.alias) + myrole.create(self.name, self.policies, self.alias) httpreq = khttp.K2hr3Http(self.base_url) self.assertTrue(httpreq.POST(myrole)) @@ -99,7 +99,7 @@ def test_role_create_role_using_post(self, mock_HTTP_REQUEST_METHOD): # 4. assert Request body import json python_data = json.loads(krole._ROLE_API_CREATE_ROLE) - python_data['role']['name'] = self.role_name + python_data['role']['name'] = self.name python_data['role']['policies'] = self.policies python_data['role']['alias'] = self.alias body = json.dumps(python_data) @@ -115,7 +115,7 @@ def test_role_create_role_using_put(self, mock_HTTP_REQUEST_METHOD): 'x-auth-token': 'U=testtoken' } self.assertEqual(myrole.headers, headers) - myrole.create(self.role_name, self.policies, self.alias) + myrole.create(self.name, self.policies, self.alias) httpreq = khttp.K2hr3Http(self.base_url) self.assertTrue(httpreq.PUT(myrole)) @@ -124,7 +124,7 @@ def test_role_create_role_using_put(self, mock_HTTP_REQUEST_METHOD): self.assertEqual(httpreq.url, f"{self.base_url}/v1/role") # 2. assert URL params s_s_urlparams = { - 'name': self.role_name, + 'name': self.name, 'policies': self.policies, 'alias': self.alias } @@ -150,14 +150,14 @@ def test_role_add_member_using_post(self, mock_HTTP_REQUEST_METHOD): 'x-auth-token': 'U=testtoken' } self.assertEqual(myrole.headers, headers) - myrole.add_member(self.role_name, self.host, self.clear_hostname, + myrole.add_member(self.name, self.host, self.clear_hostname, self.clear_ips) httpreq = khttp.K2hr3Http(self.base_url) self.assertTrue(httpreq.POST(myrole)) # 1. assert URL - self.assertEqual(httpreq.url, f"{self.base_url}/v1/role/{self.role_name}") + self.assertEqual(httpreq.url, f"{self.base_url}/v1/role/{self.name}") # 2. assert URL params self.assertEqual(myrole.urlparams, None) # 3. assert Request headers @@ -189,13 +189,13 @@ def test_role_add_member_using_put(self, mock_HTTP_REQUEST_METHOD): 'x-auth-token': f'U={self.token}' } self.assertEqual(myrole.headers, headers) - myrole.add_member(self.role_name, self.host, self.policies, self.alias) + myrole.add_member(self.name, self.host, self.policies, self.alias) httpreq = khttp.K2hr3Http(self.base_url) self.assertTrue(httpreq.PUT(myrole)) # 1. assert URL - self.assertEqual(httpreq.url, f"{self.base_url}/v1/role/{self.role_name}") + self.assertEqual(httpreq.url, f"{self.base_url}/v1/role/{self.name}") # 2. assert URL params s_s_urlparams = { 'host': self.host.host, @@ -227,14 +227,14 @@ def test_role_add_member_with_roletoken_using_put( self.assertEqual(myrole.headers, headers) myrole.add_member_with_roletoken( - self.role_name, self.host.port, self.host.cuk, self.host.extra, + self.name, self.host.port, self.host.cuk, self.host.extra, self.host.tag, self.host.inboundip, self.host.outboundip) httpreq = khttp.K2hr3Http(self.base_url) self.assertTrue(httpreq.PUT(myrole)) # 1. assert URL - self.assertEqual(httpreq.url, f"{self.base_url}/v1/role/{self.role_name}") + self.assertEqual(httpreq.url, f"{self.base_url}/v1/role/{self.name}") # 2. assert URL params s_s_urlparams = { 'port': self.host.port, @@ -263,13 +263,13 @@ def test_role_get(self, mock_HTTP_REQUEST_METHOD): } self.assertEqual(myrole.headers, headers) - myrole.get(self.role_name) + myrole.get(self.name) httpreq = khttp.K2hr3Http(self.base_url) self.assertTrue(httpreq.GET(myrole)) # 1. assert URL - self.assertEqual(httpreq.url, f"{self.base_url}/v1/role/{self.role_name}") + self.assertEqual(httpreq.url, f"{self.base_url}/v1/role/{self.name}") # 2. assert URL params s_s_urlparams = { 'expand': True @@ -293,13 +293,13 @@ def test_get_token_list(self, mock_HTTP_REQUEST_METHOD): } self.assertEqual(myrole.headers, headers) - myrole.get_token_list(self.role_name) + myrole.get_token_list(self.name) httpreq = khttp.K2hr3Http(self.base_url) self.assertTrue(httpreq.GET(myrole)) # 1. assert URL - self.assertEqual(httpreq.url, f"{self.base_url}/v1/role/token/list/{self.role_name}") # noqa + self.assertEqual(httpreq.url, f"{self.base_url}/v1/role/token/list/{self.name}") # noqa # 2. assert URL params s_s_urlparams = { 'expand': True @@ -323,13 +323,13 @@ def test_validate(self, mock_HTTP_REQUEST_METHOD): } self.assertEqual(myrole.headers, headers) - myrole.validate_role(self.role_name) + myrole.validate_role(self.name) httpreq = khttp.K2hr3Http(self.base_url) self.assertTrue(httpreq.HEAD(myrole)) # 1. assert URL - self.assertEqual(httpreq.url, f"{self.base_url}/v1/role/{self.role_name}") + self.assertEqual(httpreq.url, f"{self.base_url}/v1/role/{self.name}") # 2. assert URL params self.assertEqual(httpreq.urlparams, None) # 3. assert Request headers @@ -348,13 +348,13 @@ def test_delete_role(self, mock_HTTP_REQUEST_METHOD): } self.assertEqual(myrole.headers, headers) - myrole.delete(self.role_name) + myrole.delete(self.name) httpreq = khttp.K2hr3Http(self.base_url) self.assertTrue(httpreq.DELETE(myrole)) # 1. assert URL - self.assertEqual(httpreq.url, f"{self.base_url}/v1/role/{self.role_name}") + self.assertEqual(httpreq.url, f"{self.base_url}/v1/role/{self.name}") # 2. assert URL params self.assertEqual(httpreq.urlparams, None) # 3. assert Request headers @@ -372,14 +372,14 @@ def test_role_delete_member(self, mock_HTTP_REQUEST_METHOD): 'x-auth-token': f'U={self.token}' } self.assertEqual(myrole.headers, headers) - myrole.delete_member(self.role_name, self.host.host, self.host.port, + myrole.delete_member(self.name, self.host.host, self.host.port, self.host.cuk) httpreq = khttp.K2hr3Http(self.base_url) self.assertTrue(httpreq.DELETE(myrole)) # 1. assert URL - self.assertEqual(httpreq.url, f"{self.base_url}/v1/role/{self.role_name}") + self.assertEqual(httpreq.url, f"{self.base_url}/v1/role/{self.name}") # 2. assert URL params s_s_urlparams = { 'host': self.host.host, @@ -434,13 +434,13 @@ def test_role_delete_roletoken(self, mock_HTTP_REQUEST_METHOD): } self.assertEqual(myrole.headers, headers) - myrole.delete_roletoken(self.role_name, self.host.port, self.host.cuk) + myrole.delete_roletoken(self.name, self.host.port, self.host.cuk) httpreq = khttp.K2hr3Http(self.base_url) self.assertTrue(httpreq.DELETE(myrole)) # 1. assert URL - self.assertEqual(httpreq.url, f"{self.base_url}/v1/role/{self.role_name}") + self.assertEqual(httpreq.url, f"{self.base_url}/v1/role/{self.name}") # 2. assert URL params s_s_urlparams = { 'port': self.host.port,