Skip to content

Commit db33e3e

Browse files
author
Brian Flores
committed
added vs host-list command
1 parent 4addadf commit db33e3e

File tree

7 files changed

+344
-0
lines changed

7 files changed

+344
-0
lines changed

SoftLayer/CLI/routes.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
('virtual:notifications', 'SoftLayer.CLI.virt.notifications:cli'),
5858
('virtual:notification-add', 'SoftLayer.CLI.virt.notification_add:cli'),
5959
('virtual:notification-delete', 'SoftLayer.CLI.virt.notification_delete:cli'),
60+
('virtual:host-list', 'SoftLayer.CLI.virt.host_list:cli'),
6061

6162
('dedicatedhost', 'SoftLayer.CLI.dedicatedhost'),
6263
('dedicatedhost:list', 'SoftLayer.CLI.dedicatedhost.list:cli'),

SoftLayer/CLI/virt/host_list.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
"""List dedicated hosts."""
2+
# :license: MIT, see LICENSE for more details.
3+
4+
import click
5+
6+
import SoftLayer
7+
from SoftLayer.CLI.command import SLCommand as SLCommand
8+
from SoftLayer.CLI import environment
9+
from SoftLayer.CLI import formatting
10+
from SoftLayer import utils
11+
12+
13+
@click.command(cls=SLCommand, short_help="List virtual servers.")
14+
@click.option('--name', '-n', help='Filter by name of the dedicated host')
15+
@click.option('--datacenter', '-d', help='Filter by datacenter of the dedicated host')
16+
@click.option('--owner', help='Filter by owner of the dedicated host')
17+
@click.option('--order', help='Filter by ID of the order which purchased this dedicated host', type=click.INT)
18+
@environment.pass_env
19+
def cli(env, name, datacenter, owner, order,):
20+
"""List dedicated hosts."""
21+
22+
object_mask = "mask[id,name,createDate,cpuCount,diskCapacity,memoryCapacity,guestCount," \
23+
"datacenter,backendRouter,allocationStatus,billingItem[orderItem[order[userRecord]]]]"
24+
object_filter = {}
25+
26+
if datacenter is not None:
27+
object_filter = {
28+
"dedicatedHosts": {
29+
"datacenter": {
30+
"name": {
31+
"operation": datacenter
32+
}
33+
}
34+
}
35+
}
36+
37+
if name is not None:
38+
object_name_filter = {
39+
"dedicatedHosts": {
40+
"name": {
41+
"operation": name
42+
}
43+
}
44+
}
45+
object_filter = utils.dict_merge(object_filter, object_name_filter)
46+
47+
if owner is not None:
48+
object_owner_filter = {
49+
"dedicatedHosts": {
50+
"billingItem": {
51+
"orderItem": {
52+
"order": {
53+
"userRecord": {
54+
"username": {
55+
"operation": owner
56+
}
57+
}
58+
}
59+
}
60+
}
61+
}
62+
}
63+
object_filter = utils.dict_merge(object_filter, object_owner_filter)
64+
65+
if order is not None:
66+
object_order_filter = {
67+
"dedicatedHosts": {
68+
"billingItem": {
69+
"orderItem": {
70+
"order": {
71+
"id": {
72+
"operation": order
73+
}
74+
}
75+
}
76+
}
77+
}
78+
}
79+
object_filter = utils.dict_merge(object_filter, object_order_filter)
80+
81+
vsi = SoftLayer.AccountManager(env.client)
82+
dedicated_hosts = vsi.get_dedicated_hosts(object_mask, object_filter)
83+
table = formatting.Table(["Id", "Name", "Datacenter", "Router", "CPU (allocated/total)",
84+
"Memory (allocated/total)", "Disk (allocated/total)", "Guests"])
85+
table.align['Name'] = 'l'
86+
87+
if len(dedicated_hosts) == 0:
88+
click.secho("No dedicated hosts are found.")
89+
else:
90+
for host in dedicated_hosts:
91+
cpu_allocated = host.get('allocationStatus').get('cpuAllocated')
92+
cpu_total = host.get('allocationStatus').get('cpuCount')
93+
memory_allocated = host.get('allocationStatus').get('memoryAllocated')
94+
memory_total = host.get('allocationStatus').get('memoryCapacity')
95+
disk_allocated = host.get('allocationStatus').get('diskAllocated')
96+
disk_total = host.get('allocationStatus').get('diskCapacity')
97+
table.add_row([
98+
host.get('id'),
99+
host.get('name'),
100+
host.get('datacenter').get('name'),
101+
host.get('backendRouter').get('hostname'),
102+
f"{cpu_allocated}/{cpu_total}",
103+
f"{memory_allocated}/{memory_total}",
104+
f"{disk_allocated}/{disk_total}",
105+
host.get('guestCount')
106+
])
107+
108+
env.fout(table)

