예제 #1
0
def add(env, securitygroup_id, remote_ip, remote_group, direction, ethertype,
        port_max, port_min, protocol):
    """Add a security group rule to a security group.

    \b
    Examples:
        # Add an SSH rule (TCP port 22) to a security group
        slcli sg rule-add 384727 \\
            --direction ingress \\
            --protocol tcp \\
            --port-min 22 \\
            --port-max 22

    \b
        # Add a ping rule (ICMP type 8 code 0) to a security group
        slcli sg rule-add 384727 \\
            --direction ingress \\
            --protocol icmp \\
            --port-min 8 \\
            --port-max 0
    """
    mgr = SoftLayer.NetworkManager(env.client)

    ret = mgr.add_securitygroup_rule(securitygroup_id, remote_ip, remote_group,
                                     direction, ethertype, port_max, port_min,
                                     protocol)

    if not ret:
        raise exceptions.CLIAbort("Failed to add security group rule")

    table = formatting.Table(REQUEST_RULES_COLUMNS)
    table.add_row([ret['requestId'], str(ret['rules'])])

    env.fout(table)
예제 #2
0
def edit(env, securitygroup_id, rule_id, remote_ip, remote_group, direction,
         ethertype, port_max, port_min, protocol):
    """Edit a security group rule in a security group."""
    mgr = SoftLayer.NetworkManager(env.client)

    data = {}
    if remote_ip:
        data['remote_ip'] = remote_ip
    if remote_group:
        data['remote_group'] = remote_group
    if direction:
        data['direction'] = direction
    if ethertype:
        data['ethertype'] = ethertype
    if port_max is not None:
        data['port_max'] = port_max
    if port_min is not None:
        data['port_min'] = port_min
    if protocol:
        data['protocol'] = protocol

    ret = mgr.edit_securitygroup_rule(securitygroup_id, rule_id, **data)

    if not ret:
        raise exceptions.CLIAbort("Failed to edit security group rule")

    table = formatting.Table(REQUEST_BOOL_COLUMNS)
    table.add_row([ret['requestId']])

    env.fout(table)
예제 #3
0
    def execute(self, args):
        mgr = SoftLayer.NetworkManager(self.client)

        table = formatting.Table(['id', 'ip', 'assigned', 'target'])
        table.sortby = args.get('--sortby') or 'id'

        version = 0
        if args.get('--v4'):
            version = 4
        elif args.get('--v6'):
            version = 6

        ips = mgr.list_global_ips(version=version)

        for ip_address in ips:
            assigned = 'No'
            target = 'None'
            if ip_address.get('destinationIpAddress'):
                dest = ip_address['destinationIpAddress']
                assigned = 'Yes'
                target = dest['ipAddress']
                virtual_guest = dest.get('virtualGuest')
                if virtual_guest:
                    target += (' (%s)' %
                               virtual_guest['fullyQualifiedDomainName'])
                elif ip_address['destinationIpAddress'].get('hardware'):
                    target += (' (%s)' %
                               dest['hardware']['fullyQualifiedDomainName'])

            table.add_row([
                ip_address['id'], ip_address['ipAddress']['ipAddress'],
                assigned, target
            ])
        return table
예제 #4
0
def cli(env, identifier, no_vs, no_hardware):
    """Get subnet details."""

    mgr = SoftLayer.NetworkManager(env.client)
    subnet_id = helpers.resolve_id(mgr.resolve_subnet_ids,
                                   identifier,
                                   name='subnet')
    subnet = mgr.get_subnet(subnet_id)

    table = formatting.KeyValueTable(['name', 'value'])
    table.align['name'] = 'r'
    table.align['value'] = 'l'

    table.add_row(['id', subnet['id']])
    table.add_row([
        'identifier',
        '%s/%s' % (subnet['networkIdentifier'], str(subnet['cidr']))
    ])
    table.add_row(['subnet type', subnet['subnetType']])
    table.add_row(
        ['network space',
         utils.lookup(subnet, 'networkVlan', 'networkSpace')])
    table.add_row(['gateway', subnet.get('gateway', formatting.blank())])
    table.add_row(
        ['broadcast',
         subnet.get('broadcastAddress', formatting.blank())])
    table.add_row(['datacenter', subnet['datacenter']['name']])
    table.add_row(
        ['usable ips',
         subnet.get('usableIpAddressCount', formatting.blank())])

    if not no_vs:
        if subnet['virtualGuests']:
            vs_table = formatting.Table(
                ['hostname', 'domain', 'public_ip', 'private_ip'])
            for vsi in subnet['virtualGuests']:
                vs_table.add_row([
                    vsi['hostname'], vsi['domain'],
                    vsi.get('primaryIpAddress'),
                    vsi.get('primaryBackendIpAddress')
                ])
            table.add_row(['vs', vs_table])
        else:
            table.add_row(['vs', 'none'])

    if not no_hardware:
        if subnet['hardware']:
            hw_table = formatting.Table(
                ['hostname', 'domain', 'public_ip', 'private_ip'])
            for hardware in subnet['hardware']:
                hw_table.add_row([
                    hardware['hostname'], hardware['domain'],
                    hardware.get('primaryIpAddress'),
                    hardware.get('primaryBackendIpAddress')
                ])
            table.add_row(['hardware', hw_table])
        else:
            table.add_row(['hardware', 'none'])

    env.fout(table)
