Skip to content

Commit deaa4eb

Browse files
Merge pull request #2202 from softlayer/issues1949
Added feature to iter_call to force a orderBy filter
2 parents c226a74 + 2044aba commit deaa4eb

22 files changed

+243
-116
lines changed

SoftLayer/API.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from SoftLayer import consts
2020
from SoftLayer import exceptions
2121
from SoftLayer import transports
22+
from SoftLayer import utils
2223

2324
LOGGER = logging.getLogger(__name__)
2425
API_PUBLIC_ENDPOINT = consts.API_PUBLIC_ENDPOINT
@@ -403,6 +404,7 @@ def iter_call(self, service, method, *args, **kwargs):
403404
kwargs['iter'] = False
404405
result_count = 0
405406
keep_looping = True
407+
kwargs['filter'] = utils.fix_filter(kwargs.get('filter'))
406408

407409
while keep_looping:
408410
# Get the next results

SoftLayer/CLI/environment.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ def getpass(self, prompt, default=None):
111111
# In windows, shift+insert actually inputs the below 2 characters
112112
# If we detect those 2 characters, need to manually read from the clipbaord instead
113113
# https://stackoverflow.com/questions/101128/how-do-i-read-text-from-the-clipboard
114+
# LINUX NOTICE: `apt-get install python3-tk` required to install tk
114115
if password == 'àR':
115116
# tkinter is a built in python gui, but it has clipboard reading functions.
116117
# pylint: disable=import-outside-toplevel

