Repository: softlayer/softlayer-python (python)

Issue:
Add filter for and show subnet network type
`slcli subnet list` should show the type of network (PUBLIC or PRIVATE) for each subnet. It should also also allow `slcli subnet list --type=PUBLIC` to only show public subnets.


Pull request description:
Adds filter for subnet address space (manager and CLI)
Closes #732.

Patch:
diff --git a/SoftLayer/CLI/subnet/list.py b/SoftLayer/CLI/subnet/list.py
index 17ffe8a1..5db042a7 100644
--- a/SoftLayer/CLI/subnet/list.py
+++ b/SoftLayer/CLI/subnet/list.py
@@ -15,6 +15,7 @@
               type=click.Choice(['id',
                                  'identifier',
                                  'type',
+                                 'address_space',
                                  'datacenter',
                                  'vlan_id',
                                  'IPs',
@@ -24,17 +25,19 @@
               help="Filter by datacenter shortname (sng01, dal05, ...)")
 @click.option('--identifier', help="Filter by network identifier")
 @click.option('--subnet-type', '-t', help="Filter by subnet type")
+@click.option('--address-space', help="Filter by address space")
 @click.option('--v4', '--ipv4', is_flag=True, help="Display only IPv4 subnets")
 @click.option('--v6', '--ipv6', is_flag=True, help="Display only IPv6 subnets")
 @environment.pass_env
-def cli(env, sortby, datacenter, identifier, subnet_type, ipv4, ipv6):
+def cli(env, sortby, datacenter, identifier, subnet_type, address_space,
+        ipv4, ipv6):
     """List subnets."""
 
     mgr = SoftLayer.NetworkManager(env.client)
 
     table = formatting.Table([
-        'id', 'identifier', 'type', 'datacenter', 'vlan_id', 'IPs',
-        'hardware', 'vs',
+        'id', 'identifier', 'type', 'address_space', 'datacenter', 'vlan_id',
+        'IPs', 'hardware', 'vs',
     ])
     table.sortby = sortby
 
@@ -49,6 +52,7 @@ def cli(env, sortby, datacenter, identifier, subnet_type, ipv4, ipv6):
         version=version,
         identifier=identifier,
         subnet_type=subnet_type,
+        address_space=address_space,
     )
 
     for subnet in subnets:
@@ -56,6 +60,7 @@ def cli(env, sortby, datacenter, identifier, subnet_type, ipv4, ipv6):
             subnet['id'],
             '%s/%s' % (subnet['networkIdentifier'], str(subnet['cidr'])),
             subnet.get('subnetType', formatting.blank()),
+            subnet.get('addressSpace', formatting.blank()),
             utils.lookup(subnet, 'datacenter', 'name',) or formatting.blank(),
             subnet['networkVlanId'],
             subnet['ipAddressCount'],
diff --git a/SoftLayer/managers/network.py b/SoftLayer/managers/network.py
index 50f1121b..1cf3b315 100644
--- a/SoftLayer/managers/network.py
+++ b/SoftLayer/managers/network.py
@@ -13,7 +13,8 @@
 DEFAULT_SUBNET_MASK = ','.join(['hardware',
                                 'datacenter',
                                 'ipAddressCount',
-                                'virtualGuests'])
+                                'virtualGuests',
+                                'addressSpace'])
 DEFAULT_VLAN_MASK = ','.join([
     'firewallInterfaces',
     'hardwareCount',
@@ -244,7 +245,7 @@ def list_global_ips(self, version=None, identifier=None, **kwargs):
         return self.account.getGlobalIpRecords(**kwargs)
 
     def list_subnets(self, identifier=None, datacenter=None, version=0,
-                     subnet_type=None, **kwargs):
+                     subnet_type=None, address_space=None, **kwargs):
         """Display a list of all subnets on the account.
 
         This provides a quick overview of all subnets including information
@@ -257,6 +258,8 @@ def list_subnets(self, identifier=None, datacenter=None, version=0,
         :param int version: Only returns subnets of this version (4 or 6).
         :param string subnet_type: If specified, it will only returns subnets
                                      of this type.
+        :param string address_space: If specified, it will only returns subnets
+                                       with the given address space label.
         :param dict \\*\\*kwargs: response-level options (mask, limit, etc.)
         """
         if 'mask' not in kwargs:
@@ -277,6 +280,9 @@ def list_subnets(self, identifier=None, datacenter=None, version=0,
         else:
             # This filters out global IPs from the subnet listing.
             _filter['subnets']['subnetType'] = {'operation': '!= GLOBAL_IP'}
+        if address_space:
+            _filter['subnets']['addressSpace'] = utils.query_filter(
+                address_space)
 
         kwargs['filter'] = _filter.to_dict()
 


Test patch:
diff --git a/tests/managers/network_tests.py b/tests/managers/network_tests.py
index d02e3447..446bc7b3 100644
--- a/tests/managers/network_tests.py
+++ b/tests/managers/network_tests.py
@@ -6,6 +6,7 @@
 """
 import SoftLayer
 from SoftLayer import fixtures
+from SoftLayer.managers import network
 from SoftLayer import testing
 
 
@@ -182,33 +183,33 @@ def test_list_subnets_default(self):
 
         self.assertEqual(result, fixtures.SoftLayer_Account.getSubnets)
         _filter = {'subnets': {'subnetType': {'operation': '!= GLOBAL_IP'}}}
-        mask = 'mask[hardware,datacenter,ipAddressCount,virtualGuests]'
         self.assert_called_with('SoftLayer_Account', 'getSubnets',
-                                mask=mask,
+                                mask='mask[%s]' % network.DEFAULT_SUBNET_MASK,
                                 filter=_filter)
 
     def test_list_subnets_with_filters(self):
         result = self.network.list_subnets(
             identifier='10.0.0.1',
             datacenter='dal00',
-            subnet_type='PRIMARY',
             version=4,
+            subnet_type='PRIMARY',
+            address_space='PUBLIC',
         )
 
         self.assertEqual(result, fixtures.SoftLayer_Account.getSubnets)
         _filter = {
             'subnets': {
+                'networkIdentifier': {'operation': '_= 10.0.0.1'},
                 'datacenter': {
                     'name': {'operation': '_= dal00'}
                 },
                 'version': {'operation': 4},
                 'subnetType': {'operation': '_= PRIMARY'},
-                'networkIdentifier': {'operation': '_= 10.0.0.1'}
+                'addressSpace': {'operation': '_= PUBLIC'},
             }
         }
-        mask = 'mask[hardware,datacenter,ipAddressCount,virtualGuests]'
         self.assert_called_with('SoftLayer_Account', 'getSubnets',
-                                mask=mask,
+                                mask='mask[%s]' % network.DEFAULT_SUBNET_MASK,
                                 filter=_filter)
 
     def test_list_vlans_default(self):