예제 #5
0
def cli(env, sortby, datacenter, number, name, limit):
    """List VLANs."""

    mgr = SoftLayer.NetworkManager(env.client)

    table = formatting.Table(COLUMNS)
    table.sortby = sortby

    vlans = mgr.list_vlans(datacenter=datacenter,
                           vlan_number=number,
                           name=name,
                           limit=limit)
    for vlan in vlans:
        billing = 'Yes' if vlan.get('billingItem') else 'No'

        table.add_row([
            vlan.get('id'),
            vlan.get('vlanNumber'),
            vlan.get('name') or formatting.blank(),
            get_gateway_firewall(vlan),
            utils.lookup(vlan, 'primaryRouter', 'datacenter', 'name'),
            vlan.get('hardwareCount'),
            vlan.get('virtualGuestCount'),
            vlan.get('totalPrimaryIpAddressCount'), billing,
            formatting.tags(vlan['tagReferences'])
        ])

    env.fout(table)
예제 #6
0
def cli(env, ipv6, test):
    """Creates a global IP."""

    mgr = SoftLayer.NetworkManager(env.client)

    version = 4
    if ipv6:
        version = 6

    if not (test or env.skip_confirmations):
        if not formatting.confirm("This action will incur charges on your "
                                  "account. Continue?"):
            raise exceptions.CLIAbort('Cancelling order.')

    result = mgr.add_global_ip(version=version, test_order=test)

    table = formatting.Table(['item', 'cost'])
    table.align['Item'] = 'r'
    table.align['cost'] = 'r'

    total = 0.0
    for price in result['orderDetails']['prices']:
        total += float(price.get('recurringFee', 0.0))
        rate = "%.2f" % float(price['recurringFee'])

        table.add_row([price['item']['description'], rate])

    table.add_row(['Total monthly cost', "%.2f" % total])
    env.fout(table)
예제 #7
0
def cli(env, abuse, address1, address2, city, company, country, firstname,
        lastname, postal, public, state):
    """Edit the RWhois data on the account."""
    mgr = SoftLayer.NetworkManager(env.client)

    update = {
        'abuse_email': abuse,
        'address1': address1,
        'address2': address2,
        'company_name': company,
        'city': city,
        'country': country,
        'first_name': firstname,
        'last_name': lastname,
        'postal_code': postal,
        'state': state,
        'private_residence': public,
    }

    if public is True:
        update['private_residence'] = False
    elif public is False:
        update['private_residence'] = True

    check = [x for x in update.values() if x is not None]
    if not check:
        raise exceptions.CLIAbort(
            "You must specify at least one field to update.")

    mgr.edit_rwhois(**update)  # pylint: disable=W0142
예제 #8
0
    def execute(self, args):
        mgr = SoftLayer.NetworkManager(self.client)

        version = 4
        if args.get('--v6'):
            version = 6
        if not args.get('--test') and not args['--really']:
            if not formatting.confirm("This action will incur charges on your "
                                      "account. Continue?"):
                raise exceptions.CLIAbort('Cancelling order.')
        result = mgr.add_global_ip(version=version,
                                   test_order=args.get('--test'))

        table = formatting.Table(['Item', 'cost'])
        table.align['Item'] = 'r'
        table.align['cost'] = 'r'

        total = 0.0
        for price in result['orderDetails']['prices']:
            total += float(price.get('recurringFee', 0.0))
            rate = "%.2f" % float(price['recurringFee'])

            table.add_row([price['item']['description'], rate])

        table.add_row(['Total monthly cost', "%.2f" % total])
        return table
