Merge "Plugin types are not exposed to the client."
This commit is contained in:
commit
80e46b745a
@ -3,5 +3,6 @@
|
||||
"default": "",
|
||||
|
||||
"catalog_index": "role:admin",
|
||||
"catalog_search": ""
|
||||
"catalog_search": "",
|
||||
"catalog_plugins": ""
|
||||
}
|
||||
|
@ -690,6 +690,10 @@ class CatalogSearchRepoProxy(object):
|
||||
self.policy.enforce(self.context, 'catalog_search', {})
|
||||
return self.search_repo.search(*args, **kwargs)
|
||||
|
||||
def plugins_info(self, *args, **kwargs):
|
||||
self.policy.enforce(self.context, 'catalog_plugins', {})
|
||||
return self.search_repo.plugins_info(*args, **kwargs)
|
||||
|
||||
def index(self, *args, **kwargs):
|
||||
self.policy.enforce(self.context, 'catalog_index', {})
|
||||
return self.search_repo.index(*args, **kwargs)
|
||||
|
@ -32,6 +32,7 @@ import functools
|
||||
import os
|
||||
import platform
|
||||
import re
|
||||
import stevedore
|
||||
import subprocess
|
||||
import sys
|
||||
import uuid
|
||||
@ -729,3 +730,10 @@ def stash_conf_values():
|
||||
conf['cert_file'] = CONF.cert_file
|
||||
|
||||
return conf
|
||||
|
||||
|
||||
def get_search_plugins():
|
||||
namespace = 'glance.search.index_backend'
|
||||
ext_manager = stevedore.extension.ExtensionManager(
|
||||
namespace, invoke_on_load=True)
|
||||
return ext_manager.extensions
|
||||
|
@ -17,6 +17,8 @@ import elasticsearch
|
||||
from elasticsearch import helpers
|
||||
from oslo_config import cfg
|
||||
|
||||
from glance.common import utils
|
||||
|
||||
|
||||
search_opts = [
|
||||
cfg.ListOpt('hosts', default=['127.0.0.1:9200'],
|
||||
@ -40,6 +42,8 @@ class CatalogSearchRepo(object):
|
||||
def __init__(self, context, es_api):
|
||||
self.context = context
|
||||
self.es_api = es_api
|
||||
self.plugins = utils.get_search_plugins() or []
|
||||
self.plugins_info_dict = self._get_plugin_info()
|
||||
|
||||
def search(self, index, doc_type, query, fields, offset, limit,
|
||||
ignore_unavailable=True):
|
||||
@ -58,3 +62,16 @@ class CatalogSearchRepo(object):
|
||||
index=default_index,
|
||||
doc_type=default_type,
|
||||
actions=actions)
|
||||
|
||||
def plugins_info(self):
|
||||
return self.plugins_info_dict
|
||||
|
||||
def _get_plugin_info(self):
|
||||
plugin_info = dict()
|
||||
plugin_info['plugins'] = []
|
||||
for plugin in self.plugins:
|
||||
info = dict()
|
||||
info['type'] = plugin.obj.get_document_type()
|
||||
info['index'] = plugin.obj.get_index_name()
|
||||
plugin_info['plugins'].append(info)
|
||||
return plugin_info
|
||||
|
@ -41,6 +41,17 @@ class API(wsgi.Router):
|
||||
conditions={'method': ['PUT', 'DELETE',
|
||||
'PATCH', 'HEAD']})
|
||||
|
||||
mapper.connect('/search/plugins',
|
||||
controller=search_catalog_resource,
|
||||
action='plugins_info',
|
||||
conditions={'method': ['GET']})
|
||||
mapper.connect('/search/plugins',
|
||||
controller=reject_method_resource,
|
||||
action='reject',
|
||||
allowed_methods='GET',
|
||||
conditions={'method': ['POST', 'PUT', 'DELETE',
|
||||
'PATCH', 'HEAD']})
|
||||
|
||||
mapper.connect('/index',
|
||||
controller=search_catalog_resource,
|
||||
action='index',
|
||||
|
@ -18,7 +18,6 @@ import json
|
||||
from oslo.config import cfg
|
||||
from oslo_log import log as logging
|
||||
import six
|
||||
import stevedore
|
||||
import webob.exc
|
||||
|
||||
from glance.api import policy
|
||||
@ -76,6 +75,18 @@ class SearchController(object):
|
||||
LOG.error(utils.exception_to_str(e))
|
||||
raise webob.exc.HTTPInternalServerError()
|
||||
|
||||
def plugins_info(self, req):
|
||||
try:
|
||||
search_repo = self.gateway.get_catalog_search_repo(req.context)
|
||||
return search_repo.plugins_info()
|
||||
except exception.Forbidden as e:
|
||||
raise webob.exc.HTTPForbidden(explanation=e.msg)
|
||||
except exception.NotFound as e:
|
||||
raise webob.exc.HTTPNotFound(explanation=e.msg)
|
||||
except Exception as e:
|
||||
LOG.error(utils.exception_to_str(e))
|
||||
raise webob.exc.HTTPInternalServerError()
|
||||
|
||||
def index(self, req, actions, default_index=None, default_type=None):
|
||||
try:
|
||||
search_repo = self.gateway.get_catalog_search_repo(req.context)
|
||||
@ -351,22 +362,20 @@ class ResponseSerializer(wsgi.JSONResponseSerializer):
|
||||
response.unicode_body = six.text_type(body)
|
||||
response.content_type = 'application/json'
|
||||
|
||||
def plugins_info(self, response, query_result):
|
||||
body = json.dumps(query_result, ensure_ascii=False)
|
||||
response.unicode_body = six.text_type(body)
|
||||
response.content_type = 'application/json'
|
||||
|
||||
def index(self, response, query_result):
|
||||
body = json.dumps(query_result, ensure_ascii=False)
|
||||
response.unicode_body = six.text_type(body)
|
||||
response.content_type = 'application/json'
|
||||
|
||||
|
||||
def get_plugins():
|
||||
namespace = 'glance.search.index_backend'
|
||||
ext_manager = stevedore.extension.ExtensionManager(
|
||||
namespace, invoke_on_load=True)
|
||||
return ext_manager.extensions
|
||||
|
||||
|
||||
def create_resource():
|
||||
"""Search resource factory method"""
|
||||
plugins = get_plugins()
|
||||
plugins = utils.get_search_plugins()
|
||||
deserializer = RequestDeserializer(plugins)
|
||||
serializer = ResponseSerializer()
|
||||
controller = SearchController(plugins)
|
||||
|
@ -18,6 +18,7 @@ from oslo.serialization import jsonutils
|
||||
import webob.exc
|
||||
|
||||
from glance.common import exception
|
||||
from glance.common import utils
|
||||
import glance.gateway
|
||||
import glance.search
|
||||
from glance.search.api.v0_1 import search as search
|
||||
@ -234,12 +235,52 @@ class TestSearchController(base.IsolatedUnitTest):
|
||||
webob.exc.HTTPInternalServerError, self.search_controller.index,
|
||||
request, actions)
|
||||
|
||||
def test_plugins_info(self):
|
||||
request = unit_test_utils.get_fake_request()
|
||||
self.search_controller.plugins_info = mock.Mock(return_value="{}")
|
||||
self.search_controller.plugins_info(request)
|
||||
self.search_controller.plugins_info.assert_called_once_with(request)
|
||||
|
||||
def test_plugins_info_repo(self):
|
||||
request = unit_test_utils.get_fake_request()
|
||||
repo = glance.search.CatalogSearchRepo
|
||||
repo.plugins_info = mock.Mock(return_value="{}")
|
||||
self.search_controller.plugins_info(request)
|
||||
repo.plugins_info.assert_called_once_with()
|
||||
|
||||
def test_plugins_info_forbidden(self):
|
||||
request = unit_test_utils.get_fake_request()
|
||||
repo = glance.search.CatalogSearchRepo
|
||||
repo.plugins_info = mock.Mock(side_effect=exception.Forbidden)
|
||||
|
||||
self.assertRaises(
|
||||
webob.exc.HTTPForbidden, self.search_controller.plugins_info,
|
||||
request)
|
||||
|
||||
def test_plugins_info_not_found(self):
|
||||
request = unit_test_utils.get_fake_request()
|
||||
repo = glance.search.CatalogSearchRepo
|
||||
repo.plugins_info = mock.Mock(side_effect=exception.NotFound)
|
||||
|
||||
self.assertRaises(webob.exc.HTTPNotFound,
|
||||
self.search_controller.plugins_info, request)
|
||||
|
||||
def test_plugins_info_internal_server_error(self):
|
||||
request = unit_test_utils.get_fake_request()
|
||||
repo = glance.search.CatalogSearchRepo
|
||||
repo.plugins_info = mock.Mock(side_effect=Exception)
|
||||
|
||||
self.assertRaises(webob.exc.HTTPInternalServerError,
|
||||
self.search_controller.plugins_info, request)
|
||||
|
||||
|
||||
class TestSearchDeserializer(test_utils.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestSearchDeserializer, self).setUp()
|
||||
self.deserializer = search.RequestDeserializer(search.get_plugins())
|
||||
self.deserializer = search.RequestDeserializer(
|
||||
utils.get_search_plugins()
|
||||
)
|
||||
|
||||
def test_single_index(self):
|
||||
request = unit_test_utils.get_fake_request()
|
||||
@ -411,7 +452,9 @@ class TestIndexDeserializer(test_utils.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestIndexDeserializer, self).setUp()
|
||||
self.deserializer = search.RequestDeserializer(search.get_plugins())
|
||||
self.deserializer = search.RequestDeserializer(
|
||||
utils.get_search_plugins()
|
||||
)
|
||||
|
||||
def test_empty_request(self):
|
||||
request = unit_test_utils.get_fake_request()
|
||||
@ -874,6 +917,39 @@ class TestResponseSerializer(test_utils.BaseTestCase):
|
||||
super(TestResponseSerializer, self).setUp()
|
||||
self.serializer = search.ResponseSerializer()
|
||||
|
||||
def test_plugins_info(self):
|
||||
expected = {
|
||||
"plugins": [
|
||||
{
|
||||
"index": "glance",
|
||||
"type": "image"
|
||||
},
|
||||
{
|
||||
"index": "glance",
|
||||
"type": "metadef"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
request = webob.Request.blank('/v0.1/search')
|
||||
response = webob.Response(request=request)
|
||||
result = {
|
||||
"plugins": [
|
||||
{
|
||||
"index": "glance",
|
||||
"type": "image"
|
||||
},
|
||||
{
|
||||
"index": "glance",
|
||||
"type": "metadef"
|
||||
}
|
||||
]
|
||||
}
|
||||
self.serializer.search(response, result)
|
||||
actual = jsonutils.loads(response.body)
|
||||
self.assertEqual(expected, actual)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
def test_search(self):
|
||||
expected = [{
|
||||
'id': '1',
|
||||
|
Loading…
Reference in New Issue
Block a user