summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
authorZuul <zuul@review.openstack.org>2017-12-13 02:18:43 +0000
committerGerrit Code Review <review@openstack.org>2017-12-13 02:18:43 +0000
commit21b656ca4aa995530be474a8b9761b89f2ef93dd (patch)
treeb75291d0eb94a417b09c3cc6df1d2ea11338414b /openstackclient
parent58e5abf2946ce9f0fa118866ac89f6ce881e440e (diff)
parent12ee1861085144f43e6e535f82ba5d9b5d9a5632 (diff)
downloadpython-openstackclient-21b656ca4aa995530be474a8b9761b89f2ef93dd.tar.gz
Merge "Add support for endpoing filter commands"
Diffstat (limited to 'openstackclient')
-rw-r--r--openstackclient/identity/v3/endpoint.py147
-rw-r--r--openstackclient/tests/functional/identity/v3/common.py1
-rw-r--r--openstackclient/tests/functional/identity/v3/test_endpoint.py42
-rw-r--r--openstackclient/tests/unit/identity/v3/fakes.py27
-rw-r--r--openstackclient/tests/unit/identity/v3/test_endpoint.py139
5 files changed, 339 insertions, 17 deletions
diff --git a/openstackclient/identity/v3/endpoint.py b/openstackclient/identity/v3/endpoint.py
index 3b4dd0de..3229240e 100644
--- a/openstackclient/identity/v3/endpoint.py
+++ b/openstackclient/identity/v3/endpoint.py
@@ -36,6 +36,42 @@ def get_service_name(service):
return ''
+class AddProjectToEndpoint(command.Command):
+ _description = _("Associate a project to an endpoint")
+
+ def get_parser(self, prog_name):
+ parser = super(
+ AddProjectToEndpoint, self).get_parser(prog_name)
+ parser.add_argument(
+ 'endpoint',
+ metavar='<endpoint>',
+ help=_('Endpoint to associate with '
+ 'specified project (name or ID)'),
+ )
+ parser.add_argument(
+ 'project',
+ metavar='<project>',
+ help=_('Project to associate with '
+ 'specified endpoint name or ID)'),
+ )
+ common.add_project_domain_option_to_parser(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ client = self.app.client_manager.identity
+
+ endpoint = utils.find_resource(client.endpoints,
+ parsed_args.endpoint)
+
+ project = common.find_project(client,
+ parsed_args.project,
+ parsed_args.project_domain)
+
+ client.endpoint_filter.add_endpoint_to_project(
+ project=project.id,
+ endpoint=endpoint.id)
+
+
class CreateEndpoint(command.ShowOne):
_description = _("Create new endpoint")
@@ -152,27 +188,68 @@ class ListEndpoint(command.Lister):
metavar='<region-id>',
help=_('Filter by region ID'),
)
+ list_group = parser.add_mutually_exclusive_group()
+ list_group.add_argument(
+ '--endpoint',
+ metavar='<endpoint-group>',
+ help=_('Endpoint to list filters'),
+ )
+ list_group.add_argument(
+ '--project',
+ metavar='<project>',
+ help=_('Project to list filters (name or ID)'),
+ )
+ common.add_project_domain_option_to_parser(list_group)
return parser
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
- columns = ('ID', 'Region', 'Service Name', 'Service Type',
- 'Enabled', 'Interface', 'URL')
- kwargs = {}
- if parsed_args.service:
- service = common.find_service(identity_client, parsed_args.service)
- kwargs['service'] = service.id
- if parsed_args.interface:
- kwargs['interface'] = parsed_args.interface
- if parsed_args.region:
- kwargs['region'] = parsed_args.region
- data = identity_client.endpoints.list(**kwargs)
- service_list = identity_client.services.list()
-
- for ep in data:
- service = common.find_service_in_list(service_list, ep.service_id)
- ep.service_name = get_service_name(service)
- ep.service_type = service.type
+
+ endpoint = None
+ if parsed_args.endpoint:
+ endpoint = utils.find_resource(identity_client.endpoints,
+ parsed_args.endpoint)
+ project = None
+ if parsed_args.project:
+ project = common.find_project(identity_client,
+ parsed_args.project,
+ parsed_args.project_domain)
+
+ if endpoint:
+ columns = ('ID', 'Name')
+ data = (
+ identity_client.endpoint_filter
+ .list_projects_for_endpoint(endpoint=endpoint.id)
+ )
+ else:
+ columns = ('ID', 'Region', 'Service Name', 'Service Type',
+ 'Enabled', 'Interface', 'URL')
+ kwargs = {}
+ if parsed_args.service:
+ service = common.find_service(identity_client,
+ parsed_args.service)
+ kwargs['service'] = service.id
+ if parsed_args.interface:
+ kwargs['interface'] = parsed_args.interface
+ if parsed_args.region:
+ kwargs['region'] = parsed_args.region
+
+ if project:
+ data = (
+ identity_client.endpoint_filter
+ .list_endpoints_for_project(project=project.id)
+ )
+ else:
+ data = identity_client.endpoints.list(**kwargs)
+
+ service_list = identity_client.services.list()
+
+ for ep in data:
+ service = common.find_service_in_list(service_list,
+ ep.service_id)
+ ep.service_name = get_service_name(service)
+ ep.service_type = service.type
+
return (columns,
(utils.get_item_properties(
s, columns,
@@ -180,6 +257,42 @@ class ListEndpoint(command.Lister):
) for s in data))
+class RemoveProjectFromEndpoint(command.Command):
+ _description = _("Dissociate a project from an endpoint")
+
+ def get_parser(self, prog_name):
+ parser = super(
+ RemoveProjectFromEndpoint, self).get_parser(prog_name)
+ parser.add_argument(
+ 'endpoint',
+ metavar='<endpoint>',
+ help=_('Endpoint to dissociate from '
+ 'specified project (name or ID)'),
+ )
+ parser.add_argument(
+ 'project',
+ metavar='<project>',
+ help=_('Project to dissociate from '
+ 'specified endpoint name or ID)'),
+ )
+ common.add_project_domain_option_to_parser(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ client = self.app.client_manager.identity
+
+ endpoint = utils.find_resource(client.endpoints,
+ parsed_args.endpoint)
+
+ project = common.find_project(client,
+ parsed_args.project,
+ parsed_args.project_domain)
+
+ client.endpoint_filter.delete_endpoint_from_project(
+ project=project.id,
+ endpoint=endpoint.id)
+
+
class SetEndpoint(command.Command):
_description = _("Set endpoint properties")
diff --git a/openstackclient/tests/functional/identity/v3/common.py b/openstackclient/tests/functional/identity/v3/common.py
index 6d7896d8..33cb5d86 100644
--- a/openstackclient/tests/functional/identity/v3/common.py
+++ b/openstackclient/tests/functional/identity/v3/common.py
@@ -42,6 +42,7 @@ class IdentityTests(base.TestCase):
REGION_LIST_HEADERS = ['Region', 'Parent Region', 'Description']
ENDPOINT_LIST_HEADERS = ['ID', 'Region', 'Service Name', 'Service Type',
'Enabled', 'Interface', 'URL']
+ ENDPOINT_LIST_PROJECT_HEADERS = ['ID', 'Name']
IDENTITY_PROVIDER_FIELDS = ['description', 'enabled', 'id', 'remote_ids',
'domain_id']
diff --git a/openstackclient/tests/functional/identity/v3/test_endpoint.py b/openstackclient/tests/functional/identity/v3/test_endpoint.py
index 22dc1b65..41f0b4c8 100644
--- a/openstackclient/tests/functional/identity/v3/test_endpoint.py
+++ b/openstackclient/tests/functional/identity/v3/test_endpoint.py
@@ -42,6 +42,29 @@ class EndpointTests(common.IdentityTests):
items = self.parse_listing(raw_output)
self.assert_table_structure(items, self.ENDPOINT_LIST_HEADERS)
+ def test_endpoint_list_filter(self):
+ endpoint_id = self._create_dummy_endpoint(add_clean_up=False)
+ project_id = self._create_dummy_project(add_clean_up=False)
+ raw_output = self.openstack(
+ 'endpoint add project '
+ '%(endpoint_id)s '
+ '%(project_id)s' % {
+ 'project_id': project_id,
+ 'endpoint_id': endpoint_id})
+ self.assertEqual(0, len(raw_output))
+ raw_output = self.openstack(
+ 'endpoint list --endpoint %s' % endpoint_id)
+ self.assertIn(project_id, raw_output)
+ items = self.parse_listing(raw_output)
+ self.assert_table_structure(items,
+ self.ENDPOINT_LIST_PROJECT_HEADERS)
+
+ raw_output = self.openstack(
+ 'endpoint list --project %s' % project_id)
+ self.assertIn(endpoint_id, raw_output)
+ items = self.parse_listing(raw_output)
+ self.assert_table_structure(items, self.ENDPOINT_LIST_HEADERS)
+
def test_endpoint_set(self):
endpoint_id = self._create_dummy_endpoint()
new_endpoint_url = data_utils.rand_url()
@@ -65,3 +88,22 @@ class EndpointTests(common.IdentityTests):
raw_output = self.openstack('endpoint show %s' % endpoint_id)
items = self.parse_show(raw_output)
self.assert_show_fields(items, self.ENDPOINT_FIELDS)
+
+ def test_endpoint_add_remove_project(self):
+ endpoint_id = self._create_dummy_endpoint(add_clean_up=False)
+ project_id = self._create_dummy_project(add_clean_up=False)
+ raw_output = self.openstack(
+ 'endpoint add project '
+ '%(endpoint_id)s '
+ '%(project_id)s' % {
+ 'project_id': project_id,
+ 'endpoint_id': endpoint_id})
+ self.assertEqual(0, len(raw_output))
+
+ raw_output = self.openstack(
+ 'endpoint remove project '
+ '%(endpoint_id)s '
+ '%(project_id)s' % {
+ 'project_id': project_id,
+ 'endpoint_id': endpoint_id})
+ self.assertEqual(0, len(raw_output))
diff --git a/openstackclient/tests/unit/identity/v3/fakes.py b/openstackclient/tests/unit/identity/v3/fakes.py
index 7de25152..3e2caf01 100644
--- a/openstackclient/tests/unit/identity/v3/fakes.py
+++ b/openstackclient/tests/unit/identity/v3/fakes.py
@@ -493,6 +493,8 @@ class FakeIdentityv3Client(object):
self.credentials.resource_class = fakes.FakeResource(None, {})
self.endpoints = mock.Mock()
self.endpoints.resource_class = fakes.FakeResource(None, {})
+ self.endpoint_filter = mock.Mock()
+ self.endpoint_filter.resource_class = fakes.FakeResource(None, {})
self.groups = mock.Mock()
self.groups.resource_class = fakes.FakeResource(None, {})
self.oauth1 = mock.Mock()
@@ -911,6 +913,31 @@ class FakeEndpoint(object):
loaded=True)
return endpoint
+ @staticmethod
+ def create_one_endpoint_filter(attrs=None):
+ """Create a fake endpoint project relationship.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes of endpoint filter
+ :return:
+ A FakeResource object with project, endpoint and so on
+ """
+ attrs = attrs or {}
+
+ # Set default attribute
+ endpoint_filter_info = {
+ 'project': 'project-id-' + uuid.uuid4().hex,
+ 'endpoint': 'endpoint-id-' + uuid.uuid4().hex,
+ }
+
+ # Overwrite default attributes if there are some attributes set
+ endpoint_filter_info.update(attrs)
+
+ endpoint_filter = fakes.FakeModel(
+ copy.deepcopy(endpoint_filter_info))
+
+ return endpoint_filter
+
class FakeService(object):
"""Fake one or more service."""
diff --git a/openstackclient/tests/unit/identity/v3/test_endpoint.py b/openstackclient/tests/unit/identity/v3/test_endpoint.py
index fad53fcb..bfe930d6 100644
--- a/openstackclient/tests/unit/identity/v3/test_endpoint.py
+++ b/openstackclient/tests/unit/identity/v3/test_endpoint.py
@@ -22,11 +22,23 @@ class TestEndpoint(identity_fakes.TestIdentityv3):
# Get a shortcut to the EndpointManager Mock
self.endpoints_mock = self.app.client_manager.identity.endpoints
self.endpoints_mock.reset_mock()
+ self.ep_filter_mock = (
+ self.app.client_manager.identity.endpoint_filter
+ )
+ self.ep_filter_mock.reset_mock()
# Get a shortcut to the ServiceManager Mock
self.services_mock = self.app.client_manager.identity.services
self.services_mock.reset_mock()
+ # Get a shortcut to the DomainManager Mock
+ self.domains_mock = self.app.client_manager.identity.domains
+ self.domains_mock.reset_mock()
+
+ # Get a shortcut to the ProjectManager Mock
+ self.projects_mock = self.app.client_manager.identity.projects
+ self.projects_mock.reset_mock()
+
class TestEndpointCreate(TestEndpoint):
@@ -750,3 +762,130 @@ class TestEndpointShowServiceWithoutName(TestEndpointShow):
# Get the command object to test
self.cmd = endpoint.ShowEndpoint(self.app, None)
+
+
+class TestAddProjectToEndpoint(TestEndpoint):
+
+ project = identity_fakes.FakeProject.create_one_project()
+ domain = identity_fakes.FakeDomain.create_one_domain()
+ service = identity_fakes.FakeService.create_one_service()
+ endpoint = identity_fakes.FakeEndpoint.create_one_endpoint(
+ attrs={'service_id': service.id})
+
+ new_ep_filter = identity_fakes.FakeEndpoint.create_one_endpoint_filter(
+ attrs={'endpoint': endpoint.id,
+ 'project': project.id}
+ )
+
+ def setUp(self):
+ super(TestAddProjectToEndpoint, self).setUp()
+
+ # This is the return value for utils.find_resource()
+ self.endpoints_mock.get.return_value = self.endpoint
+
+ # Update the image_id in the MEMBER dict
+ self.ep_filter_mock.create.return_value = self.new_ep_filter
+ self.projects_mock.get.return_value = self.project
+ self.domains_mock.get.return_value = self.domain
+ # Get the command object to test
+ self.cmd = endpoint.AddProjectToEndpoint(self.app, None)
+
+ def test_add_project_to_endpoint_no_option(self):
+ arglist = [
+ self.endpoint.id,
+ self.project.id,
+ ]
+ verifylist = [
+ ('endpoint', self.endpoint.id),
+ ('project', self.project.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.ep_filter_mock.add_endpoint_to_project.assert_called_with(
+ project=self.project.id,
+ endpoint=self.endpoint.id
+ )
+ self.assertIsNone(result)
+
+ def test_add_project_to_endpoint_with_option(self):
+ arglist = [
+ self.endpoint.id,
+ self.project.id,
+ '--project-domain', self.domain.id,
+ ]
+ verifylist = [
+ ('endpoint', self.endpoint.id),
+ ('project', self.project.id),
+ ('project_domain', self.domain.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.ep_filter_mock.add_endpoint_to_project.assert_called_with(
+ project=self.project.id,
+ endpoint=self.endpoint.id
+ )
+ self.assertIsNone(result)
+
+
+class TestRemoveProjectEndpoint(TestEndpoint):
+
+ project = identity_fakes.FakeProject.create_one_project()
+ domain = identity_fakes.FakeDomain.create_one_domain()
+ service = identity_fakes.FakeService.create_one_service()
+ endpoint = identity_fakes.FakeEndpoint.create_one_endpoint(
+ attrs={'service_id': service.id})
+
+ def setUp(self):
+ super(TestRemoveProjectEndpoint, self).setUp()
+
+ # This is the return value for utils.find_resource()
+ self.endpoints_mock.get.return_value = self.endpoint
+
+ self.projects_mock.get.return_value = self.project
+ self.domains_mock.get.return_value = self.domain
+ self.ep_filter_mock.delete.return_value = None
+
+ # Get the command object to test
+ self.cmd = endpoint.RemoveProjectFromEndpoint(self.app, None)
+
+ def test_remove_project_endpoint_no_options(self):
+ arglist = [
+ self.endpoint.id,
+ self.project.id,
+ ]
+ verifylist = [
+ ('endpoint', self.endpoint.id),
+ ('project', self.project.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ self.ep_filter_mock.delete_endpoint_from_project.assert_called_with(
+ project=self.project.id,
+ endpoint=self.endpoint.id,
+ )
+ self.assertIsNone(result)
+
+ def test_remove_project_endpoint_with_options(self):
+ arglist = [
+ self.endpoint.id,
+ self.project.id,
+ '--project-domain', self.domain.id,
+ ]
+ verifylist = [
+ ('endpoint', self.endpoint.id),
+ ('project', self.project.id),
+ ('project_domain', self.domain.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ self.ep_filter_mock.delete_endpoint_from_project.assert_called_with(
+ project=self.project.id,
+ endpoint=self.endpoint.id,
+ )
+ self.assertIsNone(result)