From bfa8075f659f6fe18eb2442f2ae0722d0fd1c2ff Mon Sep 17 00:00:00 2001 From: William Wolf Date: Thu, 15 Sep 2011 10:00:38 -0400 Subject: added build_list to servers controllers and view builder and kept all old tests passing --- nova/api/openstack/servers.py | 27 +++++++++++++++++++++++---- nova/api/openstack/views/servers.py | 22 +++++++++++++++++++++- 2 files changed, 44 insertions(+), 5 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 5affd1f33..02bce1b50 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -75,6 +75,9 @@ class Controller(object): def _build_view(self, req, instance, is_detail=False): raise NotImplementedError() + def _build_list(self, req, instances, is_detail=False): + raise NotImplementedError() + def _limit_items(self, items, req): raise NotImplementedError() @@ -130,10 +133,7 @@ class Controller(object): search_opts=search_opts) limited_list = self._limit_items(instance_list, req) - servers = [self._build_view(req, inst, is_detail)['server'] - for inst in limited_list] - - return dict(servers=servers) + return self._build_list(req, limited_list, is_detail=is_detail) @scheduler_api.redirect_handler def show(self, req, id): @@ -589,6 +589,11 @@ class ControllerV10(Controller): builder = nova.api.openstack.views.servers.ViewBuilderV10(addresses) return builder.build(instance, is_detail=is_detail) + def _build_list(self, req, instances, is_detail=False): + addresses = nova.api.openstack.views.addresses.ViewBuilderV10() + builder = nova.api.openstack.views.servers.ViewBuilderV10(addresses) + return builder.build_list(instances, is_detail=is_detail) + def _limit_items(self, items, req): return common.limited(items, req) @@ -682,6 +687,20 @@ class ControllerV11(Controller): return builder.build(instance, is_detail=is_detail) + def _build_list(self, req, instances, is_detail=False): + params = common.get_pagination_params(req) + project_id = getattr(req.environ['nova.context'], 'project_id', '') + base_url = req.application_url + flavor_builder = nova.api.openstack.views.flavors.ViewBuilderV11( + base_url, project_id) + image_builder = nova.api.openstack.views.images.ViewBuilderV11( + base_url, project_id) + addresses_builder = nova.api.openstack.views.addresses.ViewBuilderV11() + builder = nova.api.openstack.views.servers.ViewBuilderV11( + addresses_builder, flavor_builder, image_builder, + base_url, project_id) + return builder.build_list(instances, is_detail=is_detail) + def _action_change_password(self, input_dict, req, id): context = req.environ['nova.context'] if (not 'changePassword' in input_dict diff --git a/nova/api/openstack/views/servers.py b/nova/api/openstack/views/servers.py index 473dc9e7e..1228c81f7 100644 --- a/nova/api/openstack/views/servers.py +++ b/nova/api/openstack/views/servers.py @@ -40,7 +40,7 @@ class ViewBuilder(object): def __init__(self, addresses_builder): self.addresses_builder = addresses_builder - def build(self, inst, is_detail): + def build(self, inst, is_detail=False): """Return a dict that represenst a server.""" if inst.get('_is_precooked', False): server = dict(server=inst) @@ -54,6 +54,16 @@ class ViewBuilder(object): return server + def build_list(self, server_objs, is_detail=False, **kwargs): + limit = kwargs.get('limit', None) + servers = [] + servers_links = [] + + for server_obj in server_objs: + servers.append(self.build(server_obj, is_detail)['server']) + + return dict(servers=servers) + def _build_simple(self, inst): """Return a simple model of a server.""" return dict(server=dict(id=inst['id'], name=inst['display_name'])) @@ -205,6 +215,16 @@ class ViewBuilderV11(ViewBuilder): response["links"] = links + def build_list(self, server_objs, is_detail=False, **kwargs): + limit = kwargs.get('limit', None) + servers = [] + servers_links = [] + + for server_obj in server_objs: + servers.append(self.build(server_obj, is_detail)['server']) + + return dict(servers=servers) + def generate_href(self, server_id): """Create an url that refers to a specific server id.""" return os.path.join(self.base_url, self.project_id, -- cgit From 41e8bbd9fd9daa669e0becd762c3c0e4639287ea Mon Sep 17 00:00:00 2001 From: William Wolf Date: Thu, 15 Sep 2011 10:21:33 -0400 Subject: added servers_links in v1.1 with tests --- nova/api/openstack/servers.py | 2 +- nova/api/openstack/views/servers.py | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 02bce1b50..30933ca34 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -699,7 +699,7 @@ class ControllerV11(Controller): builder = nova.api.openstack.views.servers.ViewBuilderV11( addresses_builder, flavor_builder, image_builder, base_url, project_id) - return builder.build_list(instances, is_detail=is_detail) + return builder.build_list(instances, is_detail=is_detail, **params) def _action_change_password(self, input_dict, req, id): context = req.environ['nova.context'] diff --git a/nova/api/openstack/views/servers.py b/nova/api/openstack/views/servers.py index 1228c81f7..52e0850fb 100644 --- a/nova/api/openstack/views/servers.py +++ b/nova/api/openstack/views/servers.py @@ -217,13 +217,30 @@ class ViewBuilderV11(ViewBuilder): def build_list(self, server_objs, is_detail=False, **kwargs): limit = kwargs.get('limit', None) + print "BUILD LIST 11", limit servers = [] servers_links = [] for server_obj in server_objs: servers.append(self.build(server_obj, is_detail)['server']) - return dict(servers=servers) + if (len(servers) and limit) and (limit == len(servers)): + print "LIMIT SET" + next_link = self.generate_next_link(servers[-1]['id'], + limit, is_detail) + servers_links = [dict(rel='next', href=next_link)] + + reval = dict(servers=servers) + if len(servers_links) > 0: + reval['servers_links'] = servers_links + + return reval + + def generate_next_link(self, server_id, limit, is_detail=False): + """ Return an href string with proper limit and marker params""" + return "%s?limit=%s&marker=%s" % ( + os.path.join(self.base_url, self.project_id, "servers"), + limit, server_id) def generate_href(self, server_id): """Create an url that refers to a specific server id.""" -- cgit From 16f3e0b4f1212ab8d34a68ad763ff6c870dbbe73 Mon Sep 17 00:00:00 2001 From: William Wolf Date: Thu, 15 Sep 2011 11:32:37 -0400 Subject: added xml support for servers_list in response with tests --- nova/api/openstack/schemas/v1.1/servers_index.rng | 3 +++ nova/api/openstack/servers.py | 10 +++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/schemas/v1.1/servers_index.rng b/nova/api/openstack/schemas/v1.1/servers_index.rng index 768f0912d..023e4b66a 100644 --- a/nova/api/openstack/schemas/v1.1/servers_index.rng +++ b/nova/api/openstack/schemas/v1.1/servers_index.rng @@ -9,4 +9,7 @@ + + + diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 30933ca34..de72537a8 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -946,18 +946,22 @@ class ServerXMLSerializer(wsgi.XMLDictSerializer): 'security_group') group_elem.set('name', group['name']) - for link in server_dict.get('links', []): - elem = etree.SubElement(server_elem, + self._populate_links(server_elem, server_dict.get('links', [])) + + def _populate_links(self, parent, links): + for link in links: + elem = etree.SubElement(parent, '{%s}link' % xmlutil.XMLNS_ATOM) elem.set('rel', link['rel']) elem.set('href', link['href']) - return server_elem def index(self, servers_dict): servers = etree.Element('servers', nsmap=self.NSMAP) for server_dict in servers_dict['servers']: server = etree.SubElement(servers, 'server') self._populate_server(server, server_dict, False) + + self._populate_links(servers, servers_dict.get('servers_links', [])) return self._to_xml(servers) def detail(self, servers_dict): -- cgit From 98693520d262dec4849c2aa71a090acfd37c73dd Mon Sep 17 00:00:00 2001 From: William Wolf Date: Thu, 15 Sep 2011 11:52:12 -0400 Subject: pep8 issues --- nova/api/openstack/views/servers.py | 1 - 1 file changed, 1 deletion(-) (limited to 'nova/api') diff --git a/nova/api/openstack/views/servers.py b/nova/api/openstack/views/servers.py index 52e0850fb..8f54d58dd 100644 --- a/nova/api/openstack/views/servers.py +++ b/nova/api/openstack/views/servers.py @@ -233,7 +233,6 @@ class ViewBuilderV11(ViewBuilder): reval = dict(servers=servers) if len(servers_links) > 0: reval['servers_links'] = servers_links - return reval def generate_next_link(self, server_id, limit, is_detail=False): -- cgit From f4a453cb99bf76e17c4ec89c850f65f6c704b4fe Mon Sep 17 00:00:00 2001 From: William Wolf Date: Thu, 15 Sep 2011 14:04:50 -0400 Subject: get rid of debugs --- nova/api/openstack/views/servers.py | 2 -- 1 file changed, 2 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/views/servers.py b/nova/api/openstack/views/servers.py index 8f54d58dd..dafa2d463 100644 --- a/nova/api/openstack/views/servers.py +++ b/nova/api/openstack/views/servers.py @@ -217,7 +217,6 @@ class ViewBuilderV11(ViewBuilder): def build_list(self, server_objs, is_detail=False, **kwargs): limit = kwargs.get('limit', None) - print "BUILD LIST 11", limit servers = [] servers_links = [] @@ -225,7 +224,6 @@ class ViewBuilderV11(ViewBuilder): servers.append(self.build(server_obj, is_detail)['server']) if (len(servers) and limit) and (limit == len(servers)): - print "LIMIT SET" next_link = self.generate_next_link(servers[-1]['id'], limit, is_detail) servers_links = [dict(rel='next', href=next_link)] -- cgit From 35bf3c005538c243351a89332f0866836f788d29 Mon Sep 17 00:00:00 2001 From: William Wolf Date: Thu, 15 Sep 2011 15:03:53 -0400 Subject: pass-through all other parameters in next links as well --- nova/api/openstack/servers.py | 7 ++++++- nova/api/openstack/views/servers.py | 10 +++++----- 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index de72537a8..966cd306a 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -688,7 +688,12 @@ class ControllerV11(Controller): return builder.build(instance, is_detail=is_detail) def _build_list(self, req, instances, is_detail=False): - params = common.get_pagination_params(req) + params = req.GET.copy() + pagination_params = common.get_pagination_params(req) + # Update params with int() values from pagination params + for key, val in pagination_params.iteritems(): + params[key] = val + project_id = getattr(req.environ['nova.context'], 'project_id', '') base_url = req.application_url flavor_builder = nova.api.openstack.views.flavors.ViewBuilderV11( diff --git a/nova/api/openstack/views/servers.py b/nova/api/openstack/views/servers.py index dafa2d463..0037fd64e 100644 --- a/nova/api/openstack/views/servers.py +++ b/nova/api/openstack/views/servers.py @@ -19,6 +19,7 @@ import datetime import hashlib import os +import urllib from nova import exception from nova.api.openstack import common @@ -225,7 +226,7 @@ class ViewBuilderV11(ViewBuilder): if (len(servers) and limit) and (limit == len(servers)): next_link = self.generate_next_link(servers[-1]['id'], - limit, is_detail) + kwargs, is_detail) servers_links = [dict(rel='next', href=next_link)] reval = dict(servers=servers) @@ -233,11 +234,10 @@ class ViewBuilderV11(ViewBuilder): reval['servers_links'] = servers_links return reval - def generate_next_link(self, server_id, limit, is_detail=False): + def generate_next_link(self, server_id, params, is_detail=False): """ Return an href string with proper limit and marker params""" - return "%s?limit=%s&marker=%s" % ( - os.path.join(self.base_url, self.project_id, "servers"), - limit, server_id) + params['marker'] = server_id + return "%s?%s" % (self.base_url, urllib.urlencode(params)) def generate_href(self, server_id): """Create an url that refers to a specific server id.""" -- cgit From 5feb413f7698633c6a598ec2899772269a96b690 Mon Sep 17 00:00:00 2001 From: William Wolf Date: Mon, 19 Sep 2011 11:26:14 -0400 Subject: make our own function instead of using urllib.urlencode since we apparently don't suppor urlencoded strings yet --- nova/api/openstack/common.py | 10 ++++++++++ nova/api/openstack/views/servers.py | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'nova/api') diff --git a/nova/api/openstack/common.py b/nova/api/openstack/common.py index ca7848678..64d7dded1 100644 --- a/nova/api/openstack/common.py +++ b/nova/api/openstack/common.py @@ -259,6 +259,16 @@ def check_img_metadata_quota_limit(context, metadata): headers={'Retry-After': 0}) +def dict_to_query_str(params): + # TODO: we should just use urllib.urlencode instead of this + # But currently we don't work with urlencoded url's + param_str = "" + for key, val in params.iteritems(): + param_str = param_str + '='.join([str(key), str(val)]) + '&' + + return param_str.rstrip('&') + + class MetadataXMLDeserializer(wsgi.XMLDeserializer): def extract_metadata(self, metadata_node): diff --git a/nova/api/openstack/views/servers.py b/nova/api/openstack/views/servers.py index 0037fd64e..49e7b6645 100644 --- a/nova/api/openstack/views/servers.py +++ b/nova/api/openstack/views/servers.py @@ -237,7 +237,7 @@ class ViewBuilderV11(ViewBuilder): def generate_next_link(self, server_id, params, is_detail=False): """ Return an href string with proper limit and marker params""" params['marker'] = server_id - return "%s?%s" % (self.base_url, urllib.urlencode(params)) + return "%s?%s" % (self.base_url, common.dict_to_query_str(params)) def generate_href(self, server_id): """Create an url that refers to a specific server id.""" -- cgit From c7f04b68ba752766fa2fc1edb68e6fb0219606e3 Mon Sep 17 00:00:00 2001 From: William Wolf Date: Mon, 19 Sep 2011 16:03:31 -0400 Subject: remove urllib import --- nova/api/openstack/views/servers.py | 1 - 1 file changed, 1 deletion(-) (limited to 'nova/api') diff --git a/nova/api/openstack/views/servers.py b/nova/api/openstack/views/servers.py index 49e7b6645..bb8bb0972 100644 --- a/nova/api/openstack/views/servers.py +++ b/nova/api/openstack/views/servers.py @@ -19,7 +19,6 @@ import datetime import hashlib import os -import urllib from nova import exception from nova.api.openstack import common -- cgit From a0e705359353cb6a9b0c3fc8178e714e4350c585 Mon Sep 17 00:00:00 2001 From: William Wolf Date: Mon, 19 Sep 2011 21:53:21 -0400 Subject: oops, add project_id and 'servers' to next links --- nova/api/openstack/views/servers.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'nova/api') diff --git a/nova/api/openstack/views/servers.py b/nova/api/openstack/views/servers.py index bb8bb0972..61480da70 100644 --- a/nova/api/openstack/views/servers.py +++ b/nova/api/openstack/views/servers.py @@ -236,7 +236,9 @@ class ViewBuilderV11(ViewBuilder): def generate_next_link(self, server_id, params, is_detail=False): """ Return an href string with proper limit and marker params""" params['marker'] = server_id - return "%s?%s" % (self.base_url, common.dict_to_query_str(params)) + return "%s?%s" % ( + os.path.join(self.base_url, self.project_id, "servers"), + common.dict_to_query_str(params)) def generate_href(self, server_id): """Create an url that refers to a specific server id.""" -- cgit