예제 #9
0
def cli(env, sortby, datacenter, number, name, limit):
    """List VLANs."""

    mgr = SoftLayer.NetworkManager(env.client)

    table = formatting.Table(COLUMNS)
    table.sortby = sortby

    vlans = mgr.list_vlans(datacenter=datacenter,
                           vlan_number=number,
                           name=name,
                           limit=limit)
    for vlan in vlans:
        table.add_row([
            vlan['id'],
            vlan['vlanNumber'],
            vlan.get('name') or formatting.blank(),
            'Yes' if vlan['firewallInterfaces'] else 'No',
            utils.lookup(vlan, 'primaryRouter', 'datacenter', 'name'),
            vlan['hardwareCount'],
            vlan['virtualGuestCount'],
            vlan['totalPrimaryIpAddressCount'],
        ])

    env.fout(table)
예제 #10
0
def rule_list(env, securitygroup_id, sortby):
    """List security group rules."""

    mgr = SoftLayer.NetworkManager(env.client)

    table = formatting.Table(COLUMNS)
    table.sortby = sortby

    rules = mgr.list_securitygroup_rules(securitygroup_id)
    for rule in rules:
        port_min = rule.get('portRangeMin')
        port_max = rule.get('portRangeMax')
        if port_min is None:
            port_min = formatting.blank()
        if port_max is None:
            port_max = formatting.blank()

        table.add_row([
            rule['id'],
            rule.get('remoteIp') or formatting.blank(),
            rule.get('remoteGroupId') or formatting.blank(),
            rule['direction'],
            rule.get('ethertype') or formatting.blank(),
            port_min,
            port_max,
            rule.get('protocol') or formatting.blank()
        ])

    env.fout(table)
예제 #11
0
def order(env, **args):
    """Creates a LB. Protocols supported are TCP, HTTP, and HTTPS."""

    mgr = SoftLayer.LoadBalancerManager(env.client)
    network = SoftLayer.NetworkManager(env.client)

    datacenter = network.get_datacenter(datacenter=args.get('datacenter'))
    if datacenter:
        location = {'id': datacenter[0]['id']}
    else:
        raise exceptions.CLIHalt('Datacenter {} was not found'.format(datacenter))

    name = args.get('name')
    description = args.get('label', None)

    backend = args.get('backend')
    frontend = args.get('frontend')
    protocols = [
        {
            "backendPort": backend.get('port'),
            "backendProtocol": backend.get('protocol'),
            "frontendPort": frontend.get('port'),
            "frontendProtocol": frontend.get('protocol'),
            "loadBalancingMethod": args.get('method'),
            "maxConn": 1000
        }
    ]

    # remove verify=True to place the order
    receipt = mgr.order_lbaas(location, name, description, protocols, args.get('subnet'),
                              public=args.get('public'), verify=args.get('verify'))
    table = parse_receipt(receipt)
    env.fout(table)
예제 #12
0
    def execute(self, args):
        mgr = SoftLayer.NetworkManager(self.client)

        update = {
            'abuse_email': args.get('--abuse'),
            'address1': args.get('--address1'),
            'address2': args.get('--address2'),
            'company_name': args.get('--company'),
            'city': args.get('--city'),
            'country': args.get('--country'),
            'first_name': args.get('--firstname'),
            'last_name': args.get('--lastname'),
            'postal_code': args.get('--postal'),
            'state': args.get('--state')
        }

        if args.get('--private'):
            update['private_residence'] = False
        elif args.get('--public'):
            update['private_residence'] = True

        check = [x for x in update.values() if x is not None]
        if not check:
            raise exceptions.CLIAbort(
                "You must specify at least one field to update.")

        mgr.edit_rwhois(**update)  # pylint: disable=W0142
예제 #13
0
def add(env, securitygroup_id, remote_ip, remote_group, direction, ethertype,
        port_max, port_min, protocol):
    """Add a security group rule to a security group.

    \b
    Examples:
        # Add an SSH rule (TCP port 22) to a security group
        slcli sg rule-add 384727 \\
            --direction ingress \\
            --protocol tcp \\
            --port-min 22 \\
            --port-max 22

    \b
        # Add a ping rule (ICMP type 8 code 0) to a security group
        slcli sg rule-add 384727 \\
            --direction ingress \\
            --protocol icmp \\
            --port-min 8 \\
            --port-max 0
    """
    mgr = SoftLayer.NetworkManager(env.client)

    ret = mgr.add_securitygroup_rule(securitygroup_id, remote_ip, remote_group,
                                     direction, ethertype, port_max, port_min,
                                     protocol)

    if not ret:
        raise exceptions.CLIAbort("Failed to add security group rule")
