diff --git a/heat/api/openstack/v1/stacks.py b/heat/api/openstack/v1/stacks.py index ab856a25a2..0cb7f8000d 100644 --- a/heat/api/openstack/v1/stacks.py +++ b/heat/api/openstack/v1/stacks.py @@ -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): diff --git a/heat/engine/environment.py b/heat/engine/environment.py index 5331bf89e2..d6ac29bcfe 100644 --- a/heat/engine/environment.py +++ b/heat/engine/environment.py @@ -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): diff --git a/heat/engine/resource.py b/heat/engine/resource.py index 9ec3c519ad..6684570380 100644 --- a/heat/engine/resource.py +++ b/heat/engine/resource.py @@ -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): diff --git a/heat/engine/service.py b/heat/engine/service.py index acc124cd54..f2c398ffe1 100644 --- a/heat/engine/service.py +++ b/heat/engine/service.py @@ -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): """ diff --git a/heat/rpc/client.py b/heat/rpc/client.py index beadf97ef1..7ab8e05677 100644 --- a/heat/rpc/client.py +++ b/heat/rpc/client.py @@ -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): """ diff --git a/heat/tests/test_api_openstack_v1.py b/heat/tests/test_api_openstack_v1.py index 4fdb9a1607..0b125255ed 100644 --- a/heat/tests/test_api_openstack_v1.py +++ b/heat/tests/test_api_openstack_v1.py @@ -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() diff --git a/heat/tests/test_engine_service.py b/heat/tests/test_engine_service.py index 99eec74af6..b18023a78d 100644 --- a/heat/tests/test_engine_service.py +++ b/heat/tests/test_engine_service.py @@ -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 = { diff --git a/heat/tests/test_rpc_client.py b/heat/tests/test_rpc_client.py index 8e99f91230..c8fef7cd43 100644 --- a/heat/tests/test_rpc_client.py +++ b/heat/tests/test_rpc_client.py @@ -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")