[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:

committed by
Nikolay Starodubtsev

parent
d911efe7a9
commit
1e0097d843
@@ -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)
|
||||
|
@@ -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):
|
||||
|
@@ -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()
|
||||
|
Reference in New Issue
Block a user