예제 #14
0
    def execute(self, args):
        mgr = SoftLayer.NetworkManager(self.client)

        table = formatting.Table([
            'id', 'number', 'datacenter', 'name', 'IPs', 'hardware', 'vs',
            'networking', 'firewall'
        ])
        table.sortby = args.get('--sortby') or 'id'

        vlans = mgr.list_vlans(
            datacenter=args.get('--datacenter'),
            vlan_number=args.get('--number'),
            name=args.get('--name'),
        )
        for vlan in vlans:
            table.add_row([
                vlan['id'],
                vlan['vlanNumber'],
                vlan['primaryRouter']['datacenter']['name'],
                vlan.get('name') or formatting.blank(),
                vlan['totalPrimaryIpAddressCount'],
                len(vlan['hardware']),
                len(vlan['virtualGuests']),
                len(vlan['networkComponents']),
                'Yes' if vlan['firewallInterfaces'] else 'No',
            ])

        return table
예제 #15
0
def cli(env, ip_version):
    """List all global IPs."""

    mgr = SoftLayer.NetworkManager(env.client)

    table = formatting.Table(['id', 'ip', 'assigned', 'target'])

    version = None
    if ip_version == 'v4':
        version = 4
    elif ip_version == 'v6':
        version = 6

    ips = mgr.list_global_ips(version=version)

    for ip_address in ips:
        assigned = 'No'
        target = 'None'
        if ip_address.get('destinationIpAddress'):
            dest = ip_address['destinationIpAddress']
            assigned = 'Yes'
            target = dest['ipAddress']
            virtual_guest = dest.get('virtualGuest')
            if virtual_guest:
                target += (' (%s)' % virtual_guest['fullyQualifiedDomainName'])
            elif ip_address['destinationIpAddress'].get('hardware'):
                target += (' (%s)' %
                           dest['hardware']['fullyQualifiedDomainName'])

        table.add_row([
            ip_address['id'], ip_address['ipAddress']['ipAddress'], assigned,
            target
        ])
    env.fout(table)
예제 #16
0
def cli(env, sortby, datacenter, number, name):
    """List VLANs."""

    mgr = SoftLayer.NetworkManager(env.client)

    table = formatting.Table([
        'id', 'number', 'datacenter', 'name', 'IPs', 'hardware', 'vs',
        'networking', 'firewall'
    ])
    table.sortby = sortby

    vlans = mgr.list_vlans(datacenter=datacenter,
                           vlan_number=number,
                           name=name)
    for vlan in vlans:
        table.add_row([
            vlan['id'],
            vlan['vlanNumber'],
            vlan['primaryRouter']['datacenter']['name'],
            vlan.get('name') or formatting.blank(),
            vlan['totalPrimaryIpAddressCount'],
            len(vlan['hardware']),
            len(vlan['virtualGuests']),
            len(vlan['networkComponents']),
            'Yes' if vlan['firewallInterfaces'] else 'No',
        ])

    return table
예제 #17
0
    def execute(self, args):
        mgr = SoftLayer.NetworkManager(self.client)

        _type = 'private'
        if args['public']:
            _type = 'public'

        version = 4
        if args.get('--v6'):
            version = 6
        if not args.get('--test') and not args['--really']:
            if not formatting.confirm("This action will incur charges on your "
                                      "account. Continue?"):
                raise exceptions.CLIAbort('Cancelling order.')
        result = mgr.add_subnet(_type,
                                quantity=args['<quantity>'],
                                vlan_id=args['<vlan>'],
                                version=version,
                                test_order=args.get('--test'))
        if not result:
            return 'Unable to place order: No valid price IDs found.'
        table = formatting.Table(['Item', 'cost'])
        table.align['Item'] = 'r'
        table.align['cost'] = 'r'

        total = 0.0
        if 'prices' in result:
            for price in result['prices']:
                total += float(price.get('recurringFee', 0.0))
                rate = "%.2f" % float(price['recurringFee'])

                table.add_row([price['item']['description'], rate])

        table.add_row(['Total monthly cost', "%.2f" % total])
        return table
예제 #18
0
def cli(env, identifier, target):
    """Assigns the global IP to a target."""

    mgr = SoftLayer.NetworkManager(env.client)
    global_ip_id = helpers.resolve_id(mgr.resolve_global_ip_ids,
                                      identifier,
                                      name='global ip')
    mgr.assign_global_ip(global_ip_id, target)
