From 2c6fc7bcd6b280a85488b0f32f8db7c7835f8b5c Mon Sep 17 00:00:00 2001 From: Zane Bitter Date: Wed, 13 Apr 2016 19:49:05 -0400 Subject: [PATCH] Remove support for accessing ResourceDefinition like a dict Heat no longer accesses resource definitions as if they were snippets of a CloudFormation template, but rather uses the APIs of the ResourceDefinition class. The ability to treat this class as a snippet of CloudFormation template has been deprecated for several release cycles to allow third-party plugins to move away from it; this change removes that ability. Change-Id: Ia9c63662438d4c979b897118b3a7a736161bcbca --- heat/engine/rsrc_defn.py | 133 +++-------------------------------- heat/tests/test_rsrc_defn.py | 43 ----------- 2 files changed, 9 insertions(+), 167 deletions(-) diff --git a/heat/engine/rsrc_defn.py b/heat/engine/rsrc_defn.py index 995d043f19..6017d8abb9 100644 --- a/heat/engine/rsrc_defn.py +++ b/heat/engine/rsrc_defn.py @@ -14,7 +14,6 @@ import collections import copy import itertools import operator -import warnings import six @@ -28,15 +27,15 @@ __all__ = ['ResourceDefinition'] @repr_wrapper -class ResourceDefinitionCore(object): +class ResourceDefinition(object): """A definition of a resource, independent of any template format.""" class Diff(object): """A diff between two versions of the same resource definition.""" def __init__(self, old_defn, new_defn): - if not (isinstance(old_defn, ResourceDefinitionCore) and - isinstance(new_defn, ResourceDefinitionCore)): + if not (isinstance(old_defn, ResourceDefinition) and + isinstance(new_defn, ResourceDefinition)): raise TypeError self.old_defn = old_defn @@ -218,8 +217,8 @@ class ResourceDefinitionCore(object): function.dependencies(data, datapath)) explicit_depends = [] if self._depends is None else self._depends - prop_deps = strict_func_deps(self._properties, path(PROPERTIES)) - metadata_deps = strict_func_deps(self._metadata, path(METADATA)) + prop_deps = strict_func_deps(self._properties, path('Properties')) + metadata_deps = strict_func_deps(self._metadata, path('Metadata')) # (ricolin) External resource should not depend on any other resources. # This operation is not allowed for now. @@ -242,7 +241,7 @@ class ResourceDefinitionCore(object): """ return properties.Properties(schema, self._properties or {}, function.resolve, self.name, context, - section=PROPERTIES) + section='Properties') def deletion_policy(self): """Return the deletion policy for the resource. @@ -259,7 +258,7 @@ class ResourceDefinitionCore(object): """ return properties.Properties(schema, self._update_policy or {}, function.resolve, self.name, context, - section=UPDATE_POLICY) + section='UpdatePolicy') def metadata(self): """Return the resource metadata.""" @@ -307,7 +306,7 @@ class ResourceDefinitionCore(object): Return a Diff object that can be used to establish differences between this definition and a previous definition of the same resource. """ - if not isinstance(previous, ResourceDefinitionCore): + if not isinstance(previous, ResourceDefinition): return NotImplemented return self.Diff(previous, self) @@ -320,7 +319,7 @@ class ResourceDefinitionCore(object): ignored, as are the actual values that any included functions resolve to. """ - if not isinstance(other, ResourceDefinitionCore): + if not isinstance(other, ResourceDefinition): return NotImplemented return self.render_hot() == other.render_hot() @@ -362,120 +361,6 @@ class ResourceDefinitionCore(object): return '%(classname)s(%(name)s, %(type)s, %(args)s)' % data -_KEYS = ( - TYPE, PROPERTIES, METADATA, DELETION_POLICY, UPDATE_POLICY, - DEPENDS_ON, DESCRIPTION, -) = ( - 'Type', 'Properties', 'Metadata', 'DeletionPolicy', 'UpdatePolicy', - 'DependsOn', 'Description', -) - - -class ResourceDefinition(ResourceDefinitionCore, collections.Mapping): - """A resource definition that also acts like a cfn template snippet. - - This class exists only for backwards compatibility with existing resource - plugins and unit tests; it is deprecated and will be replaced with - ResourceDefinitionCore, possibly as soon as the Ocata release. - """ - - _deprecation_msg = ( - 'Reading the ResourceDefinition as if it were a snippet of a ' - 'CloudFormation template is deprecated, and the ability to treat it ' - 'as such will be removed in the future. Resource plugins should use ' - 'the ResourceDefinition API to work with the definition of the ' - 'resource instance.') - - def __eq__(self, other): - """Compare this resource definition for equality with another. - - Two resource definitions are considered to be equal if they can be - generated from the same template snippet. The name of the resource is - ignored, as are the actual values that any included functions resolve - to. - - This method can also compare the resource definition to a template - snippet. In this case, two snippets are considered equal if they - compare equal in a dictionary comparison. (Specifically, this means - that intrinsic functions are compared by their results.) This exists - solely to not break existing unit tests. - """ - if not isinstance(other, ResourceDefinitionCore): - if isinstance(other, collections.Mapping): - return dict(self) == other - - return super(ResourceDefinition, self).__eq__(other) - - __hash__ = ResourceDefinitionCore.__hash__ - - def __iter__(self): - """Iterate over the available CFN template keys. - - This is for backwards compatibility with existing code that expects a - parsed-JSON template snippet. - """ - warnings.warn(self._deprecation_msg, DeprecationWarning) - - yield TYPE - if self._properties is not None: - yield PROPERTIES - if self._metadata is not None: - yield METADATA - if self._deletion_policy is not None: - yield DELETION_POLICY - if self._update_policy is not None: - yield UPDATE_POLICY - if self._depends: - yield DEPENDS_ON - if self.description: - yield DESCRIPTION - - def __getitem__(self, key): - """Get the specified item from a CFN template snippet. - - This is for backwards compatibility with existing code that expects a - parsed-JSON template snippet. - """ - warnings.warn(self._deprecation_msg, DeprecationWarning) - - if key == TYPE: - return self.resource_type - elif key == PROPERTIES: - if self._properties is not None: - return self._properties - elif key == METADATA: - if self._metadata is not None: - return self._metadata - elif key == DELETION_POLICY: - if self._deletion_policy is not None: - return self._deletion_policy - elif key == UPDATE_POLICY: - if self._update_policy is not None: - return self._update_policy - elif key == DEPENDS_ON: - if self._depends: - if len(self._depends) == 1: - return self._depends[0] - return self._depends - elif key == DESCRIPTION: - if self.description: - return self.description - - raise KeyError(key) - - def __len__(self): - """Return the number of available CFN template keys. - - This is for backwards compatibility with existing code that expects a - parsed-JSON template snippet. - """ - return len(list(iter(self))) - - def __repr__(self): - """Return a string representation of the resource definition.""" - return 'ResourceDefinition %s' % repr(dict(self)) - - def _hash_data(data): """Return a stable hash value for an arbitrary parsed-JSON data snippet.""" if isinstance(data, function.Function): diff --git a/heat/tests/test_rsrc_defn.py b/heat/tests/test_rsrc_defn.py index fdde5fe101..6905e3b2a3 100644 --- a/heat/tests/test_rsrc_defn.py +++ b/heat/tests/test_rsrc_defn.py @@ -12,7 +12,6 @@ # under the License. import six -import warnings from heat.common import exception from heat.common import template_format @@ -282,45 +281,3 @@ class ResourceDefinitionDiffTest(common.HeatTestCase): self.assertFalse(diff.update_policy_changed()) self.assertFalse(diff.metadata_changed()) self.assertFalse(diff) - - -class ResourceDefinitionSnippetTest(common.HeatTestCase): - scenarios = [ - ('type', - dict( - defn={}, - expected={})), - ('metadata', - dict( - defn={'metadata': {'Foo': 'bar'}}, - expected={'Metadata': {'Foo': 'bar'}})), - ('properties', - dict( - defn={'properties': {'Foo': 'bar'}}, - expected={'Properties': {'Foo': 'bar'}})), - ('deletion_policy', - dict( - defn={'deletion_policy': rsrc_defn.ResourceDefinition.RETAIN}, - expected={'DeletionPolicy': 'Retain'})), - ('update_policy', - dict( - defn={'update_policy': {'Foo': 'bar'}}, - expected={'UpdatePolicy': {'Foo': 'bar'}})) - ] - - def test_resource_snippet(self): - rd = rsrc_defn.ResourceDefinition('rsrc', 'SomeType', **self.defn) - with warnings.catch_warnings(record=True) as ws: - warnings.filterwarnings('always') - - # Work around http://bugs.python.org/issue4180 - getattr(rsrc_defn, '__warningregistry__', {}).clear() - - exp_result = {'Type': 'SomeType'} - exp_result.update(self.expected) - - self.assertEqual(exp_result, rd) - - self.assertTrue(ws) - for warn in ws: - self.assertTrue(issubclass(warn.category, DeprecationWarning))