Skip to content

Commit b21f4c1

Browse files
#2104 added vlan trunks on the server detail page, improved performance of 'hw detail'
1 parent 0b4fd4d commit b21f4c1

File tree

6 files changed

+249
-118
lines changed

6 files changed

+249
-118
lines changed

.secrets.baseline

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"files": "^.secrets.baseline$",
44
"lines": null
55
},
6-
"generated_at": "2023-09-27T14:21:34Z",
6+
"generated_at": "2023-10-03T22:08:00Z",
77
"plugins_used": [
88
{
99
"name": "AWSKeyDetector"
@@ -238,7 +238,7 @@
238238
"hashed_secret": "fb5f2f1b65d1f2bc130ce9d5729b38d12f2b444e",
239239
"is_secret": false,
240240
"is_verified": false,
241-
"line_number": 259,
241+
"line_number": 260,
242242
"type": "Secret Keyword",
243243
"verified_result": null
244244
}

SoftLayer/CLI/hardware/detail.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def cli(env, identifier, passwords, price, components):
2929
table.align['value'] = 'l'
3030

3131
hardware_id = helpers.resolve_id(hardware.resolve_ids, identifier, 'hardware')
32-
result = hardware.get_hardware(hardware_id)
32+
result = hardware.get_hardware_fast(hardware_id)
3333
result = utils.NestedDict(result)
3434
hard_drives = hardware.get_hard_drives(hardware_id)
3535

@@ -72,11 +72,30 @@ def cli(env, identifier, passwords, price, components):
7272
table.add_row(['last_transaction', last_transaction])
7373
table.add_row(['billing', 'Hourly' if result['hourlyBillingFlag'] else 'Monthly'])
7474

75-
vlan_table = formatting.Table(['type', 'number', 'id', 'name', 'netmask'])
75+
vlan_table = formatting.Table(['Network', 'Number', 'Id', 'Name', 'Type'])
7676
for vlan in result['networkVlans']:
77-
vlan_table.add_row([vlan['networkSpace'], vlan['vlanNumber'],
78-
vlan['id'], vlan['fullyQualifiedName'],
79-
vlan['primarySubnets'][0]['netmask']])
77+
vlan_table.add_row([
78+
vlan.get('networkSpace'),
79+
vlan.get('vlanNumber'),
80+
vlan['id'],
81+
vlan['fullyQualifiedName'],
82+
'Primary'
83+
])
84+
85+
# Shows any VLANS trunked/tagged on this server
86+
for component in result.get('networkComponents', []):
87+
# These are the Primary network components
88+
if component.get('primaryIpAddress', False):
89+
uplink = component.get('uplinkComponent')
90+
for trunk in uplink.get('networkVlanTrunks'):
91+
trunk_vlan = trunk.get('networkVlan')
92+
vlan_table.add_row([
93+
trunk_vlan.get('networkSpace'),
94+
trunk_vlan.get('vlanNumber'),
95+
trunk_vlan.get('id'),
96+
trunk_vlan.get('fullyQualifiedName'),
97+
'Trunked'
98+
])
8099

81100
table.add_row(['vlans', vlan_table])
82101

SoftLayer/fixtures/SoftLayer_Hardware_Server.py

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@
161161
}
162162
}
163163
]
164+
getNetworkComponents = getFrontendNetworkComponents
164165

165166
getBandwidthAllotmentDetail = {
166167
'allocationId': 25465663,
@@ -410,4 +411,64 @@
410411
{
411412
"createDate": "2019-10-14T16:51:12-06:00",
412413
"version": "5.10"
413-
}]}}]
414+
}
415+
]
416+
}
417+
}]
418+
getActiveComponents = getComponents
419+
getActiveTransaction = getObject['activeTransaction']
420+
getOperatingSystem = getObject['operatingSystem']
421+
getSoftwareComponents = [
422+
{
423+
"hardwareId": 1907356,
424+
"id": 59003868,
425+
"manufacturerLicenseInstance": "",
426+
"softwareLicense": {
427+
"id": 20658,
428+
"softwareDescriptionId": 2888,
429+
"softwareDescription": {
430+
"controlPanel": 0,
431+
"id": 2888,
432+
"licenseTermValue": 0,
433+
"longDescription": "Juniper vSRX 1G 19.4R2-S3 Standard 19.4.2.3",
434+
"manufacturer": "Juniper",
435+
"name": "vSRX 1G 19.4R2-S3 Standard",
436+
"operatingSystem": 1,
437+
"referenceCode": "UBUNTU_18_64",
438+
"upgradeSoftwareDescriptionId": None,
439+
"upgradeSwDescId": None,
440+
"version": "19.4.2.3",
441+
"virtualLicense": 0,
442+
"virtualizationPlatform": 0,
443+
"requiredUser": "root"
444+
}
445+
}
446+
},
447+
{
448+
"hardwareId": 1907356,
449+
"id": 59003870,
450+
"manufacturerLicenseInstance": "",
451+
"softwareLicense": {
452+
"id": 147,
453+
"softwareDescriptionId": 148,
454+
"softwareDescription": {
455+
"controlPanel": 0,
456+
"id": 148,
457+
"licenseTermValue": None,
458+
"longDescription": "Passmark Suite Latest",
459+
"manufacturer": "Passmark",
460+
"name": "Passmark Suite",
461+
"operatingSystem": 0,
462+
"upgradeSoftwareDescriptionId": None,
463+
"upgradeSwDescId": None,
464+
"version": "Latest",
465+
"virtualLicense": 0,
466+
"virtualizationPlatform": 0
467+
}
468+
}
469+
}
470+
]
471+
getBillingItem = getObject['billingItem']
472+
getTagReferences = getObject['tagReferences']
473+
getNetworkVlans = getObject['networkVlans']
474+
getRemoteManagementAccounts = getObject['remoteManagementAccounts']

