Example #1
0
def _normalize_pools(existing, desired):
    pools = {'existing': {4: None, 6: None}, 'desired': {4: None, 6: None}}

    for pool in existing['Config']:
        subnet = ipaddress.ip_network(pool.get('Subnet'))
        pools['existing'][subnet.version] = pool

    for pool in desired['Config']:
        subnet = ipaddress.ip_network(pool.get('Subnet'))
        if pools['desired'][subnet.version] is not None:
            raise ValueError('Only one IPv{0} pool is permitted'.format(
                subnet.version))
        else:
            pools['desired'][subnet.version] = pool

    if pools['desired'][6] and not pools['desired'][4]:
        raise ValueError(
            'An IPv4 pool is required when an IPv6 pool is used. See the '
            'documentation for details.')

    # The pools will be sorted when comparing
    existing['Config'] = [
        pools['existing'][x] for x in (4, 6)
        if pools['existing'][x] is not None
    ]
    desired['Config'] = [
        pools['desired'][x] for x in (4, 6) if pools['desired'][x] is not None
    ]
Example #2
0
def _normalize_pools(existing, desired):
    pools = {"existing": {4: None, 6: None}, "desired": {4: None, 6: None}}

    for pool in existing["Config"]:
        subnet = ipaddress.ip_network(pool.get("Subnet"))
        pools["existing"][subnet.version] = pool

    for pool in desired["Config"]:
        subnet = ipaddress.ip_network(pool.get("Subnet"))
        if pools["desired"][subnet.version] is not None:
            raise ValueError("Only one IPv{} pool is permitted".format(subnet.version))
        else:
            pools["desired"][subnet.version] = pool

    if pools["desired"][6] and not pools["desired"][4]:
        raise ValueError(
            "An IPv4 pool is required when an IPv6 pool is used. See the "
            "documentation for details."
        )

    # The pools will be sorted when comparing
    existing["Config"] = [
        pools["existing"][x] for x in (4, 6) if pools["existing"][x] is not None
    ]
    desired["Config"] = [
        pools["desired"][x] for x in (4, 6) if pools["desired"][x] is not None
    ]
Example #3
0
def _parse_member(settype, member, strict=False):
    subtypes = settype.split(":")[1].split(",")

    all_parts = member.split(" ", 1)
    parts = all_parts[0].split(",")

    parsed_member = []
    for i in range(len(subtypes)):
        subtype = subtypes[i]
        part = parts[i]

        if subtype in ["ip", "net"]:
            try:
                if "/" in part:
                    part = ipaddress.ip_network(part, strict=strict)
                elif "-" in part:
                    start, end = list(
                        map(ipaddress.ip_address, part.split("-")))

                    part = list(ipaddress.summarize_address_range(start, end))
                else:
                    part = ipaddress.ip_address(part)
            except ValueError:
                pass

        elif subtype == "port":
            part = int(part)

        parsed_member.append(part)

    if len(all_parts) > 1:
        parsed_member.append(all_parts[1])

    return parsed_member
Example #4
0
def _parse_member(settype, member, strict=False):
    subtypes = settype.split(':')[1].split(',')

    all_parts = member.split(' ', 1)
    parts = all_parts[0].split(',')

    parsed_member = []
    for i in range(len(subtypes)):
        subtype = subtypes[i]
        part = parts[i]

        if subtype in ['ip', 'net']:
            try:
                if '/' in part:
                    part = ipaddress.ip_network(part, strict=strict)
                elif '-' in part:
                    start, end = list(map(ipaddress.ip_address, part.split('-')))

                    part = list(ipaddress.summarize_address_range(start, end))
                else:
                    part = ipaddress.ip_address(part)
            except ValueError:
                pass

        elif subtype == 'port':
            part = int(part)

        parsed_member.append(part)

    if len(all_parts) > 1:
        parsed_member.append(all_parts[1])

    return parsed_member
