Allow replacing service implementation

Some clouds are offering their own incompatible implementation of system 
services. While with add_service we can add new implementation of the 
service, we can not replace system-ones. So let's allow deleting service 
to be able to have a custom service implementation in SDK.

Change-Id: I55ef310d114702e5dc98a237fc1d8d130c09c5e1
This commit is contained in:
Artem Goncharov 2019-03-29 15:35:26 +01:00
parent 6570148534
commit 3fe09b84e9
2 changed files with 36 additions and 1 deletions

View File

@ -202,4 +202,13 @@ class ServiceDescription(object):
raise AttributeError('Service Descriptors cannot be set')
def __delete__(self, instance):
raise AttributeError('Service Descriptors cannot be deleted')
# NOTE(gtema) Some clouds are not very fast (or interested at all)
# in bringing their changes upstream. If there are incompatible changes
# downstream we need to allow overriding default implementation by
# deleting service_type attribute of the connection and then
# "add_service" with new implementation.
# This is implemented explicitely not very comfortable to use
# to show how bad it is not to contribute changes back
for service_type in self.all_types:
if service_type in instance._proxies:
del instance._proxies[service_type]

View File

@ -308,3 +308,29 @@ class TestNewService(base.TestCase):
'openstack.tests.unit.fake.v2._proxy',
conn.fake.__class__.__module__)
self.assertFalse(conn.fake.dummy())
def test_replace_system_service(self):
self.use_keystone_v3(catalog='catalog-v3-fake-v2.json')
conn = self.cloud
# delete native dns service
delattr(conn, 'dns')
self.register_uris([
dict(method='GET',
uri='https://fake.example.com',
status_code=404),
dict(method='GET',
uri='https://fake.example.com/v2/',
status_code=404),
dict(method='GET',
uri=self.get_mock_url('fake'),
status_code=404),
])
# add fake service with alias 'DNS'
service = fake_service.FakeService('fake', aliases=['dns'])
conn.add_service(service)
# ensure dns service responds as we expect from replacement
self.assertFalse(conn.dns.dummy())