Skip to content

Commit bd1ecce

Browse files
Merge pull request #2189 from allmightyspiff/issues2037
Added --owner, --public_ip and --private_ip search fields for hardware list
2 parents 7b7446b + 8aeb2ce commit bd1ecce

File tree

5 files changed

+136
-78
lines changed

5 files changed

+136
-78
lines changed

SoftLayer/CLI/hardware/list.py

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
lambda server: formatting.active_txn(server),
2323
mask='activeTransaction[id, transactionStatus[name, friendlyName]]'),
2424
column_helper.Column(
25-
'created_by',
25+
'owner',
2626
lambda created_by: utils.lookup(created_by, 'billingItem', 'orderItem', 'order', 'userRecord', 'username'),
2727
mask='billingItem[id,orderItem[id,order[id,userRecord[username]]]]'),
2828
column_helper.Column(
@@ -38,6 +38,8 @@
3838
'backend_ip',
3939
'datacenter',
4040
'action',
41+
'owner',
42+
'tags',
4143
]
4244

4345

@@ -48,6 +50,9 @@
4850
@click.option('--hostname', '-H', help='Filter by hostname')
4951
@click.option('--memory', '-m', help='Filter by memory in gigabytes')
5052
@click.option('--network', '-n', help='Filter by network port speed in Mbps')
53+
@click.option('--owner', help='Filter by created_by username')
54+
@click.option('--primary_ip', help='Filter by Primary Ip Address')
55+
@click.option('--backend_ip', help='Filter by Backend Ip Address')
5156
@click.option('--search', is_flag=False, flag_value="", default=None,
5257
help="Use the more flexible Search API to list instances. See `slcli search --types` for list " +
5358
"of searchable fields.")
@@ -63,29 +68,41 @@
6368
default=100,
6469
show_default=True)
6570
@environment.pass_env
66-
def cli(env, sortby, cpu, domain, datacenter, hostname, memory, network, search, tag, columns, limit):
71+
def cli(env, sortby, cpu, domain, datacenter, hostname, memory, network, owner, primary_ip, backend_ip,
72+
search, tag, columns, limit):
6773
"""List hardware servers."""
6874

6975
if search is not None:
7076
object_mask = "mask[resource(SoftLayer_Hardware)]"
7177
search_manager = SoftLayer.SearchManager(env.client)
72-
servers = search_manager.search_hadrware_instances(hostname=hostname, domain=domain, datacenter=datacenter,
73-
tags=tag, search_string=search, mask=object_mask)
78+
servers = search_manager.search_hadrware_instances(
79+
hostname=hostname,
80+
domain=domain,
81+
datacenter=datacenter,
82+
tags=tag,
83+
search_string=search,
84+
mask=object_mask)
7485

7586
else:
7687
manager = SoftLayer.HardwareManager(env.client)
77-
servers = manager.list_hardware(hostname=hostname,
78-
domain=domain,
79-
cpus=cpu,
80-
memory=memory,
81-
datacenter=datacenter,
82-
nic_speed=network,
83-
tags=tag,
84-
mask="mask(SoftLayer_Hardware_Server)[%s]" % columns.mask(),
85-
limit=limit)
88+
servers = manager.list_hardware(
89+
hostname=hostname,
90+
domain=domain,
91+
cpus=cpu,
92+
memory=memory,
93+
datacenter=datacenter,
94+
nic_speed=network,
95+
tags=tag,
96+
owner=owner,
97+
public_ip=primary_ip,
98+
private_ip=backend_ip,
99+
mask="mask(SoftLayer_Hardware_Server)[%s]" % columns.mask(),
100+
limit=limit)
86101

87102
table = formatting.Table(columns.columns)
88103
table.sortby = sortby
104+
table.align['created_by'] = 'l'
105+
table.align['tags'] = 'l'
89106

