From de7c255dd332e54bf41d610e3951f98d9b57a536 Mon Sep 17 00:00:00 2001 From: Flavio Fernandes Date: Thu, 5 Jul 2018 16:46:26 -0400 Subject: [PATCH] scli vlan detail: gracefully handle hardware that has no name/domain Avoid exceptions in cases when IMS returns hardware or VSI instances that have no 'hostname' and 'domain' attributes. An example of such: $ slcli vlan detail 1499927 An unexpected error has occured: Traceback (most recent call last): File "/home/vagrant/.venv/local/lib/python2.7/site-packages/SoftLayer/CLI/core.py", line 176, in main cli.main(**kwargs) File "/home/vagrant/.venv/local/lib/python2.7/site-packages/click/core.py", line 697, in main rv = self.invoke(ctx) File "/home/vagrant/.venv/local/lib/python2.7/site-packages/click/core.py", line 1066, in invoke return _process_result(sub_ctx.command.invoke(sub_ctx)) File "/home/vagrant/.venv/local/lib/python2.7/site-packages/click/core.py", line 1066, in invoke return _process_result(sub_ctx.command.invoke(sub_ctx)) File "/home/vagrant/.venv/local/lib/python2.7/site-packages/click/core.py", line 895, in invoke return ctx.invoke(self.callback, **ctx.params) File "/home/vagrant/.venv/local/lib/python2.7/site-packages/click/core.py", line 535, in invoke return callback(*args, **kwargs) File "/home/vagrant/.venv/local/lib/python2.7/site-packages/click/decorators.py", line 64, in new_func return ctx.invoke(f, obj, *args[1:], **kwargs) File "/home/vagrant/.venv/local/lib/python2.7/site-packages/click/core.py", line 535, in invoke return callback(*args, **kwargs) File "/home/vagrant/.venv/local/lib/python2.7/site-packages/SoftLayer/CLI/vlan/detail.py", line 76, in cli hardware['domain'], KeyError: 'domain' Feel free to report this error as it is likely a bug: https://github.com/softlayer/softlayer-python/issues The following snippet should be able to reproduce the error --- SoftLayer/CLI/vlan/detail.py | 8 ++++---- tests/CLI/modules/vlan_tests.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/SoftLayer/CLI/vlan/detail.py b/SoftLayer/CLI/vlan/detail.py index 59a086558..6acfb50cb 100644 --- a/SoftLayer/CLI/vlan/detail.py +++ b/SoftLayer/CLI/vlan/detail.py @@ -60,8 +60,8 @@ def cli(env, identifier, no_vs, no_hardware): if vlan.get('virtualGuests'): vs_table = formatting.KeyValueTable(server_columns) for vsi in vlan['virtualGuests']: - vs_table.add_row([vsi['hostname'], - vsi['domain'], + vs_table.add_row([vsi.get('hostname'), + vsi.get('domain'), vsi.get('primaryIpAddress'), vsi.get('primaryBackendIpAddress')]) table.add_row(['vs', vs_table]) @@ -72,8 +72,8 @@ def cli(env, identifier, no_vs, no_hardware): if vlan.get('hardware'): hw_table = formatting.Table(server_columns) for hardware in vlan['hardware']: - hw_table.add_row([hardware['hostname'], - hardware['domain'], + hw_table.add_row([hardware.get('hostname'), + hardware.get('domain'), hardware.get('primaryIpAddress'), hardware.get('primaryBackendIpAddress')]) table.add_row(['hardware', hw_table]) diff --git a/tests/CLI/modules/vlan_tests.py b/tests/CLI/modules/vlan_tests.py index d77f935e4..86b15507a 100644 --- a/tests/CLI/modules/vlan_tests.py +++ b/tests/CLI/modules/vlan_tests.py @@ -47,3 +47,32 @@ def test_subnet_list(self): vlan_mock.return_value = getObject result = self.run_command(['vlan', 'detail', '1234']) self.assert_no_fail(result) + + def test_detail_hardware_without_hostname(self): + vlan_mock = self.set_mock('SoftLayer_Network_Vlan', 'getObject') + getObject = { + 'primaryRouter': { + 'datacenter': {'id': 1234, 'longName': 'TestDC'}, + 'fullyQualifiedDomainName': 'fcr01.TestDC' + }, + 'id': 1234, + 'vlanNumber': 4444, + 'firewallInterfaces': None, + 'subnets': [], + 'hardware': [ + {'a_hardware': 'that_has_none_of_the_expected_attributes_provided'}, + {'domain': 'example.com', + 'networkManagementIpAddress': '10.171.202.131', + 'hardwareStatus': {'status': 'ACTIVE', 'id': 5}, + 'notes': '', + 'hostname': 'hw1', 'hardwareStatusId': 5, + 'globalIdentifier': 'f6ea716a-41d8-4c52-bb2e-48d63105f4b0', + 'primaryIpAddress': '169.60.169.169', + 'primaryBackendIpAddress': '10.171.202.130', 'id': 826425, + 'privateIpAddress': '10.171.202.130', + 'fullyQualifiedDomainName': 'hw1.example.com'} + ] + } + vlan_mock.return_value = getObject + result = self.run_command(['vlan', 'detail', '1234']) + self.assert_no_fail(result)