Example #5
0
File: scan.py Project: DaveQB/salt
 def targets(self):
     '''
     Return ip addrs based on netmask, sitting in the "glob" spot because
     it is the default
     '''
     addrs = ()
     ret = {}
     ports = __opts__['ssh_scan_ports']
     if not isinstance(ports, list):
         # Comma-separate list of integers
         ports = list(map(int, str(ports).split(',')))
     try:
         addrs = [ipaddress.ip_address(self.tgt)]
     except ValueError:
         try:
             addrs = ipaddress.ip_network(self.tgt).hosts()
         except ValueError:
             pass
     for addr in addrs:
         addr = str(addr)
         log.trace('Scanning host: {0}'.format(addr))
         for port in ports:
             log.trace('Scanning port: {0}'.format(port))
             try:
                 sock = salt.utils.network.get_socket(addr, socket.SOCK_STREAM)
                 sock.settimeout(float(__opts__['ssh_scan_timeout']))
                 sock.connect((addr, port))
                 sock.shutdown(socket.SHUT_RDWR)
                 sock.close()
                 ret[addr] = {'host': addr, 'port': port}
             except socket.error:
                 pass
     return ret
Example #6
0
 def targets(self):
     '''
     Return ip addrs based on netmask, sitting in the "glob" spot because
     it is the default
     '''
     addrs = ()
     ret = {}
     ports = __opts__['ssh_scan_ports']
     if not isinstance(ports, list):
         # Comma-separate list of integers
         ports = list(map(int, str(ports).split(',')))
     try:
         addrs = [ipaddress.ip_address(self.tgt)]
     except ValueError:
         try:
             addrs = ipaddress.ip_network(self.tgt).hosts()
         except ValueError:
             pass
     for addr in addrs:
         addr = str(addr)
         ret[addr] = copy.deepcopy(__opts__.get('roster_defaults', {}))
         log.trace('Scanning host: {0}'.format(addr))
         for port in ports:
             log.trace('Scanning port: {0}'.format(port))
             try:
                 sock = salt.utils.network.get_socket(addr, socket.SOCK_STREAM)
                 sock.settimeout(float(__opts__['ssh_scan_timeout']))
                 sock.connect((addr, port))
                 sock.shutdown(socket.SHUT_RDWR)
                 sock.close()
                 ret[addr].update({'host': addr, 'port': port})
             except socket.error:
                 pass
     return ret
Example #7
0
 def targets(self):
     """
     Return ip addrs based on netmask, sitting in the "glob" spot because
     it is the default
     """
     addrs = ()
     ret = {}
     ports = __opts__["ssh_scan_ports"]
     if not isinstance(ports, list):
         # Comma-separate list of integers
         ports = list(map(int, six.text_type(ports).split(",")))
     try:
         addrs = [ipaddress.ip_address(self.tgt)]
     except ValueError:
         try:
             addrs = ipaddress.ip_network(self.tgt).hosts()
         except ValueError:
             pass
     for addr in addrs:
         addr = six.text_type(addr)
         ret[addr] = copy.deepcopy(__opts__.get("roster_defaults", {}))
         log.trace("Scanning host: %s", addr)
         for port in ports:
             log.trace("Scanning port: %s", port)
             try:
                 sock = salt.utils.network.get_socket(
                     addr, socket.SOCK_STREAM)
                 sock.settimeout(float(__opts__["ssh_scan_timeout"]))
                 sock.connect((addr, port))
                 sock.shutdown(socket.SHUT_RDWR)
                 sock.close()
                 ret[addr].update({"host": addr, "port": port})
             except socket.error:
                 pass
     return ret
Example #8
0
def match(tgt, opts=None):
    """
    Matches based on IP address or CIDR notation
    """
    if not opts:
        opts = __opts__

    try:
        # Target is an address?
        tgt = ipaddress.ip_address(tgt)
    except:  # pylint: disable=bare-except
        try:
            # Target is a network?
            tgt = ipaddress.ip_network(tgt)
        except:  # pylint: disable=bare-except
            log.error("Invalid IP/CIDR target: %s", tgt)
            return []
    proto = "ipv{}".format(tgt.version)

    grains = opts["grains"]

    if proto not in grains:
        match = False
    elif isinstance(tgt, (ipaddress.IPv4Address, ipaddress.IPv6Address)):
        match = str(tgt) in grains[proto]
    else:
        match = salt.utils.network.in_subnet(tgt, grains[proto])

    return match
