Follow up - API - Implement /events endpoint

This is a follow up to address the some comments on
https://review.openstack.org/631946.

Change-Id: I9ed789ea5e0921f10085eaf05e871730a8257913
Story: 1304673
This commit is contained in:
Harald Jensås 2019-01-19 23:33:31 +01:00
parent ccf2bb1ea1
commit f4c43f8b26
4 changed files with 29 additions and 13 deletions

View File

@ -51,4 +51,4 @@ class EventsController(pecan.rest.RestController):
cdict = pecan.request.context.to_policy_values()
policy.authorize('baremetal:events:post', cdict, cdict)
for e in evts.events:
LOG.debug("Recieved external event: %s", e)
LOG.debug("Received external event: %s", e)

View File

@ -436,7 +436,8 @@ class EventType(wtypes.UserType):
# Check all keys are valid for network port event
invalid = keys.difference(EventType.mandatory_fields.union(net_keys))
if invalid:
raise exception.Invalid(_('%s are invalid keys') % (invalid))
raise exception.Invalid(_('%s are invalid keys') %
', '.join(invalid))
# Check all mandatory fields for network port event is present
missing = net_mandatory_fields.difference(keys)
@ -446,8 +447,13 @@ class EventType(wtypes.UserType):
# Check all values are of expected type
for key in net_keys:
if value.get(key):
validators[key](value[key])
if key in value:
try:
validators[key](value[key])
except Exception as e:
msg = (_('Event validation failure for %(key)s. '
'%(message)s') % {'key': key, 'message': e})
raise exception.Invalid(msg)
return value
@ -457,6 +463,7 @@ class EventType(wtypes.UserType):
'network.unbind_port': _validate_network_port_event,
'network.delete_port': _validate_network_port_event,
}
valid_events = set(event_validators)
@staticmethod
def validate(value):
@ -473,12 +480,15 @@ class EventType(wtypes.UserType):
# Check all mandatory fields are present
missing = EventType.mandatory_fields.difference(keys)
if missing:
raise exception.Invalid(_('Missing mandatory keys: %s') % missing)
raise exception.Invalid(_('Missing mandatory keys: %s') %
', '.join(missing))
# Check event is a supported event
if value['event'] not in EventType.event_validators:
raise exception.Invalid(_('%s is not a valid event.')
% value['event'])
if value['event'] not in EventType.valid_events:
raise exception.Invalid(
_('%(event)s is not one of valid events: %(valid_events)s.') %
{'event': value['event'],
'valid_events': ', '.join(EventType.valid_events)})
return EventType.event_validators[value['event']](value)

View File

@ -42,6 +42,7 @@ class TestPost(test_api_base.BaseApiTest):
@mock.patch.object(types.EventType, 'event_validators',
{'valid.event': fake_event_validator})
@mock.patch.object(types.EventType, 'valid_events', {'valid.event'})
def test_events(self):
events_dict = {'events': [{'event': 'valid.event'}]}
response = self.post_json('/events', events_dict, headers=self.headers)
@ -51,6 +52,8 @@ class TestPost(test_api_base.BaseApiTest):
{'valid.event1': fake_event_validator,
'valid.event2': fake_event_validator,
'valid.event3': fake_event_validator})
@mock.patch.object(types.EventType, 'valid_events',
{'valid.event1', 'valid.event2', 'valid.event3'})
def test_multiple_events(self):
events_dict = {'events': [{'event': 'valid.event1'},
{'event': 'valid.event2'},
@ -166,6 +169,7 @@ class TestPost(test_api_base.BaseApiTest):
@mock.patch.object(types.EventType, 'event_validators',
{'valid.event': fake_event_validator})
@mock.patch.object(types.EventType, 'valid_events', {'valid.event'})
def test_events_unsupported_api_version(self):
headers = {api_base.Version.string: '1.50'}
events_dict = {'events': [{'event': 'valid.event'}]}

View File

@ -404,16 +404,16 @@ class TestEventType(base.TestCase):
@mock.patch.object(types.EventType, 'event_validators',
{'valid.event': fake_event_validator})
@mock.patch.object(types.EventType, 'valid_events', set(['valid.event']))
def test_simple_event_type(self):
value = {'event': 'valid.event'}
self.assertItemsEqual(value, self.v.validate(value))
@mock.patch.object(types.EventType, 'event_validators',
{'valid.event': fake_event_validator})
@mock.patch.object(types.EventType, 'valid_events', set(['valid.event']))
def test_invalid_event_type(self):
value = {'event': 'invalid.event'}
self.assertRaisesRegex(exception.Invalid, 'invalid.event is not a '
'valid event.',
self.assertRaisesRegex(exception.Invalid,
'invalid.event is not one of valid events:',
self.v.validate, value)
def test_event_missing_madatory_field(self):
@ -441,7 +441,9 @@ class TestEventType(base.TestCase):
'binding:host_id': '22222222-aaaa-bbbb-cccc-555555555555',
'binding:vnic_type': 'baremetal'
}
self.assertRaises(exception.InvalidMAC, self.v.validate, value)
self.assertRaisesRegex(exception.Invalid,
'Event validation failure for mac_address.',
self.v.validate, value)
def test_missing_mandatory_fields_network_port_event(self):
value = {'event': 'network.bind_port',