# Buggy code
def _interfaces_ip(out):
    """
    Uses ip to return a dictionary of interfaces with various information about
    each (up/down state, ip address, netmask, and hwaddr)
    """
    ret = dict()

    def parse_network(value, cols):
        """
        Return a tuple of ip, netmask, broadcast
        based on the current set of cols
        """
        brd = None
        scope = None
        if "/" in value:  # we have a CIDR in this address
            ip, cidr = value.split("/")  # pylint: disable=C0103
        else:
            ip = value  # pylint: disable=C0103
            cidr = 32

        if type_ == "inet":
            mask = cidr_to_ipv4_netmask(int(cidr))
            if "brd" in cols:
                brd = cols[cols.index("brd") + 1]
        elif type_ == "inet6":
            mask = cidr
            scope = cols[cols.index("scope") + 1]
        return (ip, mask, brd, scope)

    groups = re.compile("\r?\n\\d").split(out)
    for group in groups:
        iface = None
        data = dict()

        for line in group.splitlines():
            if " " not in line:
                continue
            match = re.match(r"^\d*:\s+([\w.\-]+)(?:@)?([\w.\-]+)?:\s+<(.+)>", line)
            if match:
                iface, parent, attrs = match.groups()
                if "UP" in attrs.split(","):
                    data["up"] = True
                else:
                    data["up"] = False
                if parent:
                    data["parent"] = parent
                continue

            cols = line.split()
            if len(cols) >= 2:
                type_, value = tuple(cols[0:2])
                iflabel = cols[-1:][0]
                if type_ in ("inet", "inet6"):
                    if "secondary" not in cols:
                        ipaddr, netmask, broadcast, scope = parse_network(value, cols)
                        if type_ == "inet":
                            if "inet" not in data:
                                data["inet"] = list()
                            addr_obj = dict()
                            addr_obj["address"] = ipaddr
                            addr_obj["netmask"] = netmask
                            addr_obj["broadcast"] = broadcast
                            addr_obj["label"] = iflabel
                            data["inet"].append(addr_obj)
                        elif type_ == "inet6":
                            if "inet6" not in data:
                                data["inet6"] = list()
                            addr_obj = dict()
                            addr_obj["address"] = ipaddr
                            addr_obj["prefixlen"] = netmask
                            addr_obj["scope"] = scope
                            data["inet6"].append(addr_obj)
                    else:
                        if "secondary" not in data:
                            data["secondary"] = list()
                        ip_, mask, brd, scp = parse_network(value, cols)
                        data["secondary"].append(
                            {
                                "type": type_,
                                "address": ip_,
                                "netmask": mask,
                                "broadcast": brd,
                                "label": iflabel,
                            }
                        )
                        del ip_, mask, brd, scp
                elif type_.startswith("link"):
                    data["hwaddr"] = value
        if iface:
            ret[iface] = data
            del iface, data
    return ret


# Traceback (ValueError)
=> salt --versions-report