Example #9
0
def _minion_lookup(minion_id, key, minion):
    grains, pillar, addrs, mine = minion
    if key == 'id':
        # Just paste in the minion ID
        return minion_id
    elif isinstance(key, dict):
        # Lookup the key in the dict
        for data_id, lookup in key.items():
            ref = {
                'pillar': pillar,
                'grain': grains,
                'mine': mine,
            }[data_id]

            for k in _data_lookup(ref, lookup):
                if k:
                    return k

            return None
    elif re.match(r'^[0-9a-fA-F:./]+$', key):
        # It smells like a CIDR block
        try:
            net = ipaddress.ip_network(key, strict=True)
        except ValueError:
            log.error('{0} is an invalid CIDR network'.format(net))
            return None

        for addr in addrs[net.version]:
            if addr in net:
                return str(addr)
    else:
        # Take the addresses from the grains and filter them
        filters = {
            'global':
            lambda addr: addr.is_global
            if addr.version == 6 else not addr.is_private,
            'public':
            lambda addr: not addr.is_private,
            'private':
            lambda addr: addr.is_private and not addr.is_loopback and not addr.
            is_link_local,
            'local':
            lambda addr: addr.is_loopback,
        }

        ip_vers = [4, 6]
        if key.startswith('ipv'):
            ip_vers = [int(key[3])]
            key = key[5:]

        for ip_ver in ip_vers:
            try:
                for addr in addrs[ip_ver]:
                    if filters[key](addr):
                        return str(addr)
            except KeyError:
                raise KeyError(
                    'Invalid filter {0} specified in roster_order'.format(key))
Example #10
0
def _minion_lookup(minion_id, key, minion):
    grains, pillar, addrs, mine = minion

    if key == "id":
        # Just paste in the minion ID
        return minion_id
    elif isinstance(key, dict):
        # Lookup the key in the dict
        for data_id, lookup in key.items():
            ref = {"pillar": pillar, "grain": grains, "mine": mine}[data_id]

            for k in _data_lookup(ref, lookup):
                if k:
                    return k

            return None
    elif key.startswith("sdb://"):
        # It's a Salt SDB url
        return salt["sdb.get"](key)
    elif re.match(r"^[0-9a-fA-F:./]+$", key):
        # It smells like a CIDR block
        try:
            net = ipaddress.ip_network(key, strict=True)
        except ValueError:
            log.error("%s is an invalid CIDR network", net)
            return None

        for addr in addrs[net.version]:
            if addr in net:
                return str(addr)
    else:
        # Take the addresses from the grains and filter them
        filters = {
            "global":
            lambda addr: addr.is_global
            if addr.version == 6 else not addr.is_private,
            "public":
            lambda addr: not addr.is_private,
            "private":
            lambda addr: addr.is_private and not addr.is_loopback and not addr.
            is_link_local,
            "local":
            lambda addr: addr.is_loopback,
        }

        ip_vers = [4, 6]
        if key.startswith("ipv"):
            ip_vers = [int(key[3])]
            key = key[5:]

        for ip_ver in ip_vers:
            try:
                for addr in addrs[ip_ver]:
                    if filters[key](addr):
                        return str(addr)
            except KeyError:
                raise KeyError(
                    "Invalid filter {} specified in roster_order".format(key))
Example #11
0
    def _check_ipcidr_minions(self, expr, greedy):
        '''
        Return the minions found by looking via ipcidr
        '''
        cache_enabled = self.opts.get('minion_data_cache', False)

        if greedy:
            minions = self._pki_minions()
        elif cache_enabled:
            minions = self.cache.list('minions')
        else:
            return {'minions': [],
                    'missing': []}

        if cache_enabled:
            if greedy:
                cminions = self.cache.list('minions')
            else:
                cminions = minions
            if cminions is None:
                return {'minions': minions,
                        'missing': []}

            tgt = expr
            try:
                # Target is an address?
                tgt = ipaddress.ip_address(tgt)
            except Exception:
                try:
                    # Target is a network?
                    tgt = ipaddress.ip_network(tgt)
                except Exception:
                    log.error('Invalid IP/CIDR target: %s', tgt)
                    return {'minions': [],
                            'missing': []}
            proto = 'ipv{0}'.format(tgt.version)

            minions = set(minions)
            for id_ in cminions:
                mdata = self.cache.fetch('minions/{0}'.format(id_), 'data')
                if mdata is None:
                    if not greedy:
                        minions.remove(id_)
                    continue
                grains = mdata.get('grains')
                if grains is None or proto not in grains:
                    match = False
                elif isinstance(tgt, (ipaddress.IPv4Address, ipaddress.IPv6Address)):
                    match = six.text_type(tgt) in grains[proto]
                else:
                    match = salt.utils.network.in_subnet(tgt, grains[proto])

                if not match and id_ in minions:
                    minions.remove(id_)

        return {'minions': list(minions),
                'missing': []}
