From 8b326a5aeb0f9655ff0ebfe0d87ff1ea8f66bc38 Mon Sep 17 00:00:00 2001 From: RHE Date: Thu, 21 Dec 2017 10:06:52 +0100 Subject: python_moonclient init Change-Id: Iaf104b3208a07dc80cc266830be444d019b0f196 Signed-off-by: RHE --- moonv4/python_moonclient/Changelog | 12 ++ moonv4/python_moonclient/LICENSE | 202 +++++++++++++++++++++ moonv4/python_moonclient/MANIFEST.in | 10 + moonv4/python_moonclient/README.md | 33 ++++ .../python_moonclient/__init__.py | 6 + .../python_moonclient/python_moonclient/config.py | 44 +++++ moonv4/python_moonclient/requirements.txt | 3 + moonv4/python_moonclient/setup.py | 42 +++++ .../tests/unit_python/conftest.py | 12 ++ .../tests/unit_python/mock_config.py | 35 ++++ .../tests/unit_python/requirements.txt | 2 + .../tests/unit_python/test_config.py | 8 + .../tests/unit_python/utilities.py | 153 ++++++++++++++++ 13 files changed, 562 insertions(+) create mode 100644 moonv4/python_moonclient/Changelog create mode 100644 moonv4/python_moonclient/LICENSE create mode 100644 moonv4/python_moonclient/MANIFEST.in create mode 100644 moonv4/python_moonclient/README.md create mode 100644 moonv4/python_moonclient/python_moonclient/__init__.py create mode 100644 moonv4/python_moonclient/python_moonclient/config.py create mode 100644 moonv4/python_moonclient/requirements.txt create mode 100644 moonv4/python_moonclient/setup.py create mode 100644 moonv4/python_moonclient/tests/unit_python/conftest.py create mode 100644 moonv4/python_moonclient/tests/unit_python/mock_config.py create mode 100644 moonv4/python_moonclient/tests/unit_python/requirements.txt create mode 100644 moonv4/python_moonclient/tests/unit_python/test_config.py create mode 100644 moonv4/python_moonclient/tests/unit_python/utilities.py (limited to 'moonv4/python_moonclient') diff --git a/moonv4/python_moonclient/Changelog b/moonv4/python_moonclient/Changelog new file mode 100644 index 00000000..854200cb --- /dev/null +++ b/moonv4/python_moonclient/Changelog @@ -0,0 +1,12 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + + +CHANGES +======= + +0.1.0 +----- +- First version of the python-moonclient \ No newline at end of file diff --git a/moonv4/python_moonclient/LICENSE b/moonv4/python_moonclient/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/moonv4/python_moonclient/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/moonv4/python_moonclient/MANIFEST.in b/moonv4/python_moonclient/MANIFEST.in new file mode 100644 index 00000000..2a5ac509 --- /dev/null +++ b/moonv4/python_moonclient/MANIFEST.in @@ -0,0 +1,10 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +include README.md +include LICENSE +include Changelog +include setup.py +include requirements.txt diff --git a/moonv4/python_moonclient/README.md b/moonv4/python_moonclient/README.md new file mode 100644 index 00000000..d091cdf5 --- /dev/null +++ b/moonv4/python_moonclient/README.md @@ -0,0 +1,33 @@ +# python-moonclient Package +This package contains the core module for the Moon project. +It is designed to provide authorization feature to all OpenStack components. + +For any other information, refer to the parent project: + + https://git.opnfv.org/moon + +moon_utilities is a common Python lib for other Moon Python packages + +## Build +### Build Python Package +```bash +cd ${MOON_HOME}/moonv4/python_moonclient +python3 setup.py sdist bdist_wheel +``` + +### Push Python Package to PIP +```bash +cd ${MOON_HOME}/moonv4/python_moonclient +gpg --detach-sign -u "${GPG_ID}" -a dist/python_moonclient-X.Y.Z-py3-none-any.whl +gpg --detach-sign -u "${GPG_ID}" -a dist/python_moonclient-X.Y.Z.tar.gz +twine upload dist/python_moonclient-X.Y.Z-py3-none-any.whl dist/python_moonclient-X.Y.Z-py3-none-any.whl.asc +twine upload dist/python_moonclient-X.Y.Z.tar.gz dist/python_moonclient-X.Y.Z.tar.gz.asc +``` + +## Test +### Python Unit Test +launch Docker for Python unit tests +```bash +cd ${MOON_HOME}/moonv4/python_moonclient +docker run --rm --volume $(pwd):/data wukongsun/moon_python_unit_test:latest +``` diff --git a/moonv4/python_moonclient/python_moonclient/__init__.py b/moonv4/python_moonclient/python_moonclient/__init__.py new file mode 100644 index 00000000..d7cdd111 --- /dev/null +++ b/moonv4/python_moonclient/python_moonclient/__init__.py @@ -0,0 +1,6 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +__version__ = "0.0.1" diff --git a/moonv4/python_moonclient/python_moonclient/config.py b/moonv4/python_moonclient/python_moonclient/config.py new file mode 100644 index 00000000..d6317820 --- /dev/null +++ b/moonv4/python_moonclient/python_moonclient/config.py @@ -0,0 +1,44 @@ +import base64 +import json +import requests + + +def get_configuration(consul_host, consul_port, key): + url = "http://{}:{}/v1/kv/{}".format(consul_host, consul_port, key) + req = requests.get(url) + if req.status_code != 200: + raise Exception("xxx") + data = req.json() + if len(data) == 1: + data = data[0] + return {data["Key"]: json.loads(base64.b64decode(data["Value"]).decode("utf-8"))} + else: + return [ + {item["Key"]: json.loads(base64.b64decode(item["Value"]).decode("utf-8"))} + for item in data + ] + + +def get_config_data(consul_host, consul_port): + conf_data = dict() + conf_data['manager_host'] = get_configuration(consul_host, consul_port, + 'components/manager')['components/manager']['external']['hostname'] + conf_data['manager_port'] = get_configuration(consul_host, consul_port, + 'components/manager')['components/manager']['external']['port'] + # conf_data['authz_host'] = get_configuration(consul_host, consul_port, + # 'components/interface')['components/interface']['external']['hostname'] + # conf_data['authz_port'] = get_configuration(consul_host, consul_port, + # 'components/interface')['components/interface']['external']['port'] + conf_data['keystone_host'] = get_configuration(consul_host, consul_port, + 'openstack/keystone')['openstack/keystone']['external']['url'] + # conf_data['keystone_port'] = '5000' + conf_data['keystone_user'] = get_configuration(consul_host, consul_port, + 'openstack/keystone')['openstack/keystone']['user'] + conf_data['keystone_password'] = get_configuration(consul_host, consul_port, + 'openstack/keystone')['openstack/keystone']['password'] + conf_data['keystone_project'] = get_configuration(consul_host, consul_port, + 'openstack/keystone')['openstack/keystone']['project'] + return conf_data + +# get_conf_data('88.88.88.2', '30005') +# get_conf_data('127.0.0.1', 8082) diff --git a/moonv4/python_moonclient/requirements.txt b/moonv4/python_moonclient/requirements.txt new file mode 100644 index 00000000..5b80e5f2 --- /dev/null +++ b/moonv4/python_moonclient/requirements.txt @@ -0,0 +1,3 @@ +werkzeug +flask +requests \ No newline at end of file diff --git a/moonv4/python_moonclient/setup.py b/moonv4/python_moonclient/setup.py new file mode 100644 index 00000000..000e87ca --- /dev/null +++ b/moonv4/python_moonclient/setup.py @@ -0,0 +1,42 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +from setuptools import setup, find_packages +import python_moonclient + +with open('requirements.txt') as f: + required = f.read().splitlines() + +setup( + + name='python-moonclient', + + version=python_moonclient.__version__, + + packages=find_packages(), + + author='Thomas Duval & Ruan He', + + author_email='thomas.duval@orange.com, ruan.he@orange.com', + + description='client lib for all the Moon components', + + long_description=open('README.md').read(), + + install_requires=required, + + include_package_data=True, + + url='https://git.opnfv.org/cgit/moon', + + classifiers=[ + 'Programming Language :: Python :: 3', + 'Development Status :: 1 - Planning', + 'License :: OSI Approved', + 'Natural Language :: English', + 'Operating System :: OS Independent', + ], + +) diff --git a/moonv4/python_moonclient/tests/unit_python/conftest.py b/moonv4/python_moonclient/tests/unit_python/conftest.py new file mode 100644 index 00000000..d26df946 --- /dev/null +++ b/moonv4/python_moonclient/tests/unit_python/conftest.py @@ -0,0 +1,12 @@ +import pytest +import requests_mock +import mock_config + + +@pytest.fixture(autouse=True) +def no_requests(monkeypatch): + """ Modify the response from Requests module + """ + with requests_mock.Mocker(real_http=True) as m: + mock_config.register_consul(m) + yield m diff --git a/moonv4/python_moonclient/tests/unit_python/mock_config.py b/moonv4/python_moonclient/tests/unit_python/mock_config.py new file mode 100644 index 00000000..a3084485 --- /dev/null +++ b/moonv4/python_moonclient/tests/unit_python/mock_config.py @@ -0,0 +1,35 @@ +import utilities + + +components_manager_mock = { + "port": 8082, + "bind": "0.0.0.0", + "hostname": "manager", + "container": "wukongsun/moon_manager:v4.3.1", + "external": { + "port": 30001, + "hostname": "88.88.88.2" + } +} + + +openstack_keystone_mock = { + "url": "http://keystone:5000/v3", + "user": "admin", + "password": "p4ssw0rd", + "domain": "default", + "project": "admin", + "check_token": False, + "certificate": False, + "external": { + "url": "http://88.88.88.2:30006/v3" + } +} + + +def register_consul(m): + for component in utilities.COMPONENTS: + m.register_uri( + 'GET', 'http://consul:8500/v1/kv/{}'.format(component), + json=[{'Key': component, 'Value': utilities.get_b64_conf(component)}] + ) diff --git a/moonv4/python_moonclient/tests/unit_python/requirements.txt b/moonv4/python_moonclient/tests/unit_python/requirements.txt new file mode 100644 index 00000000..3c1ad607 --- /dev/null +++ b/moonv4/python_moonclient/tests/unit_python/requirements.txt @@ -0,0 +1,2 @@ +pytest +requests_mock \ No newline at end of file diff --git a/moonv4/python_moonclient/tests/unit_python/test_config.py b/moonv4/python_moonclient/tests/unit_python/test_config.py new file mode 100644 index 00000000..21b5f630 --- /dev/null +++ b/moonv4/python_moonclient/tests/unit_python/test_config.py @@ -0,0 +1,8 @@ +import pytest +import utilities + + +def test_authz_request(): + from python_moonclient import config + conf_data = config.get_config_data("consul", 8500) + assert isinstance(conf_data, dict) diff --git a/moonv4/python_moonclient/tests/unit_python/utilities.py b/moonv4/python_moonclient/tests/unit_python/utilities.py new file mode 100644 index 00000000..ae2932c7 --- /dev/null +++ b/moonv4/python_moonclient/tests/unit_python/utilities.py @@ -0,0 +1,153 @@ +import base64 +import json + +CONF = { + "openstack": { + "keystone": { + "url": "http://keystone:5000/v3", + "user": "admin", + "check_token": False, + "password": "p4ssw0rd", + "domain": "default", + "certificate": False, + "project": "admin", + "external": { + "url": "http://keystone:5000/v3", + } + } + }, + "components": { + "wrapper": { + "bind": "0.0.0.0", + "port": 8080, + "container": "wukongsun/moon_wrapper:v4.3", + "timeout": 5, + "hostname": "wrapper" + }, + "manager": { + "bind": "0.0.0.0", + "port": 8082, + "container": "wukongsun/moon_manager:v4.3", + "hostname": "manager", + "external": { + "hostname": "manager", + "port": 30001 + } + }, + "port_start": 31001, + "orchestrator": { + "bind": "0.0.0.0", + "port": 8083, + "container": "wukongsun/moon_orchestrator:v4.3", + "hostname": "orchestrator" + }, + "interface": { + "bind": "0.0.0.0", + "port": 8080, + "container": "wukongsun/moon_interface:v4.3", + "hostname": "interface" + } + }, + "plugins": { + "session": { + "port": 8082, + "container": "asteroide/session:latest" + }, + "authz": { + "port": 8081, + "container": "wukongsun/moon_authz:v4.3" + } + }, + "logging": { + "handlers": { + "file": { + "filename": "/tmp/moon.log", + "class": "logging.handlers.RotatingFileHandler", + "level": "DEBUG", + "formatter": "custom", + "backupCount": 3, + "maxBytes": 1048576 + }, + "console": { + "class": "logging.StreamHandler", + "formatter": "brief", + "level": "INFO", + "stream": "ext://sys.stdout" + } + }, + "formatters": { + "brief": { + "format": "%(levelname)s %(name)s %(message)-30s" + }, + "custom": { + "format": "%(asctime)-15s %(levelname)s %(name)s %(message)s" + } + }, + "root": { + "handlers": [ + "console" + ], + "level": "ERROR" + }, + "version": 1, + "loggers": { + "moon": { + "handlers": [ + "console", + "file" + ], + "propagate": False, + "level": "DEBUG" + } + } + }, + "slave": { + "name": None, + "master": { + "url": None, + "login": None, + "password": None + } + }, + "docker": { + "url": "tcp://172.88.88.1:2376", + "network": "moon" + }, + "database": { + "url": "sqlite:///database.db", + # "url": "mysql+pymysql://moon:p4sswOrd1@db/moon", + "driver": "sql" + }, + "messenger": { + "url": "rabbit://moon:p4sswOrd1@messenger:5672/moon" + } +} + +COMPONENTS = ( + "logging", + "openstack/keystone", + "database", + "slave", + "components/manager", + "components/orchestrator", + "components/interface", + "components/wrapper", +) + + +def get_b64_conf(component=None): + if component == "components": + return base64.b64encode( + json.dumps(CONF["components"]).encode('utf-8')+b"\n").decode('utf-8') + elif component in CONF: + return base64.b64encode( + json.dumps( + CONF[component]).encode('utf-8')+b"\n").decode('utf-8') + elif not component: + return base64.b64encode( + json.dumps(CONF).encode('utf-8')+b"\n").decode('utf-8') + elif "/" in component: + key1, _, key2 = component.partition("/") + return base64.b64encode( + json.dumps( + CONF[key1][key2]).encode('utf-8')+b"\n").decode('utf-8') -- cgit 1.2.3-korg