Skip to content

Commit

Permalink
Added --owner, --public_ip and --private_ip search fields for hardwar…
Browse files Browse the repository at this point in the history
…e list, added owner and tags to the default output. Fixed #2037
  • Loading branch information
allmightyspiff committed Oct 3, 2024
1 parent 7b7446b commit 0e1d28f
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 76 deletions.
43 changes: 30 additions & 13 deletions SoftLayer/CLI/hardware/list.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
lambda server: formatting.active_txn(server),
mask='activeTransaction[id, transactionStatus[name, friendlyName]]'),
column_helper.Column(
'created_by',
'owner',
lambda created_by: utils.lookup(created_by, 'billingItem', 'orderItem', 'order', 'userRecord', 'username'),
mask='billingItem[id,orderItem[id,order[id,userRecord[username]]]]'),
column_helper.Column(
Expand All @@ -38,6 +38,8 @@
'backend_ip',
'datacenter',
'action',
'owner',
'tags',
]


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

if search is not None:
object_mask = "mask[resource(SoftLayer_Hardware)]"
search_manager = SoftLayer.SearchManager(env.client)
servers = search_manager.search_hadrware_instances(hostname=hostname, domain=domain, datacenter=datacenter,
tags=tag, search_string=search, mask=object_mask)
servers = search_manager.search_hadrware_instances(
hostname=hostname,
domain=domain,
datacenter=datacenter,
tags=tag,
search_string=search,
mask=object_mask)

else:
manager = SoftLayer.HardwareManager(env.client)
servers = manager.list_hardware(hostname=hostname,
domain=domain,
cpus=cpu,
memory=memory,
datacenter=datacenter,
nic_speed=network,
tags=tag,
mask="mask(SoftLayer_Hardware_Server)[%s]" % columns.mask(),
limit=limit)
servers = manager.list_hardware(
hostname=hostname,
domain=domain,
cpus=cpu,
memory=memory,
datacenter=datacenter,
nic_speed=network,
tags=tag,
owner=owner,
public_ip=primary_ip,
private_ip=backend_ip,
mask="mask(SoftLayer_Hardware_Server)[%s]" % columns.mask(),
limit=limit)

table = formatting.Table(columns.columns)
table.sortby = sortby
table.align['created_by'] = 'l'
table.align['tags'] = 'l'

