Add update_endpoint()

v3 allows us to update the endpoints, we should do that.

The other endpoint calls have been validated against v3 api to do what
we want them to do. All comments regarding implementing v3 keystone
have been removed.

Change-Id: Icae8a02815b1416a60bc8c6d57ee892fbfd7ccc4
This commit is contained in:
SamYaple 2016-03-06 16:38:09 +00:00 committed by Sam Yaple
parent acf010f463
commit 3326bb7706
5 changed files with 107 additions and 2 deletions

View File

@ -0,0 +1,8 @@
---
features:
- Added update_endpoint as a new function that allows
the user to update a created endpoint with new values
rather than deleting and recreating that endpoint.
This feature only works with keystone v3, with v2 it
will raise an exception stating the feature is not
available.

View File

@ -724,6 +724,11 @@ class EndpointCreate(task_manager.Task):
return client.keystone_client.endpoints.create(**self.args)
class EndpointUpdate(task_manager.Task):
def main(self, client):
return client.keystone_client.endpoints.update(**self.args)
class EndpointList(task_manager.Task):
def main(self, client):
return client.keystone_client.endpoints.list()

View File

@ -980,6 +980,26 @@ class OperatorCloud(openstackcloud.OpenStackCloud):
endpoints.append(endpoint)
return endpoints
@_utils.valid_kwargs('enabled', 'service_name_or_id', 'url', 'interface',
'region')
def update_endpoint(self, endpoint_id, **kwargs):
# NOTE(SamYaple): Endpoint updates are only available on v3 api
if self.cloud_config.get_api_version('identity').startswith('2'):
raise OpenStackCloudUnavailableFeature(
'Unavailable Feature: Endpoint update'
)
service_name_or_id = kwargs.pop('service_name_or_id', None)
if service_name_or_id is not None:
kwargs['service'] = service_name_or_id
with _utils.shade_exceptions(
"Failed to update endpoint {}".format(endpoint_id)
):
return self.manager.submitTask(_tasks.EndpointUpdate(
endpoint=endpoint_id, **kwargs
))
def list_endpoints(self):
"""List Keystone endpoints.
@ -988,7 +1008,10 @@ class OperatorCloud(openstackcloud.OpenStackCloud):
:raises: ``OpenStackCloudException``: if something goes wrong during
the openstack API call.
"""
# ToDo: support v3 api (dguerri)
# NOTE(SamYaple): With keystone v3 we can filter directly via the
# the keystone api, but since the return of all the endpoints even in
# large environments is small, we can continue to filter in shade just
# like the v2 api.
with _utils.shade_exceptions("Failed to list endpoints"):
endpoints = self.manager.submitTask(_tasks.EndpointList())
@ -1042,7 +1065,6 @@ class OperatorCloud(openstackcloud.OpenStackCloud):
:raises: ``OpenStackCloudException`` if something goes wrong during
the openstack API call.
"""
# ToDo: support v3 api (dguerri)
endpoint = self.get_endpoint(id=id)
if endpoint is None:
self.log.debug("Endpoint %s not found for deleting" % id)

View File

@ -25,6 +25,7 @@ import string
import random
from shade.exc import OpenStackCloudException
from shade.exc import OpenStackCloudUnavailableFeature
from shade.tests.functional import base
@ -101,6 +102,39 @@ class TestEndpoints(base.BaseFunctionalTestCase):
self.assertNotEqual([], endpoints)
self.assertIsNotNone(endpoints[0].get('id'))
def test_update_endpoint(self):
if self.operator_cloud.cloud_config.get_api_version(
'identity').startswith('2'):
# NOTE(SamYaple): Update endpoint only works with v3 api
self.assertRaises(OpenStackCloudUnavailableFeature,
self.operator_cloud.update_endpoint,
'endpoint_id1')
else:
service = self.operator_cloud.create_service(
name='service1', type='test_type')
endpoint = self.operator_cloud.create_endpoint(
service_name_or_id=service['id'],
url='http://admin.url/',
interface='admin',
region='orig_region',
enabled=False)[0]
new_service = self.operator_cloud.create_service(
name='service2', type='test_type')
new_endpoint = self.operator_cloud.update_endpoint(
endpoint.id,
service_name_or_id=new_service.id,
url='http://public.url/',
interface='public',
region='update_region',
enabled=True)
self.assertEqual(new_endpoint.url, 'http://public.url/')
self.assertEqual(new_endpoint.interface, 'public')
self.assertEqual(new_endpoint.region, 'update_region')
self.assertEqual(new_endpoint.service_id, new_service.id)
self.assertTrue(new_endpoint.enabled)
def test_list_endpoints(self):
service_name = self.new_item_name + '_list'

View File

@ -23,6 +23,7 @@ from mock import patch
import os_client_config
from shade import OperatorCloud
from shade.exc import OpenStackCloudException
from shade.exc import OpenStackCloudUnavailableFeature
from shade.tests.fakes import FakeEndpoint
from shade.tests.fakes import FakeEndpointv3
from shade.tests.unit import base
@ -170,6 +171,41 @@ class TestCloudEndpoints(base.TestCase):
for k, v in self.mock_endpoints_v3[count].items():
self.assertEquals(v, endpoints_2on3[count].get(k))
@patch.object(os_client_config.cloud_config.CloudConfig, 'get_api_version')
def test_update_endpoint_v2(self, mock_api_version):
mock_api_version.return_value = '2.0'
# NOTE(SamYaple): Update endpoint only works with v3 api
self.assertRaises(OpenStackCloudUnavailableFeature,
self.client.update_endpoint, 'endpoint_id')
@patch.object(OperatorCloud, 'keystone_client')
@patch.object(os_client_config.cloud_config.CloudConfig, 'get_api_version')
def test_update_endpoint_v3(self, mock_api_version, mock_keystone_client):
mock_api_version.return_value = '3'
mock_keystone_client.endpoints.update.return_value = \
self.mock_ks_endpoints_v3[0]
endpoint = self.client.update_endpoint(
'id1',
service_name_or_id='service_id1',
region='mock_region',
url='mock_url',
interface='mock_interface',
enabled=False
)
mock_keystone_client.endpoints.update.assert_called_with(
endpoint='id1',
service='service_id1',
region='mock_region',
url='mock_url',
interface='mock_interface',
enabled=False
)
# test keys and values are correct
for k, v in self.mock_endpoints_v3[0].items():
self.assertEquals(v, endpoint.get(k))
@patch.object(OperatorCloud, 'keystone_client')
def test_list_endpoints(self, mock_keystone_client):
mock_keystone_client.endpoints.list.return_value = \