Add notifications for policy, region, service and endpoint.

The endpoint policy extension will need to ensure stale
associations are removed on deletion of these entities. Delete
events are already generated for endpoints. For completeness,
create and update notifcations for these entities have also
been implemented.

Partially implements: bp endpoint-policy
Change-Id: I5de15459f5b577955056ecc166b450963e85bbc9
This commit is contained in:
Henry Nash 2014-08-20 20:53:15 +01:00
parent d486e7663a
commit 8612a54f91
4 changed files with 104 additions and 0 deletions

View File

@ -38,6 +38,10 @@ immutable from a Keystone perspective will not support update operations:
- ``role``
- ``user``
- ``trust`` (immutable resource - no ``updated`` notification)
- ``region``
- ``endpoint``
- ``service``
- ``policy``
The following message template is used to form a message when an operation on a
resource completes successfully:

View File

@ -78,10 +78,13 @@ class Manager(manager.Manager):
"""
_ENDPOINT = 'endpoint'
_SERVICE = 'service'
_REGION = 'region'
def __init__(self):
super(Manager, self).__init__(CONF.catalog.driver)
@notifications.created(_REGION, public=False, result_id_arg_attr='id')
def create_region(self, region_ref):
# Check duplicate ID
try:
@ -110,6 +113,11 @@ class Manager(manager.Manager):
except exception.NotFound:
raise exception.RegionNotFound(region_id=region_id)
@notifications.updated(_REGION, public=False)
def update_region(self, region_id, region_ref):
return self.driver.update_region(region_id, region_ref)
@notifications.deleted(_REGION, public=False)
def delete_region(self, region_id):
try:
ret = self.driver.delete_region(region_id)
@ -122,6 +130,7 @@ class Manager(manager.Manager):
def list_regions(self, hints=None):
return self.driver.list_regions(hints or driver_hints.Hints())
@notifications.created(_SERVICE, public=False)
def create_service(self, service_id, service_ref):
service_ref.setdefault('enabled', True)
return self.driver.create_service(service_id, service_ref)
@ -134,6 +143,11 @@ class Manager(manager.Manager):
except exception.NotFound:
raise exception.ServiceNotFound(service_id=service_id)
@notifications.updated(_SERVICE, public=False)
def update_service(self, service_id, service_ref):
return self.driver.update_service(service_id, service_ref)
@notifications.deleted(_SERVICE, public=False)
def delete_service(self, service_id):
try:
endpoints = self.list_endpoints()
@ -150,6 +164,7 @@ class Manager(manager.Manager):
def list_services(self, hints=None):
return self.driver.list_services(hints or driver_hints.Hints())
@notifications.created(_ENDPOINT, public=False)
def create_endpoint(self, endpoint_id, endpoint_ref):
try:
return self.driver.create_endpoint(endpoint_id, endpoint_ref)
@ -157,6 +172,10 @@ class Manager(manager.Manager):
service_id = endpoint_ref.get('service_id')
raise exception.ServiceNotFound(service_id=service_id)
@notifications.updated(_ENDPOINT, public=False)
def update_endpoint(self, endpoint_id, endpoint_ref):
return self.driver.update_endpoint(endpoint_id, endpoint_ref)
@notifications.deleted(_ENDPOINT, public=False)
def delete_endpoint(self, endpoint_id):
try:

View File

@ -22,6 +22,7 @@ from keystone.common import dependency
from keystone.common import manager
from keystone import config
from keystone import exception
from keystone import notifications
CONF = config.CONF
@ -35,16 +36,22 @@ class Manager(manager.Manager):
dynamically calls the backend.
"""
_POLICY = 'policy'
def __init__(self):
super(Manager, self).__init__(CONF.policy.driver)
@notifications.created(_POLICY, public=False)
def create_policy(self, policy_id, policy):
return self.driver.create_policy(policy_id, policy)
def get_policy(self, policy_id):
try:
return self.driver.get_policy(policy_id)
except exception.NotFound:
raise exception.PolicyNotFound(policy_id=policy_id)
@notifications.updated(_POLICY, public=False)
def update_policy(self, policy_id, policy):
if 'id' in policy and policy_id != policy['id']:
raise exception.ValidationError('Cannot change policy ID')
@ -60,6 +67,7 @@ class Manager(manager.Manager):
# caller.
return self.driver.list_policies()
@notifications.deleted(_POLICY, public=False)
def delete_policy(self, policy_id):
try:
return self.driver.delete_policy(policy_id)