90107
for server in servers:
91108
table.add_row([value or formatting.blank()

SoftLayer/managers/hardware.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ def cancel_hardware(self, hardware_id, reason='unneeded', comment='', immediate=
121121

122122
@retry(logger=LOGGER)
123123
def list_hardware(self, tags=None, cpus=None, memory=None, hostname=None,
124-
domain=None, datacenter=None, nic_speed=None,
124+
domain=None, datacenter=None, nic_speed=None, owner=None,
125125
public_ip=None, private_ip=None, **kwargs):
126126
"""List all hardware (servers and bare metal computing instances).
127127
@@ -169,15 +169,15 @@ def list_hardware(self, tags=None, cpus=None, memory=None, hostname=None,
169169
% (','.join(hw_items), ','.join(server_items)))
170170

171171
_filter = utils.NestedDict(kwargs.get('filter') or {})
172+
_filter['hardware']['id'] = utils.query_filter_orderby()
172173
if tags:
173174
_filter['hardware']['tagReferences']['tag']['name'] = {
174175
'operation': 'in',
175176
'options': [{'name': 'data', 'value': tags}],
176177
}
177178

178179
if cpus:
179-
_filter['hardware']['processorPhysicalCoreAmount'] = (
180-
utils.query_filter(cpus))
180+
_filter['hardware']['processorPhysicalCoreAmount'] = utils.query_filter(cpus)
181181

182182
if memory:
183183
_filter['hardware']['memoryCapacity'] = utils.query_filter(memory)
@@ -189,20 +189,20 @@ def list_hardware(self, tags=None, cpus=None, memory=None, hostname=None,
189189
_filter['hardware']['domain'] = utils.query_filter(domain)
190190

191191
if datacenter:
192-
_filter['hardware']['datacenter']['name'] = (
193-
utils.query_filter(datacenter))
192+
_filter['hardware']['datacenter']['name'] = utils.query_filter(datacenter)
194193

195194
if nic_speed:
196-
_filter['hardware']['networkComponents']['maxSpeed'] = (
197-
utils.query_filter(nic_speed))
195+
_filter['hardware']['networkComponents']['maxSpeed'] = utils.query_filter(nic_speed)
198196

199197
if public_ip:
200-
_filter['hardware']['primaryIpAddress'] = (
201-
utils.query_filter(public_ip))
198+
_filter['hardware']['primaryIpAddress'] = utils.query_filter(public_ip)
202199

203200
if private_ip:
204-
_filter['hardware']['primaryBackendIpAddress'] = (
205-
utils.query_filter(private_ip))
201+
_filter['hardware']['primaryBackendIpAddress'] = utils.query_filter(private_ip)
202+
203+
if owner:
204+
_filter['hardware']['billingItem']['orderItem']['order']['userRecord']['username'] = (
205+
utils.query_filter(owner))
206206

207207
kwargs['filter'] = _filter.to_dict()
208208
kwargs['iter'] = True

tests/CLI/modules/hardware/hardware_basic_tests.py

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -169,47 +169,6 @@ def test_detail_drives(self):
169169
self.assertEqual(output['drives'][0]['Name'], 'Seagate Constellation ES')
170170
self.assertEqual(output['drives'][0]['Serial #'], 'z1w4sdf')
171171

172-
def test_list_servers(self):
173-
result = self.run_command(['server', 'list', '--tag=openstack'])
174-
175-
expected = [
176-
{
177-
'datacenter': 'TEST00',
178-
'primary_ip': '172.16.1.100',
179-
'hostname': 'hardware-test1',
180-
'id': 1000,
181-
'backend_ip': '10.1.0.2',
182-
'action': 'TXN_NAME',
183-
},
184-
{
185-
'datacenter': 'TEST00',
186-
'primary_ip': '172.16.4.94',
187-
'hostname': 'hardware-test2',
188-
'id': 1001,
189-
'backend_ip': '10.1.0.3',
190-
'action': None,
191-
},
192-
{
193-
'datacenter': 'TEST00',
194-
'primary_ip': '172.16.4.95',
195-
'hostname': 'hardware-bad-memory',
196-
'id': 1002,
197-
'backend_ip': '10.1.0.4',
198-
'action': None,
199-
},
200-
{
201-
'action': None,
202-
'backend_ip': None,
203-
'datacenter': None,
204-
'hostname': None,
205-
'id': 1003,
206-
'primary_ip': None,
207-
},
208-
]
209-
210-
self.assert_no_fail(result)
211-
self.assertEqual(expected, json.loads(result.output))
212-
213172
@mock.patch('SoftLayer.CLI.formatting.no_going_back')
214173
@mock.patch('SoftLayer.HardwareManager.reload')
215174
def test_server_reload(self, reload_mock, ngb_mock):
@@ -992,17 +951,6 @@ def test_create_credential(self):
992951
'--notes', 'test slcli', '--software', 'system'])
993952
self.assert_no_fail(result)
994953

995-
def test_list_hw_search_noargs(self):
996-
result = self.run_command(['hw', 'list', '--search'])
997-
self.assert_no_fail(result)
998-
self.assert_called_with('SoftLayer_Search', 'advancedSearch', args=('_objectType:SoftLayer_Hardware ',))
999-
1000-
def test_list_hw_search_noargs_domain(self):
1001-
result = self.run_command(['hw', 'list', '--search', '-Dtest'])
1002-
self.assert_no_fail(result)
1003-
self.assert_called_with('SoftLayer_Search', 'advancedSearch',
1004-
args=('_objectType:SoftLayer_Hardware domain: *test*',))
1005-
1006954
@mock.patch('SoftLayer.CLI.formatting.confirm')
1007955
def test_hardware_cancel_no_force(self, confirm_mock):
1008956
confirm_mock.return_value = False
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
"""
2+
SoftLayer.tests.CLI.modules.hardware.hardware_list_tests
3+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4+
5+
These tests the `slcli hw list` command. Its complex enough to warrant its own file
6+
7+
:license: MIT, see LICENSE for more details.
8+
"""
9+
10+
import json
11+
12+
from SoftLayer import testing
13+
from SoftLayer import utils
14+
15+
16+
class HardwareListCLITests(testing.TestCase):
17+
def test_list_servers(self):
18+
colums = 'datacenter,primary_ip,hostname,id,backend_ip,action'
19+
result = self.run_command(['server', 'list', '--tag=openstack', f'--columns={colums}'])
20+
21+
expected = [
22+
{
23+
'datacenter': 'TEST00',
24+
'primary_ip': '172.16.1.100',
25+
'hostname': 'hardware-test1',
26+
'id': 1000,
27+
'backend_ip': '10.1.0.2',
28+
'action': 'TXN_NAME',
29+
},
30+
{
31+
'datacenter': 'TEST00',
32+
'primary_ip': '172.16.4.94',
33+
'hostname': 'hardware-test2',
34+
'id': 1001,
35+
'backend_ip': '10.1.0.3',
36+
'action': None,
37+
},
38+
{
39+
'datacenter': 'TEST00',
40+
'primary_ip': '172.16.4.95',
41+
'hostname': 'hardware-bad-memory',
42+
'id': 1002,
43+
'backend_ip': '10.1.0.4',
44+
'action': None,
45+
},
46+
{
47+
'action': None,
48+
'backend_ip': None,
49+
'datacenter': None,
50+
'hostname': None,
51+
'id': 1003,
52+
'primary_ip': None,
53+
},
54+
]
55+
56+
self.assert_no_fail(result)
57+
self.assertEqual(expected, json.loads(result.output))
58+
59+
def test_list_hw_search_noargs(self):
60+
result = self.run_command(['hw', 'list', '--search'])
61+
self.assert_no_fail(result)
62+
self.assert_called_with('SoftLayer_Search', 'advancedSearch', args=('_objectType:SoftLayer_Hardware ',))
63+
64+
def test_list_hw_search_noargs_domain(self):
65+
result = self.run_command(['hw', 'list', '--search', '-Dtest'])
66+
self.assert_no_fail(result)
67+
self.assert_called_with('SoftLayer_Search', 'advancedSearch',
68+
args=('_objectType:SoftLayer_Hardware domain: *test*',))
69+
70+
def test_list_by_owner(self):
71+
result = self.run_command(['hw', 'list', '--owner=testUser'])
72+
self.assert_no_fail(result)
73+
expectedFilter = utils.NestedDict()
74+
expectedFilter['hardware']['id'] = utils.query_filter_orderby()
75+
expectedFilter['hardware']['billingItem']['orderItem']['order']['userRecord']['username'] = (
76+
utils.query_filter('testUser'))
77+
self.assert_called_with('SoftLayer_Account', 'getHardware', filter=expectedFilter)
78+
79+
def test_list_by_pub_ip(self):
80+
result = self.run_command(['hw', 'list', '--primary_ip=1.2.3.4'])
81+
self.assert_no_fail(result)
82+
expectedFilter = utils.NestedDict()
83+
expectedFilter['hardware']['id'] = utils.query_filter_orderby()
84+
expectedFilter['hardware']['primaryIpAddress'] = utils.query_filter('1.2.3.4')
85+
self.assert_called_with('SoftLayer_Account', 'getHardware', filter=expectedFilter)
86+
87+
def test_list_by_pri_ip(self):
88+
result = self.run_command(['hw', 'list', '--backend_ip=1.2.3.4'])
89+
self.assert_no_fail(result)
90+
expectedFilter = utils.NestedDict()
91+
expectedFilter['hardware']['id'] = utils.query_filter_orderby()
92+
expectedFilter['hardware']['primaryBackendIpAddress'] = utils.query_filter('1.2.3.4')
93+
self.assert_called_with('SoftLayer_Account', 'getHardware', filter=expectedFilter)

tests/managers/hardware_tests.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ def test_list_hardware_with_filters(self):
5757
self.assertEqual(results, fixtures.SoftLayer_Account.getHardware)
5858
_filter = {
5959
'hardware': {
60+
'id': {'operation': 'orderBy', 'options': [{'name': 'sort', 'value': ['ASC']}]},
6061
'datacenter': {'name': {'operation': '_= dal05'}},
6162
'domain': {'operation': '_= example.com'},
6263
'tagReferences': {
@@ -73,8 +74,7 @@ def test_list_hardware_with_filters(self):
7374
'networkComponents': {'maxSpeed': {'operation': 100}},
7475
'primaryBackendIpAddress': {'operation': '_= 4.3.2.1'}}
7576
}
76-
self.assert_called_with('SoftLayer_Account', 'getHardware',
77-
filter=_filter)
77+
self.assert_called_with('SoftLayer_Account', 'getHardware', filter=_filter)
7878

7979
def test_resolve_ids_ip(self):
8080
_id = self.hardware._get_ids_from_ip('172.16.1.100')

0 commit comments

Comments
 (0)