Adapt Kind to OCCI 1.2
OCCI 1.2 uses "parent" instead of related in the Kind class. Adapt existing classes and rendering. Partially-Implements: blueprint occi-1-2-core Change-Id: I7f3c5ff57bf01c9a20991a72387c63056256251f
This commit is contained in:
committed by
Enol Fernandez
parent
75c210ce05
commit
ecaaa3cc37
@@ -28,14 +28,14 @@ class Kind(category.Category):
|
||||
"""
|
||||
|
||||
def __init__(self, scheme, term, title, attributes=None, location=None,
|
||||
related=[], actions=[]):
|
||||
parent=None, actions=[]):
|
||||
super(Kind, self).__init__(scheme, term, title, attributes=attributes,
|
||||
location=location)
|
||||
|
||||
helpers.check_type(related, Kind)
|
||||
helpers.check_single_type(parent, Kind)
|
||||
helpers.check_type(actions, action.Action)
|
||||
|
||||
self.related = related
|
||||
self.parent = parent
|
||||
self.actions = actions
|
||||
|
||||
def _class_name(self):
|
||||
|
||||
@@ -37,7 +37,7 @@ class Resource(entity.Entity):
|
||||
|
||||
kind = kind.Kind(helpers.build_scheme('core'), 'resource',
|
||||
'resource', attributes, 'resource/',
|
||||
related=[entity.Entity.kind])
|
||||
parent=entity.Entity.kind)
|
||||
|
||||
def __init__(self, title, mixins, id=None, summary=None):
|
||||
super(Resource, self).__init__(title, mixins, id=id)
|
||||
|
||||
@@ -24,6 +24,11 @@ def build_scheme(category, prefix=_PREFIX):
|
||||
return '%s#' % scheme
|
||||
|
||||
|
||||
def check_single_type(obj, obj_type):
|
||||
if obj is not None and not isinstance(obj, obj_type):
|
||||
raise TypeError('object must be of class %s' % obj_type)
|
||||
|
||||
|
||||
def check_type(obj_list, obj_type):
|
||||
if not isinstance(obj_list, (list, tuple)):
|
||||
raise TypeError('must be a list or tuple of objects')
|
||||
|
||||
@@ -44,7 +44,7 @@ class ComputeResource(resource.Resource):
|
||||
kind = kind.Kind(helpers.build_scheme('infrastructure'), 'compute',
|
||||
'compute resource', attributes, 'compute/',
|
||||
actions=actions,
|
||||
related=[resource.Resource.kind])
|
||||
parent=resource.Resource.kind)
|
||||
|
||||
def __init__(self, title, summary=None, id=None, architecture=None,
|
||||
cores=None, hostname=None, speed=None, memory=None,
|
||||
|
||||
@@ -36,7 +36,7 @@ class NetworkResource(resource.Resource):
|
||||
kind = kind.Kind(helpers.build_scheme('infrastructure'), 'network',
|
||||
'network resource', attributes, 'network/',
|
||||
actions=actions,
|
||||
related=[resource.Resource.kind])
|
||||
parent=resource.Resource.kind)
|
||||
|
||||
def __init__(self, title, summary=None, id=None, vlan=None, label=None,
|
||||
state=None, mixins=[]):
|
||||
|
||||
@@ -28,7 +28,7 @@ class NetworkInterface(link.Link):
|
||||
kind = kind.Kind(helpers.build_scheme('infrastructure'),
|
||||
'networkinterface', 'network link resource',
|
||||
attributes, 'networklink/',
|
||||
related=[link.Link.kind])
|
||||
parent=link.Link.kind)
|
||||
|
||||
def __init__(self, mixins, source, target, id=None, interface=None,
|
||||
mac=None, state=None):
|
||||
|
||||
@@ -43,7 +43,7 @@ class StorageResource(resource.Resource):
|
||||
kind = kind.Kind(helpers.build_scheme('infrastructure'), 'storage',
|
||||
'storage resource', attributes, 'storage/',
|
||||
actions=actions,
|
||||
related=[resource.Resource.kind])
|
||||
parent=resource.Resource.kind)
|
||||
|
||||
def __init__(self, title, summary=None, id=None, size=None, state=None):
|
||||
mixins = []
|
||||
|
||||
@@ -26,7 +26,7 @@ class StorageLink(link.Link):
|
||||
"occi.storagelink.state"])
|
||||
kind = kind.Kind(helpers.build_scheme('infrastructure'), 'storagelink',
|
||||
'storage link resource', attributes, 'storagelink/',
|
||||
related=[link.Link.kind])
|
||||
parent=link.Link.kind)
|
||||
|
||||
def __init__(self, source, target, deviceid=None, mountpoint=None,
|
||||
state=None):
|
||||
|
||||
@@ -49,6 +49,9 @@ class CategoryRenderer(HeaderRenderer):
|
||||
return ['location="%s"' % loc]
|
||||
return []
|
||||
|
||||
def _render_rel(self, env={}):
|
||||
return []
|
||||
|
||||
def render(self, env={}):
|
||||
d = {
|
||||
"term": self.obj.term,
|
||||
@@ -59,16 +62,19 @@ class CategoryRenderer(HeaderRenderer):
|
||||
ret = []
|
||||
ret.append(('%(term)s; scheme="%(scheme)s"; class="%(class)s"; '
|
||||
'title="%(title)s"') % d)
|
||||
for rel in getattr(self.obj, 'related', []):
|
||||
d = {"scheme": rel.scheme, "term": rel.term}
|
||||
ret.append('rel="%(scheme)s%(term)s"' % d)
|
||||
ret.extend(self._render_rel(env))
|
||||
ret.extend(self._render_location(env))
|
||||
# FIXME(enolfc): missing attributes and actions
|
||||
return [('Category', "; ".join(ret))]
|
||||
|
||||
|
||||
class KindRenderer(CategoryRenderer):
|
||||
pass
|
||||
def _render_rel(self, env={}):
|
||||
parent = getattr(self.obj, 'parent', None)
|
||||
if parent is not None:
|
||||
d = {"scheme": parent.scheme, "term": parent.term}
|
||||
return ['rel="%(scheme)s%(term)s"' % d]
|
||||
return []
|
||||
|
||||
|
||||
class ActionRenderer(CategoryRenderer):
|
||||
|
||||
@@ -27,7 +27,6 @@ class OpenStackOSTemplate(templates.OCCIOSTemplate):
|
||||
super(OpenStackOSTemplate, self).__init__(
|
||||
uuid,
|
||||
name,
|
||||
related=[templates.os_tpl],
|
||||
location=location)
|
||||
|
||||
|
||||
@@ -51,7 +50,6 @@ class OpenStackResourceTemplate(templates.OCCIResourceTemplate):
|
||||
super(OpenStackResourceTemplate, self).__init__(
|
||||
id,
|
||||
"Flavor: %s" % name,
|
||||
related=[templates.resource_tpl],
|
||||
attributes=attrs,
|
||||
location=location)
|
||||
|
||||
|
||||
@@ -313,13 +313,11 @@ def fake_query_results():
|
||||
'bar; '
|
||||
'scheme="http://schemas.openstack.org/template/os#"; '
|
||||
'class="mixin"; title="bar"; '
|
||||
'rel="http://schemas.ogf.org/occi/infrastructure#os_tpl"; '
|
||||
'location="%s/os_tpl/bar"' % application_url)
|
||||
cats.append(
|
||||
'foo; '
|
||||
'scheme="http://schemas.openstack.org/template/os#"; '
|
||||
'class="mixin"; title="foo"; '
|
||||
'rel="http://schemas.ogf.org/occi/infrastructure#os_tpl"; '
|
||||
'location="%s/os_tpl/foo"' % application_url)
|
||||
|
||||
# OpenStack Flavors
|
||||
@@ -327,13 +325,11 @@ def fake_query_results():
|
||||
'1; '
|
||||
'scheme="http://schemas.openstack.org/template/resource#"; '
|
||||
'class="mixin"; title="Flavor: foo"; '
|
||||
'rel="http://schemas.ogf.org/occi/infrastructure#resource_tpl"; '
|
||||
'location="%s/resource_tpl/1"' % application_url)
|
||||
cats.append(
|
||||
'2; '
|
||||
'scheme="http://schemas.openstack.org/template/resource#"; '
|
||||
'class="mixin"; title="Flavor: bar"; '
|
||||
'rel="http://schemas.ogf.org/occi/infrastructure#resource_tpl"; '
|
||||
'location="%s/resource_tpl/2"' % application_url)
|
||||
|
||||
# OCCI Infrastructure Network
|
||||
|
||||
@@ -48,14 +48,11 @@ def build_occi_server(server):
|
||||
cats.append('%s; '
|
||||
'scheme="http://schemas.openstack.org/template/os#"; '
|
||||
'class="mixin"; title="%s"; '
|
||||
'rel="http://schemas.ogf.org/occi/infrastructure#os_tpl"; '
|
||||
'location="%s/os_tpl/%s"'
|
||||
% (image_id, image_id, app_url, image_id)),
|
||||
cats.append('%s; '
|
||||
'scheme="http://schemas.openstack.org/template/resource#"; '
|
||||
'class="mixin"; title="Flavor: %s"; '
|
||||
'rel="http://schemas.ogf.org/occi/infrastructure#resource_tpl"'
|
||||
'; '
|
||||
'location="%s/resource_tpl/%s"'
|
||||
% (flavor_id, flavor_name, app_url, flavor_id)),
|
||||
|
||||
|
||||
@@ -155,35 +155,22 @@ class TestCoreOCCIKind(BaseTestCoreOCCICategory):
|
||||
*self.args,
|
||||
actions=actions)
|
||||
|
||||
def test_related(self):
|
||||
related = [self.obj(None, None, None)]
|
||||
kind = self.obj(*self.args, related=related)
|
||||
|
||||
def TestCoreOCCIKindRelations(TestCoreOCCIKind):
|
||||
def test_parent(self):
|
||||
parent = self.obj(None, None, None)
|
||||
kind = self.obj(*self.args, parent=parent)
|
||||
|
||||
for i in (self.args):
|
||||
self.assertEqual(i, getattr(kind, i))
|
||||
self.assertEqual(related, kind.related)
|
||||
self.assertEqual(parent, kind.parent)
|
||||
|
||||
def test_related_empty(self):
|
||||
related = []
|
||||
kind = self.obj(*self.args, related=related)
|
||||
|
||||
for i in (self.args):
|
||||
self.assertEqual(i, getattr(kind, i))
|
||||
self.assertEqual(related, kind.related)
|
||||
|
||||
def test_related_invalid(self):
|
||||
related = None
|
||||
def test_parent_invalid(self):
|
||||
parent = None
|
||||
self.assertRaises(TypeError,
|
||||
self.obj,
|
||||
*self.args,
|
||||
related=related)
|
||||
|
||||
def test_related_invalid_list(self):
|
||||
related = [None]
|
||||
self.assertRaises(TypeError,
|
||||
self.obj,
|
||||
*self.args,
|
||||
related=related)
|
||||
parent=parent)
|
||||
|
||||
|
||||
class TestCoreOCCIMixin(TestCoreOCCIKind):
|
||||
@@ -199,7 +186,7 @@ class TestCoreOCCIEntity(base.TestCase):
|
||||
e = entity.Entity
|
||||
self.assertIn("occi.core.id", e.attributes)
|
||||
self.assertIn("occi.core.title", e.attributes)
|
||||
self.assertEqual([], e.kind.related)
|
||||
self.assertIsNone(e.kind.parent)
|
||||
# TODO(aloga): We need to check that the attributes are actually set
|
||||
# after we get an object
|
||||
|
||||
@@ -241,7 +228,7 @@ class TestCoreOCCIResource(base.TestCase):
|
||||
self.assertIn("occi.core.id", r.attributes)
|
||||
self.assertIn("occi.core.summary", r.attributes)
|
||||
self.assertIn("occi.core.title", r.attributes)
|
||||
self.assertIn(entity.Entity.kind, r.kind.related)
|
||||
self.assertEqual(entity.Entity.kind, r.kind.parent)
|
||||
# TODO(aloga): We need to check that the attributes are actually set
|
||||
# after we get an object
|
||||
|
||||
@@ -253,7 +240,7 @@ class TestCoreOCCIResource(base.TestCase):
|
||||
self.assertEqual("bar", r.title)
|
||||
self.assertEqual("baz", r.summary)
|
||||
self.assertEqual(id, r.id)
|
||||
self.assertIn(entity.Entity.kind, r.kind.related)
|
||||
self.assertEqual(entity.Entity.kind, r.kind.parent)
|
||||
r.summary = "bazonk"
|
||||
self.assertEqual("bazonk", r.summary)
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ class TestOCCICompute(base.TestCase):
|
||||
self.assertIn("occi.compute.memory", c.attributes)
|
||||
self.assertIn("occi.compute.speed", c.attributes)
|
||||
self.assertIn("occi.compute.state", c.attributes)
|
||||
self.assertIn(resource.Resource.kind, c.kind.related)
|
||||
self.assertEqual(resource.Resource.kind, c.kind.parent)
|
||||
self.assertEqual(c.kind.location, "compute/")
|
||||
# TODO(aloga): We need to check that the attributes are actually set
|
||||
# after we get an object (we have to check this for this but also for
|
||||
@@ -106,7 +106,7 @@ class TestOCCIStorage(base.TestCase):
|
||||
self.assertIn("occi.core.title", s.attributes)
|
||||
self.assertIn("occi.storage.size", s.attributes)
|
||||
self.assertIn("occi.storage.state", s.attributes)
|
||||
self.assertIn(resource.Resource.kind, s.kind.related)
|
||||
self.assertEqual(resource.Resource.kind, s.kind.parent)
|
||||
self.assertEqual(s.kind.location, "storage/")
|
||||
# TODO(aloga): We need to check that the attributes are actually set
|
||||
# after we get an object (we have to check this for this but also for
|
||||
@@ -144,7 +144,7 @@ class TestOCCIStorageLink(base.TestCase):
|
||||
self.assertIn("occi.storagelink.mountpoint", s.attributes)
|
||||
self.assertIn("occi.storagelink.deviceid", s.attributes)
|
||||
self.assertIn("occi.storagelink.state", s.attributes)
|
||||
self.assertIn(link.Link.kind, s.kind.related)
|
||||
self.assertEqual(link.Link.kind, s.kind.parent)
|
||||
self.assertEqual(s.kind.location, "storagelink/")
|
||||
|
||||
def test_storagelink(self):
|
||||
@@ -217,7 +217,7 @@ class TestOCCINetwork(base.TestCase):
|
||||
self.assertIn("occi.network.vlan", n.attributes)
|
||||
self.assertIn("occi.network.label", n.attributes)
|
||||
self.assertIn("occi.network.state", n.attributes)
|
||||
self.assertIn(resource.Resource.kind, n.kind.related)
|
||||
self.assertEqual(resource.Resource.kind, n.kind.parent)
|
||||
self.assertEqual(n.kind.location, "network/")
|
||||
# TODO(aloga): We need to check that the attributes are actually set
|
||||
# after we get an object (we have to check this for this but also for
|
||||
@@ -283,7 +283,7 @@ class TestOCCINetworkInterface(base.TestCase):
|
||||
self.assertIn("occi.networkinterface.interface", l.attributes)
|
||||
self.assertIn("occi.networkinterface.mac", l.attributes)
|
||||
self.assertIn("occi.networkinterface.state", l.attributes)
|
||||
self.assertIn(link.Link.kind, l.kind.related)
|
||||
self.assertEqual(link.Link.kind, l.kind.parent)
|
||||
self.assertEqual(l.kind.location, "networklink/")
|
||||
|
||||
def test_networkinterface(self):
|
||||
|
||||
@@ -38,7 +38,6 @@ class TestOpenStackOSTemplate(base.TestCase):
|
||||
self.assertEqual(id, tpl.term)
|
||||
self.assertEqual(title, tpl.title)
|
||||
self.assertTrue(tpl.scheme.startswith(helpers._PREFIX))
|
||||
self.assertIn(occi_templates.os_tpl, tpl.related)
|
||||
self.assertEqual(location, tpl.location)
|
||||
|
||||
|
||||
@@ -64,7 +63,6 @@ class TestOpenStackResourceTemplate(base.TestCase):
|
||||
self.assertEqual(id, tpl.term)
|
||||
self.assertEqual("Flavor: %s" % name, tpl.title)
|
||||
self.assertTrue(tpl.scheme.startswith(helpers._PREFIX))
|
||||
self.assertIn(occi_templates.resource_tpl, tpl.related)
|
||||
self.assertEqual(cores, tpl.cores)
|
||||
self.assertEqual(memory, tpl.memory)
|
||||
self.assertEqual(disk, tpl.disk)
|
||||
|
||||
@@ -19,7 +19,7 @@ import collections
|
||||
from ooi.occi.rendering import headers as header_rendering
|
||||
from ooi.occi.rendering import text as text_rendering
|
||||
from ooi.occi.rendering import urilist as urilist_rendering
|
||||
from ooi.wsgi import utils
|
||||
from ooi import utils
|
||||
|
||||
|
||||
_MEDIA_TYPE_MAP = collections.OrderedDict([
|
||||
|
||||
Reference in New Issue
Block a user