Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 30 additions & 4 deletions SoftLayer/CLI/call_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@
import click

from SoftLayer.CLI import environment
from SoftLayer.CLI import exceptions
from SoftLayer.CLI import formatting
from SoftLayer.CLI import helpers
from SoftLayer import utils

SPLIT_TOKENS = [
('in', ' IN '),
('eq', '='),
]


def _build_filters(_filters):
"""Builds filters using the filter options passed into the CLI.
Expand All @@ -14,17 +20,35 @@ def _build_filters(_filters):
"""
root = utils.NestedDict({})
for _filter in _filters:
# split "some.key=value" into ["some.key", "value"]
key, value = _filter.split('=', 1)

operation = None
for operation, token in SPLIT_TOKENS:
# split "some.key=value" into ["some.key", "value"]
top_parts = _filter.split(token, 1)
if len(top_parts) == 2:
break
else:
raise exceptions.CLIAbort('Failed to find valid operation for: %s'
% _filter)

key, value = top_parts
current = root
# split "some.key" into ["some", "key"]
parts = [part.strip() for part in key.split('.')]

# Actually drill down and add the filter
for part in parts[:-1]:
current = current[part]
current[parts[-1]] = utils.query_filter(value.strip())

if operation == 'eq':
current[parts[-1]] = utils.query_filter(value.strip())
elif operation == 'in':
current[parts[-1]] = {
'operation': 'in',
'options': [{
'name': 'data',
'value': [p.strip() for p in value.split(',')],
}],
}

return root.to_dict()

Expand Down Expand Up @@ -74,6 +98,8 @@ def cli(env, service, method, parameters, _id, _filters, mask, limit, offset,
-f 'virtualGuests.datacenter.name=dal05' \\
-f 'virtualGuests.maxCpu=4' \\
--mask=id,hostname,datacenter.name,maxCpu
slcli call-api Account getVirtualGuests \\
-f 'virtualGuests.datacenter.name IN dal05,sng01'
"""

args = [service, method] + list(parameters)
Expand Down
45 changes: 45 additions & 0 deletions tests/CLI/modules/call_api_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@
import json

from SoftLayer.CLI import call_api
from SoftLayer.CLI import exceptions
from SoftLayer import testing

import pytest


class BuildFilterTests(testing.TestCase):

Expand All @@ -30,6 +33,48 @@ def test_multi(self):
'prop2': {'operation': '_= prop2'},
}

def test_in(self):
result = call_api._build_filters(['prop IN value1,value2'])
assert result == {
'prop': {
'operation': 'in',
'options': [{'name': 'data', 'value': ['value1', 'value2']}],
}
}

def test_in_multi(self):
result = call_api._build_filters([
'prop_a IN a_val1,a_val2',
'prop_b IN b_val1,b_val2',
])
assert result == {
'prop_a': {
'operation': 'in',
'options': [{'name': 'data', 'value': ['a_val1', 'a_val2']}],
},
'prop_b': {
'operation': 'in',
'options': [{'name': 'data', 'value': ['b_val1', 'b_val2']}],
},
}

def test_in_with_whitespace(self):
result = call_api._build_filters(['prop IN value1 , value2 '])
assert result == {
'prop': {
'operation': 'in',
'options': [{'name': 'data', 'value': ['value1', 'value2']}],
}
}

def test_invalid_operation(self):
with pytest.raises(exceptions.CLIAbort):
call_api._build_filters(['prop N/A value1'])

def test_only_whitespace(self):
with pytest.raises(exceptions.CLIAbort):
call_api._build_filters([' '])


class CallCliTests(testing.TestCase):

Expand Down