예제 #19
0
def cli(env, identifier):
    """Unassigns a global IP from a target."""

    mgr = SoftLayer.NetworkManager(env.client)
    global_ip_id = helpers.resolve_id(mgr.resolve_global_ip_ids,
                                      identifier,
                                      name='global ip')
    mgr.unassign_global_ip(global_ip_id)
예제 #20
0
def cli(env, identifier):
    """List NAS account credentials."""

    nw_mgr = SoftLayer.NetworkManager(env.client)
    result = nw_mgr.get_nas_credentials(identifier)
    table = formatting.Table(['username', 'password'])
    table.add_row([result['username'], result['password']])
    return table
예제 #21
0
def cli(env, network, quantity, endpoint_id, ipv6, test):
    """Add a new subnet to your account. Valid quantities vary by type.

    \b
    IPv4
    static  - 1, 2, 4, 8, 16, 32, 64, 128, 256
    public  - 4, 8, 16, 32, 64, 128, 256
    private - 4, 8, 16, 32, 64, 128, 256

    \b
    IPv6
    static  - 64
    public  - 64

    \b
    endpoint-id
    static  - Network_Subnet_IpAddress identifier.
    public  - Network_Vlan identifier
    private - Network_Vlan identifier
"""

    mgr = SoftLayer.NetworkManager(env.client)

    if not (test or env.skip_confirmations):
        if not formatting.confirm("This action will incur charges on your "
                                  "account. Continue?"):
            raise exceptions.CLIAbort('Cancelling order.')

    version = 4
    if ipv6:
        version = 6

    try:
        result = mgr.add_subnet(network,
                                quantity=quantity,
                                endpoint_id=endpoint_id,
                                version=version,
                                test_order=test)

    except SoftLayer.SoftLayerAPIError as error:
        raise exceptions.CLIAbort(
            'Unable to order {} {} ipv{} , error: {}'.format(
                quantity, network, version, error.faultString))

    table = formatting.Table(['Item', 'cost'])
    table.align['Item'] = 'r'
    table.align['cost'] = 'r'

    total = 0.0
    if 'prices' in result:
        for price in result['prices']:
            total += float(price.get('recurringFee', 0.0))
            rate = "%.2f" % float(price['recurringFee'])

            table.add_row([price['item']['description'], rate])

    table.add_row(['Total monthly cost', "%.2f" % total])
    env.fout(table)
예제 #22
0
def cli(env, identifier, no_vs, no_hardware):
    """Cancel a subnet."""

    mgr = SoftLayer.NetworkManager(env.client)
    subnet_id = helpers.resolve_id(mgr.resolve_subnet_ids,
                                   identifier,
                                   name='subnet')
    subnet = mgr.get_subnet(subnet_id)

    table = formatting.KeyValueTable(['Name', 'Value'])
    table.align['Name'] = 'r'
    table.align['Value'] = 'l'

    table.add_row(['id', subnet['id']])
    table.add_row([
        'identifier',
        '%s/%s' % (subnet['networkIdentifier'], str(subnet['cidr']))
    ])
    table.add_row(['subnet type', subnet['subnetType']])
    table.add_row(['gateway', subnet.get('gateway', formatting.blank())])
    table.add_row(
        ['broadcast',
         subnet.get('broadcastAddress', formatting.blank())])
    table.add_row(['datacenter', subnet['datacenter']['name']])
    table.add_row(
        ['usable ips',
         subnet.get('usableIpAddressCount', formatting.blank())])

    if not no_vs:
        if subnet['virtualGuests']:
            vs_table = formatting.Table(['Hostname', 'Domain', 'IP'])
            vs_table.align['Hostname'] = 'r'
            vs_table.align['IP'] = 'l'
            for vsi in subnet['virtualGuests']:
                vs_table.add_row([
                    vsi['hostname'], vsi['domain'],
                    vsi.get('primaryIpAddress')
                ])
            table.add_row(['vs', vs_table])
        else:
            table.add_row(['vs', 'none'])

    if not no_hardware:
        if subnet['hardware']:
            hw_table = formatting.Table(['Hostname', 'Domain', 'IP'])
            hw_table.align['Hostname'] = 'r'
            hw_table.align['IP'] = 'l'
            for hardware in subnet['hardware']:
                hw_table.add_row([
                    hardware['hostname'], hardware['domain'],
                    hardware.get('primaryIpAddress')
                ])
            table.add_row(['hardware', hw_table])
        else:
            table.add_row(['hardware', 'none'])

    return table
