summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel de Medeiros Queiroz <samueldmq@gmail.com>2017-01-05 23:37:39 -0300
committerSamuel de Medeiros Queiroz <samueldmq@gmail.com>2017-02-11 12:38:37 +0000
commit34d99f0c09a253b3f51f3855fa6ce7449ffc235e (patch)
tree84f8ffc84986f8b1b1a337bb35dc94f2234d8178
parent004450040c38a0df05469b844ba30854b67aabd5 (diff)
downloadpython-keystoneclient-34d99f0c09a253b3f51f3855fa6ce7449ffc235e.tar.gz
Add support for endpoint group CRUD
The following API calls are made available: - POST /OS-EP-FILTER/endpoint_groups - GET /OS-EP-FILTER/endpoint_groups/{endpoint_group_id} - HEAD /OS-EP-FILTER/endpoint_groups/{endpoint_group_id} - PATCH /OS-EP-FILTER/endpoint_groups/{endpoint_group_id} - DELETE /OS-EP-FILTER/endpoint_groups/{endpoint_group_id} - GET /OS-EP-FILTER/endpoint_groups Partial-Bug: #1641674 Change-Id: I285eefe82152b178268f671e8800a0ff8c1511e4
-rw-r--r--keystoneclient/tests/functional/v3/client_fixtures.py12
-rw-r--r--keystoneclient/tests/functional/v3/test_endpoint_groups.py120
-rw-r--r--keystoneclient/tests/unit/v3/test_endpoint_groups.py34
-rw-r--r--keystoneclient/v3/client.py8
-rw-r--r--keystoneclient/v3/endpoint_groups.py136
5 files changed, 310 insertions, 0 deletions
diff --git a/keystoneclient/tests/functional/v3/client_fixtures.py b/keystoneclient/tests/functional/v3/client_fixtures.py
index 9873b26..dd7209a 100644
--- a/keystoneclient/tests/functional/v3/client_fixtures.py
+++ b/keystoneclient/tests/functional/v3/client_fixtures.py
@@ -178,6 +178,18 @@ class Endpoint(Base):
self.addCleanup(self.client.endpoints.delete, self.entity)
+class EndpointGroup(Base):
+
+ def setUp(self):
+ super(EndpointGroup, self).setUp()
+
+ self.ref = {'name': RESOURCE_NAME_PREFIX + uuid.uuid4().hex,
+ 'filters': {'interface': 'public'},
+ 'description': uuid.uuid4().hex}
+ self.entity = self.client.endpoint_groups.create(**self.ref)
+ self.addCleanup(self.client.endpoint_groups.delete, self.entity)
+
+
class Credential(Base):
def __init__(self, client, user, type, project=None):
diff --git a/keystoneclient/tests/functional/v3/test_endpoint_groups.py b/keystoneclient/tests/functional/v3/test_endpoint_groups.py
new file mode 100644
index 0000000..10eccfb
--- /dev/null
+++ b/keystoneclient/tests/functional/v3/test_endpoint_groups.py
@@ -0,0 +1,120 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import uuid
+
+from keystoneauth1.exceptions import http
+
+from keystoneclient.tests.functional import base
+from keystoneclient.tests.functional.v3 import client_fixtures as fixtures
+
+
+class EndpointGroupsTestCase(base.V3ClientTestCase):
+
+ def check_endpoint_group(self, endpoint_group, endpoint_group_ref=None):
+ self.assertIsNotNone(endpoint_group.id)
+ self.assertIn('self', endpoint_group.links)
+ self.assertIn('/endpoint_groups/' + endpoint_group.id,
+ endpoint_group.links['self'])
+
+ if endpoint_group_ref:
+ self.assertEqual(endpoint_group_ref['name'], endpoint_group.name)
+ self.assertEqual(endpoint_group_ref['filters'],
+ endpoint_group.filters)
+
+ # There is no guarantee description is present in endpoint groups
+ if hasattr(endpoint_group_ref, 'description'):
+ self.assertEqual(endpoint_group_ref['description'],
+ endpoint_group.description)
+ else:
+ # Only check remaining mandatory attributes
+ self.assertIsNotNone(endpoint_group.name)
+ self.assertIsNotNone(endpoint_group.filters)
+
+ def test_create_endpoint_group(self):
+ endpoint_group_ref = {
+ 'name': fixtures.RESOURCE_NAME_PREFIX + uuid.uuid4().hex,
+ 'filters': {'interface': 'internal'},
+ 'description': uuid.uuid4().hex}
+ endpoint_group = self.client.endpoint_groups.create(
+ **endpoint_group_ref)
+
+ self.addCleanup(self.client.endpoint_groups.delete, endpoint_group)
+ self.check_endpoint_group(endpoint_group, endpoint_group_ref)
+
+ def test_get_endpoint_group(self):
+ endpoint_group = fixtures.EndpointGroup(self.client)
+ self.useFixture(endpoint_group)
+
+ endpoint_ret = self.client.endpoint_groups.get(endpoint_group.id)
+ self.check_endpoint_group(endpoint_ret, endpoint_group.ref)
+
+ self.assertRaises(http.NotFound,
+ self.client.endpoint_groups.get,
+ uuid.uuid4().hex)
+
+ def test_check_endpoint_group(self):
+ endpoint_group = fixtures.EndpointGroup(self.client)
+ self.useFixture(endpoint_group)
+
+ self.client.endpoint_groups.check(endpoint_group.id)
+ self.assertRaises(http.NotFound,
+ self.client.endpoint_groups.check,
+ uuid.uuid4().hex)
+
+ def test_list_endpoint_groups(self):
+ endpoint_group_one = fixtures.EndpointGroup(self.client)
+ self.useFixture(endpoint_group_one)
+
+ endpoint_group_two = fixtures.EndpointGroup(self.client)
+ self.useFixture(endpoint_group_two)
+
+ endpoint_groups = self.client.endpoint_groups.list()
+
+ # All endpoints are valid
+ for endpoint_group in endpoint_groups:
+ self.check_endpoint_group(endpoint_group)
+
+ self.assertIn(endpoint_group_one.entity, endpoint_groups)
+ self.assertIn(endpoint_group_two.entity, endpoint_groups)
+
+ def test_update_endpoint_group(self):
+ endpoint_group = fixtures.EndpointGroup(self.client)
+ self.useFixture(endpoint_group)
+
+ new_name = fixtures.RESOURCE_NAME_PREFIX + uuid.uuid4().hex
+ new_filters = {'interface': 'public'}
+ new_description = uuid.uuid4().hex
+
+ endpoint_group_ret = self.client.endpoint_groups.update(
+ endpoint_group,
+ name=new_name,
+ filters=new_filters,
+ description=new_description)
+
+ endpoint_group.ref.update({'name': new_name, 'filters': new_filters,
+ 'description': new_description})
+ self.check_endpoint_group(endpoint_group_ret, endpoint_group.ref)
+
+ def test_delete_endpoint_group(self):
+ endpoint_group = self.client.endpoint_groups.create(
+ name=fixtures.RESOURCE_NAME_PREFIX + uuid.uuid4().hex,
+ filters={'interface': 'admin'},
+ description=uuid.uuid4().hex)
+
+ self.client.endpoint_groups.delete(endpoint_group.id)
+ self.assertRaises(http.NotFound,
+ self.client.endpoint_groups.check,
+ endpoint_group.id)
+ self.assertRaises(http.NotFound,
+ self.client.endpoint_groups.get,
+ endpoint_group.id)
diff --git a/keystoneclient/tests/unit/v3/test_endpoint_groups.py b/keystoneclient/tests/unit/v3/test_endpoint_groups.py
new file mode 100644
index 0000000..364fd53
--- /dev/null
+++ b/keystoneclient/tests/unit/v3/test_endpoint_groups.py
@@ -0,0 +1,34 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import uuid
+
+from keystoneclient.tests.unit.v3 import utils
+from keystoneclient.v3 import endpoint_groups
+
+
+class EndpointGroupTests(utils.ClientTestCase, utils.CrudTests):
+
+ def setUp(self):
+ super(EndpointGroupTests, self).setUp()
+ self.key = 'endpoint_group'
+ self.collection_key = 'endpoint_groups'
+ self.model = endpoint_groups.EndpointGroup
+ self.manager = self.client.endpoint_groups
+ self.path_prefix = 'OS-EP-FILTER'
+
+ def new_ref(self, **kwargs):
+ kwargs.setdefault('id', uuid.uuid4().hex)
+ kwargs.setdefault('name', uuid.uuid4().hex)
+ kwargs.setdefault('filters', '{"interface": "public"}')
+ kwargs.setdefault('description', uuid.uuid4().hex)
+ return kwargs
diff --git a/keystoneclient/v3/client.py b/keystoneclient/v3/client.py
index 181af89..2ca180a 100644
--- a/keystoneclient/v3/client.py
+++ b/keystoneclient/v3/client.py
@@ -33,6 +33,7 @@ from keystoneclient.v3 import credentials
from keystoneclient.v3 import domain_configs
from keystoneclient.v3 import domains
from keystoneclient.v3 import ec2
+from keystoneclient.v3 import endpoint_groups
from keystoneclient.v3 import endpoints
from keystoneclient.v3 import groups
from keystoneclient.v3 import policies
@@ -130,6 +131,11 @@ class Client(httpclient.HTTPClient):
:py:class:`keystoneclient.v3.contrib.endpoint_filter.\
EndpointFilterManager`
+ .. py:attribute:: endpoint_groups
+
+ :py:class:`keystoneclient.v3.endpoint_groups.\
+ EndpointGroupManager`
+
.. py:attribute:: endpoint_policy
:py:class:`keystoneclient.v3.contrib.endpoint_policy.\
@@ -211,6 +217,8 @@ class Client(httpclient.HTTPClient):
self.ec2 = ec2.EC2Manager(self._adapter)
self.endpoint_filter = endpoint_filter.EndpointFilterManager(
self._adapter)
+ self.endpoint_groups = endpoint_groups.EndpointGroupManager(
+ self._adapter)
self.endpoint_policy = endpoint_policy.EndpointPolicyManager(
self._adapter)
self.endpoints = endpoints.EndpointManager(self._adapter)
diff --git a/keystoneclient/v3/endpoint_groups.py b/keystoneclient/v3/endpoint_groups.py
new file mode 100644
index 0000000..f8b47c4
--- /dev/null
+++ b/keystoneclient/v3/endpoint_groups.py
@@ -0,0 +1,136 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from keystoneclient import base
+
+
+class EndpointGroup(base.Resource):
+ """Represents an identity endpoint group.
+
+ Attributes:
+ * id: a UUID that identifies the endpoint group
+ * name: the endpoint group name
+ * description: the endpoint group description
+ * filters: representation of filters in the format of JSON that define
+ what endpoint entities are part of the group
+
+ """
+
+ pass
+
+
+class EndpointGroupManager(base.CrudManager):
+ """Manager class for Endpoint Groups."""
+
+ resource_class = EndpointGroup
+ collection_key = 'endpoint_groups'
+ key = 'endpoint_group'
+ base_url = 'OS-EP-FILTER'
+
+ def create(self, name, filters, description=None, **kwargs):
+ """Create an endpoint group.
+
+ :param str name: the name of the endpoint group.
+ :param str filters: representation of filters in the format of JSON
+ that define what endpoint entities are part of the
+ group.
+ :param str description: a description of the endpoint group.
+ :param kwargs: any other attribute provided will be passed to the
+ server.
+
+ :returns: the created endpoint group returned from server.
+ :rtype: :class:`keystoneclient.v3.endpoint_groups.EndpointGroup`
+
+ """
+ return super(EndpointGroupManager, self).create(
+ name=name,
+ filters=filters,
+ description=description,
+ **kwargs)
+
+ def get(self, endpoint_group):
+ """Retrieve an endpoint group.
+
+ :param endpoint_group: the endpoint group to be retrieved from the
+ server.
+ :type endpoint_group:
+ str or :class:`keystoneclient.v3.endpoint_groups.EndpointGroup`
+
+ :returns: the specified endpoint group returned from server.
+ :rtype: :class:`keystoneclient.v3.endpoint_groups.EndpointGroup`
+
+ """
+ return super(EndpointGroupManager, self).get(
+ endpoint_group_id=base.getid(endpoint_group))
+
+ def check(self, endpoint_group):
+ """Check if an endpoint group exists.
+
+ :param endpoint_group: the endpoint group to be checked against the
+ server.
+ :type endpoint_group:
+ str or :class:`keystoneclient.v3.endpoint_groups.EndpointGroup`
+
+ :returns: none if the specified endpoint group exists.
+
+ """
+ return super(EndpointGroupManager, self).head(
+ endpoint_group_id=base.getid(endpoint_group))
+
+ def list(self, **kwargs):
+ """List endpoint groups.
+
+ Any parameter provided will be passed to the server.
+
+ :returns: a list of endpoint groups.
+ :rtype: list of
+ :class:`keystoneclient.v3.endpoint_groups.EndpointGroup`.
+
+ """
+ return super(EndpointGroupManager, self).list(**kwargs)
+
+ def update(self, endpoint_group, name=None, filters=None,
+ description=None, **kwargs):
+ """Update an endpoint group.
+
+ :param str name: the new name of the endpoint group.
+ :param str filters: the new representation of filters in the format of
+ JSON that define what endpoint entities are part of
+ the group.
+ :param str description: the new description of the endpoint group.
+ :param kwargs: any other attribute provided will be passed to the
+ server.
+
+ :returns: the updated endpoint group returned from server.
+ :rtype: :class:`keystoneclient.v3.endpoint_groups.EndpointGroup`
+
+ """
+ return super(EndpointGroupManager, self).update(
+ endpoint_group_id=base.getid(endpoint_group),
+ name=name,
+ filters=filters,
+ description=description,
+ **kwargs)
+
+ def delete(self, endpoint_group):
+ """Delete an endpoint group.
+
+ :param endpoint_group: the endpoint group to be deleted on the server.
+ :type endpoint_group:
+ str or :class:`keystoneclient.v3.endpoint_groups.EndpointGroup`
+
+ :returns: Response object with 204 status.
+ :rtype: :class:`requests.models.Response`
+
+ """
+ return super(EndpointGroupManager, self).delete(
+ endpoint_group_id=base.getid(endpoint_group))