View a single prefix.

def view_prefix(arg, opts, shell_opts):
    """ View a single prefix.
    """
    # Internally, this function searches in the prefix column which means that
    # hosts have a prefix length of 32/128 while they are normally displayed
    # with the prefix length of the network they are in. To allow the user to
    # input either, e.g. 1.0.0.1 or 1.0.0.1/31 we strip the prefix length bits
    # to assume /32 if the address is not a network address. If it is the
    # network address we always search using the specified mask. In certain
    # cases there is a host with the network address, typically when /31 or /127
    # prefix lengths are used, for example 1.0.0.0/31 and 1.0.0.0/32 (first host
    # in /31 network) in which case it becomes necessary to distinguish between
    # the two using the mask.
    try:
        # this fails if bits are set on right side of mask
        ip = IPy.IP(arg)
    except ValueError:
        arg = arg.split('/')[0]

    q = { 'prefix': arg }

    v = get_vrf(opts.get('vrf_rt'), abort=True)
    if v.rt != 'all':
        q['vrf_rt'] = v.rt

    res = Prefix.list(q)

    if len(res) == 0:
        vrf_text = 'any VRF'
        if v.rt != 'all':
            vrf_text = vrf_format(v)
        print("Address %s not found in %s." % (arg, vrf_text), file=sys.stderr)
        sys.exit(1)

    p = res[0]
    vrf = p.vrf.rt

    print("-- Address ")
    print("  %-26s : %s" % ("Prefix", p.prefix))
    print("  %-26s : %s" % ("Display prefix", p.display_prefix))
    print("  %-26s : %s" % ("Type", p.type))
    print("  %-26s : %s" % ("Status", p.status))
    print("  %-26s : IPv%s" % ("Family", p.family))
    print("  %-26s : %s" % ("VRF", vrf))
    print("  %-26s : %s" % ("Description", p.description))
    print("  %-26s : %s" % ("Node", p.node))
    print("  %-26s : %s" % ("Country", p.country))
    print("  %-26s : %s" % ("Order", p.order_id))
    print("  %-26s : %s" % ("Customer", p.customer_id))
    print("  %-26s : %s" % ("VLAN", p.vlan))
    print("  %-26s : %s" % ("Alarm priority", p.alarm_priority))
    print("  %-26s : %s" % ("Monitor", p.monitor))
    print("  %-26s : %s" % ("Added", p.added))
    print("  %-26s : %s" % ("Last modified", p.last_modified))
    print("  %-26s : %s" % ("Expires", p.expires or '-'))
    if p.family == 4:
        print("  %-26s : %s / %s (%.2f%% of %s)" % ("Addresses Used / Free", p.used_addresses,
                p.free_addresses, (float(p.used_addresses)/p.total_addresses)*100,
                p.total_addresses))
    else:
        print("  %-26s : %.4e / %.4e (%.2f%% of %.4e)" % ("Addresses Used / Free", p.used_addresses,
                p.free_addresses, (float(p.used_addresses)/p.total_addresses)*100,
                p.total_addresses))
    print("-- Extra Attributes")
    if p.avps is not None:
        for key in sorted(p.avps, key=lambda s: s.lower()):
            print("  %-26s : %s" % (key, p.avps[key]))
    print("-- Tags")
    for tag_name in sorted(p.tags, key=lambda s: s.lower()):
        print("  %s" % tag_name)
    print("-- Inherited Tags")
    for tag_name in sorted(p.inherited_tags, key=lambda s: s.lower()):
        print("  %s" % tag_name)
    print("-- Comment")
    print(p.comment or '')