View File

@ -303,6 +303,19 @@ class NotificationsForEntities(test_v3.RestfulTestCase):
self.assignment_api.delete_domain(domain_ref['id'])
self._assert_last_note(domain_ref['id'], DELETED_OPERATION, 'domain')
def test_create_endpoint(self):
endpoint_ref = self.new_endpoint_ref(service_id=self.service_id)
self.catalog_api.create_endpoint(endpoint_ref['id'], endpoint_ref)
self._assert_notify_sent(endpoint_ref['id'], CREATED_OPERATION,
'endpoint', public=False)
def test_update_endpoint(self):
endpoint_ref = self.new_endpoint_ref(service_id=self.service_id)
self.catalog_api.create_endpoint(endpoint_ref['id'], endpoint_ref)
self.catalog_api.update_endpoint(endpoint_ref['id'], endpoint_ref)
self._assert_notify_sent(endpoint_ref['id'], UPDATED_OPERATION,
'endpoint', public=False)
def test_delete_endpoint(self):
endpoint_ref = self.new_endpoint_ref(service_id=self.service_id)
self.catalog_api.create_endpoint(endpoint_ref['id'], endpoint_ref)
@ -310,6 +323,66 @@ class NotificationsForEntities(test_v3.RestfulTestCase):
self._assert_notify_sent(endpoint_ref['id'], DELETED_OPERATION,
'endpoint', public=False)
def test_create_service(self):
service_ref = self.new_service_ref()
self.catalog_api.create_service(service_ref['id'], service_ref)
self._assert_notify_sent(service_ref['id'], CREATED_OPERATION,
'service', public=False)
def test_update_service(self):
service_ref = self.new_service_ref()
self.catalog_api.create_service(service_ref['id'], service_ref)
self.catalog_api.update_service(service_ref['id'], service_ref)
self._assert_notify_sent(service_ref['id'], UPDATED_OPERATION,
'service', public=False)
def test_delete_service(self):
service_ref = self.new_service_ref()
self.catalog_api.create_service(service_ref['id'], service_ref)
self.catalog_api.delete_service(service_ref['id'])
self._assert_notify_sent(service_ref['id'], DELETED_OPERATION,
'service', public=False)
def test_create_region(self):
region_ref = self.new_region_ref()
self.catalog_api.create_region(region_ref)
self._assert_notify_sent(region_ref['id'], CREATED_OPERATION,
'region', public=False)
def test_update_region(self):
region_ref = self.new_region_ref()
self.catalog_api.create_region(region_ref)
self.catalog_api.update_region(region_ref['id'], region_ref)
self._assert_notify_sent(region_ref['id'], UPDATED_OPERATION,
'region', public=False)
def test_delete_region(self):
region_ref = self.new_region_ref()
self.catalog_api.create_region(region_ref)
self.catalog_api.delete_region(region_ref['id'])
self._assert_notify_sent(region_ref['id'], DELETED_OPERATION,
'region', public=False)
def test_create_policy(self):
policy_ref = self.new_policy_ref()
self.policy_api.create_policy(policy_ref['id'], policy_ref)
self._assert_notify_sent(policy_ref['id'], CREATED_OPERATION,
'policy', public=False)
def test_update_policy(self):
policy_ref = self.new_policy_ref()
self.policy_api.create_policy(policy_ref['id'], policy_ref)
self.policy_api.update_policy(policy_ref['id'], policy_ref)
self._assert_notify_sent(policy_ref['id'], UPDATED_OPERATION,
'policy', public=False)
def test_delete_policy(self):
policy_ref = self.new_policy_ref()
self.policy_api.create_policy(policy_ref['id'], policy_ref)
self.policy_api.delete_policy(policy_ref['id'])
self._assert_notify_sent(policy_ref['id'], DELETED_OPERATION,
'policy', public=False)
def test_disable_domain(self):
domain_ref = self.new_domain_ref()
self.assignment_api.create_domain(domain_ref['id'], domain_ref)