Merge "Glance Rest API for Angular Front End"
This commit is contained in:
commit
b7956c9c65
|
@ -0,0 +1,159 @@
|
||||||
|
/*
|
||||||
|
Copyright 2015, Hewlett-Packard Development Company, L.P.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc service
|
||||||
|
* @name hz.api.glanceAPI
|
||||||
|
* @description Provides direct pass through to Glance with NO abstraction.
|
||||||
|
*/
|
||||||
|
function GlanceAPI(apiService) {
|
||||||
|
|
||||||
|
// Images
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name hz.api.glanceAPI.getImage
|
||||||
|
* @description
|
||||||
|
* Get a single image by ID
|
||||||
|
* @param {string} id
|
||||||
|
* Specifies the id of the image to request.
|
||||||
|
*/
|
||||||
|
this.getImage = function(id) {
|
||||||
|
return apiService.get('/api/glance/images/' + id)
|
||||||
|
.error(function () {
|
||||||
|
horizon.alert('error', gettext('Unable to retrieve image.'));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name hz.api.glanceAPI.getImages
|
||||||
|
* @description
|
||||||
|
* Get a list of images.
|
||||||
|
*
|
||||||
|
* The listing result is an object with property "items". Each item is
|
||||||
|
* an image.
|
||||||
|
*
|
||||||
|
* @param {Object} params
|
||||||
|
* Query parameters. Optional.
|
||||||
|
*
|
||||||
|
* @param {boolean} params.paginate
|
||||||
|
* True to paginate automatically.
|
||||||
|
*
|
||||||
|
* @param {string} params.marker
|
||||||
|
* Specifies the image of the last-seen image.
|
||||||
|
*
|
||||||
|
* The typical pattern of limit and marker is to make an
|
||||||
|
* initial limited request and then to use the last
|
||||||
|
* image from the response as the marker parameter
|
||||||
|
* in a subsequent limited request. With paginate, limit
|
||||||
|
* is automatically set.
|
||||||
|
*
|
||||||
|
* @param {string} params.sort_dir
|
||||||
|
* The sort direction ('asc' or 'desc').
|
||||||
|
*
|
||||||
|
* @param {string} params.sort_key
|
||||||
|
* The field to sort on (for example, 'created_at').
|
||||||
|
* Default is created_at.
|
||||||
|
*
|
||||||
|
* @param {string} params.other
|
||||||
|
* Any additional request parameters will be passed through the API as
|
||||||
|
* filters. For example "name" : "fedora" would filter on the fedora name.
|
||||||
|
*/
|
||||||
|
this.getImages = function(params) {
|
||||||
|
var config = (params) ? { 'params' : params} : {};
|
||||||
|
return apiService.get('/api/glance/images/', config)
|
||||||
|
.error(function () {
|
||||||
|
horizon.alert('error', gettext('Unable to retrieve images.'));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Metadata Definitions - Namespaces
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name hz.api.glanceAPI.getNamespaces
|
||||||
|
* @description
|
||||||
|
* Get a list of metadata definition namespaces.
|
||||||
|
*
|
||||||
|
* http://docs.openstack.org/developer/glance/metadefs-concepts.html
|
||||||
|
*
|
||||||
|
* The listing result is an object with property "items". Each item is
|
||||||
|
* an namespace.
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Get a list of namespaces.
|
||||||
|
*
|
||||||
|
* The listing result is an object with property "items". Each item is
|
||||||
|
* a namespace.
|
||||||
|
*
|
||||||
|
* @param {Object} params
|
||||||
|
* Query parameters. Optional.
|
||||||
|
*
|
||||||
|
* @param {boolean} params.paginate
|
||||||
|
* True to paginate automatically.
|
||||||
|
*
|
||||||
|
* @param {string} params.marker
|
||||||
|
* Specifies the namespace of the last-seen namespace.
|
||||||
|
*
|
||||||
|
* The typical pattern of limit and marker is to make an
|
||||||
|
* initial limited request and then to use the last
|
||||||
|
* namespace from the response as the marker parameter
|
||||||
|
* in a subsequent limited request. With paginate, limit
|
||||||
|
* is automatically set.
|
||||||
|
*
|
||||||
|
* @param {string} params.sort_dir
|
||||||
|
* The sort direction ('asc' or 'desc').
|
||||||
|
*
|
||||||
|
* @param {string} params.sort_key
|
||||||
|
* The field to sort on (for example, 'created_at').
|
||||||
|
* Default is namespace.
|
||||||
|
*
|
||||||
|
* @param {string} params.other
|
||||||
|
* Any additional request parameters will be passed through the API as
|
||||||
|
* filters.
|
||||||
|
*/
|
||||||
|
this.getNamespaces = function(params) {
|
||||||
|
var config = (params) ? { 'params' : params} : {};
|
||||||
|
return apiService.get('/api/glance/metadefs/namespaces/', config)
|
||||||
|
.error(function () {
|
||||||
|
horizon.alert('error', gettext('Unable to retrieve namespaces.'));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name hz.api.glanceAPI.getImages
|
||||||
|
* @description
|
||||||
|
* Get a specific namespace.
|
||||||
|
*
|
||||||
|
* http://docs.openstack.org/developer/glance/metadefs-concepts.html
|
||||||
|
*/
|
||||||
|
this.getNamespace = function(namespace) {
|
||||||
|
return apiService.get('/api/glance/metadefs/namespaces/' + namespace)
|
||||||
|
.error(function () {
|
||||||
|
horizon.alert('error', gettext('Unable to retrieve namespace.'));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register it with the API module so that anybody using the
|
||||||
|
// API module will have access to the Glance APIs.
|
||||||
|
|
||||||
|
angular.module('hz.api')
|
||||||
|
.service('glanceAPI', ['apiService', GlanceAPI]);
|
||||||
|
|
||||||
|
}());
|
|
@ -21,6 +21,7 @@
|
||||||
<script src='{{ STATIC_URL }}horizon/js/angular/hz.api.module.js'></script>
|
<script src='{{ STATIC_URL }}horizon/js/angular/hz.api.module.js'></script>
|
||||||
<script src='{{ STATIC_URL }}horizon/js/angular/services/hz.api.service.js'></script>
|
<script src='{{ STATIC_URL }}horizon/js/angular/services/hz.api.service.js'></script>
|
||||||
<script src='{{ STATIC_URL }}horizon/js/angular/services/hz.api.keystone.js'></script>
|
<script src='{{ STATIC_URL }}horizon/js/angular/services/hz.api.keystone.js'></script>
|
||||||
|
<script src='{{ STATIC_URL }}horizon/js/angular/services/hz.api.glance.js'></script>
|
||||||
|
|
||||||
<script src='{{ STATIC_URL }}angular/widget.module.js'></script>
|
<script src='{{ STATIC_URL }}angular/widget.module.js'></script>
|
||||||
<script src='{{ STATIC_URL }}angular/help-panel/help-panel.js'></script>
|
<script src='{{ STATIC_URL }}angular/help-panel/help-panel.js'></script>
|
||||||
|
|
|
@ -168,6 +168,9 @@ class BaseGlanceMetadefAPIResourceWrapper(base.APIResourceWrapper):
|
||||||
result[attr] = getattr(self, attr)
|
result[attr] = getattr(self, attr)
|
||||||
return json.dumps(result, indent=indent)
|
return json.dumps(result, indent=indent)
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
return self._apiresource
|
||||||
|
|
||||||
|
|
||||||
class Namespace(BaseGlanceMetadefAPIResourceWrapper):
|
class Namespace(BaseGlanceMetadefAPIResourceWrapper):
|
||||||
|
|
||||||
|
@ -222,7 +225,8 @@ def metadefs_namespace_list(request,
|
||||||
typically at first deployment is done in a single transaction
|
typically at first deployment is done in a single transaction
|
||||||
giving them a potentially unpredictable sort result when using
|
giving them a potentially unpredictable sort result when using
|
||||||
create_at.
|
create_at.
|
||||||
:param filters: specifies addition fields to filter on such as name.
|
:param filters: specifies addition fields to filter on such as
|
||||||
|
resource_types.
|
||||||
:returns A tuple of three values:
|
:returns A tuple of three values:
|
||||||
1) Current page results
|
1) Current page results
|
||||||
2) A boolean of whether or not there are previous page(s).
|
2) A boolean of whether or not there are previous page(s).
|
||||||
|
|
|
@ -22,4 +22,5 @@ in https://wiki.openstack.org/wiki/APIChangeGuidelines.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# import REST API modules here
|
# import REST API modules here
|
||||||
|
import glance #flake8: noqa
|
||||||
import keystone #flake8: noqa
|
import keystone #flake8: noqa
|
||||||
|
|
|
@ -0,0 +1,176 @@
|
||||||
|
|
||||||
|
# Copyright 2015, Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
"""API for the glance service.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from django.views import generic
|
||||||
|
|
||||||
|
from openstack_dashboard import api
|
||||||
|
from openstack_dashboard.api.rest import utils as rest_utils
|
||||||
|
from openstack_dashboard.api.rest import urls
|
||||||
|
|
||||||
|
|
||||||
|
CLIENT_KEYWORDS = {'marker', 'sort_dir', 'sort_key', 'paginate'}
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_filters_kwargs(request):
|
||||||
|
"""REST request parameters are separated appropriately.
|
||||||
|
|
||||||
|
Glance client processes some keywords separately
|
||||||
|
from filters and takes them as separate inputs.
|
||||||
|
This potentially may not be needed when Glance
|
||||||
|
v2 support is brought into Horizon via a separate effort.
|
||||||
|
"""
|
||||||
|
filters = {}
|
||||||
|
kwargs = {}
|
||||||
|
for param in request.GET:
|
||||||
|
if param in CLIENT_KEYWORDS:
|
||||||
|
kwargs[param] = request.GET[param]
|
||||||
|
else:
|
||||||
|
filters[param] = request.GET[param]
|
||||||
|
return filters, kwargs
|
||||||
|
|
||||||
|
|
||||||
|
@urls.register
|
||||||
|
class Image(generic.View):
|
||||||
|
"""API for retrieving a single image
|
||||||
|
"""
|
||||||
|
url_regex = r'glance/images/(?P<image_id>.+|default)$'
|
||||||
|
|
||||||
|
@rest_utils.ajax()
|
||||||
|
def get(self, request, image_id):
|
||||||
|
"""Get a specific image
|
||||||
|
|
||||||
|
http://localhost/api/glance/images/cc758c90-3d98-4ea1-af44-aab405c9c915
|
||||||
|
"""
|
||||||
|
return api.glance.image_get(request, image_id).to_dict()
|
||||||
|
|
||||||
|
|
||||||
|
@urls.register
|
||||||
|
class Images(generic.View):
|
||||||
|
"""API for Glance images.
|
||||||
|
"""
|
||||||
|
url_regex = r'glance/images/$'
|
||||||
|
|
||||||
|
@rest_utils.ajax()
|
||||||
|
def get(self, request):
|
||||||
|
"""Get a list of images.
|
||||||
|
|
||||||
|
The listing result is an object with property "items". Each item is
|
||||||
|
an image.
|
||||||
|
|
||||||
|
Example GET:
|
||||||
|
http://localhost/api/glance/images?sort_dir=desc&sort_key=name&name=cirros-0.3.2-x86_64-uec #flake8: noqa
|
||||||
|
|
||||||
|
The following get parameters may be passed in the GET
|
||||||
|
request:
|
||||||
|
|
||||||
|
:param paginate: If true will perform pagination based on settings.
|
||||||
|
:param marker: Specifies the namespace of the last-seen image.
|
||||||
|
The typical pattern of limit and marker is to make an
|
||||||
|
initial limited request and then to use the last
|
||||||
|
namespace from the response as the marker parameter
|
||||||
|
in a subsequent limited request. With paginate, limit
|
||||||
|
is automatically set.
|
||||||
|
:param sort_dir: The sort direction ('asc' or 'desc').
|
||||||
|
:param sort_key: The field to sort on (for example, 'created_at').
|
||||||
|
Default is created_at.
|
||||||
|
|
||||||
|
Any additional request parameters will be passed through the API as
|
||||||
|
filters. There are v1/v2 complications which are being addressed as a
|
||||||
|
separate work stream: https://review.openstack.org/#/c/150084/
|
||||||
|
"""
|
||||||
|
|
||||||
|
filters, kwargs = _parse_filters_kwargs(request)
|
||||||
|
|
||||||
|
images, has_more_data, has_prev_data = api.glance.image_list_detailed(
|
||||||
|
request, filters=filters, **kwargs)
|
||||||
|
|
||||||
|
return {
|
||||||
|
'items': [i.to_dict() for i in images],
|
||||||
|
'has_more_data': has_more_data,
|
||||||
|
'has_prev_data': has_prev_data,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@urls.register
|
||||||
|
class MetadefsNamespace(generic.View):
|
||||||
|
"""API for Glance Metadata Definitions.
|
||||||
|
|
||||||
|
http://docs.openstack.org/developer/glance/metadefs-concepts.html
|
||||||
|
"""
|
||||||
|
url_regex = r'glance/metadefs/namespaces/(?P<namespace>.+|default)$'
|
||||||
|
|
||||||
|
@rest_utils.ajax()
|
||||||
|
def get(self, request, namespace):
|
||||||
|
"""Get a specific metadata definition namespaces.
|
||||||
|
|
||||||
|
Returns the namespace. GET params are passed through.
|
||||||
|
|
||||||
|
Example GET:
|
||||||
|
http://localhost/api/glance/metadefs/namespaces/OS::Compute::Watchdog
|
||||||
|
"""
|
||||||
|
return api.glance.metadefs_namespace_get(request, namespace)
|
||||||
|
|
||||||
|
|
||||||
|
@urls.register
|
||||||
|
class MetadefsNamespaces(generic.View):
|
||||||
|
"""API for Single Glance Metadata Definitions.
|
||||||
|
|
||||||
|
http://docs.openstack.org/developer/glance/metadefs-concepts.html
|
||||||
|
"""
|
||||||
|
url_regex = r'glance/metadefs/namespaces/$'
|
||||||
|
|
||||||
|
@rest_utils.ajax()
|
||||||
|
def get(self, request):
|
||||||
|
"""Get a list of metadata definition namespaces.
|
||||||
|
|
||||||
|
The listing result is an object with property "items". Each item is
|
||||||
|
a namespace.
|
||||||
|
|
||||||
|
Example GET:
|
||||||
|
http://localhost/api/glance/metadefs/namespaces?resource_types=OS::Nova::Flavor&sort_dir=desc&marker=OS::Compute::Watchdog&paginate=False&sort_key=namespace #flake8: noqa
|
||||||
|
|
||||||
|
The following get parameters may be passed in the GET
|
||||||
|
request:
|
||||||
|
|
||||||
|
:param paginate: If true will perform pagination based on settings.
|
||||||
|
:param marker: Specifies the namespace of the last-seen namespace.
|
||||||
|
The typical pattern of limit and marker is to make an
|
||||||
|
initial limited request and then to use the last
|
||||||
|
namespace from the response as the marker parameter
|
||||||
|
in a subsequent limited request. With paginate, limit
|
||||||
|
is automatically set.
|
||||||
|
:param sort_dir: The sort direction ('asc' or 'desc').
|
||||||
|
:param sort_key: The field to sort on (for example, 'created_at').
|
||||||
|
Default is namespace. The way base namespaces are loaded into
|
||||||
|
glance typically at first deployment is done in a single
|
||||||
|
transaction giving them a potentially unpredictable sort result
|
||||||
|
when using create_at.
|
||||||
|
|
||||||
|
Any additional request parameters will be passed through the API as
|
||||||
|
filters.
|
||||||
|
"""
|
||||||
|
|
||||||
|
filters, kwargs = _parse_filters_kwargs(request)
|
||||||
|
|
||||||
|
namespaces, has_more, has_prev = api.glance.metadefs_namespace_list(
|
||||||
|
request, filters=filters, **kwargs)
|
||||||
|
|
||||||
|
return {
|
||||||
|
'items': [n.to_dict() for n in namespaces],
|
||||||
|
'has_more_data': has_more,
|
||||||
|
'has_prev_data': has_prev,
|
||||||
|
}
|
|
@ -0,0 +1,153 @@
|
||||||
|
# Copyright 2015, Rackspace, US, Inc.
|
||||||
|
# Copyright 2015, Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
import mock
|
||||||
|
|
||||||
|
from openstack_dashboard.api.rest import glance
|
||||||
|
from openstack_dashboard.test.api_tests import rest_test_utils # noqa
|
||||||
|
from openstack_dashboard.test import helpers as test
|
||||||
|
|
||||||
|
|
||||||
|
class ImagesRestTestCase(test.APITestCase):
|
||||||
|
def assertStatusCode(self, response, expected_code):
|
||||||
|
if response.status_code == expected_code:
|
||||||
|
return
|
||||||
|
self.fail('status code %r != %r: %s' % (response.status_code,
|
||||||
|
expected_code,
|
||||||
|
response.content))
|
||||||
|
|
||||||
|
@mock.patch.object(glance.api, 'glance')
|
||||||
|
def test_image_get_single(self, gc):
|
||||||
|
request = rest_test_utils.construct_request()
|
||||||
|
gc.image_get.return_value.to_dict.return_value = {'name': '1'}
|
||||||
|
|
||||||
|
response = glance.Image().get(request, "1")
|
||||||
|
self.assertStatusCode(response, 200)
|
||||||
|
gc.image_get.assert_called_once_with(request, "1")
|
||||||
|
|
||||||
|
@mock.patch.object(glance.api, 'glance')
|
||||||
|
def test_image_get_list_detailed(self, gc):
|
||||||
|
kwargs = {
|
||||||
|
'sort_dir': 'desc',
|
||||||
|
'sort_key': 'namespace',
|
||||||
|
'marker': 1,
|
||||||
|
'paginate': False,
|
||||||
|
}
|
||||||
|
filters = {'name': 'fedora'}
|
||||||
|
request = rest_test_utils.construct_request(
|
||||||
|
**{'GET': dict(kwargs, **filters)})
|
||||||
|
gc.image_list_detailed.return_value = ([
|
||||||
|
mock.Mock(**{'to_dict.return_value': {'name': 'fedora'}}),
|
||||||
|
mock.Mock(**{'to_dict.return_value': {'name': 'cirros'}})
|
||||||
|
], False, False)
|
||||||
|
|
||||||
|
response = glance.Images().get(request)
|
||||||
|
self.assertStatusCode(response, 200)
|
||||||
|
self.assertEqual(response.content,
|
||||||
|
'{"items": [{"name": "fedora"}, {"name": "cirros"}]'
|
||||||
|
', "has_more_data": false, "has_prev_data": false}')
|
||||||
|
gc.image_list_detailed.assert_called_once_with(request,
|
||||||
|
filters=filters,
|
||||||
|
**kwargs)
|
||||||
|
|
||||||
|
@mock.patch.object(glance.api, 'glance')
|
||||||
|
def test_namespace_get_list(self, gc):
|
||||||
|
request = rest_test_utils.construct_request(**{'GET': {}})
|
||||||
|
gc.metadefs_namespace_list.return_value = ([
|
||||||
|
mock.Mock(**{'to_dict.return_value': {'namespace': '1'}}),
|
||||||
|
mock.Mock(**{'to_dict.return_value': {'namespace': '2'}})
|
||||||
|
], False, False)
|
||||||
|
|
||||||
|
response = glance.MetadefsNamespaces().get(request)
|
||||||
|
self.assertStatusCode(response, 200)
|
||||||
|
self.assertEqual(response.content,
|
||||||
|
'{"items": [{"namespace": "1"}, {"namespace": "2"}]'
|
||||||
|
', "has_more_data": false, "has_prev_data": false}')
|
||||||
|
gc.metadefs_namespace_list.assert_called_once_with(request,
|
||||||
|
filters={},
|
||||||
|
**{})
|
||||||
|
|
||||||
|
@mock.patch.object(glance.api, 'glance')
|
||||||
|
def test_namespace_get_list_kwargs_and_filters(self, gc):
|
||||||
|
kwargs = {
|
||||||
|
'sort_dir': 'desc',
|
||||||
|
'sort_key': 'namespace',
|
||||||
|
'marker': 1,
|
||||||
|
'paginate': False,
|
||||||
|
}
|
||||||
|
filters = {'resource_types': 'type'}
|
||||||
|
request = rest_test_utils.construct_request(
|
||||||
|
**{'GET': dict(kwargs, **filters)})
|
||||||
|
gc.metadefs_namespace_list.return_value = ([
|
||||||
|
mock.Mock(**{'to_dict.return_value': {'namespace': '1'}}),
|
||||||
|
mock.Mock(**{'to_dict.return_value': {'namespace': '2'}})
|
||||||
|
], False, False)
|
||||||
|
|
||||||
|
response = glance.MetadefsNamespaces().get(request)
|
||||||
|
self.assertStatusCode(response, 200)
|
||||||
|
self.assertEqual(response.content,
|
||||||
|
'{"items": [{"namespace": "1"}, {"namespace": "2"}]'
|
||||||
|
', "has_more_data": false, "has_prev_data": false}')
|
||||||
|
gc.metadefs_namespace_list.assert_called_once_with(request,
|
||||||
|
filters=filters,
|
||||||
|
**kwargs)
|
||||||
|
|
||||||
|
@mock.patch.object(glance.api, 'glance')
|
||||||
|
def test_namespace_get_namespace(self, gc):
|
||||||
|
kwargs = {'resource_type': ['OS::Nova::Flavor']}
|
||||||
|
request = rest_test_utils.construct_request(**{'GET': dict(kwargs)})
|
||||||
|
gc.metadefs_namespace_get.return_value\
|
||||||
|
.to_dict.return_value = {'namespace': '1'}
|
||||||
|
|
||||||
|
response = glance.MetadefsNamespace().get(request, "1")
|
||||||
|
self.assertStatusCode(response, 200)
|
||||||
|
gc.metadefs_namespace_get.assert_called_once_with(request,
|
||||||
|
"1")
|
||||||
|
|
||||||
|
def test_parse_filters_keywords(self):
|
||||||
|
kwargs = {
|
||||||
|
'sort_dir': '1',
|
||||||
|
'sort_key': '2',
|
||||||
|
}
|
||||||
|
filters = {
|
||||||
|
'filter1': '1',
|
||||||
|
'filter2': '2',
|
||||||
|
}
|
||||||
|
|
||||||
|
# Combined
|
||||||
|
request_params = dict(kwargs)
|
||||||
|
request_params.update(filters)
|
||||||
|
request = rest_test_utils.construct_request(
|
||||||
|
**{'GET': dict(request_params)})
|
||||||
|
output_filters, output_kwargs = glance._parse_filters_kwargs(request)
|
||||||
|
self.assertDictEqual(kwargs, output_kwargs)
|
||||||
|
self.assertDictEqual(filters, output_filters)
|
||||||
|
|
||||||
|
# Empty Filters
|
||||||
|
request = rest_test_utils.construct_request(**{'GET': dict(kwargs)})
|
||||||
|
output_filters, output_kwargs = glance._parse_filters_kwargs(request)
|
||||||
|
self.assertDictEqual(kwargs, output_kwargs)
|
||||||
|
self.assertDictEqual({}, output_filters)
|
||||||
|
|
||||||
|
# Emtpy keywords
|
||||||
|
request = rest_test_utils.construct_request(**{'GET': dict(filters)})
|
||||||
|
output_filters, output_kwargs = glance._parse_filters_kwargs(request)
|
||||||
|
self.assertDictEqual({}, output_kwargs)
|
||||||
|
self.assertDictEqual(filters, output_filters)
|
||||||
|
|
||||||
|
# Empty both
|
||||||
|
request = rest_test_utils.construct_request(**{'GET': dict()})
|
||||||
|
output_filters, output_kwargs = glance._parse_filters_kwargs(request)
|
||||||
|
self.assertDictEqual({}, output_kwargs)
|
||||||
|
self.assertDictEqual({}, output_filters)
|
Loading…
Reference in New Issue