Traceback (most recent call last):
File "/usr/local/bin/salt-ssh", line 10, in <module>
salt_ssh()
File "/usr/local/lib/python2.7/site-packages/salt/scripts.py", line 269, in salt_ssh
client = salt.cli.ssh.SaltSSH()
File "/usr/local/lib/python2.7/site-packages/salt/utils/parsers.py", line 128, in __init__
optparse.OptionParser.__init__(self, *args, **kwargs)
File "/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/optparse.py", line 1220, in __init__
add_help=add_help_option)
File "/usr/local/lib/python2.7/site-packages/salt/utils/parsers.py", line 204, in _populate_option_list
mixin_setup_func(self)
File "/usr/local/lib/python2.7/site-packages/salt/utils/parsers.py", line 1014, in _mixin_setup
config.minion_config(None)
File "/usr/local/lib/python2.7/site-packages/salt/config.py", line 1415, in minion_config
opts = apply_minion_config(overrides, defaults, cache_minion_id=cache_minion_id)
File "/usr/local/lib/python2.7/site-packages/salt/config.py", line 2504, in apply_minion_config
cache_minion_id=cache_minion_id)
File "/usr/local/lib/python2.7/site-packages/salt/config.py", line 2473, in get_id
newid = salt.utils.network.generate_minion_id()
File "/usr/local/lib/python2.7/site-packages/salt/utils/network.py", line 275, in generate_minion_id
for addr in salt.utils.network.ip_addrs():
File "/usr/local/lib/python2.7/site-packages/salt/utils/network.py", line 969, in ip_addrs
return _ip_addrs(interface, include_loopback, interface_data, 'inet')
File "/usr/local/lib/python2.7/site-packages/salt/utils/network.py", line 944, in _ip_addrs
else interfaces()
File "/usr/local/lib/python2.7/site-packages/salt/utils/network.py", line 760, in interfaces
return linux_interfaces()
File "/usr/local/lib/python2.7/site-packages/salt/utils/network.py", line 647, in linux_interfaces
salt.utils.to_str(cmd2)))
File "/usr/local/lib/python2.7/site-packages/salt/utils/network.py", line 508, in _interfaces_ip
ipaddr, netmask, broadcast, scope = parse_network(value, cols)
File "/usr/local/lib/python2.7/site-packages/salt/utils/network.py", line 480, in parse_network
scope = cols[cols.index('scope') + 1]
ValueError: 'scope' is not in list

# Fixed code
def _interfaces_ip(out):
    """
    Uses ip to return a dictionary of interfaces with various information about
    each (up/down state, ip address, netmask, and hwaddr)
    """
    ret = dict()

    def parse_network(value, cols):
        """
        Return a tuple of ip, netmask, broadcast
        based on the current set of cols
        """
        brd = None
        scope = None
        if "/" in value:  # we have a CIDR in this address
            ip, cidr = value.split("/")  # pylint: disable=C0103
        else:
            ip = value  # pylint: disable=C0103
            cidr = 32

        if type_ == "inet":
            mask = cidr_to_ipv4_netmask(int(cidr))
            if "brd" in cols:
                brd = cols[cols.index("brd") + 1]
        elif type_ == "inet6":
            mask = cidr
            if "scope" in cols:
                scope = cols[cols.index("scope") + 1]
        return (ip, mask, brd, scope)

    groups = re.compile("\r?\n\\d").split(out)
    for group in groups:
        iface = None
        data = dict()

        for line in group.splitlines():
            if " " not in line:
                continue
            match = re.match(r"^\d*:\s+([\w.\-]+)(?:@)?([\w.\-]+)?:\s+<(.+)>", line)
            if match:
                iface, parent, attrs = match.groups()
                if "UP" in attrs.split(","):
                    data["up"] = True
                else:
                    data["up"] = False
                if parent:
                    data["parent"] = parent
                continue

            cols = line.split()
            if len(cols) >= 2:
                type_, value = tuple(cols[0:2])
                iflabel = cols[-1:][0]
                if type_ in ("inet", "inet6"):
                    if "secondary" not in cols:
                        ipaddr, netmask, broadcast, scope = parse_network(value, cols)
                        if type_ == "inet":
                            if "inet" not in data:
                                data["inet"] = list()
                            addr_obj = dict()
                            addr_obj["address"] = ipaddr
                            addr_obj["netmask"] = netmask
                            addr_obj["broadcast"] = broadcast
                            addr_obj["label"] = iflabel
                            data["inet"].append(addr_obj)
                        elif type_ == "inet6":
                            if "inet6" not in data:
                                data["inet6"] = list()
                            addr_obj = dict()
                            addr_obj["address"] = ipaddr
                            addr_obj["prefixlen"] = netmask
                            addr_obj["scope"] = scope
                            data["inet6"].append(addr_obj)
                    else:
                        if "secondary" not in data:
                            data["secondary"] = list()
                        ip_, mask, brd, scp = parse_network(value, cols)
                        data["secondary"].append(
                            {
                                "type": type_,
                                "address": ip_,
                                "netmask": mask,
                                "broadcast": brd,
                                "label": iflabel,
                            }
                        )
                        del ip_, mask, brd, scp
                elif type_.startswith("link"):
                    data["hwaddr"] = value
        if iface:
            ret[iface] = data
            del iface, data
    return ret