Example #12
0
def calc_net(ipaddr, netmask=None):
    '''
    Takes IP (CIDR notation supported) and optionally netmask
    and returns the network in CIDR-notation.
    (The IP can be any IP inside the subnet)
    '''
    if netmask is not None:
        ipaddr = '{0}/{1}'.format(ipaddr, netmask)

    return str(ipaddress.ip_network(ipaddr, strict=False))
Example #13
0
def calc_net(ipaddr, netmask=None):
    '''
    Takes IP (CIDR notation supported) and optionally netmask
    and returns the network in CIDR-notation.
    (The IP can be any IP inside the subnet)
    '''
    if netmask is not None:
        ipaddr = '{0}/{1}'.format(ipaddr, netmask)

    return str(ipaddress.ip_network(ipaddr, strict=False))
Example #14
0
    def _check_ipcidr_minions(self, expr, greedy):
        """
        Return the minions found by looking via ipcidr
        """
        cache_enabled = self.opts.get("minion_data_cache", False)

        if greedy:
            minions = self._pki_minions()
        elif cache_enabled:
            minions = self.cache.list("minions")
        else:
            return {"minions": [], "missing": []}

        if cache_enabled:
            if greedy:
                cminions = self.cache.list("minions")
            else:
                cminions = minions
            if cminions is None:
                return {"minions": minions, "missing": []}

            tgt = expr
            try:
                # Target is an address?
                tgt = ipaddress.ip_address(tgt)
            except Exception:  # pylint: disable=broad-except
                try:
                    # Target is a network?
                    tgt = ipaddress.ip_network(tgt)
                except Exception:  # pylint: disable=broad-except
                    log.error("Invalid IP/CIDR target: %s", tgt)
                    return {"minions": [], "missing": []}
            proto = "ipv{}".format(tgt.version)

            minions = set(minions)
            for id_ in cminions:
                mdata = self.cache.fetch("minions/{}".format(id_), "data")
                if mdata is None:
                    if not greedy:
                        minions.remove(id_)
                    continue
                grains = mdata.get("grains")
                if grains is None or proto not in grains:
                    match = False
                elif isinstance(
                        tgt, (ipaddress.IPv4Address, ipaddress.IPv6Address)):
                    match = str(tgt) in grains[proto]
                else:
                    match = salt.utils.network.in_subnet(tgt, grains[proto])

                if not match and id_ in minions:
                    minions.remove(id_)

        return {"minions": list(minions), "missing": []}
Example #15
0
 def __init__(self, name, **kwargs):
     self.kwargs = kwargs
     self.name = name
     try:
         self.net = ipaddress.ip_network(self.kwargs['subnet'])
         self._rand_indexes = random.sample(
             range(2, self.net.num_addresses - 1),
             self.net.num_addresses - 3)
         self.ip_arg = 'ipv{0}_address'.format(self.net.version)
     except KeyError:
         # No explicit subnet passed
         self.net = self.ip_arg = None
Example #16
0
def mac2eui64(mac, prefix=None):
    '''
    Convert a MAC address to a EUI64 identifier
    or, with prefix provided, a full IPv6 address
    '''
    # http://tools.ietf.org/html/rfc4291#section-2.5.1
    eui64 = re.sub(r'[.:-]', '', mac).lower()
    eui64 = eui64[0:6] + 'fffe' + eui64[6:]
    eui64 = hex(int(eui64[0:2], 16) | 2)[2:].zfill(2) + eui64[2:]

    if prefix is None:
        return ':'.join(re.findall(r'.{4}', eui64))
    else:
        try:
            net = ipaddress.ip_network(prefix, strict=False)
            euil = int('0x{0}'.format(eui64), 16)
            return '{0}/{1}'.format(net[euil], net.prefixlen)
        except:  # pylint: disable=bare-except
            return
