Refactor swap_filter in instance views

Previously we check if a fake_field is contained in search_opts
before calling swap_filter, but we can move it into the inside
of swap_filter.

This commit is split from https://review.openstack.org/#/c/507388/
to avoid doing a fix and refactoring in a single commit.

Co-Authored-By: Huan Xiong <huan.xiong@hxt-semitech.com>
Change-Id: I3069c6c9e66f32f53a64124f1d9d191d6aa703a3
This commit is contained in:
Akihiro Motoki 2017-11-23 20:21:10 +00:00
parent 9854147407
commit 6c4d254b4a
2 changed files with 47 additions and 32 deletions

View File

@ -66,11 +66,6 @@ def mks(args, **kvargs):
return views.mks(args, **kvargs)
# re-use get_resource_id_by_name from project.instances.views
def swap_filter(resources, filters, fake_field, real_field):
return views.swap_filter(resources, filters, fake_field, real_field)
class AdminUpdateView(views.UpdateView):
workflow_class = update_instance.AdminUpdateInstance
success_url = reverse_lazy("horizon:admin:instances:index")
@ -172,18 +167,14 @@ class AdminIndexView(tables.DataTableView):
e.submit(fn=_task_get_images)
e.submit(fn=_task_get_flavors)
if 'project' in search_opts and \
not swap_filter(tenants, search_opts, 'project', 'tenant_id'):
self._more = False
return instances
elif 'image_name' in search_opts and \
not swap_filter(images, search_opts, 'image_name', 'image'):
self._more = False
return instances
elif "flavor_name" in search_opts and \
not swap_filter(flavors, search_opts, 'flavor_name', 'flavor'):
self._more = False
return instances
non_api_filter_info = (
('project', 'tenant_id', tenants),
('image_name', 'image', images),
('flavor_name', 'flavor', flavors),
)
if not views.process_non_api_filters(search_opts, non_api_filter_info):
self._more = False
return []
_task_get_instances()

View File

@ -123,14 +123,13 @@ class IndexView(tables.DataTableView):
e.submit(fn=_task_get_flavors)
e.submit(fn=_task_get_images)
if 'image_name' in search_opts and \
not swap_filter(images, search_opts, 'image_name', 'image'):
non_api_filter_info = (
('image_name', 'image', images),
('flavor_name', 'flavor', flavors),
)
if not process_non_api_filters(search_opts, non_api_filter_info):
self._more = False
return instances
elif 'flavor_name' in search_opts and \
not swap_filter(flavors, search_opts, 'flavor_name', 'flavor'):
self._more = False
return instances
return []
_task_get_instances()
@ -160,14 +159,39 @@ class IndexView(tables.DataTableView):
return instances
def swap_filter(resources, filters, fake_field, real_field):
if fake_field in filters:
filter_string = filters[fake_field]
for resource in resources:
if resource.name.lower() == filter_string.lower():
filters[real_field] = resource.id
del filters[fake_field]
return True
def process_non_api_filters(search_opts, non_api_filter_info):
"""Process filters by non-API fields
There are cases where it is useful to provide a filter field
which does not exist in a resource in a backend service.
For example, nova server list provides 'image' field with image ID
but 'image name' is more useful for GUI users.
This function replaces fake fields into corresponding real fields.
The format of non_api_filter_info is a tuple/list of
(fake_field, real_field, resources).
This returns True if further lookup is required.
It returns False if there are no matching resources,
for example, if no corresponding real field exists.
"""
for fake_field, real_field, resources in non_api_filter_info:
if not _swap_filter(resources, search_opts, fake_field, real_field):
return False
return True
def _swap_filter(resources, search_opts, fake_field, real_field):
if fake_field not in search_opts:
return True
filter_string = search_opts[fake_field]
matched = [resource for resource in resources
if resource.name.lower() == filter_string.lower()]
if not matched:
return False
search_opts[real_field] = matched[0].id
del search_opts[fake_field]
return True
class LaunchInstanceView(workflows.WorkflowView):