From 8bc1a9cf93d500f7fb52432ffc5d3b33c5671838 Mon Sep 17 00:00:00 2001 From: Christopher Gallo Date: Thu, 9 Jan 2025 13:14:18 -0600 Subject: [PATCH] Updated vlan masks to fix id/number fields not being retrieved properly. Fixed #2204 --- SoftLayer/CLI/vlan/detail.py | 56 ++++++++++++++++++++++------------- SoftLayer/CLI/vlan/list.py | 36 ++++++++++++---------- SoftLayer/managers/network.py | 23 ++++++-------- 3 files changed, 64 insertions(+), 51 deletions(-) diff --git a/SoftLayer/CLI/vlan/detail.py b/SoftLayer/CLI/vlan/detail.py index 6e16d9d8c..8c772d8bf 100644 --- a/SoftLayer/CLI/vlan/detail.py +++ b/SoftLayer/CLI/vlan/detail.py @@ -12,14 +12,11 @@ @click.command(cls=SoftLayer.CLI.command.SLCommand, ) @click.argument('identifier') -@click.option('--no-vs', - is_flag=True, +@click.option('--no-vs', is_flag=True, help="Hide virtual server listing") -@click.option('--no-hardware', - is_flag=True, +@click.option('--no-hardware', is_flag=True, help="Hide hardware listing") -@click.option('--no-trunks', - is_flag=True, +@click.option('--no-trunks', is_flag=True, help="Hide devices with trunks") @environment.pass_env def cli(env, identifier, no_vs, no_hardware, no_trunks): @@ -28,11 +25,24 @@ def cli(env, identifier, no_vs, no_hardware, no_trunks): vlan_id = helpers.resolve_id(mgr.resolve_vlan_ids, identifier, 'VLAN') - mask = """mask[firewallInterfaces,primaryRouter[id, fullyQualifiedDomainName, datacenter], - totalPrimaryIpAddressCount,networkSpace,billingItem,hardware,subnets,virtualGuests, - networkVlanFirewall[id,fullyQualifiedDomainName,primaryIpAddress],attachedNetworkGateway[id,name,networkFirewall], - networkComponentTrunks[networkComponent[downlinkComponent[networkComponentGroup[membersDescription], - hardware[tagReferences]]]]]""" + mask = """mask[ +firewallInterfaces, primaryRouter[id, fullyQualifiedDomainName, datacenter[longName]], +totalPrimaryIpAddressCount, +networkSpace, id, vlanNumber, fullyQualifiedName, name, +hardware[id, hostname, domain, primaryIpAddress, primaryBackendIpAddress, tagReferences], +subnets[id, networkIdentifier, netmask, gateway, subnetType, usableIpAddressCount], +virtualGuests[id, hostname, domain, primaryIpAddress, primaryBackendIpAddress], +networkVlanFirewall[id,fullyQualifiedDomainName,primaryIpAddress], +attachedNetworkGateway[id,name,networkFirewall], +networkComponentTrunks[ + networkComponent[ + downlinkComponent[ + networkComponentGroup[membersDescription], + hardware[tagReferences] + ] + ] +] +]""" vlan = mgr.get_vlan(vlan_id, mask=mask) @@ -42,10 +52,8 @@ def cli(env, identifier, no_vs, no_hardware, no_trunks): table.add_row(['id', vlan.get('id')]) table.add_row(['number', vlan.get('vlanNumber')]) - table.add_row(['datacenter', - utils.lookup(vlan, 'primaryRouter', 'datacenter', 'longName')]) - table.add_row(['primary_router', - utils.lookup(vlan, 'primaryRouter', 'fullyQualifiedDomainName')]) + table.add_row(['datacenter', utils.lookup(vlan, 'primaryRouter', 'datacenter', 'longName')]) + table.add_row(['primary_router', utils.lookup(vlan, 'primaryRouter', 'fullyQualifiedDomainName')]) table.add_row(['Gateway/Firewall', get_gateway_firewall(vlan)]) if vlan.get('subnets'): @@ -93,12 +101,7 @@ def cli(env, identifier, no_vs, no_hardware, no_trunks): trunks = filter_trunks(vlan.get('networkComponentTrunks')) trunks_table = formatting.Table(['device', 'port', 'tags']) for trunk in trunks: - trunks_table.add_row([utils.lookup(trunk, 'networkComponent', 'downlinkComponent', - 'hardware', 'fullyQualifiedDomainName'), - utils.lookup(trunk, 'networkComponent', 'downlinkComponent', - 'networkComponentGroup', 'membersDescription'), - formatting.tags(utils.lookup(trunk, 'networkComponent', 'downlinkComponent', - 'hardware', 'tagReferences'))]) + trunks_table.add_row(get_trunk_row(trunk)) table.add_row(['trunks', trunks_table]) else: table.add_row(['trunks', '-']) @@ -106,6 +109,17 @@ def cli(env, identifier, no_vs, no_hardware, no_trunks): env.fout(table) +def get_trunk_row(trunk: dict) -> list: + """Parses a vlan trunk and returns a table row for it""" + dl_component = utils.lookup(trunk, 'networkComponent', 'downlinkComponent') + row = [ + utils.lookup(dl_component, 'hardware', 'fullyQualifiedDomainName'), + utils.lookup(dl_component, 'networkComponentGroup', 'membersDescription'), + formatting.tags(utils.lookup(dl_component, 'hardware', 'tagReferences')) + ] + return row + + def get_gateway_firewall(vlan): """Gets the name of a gateway/firewall from a VLAN. """ diff --git a/SoftLayer/CLI/vlan/list.py b/SoftLayer/CLI/vlan/list.py index ed55561db..918d58988 100644 --- a/SoftLayer/CLI/vlan/list.py +++ b/SoftLayer/CLI/vlan/list.py @@ -9,19 +9,21 @@ from SoftLayer.CLI.vlan.detail import get_gateway_firewall from SoftLayer import utils -COLUMNS = ['Id', - 'Number', - 'Fully qualified name', - 'Name', - 'Network', - 'Data center', - 'Pod', - 'Gateway/Firewall', - 'Hardware', - 'Virtual servers', - 'Public ips', - 'Premium', - 'Tags'] +COLUMNS = [ + 'Id', + 'Number', + 'Fully qualified name', + 'Name', + 'Network', + 'Data center', + 'Pod', + 'Gateway/Firewall', + 'Hardware', + 'Virtual servers', + 'Public ips', + 'Premium', + 'Tags' +] @click.command(cls=SoftLayer.CLI.command.SLCommand, ) @@ -49,9 +51,11 @@ def cli(env, sortby, datacenter, number, name, limit): name=name, limit=limit) - mask = """mask[name, datacenterLongName, frontendRouterId, capabilities, datacenterId, backendRouterId, - backendRouterName, frontendRouterName]""" - pods = mgr.get_pods(mask=mask) + pod_mask = """mask[ +name, datacenterLongName, capabilities, datacenterId, +backendRouterId, backendRouterName, frontendRouterName, frontendRouterId +]""" + pods = mgr.get_pods(mask=pod_mask) for vlan in vlans: billing = 'Yes' if vlan.get('billingItem') else 'No' diff --git a/SoftLayer/managers/network.py b/SoftLayer/managers/network.py index 261f6f91b..6ac46a741 100644 --- a/SoftLayer/managers/network.py +++ b/SoftLayer/managers/network.py @@ -38,19 +38,7 @@ 'addressSpace', 'endPointIpAddress' ]) -DEFAULT_VLAN_MASK = ','.join([ - 'firewallInterfaces', - 'hardwareCount', - 'primaryRouter[id, fullyQualifiedDomainName, datacenter]', - 'subnetCount', - 'billingItem', - 'totalPrimaryIpAddressCount', - 'virtualGuestCount', - 'networkSpace', - 'networkVlanFirewall[id,fullyQualifiedDomainName,primaryIpAddress]', - 'attachedNetworkGateway[id,name,networkFirewall]', - 'tagReferences[tag[name]]', -]) + DEFAULT_GET_VLAN_MASK = ','.join([ 'firewallInterfaces', 'primaryRouter[id, fullyQualifiedDomainName, datacenter]', @@ -528,6 +516,13 @@ def list_vlans(self, datacenter=None, vlan_number=None, name=None, limit=100, ma :param dict \\*\\*kwargs: response-level options (mask, limit, etc.) """ + vlan_mask = """mask[ +networkSpace, id, vlanNumber, fullyQualifiedName, name, +networkVlanFirewall[id,fullyQualifiedDomainName], attachedNetworkGateway[id,name], +firewallInterfaces, primaryRouter[id, fullyQualifiedDomainName, datacenter[name]], +hardwareCount, subnetCount, totalPrimaryIpAddressCount, virtualGuestCount, +billingItem[id], tagReferences[tag[name]] +]""" _filter = utils.NestedDict(_filter or {}) _filter['networkVlans']['id'] = utils.query_filter_orderby() @@ -542,7 +537,7 @@ def list_vlans(self, datacenter=None, vlan_number=None, name=None, limit=100, ma _filter['networkVlans']['primaryRouter']['datacenter']['name'] = utils.query_filter(datacenter) if mask is None: - mask = DEFAULT_VLAN_MASK + mask = vlan_mask # cf_call uses threads to get all results. return self.client.cf_call('SoftLayer_Account', 'getNetworkVlans',