From 84c42160e9eac654e734a19032237fdf1a8cb058 Mon Sep 17 00:00:00 2001 From: Akihiro Motoki Date: Wed, 27 Jul 2016 22:37:13 +0000 Subject: [PATCH] Move find_resource family to API binding layer find_resource variants are also used by OSC plugin. It looks reasonable to move them to the API binding layer. This commit does not touch the related unit tests to ensure backward compatibility. Related-Bug: #1521291 Change-Id: Iec3e9b379255111f5390325778a1d07bf73b29d6 --- neutronclient/neutron/v2_0/__init__.py | 96 ++-------------------- neutronclient/neutron/v2_0/tag.py | 3 +- neutronclient/tests/unit/test_cli20.py | 3 +- neutronclient/tests/unit/test_cli20_tag.py | 7 +- neutronclient/v2_0/client.py | 88 ++++++++++++++++++++ 5 files changed, 100 insertions(+), 97 deletions(-) diff --git a/neutronclient/neutron/v2_0/__init__.py b/neutronclient/neutron/v2_0/__init__.py index 05402f1f7..51c4b7daf 100644 --- a/neutronclient/neutron/v2_0/__init__.py +++ b/neutronclient/neutron/v2_0/__init__.py @@ -20,7 +20,6 @@ import abc import argparse import functools import logging -import re from cliff import command from cliff import lister @@ -32,104 +31,26 @@ from neutronclient._i18n import _ from neutronclient.common import exceptions from neutronclient.common import utils -HEX_ELEM = '[0-9A-Fa-f]' -UUID_PATTERN = '-'.join([HEX_ELEM + '{8}', HEX_ELEM + '{4}', - HEX_ELEM + '{4}', HEX_ELEM + '{4}', - HEX_ELEM + '{12}']) HYPHEN_OPTS = ['tags_any', 'not_tags', 'not_tags_any'] -def _get_resource_plural(resource, client): - plurals = getattr(client, 'EXTED_PLURALS', []) - for k in plurals: - if plurals[k] == resource: - return k - return resource + 's' - - def find_resource_by_id(client, resource, resource_id, cmd_resource=None, parent_id=None, fields=None): - if not cmd_resource: - cmd_resource = resource - cmd_resource_plural = _get_resource_plural(cmd_resource, client) - resource_plural = _get_resource_plural(resource, client) - obj_lister = getattr(client, "list_%s" % cmd_resource_plural) - # perform search by id only if we are passing a valid UUID - match = re.match(UUID_PATTERN, resource_id) - collection = resource_plural - if match: - params = {'id': resource_id} - if fields: - params['fields'] = fields - if parent_id: - data = obj_lister(parent_id, **params) - else: - data = obj_lister(**params) - if data and data[collection]: - return data[collection][0] - not_found_message = (_("Unable to find %(resource)s with id " - "'%(id)s'") % - {'resource': resource, 'id': resource_id}) - # 404 is raised by exceptions.NotFound to simulate serverside behavior - raise exceptions.NotFound(message=not_found_message) + return client.find_resource_by_id(resource, resource_id, cmd_resource, + parent_id, fields) def find_resourceid_by_id(client, resource, resource_id, cmd_resource=None, parent_id=None): - info = find_resource_by_id(client, resource, resource_id, cmd_resource, - parent_id, fields='id') - return info['id'] - - -def _find_resource_by_name(client, resource, name, project_id=None, - cmd_resource=None, parent_id=None, fields=None): - if not cmd_resource: - cmd_resource = resource - cmd_resource_plural = _get_resource_plural(cmd_resource, client) - resource_plural = _get_resource_plural(resource, client) - obj_lister = getattr(client, "list_%s" % cmd_resource_plural) - params = {'name': name} - if fields: - params['fields'] = fields - if project_id: - params['tenant_id'] = project_id - if parent_id: - data = obj_lister(parent_id, **params) - else: - data = obj_lister(**params) - collection = resource_plural - info = data[collection] - if len(info) > 1: - raise exceptions.NeutronClientNoUniqueMatch(resource=resource, - name=name) - elif len(info) == 0: - not_found_message = (_("Unable to find %(resource)s with name " - "'%(name)s'") % - {'resource': resource, 'name': name}) - # 404 is raised by exceptions.NotFound to simulate serverside behavior - raise exceptions.NotFound(message=not_found_message) - else: - return info[0] + return find_resource_by_id(client, resource, resource_id, cmd_resource, + parent_id, fields='id')['id'] def find_resource_by_name_or_id(client, resource, name_or_id, project_id=None, cmd_resource=None, parent_id=None, fields=None): - try: - return find_resource_by_id(client, resource, name_or_id, - cmd_resource, parent_id, fields) - except exceptions.NotFound: - try: - return _find_resource_by_name(client, resource, name_or_id, - project_id, cmd_resource, parent_id, - fields) - except exceptions.NotFound: - not_found_message = (_("Unable to find %(resource)s with name " - "or id '%(name_or_id)s'") % - {'resource': resource, - 'name_or_id': name_or_id}) - raise exceptions.NotFound( - message=not_found_message) + return client.find_resource(resource, name_or_id, project_id, + cmd_resource, parent_id, fields) def find_resourceid_by_name_or_id(client, resource, name_or_id, @@ -695,8 +616,7 @@ class ListCommand(NeutronCommand, lister.Lister): return search_opts def call_server(self, neutron_client, search_opts, parsed_args): - resource_plural = _get_resource_plural(self.cmd_resource, - neutron_client) + resource_plural = neutron_client.get_resource_plural(self.cmd_resource) obj_lister = getattr(neutron_client, "list_%s" % resource_plural) if self.parent_id: data = obj_lister(self.parent_id, **search_opts) @@ -729,7 +649,7 @@ class ListCommand(NeutronCommand, lister.Lister): if dirs: search_opts.update({'sort_dir': dirs}) data = self.call_server(neutron_client, search_opts, parsed_args) - collection = _get_resource_plural(self.resource, neutron_client) + collection = neutron_client.get_resource_plural(self.resource) return data.get(collection, []) def extend_list(self, data, parsed_args): diff --git a/neutronclient/neutron/v2_0/tag.py b/neutronclient/neutron/v2_0/tag.py index 2507d417e..774849cd8 100644 --- a/neutronclient/neutron/v2_0/tag.py +++ b/neutronclient/neutron/v2_0/tag.py @@ -20,8 +20,7 @@ TAG_RESOURCES = ['network'] def _convert_resource_args(client, parsed_args): - resource_type = neutronv20._get_resource_plural( - parsed_args.resource_type, client) + resource_type = client.get_resource_plural(parsed_args.resource_type) resource_id = neutronv20.find_resourceid_by_name_or_id( client, parsed_args.resource_type, parsed_args.resource) return resource_type, resource_id diff --git a/neutronclient/tests/unit/test_cli20.py b/neutronclient/tests/unit/test_cli20.py index 19bd29708..324782f0b 100644 --- a/neutronclient/tests/unit/test_cli20.py +++ b/neutronclient/tests/unit/test_cli20.py @@ -250,8 +250,7 @@ class CLITestV20Base(base.BaseTestCase): ress[resource].update({'name': name}) resstr = self.client.serialize(ress) # url method body - resource_plural = neutronV2_0._get_resource_plural(cmd_resource, - self.client) + resource_plural = self.client.get_resource_plural(cmd_resource) path = getattr(self.client, resource_plural + "_path") if parent_id: path = path % parent_id diff --git a/neutronclient/tests/unit/test_cli20_tag.py b/neutronclient/tests/unit/test_cli20_tag.py index 24f07b73a..09b99ab0a 100644 --- a/neutronclient/tests/unit/test_cli20_tag.py +++ b/neutronclient/tests/unit/test_cli20_tag.py @@ -15,7 +15,6 @@ import sys from mox3 import mox from neutronclient.common import exceptions -from neutronclient.neutron import v2_0 as neutronV2_0 from neutronclient.neutron.v2_0 import network from neutronclient.neutron.v2_0 import tag from neutronclient import shell @@ -68,14 +67,12 @@ class CLITestV20Tag(test_cli20.CLITestV20Base): def _make_tag_path(self, resource, resource_id, tag): path = getattr(self.client, "tag_path") - resource_plural = neutronV2_0._get_resource_plural(resource, - self.client) + resource_plural = self.client.get_resource_plural(resource) return path % (resource_plural, resource_id, tag) def _make_tags_path(self, resource, resource_id): path = getattr(self.client, "tags_path") - resource_plural = neutronV2_0._get_resource_plural(resource, - self.client) + resource_plural = self.client.get_resource_plural(resource) return path % (resource_plural, resource_id) def test_add_tag(self): diff --git a/neutronclient/v2_0/client.py b/neutronclient/v2_0/client.py index 5504fd1dd..0b5ca6b07 100644 --- a/neutronclient/v2_0/client.py +++ b/neutronclient/v2_0/client.py @@ -18,6 +18,7 @@ import inspect import itertools import logging +import re import time import debtcollector.renames @@ -35,6 +36,11 @@ from neutronclient.common import utils _logger = logging.getLogger(__name__) +HEX_ELEM = '[0-9A-Fa-f]' +UUID_PATTERN = '-'.join([HEX_ELEM + '{8}', HEX_ELEM + '{4}', + HEX_ELEM + '{4}', HEX_ELEM + '{4}', + HEX_ELEM + '{12}']) + def exception_handler_v20(status_code, error_content): """Exception handler for API v2.0 client. @@ -396,6 +402,88 @@ class ClientBase(object): else: return _TupleWithMeta((), resp) + def get_resource_plural(self, resource): + for k in self.EXTED_PLURALS: + if self.EXTED_PLURALS[k] == resource: + return k + return resource + 's' + + def _find_resource_by_id(self, resource, resource_id, cmd_resource=None, + parent_id=None, fields=None): + if not cmd_resource: + cmd_resource = resource + cmd_resource_plural = self.get_resource_plural(cmd_resource) + resource_plural = self.get_resource_plural(resource) + # TODO(amotoki): Use show_%s instead of list_%s + obj_lister = getattr(self, "list_%s" % cmd_resource_plural) + # perform search by id only if we are passing a valid UUID + match = re.match(UUID_PATTERN, resource_id) + collection = resource_plural + if match: + params = {'id': resource_id} + if fields: + params['fields'] = fields + if parent_id: + data = obj_lister(parent_id, **params) + else: + data = obj_lister(**params) + if data and data[collection]: + return data[collection][0] + not_found_message = (_("Unable to find %(resource)s with id " + "'%(id)s'") % + {'resource': resource, 'id': resource_id}) + # 404 is raised by exceptions.NotFound to simulate serverside behavior + raise exceptions.NotFound(message=not_found_message) + + def _find_resource_by_name(self, resource, name, project_id=None, + cmd_resource=None, parent_id=None, fields=None): + if not cmd_resource: + cmd_resource = resource + cmd_resource_plural = self.get_resource_plural(cmd_resource) + resource_plural = self.get_resource_plural(resource) + obj_lister = getattr(self, "list_%s" % cmd_resource_plural) + params = {'name': name} + if fields: + params['fields'] = fields + if project_id: + params['tenant_id'] = project_id + if parent_id: + data = obj_lister(parent_id, **params) + else: + data = obj_lister(**params) + collection = resource_plural + info = data[collection] + if len(info) > 1: + raise exceptions.NeutronClientNoUniqueMatch(resource=resource, + name=name) + elif len(info) == 0: + not_found_message = (_("Unable to find %(resource)s with name " + "'%(name)s'") % + {'resource': resource, 'name': name}) + # 404 is raised by exceptions.NotFound + # to simulate serverside behavior + raise exceptions.NotFound(message=not_found_message) + else: + return info[0] + + def find_resource(self, resource, name_or_id, project_id=None, + cmd_resource=None, parent_id=None, fields=None): + try: + return self._find_resource_by_id(resource, name_or_id, + cmd_resource, parent_id, fields) + except exceptions.NotFound: + try: + return self._find_resource_by_name( + resource, name_or_id, project_id, + cmd_resource, parent_id, fields) + except exceptions.NotFound: + not_found_message = (_("Unable to find %(resource)s with name " + "or id '%(name_or_id)s'") % + {'resource': resource, + 'name_or_id': name_or_id}) + raise exceptions.NotFound( + message=not_found_message) + class Client(ClientBase):