Example #17
0
def in_subnet(cidr, addr=None):
    '''
    Returns True if host or (any of) addrs is within specified subnet, otherwise False
    '''
    try:
        cidr = ipaddress.ip_network(cidr)
    except ValueError:
        log.error('Invalid CIDR \'{0}\''.format(cidr))
        return False

    if addr is None:
        addr = ip_addrs()
    elif isinstance(addr, six.string_types):
        return ipaddress.ip_address(addr) in cidr

    for ip_addr in addr:
        if ipaddress.ip_address(ip_addr) in cidr:
            return True
    return False
Example #18
0
def mac2eui64(mac, prefix=None):
    '''
    Convert a MAC address to a EUI64 identifier
    or, with prefix provided, a full IPv6 address
    '''
    # http://tools.ietf.org/html/rfc4291#section-2.5.1
    eui64 = re.sub(r'[.:-]', '', mac).lower()
    eui64 = eui64[0:6] + 'fffe' + eui64[6:]
    eui64 = hex(int(eui64[0:2], 16) | 2)[2:].zfill(2) + eui64[2:]

    if prefix is None:
        return ':'.join(re.findall(r'.{4}', eui64))
    else:
        try:
            net = ipaddress.ip_network(prefix, strict=False)
            euil = int('0x{0}'.format(eui64), 16)
            return '{0}/{1}'.format(net[euil], net.prefixlen)
        except:  # pylint: disable=bare-except
            return
Example #19
0
def get_net_start(ipaddr, netmask):
    '''
    Return the address of the network
    '''
    net = ipaddress.ip_network('{0}/{1}'.format(ipaddr, netmask), strict=False)
    return str(net.network_address)
Example #20
0
def get_ssh_config(name, network_mask='', get_private_key=False):
    r'''
    Retrieve hints of how you might connect to a Vagrant VM.

    :param name: the salt_id of the machine
    :param network_mask: a CIDR mask to search for the VM's address
    :param get_private_key: (default: False) return the key used for ssh login
    :return: a dict of ssh login information for the VM

    CLI Example:

    .. code-block:: bash

        salt <host> vagrant.get_ssh_config <salt_id>
        salt my_laptop vagrant.get_ssh_config quail1 network_mask=10.0.0.0/8 get_private_key=True

    The returned dictionary contains:

    - key_filename:  the name of the private key file on the VM host computer
    - ssh_username:  the username to be used to log in to the VM
    - ssh_host:  the IP address used to log in to the VM.  (This will usually be `127.0.0.1`)
    - ssh_port:  the TCP port used to log in to the VM.  (This will often be `2222`)
    - \[ip_address:\]  (if `network_mask` is defined. see below)
    - \[private_key:\]  (if `get_private_key` is True) the private key for ssh_username

    About `network_mask`:

    Vagrant usually uses a redirected TCP port on its host computer to log in to a VM using ssh.
    This redirected port and its IP address are "ssh_port" and "ssh_host".  The ssh_host is
    usually the localhost (127.0.0.1).
    This makes it impossible for a third machine (such as a salt-cloud master) to contact the VM
    unless the VM has another network interface defined.  You will usually want a bridged network
    defined by having a `config.vm.network "public_network"` statement in your `Vagrantfile`.

    The IP address of the bridged adapter will typically be assigned by DHCP and unknown to you,
    but you should be able to determine what IP network the address will be chosen from.
    If you enter a CIDR network mask, Salt will attempt to find the VM's address for you.
    The host machine will send an "ifconfig" command to the VM (using ssh to `ssh_host`:`ssh_port`)
    and return the IP address of the first interface it can find which matches your mask.
    '''
    vm_ = get_vm_info(name)

    ssh_config = _vagrant_ssh_config(vm_)

    try:
        ans = {
            'key_filename': ssh_config['IdentityFile'],
            'ssh_username': ssh_config['User'],
            'ssh_host': ssh_config['HostName'],
            'ssh_port': ssh_config['Port'],
        }

    except KeyError:
        raise CommandExecutionError(
            'Insufficient SSH information to contact VM {}. '
            'Is it running?'.format(vm_.get('machine', '(default)')))

    if network_mask:
        #  ask the new VM to report its network address
        command = 'ssh -i {IdentityFile} -p {Port} ' \
                  '-oStrictHostKeyChecking={StrictHostKeyChecking} ' \
                  '-oUserKnownHostsFile={UserKnownHostsFile} ' \
                  '-oControlPath=none ' \
                  '{User}@{HostName} ifconfig'.format(**ssh_config)

        log.info('Trying ssh -p {Port} {User}@{HostName} ifconfig'.format(
            **ssh_config))
        reply = __salt__['cmd.shell'](command)
        log.info('--->\n%s', reply)
        target_network_range = ipaddress.ip_network(network_mask, strict=False)

        for line in reply.split('\n'):
            try:  # try to find a bridged network address
                # the lines we are looking for appear like:
                #    "inet addr:10.124.31.185  Bcast:10.124.31.255  Mask:255.255.248.0"
                # or "inet6 addr: fe80::a00:27ff:fe04:7aac/64 Scope:Link"
                tokens = line.replace(
                    'addr:', '',
                    1).split()  # remove "addr:" if it exists, then split
                found_address = None
                if "inet" in tokens:
                    nxt = tokens.index("inet") + 1
                    found_address = ipaddress.ip_address(tokens[nxt])
                elif "inet6" in tokens:
                    nxt = tokens.index("inet6") + 1
                    found_address = ipaddress.ip_address(
                        tokens[nxt].split('/')[0])
                if found_address in target_network_range:
                    ans['ip_address'] = six.text_type(found_address)
                    break  # we have located a good matching address
            except (IndexError, AttributeError, TypeError):
                pass  # all syntax and type errors loop here
                # falling out if the loop leaves us remembering the last candidate
        log.info('Network IP address in %s detected as: %s',
                 target_network_range, ans.get('ip_address', '(not found)'))

    if get_private_key:
        # retrieve the Vagrant private key from the host
        try:
            with salt.utils.files.fopen(ssh_config['IdentityFile']) as pks:
                ans['private_key'] = salt.utils.stringutils.to_unicode(
                    pks.read())
        except (OSError, IOError) as e:
            raise CommandExecutionError(
                "Error processing Vagrant private key file: {}".format(e))
    return ans
