Adding attribute schema class for attributes

This patch introduces simple schema class for attributes.
There are two options avaliable for this schema:
 - description
 - support status
It gives ability for adding support status for each attribute.

Change-Id: I46cbf776f315cbe6414005cbee65da1cefdc5f7d
Closes-Bug: #1305584
This commit is contained in:
Sergey Kraynev 2014-04-10 04:33:25 -04:00
parent 635fad8ffb
commit fdc702bc78
3 changed files with 109 additions and 9 deletions

View File

@ -13,23 +13,72 @@
import collections import collections
from heat.engine import constraints as constr
from heat.engine import support
class Schema(constr.Schema):
"""
Simple schema class for attributes.
Schema objects are serialisable to dictionaries following a superset of
the HOT input Parameter schema using dict().
"""
KEYS = (
DESCRIPTION,
) = (
'description',
)
def __init__(self, description=None,
support_status=support.SupportStatus()):
self.description = description
self.support_status = support_status
def __getitem__(self, key):
if key == self.DESCRIPTION:
if self.description is not None:
return self.description
raise KeyError(key)
@classmethod
def from_attribute(cls, schema_dict):
"""
Return a Property Schema corresponding to a Attribute Schema.
"""
if isinstance(schema_dict, cls):
return schema_dict
# it's necessary for supporting old attribute schema format,
# where value is not Schema object
return cls(description=schema_dict)
def schemata(schema):
"""
Return dictionary of Schema objects for given dictionary of schemata.
"""
return dict((n, Schema.from_attribute(s)) for n, s in schema.items())
class Attribute(object): class Attribute(object):
""" """
An Attribute schema. An Attribute schema.
""" """
(DESCRIPTION,) = ('description',) def __init__(self, attr_name, schema):
def __init__(self, attr_name, description):
""" """
Initialise with a name and description. Initialise with a name and description.
:param attr_name: the name of the attribute :param attr_name: the name of the attribute
:param description: attribute description :param schema: attribute schema
""" """
self.name = attr_name self.name = attr_name
self.description = description self.schema = Schema.from_attribute(schema)
def support_status(self):
return self.schema.support_status
def as_output(self, resource_name): def as_output(self, resource_name):
""" """
@ -42,7 +91,7 @@ class Attribute(object):
return { return {
"Value": '{"Fn::GetAtt": ["%s", "%s"]}' % (resource_name, "Value": '{"Fn::GetAtt": ["%s", "%s"]}' % (resource_name,
self.name), self.name),
"Description": self.description "Description": self.schema.description
} }

View File

@ -787,9 +787,9 @@ class EngineService(service.Service):
yield name, dict(schema) yield name, dict(schema)
def attributes_schema(): def attributes_schema():
for schema_item in resource_class.attributes_schema.items(): for name, schema_data in resource_class.attributes_schema.items():
schema = attributes.Attribute(*schema_item) schema = attributes.Schema.from_attribute(schema_data)
yield schema.name, {schema.DESCRIPTION: schema.description} yield name, {schema.DESCRIPTION: schema.description}
return { return {
rpc_api.RES_SCHEMA_RES_TYPE: type_name, rpc_api.RES_SCHEMA_RES_TYPE: type_name,

View File

@ -11,10 +11,61 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import testtools
from heat.engine import attributes from heat.engine import attributes
from heat.engine import resources
from heat.engine import support
from heat.tests import common from heat.tests import common
class AttributeSchemaTest(testtools.TestCase):
def test_schema_all(self):
d = {'description': 'A attribute'}
s = attributes.Schema('A attribute')
self.assertEqual(d, dict(s))
def test_all_resource_schemata(self):
for resource_type in resources.global_env().get_types():
for schema in getattr(resource_type,
'attributes_schema',
{}).itervalues():
attributes.Schema.from_attribute(schema)
def test_from_attribute_new_schema_format(self):
s = attributes.Schema('Test description.')
self.assertIs(s, attributes.Schema.from_attribute(s))
self.assertEqual('Test description.',
attributes.Schema.from_attribute(s).description)
def test_schema_support_status(self):
schema = {
'foo_sup': attributes.Schema(
'Description1'
),
'bar_dep': attributes.Schema(
'Description2',
support_status=support.SupportStatus(
support.DEPRECATED,
'Do not use this ever')
)
}
attrs = attributes.Attributes('test_rsrc', schema, lambda d: d)
self.assertEqual(support.SUPPORTED,
attrs._attributes['foo_sup'].support_status().status)
self.assertEqual(support.DEPRECATED,
attrs._attributes['bar_dep'].support_status().status)
self.assertEqual('Do not use this ever',
attrs._attributes['bar_dep'].support_status().message)
def test_from_attribute_old_schema_format(self):
s = 'Test description.'
self.assertEqual(type(attributes.Schema(s)),
type(attributes.Schema.from_attribute(s)))
self.assertEqual('Test description.',
attributes.Schema.from_attribute(s).description)
class AttributeTest(common.HeatTestCase): class AttributeTest(common.HeatTestCase):
"""Test the Attribute class.""" """Test the Attribute class."""