SoftLayer/managers/hardware.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
66
:license: MIT, see LICENSE for more details.
77
"""
8+
import concurrent.futures as cf
89
import datetime
910
import logging
1011
import socket
@@ -276,6 +277,97 @@ def get_hardware(self, hardware_id, **kwargs):
276277

277278
return self.hardware.getObject(id=hardware_id, **kwargs)
278279

280+
@retry(logger=LOGGER)
281+
def get_hardware_fast(self, hardware_id):
282+
"""Get details about a hardware device. Similar to get_hardware() but this uses threads
283+
284+
:param integer id: the hardware ID
285+
:returns: A dictionary containing a large amount of information about the specified server.
286+
"""
287+
288+
hw_mask = (
289+
'id, globalIdentifier, fullyQualifiedDomainName, hostname, domain,'
290+
'provisionDate, hardwareStatus, bareMetalInstanceFlag, processorPhysicalCoreAmount,'
291+
'memoryCapacity, notes, privateNetworkOnlyFlag, primaryBackendIpAddress,'
292+
'primaryIpAddress, networkManagementIpAddress, userData, datacenter, hourlyBillingFlag,'
293+
'lastTransaction[transactionGroup], hardwareChassis[id,name]'
294+
)
295+
server = self.client.call('SoftLayer_Hardware_Server', 'getObject', id=hardware_id, mask=hw_mask)
296+
with cf.ThreadPoolExecutor(max_workers=10) as executor:
297+
networkComponentsMask = (
298+
"id, status, speed, maxSpeed, name, ipmiMacAddress, ipmiIpAddress, macAddress, primaryIpAddress,"
299+
"port, primarySubnet[id, netmask, broadcastAddress, networkIdentifier, gateway],"
300+
"uplinkComponent[networkVlanTrunks[networkVlan[networkSpace]]]"
301+
)
302+
networkComponents = executor.submit(
303+
self.client.call, 'SoftLayer_Hardware_Server', 'getNetworkComponents',
304+
id=hardware_id, mask=networkComponentsMask
305+
)
306+
activeComponentsMask = (
307+
'id,hardwareComponentModel[hardwareGenericComponentModel[id,hardwareComponentType[keyName]]]'
308+
)
309+
activeComponents = executor.submit(
310+
self.client.call, 'SoftLayer_Hardware_Server', 'getActiveComponents',
311+
id=hardware_id, mask=activeComponentsMask
312+
)
313+
314+
activeTransaction = executor.submit(
315+
self.client.call, 'SoftLayer_Hardware_Server', 'getActiveTransaction',
316+
id=hardware_id, mask="id, transactionStatus[friendlyName,name]"
317+
)
318+
319+
operatingSystemMask = (
320+
'softwareLicense[softwareDescription[manufacturer, name, version, referenceCode]],'
321+
'passwords[id,username,password]'
322+
)
323+
operatingSystem = executor.submit(
324+
self.client.call, 'SoftLayer_Hardware_Server', 'getOperatingSystem',
325+
id=hardware_id, mask=operatingSystemMask
326+
)
327+
328+
# Intentionally reusing the operatingSystemMask here. They are both softwareComponents
329+
softwareComponents = executor.submit(
330+
self.client.call, 'SoftLayer_Hardware_Server', 'getSoftwareComponents',
331+
id=hardware_id, mask=operatingSystemMask
332+
)
333+
334+
billingItemMask = (
335+
'id,nextInvoiceTotalRecurringAmount,'
336+
'nextInvoiceChildren[nextInvoiceTotalRecurringAmount],'
337+
'orderItem.order.userRecord[username]'
338+
)
339+
billingItem = executor.submit(
340+
self.client.call, 'SoftLayer_Hardware_Server', 'getBillingItem',
341+
id=hardware_id, mask=billingItemMask
342+
)
343+
344+
tagReferences = executor.submit(
345+
self.client.call, 'SoftLayer_Hardware_Server', 'getTagReferences',
346+
id=hardware_id, mask="id,tag[name,id]"
347+
)
348+
349+
networkVlans = executor.submit(
350+
self.client.call, 'SoftLayer_Hardware_Server', 'getNetworkVlans',
351+
id=hardware_id, mask="id,vlanNumber,networkSpace,fullyQualifiedName,primarySubnets[ipAddresses]"
352+
)
353+
354+
remoteManagementAccounts = executor.submit(
355+
self.client.call, 'SoftLayer_Hardware_Server', 'getRemoteManagementAccounts',
356+
id=hardware_id, mask="username,password"
357+
)
358+
359+
server['networkComponents'] = networkComponents.result()
360+
server['activeComponents'] = activeComponents.result()
361+
server['activeTransaction'] = activeTransaction.result()
362+
server['operatingSystem'] = operatingSystem.result()
363+
server['softwareComponents'] = softwareComponents.result()
364+
server['billingItem'] = billingItem.result()
365+
server['networkVlans'] = networkVlans.result()
366+
server['remoteManagementAccounts'] = remoteManagementAccounts.result()
367+
server['tagReferences'] = tagReferences.result()
368+
369+
return server
370+
279371
def reload(self, hardware_id, post_uri=None, ssh_keys=None, lvm=False):
280372
"""Perform an OS reload of a server with its current configuration.
281373

0 commit comments

Comments
 (0)