Use resource description as default description property
We allow users to provide a description for a resource that shows up in the Heat API. Many resource types also allow users to add descriptions, and these have typically been exposed as properties rather than by trying to read the resource's own description. To prevent the need to duplicate information, use the resource's description as the default for any top-level properties named 'description'. One downside of this is that any changes to the resource description could cause updates to the resource. (However, there are no issues specific to updgrades, because the subsitution is also done on the previous properties.) To guard against the worst of this, only enable this behaviour if the description can be updated without resource replacement. Change-Id: I56560d014a02b5f2ddbc08689d39147fbe4ffca4
This commit is contained in:
parent
6f0f14a3a0
commit
da974ed216
|
@ -284,6 +284,8 @@ resources:
|
|||
default = nodes.literal('', json.dumps(prop.default))
|
||||
para.append(default)
|
||||
definition.append(para)
|
||||
elif prop_key == 'description' and prop.update_allowed:
|
||||
para = nodes.line('', _('Defaults to the resource description'))
|
||||
|
||||
for constraint in prop.constraints:
|
||||
para = nodes.line('', str(constraint))
|
||||
|
|
|
@ -377,7 +377,8 @@ class Property(object):
|
|||
class Properties(collections.Mapping):
|
||||
|
||||
def __init__(self, schema, data, resolver=lambda d: d, parent_name=None,
|
||||
context=None, section=None, translation=None):
|
||||
context=None, section=None, translation=None,
|
||||
rsrc_description=None):
|
||||
self.props = dict((k, Property(s, k, context, path=parent_name))
|
||||
for k, s in schema.items())
|
||||
self.resolve = resolver
|
||||
|
@ -387,6 +388,7 @@ class Properties(collections.Mapping):
|
|||
self.context = context
|
||||
self.translation = (trans.Translation(properties=self)
|
||||
if translation is None else translation)
|
||||
self.rsrc_description = rsrc_description or None
|
||||
|
||||
def update_translation(self, rules, client_resolve=True,
|
||||
ignore_resolve_error=False):
|
||||
|
@ -507,6 +509,10 @@ class Properties(collections.Mapping):
|
|||
translation=self.translation)
|
||||
elif prop.required():
|
||||
raise ValueError(_('Property %s not assigned') % key)
|
||||
elif key == 'description' and prop.schema.update_allowed:
|
||||
return self.rsrc_description
|
||||
else:
|
||||
return None
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self._get_property_value(key)
|
||||
|
|
|
@ -306,7 +306,8 @@ class ResourceDefinition(object):
|
|||
"""
|
||||
props = properties.Properties(schema, self._properties or {},
|
||||
function.resolve, context=context,
|
||||
section=PROPERTIES)
|
||||
section=PROPERTIES,
|
||||
rsrc_description=self.description)
|
||||
props.update_translation(self._rules, self._client_resolve)
|
||||
return props
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ from heat.engine import parameters
|
|||
from heat.engine import plugin_manager
|
||||
from heat.engine import properties
|
||||
from heat.engine import resources
|
||||
from heat.engine import rsrc_defn
|
||||
from heat.engine import support
|
||||
from heat.engine import translation
|
||||
from heat.tests import common
|
||||
|
@ -1651,6 +1652,30 @@ class PropertiesTest(common.HeatTestCase):
|
|||
props_b = properties.Properties(schema, {'foo': 1})
|
||||
self.assertTrue(props_a != props_b)
|
||||
|
||||
def test_description_substitution(self):
|
||||
schema = {
|
||||
'description': properties.Schema('String',
|
||||
update_allowed=True),
|
||||
'not_description': properties.Schema('String',
|
||||
update_allowed=True),
|
||||
}
|
||||
blank_rsrc = rsrc_defn.ResourceDefinition('foo', 'FooResource', {},
|
||||
description='Foo resource')
|
||||
bar_rsrc = rsrc_defn.ResourceDefinition('foo', 'FooResource',
|
||||
{'description': 'bar'},
|
||||
description='Foo resource')
|
||||
|
||||
blank_props = blank_rsrc.properties(schema)
|
||||
self.assertEqual('Foo resource', blank_props['description'])
|
||||
self.assertEqual(None, blank_props['not_description'])
|
||||
|
||||
replace_schema = {'description': properties.Schema('String')}
|
||||
empty_props = blank_rsrc.properties(replace_schema)
|
||||
self.assertEqual(None, empty_props['description'])
|
||||
|
||||
bar_props = bar_rsrc.properties(schema)
|
||||
self.assertEqual('bar', bar_props['description'])
|
||||
|
||||
|
||||
class PropertiesValidationTest(common.HeatTestCase):
|
||||
def test_required(self):
|
||||
|
|
Loading…
Reference in New Issue