From 786f83d18224e4dff3194e92b30d5f62e253deb9 Mon Sep 17 00:00:00 2001 From: Lingxian Kong Date: Sun, 2 Jul 2017 22:58:17 +1200 Subject: [PATCH] Support Keystone session in python runtime Keystone session can be used directly in user function to access OpenStack services. Include openstack clients in python requirements as well. Add a python function example. Implements: blueprint qinling-openstack-clients Change-Id: I4798c404cb57bafe14049f57ba8db7c7125106c7 --- example/functions/python/get_swift_object.py | 12 ++++++++++++ qinling/orchestrator/kubernetes/manager.py | 1 + runtimes/python2/Dockerfile | 2 +- runtimes/python2/requirements.txt | 9 ++++++--- runtimes/python2/server.py | 15 +++++++++++++-- tox.ini | 2 +- 6 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 example/functions/python/get_swift_object.py diff --git a/example/functions/python/get_swift_object.py b/example/functions/python/get_swift_object.py new file mode 100644 index 00000000..41332ca1 --- /dev/null +++ b/example/functions/python/get_swift_object.py @@ -0,0 +1,12 @@ +import swiftclient + + +def stat_object(context, container, object): + conn = swiftclient.Connection( + session=context['os_session'], + os_options={'region_name': 'RegionOne'}, + ) + + obj_header = conn.head_object(container, object) + + return obj_header diff --git a/qinling/orchestrator/kubernetes/manager.py b/qinling/orchestrator/kubernetes/manager.py index 11d9ed83..637e210b 100644 --- a/qinling/orchestrator/kubernetes/manager.py +++ b/qinling/orchestrator/kubernetes/manager.py @@ -286,6 +286,7 @@ class KubernetesManager(base.OrchestratorBase): 'function_id': function_id, 'entry': entry, 'token': context.get_ctx().auth_token, + 'auth_url': self.conf.keystone_authtoken.auth_url } LOG.debug( diff --git a/runtimes/python2/Dockerfile b/runtimes/python2/Dockerfile index b33653be..f4a8f01a 100644 --- a/runtimes/python2/Dockerfile +++ b/runtimes/python2/Dockerfile @@ -1,7 +1,7 @@ FROM alpine:3.5 RUN apk update -RUN apk add --no-cache python2 python2-dev build-base py2-pip +RUN apk add --no-cache linux-headers python2 python2-dev build-base py2-pip py2-pbr RUN pip install --upgrade pip RUN rm -r /root/.cache diff --git a/runtimes/python2/requirements.txt b/runtimes/python2/requirements.txt index 5ff6fc84..22918d98 100644 --- a/runtimes/python2/requirements.txt +++ b/runtimes/python2/requirements.txt @@ -1,3 +1,6 @@ -Flask>=0.11.1 -httplib2 -requests>=2.7.0 +Flask>=0.10,!=0.11,<1.0 # BSD +python-openstackclient>=3.3.0,!=3.10.0 # Apache-2.0 +python-neutronclient>=6.3.0 # Apache-2.0 +python-swiftclient>=3.2.0 # Apache-2.0 +python-ceilometerclient>=2.5.0 # Apache-2.0 +keystoneauth1>=2.21.0 # Apache-2.0 diff --git a/runtimes/python2/server.py b/runtimes/python2/server.py index d725173e..c7d9ef1e 100644 --- a/runtimes/python2/server.py +++ b/runtimes/python2/server.py @@ -23,12 +23,15 @@ from flask import abort from flask import Flask from flask import request from flask import Response +from keystoneauth1.identity import generic +from keystoneauth1 import session import requests app = Flask(__name__) zip_file = '' function_module = 'main' function_method = 'main' +openstack_session = None @app.route('/download', methods=['POST']) @@ -37,11 +40,17 @@ def download(): function_id = request.form['function_id'] entry = request.form['entry'] token = request.form.get('token') + auth_url = request.form.get('auth_url') headers = {} if token: headers = {'X-Auth-Token': token} + # Get openstack session. + global openstack_session + auth = generic.Token(auth_url=auth_url, token=token) + openstack_session = session.Session(auth=auth, verify=False) + global zip_file zip_file = '%s.zip' % function_id @@ -73,6 +82,9 @@ def execute(): global zip_file global function_module global function_method + global openstack_session + + context = {'os_session': openstack_session} importer = zipimport.zipimporter(zip_file) module = importer.load_module(function_module) @@ -88,10 +100,9 @@ def execute(): start = time.time() try: func = getattr(module, function_method) - result = func(**input) + result = func(context=context, **input) except Exception as e: result = str(e) - duration = time.time() - start return Response( diff --git a/tox.ini b/tox.ini index 120d141e..7f891893 100644 --- a/tox.ini +++ b/tox.ini @@ -45,4 +45,4 @@ commands = oslo_debug_helper {posargs} ignore = show-source = true builtins = _ -exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,tools,build +exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,tools,build,example