Fixes to allow OVO deserializion of ports/networks

A few fixes required to allow deserialization/serialization
of OVO resources.

* Set shared to False when context is missing for RBAC calculations
* Parse strings received from json into netaddr objects

Partially-Implements: blueprint push-notifications
Change-Id: I1609014d6100a0c410c66d159f9e682d8aa3e7ba
This commit is contained in:
Kevin Benton 2017-01-22 16:47:53 -08:00
parent 7915b4a2ea
commit 28d2e699b5
4 changed files with 40 additions and 8 deletions

View File

@ -24,6 +24,7 @@ import six
from neutron._i18n import _
from neutron.common import constants
from neutron.common import utils
from neutron.objects import exceptions as o_exc
from neutron.plugins.common import constants as plugin_constants
@ -205,6 +206,14 @@ class MACAddress(obj_fields.FieldType):
def to_primitive(obj, attr, value):
return str(value)
@staticmethod
def from_primitive(obj, attr, value):
try:
return utils.AuthenticEUI(value)
except Exception:
msg = _("Field value %s is not a netaddr.EUI") % value
raise ValueError(msg)
class MACAddressField(obj_fields.AutoTypedField):
AUTO_TYPE = MACAddress()
@ -264,6 +273,14 @@ class IPNetwork(obj_fields.FieldType):
def to_primitive(obj, attr, value):
return str(value)
@staticmethod
def from_primitive(obj, attr, value):
try:
return utils.AuthenticIPNetwork(value)
except Exception:
msg = _("Field value %s is not a netaddr.IPNetwork") % value
raise ValueError(msg)
class IPNetworkField(obj_fields.AutoTypedField):
AUTO_TYPE = IPNetwork()

View File

@ -254,9 +254,14 @@ def _create_hook(self, orig_create):
def _to_dict_hook(self, to_dict_orig):
dct = to_dict_orig(self)
dct['shared'] = self.is_shared_with_tenant(self.obj_context,
self.id,
self.obj_context.tenant_id)
if self.obj_context:
dct['shared'] = self.is_shared_with_tenant(self.obj_context,
self.id,
self.obj_context.tenant_id)
else:
# most OVO objects on an agent will not have a context set on the
# object because they will be generated from obj_from_primitive.
dct['shared'] = False
return dct

View File

@ -52,8 +52,11 @@ class TestField(object):
_context = 'context'
for prim_val, out_val in self.from_primitive_values:
self.assertEqual(out_val, self.field.from_primitive(
ObjectLikeThing, 'attr', prim_val))
from_prim = self.field.from_primitive(ObjectLikeThing, 'attr',
prim_val)
self.assertEqual(out_val, from_prim)
# ensure it's coercable for sanity
self.field.coerce('obj', 'attr', from_prim)
@abc.abstractmethod
def test_stringify(self):
@ -117,8 +120,10 @@ class MACAddressFieldTest(test_base.BaseTestCase, TestField):
# if they represent a valid MAC address
tools.get_random_mac(),
]
self.to_primitive_values = self.coerce_good_values
self.from_primitive_values = self.coerce_good_values
self.to_primitive_values = ((a1, str(a2))
for a1, a2 in self.coerce_good_values)
self.from_primitive_values = ((a2, a1)
for a1, a2 in self.to_primitive_values)
def test_stringify(self):
for in_val, out_val in self.coerce_good_values:
@ -142,7 +147,8 @@ class IPNetworkFieldTest(test_base.BaseTestCase, TestField):
]
self.to_primitive_values = ((a1, str(a2))
for a1, a2 in self.coerce_good_values)
self.from_primitive_values = self.coerce_good_values
self.from_primitive_values = ((a2, a1)
for a1, a2 in self.to_primitive_values)
def test_stringify(self):
for in_val, out_val in self.coerce_good_values:

View File

@ -281,6 +281,10 @@ class RbacNeutronDbObjectTestCase(test_base.BaseObjectIfaceTestCase,
attach_rbac_mock.assert_called_with(
obj_id, test_neutron_obj.obj_context.tenant_id)
def test_shared_field_false_without_context(self):
test_neutron_obj = self._test_class()
self.assertFalse(test_neutron_obj.to_dict()['shared'])
@mock.patch.object(_test_class, 'attach_rbac')
@mock.patch.object(obj_db_api, 'get_object',
return_value=['fake_rbac_policy'])