for server in servers:
table.add_row([value or formatting.blank()
Expand Down
22 changes: 11 additions & 11 deletions SoftLayer/managers/hardware.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def cancel_hardware(self, hardware_id, reason='unneeded', comment='', immediate=

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

_filter = utils.NestedDict(kwargs.get('filter') or {})
_filter['id'] = utils.query_filter_orderby()
if tags:
_filter['hardware']['tagReferences']['tag']['name'] = {
'operation': 'in',
'options': [{'name': 'data', 'value': tags}],
}

if cpus:
_filter['hardware']['processorPhysicalCoreAmount'] = (
utils.query_filter(cpus))
_filter['hardware']['processorPhysicalCoreAmount'] = utils.query_filter(cpus)

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

if datacenter:
_filter['hardware']['datacenter']['name'] = (
utils.query_filter(datacenter))
_filter['hardware']['datacenter']['name'] = utils.query_filter(datacenter)

if nic_speed:
_filter['hardware']['networkComponents']['maxSpeed'] = (
utils.query_filter(nic_speed))
_filter['hardware']['networkComponents']['maxSpeed'] = utils.query_filter(nic_speed)

if public_ip:
_filter['hardware']['primaryIpAddress'] = (
utils.query_filter(public_ip))
_filter['hardware']['primaryIpAddress'] = utils.query_filter(public_ip)

if private_ip:
_filter['hardware']['primaryBackendIpAddress'] = (
utils.query_filter(private_ip))
_filter['hardware']['primaryBackendIpAddress'] = utils.query_filter(private_ip)

if owner:
_filter['hardware']['billingItem']['orderItem']['order']['userRecord']['username'] = (
utils.query_filter(owner))

kwargs['filter'] = _filter.to_dict()
kwargs['iter'] = True
Expand Down
52 changes: 0 additions & 52 deletions tests/CLI/modules/hardware/hardware_basic_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,47 +169,6 @@ def test_detail_drives(self):
self.assertEqual(output['drives'][0]['Name'], 'Seagate Constellation ES')
self.assertEqual(output['drives'][0]['Serial #'], 'z1w4sdf')

def test_list_servers(self):
result = self.run_command(['server', 'list', '--tag=openstack'])

expected = [
{
'datacenter': 'TEST00',
'primary_ip': '172.16.1.100',
'hostname': 'hardware-test1',
'id': 1000,
'backend_ip': '10.1.0.2',
'action': 'TXN_NAME',
},
{
'datacenter': 'TEST00',
'primary_ip': '172.16.4.94',
'hostname': 'hardware-test2',
'id': 1001,
'backend_ip': '10.1.0.3',
'action': None,
},
{
'datacenter': 'TEST00',
'primary_ip': '172.16.4.95',
'hostname': 'hardware-bad-memory',
'id': 1002,
'backend_ip': '10.1.0.4',
'action': None,
},
{
'action': None,
'backend_ip': None,
'datacenter': None,
'hostname': None,
'id': 1003,
'primary_ip': None,
},
]

self.assert_no_fail(result)
self.assertEqual(expected, json.loads(result.output))

@mock.patch('SoftLayer.CLI.formatting.no_going_back')
@mock.patch('SoftLayer.HardwareManager.reload')
def test_server_reload(self, reload_mock, ngb_mock):
Expand Down Expand Up @@ -992,17 +951,6 @@ def test_create_credential(self):
'--notes', 'test slcli', '--software', 'system'])
self.assert_no_fail(result)

def test_list_hw_search_noargs(self):
result = self.run_command(['hw', 'list', '--search'])
self.assert_no_fail(result)
self.assert_called_with('SoftLayer_Search', 'advancedSearch', args=('_objectType:SoftLayer_Hardware ',))

def test_list_hw_search_noargs_domain(self):
result = self.run_command(['hw', 'list', '--search', '-Dtest'])
self.assert_no_fail(result)
self.assert_called_with('SoftLayer_Search', 'advancedSearch',
args=('_objectType:SoftLayer_Hardware domain: *test*',))

@mock.patch('SoftLayer.CLI.formatting.confirm')
def test_hardware_cancel_no_force(self, confirm_mock):
confirm_mock.return_value = False
Expand Down
93 changes: 93 additions & 0 deletions tests/CLI/modules/hardware/hardware_list_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
"""
SoftLayer.tests.CLI.modules.hardware.hardware_list_tests
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
These tests the `slcli hw list` command. Its complex enough to warrant its own file
:license: MIT, see LICENSE for more details.
"""

import json

from SoftLayer import testing
from SoftLayer import utils


class HardwareListCLITests(testing.TestCase):
def test_list_servers(self):
colums = 'datacenter,primary_ip,hostname,id,backend_ip,action'
result = self.run_command(['server', 'list', '--tag=openstack', f'--columns={colums}'])

expected = [
{
'datacenter': 'TEST00',
'primary_ip': '172.16.1.100',
'hostname': 'hardware-test1',
'id': 1000,
'backend_ip': '10.1.0.2',
'action': 'TXN_NAME',
},
{
'datacenter': 'TEST00',
'primary_ip': '172.16.4.94',
'hostname': 'hardware-test2',
'id': 1001,
'backend_ip': '10.1.0.3',
'action': None,
},
{
'datacenter': 'TEST00',
'primary_ip': '172.16.4.95',
'hostname': 'hardware-bad-memory',
'id': 1002,
'backend_ip': '10.1.0.4',
'action': None,
},
{
'action': None,
'backend_ip': None,
'datacenter': None,
'hostname': None,
'id': 1003,
'primary_ip': None,
},
]

self.assert_no_fail(result)
self.assertEqual(expected, json.loads(result.output))

def test_list_hw_search_noargs(self):
result = self.run_command(['hw', 'list', '--search'])
self.assert_no_fail(result)
self.assert_called_with('SoftLayer_Search', 'advancedSearch', args=('_objectType:SoftLayer_Hardware ',))

def test_list_hw_search_noargs_domain(self):
result = self.run_command(['hw', 'list', '--search', '-Dtest'])
self.assert_no_fail(result)
self.assert_called_with('SoftLayer_Search', 'advancedSearch',
args=('_objectType:SoftLayer_Hardware domain: *test*',))

def test_list_by_owner(self):
result = self.run_command(['hw', 'list', '--owner=testUser'])
self.assert_no_fail(result)
expectedFilter = utils.NestedDict()
expectedFilter['id'] = utils.query_filter_orderby()
expectedFilter['hardware']['billingItem']['orderItem']['order']['userRecord']['username'] = (
utils.query_filter('testUser'))
self.assert_called_with('SoftLayer_Account', 'getHardware', filter=expectedFilter)

def test_list_by_pub_ip(self):
result = self.run_command(['hw', 'list', '--primary_ip=1.2.3.4'])
self.assert_no_fail(result)
expectedFilter = utils.NestedDict()
expectedFilter['id'] = utils.query_filter_orderby()
expectedFilter['hardware']['primaryIpAddress'] = utils.query_filter('1.2.3.4')
self.assert_called_with('SoftLayer_Account', 'getHardware', filter=expectedFilter)

def test_list_by_pri_ip(self):
result = self.run_command(['hw', 'list', '--backend_ip=1.2.3.4'])
self.assert_no_fail(result)
expectedFilter = utils.NestedDict()
expectedFilter['id'] = utils.query_filter_orderby()
expectedFilter['hardware']['primaryBackendIpAddress'] = utils.query_filter('1.2.3.4')
self.assert_called_with('SoftLayer_Account', 'getHardware', filter=expectedFilter)

0 comments on commit 0e1d28f

Please sign in to comment.