Example #21
0
def get_net_start(ipaddr, netmask):
    '''
    Return the address of the network
    '''
    net = ipaddress.ip_network('{0}/{1}'.format(ipaddr, netmask), strict=False)
    return str(net.network_address)
Example #22
0
File: dns.py Project: yvwulei/salt
def parse_resolv(src='/etc/resolv.conf'):
    '''
    Parse a resolver configuration file (traditionally /etc/resolv.conf)
    '''

    nameservers = []
    ip4_nameservers = []
    ip6_nameservers = []
    search = []
    sortlist = []
    domain = ''
    options = []

    try:
        with salt.utils.files.fopen(src) as src_file:
            # pylint: disable=too-many-nested-blocks
            for line in src_file:
                line = salt.utils.stringutils.to_unicode(line).strip().split()

                try:
                    (directive, arg) = (line[0].lower(), line[1:])
                    # Drop everything after # or ; (comments)
                    arg = list(
                        itertools.takewhile(lambda x: x[0] not in ('#', ';'),
                                            arg))

                    if directive == 'nameserver':
                        # Split the scope (interface) if it is present
                        addr, scope = arg[0].split(
                            '%', 1) if '%' in arg[0] else (arg[0], '')
                        try:
                            ip_addr = ipaddress.ip_address(addr)
                            version = ip_addr.version
                            # Rejoin scope after address validation
                            if scope:
                                ip_addr = '%'.join((str(ip_addr), scope))
                            if ip_addr not in nameservers:
                                nameservers.append(ip_addr)
                            if version == 4 and ip_addr not in ip4_nameservers:
                                ip4_nameservers.append(ip_addr)
                            elif version == 6 and ip_addr not in ip6_nameservers:
                                ip6_nameservers.append(ip_addr)
                        except ValueError as exc:
                            log.error('%s: %s', src, exc)
                    elif directive == 'domain':
                        domain = arg[0]
                    elif directive == 'search':
                        search = arg
                    elif directive == 'sortlist':
                        # A sortlist is specified by IP address netmask pairs.
                        # The netmask is optional and defaults to the natural
                        # netmask of the net. The IP address and optional
                        # network pairs are separated by slashes.
                        for ip_raw in arg:
                            try:
                                ip_net = ipaddress.ip_network(ip_raw)
                            except ValueError as exc:
                                log.error('%s: %s', src, exc)
                            else:
                                if '/' not in ip_raw:
                                    # No netmask has been provided, guess
                                    # the "natural" one
                                    if ip_net.version == 4:
                                        ip_addr = six.text_type(
                                            ip_net.network_address)
                                        # pylint: disable=protected-access
                                        mask = salt.utils.network.natural_ipv4_netmask(
                                            ip_addr)
                                        ip_net = ipaddress.ip_network(
                                            '{0}{1}'.format(ip_addr, mask),
                                            strict=False)
                                    if ip_net.version == 6:
                                        # TODO
                                        pass

                                if ip_net not in sortlist:
                                    sortlist.append(ip_net)
                    elif directive == 'options':
                        # Options allows certain internal resolver variables to
                        # be modified.
                        if arg[0] not in options:
                            options.append(arg[0])
                except IndexError:
                    continue

        if domain and search:
            # The domain and search keywords are mutually exclusive.  If more
            # than one instance of these keywords is present, the last instance
            # will override.
            log.debug(
                '%s: The domain and search keywords are mutually exclusive.',
                src)

        return {
            'nameservers': nameservers,
            'ip4_nameservers': ip4_nameservers,
            'ip6_nameservers': ip6_nameservers,
            'sortlist': [ip.with_netmask for ip in sortlist],
            'domain': domain,
            'search': search,
            'options': options
        }
    except IOError:
        return {}
