[cfapi] Use muranoclient to access murano packages

Previously service broker queried murano db instead of
using python-muranoclient to make REST API calls.
It's caused some problems, e.g. service broker and GLARE couldn't
work simultaneously.

This commit improves creation of muranoclient in cfapi, adds
artifacts-clients if package_service is set to glare and enables cfapi
to query keystone in case respective urls are not provided.

Co-Authored-By: Kirill Zaitsev <k.zaitsev@me.com>
Change-Id: Ib87f287434eb6a5df4e3f369e5d774c780e7200a
Closes-Bug: #1543986
This commit is contained in:
Nikolay Starodubtsev
2016-03-16 21:06:11 +03:00
committed by Nikolay Starodubtsev
parent d911efe7a9
commit 1e0097d843
3 changed files with 75 additions and 30 deletions

View File

@@ -14,6 +14,7 @@
import base64
import keystoneclient
from keystoneclient.auth.identity import v3
from keystoneclient import exceptions
from keystoneclient import session as ks_session
@@ -55,8 +56,30 @@ class ExternalContextMiddleware(wsgi.Middleware):
password_auth = v3.Password(**kwargs)
session = ks_session.Session(auth=password_auth)
self._query_endpoints(password_auth, session)
return session.get_token()
def _query_endpoints(self, auth, session):
if not hasattr(self, '_murano_endpoint'):
try:
self._murano_endpoint = auth.get_endpoint(
session, 'application-catalog')
except keystoneclient.exceptions.EndpointNotFound:
pass
if not hasattr(self, '_glare_endpoint'):
try:
self._glare_endpoint = auth.get_endpoint(
session, 'artifact')
except keystoneclient.exceptions.EndpointNotFound:
pass
def get_endpoints(self):
return {
'murano': getattr(self, '_murano_endpoint', None),
'glare': getattr(self, '_glare_endpoint', None),
}
def process_request(self, req):
"""Get keystone token for external request
@@ -72,6 +95,7 @@ class ExternalContextMiddleware(wsgi.Middleware):
user, password = credentials.split(':', 2)
req.headers['X-Auth-Token'] = self.get_keystone_token(user,
password)
req.endpoints = self.get_endpoints()
except KeyError:
msg = _("Authorization required")
LOG.warning(msg)

View File

@@ -15,16 +15,17 @@
import json
import uuid
import muranoclient.client as client
from oslo_config import cfg
from oslo_log import log as logging
import six
from webob import response
from murano.common.i18n import _LI, _LW
from murano.common import auth_utils # noqa
from murano.common import wsgi
from murano.db.catalog import api as db_api
from murano.db.services import cf_connections as db_cf
import muranoclient.client as muranoclient
from muranoclient.glance import client as glare_client
cfapi_opts = [
@@ -57,7 +58,7 @@ class Controller(object):
srv['bindable'] = True
srv['tags'] = []
for tag in package.tags:
srv['tags'].append(tag.name)
srv['tags'].append(tag)
plan = {'id': package.id + '-1',
'name': 'default',
'description': 'Default plan for the service {name}'.format(
@@ -81,9 +82,10 @@ class Controller(object):
def list(self, req):
packages = db_api.package_search({'type': 'application'},
req.context,
catalog=True)
token = req.headers['X-Auth-Token']
m_cli = _get_muranoclient(token, req)
kwargs = {'type': 'application'}
packages = m_cli.packages.filter(**kwargs)
services = []
for package in packages:
services.append(self._package_to_service(package))
@@ -124,7 +126,7 @@ class Controller(object):
tenant_name=tenant))
token = req.headers['X-Auth-Token']
m_cli = muranoclient(token)
m_cli = _get_muranoclient(token, req)
try:
environment_id = db_cf.get_environment_for_space(space_guid)
except AttributeError:
@@ -136,7 +138,7 @@ class Controller(object):
.format(space_id=space_guid,
environment_id=environment_id))
package = db_api.package_get(service_id, req.context)
package = m_cli.packages.get(service_id)
LOG.debug('Adding service {name}'.format(name=package.name))
service = self._make_service(space_guid, package, plan_id)
@@ -179,7 +181,7 @@ class Controller(object):
service_id = service.service_id
environment_id = service.environment_id
token = req.headers['X-Auth-Token']
m_cli = muranoclient(token)
m_cli = _get_muranoclient(token, req)
session_id = create_session(m_cli, environment_id)
m_cli.services.delete(environment_id, '/' + service_id, session_id)
@@ -195,7 +197,7 @@ class Controller(object):
service_id = db_service.service_id
environment_id = db_service.environment_id
token = req.headers['X-Auth-Token']
m_cli = muranoclient(token)
m_cli = _get_muranoclient(token, req)
session_id = create_session(m_cli, environment_id)
env = m_cli.environments.get(environment_id, session_id)
@@ -232,7 +234,7 @@ class Controller(object):
return resp
env_id = service.environment_id
token = req.headers["X-Auth-Token"]
m_cli = muranoclient(token)
m_cli = _get_muranoclient(token, req)
# NOTE(starodubcevna): we can track only environment status. it's
# murano API limitation.
@@ -253,17 +255,37 @@ class Controller(object):
return resp
def muranoclient(token_id):
# TODO(starodubcevna): I guess it can be done better.
endpoint = "http://{murano_host}:{murano_port}".format(
murano_host=CONF.bind_host, murano_port=CONF.bind_port)
insecure = False
def _get_muranoclient(token_id, req):
LOG.debug('murano client created. Murano::Client <Url: {endpoint}'.format(
endpoint=endpoint))
artifacts_client = None
if CONF.engine.packages_service in ['glance', 'glare']:
artifacts_client = _get_glareclient(token_id, req)
return client.Client(1, endpoint=endpoint, token=token_id,
insecure=insecure)
murano_url = CONF.murano.url or req.endpoints.get('murano')
if not murano_url:
LOG.error('No murano url is specified and no "application-catalog" '
'service is registered in keystone.')
return muranoclient.Client(1, murano_url, token=token_id,
artifacts_client=artifacts_client)
def _get_glareclient(token_id, req):
glare_settings = CONF.glare
url = glare_settings.url or req.endpoints.get('glare')
if not url:
LOG.error('No glare url is specified and no "artifact" '
'service is registered in keystone.')
return glare_client.Client(
endpoint=url, token=token_id,
insecure=glare_settings.insecure,
key_file=glare_settings.key_file or None,
ca_file=glare_settings.ca_file or None,
cert_file=glare_settings.cert_file or None,
type_name='murano',
type_version=1)
def create_session(client, environment_id):

View File

@@ -33,15 +33,16 @@ class TestController(base.MuranoTestCase):
'X-Project-Id': 'bar-baz'}
@mock.patch('murano.common.policy.check_is_admin')
@mock.patch('murano.db.catalog.api.package_search')
def test_list(self, mock_db_search, mock_policy):
@mock.patch('murano.api.v1.cloudfoundry.cfapi._get_muranoclient')
def test_list(self, mock_client, mock_policy):
pkg0 = mock.MagicMock()
pkg0.id = 'xxx'
pkg0.name = 'foo'
pkg0.description = 'stub pkg'
mock_db_search.return_value = [pkg0]
mock_client.return_value.packages.filter =\
mock.MagicMock(return_value=[pkg0])
answer = {'services': [{'bindable': True,
'description': pkg0.description,
@@ -59,14 +60,13 @@ class TestController(base.MuranoTestCase):
self.assertEqual(answer, resp)
@mock.patch('murano.common.policy.check_is_admin')
@mock.patch('murano.db.catalog.api.package_get')
@mock.patch('murano.api.v1.cloudfoundry.cfapi.muranoclient')
@mock.patch('murano.api.v1.cloudfoundry.cfapi._get_muranoclient')
@mock.patch('murano.db.services.cf_connections.set_instance_for_service')
@mock.patch('murano.db.services.cf_connections.get_environment_for_space')
@mock.patch('murano.db.services.cf_connections.get_tenant_for_org')
def test_provision_from_scratch(self, mock_get_tenant,
mock_get_environment, mock_is, mock_client,
mock_package, mock_policy):
mock_policy):
body = {"space_guid": "s1-p1",
"organization_guid": "o1-r1",
@@ -78,7 +78,6 @@ class TestController(base.MuranoTestCase):
mock_get_environment.return_value = '555-555'
mock_client.return_value = mock.MagicMock()
mock_package.return_value = mock.MagicMock()
resp = self.controller.provision(self.request, {}, '111-111')
@@ -86,7 +85,7 @@ class TestController(base.MuranoTestCase):
@mock.patch('murano.common.policy.check_is_admin')
@mock.patch('murano.db.catalog.api.package_get')
@mock.patch('murano.api.v1.cloudfoundry.cfapi.muranoclient')
@mock.patch('murano.api.v1.cloudfoundry.cfapi._get_muranoclient')
@mock.patch('murano.db.services.cf_connections.set_instance_for_service')
@mock.patch('murano.db.services.cf_connections.set_environment_for_space')
@mock.patch('murano.db.services.cf_connections.set_tenant_for_org')
@@ -113,7 +112,7 @@ class TestController(base.MuranoTestCase):
self.assertIsInstance(resp, response.Response)
@mock.patch('murano.api.v1.cloudfoundry.cfapi.muranoclient')
@mock.patch('murano.api.v1.cloudfoundry.cfapi._get_muranoclient')
@mock.patch('murano.db.services.cf_connections.get_service_for_instance')
def test_deprovision(self, mock_get_si, mock_client):
service = mock.MagicMock()
@@ -126,7 +125,7 @@ class TestController(base.MuranoTestCase):
self.assertIsInstance(resp, response.Response)
@mock.patch('murano.api.v1.cloudfoundry.cfapi.muranoclient')
@mock.patch('murano.api.v1.cloudfoundry.cfapi._get_muranoclient')
@mock.patch('murano.db.services.cf_connections.get_service_for_instance')
def test_bind(self, mock_get_si, mock_client):
service = mock.MagicMock()