SoftLayer/managers/block.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,23 +53,21 @@ def list_block_volumes(self, datacenter=None, username=None, storage_type=None,
5353
_filter = utils.NestedDict(kwargs.get('filter') or {})
5454

5555
_filter['iscsiNetworkStorage']['serviceResource']['type']['type'] = utils.query_filter('!~ ISCSI')
56+
_filter['iscsiNetworkStorage']['id'] = utils.query_filter_orderby()
5657

57-
_filter['iscsiNetworkStorage']['storageType']['keyName'] = (
58-
utils.query_filter('*BLOCK_STORAGE*'))
58+
_filter['iscsiNetworkStorage']['storageType']['keyName'] = utils.query_filter('*BLOCK_STORAGE*')
5959
if storage_type:
6060
_filter['iscsiNetworkStorage']['storageType']['keyName'] = (
6161
utils.query_filter('%s_BLOCK_STORAGE*' % storage_type.upper()))
6262

6363
if datacenter:
64-
_filter['iscsiNetworkStorage']['serviceResource']['datacenter'][
65-
'name'] = utils.query_filter(datacenter)
64+
_filter['iscsiNetworkStorage']['serviceResource']['datacenter']['name'] = utils.query_filter(datacenter)
6665

6766
if username:
6867
_filter['iscsiNetworkStorage']['username'] = utils.query_filter(username)
6968

7069
if order:
71-
_filter['iscsiNetworkStorage']['billingItem']['orderItem'][
72-
'order']['id'] = utils.query_filter(order)
70+
_filter['iscsiNetworkStorage']['billingItem']['orderItem']['order']['id'] = utils.query_filter(order)
7371

7472
kwargs['filter'] = _filter.to_dict()
7573
return self.client.call('Account', 'getIscsiNetworkStorage', iter=True, **kwargs)

SoftLayer/managers/dns.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ def get_records(self, zone_id, ttl=None, data=None, host=None, record_type=None)
196196
:returns: A list of dictionaries representing the matching records within the specified zone.
197197
"""
198198
_filter = utils.NestedDict()
199+
_filter['resourceRecords']['id'] = utils.query_filter_orderby()
199200

200201
if ttl:
201202
_filter['resourceRecords']['ttl'] = utils.query_filter(ttl)

SoftLayer/managers/event_log.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,8 @@ def build_filter(date_min=None, date_max=None, obj_event=None, obj_id=None, obj_
6565
6666
:returns: dict: The generated query filter
6767
"""
68-
69-
if not any([date_min, date_max, obj_event, obj_id, obj_type]):
70-
return {}
71-
7268
request_filter = {}
69+
request_filter['traceId'] = utils.query_filter_orderby()
7370

7471
if date_min and date_max:
7572
request_filter['eventCreateDate'] = utils.event_log_filter_between_date(date_min, date_max, utc_offset)

SoftLayer/managers/file.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def list_file_volumes(self, datacenter=None, username=None, storage_type=None, o
4747
kwargs['mask'] = ','.join(items)
4848

4949
_filter = utils.NestedDict(kwargs.get('filter') or {})
50-
50+
_filter['nasNetworkStorage']['id'] = utils.query_filter_orderby()
5151
_filter['nasNetworkStorage']['serviceResource']['type']['type'] = utils.query_filter('!~ NAS')
5252

5353
_filter['nasNetworkStorage']['storageType']['keyName'] = (

SoftLayer/managers/image.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,12 @@ def list_private_images(self, guid=None, name=None, limit=100, **kwargs):
5757
kwargs['mask'] = IMAGE_MASK
5858

5959
_filter = utils.NestedDict(kwargs.get('filter') or {})
60+
_filter['privateBlockDeviceTemplateGroups']['id'] = utils.query_filter_orderby()
6061
if name:
61-
_filter['privateBlockDeviceTemplateGroups']['name'] = (
62-
utils.query_filter(name))
62+
_filter['privateBlockDeviceTemplateGroups']['name'] = utils.query_filter(name)
6363

6464
if guid:
65-
_filter['privateBlockDeviceTemplateGroups']['globalIdentifier'] = (
66-
utils.query_filter(guid))
65+
_filter['privateBlockDeviceTemplateGroups']['globalIdentifier'] = utils.query_filter(guid)
6766

6867
kwargs['filter'] = _filter.to_dict()
6968

@@ -81,6 +80,7 @@ def list_public_images(self, guid=None, name=None, limit=100, **kwargs):
8180
kwargs['mask'] = IMAGE_MASK
8281

8382
_filter = utils.NestedDict(kwargs.get('filter') or {})
83+
_filter['id'] = utils.query_filter_orderby()
8484
if name:
8585
_filter['name'] = utils.query_filter(name)
8686

SoftLayer/managers/network.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,7 @@ def list_subnets(self, identifier=None, datacenter=None, version=0,
496496
kwargs['mask'] = DEFAULT_SUBNET_MASK
497497

498498
_filter = utils.NestedDict(kwargs.get('filter') or {})
499+
_filter['subnets']['id'] = utils.query_filter_orderby()
499500

500501
if identifier:
501502
_filter['subnets']['networkIdentifier'] = (

SoftLayer/utils.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"""
77

88
import collections
9+
import copy
910
import datetime
1011
from json import JSONDecoder
1112
import re
@@ -41,6 +42,32 @@ def lookup(dic, key, *keys):
4142
return dic.get(key)
4243

4344

45+
def has_key_value(d: dict, key: str = "operation", value: str = "orderBy") -> bool:
46+
"""Scan through a dictionary looking for an orderBy clause, but can be used for any key/value combo"""
47+
if d.get(key) and d.get(key) == value:
48+
return True
49+
for x in d.values():
50+
if isinstance(x, dict):
51+
if has_key_value(x, key, value):
52+
return True
53+
return False
54+
55+
56+
def fix_filter(sl_filter: dict = None) -> dict:
57+
"""Forces an object filter to have an orderBy clause if it doesn't have one already"""
58+
59+
if sl_filter is None:
60+
sl_filter = {}
61+
62+
# Make a copy to prevent sl_filter from being modified by this function
63+
this_filter = copy.copy(sl_filter)
64+
if not has_key_value(this_filter, "operation", "orderBy"):
65+
# Check to see if 'id' is already a filter, if so just skip
66+
if not this_filter.get('id', False):
67+
this_filter['id'] = query_filter_orderby()
68+
return this_filter
69+
70+
4471
class NestedDict(dict):
4572
"""This helps with accessing a heavily nested dictionary.
4673

tests/CLI/modules/block_tests.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,8 @@ def test_volume_detail_name_identifier(self):
125125
'storageType': {
126126
'keyName': {'operation': '*= BLOCK_STORAGE'}
127127
},
128-
'username': {'operation': '_= SL-12345'}
128+
'username': {'operation': '_= SL-12345'},
129+
'id': {'operation': 'orderBy', 'options': [{'name': 'sort', 'value': ['ASC']}]}
129130
}
130131
}
131132

0 commit comments

Comments
 (0)