Example #23
0
def _network_size(ip_addr_entry):
    return ipaddress.ip_network(ip_addr_entry, strict=False).num_addresses
Example #24
0
def _network_hosts(ip_addr_entry):
    return [
        str(host)
        for host in ipaddress.ip_network(ip_addr_entry, strict=False).hosts()
    ]
Example #25
0
def _network_size(ip_addr_entry):
    return ipaddress.ip_network(ip_addr_entry, strict=False).num_addresses
Example #26
0
def _network_hosts(ip_addr_entry):
    return [
        str(host)
        for host in ipaddress.ip_network(ip_addr_entry, strict=False).hosts()
    ]
Example #27
0
 def _net(self):
     return ipaddress.ip_network(self.subnet)
Example #28
0
def parse_resolv(src="/etc/resolv.conf"):
    """
    Parse a resolver configuration file (traditionally /etc/resolv.conf)
    """

    nameservers = []
    ip4_nameservers = []
    ip6_nameservers = []
    search = []
    sortlist = []
    domain = ""
    options = []

    try:
        with salt.utils.files.fopen(src) as src_file:
            # pylint: disable=too-many-nested-blocks
            for line in src_file:
                line = salt.utils.stringutils.to_unicode(line).strip().split()

                try:
                    (directive, arg) = (line[0].lower(), line[1:])
                    # Drop everything after # or ; (comments)
                    arg = list(
                        itertools.takewhile(lambda x: x[0] not in ("#", ";"),
                                            arg))
                    if directive == "nameserver":
                        addr = arg[0]
                        try:
                            ip_addr = ipaddress.ip_address(addr)
                            version = ip_addr.version
                            ip_addr = str(ip_addr)
                            if ip_addr not in nameservers:
                                nameservers.append(ip_addr)
                            if version == 4 and ip_addr not in ip4_nameservers:
                                ip4_nameservers.append(ip_addr)
                            elif version == 6 and ip_addr not in ip6_nameservers:
                                ip6_nameservers.append(ip_addr)
                        except ValueError as exc:
                            log.error("%s: %s", src, exc)
                    elif directive == "domain":
                        domain = arg[0]
                    elif directive == "search":
                        search = arg
                    elif directive == "sortlist":
                        # A sortlist is specified by IP address netmask pairs.
                        # The netmask is optional and defaults to the natural
                        # netmask of the net. The IP address and optional
                        # network pairs are separated by slashes.
                        for ip_raw in arg:
                            try:
                                ip_net = ipaddress.ip_network(ip_raw)
                            except ValueError as exc:
                                log.error("%s: %s", src, exc)
                            else:
                                if "/" not in ip_raw:
                                    # No netmask has been provided, guess
                                    # the "natural" one
                                    if ip_net.version == 4:
                                        ip_addr = str(ip_net.network_address)
                                        # pylint: disable=protected-access
                                        mask = salt.utils.network.natural_ipv4_netmask(
                                            ip_addr)
                                        ip_net = ipaddress.ip_network(
                                            "{}{}".format(ip_addr, mask),
                                            strict=False)
                                    if ip_net.version == 6:
                                        # TODO
                                        pass

                                if ip_net not in sortlist:
                                    sortlist.append(ip_net)
                    elif directive == "options":
                        # Options allows certain internal resolver variables to
                        # be modified.
                        if arg[0] not in options:
                            options.append(arg[0])
                except IndexError:
                    continue

        if domain and search:
            # The domain and search keywords are mutually exclusive.  If more
            # than one instance of these keywords is present, the last instance
            # will override.
            log.debug(
                "%s: The domain and search keywords are mutually exclusive.",
                src)

        return {
            "nameservers": nameservers,
            "ip4_nameservers": ip4_nameservers,
            "ip6_nameservers": ip6_nameservers,
            "sortlist": [ip.with_netmask for ip in sortlist],
            "domain": domain,
            "search": search,
            "options": options,
        }
    except OSError:
        return {}