SoftLayer/fixtures/SoftLayer_Account.py

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,3 +1294,190 @@
12941294
'keyName': 'ACTIVE'
12951295
}
12961296
}]
1297+
1298+
getFilteredDedicatedHosts = [
1299+
{
1300+
"cpuCount": 56,
1301+
"createDate": "2021-11-18T15:13:57-06:00",
1302+
"diskCapacity": 1200,
1303+
"id": 656700,
1304+
"memoryCapacity": 242,
1305+
"name": "dedicatedhost01",
1306+
"guestCount": 0,
1307+
"allocationStatus": {
1308+
"cpuAllocated": 0,
1309+
"cpuAvailable": 56,
1310+
"cpuCount": 56,
1311+
"diskAllocated": 0,
1312+
"diskAvailable": 1200,
1313+
"diskCapacity": 1200,
1314+
"guestCount": 0,
1315+
"memoryAllocated": 0,
1316+
"memoryAvailable": 242,
1317+
"memoryCapacity": 242
1318+
},
1319+
"backendRouter": {
1320+
"accountId": 1,
1321+
"bareMetalInstanceFlag": 0,
1322+
"domain": "softlayer.com",
1323+
"fullyQualifiedDomainName": "bcr01a.dal13.softlayer.com",
1324+
"hardwareStatusId": 5,
1325+
"hostname": "bcr01a.dal13",
1326+
"id": 1883692,
1327+
"notes": "",
1328+
"provisionDate": None,
1329+
"serviceProviderId": 1,
1330+
"serviceProviderResourceId": None
1331+
},
1332+
"billingItem": {
1333+
"allowCancellationFlag": 1,
1334+
"cancellationDate": None,
1335+
"categoryCode": "dedicated_virtual_hosts",
1336+
"createDate": "2021-11-18T15:13:59-06:00",
1337+
"currentHourlyCharge": "0",
1338+
"cycleStartDate": "2023-01-04T00:07:36-06:00",
1339+
"description": "56 Cores X 242 RAM X 1.2 TB",
1340+
"hostName": "dedicatedhost01",
1341+
"hourlyRecurringFee": "0",
1342+
"hoursUsed": "465",
1343+
"id": 910104016,
1344+
"laborFee": "0",
1345+
"laborFeeTaxRate": "0",
1346+
"lastBillDate": "2023-01-04T00:07:36-06:00",
1347+
"modifyDate": "2023-01-04T00:07:36-06:00",
1348+
"nextBillDate": "2023-02-04T00:00:00-06:00",
1349+
"oneTimeFee": "0",
1350+
"oneTimeFeeTaxRate": "0",
1351+
"orderItemId": 874370304,
1352+
"parentId": None,
1353+
"recurringFee": "0",
1354+
"recurringFeeTaxRate": "0",
1355+
"recurringMonths": 1,
1356+
"serviceProviderId": 1,
1357+
"setupFee": "0",
1358+
"setupFeeTaxRate": "0",
1359+
"orderItem": {
1360+
"categoryCode": "dedicated_virtual_hosts",
1361+
"description": "56 Cores X 242 RAM X 1.2 TB",
1362+
"hostName": "dedicatedhost01",
1363+
"hourlyRecurringFee": "0",
1364+
"id": 874370304,
1365+
"itemId": 10195,
1366+
"itemPriceId": "200269",
1367+
"laborAfterTaxAmount": "0",
1368+
"laborFee": "0",
1369+
"laborFeeTaxRate": "0",
1370+
"laborTaxAmount": "0",
1371+
"oneTimeAfterTaxAmount": "0",
1372+
"oneTimeFee": "0",
1373+
"oneTimeFeeTaxRate": "0",
1374+
"oneTimeTaxAmount": "0",
1375+
"parentId": None,
1376+
"presetId": None,
1377+
"promoCodeId": None,
1378+
"quantity": None,
1379+
"recurringAfterTaxAmount": "0",
1380+
"recurringFee": "0",
1381+
"recurringTaxAmount": "0",
1382+
"setupAfterTaxAmount": "0",
1383+
"setupFee": "0",
1384+
"setupFeeDeferralMonths": None,
1385+
"setupFeeTaxRate": "0",
1386+
"setupTaxAmount": "0",
1387+
"order": {
1388+
"accountId": 307608,
1389+
"createDate": "2021-11-18T15:13:57-06:00",
1390+
"id": 85857762,
1391+
"impersonatingUserRecordId": None,
1392+
"modifyDate": "2021-11-18T15:14:00-06:00",
1393+
"orderQuoteId": None,
1394+
"orderTypeId": 11,
1395+
"presaleEventId": None,
1396+
"privateCloudOrderFlag": False,
1397+
"status": "APPROVED",
1398+
"userRecordId": 7650493,
1399+
"userRecord": {
1400+
"accountId": 307608,
1401+
"address1": "4849 Alpha Rd",
1402+
"city": "Dallas",
1403+
"companyName": "SoftLayer Internal - Development Community",
1404+
"country": "US",
1405+
"createDate": "2019-06-10T15:21:33-07:00",
1406+
"daylightSavingsTimeFlag": False,
1407+
"denyAllResourceAccessOnCreateFlag": False,
1408+
"displayName": "danielc",
1409+
"email": "daniel.cabero@jalasoft.com",
1410+
"firstName": "daniel",
1411+
"forumPasswordHash": "unused",
1412+
"iamAuthorizationStatus": 1,
1413+
"iamId": "IBMid-550003CUGT",
1414+
"id": 7650493,
1415+
"isMasterUserFlag": False,
1416+
"lastName": "cabero",
1417+
"localeId": 1,
1418+
"managedByFederationFlag": False,
1419+
"managedByOpenIdConnectFlag": True,
1420+
"minimumPasswordLifeHours": 0,
1421+
"modifyDate": "2019-12-13T07:29:07-06:00",
1422+
"openIdConnectUserName": "daniel.cabero@jalasoft.com",
1423+
"parentId": 167758,
1424+
"passwordExpireDate": None,
1425+
"permissionCheckLikeMasterUserFlag": 0,
1426+
"postalCode": "75244-4608",
1427+
"pptpVpnAllowedFlag": False,
1428+
"preventPreviousPasswords": 0,
1429+
"savedId": "7650493",
1430+
"secondaryLoginManagementFlag": True,
1431+
"secondaryLoginRequiredFlag": None,
1432+
"secondaryPasswordModifyDate": "2019-06-10T15:21:33-07:00",
1433+
"secondaryPasswordTimeoutDays": 0,
1434+
"sslVpnAllowedFlag": False,
1435+
"state": "TX",
1436+
"statusDate": None,
1437+
"timezoneId": 113,
1438+
"userStatusId": 1001,
1439+
"username": "sl307608-dcabero",
1440+
"vpnManualConfig": False,
1441+
"ibmIdLink": {
1442+
"createDate": "2019-06-10T15:21:34-07:00",
1443+
"defaultFlag": 1,
1444+
"destinationUserAlphanumericId": "daniel%2ecabero@jalasoft%2ecom",
1445+
"destinationUserId": None,
1446+
"iamIdVerificationFlag": 2,
1447+
"id": 1051135,
1448+
"realm": "IBMid",
1449+
"serviceProviderId": 348,
1450+
"uniqueIdentifier": "IBMid-550003CUGT",
1451+
"userId": 7650493
1452+
},
1453+
"locale": {
1454+
"friendlyName": "English",
1455+
"id": 1,
1456+
"languageTag": "en-US",
1457+
"name": "English"
1458+
},
1459+
"timezone": {
1460+
"id": 113,
1461+
"longName": "(GMT-06:00) America/Chicago - CST",
1462+
"name": "America/Chicago",
1463+
"offset": "-0600",
1464+
"shortName": "CST"
1465+
},
1466+
"userStatus": {
1467+
"id": 1001,
1468+
"keyName": "ACTIVE",
1469+
"name": "Active"
1470+
}
1471+
}
1472+
}
1473+
},
1474+
"resourceTableId": 656700
1475+
},
1476+
"datacenter": {
1477+
"id": 1854895,
1478+
"longName": "Dallas 13",
1479+
"name": "dal13",
1480+
"statusId": 2
1481+
}
1482+
}
1483+
]

