Adapt Mixin to OCCI 1.2

OCCI 1.2 has new "depends" and "applies" in the Mixins.
Adapt existing classes and rendering.

Change-Id: I03f46e80640034696bd91d0e2696aafd5d72176b
Partially-Implements: blueprint occi-1-2-core
This commit is contained in:
Enol Fernandez 2016-10-20 11:02:10 +01:00
parent ecaaa3cc37
commit d2c2238394
9 changed files with 51 additions and 6 deletions

View File

@ -16,6 +16,7 @@
from ooi.occi.core import action
from ooi.occi.core import category
from ooi.occi.core import kind
from ooi.occi import helpers
@ -28,15 +29,17 @@ class Mixin(category.Category):
"""
def __init__(self, scheme, term, title, attributes=None, location=None,
related=[], actions=[]):
depends=[], applies=[], actions=[]):
super(Mixin, self).__init__(scheme, term, title, attributes=attributes,
location=location)
helpers.check_type(related, Mixin)
helpers.check_type(depends, Mixin)
helpers.check_type(actions, action.Action)
helpers.check_type(applies, kind.Kind)
self.related = related
self.depends = depends
self.actions = actions
self.applies = applies
def _class_name(self):
return "mixin"

View File

@ -75,4 +75,5 @@ ip_network = mixin.Mixin(helpers.build_scheme("infrastructure/network"),
attributes=attr.AttributeCollection([
"occi.network.address",
"occi.network.gateway",
"occi.network.allocation"]))
"occi.network.allocation"]),
applies=[NetworkResource.kind])

View File

@ -66,4 +66,5 @@ ip_network_interface = mixin.Mixin(
attributes=attr.AttributeCollection([
"occi.networkinterface.address",
"occi.networkinterface.gateway",
"occi.networkinterface.allocation"]))
"occi.networkinterface.allocation"]),
applies=[NetworkInterface.kind])

View File

@ -98,7 +98,14 @@ class ActionRenderer(CategoryRenderer):
class MixinRenderer(CategoryRenderer):
pass
# See OCCI 1.2 text rendering 5.5.2 Mixin Instance Attribute Rendering
# Specifics: only render as "rel" the first "depends" of mixin
def _render_rel(self, env={}):
depends = getattr(self.obj, 'depends', [])
if depends:
d = {"scheme": depends[0].scheme, "term": depends[0].term}
return ['rel="%(scheme)s%(term)s"' % d]
return []
class CollectionRenderer(HeaderRenderer):

View File

@ -27,6 +27,7 @@ class OpenStackOSTemplate(templates.OCCIOSTemplate):
super(OpenStackOSTemplate, self).__init__(
uuid,
name,
depends=[templates.os_tpl],
location=location)
@ -50,6 +51,7 @@ class OpenStackResourceTemplate(templates.OCCIResourceTemplate):
super(OpenStackResourceTemplate, self).__init__(
id,
"Flavor: %s" % name,
depends=[templates.resource_tpl],
attributes=attrs,
location=location)

View File

@ -313,11 +313,13 @@ 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
@ -325,11 +327,13 @@ 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

View File

@ -48,11 +48,14 @@ 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)),

View File

@ -176,6 +176,28 @@ def TestCoreOCCIKindRelations(TestCoreOCCIKind):
class TestCoreOCCIMixin(TestCoreOCCIKind):
obj = mixin.Mixin
def relation_test(self, relation, rel_type):
rel = [rel_type(None, None, None)]
kwargs = {relation: rel}
o = self.obj(*self.args, **kwargs)
for i in (self.args):
self.assertEqual(i, getattr(o, i))
self.assertEqual(rel, getattr(o, relation))
def test_depends(self):
self.relation_test("depends", mixin.Mixin)
def test_applies(self):
self.relation_test("applies", kind.Kind)
def relation_invalid(self, relation):
kwargs = {relation: None}
self.assertRaises(TypeError,
self.obj,
*self.args,
**kwargs)
class TestCoreOCCIAction(BaseTestCoreOCCICategory):
obj = action.Action

View File

@ -38,6 +38,7 @@ 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.depends)
self.assertEqual(location, tpl.location)
@ -63,6 +64,7 @@ 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.depends)
self.assertEqual(cores, tpl.cores)
self.assertEqual(memory, tpl.memory)
self.assertEqual(disk, tpl.disk)