Example #29
0
File: dns.py Project: bryson/salt
def parse_resolv(src='/etc/resolv.conf'):
    '''
    Parse a resolver configuration file (traditionally /etc/resolv.conf)
    '''

    nameservers = []
    search = []
    sortlist = []
    domain = ''
    options = []

    try:
        with salt.utils.fopen(src) as src_file:
            # pylint: disable=too-many-nested-blocks
            for line in src_file:
                line = line.strip().split()

                try:
                    (directive, arg) = (line[0].lower(), line[1:])
                    # Drop everything after # or ; (comments)
                    arg = list(itertools.takewhile(
                        lambda x: x[0] not in ('#', ';'), arg))

                    if directive == 'nameserver':
                        try:
                            ip_addr = ipaddress.ip_address(arg[0])
                            if ip_addr not in nameservers:
                                nameservers.append(ip_addr)
                        except ValueError as exc:
                            log.error('{0}: {1}'.format(src, exc))
                    elif directive == 'domain':
                        domain = arg[0]
                    elif directive == 'search':
                        search = arg
                    elif directive == 'sortlist':
                        # A sortlist is specified by IP address netmask pairs.
                        # The netmask is optional and defaults to the natural
                        # netmask of the net. The IP address and optional
                        # network pairs are separated by slashes.
                        for ip_raw in arg:
                            try:
                                ip_net = ipaddress.ip_network(ip_raw)
                            except ValueError as exc:
                                log.error('{0}: {1}'.format(src, exc))
                            else:
                                if '/' not in ip_raw:
                                    # No netmask has been provided, guess
                                    # the "natural" one
                                    if ip_net.version == 4:
                                        ip_addr = str(ip_net.network_address)
                                        # pylint: disable=protected-access
                                        mask = salt.utils.network.\
                                            natural_ipv4_netmask(ip_addr)

                                        ip_net = ipaddress.ip_network(
                                            '{0}{1}'.format(ip_addr, mask),
                                            strict=False
                                        )
                                    if ip_net.version == 6:
                                        # TODO
                                        pass

                                if ip_net not in sortlist:
                                    sortlist.append(ip_net)
                    elif directive == 'options':
                        # Options allows certain internal resolver variables to
                        # be modified.
                        if arg[0] not in options:
                            options.append(arg[0])
                except IndexError:
                    continue

        if domain and search:
            # The domain and search keywords are mutually exclusive.  If more
            # than one instance of these keywords is present, the last instance
            # will override.
            log.debug('{0}: The domain and search keywords are mutually '
                        'exclusive.'.format(src))

        return {
            'nameservers': nameservers,
            'ip4_nameservers': [ip for ip in nameservers if ip.version == 4],
            'ip6_nameservers': [ip for ip in nameservers if ip.version == 6],
            'sortlist': [ip.with_netmask for ip in sortlist],
            'domain': domain,
            'search': search,
            'options': options
        }
    except IOError:
        return {}
Example #30
0
def network_address(value):
    try:
        return str(ipaddress.ip_network(value, False))
    except Exception:
        log.exception("Failed to determine network address from '%s'", value)
    return ''