SoftLayer/managers/account.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,3 +366,16 @@ def getBandwidthDetail(self, identifier):
366366
virtualGuests[outboundPublicBandwidthUsage,bandwidthAllotmentDetail[allocation]],
367367
bareMetalInstances[outboundBandwidthUsage,bandwidthAllotmentDetail[allocation]]"""
368368
return self.client['SoftLayer_Network_Bandwidth_Version1_Allotment'].getObject(id=identifier, mask=_mask)
369+
370+
def get_dedicated_hosts(self, object_mask, object_filter):
371+
"""Returns all associated virtual dedicated host objects.
372+
373+
:return SoftLayer_Virtual_DedicatedHost[].
374+
"""
375+
376+
if object_mask == "":
377+
object_mask = "mask[id,name,createDate,cpuCount,diskCapacity,memoryCapacity,guestCount,datacenter]"
378+
379+
if object_filter == "":
380+
object_filter = {}
381+
return self.client.call('SoftLayer_Account', 'getDedicatedHosts', mask=object_mask, filter=object_filter)

docs/cli/vs.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,10 @@ If no timezone is specified, IMS local time (CST) will be assumed, which might n
291291
:prog: virtual notification-delete
292292
:show-nested:
293293

294+
.. click:: SoftLayer.CLI.user.host_list:cli
295+
:prog: user host-list
296+
:show-nested:
297+
294298
Manages the migration of virutal guests. Supports migrating virtual guests on Dedicated Hosts as well.
295299

296300
Reserved Capacity

tests/CLI/modules/vs/vs_tests.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from unittest import mock as mock
1111

1212
from SoftLayer.CLI import exceptions
13+
from SoftLayer.fixtures import SoftLayer_Account
1314
from SoftLayer.fixtures import SoftLayer_Product_Package
1415
from SoftLayer.fixtures import SoftLayer_Virtual_Guest as SoftLayer_Virtual_Guest
1516
from SoftLayer import SoftLayerAPIError
@@ -995,3 +996,29 @@ def test_add_notification(self):
995996
def test_notification_delete(self):
996997
result = self.run_command(['vs', 'notification-delete', '100'])
997998
self.assert_no_fail(result)
999+
1000+
def test_host_list(self):
1001+
mock = self.set_mock('SoftLayer_Account', 'getDedicatedHosts')
1002+
mock.return_value = SoftLayer_Account.getFilteredDedicatedHosts
1003+
result = self.run_command(['vs', 'host-list', '-n', 'dedicatedhost01', '-d', 'dal13',
1004+
'--owner', 'sl307608-dcabero', '--order', '85857762'])
1005+
self.assert_no_fail(result)
1006+
expected = [{
1007+
"Id": 656700,
1008+
"Name": "dedicatedhost01",
1009+
"Datacenter": "dal13",
1010+
"Router": "bcr01a.dal13",
1011+
"CPU (allocated/total)": "0/56",
1012+
"Memory (allocated/total)": "0/242",
1013+
"Disk (allocated/total)": "0/1200",
1014+
"Guests": 0
1015+
}]
1016+
self.assertEqual(json.loads(result.output), expected)
1017+
1018+
def test_empty_host_list(self):
1019+
mock = self.set_mock('SoftLayer_Account', 'getDedicatedHosts')
1020+
mock.return_value = {}
1021+
result = self.run_command(['vs', 'host-list', '-n', 'dedicatedhost01', '-d', 'dal13',
1022+
'--owner', 'sl307608-dcabero', '--order', '85857762'])
1023+
self.assert_no_fail(result)
1024+
self.assertIn("No dedicated hosts are found.", result.output)

tests/managers/account_tests.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,3 +176,7 @@ def test_get_bandwidth_pool_counts(self):
176176
total = self.manager.get_bandwidth_pool_counts(1234)
177177
self.assert_called_with('SoftLayer_Network_Bandwidth_Version1_Allotment', 'getObject', identifier=1234)
178178
self.assertEqual(total, 2)
179+
180+
def test_get_dedicated_hosts(self):
181+
self.manager.get_dedicated_hosts("", "")
182+
self.assert_called_with('SoftLayer_Account', 'getDedicatedHosts')

0 commit comments

Comments
 (0)