summaryrefslogtreecommitdiff
path: root/openstackclient/api
diff options
context:
space:
mode:
Diffstat (limited to 'openstackclient/api')
-rw-r--r--openstackclient/api/image_v1.py2
-rw-r--r--openstackclient/api/image_v2.py9
-rw-r--r--openstackclient/api/utils.py84
3 files changed, 89 insertions, 6 deletions
diff --git a/openstackclient/api/image_v1.py b/openstackclient/api/image_v1.py
index f9c780a4..c363ce49 100644
--- a/openstackclient/api/image_v1.py
+++ b/openstackclient/api/image_v1.py
@@ -49,8 +49,6 @@ class APIv1(api.BaseAPI):
http://docs.openstack.org/api/openstack-image-service/1.1/content/requesting-a-list-of-public-vm-images.html
http://docs.openstack.org/api/openstack-image-service/1.1/content/requesting-detailed-metadata-on-public-vm-images.html
http://docs.openstack.org/api/openstack-image-service/1.1/content/filtering-images-returned-via-get-images-and-get-imagesdetail.html
-
- TODO(dtroyer): Implement filtering
"""
url = "/images"
diff --git a/openstackclient/api/image_v2.py b/openstackclient/api/image_v2.py
index c5c78431..37c2ed83 100644
--- a/openstackclient/api/image_v2.py
+++ b/openstackclient/api/image_v2.py
@@ -30,6 +30,7 @@ class APIv2(image_v1.APIv1):
detailed=False,
public=False,
private=False,
+ shared=False,
**filter
):
"""Get available images
@@ -49,17 +50,17 @@ class APIv2(image_v1.APIv1):
both public and private images which is the same set as all images.
http://docs.openstack.org/api/openstack-image-service/2.0/content/list-images.html
-
- TODO(dtroyer): Implement filtering
"""
- if public == private:
- # No filtering for both False and both True cases
+ if not public and not private and not shared:
+ # No filtering for all False
filter.pop('visibility', None)
elif public:
filter['visibility'] = 'public'
elif private:
filter['visibility'] = 'private'
+ elif shared:
+ filter['visibility'] = 'shared'
url = "/images"
if detailed:
diff --git a/openstackclient/api/utils.py b/openstackclient/api/utils.py
new file mode 100644
index 00000000..b7ff7f23
--- /dev/null
+++ b/openstackclient/api/utils.py
@@ -0,0 +1,84 @@
+# 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 Utilities Library"""
+
+
+def simple_filter(
+ data=None,
+ attr=None,
+ value=None,
+ property_field=None,
+):
+ """Filter a list of dicts
+
+ :param list data:
+ The list to be filtered. The list is modified in-place and will
+ be changed if any filtering occurs.
+ :param string attr:
+ The name of the attribute to filter. If attr does not exist no
+ match will succeed and no rows will be retrurned. If attr is
+ None no filtering will be performed and all rows will be returned.
+ :param sring value:
+ The value to filter. None is considered to be a 'no filter' value.
+ '' matches agains a Python empty string.
+ :param string property_field:
+ The name of the data field containing a property dict to filter.
+ If property_field is None, attr is a field name. If property_field
+ is not None, attr is a property key name inside the named property
+ field.
+
+ :returns:
+ Returns the filtered list
+ :rtype list:
+
+ This simple filter (one attribute, one exact-match value) searches a
+ list of dicts to select items. It first searches the item dict for a
+ matching ``attr`` then does an exact-match on the ``value``. If
+ ``property_field`` is given, it will look inside that field (if it
+ exists and is a dict) for a matching ``value``.
+ """
+
+ # Take the do-nothing case shortcut
+ if not data or not attr or value is None:
+ return data
+
+ # NOTE:(dtroyer): This filter modifies the provided list in-place using
+ # list.remove() so we need to start at the end so the loop pointer does
+ # not skip any items after a deletion.
+ for d in reversed(data):
+ if attr in d:
+ # Searching data fields
+ search_value = d[attr]
+ elif (property_field and property_field in d and
+ type(d[property_field]) is dict):
+ # Searching a properties field - do this separately because
+ # we don't want to fail over to checking the fields if a
+ # property name is given.
+ if attr in d[property_field]:
+ search_value = d[property_field][attr]
+ else:
+ search_value = None
+ else:
+ search_value = None
+
+ # could do regex here someday...
+ if not search_value or search_value != value:
+ # remove from list
+ try:
+ data.remove(d)
+ except ValueError:
+ # it's already gone!
+ pass
+
+ return data