예제 #23
0
    def execute(self, args):
        mgr = SoftLayer.NetworkManager(self.client)
        global_ip_id = helpers.resolve_id(mgr.resolve_global_ip_ids,
                                          args.get('<identifier>'),
                                          name='global ip')

        if args['--really'] or formatting.no_going_back(global_ip_id):
            mgr.cancel_global_ip(global_ip_id)
        else:
            raise exceptions.CLIAbort('Aborted')
예제 #24
0
def add(env, securitygroup_id, network_component, server, interface):
    """Attach an interface to a security group."""
    _validate_args(network_component, server, interface)

    mgr = SoftLayer.NetworkManager(env.client)
    component_id = _get_component_id(env, network_component, server, interface)

    success = mgr.attach_securitygroup_component(securitygroup_id,
                                                 component_id)
    if not success:
        raise exceptions.CLIAbort("Could not attach network component")
예제 #25
0
def cli(env, identifier):
    """Cancel a subnet."""

    mgr = SoftLayer.NetworkManager(env.client)
    subnet_id = helpers.resolve_id(mgr.resolve_subnet_ids, identifier,
                                   name='subnet')

    if not (env.skip_confirmations or formatting.no_going_back(subnet_id)):
        raise exceptions.CLIAbort('Aborted')

    mgr.cancel_subnet(subnet_id)
예제 #26
0
def cli(env, group_id, name, description):
    """Edit details of a security group."""
    mgr = SoftLayer.NetworkManager(env.client)
    data = {}
    if name:
        data['name'] = name
    if description:
        data['description'] = description

    if not mgr.edit_securitygroup(group_id, **data):
        raise exceptions.CLIAbort("Failed to edit security group")
예제 #27
0
def add(env, securitygroup_id, remote_ip, remote_group,
        direction, ethertype, port_max, port_min, protocol):
    """Add a security group rule to a security group."""
    mgr = SoftLayer.NetworkManager(env.client)

    ret = mgr.add_securitygroup_rule(securitygroup_id, remote_ip, remote_group,
                                     direction, ethertype, port_max,
                                     port_min, protocol)

    if not ret:
        raise exceptions.CLIAbort("Failed to add security group rule")
예제 #28
0
def cli(env, identifier):
    """Cancel global IP."""

    mgr = SoftLayer.NetworkManager(env.client)
    global_ip_id = helpers.resolve_id(mgr.resolve_global_ip_ids, identifier,
                                      name='global ip')

    if env.skip_confirmations or formatting.no_going_back(global_ip_id):
        mgr.cancel_global_ip(global_ip_id)
    else:
        raise exceptions.CLIAbort('Aborted')
예제 #29
0
def cli(env, identifier, note):
    """Set the note of the ipAddress"""

    data = {'note': note}
    mgr = SoftLayer.NetworkManager(env.client)
    ip_id = None
    if str.isdigit(identifier):
        ip_id = identifier
    else:
        ip_object = mgr.get_ip_by_address(identifier)
        ip_id = ip_object.get('id')
    mgr.set_subnet_ipddress_note(ip_id, data)
예제 #30
0
def cli(env, sortby, datacenter, identifier, subnet_type, network_space, ipv4,
        ipv6):
    """List subnets."""

    mgr = SoftLayer.NetworkManager(env.client)

    table = formatting.Table([
        'id',
        'identifier',
        'type',
        'network_space',
        'datacenter',
        'vlan_id',
        'IPs',
        'hardware',
        'vs',
    ])
    table.sortby = sortby

    version = 0
    if ipv4:
        version = 4
    elif ipv6:
        version = 6

    subnets = mgr.list_subnets(
        datacenter=datacenter,
        version=version,
        identifier=identifier,
        subnet_type=subnet_type,
        network_space=network_space,
    )

    for subnet in subnets:
        table.add_row([
            subnet['id'],
            '%s/%s' % (subnet['networkIdentifier'], str(subnet['cidr'])),
            subnet.get('subnetType', formatting.blank()),
            utils.lookup(subnet, 'networkVlan', 'networkSpace')
            or formatting.blank(),
            utils.lookup(
                subnet,
                'datacenter',
                'name',
            ) or formatting.blank(),
            subnet['networkVlanId'],
            subnet['ipAddressCount'],
            len(subnet['hardware']),
            len(subnet['virtualGuests']),
        ])

    env.fout(table)