diff options
| author | Zuul <zuul@review.openstack.org> | 2017-12-13 02:18:43 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2017-12-13 02:18:43 +0000 |
| commit | 21b656ca4aa995530be474a8b9761b89f2ef93dd (patch) | |
| tree | b75291d0eb94a417b09c3cc6df1d2ea11338414b /openstackclient | |
| parent | 58e5abf2946ce9f0fa118866ac89f6ce881e440e (diff) | |
| parent | 12ee1861085144f43e6e535f82ba5d9b5d9a5632 (diff) | |
| download | python-openstackclient-21b656ca4aa995530be474a8b9761b89f2ef93dd.tar.gz | |
Merge "Add support for endpoing filter commands"
Diffstat (limited to 'openstackclient')
| -rw-r--r-- | openstackclient/identity/v3/endpoint.py | 147 | ||||
| -rw-r--r-- | openstackclient/tests/functional/identity/v3/common.py | 1 | ||||
| -rw-r--r-- | openstackclient/tests/functional/identity/v3/test_endpoint.py | 42 | ||||
| -rw-r--r-- | openstackclient/tests/unit/identity/v3/fakes.py | 27 | ||||
| -rw-r--r-- | openstackclient/tests/unit/identity/v3/test_endpoint.py | 139 |
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) |
