diff options
author | Thomas Duval <thomas.duval@orange.com> | 2017-12-13 11:04:09 +0100 |
---|---|---|
committer | Thomas Duval <thomas.duval@orange.com> | 2017-12-13 11:04:09 +0100 |
commit | bf495b93579a71dd01460cfeaf750703b239892d (patch) | |
tree | 54bcfd520a3ec14c0b7fd480ce8aa6d11841c7b6 | |
parent | 4fa851471190f968289e04ae0f803b5b63744f6b (diff) |
Add moon_bouchon component.
Change-Id: I6b5e88ca9349923c15c252f7f338b790a6714320
-rw-r--r-- | moonv4/moon_bouchon/Dockerfile | 8 | ||||
-rw-r--r-- | moonv4/moon_bouchon/README.md | 42 | ||||
-rw-r--r-- | moonv4/moon_bouchon/moon_bouchon/__init__.py | 7 | ||||
-rw-r--r-- | moonv4/moon_bouchon/moon_bouchon/__main__.py | 9 | ||||
-rw-r--r-- | moonv4/moon_bouchon/moon_bouchon/server.py | 138 | ||||
-rw-r--r-- | moonv4/moon_bouchon/requirements.txt | 1 | ||||
-rw-r--r-- | moonv4/moon_bouchon/setup.cfg | 2 | ||||
-rw-r--r-- | moonv4/moon_bouchon/setup.py | 47 | ||||
-rw-r--r-- | moonv4/moon_bouchon/tests/test_interface.py | 61 | ||||
-rw-r--r-- | moonv4/moon_bouchon/tests/test_wrapper.py | 38 |
10 files changed, 353 insertions, 0 deletions
diff --git a/moonv4/moon_bouchon/Dockerfile b/moonv4/moon_bouchon/Dockerfile new file mode 100644 index 00000000..ed013935 --- /dev/null +++ b/moonv4/moon_bouchon/Dockerfile @@ -0,0 +1,8 @@ +FROM python:3 + +ADD . /root +RUN pip install -r /root/requirements.txt --upgrade +WORKDIR /root +RUN pip install . + +CMD ["python", "-m", "moon_bouchon"]
\ No newline at end of file diff --git a/moonv4/moon_bouchon/README.md b/moonv4/moon_bouchon/README.md new file mode 100644 index 00000000..11733cef --- /dev/null +++ b/moonv4/moon_bouchon/README.md @@ -0,0 +1,42 @@ +#Moon Bouchon + +Moon_bouchon is a fake interface to the Moon platform. +Moon platform can be requested through 2 interfaces: + +- ''wrapper'', interface for the OpenStack platform +- ''interface'', interface for other components + +## Usage: + +### server + +To start the server: + + docker run -ti -p 31002:31002 wukongsun/moon_bouchon:v1.0 + # or docker run -dti -p 31002:31002 wukongsun/moon_bouchon:v1.0 + +### wrapper + +Here are the URL, you can request: + + POST /wrapper/authz/grant to request the wrapper component with always a "True" response + POST /wrapper/authz/deny to request the wrapper component with always a "False" response + POST /wrapper/authz to request the wrapper component with always a "True" or "False" response + +In each request you must pass the following data (or similar): + + {'rule': 'start', 'target': '{"target": {"name": "vm0"}, "user_id": "user0"}', 'credentials': 'null'} + +You have examples in the moon_bouchon/tests directory. + +### interface + +Here are the URL, you can request: + + GET /interface/authz/grant/<string:project_id>/<string:subject_name>/<string:object_name>/<string:action_name> to request the interface component with always a "True" response + GET /interface/authz/deny/<string:project_id>/<string:subject_name>/<string:object_name>/<string:action_name> to request the interface component with always a "False" response + GET /interface/authz/<string:project_id>/<string:subject_name>/<string:object_name>/<string:action_name> to request the interface component with always a "True" or "False" response + +You have examples in the moon_bouchon/tests directory. + + diff --git a/moonv4/moon_bouchon/moon_bouchon/__init__.py b/moonv4/moon_bouchon/moon_bouchon/__init__.py new file mode 100644 index 00000000..8811d91d --- /dev/null +++ b/moonv4/moon_bouchon/moon_bouchon/__init__.py @@ -0,0 +1,7 @@ +# 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__ = "1.1" diff --git a/moonv4/moon_bouchon/moon_bouchon/__main__.py b/moonv4/moon_bouchon/moon_bouchon/__main__.py new file mode 100644 index 00000000..4499a96b --- /dev/null +++ b/moonv4/moon_bouchon/moon_bouchon/__main__.py @@ -0,0 +1,9 @@ +# 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'. + + +import moon_bouchon.server + +moon_bouchon.server.main() diff --git a/moonv4/moon_bouchon/moon_bouchon/server.py b/moonv4/moon_bouchon/moon_bouchon/server.py new file mode 100644 index 00000000..29e9101e --- /dev/null +++ b/moonv4/moon_bouchon/moon_bouchon/server.py @@ -0,0 +1,138 @@ +# 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'. + +import sys +import flask +from flask import Flask +from flask import request +import json +import logging +import random + +logger = logging.getLogger(__name__) +app = Flask(__name__) + + +@app.route("/interface/authz/grant/<string:project_id>/<string:subject_name>/" + "<string:object_name>/<string:action_name>", + methods=["GET"]) +def interface_grant(project_id, subject_name, object_name, action_name): + logger.info("Requesting interface authz on {} {} {} {}".format( + project_id, subject_name, object_name, action_name)) + return json.dumps({ + "result": True, + "context": { + "project_id": project_id, + "subject_name": subject_name, + "object_name": object_name, + "action_name": action_name + } + }) + + +@app.route("/interface/authz/deny/<string:project_id>/<string:subject_name>/" + "<string:object_name>/<string:action_name>", + methods=["GET"]) +def interface_deny(project_id, subject_name, object_name, action_name): + logger.info("Requesting interface authz on {} {} {} {}".format( + project_id, subject_name, object_name, action_name)) + return json.dumps({ + "result": False, + "context": { + "project_id": project_id, + "subject_name": subject_name, + "object_name": object_name, + "action_name": action_name + } + }) + + +@app.route("/interface/authz/<string:project_id>/<string:subject_name>/" + "<string:object_name>/<string:action_name>", + methods=["GET"]) +def interface_authz(project_id, subject_name, object_name, action_name): + logger.info("Requesting interface authz on {} {} {} {}".format( + project_id, subject_name, object_name, action_name)) + return json.dumps({ + "result": random.choice((True, False)), + "context": { + "project_id": project_id, + "subject_name": subject_name, + "object_name": object_name, + "action_name": action_name + } + }) + + +def test_data(): + data = request.form + if not dict(request.form): + data = json.loads(request.data.decode("utf-8")) + try: + target = json.loads(data.get('target', {})) + except Exception: + raise Exception("Error reading target") + try: + credentials = json.loads(data.get('credentials', {})) + except Exception: + raise Exception("Error reading credentials") + try: + rule = data.get('rule', "") + except Exception: + raise Exception("Error reading rule") + + +@app.route("/wrapper/authz/grant", methods=["POST"]) +def wrapper_grant(): + logger.info("Requesting wrapper authz") + try: + test_data() + except Exception as e: + logger.exception(e) + return str(e), 400 + response = flask.make_response("True") + response.headers['content-type'] = 'application/octet-stream' + return response + + +@app.route("/wrapper/authz/deny", methods=["POST"]) +def wrapper_deny(): + logger.info("Requesting wrapper authz") + try: + test_data() + except Exception as e: + logger.exception(e) + return str(e), 400 + response = flask.make_response("False") + response.headers['content-type'] = 'application/octet-stream' + return response + + +@app.route("/wrapper/authz", methods=["POST"]) +def wrapper_authz(): + logger.info("Requesting wrapper authz") + try: + test_data() + except Exception as e: + logger.exception(e) + return str(e), 400 + response = flask.make_response(random.choice(("True", "False"))) + response.headers['content-type'] = 'application/octet-stream' + return response + + +def main(): + port = 31002 + if len(sys.argv) > 1: + try: + port = int(sys.argv[1]) + except ValueError: + logger.error("Argument for Port in command line is not an integer") + sys.exit(1) + app.run(host="0.0.0.0", port=port) + + +if __name__ == "__main__": + main() diff --git a/moonv4/moon_bouchon/requirements.txt b/moonv4/moon_bouchon/requirements.txt new file mode 100644 index 00000000..8ab6294c --- /dev/null +++ b/moonv4/moon_bouchon/requirements.txt @@ -0,0 +1 @@ +flask
\ No newline at end of file diff --git a/moonv4/moon_bouchon/setup.cfg b/moonv4/moon_bouchon/setup.cfg new file mode 100644 index 00000000..7c2b2874 --- /dev/null +++ b/moonv4/moon_bouchon/setup.cfg @@ -0,0 +1,2 @@ +[bdist_wheel] +universal = 1
\ No newline at end of file diff --git a/moonv4/moon_bouchon/setup.py b/moonv4/moon_bouchon/setup.py new file mode 100644 index 00000000..a875be40 --- /dev/null +++ b/moonv4/moon_bouchon/setup.py @@ -0,0 +1,47 @@ +# 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 moon_bouchon + + +setup( + + name='moon_bouchon', + + version=moon_bouchon.__version__, + + packages=find_packages(), + + author="Thomas Duval", + + author_email="thomas.duval@orange.com", + + description="", + + long_description=open('README.md').read(), + + install_requires=["flask"], + + include_package_data=True, + + url='https://git.opnfv.org/cgit/moon', + + classifiers=[ + "Programming Language :: Python", + "Development Status :: 1 - Planning", + "License :: OSI Approved", + "Natural Language :: French", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3", + ], + + entry_points={ + 'console_scripts': [ + 'moon_bouchon = moon_bouchon.server:main', + ], + } + +) diff --git a/moonv4/moon_bouchon/tests/test_interface.py b/moonv4/moon_bouchon/tests/test_interface.py new file mode 100644 index 00000000..425ba2e5 --- /dev/null +++ b/moonv4/moon_bouchon/tests/test_interface.py @@ -0,0 +1,61 @@ +import requests +from uuid import uuid4 +import pytest + + +@pytest.fixture +def args(): + return { + "project_id": uuid4().hex, + "subject_id": uuid4().hex, + "object_id": uuid4().hex, + "action_id": uuid4().hex + } + + +def test_false(args): + url = "http://127.0.0.1:31002/interface/authz/deny/{project_id}" \ + "/{subject_id}/{object_id}/{action_id}".format(**args) + data = {'rule': 'start', + 'target': '{"target": {"name": "vm0"}, "user_id": "user0"}', + 'credentials': 'null'} + req = requests.get( + url, json=data, + headers={'content-type': "application/x-www-form-urlencode"} + ) + assert req.status_code == 200 + assert "result" in req.json() + assert req.json()["result"] == False + + +def test_true(args): + url = "http://127.0.0.1:31002/interface/authz/grant/{project_id}" \ + "/{subject_id}/{object_id}/{action_id}".format(**args) + + data = {'rule': 'start', + 'target': '{"target": {"name": "vm0"}, "user_id": "user0"}', + 'credentials': 'null'} + req = requests.get( + url, json=data, + headers={'content-type': "application/x-www-form-urlencode"} + ) + assert req.status_code == 200 + assert "result" in req.json() + assert req.json()["result"] == True + + +def test_random(args): + url = "http://127.0.0.1:31002/interface/authz/{project_id}" \ + "/{subject_id}/{object_id}/{action_id}".format(**args) + + data = {'rule': 'start', + 'target': '{"target": {"name": "vm0"}, "user_id": "user0"}', + 'credentials': 'null'} + req = requests.get( + url, json=data, + headers={'content-type': "application/x-www-form-urlencode"} + ) + assert req.status_code == 200 + assert "result" in req.json() + assert req.json()["result"] in (False, True) + diff --git a/moonv4/moon_bouchon/tests/test_wrapper.py b/moonv4/moon_bouchon/tests/test_wrapper.py new file mode 100644 index 00000000..3d5e150c --- /dev/null +++ b/moonv4/moon_bouchon/tests/test_wrapper.py @@ -0,0 +1,38 @@ +import requests + + +def test_false(): + url = "http://127.0.0.1:31002/wrapper/authz/deny" + + data = {'rule': 'start', 'target': '{"target": {"name": "vm0"}, "user_id": "user0"}', 'credentials': 'null'} + req = requests.post( + url, json=data, + headers={'content-type': "application/x-www-form-urlencode"} + ) + assert req.status_code == 200 + assert req.text == "False" + + +def test_true(): + url = "http://127.0.0.1:31002/wrapper/authz/grant" + + data = {'rule': 'start', 'target': '{"target": {"name": "vm0"}, "user_id": "user0"}', 'credentials': 'null'} + req = requests.post( + url, json=data, + headers={'content-type': "application/x-www-form-urlencode"} + ) + assert req.status_code == 200 + assert req.text == "True" + + +def test_random(): + url = "http://127.0.0.1:31002/wrapper/authz" + + data = {'rule': 'start', 'target': '{"target": {"name": "vm0"}, "user_id": "user0"}', 'credentials': 'null'} + req = requests.post( + url, json=data, + headers={'content-type': "application/x-www-form-urlencode"} + ) + assert req.status_code == 200 + assert req.text in ("False", "True") + |