Filter resource types by support status

Now heat resources haven't support status. We want service providers
to have a way to assign support status metadata to resources. And
then user should be able to filter resource types by support status
when quering the api for resource types.

Add processing of query parameter support_status to list_resource_types
function in heat/api to filter resources by. List_resource_types
returns a list of resources with a certain status or a list of all
resource types by default.

Add filtering on the server.

Add changes to tests:
- test_rpc_client.py
- test_api_openstack_v1.py
- test_engine_service.py

Implements bp filter-resources-by-support

Change-Id: I719c0d690886153adb698aea4695ddd526e7a4af
This commit is contained in:
Julia Varlamova 2013-11-20 17:27:42 +04:00
parent ef8b312df8
commit 1cb1c00fb6
8 changed files with 44 additions and 20 deletions

View File

@ -324,7 +324,10 @@ class StackController(object):
"""
Returns a list of valid resource types that may be used in a template.
"""
return {'resource_types': self.engine.list_resource_types(req.context)}
support_status = req.params.get('support_status', None)
return {
'resource_types':
self.engine.list_resource_types(req.context, support_status)}
@util.tenant_local
def resource_schema(self, req, type_name):

View File

@ -303,13 +303,18 @@ class ResourceRegistry(object):
return _as_dict(self._registry)
def get_types(self):
def get_types(self, support_status):
'''Return a list of valid resource types.'''
def is_plugin(key):
if isinstance(self._registry[key], ClassResourceInfo):
return True
return False
return [k for k in self._registry if is_plugin(k)]
return isinstance(self._registry[key], ClassResourceInfo)
def status_matches(cls):
return support_status is None or \
cls.value.support_status.status == support_status.encode()
return [name for name, cls in self._registry.iteritems()
if is_plugin(name) and status_matches(cls)]
SECTIONS = (PARAMETERS, RESOURCE_REGISTRY) = \
@ -358,8 +363,8 @@ class Environment(object):
def get_class(self, resource_type, resource_name=None):
return self.registry.get_class(resource_type, resource_name)
def get_types(self):
return self.registry.get_types()
def get_types(self, support_status=None):
return self.registry.get_types(support_status)
def get_resource_info(self, resource_type, resource_name=None,
registry_type=None):

View File

@ -37,9 +37,9 @@ logger = logging.getLogger(__name__)
DELETION_POLICY = (DELETE, RETAIN, SNAPSHOT) = ('Delete', 'Retain', 'Snapshot')
def get_types():
'''Return an iterator over the list of valid resource types.'''
return iter(resources.global_env().get_types())
def get_types(support_status):
'''Return a list of valid resource types.'''
return resources.global_env().get_types(support_status)
def get_class(resource_type, resource_name=None):

View File

@ -86,6 +86,9 @@ class EngineService(service.Service):
are also dynamically added and will be named as keyword arguments
by the RPC caller.
"""
RPC_API_VERSION = '1.1'
def __init__(self, host, topic, manager=None):
super(EngineService, self).__init__(host, topic)
# stg == "Stack Thread Groups"
@ -529,13 +532,13 @@ class EngineService(service.Service):
self._start_thread_with_lock(cnxt, stack, stack.delete)
return stack_info
def list_resource_types(self, cnxt):
def list_resource_types(self, cnxt, support_status=None):
"""
Get a list of supported resource types.
:param cnxt: RPC context.
"""
return list(resource.get_types())
return resource.get_types(support_status)
def resource_schema(self, cnxt, type_name):
"""

View File

@ -29,6 +29,7 @@ class EngineClient(heat.openstack.common.rpc.proxy.RpcProxy):
API version history::
1.0 - Initial version.
1.1 - Add support_status argument to list_resource_types()
'''
BASE_RPC_API_VERSION = '1.0'
@ -185,13 +186,15 @@ class EngineClient(heat.openstack.common.rpc.proxy.RpcProxy):
self.make_msg('abandon_stack',
stack_identity=stack_identity))
def list_resource_types(self, ctxt):
def list_resource_types(self, ctxt, support_status=None):
"""
Get a list of valid resource types.
:param ctxt: RPC context.
"""
return self.call(ctxt, self.make_msg('list_resource_types'))
return self.call(ctxt, self.make_msg('list_resource_types',
support_status=support_status),
version='1.1')
def resource_schema(self, ctxt, type_name):
"""

View File

@ -1272,8 +1272,8 @@ class StackControllerTest(ControllerTest, HeatTestCase):
rpc.call(req.context, self.topic,
{'namespace': None,
'method': 'list_resource_types',
'args': {},
'version': self.api_version},
'args': {'support_status': None},
'version': '1.1'},
None).AndReturn(engine_response)
self.m.ReplayAll()
response = self.controller.list_resource_types(req,
@ -1289,8 +1289,8 @@ class StackControllerTest(ControllerTest, HeatTestCase):
rpc.call(req.context, self.topic,
{'namespace': None,
'method': 'list_resource_types',
'args': {},
'version': self.api_version},
'args': {'support_status': None},
'version': '1.1'},
None).AndRaise(to_remote_error(error))
self.m.ReplayAll()

View File

@ -1296,6 +1296,15 @@ class StackServiceTest(HeatTestCase):
self.assertTrue(isinstance(resources, list))
self.assertIn('AWS::EC2::Instance', resources)
def test_list_resource_types_deprecated(self):
resources = self.eng.list_resource_types(self.ctx, "DEPRECATED")
self.assertEqual(['OS::Neutron::RouterGateway'], resources)
def test_list_resource_types_supported(self):
resources = self.eng.list_resource_types(self.ctx, "SUPPORTED")
self.assertNotIn(['OS::Neutron::RouterGateway'], resources)
self.assertIn('AWS::EC2::Instance', resources)
def test_resource_schema(self):
type_name = 'ResourceWithPropsType'
expected = {

View File

@ -131,7 +131,8 @@ class EngineRpcAPITestCase(testtools.TestCase):
template={u'Foo': u'bar'})
def test_list_resource_types(self):
self._test_engine_api('list_resource_types', 'call')
self._test_engine_api('list_resource_types', 'call',
support_status=None, version='1.1')
def test_resource_schema(self):
self._test_engine_api('resource_schema', 'call', type_name="TYPE")