Esempio n. 1
0
def inet_pton(address_family, ip_string):
    # Verify IP Address
    # This will catch IP Addresses such as 10.1.2
    if address_family == socket.AF_INET:
        try:
            ipaddress.ip_address(six.text_type(ip_string))
        except ValueError:
            raise socket.error('illegal IP address string passed to inet_pton')
        return socket.inet_aton(ip_string)

    # Verify IP Address
    # The `WSAStringToAddressA` function handles notations used by Berkeley
    # software which includes 3 part IP Addresses such as `10.1.2`. That's why
    # the above check is needed to enforce more strict IP Address validation as
    # used by the `inet_pton` function in Unix.
    # See the following:
    # https://stackoverflow.com/a/29286098
    # Docs for the `inet_addr` function on MSDN
    # https://msdn.microsoft.com/en-us/library/windows/desktop/ms738563.aspx
    addr = sockaddr()
    addr.sa_family = address_family
    addr_size = ctypes.c_int(ctypes.sizeof(addr))

    if WSAStringToAddressA(ip_string.encode('ascii'), address_family, None,
                           ctypes.byref(addr), ctypes.byref(addr_size)) != 0:
        raise socket.error(ctypes.FormatError())

    if address_family == socket.AF_INET:
        return ctypes.string_at(addr.ipv4_addr, 4)
    if address_family == socket.AF_INET6:
        return ctypes.string_at(addr.ipv6_addr, 16)

    raise socket.error('unknown address family')
Esempio n. 2
0
def _build_required_items(nodes):
    ret = {}
    for name, grains in nodes.items():
        if grains:
            private_ips = []
            public_ips = []
            ips = grains['ipv4'] + grains['ipv6']
            for adrs in ips:
                ip_ = ipaddress.ip_address(adrs)
                if not ip_.is_loopback:
                    if ip_.is_private:
                        private_ips.append(adrs)
                    else:
                        public_ips.append(adrs)

            ret[name] = {
                'id': grains['id'],
                'image': grains['salt-cloud']['profile'],
                'private_ips': private_ips,
                'public_ips': public_ips,
                'size': '',
                'state': 'running'
            }

    return ret
Esempio n. 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
Esempio n. 4
0
def _ip_addrs(interface=None, include_loopback=False, interface_data=None, proto='inet'):
    '''
    Return the full list of IP adresses matching the criteria

    proto = inet|inet6
    '''
    ret = set()

    ifaces = interface_data \
        if isinstance(interface_data, dict) \
        else interfaces()
    if interface is None:
        target_ifaces = ifaces
    else:
        target_ifaces = dict([(k, v) for k, v in six.iteritems(ifaces)
                              if k == interface])
        if not target_ifaces:
            log.error('Interface {0} not found.'.format(interface))
    for ip_info in six.itervalues(target_ifaces):
        addrs = ip_info.get(proto, [])
        addrs.extend([addr for addr in ip_info.get('secondary', []) if addr.get('type') == proto])

        for addr in addrs:
            addr = ipaddress.ip_address(addr.get('address'))
            if not addr.is_loopback or include_loopback:
                ret.add(addr)
    return [str(addr) for addr in sorted(ret)]
Esempio n. 5
0
def generate_minion_id():
    '''
    Returns a minion id after checking multiple sources for a FQDN.
    If no FQDN is found you may get an ip address

    CLI Example:

    .. code-block:: bash

        salt '*' network.generate_minion_id
    '''
    possible_ids = get_hostnames()

    # include public and private ipaddresses
    for addr in salt.utils.network.ip_addrs():
        addr = ipaddress.ip_address(addr)
        if addr.is_loopback:
            continue
        possible_ids.append(str(addr))

    possible_ids = _filter_localhost_names(possible_ids)

    # if no minion id
    if len(possible_ids) == 0:
        return 'noname'

    hosts = _sort_hostnames(possible_ids)
    return hosts[0]
Esempio n. 6
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
Esempio n. 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, 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
Esempio n. 8
0
File: scan.py Progetto: 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
Esempio n. 9
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
Esempio n. 10
0
def ip_bracket(addr):
    '''
    Convert IP address representation to ZMQ (URL) format. ZMQ expects
    brackets around IPv6 literals, since they are used in URLs.
    '''
    addr = ipaddress.ip_address(addr)
    return ('[{}]' if addr.version == 6 else '{}').format(addr)
Esempio n. 11
0
def _ip_addrs(interface=None, include_loopback=False, interface_data=None, proto='inet'):
    '''
    Return the full list of IP adresses matching the criteria

    proto = inet|inet6
    '''
    ret = set()

    ifaces = interface_data \
        if isinstance(interface_data, dict) \
        else interfaces()
    if interface is None:
        target_ifaces = ifaces
    else:
        target_ifaces = dict([(k, v) for k, v in six.iteritems(ifaces)
                              if k == interface])
        if not target_ifaces:
            log.error('Interface {0} not found.'.format(interface))
    for ip_info in six.itervalues(target_ifaces):
        addrs = ip_info.get(proto, [])
        addrs.extend([addr for addr in ip_info.get('secondary', []) if addr.get('type') == proto])

        for addr in addrs:
            addr = ipaddress.ip_address(addr.get('address'))
            if not addr.is_loopback or include_loopback:
                ret.add(addr)
    return [str(addr) for addr in sorted(ret)]
Esempio n. 12
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
Esempio n. 13
0
def _build_required_items(nodes):
    ret = {}
    for name, grains in nodes.items():
        if grains:
            private_ips = []
            public_ips = []
            ips = grains["ipv4"] + grains["ipv6"]
            for adrs in ips:
                ip_ = ipaddress.ip_address(adrs)
                if not ip_.is_loopback:
                    if ip_.is_private:
                        private_ips.append(adrs)
                    else:
                        public_ips.append(adrs)

            ret[name] = {
                "id": grains["id"],
                "image": grains["salt-cloud"]["profile"],
                "private_ips": private_ips,
                "public_ips": public_ips,
                "size": "",
                "state": "running",
            }

    return ret
def get_address_as_decimal(addr):
    '''
    Return the decimal representation of an IP address

    This function is primarily used to generate a unique mark to identify traffic
    for a particular IPSec tunnel using the remote address.
    '''
    return int(ipaddress.ip_address(addr))
Esempio n. 15
0
def is_ipv6(ip):
    '''
    Returns a bool telling if the value passed to it was a valid IPv6 address
    '''
    try:
        return ipaddress.ip_address(ip).version == 6
    except ValueError:
        return False
Esempio n. 16
0
def is_ipv6(ip):
    '''
    Returns a bool telling if the value passed to it was a valid IPv6 address
    '''
    try:
        return ipaddress.ip_address(ip).version == 6
    except ValueError:
        return False
Esempio n. 17
0
def _get_master_uri(master_ip, master_port, source_ip=None, source_port=None):
    """
    Return the ZeroMQ URI to connect the Minion to the Master.
    It supports different source IP / port, given the ZeroMQ syntax:
    // Connecting using a IP address and bind to an IP address
    rc = zmq_connect(socket, "tcp://192.168.1.17:5555;192.168.1.1:5555"); assert (rc == 0);
    Source: http://api.zeromq.org/4-1:zmq-tcp
    """
    from salt.utils.zeromq import ip_bracket

    master_uri = "tcp://{master_ip}:{master_port}".format(
        master_ip=ip_bracket(master_ip), master_port=master_port
    )

    if source_ip or source_port:
        if LIBZMQ_VERSION_INFO >= (4, 1, 6) and ZMQ_VERSION_INFO >= (16, 0, 1):
            # The source:port syntax for ZeroMQ has been added in libzmq 4.1.6
            # which is included in the pyzmq wheels starting with 16.0.1.
            if source_ip and source_port:
                master_uri = (
                    "tcp://{source_ip}:{source_port};{master_ip}:{master_port}".format(
                        source_ip=ip_bracket(source_ip),
                        source_port=source_port,
                        master_ip=ip_bracket(master_ip),
                        master_port=master_port,
                    )
                )
            elif source_ip and not source_port:
                master_uri = "tcp://{source_ip}:0;{master_ip}:{master_port}".format(
                    source_ip=ip_bracket(source_ip),
                    master_ip=ip_bracket(master_ip),
                    master_port=master_port,
                )
            elif source_port and not source_ip:
                ip_any = (
                    "0.0.0.0"
                    if ipaddress.ip_address(master_ip).version == 4
                    else ip_bracket("::")
                )
                master_uri = (
                    "tcp://{ip_any}:{source_port};{master_ip}:{master_port}".format(
                        ip_any=ip_any,
                        source_port=source_port,
                        master_ip=ip_bracket(master_ip),
                        master_port=master_port,
                    )
                )
        else:
            log.warning(
                "Unable to connect to the Master using a specific source IP / port"
            )
            log.warning("Consider upgrading to pyzmq >= 16.0.1 and libzmq >= 4.1.6")
            log.warning(
                "Specific source IP / port for connecting to master returner port:"
                " configuraion ignored"
            )

    return master_uri
Esempio n. 18
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': []}
Esempio n. 19
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
Esempio n. 20
0
def is_ipv6(ip):
    """
    Returns a bool telling if the value passed to it was a valid IPv6 address
    """
    # TODO: use the builtin filter (https://docs.saltstack.com/en/latest/topics/jinja/index.html#is-ipv6)
    #       once we Salt>2017.7.0
    try:
        return ipaddress.ip_address(ip).version == 6
    except ValueError:
        return False
Esempio n. 21
0
def ip_bracket(addr):
    '''
    Ensure IP addresses are URI-compatible - specifically, add brackets
    around IPv6 literals if they are not already present.
    '''
    addr = str(addr)
    addr = addr.lstrip('[')
    addr = addr.rstrip(']')
    addr = ipaddress.ip_address(addr)
    return ('[{}]' if addr.version == 6 else '{}').format(addr)
Esempio n. 22
0
def ip_bracket(addr):
    """
    Ensure IP addresses are URI-compatible - specifically, add brackets
    around IPv6 literals if they are not already present.
    """
    addr = str(addr)
    addr = addr.lstrip("[")
    addr = addr.rstrip("]")
    addr = ipaddress.ip_address(addr)
    return ("[{}]" if addr.version == 6 else "{}").format(addr)
Esempio n. 23
0
def ptr_name(rdata):
    '''
    Return PTR name of given IP
    :param rdata: IP address
    :return: PTR record name
    '''
    try:
        return ipaddress.ip_address(rdata).reverse_pointer
    except ValueError:
        log.error('Unable to generate PTR record; {0} is not a valid IP address'.format(rdata))
        return False
Esempio n. 24
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": []}
Esempio n. 25
0
def ptr_name(rdata):
    """
    Return PTR name of given IP
    :param rdata: IP address
    :return: PTR record name
    """
    try:
        return ipaddress.ip_address(rdata).reverse_pointer
    except ValueError:
        log.error("Unable to generate PTR record; %s is not a valid IP address", rdata)
        return False
Esempio n. 26
0
    def test_ip_bracket(self):
        test_ipv4 = "127.0.0.1"
        test_ipv6 = "::1"
        test_ipv6_uri = "[::1]"
        self.assertEqual(test_ipv4, salt.utils.zeromq.ip_bracket(test_ipv4))
        self.assertEqual("[{}]".format(test_ipv6),
                         salt.utils.zeromq.ip_bracket(test_ipv6))
        self.assertEqual("[{}]".format(test_ipv6),
                         salt.utils.zeromq.ip_bracket(test_ipv6_uri))

        ip_addr_obj = ipaddress.ip_address(test_ipv4)
        self.assertEqual(test_ipv4, salt.utils.zeromq.ip_bracket(ip_addr_obj))
Esempio n. 27
0
    def test_ip_bracket(self):
        test_ipv4 = '127.0.0.1'
        test_ipv6 = '::1'
        test_ipv6_uri = '[::1]'
        self.assertEqual(test_ipv4, salt.utils.zeromq.ip_bracket(test_ipv4))
        self.assertEqual('[{0}]'.format(test_ipv6),
                         salt.utils.zeromq.ip_bracket(test_ipv6))
        self.assertEqual('[{0}]'.format(test_ipv6),
                         salt.utils.zeromq.ip_bracket(test_ipv6_uri))

        ip_addr_obj = ipaddress.ip_address(test_ipv4)
        self.assertEqual(test_ipv4, salt.utils.zeromq.ip_bracket(ip_addr_obj))
Esempio n. 28
0
def get_socket(addr, type=socket.SOCK_STREAM, proto=0):
    '''
    Return a socket object for the addr
    IP-version agnostic
    '''

    version = ipaddress.ip_address(addr).version
    if version == 4:
        family = socket.AF_INET
    elif version == 6:
        family = socket.AF_INET6
    return socket.socket(family, type, proto)
Esempio n. 29
0
def get_socket(addr, type=socket.SOCK_STREAM, proto=0):
    '''
    Return a socket object for the addr
    IP-version agnostic
    '''

    version = ipaddress.ip_address(addr).version
    if version == 4:
        family = socket.AF_INET
    elif version == 6:
        family = socket.AF_INET6
    return socket.socket(family, type, proto)
Esempio n. 30
0
def is_private(ip_addr):
    '''
    Check if the given IP address is a private address

    .. versionadded:: Fluorine

    CLI Example:

    .. code-block:: bash

        salt '*' network.is_private 10.0.0.3
    '''
    return ipaddress.ip_address(ip_addr).is_private
Esempio n. 31
0
def is_private(ip_addr):
    """
    Check if the given IP address is a private address

    .. versionadded:: 2019.2.0

    CLI Example:

    .. code-block:: bash

        salt '*' network.is_private 10.0.0.3
    """
    return ipaddress.ip_address(ip_addr).is_private
Esempio n. 32
0
def generate_minion_id():
    '''
    Returns a minion id after checking multiple sources for a FQDN.
    If no FQDN is found you may get an ip address
    '''
    possible_ids = get_hostnames()

    # include public and private ipaddresses
    for addr in salt.utils.network.ip_addrs():
        addr = ipaddress.ip_address(addr)
        if addr.is_loopback:
            continue
        possible_ids.append(str(addr))

    possible_ids = _filter_localhost_names(possible_ids)

    # if no minion id
    if len(possible_ids) == 0:
        return 'noname'

    hosts = _sort_hostnames(possible_ids)
    return hosts[0]
Esempio n. 33
0
def resolve_network():
    """
    A function to determine canonical properties of networks
    from the nodes pillar.

    CLI Example:
        salt * node.resolve_network
    """
    network = {
        "ipv4_address": "",
        "ipv4_gateway": "",
    }
    private_network = network.copy()

    interfaces = _get_property("network:interfaces", __grains__["id"], {})
    for interface_name, interface in interfaces.items():
        if "ipv4" not in interface:
            continue

        ipv4 = interface["ipv4"]["address"]
        if ipaddress.ip_address(ipv4).is_private:
            target = private_network
        else:
            target = network

        if target["ipv4_address"] != "":
            continue

        target["ipv4_address"] = ipv4
        try:
            target["ipv4_gateway"] = interface["ipv4"]["gateway"]
        except KeyError:
            pass

    if network["ipv4_address"] == "":
        return private_network

    return network
Esempio n. 34
0
def _is_ipv(ip, version, options=None):

    if not version:
        version = 4

    if version not in (4, 6):
        return None

    try:
        ip_obj = ipaddress.ip_address(ip)
    except ValueError:
        # maybe it is an IP network
        try:
            ip_obj = ipaddress.ip_interface(ip)
        except ValueError:
            # nope, still not :(
            return None

    if not ip_obj.version == version:
        return None

    # has the right version, let's move on
    return _ip_options(ip_obj, version, options=options)
Esempio n. 35
0
def _is_ipv(ip, version, options=None):

    if not version:
        version = 4

    if version not in (4, 6):
        return None

    try:
        ip_obj = ipaddress.ip_address(ip)
    except ValueError:
        # maybe it is an IP network
        try:
            ip_obj = ipaddress.ip_interface(ip)
        except ValueError:
            # nope, still not :(
            return None

    if not ip_obj.version == version:
        return None

    # has the right version, let's move on
    return _ip_options(ip_obj, version, options=options)
Esempio n. 36
0
File: dns.py Progetto: 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 {}
Esempio n. 37
0
def _generate_minion_id():
    '''
    Get list of possible host names and convention names.

    :return:
    '''
    # There are three types of hostnames:
    # 1. Network names. How host is accessed from the network.
    # 2. Host aliases. They might be not available in all the network or only locally (/etc/hosts)
    # 3. Convention names, an internal nodename.

    class DistinctList(list):
        '''
        List, which allows to append only distinct objects.
        Needs to work on Python 2.6, because of collections.OrderedDict only since 2.7 version.
        Override 'filter()' for custom filtering.
        '''
        localhost_matchers = ['localhost.*', 'ip6-.*', '127.*', r'0\.0\.0\.0',
                              '::1.*', 'ipv6-.*', 'fe00::.*', 'fe02::.*', '1.0.0.*.ip6.arpa']

        def append(self, p_object):
            if p_object and p_object not in self and not self.filter(p_object):
                super(self.__class__, self).append(p_object)
            return self

        def extend(self, iterable):
            for obj in iterable:
                self.append(obj)
            return self

        def filter(self, element):
            'Returns True if element needs to be filtered'
            for rgx in self.localhost_matchers:
                if re.match(rgx, element):
                    return True

        def first(self):
            return self and self[0] or None

    hosts = DistinctList().append(socket.getfqdn()).append(platform.node()).append(socket.gethostname())
    if not hosts:
        try:
            for a_nfo in socket.getaddrinfo(hosts.first() or 'localhost', None, socket.AF_INET,
                                            socket.SOCK_RAW, socket.IPPROTO_IP, socket.AI_CANONNAME):
                if len(a_nfo) > 3:
                    hosts.append(a_nfo[3])
        except socket.gaierror:
            log.warning('Cannot resolve address {addr} info via socket: {message}'.format(
                addr=hosts.first() or 'localhost (N/A)', message=socket.gaierror)
            )
    # Universal method for everywhere (Linux, Slowlaris, Windows etc)
    for f_name in ['/etc/hostname', '/etc/nodename', '/etc/hosts',
                   r'{win}\system32\drivers\etc\hosts'.format(win=os.getenv('WINDIR'))]:
        if not os.path.exists(f_name):
            continue
        with salt.utils.fopen(f_name) as f_hdl:
            for hst in (line.strip().split('#')[0].strip().split() or None for line in f_hdl.read().split(os.linesep)):
                if hst and (hst[0][:4] in ['127.', '::1'] or len(hst) == 1):
                    hosts.extend(hst)

    # include public and private ipaddresses
    return hosts.extend([addr for addr in salt.utils.network.ip_addrs()
                         if not ipaddress.ip_address(addr).is_loopback])
Esempio n. 38
0
def _generate_minion_id():
    '''
    Get list of possible host names and convention names.

    :return:
    '''
    # There are three types of hostnames:
    # 1. Network names. How host is accessed from the network.
    # 2. Host aliases. They might be not available in all the network or only locally (/etc/hosts)
    # 3. Convention names, an internal nodename.

    class DistinctList(list):
        '''
        List, which allows to append only distinct objects.
        Needs to work on Python 2.6, because of collections.OrderedDict only since 2.7 version.
        Override 'filter()' for custom filtering.
        '''
        localhost_matchers = [r'localhost.*', r'ip6-.*', r'127[.]\d', r'0\.0\.0\.0',
                              r'::1.*', r'ipv6-.*', r'fe00::.*', r'fe02::.*', r'1.0.0.*.ip6.arpa']

        def append(self, p_object):
            if p_object and p_object not in self and not self.filter(p_object):
                super(self.__class__, self).append(p_object)
            return self

        def extend(self, iterable):
            for obj in iterable:
                self.append(obj)
            return self

        def filter(self, element):
            'Returns True if element needs to be filtered'
            for rgx in self.localhost_matchers:
                if re.match(rgx, element):
                    return True

        def first(self):
            return self and self[0] or None

    hosts = DistinctList().append(socket.getfqdn()).append(platform.node()).append(socket.gethostname())
    if not hosts:
        try:
            for a_nfo in socket.getaddrinfo(hosts.first(), None, socket.AF_INET,
                                            socket.SOCK_RAW, socket.IPPROTO_IP, socket.AI_CANONNAME):
                if len(a_nfo) > 3:
                    hosts.append(a_nfo[3])
        except socket.gaierror:
            log.warning('Cannot resolve address {addr} info via socket: {message}'.format(
                addr=hosts.first(), message=socket.gaierror)
            )
    # Universal method for everywhere (Linux, Slowlaris, Windows etc)
    for f_name in ['/etc/hostname', '/etc/nodename', '/etc/hosts',
                   r'{win}\system32\drivers\etc\hosts'.format(win=os.getenv('WINDIR'))]:
        if not os.path.exists(f_name):
            continue
        with salt.utils.fopen(f_name) as f_hdl:
            for hst in (line.strip().split('#')[0].strip().split() or None for line in f_hdl.read().split(os.linesep)):
                if hst and (hst[0][:4] in ['127.', '::1'] or len(hst) == 1):
                    hosts.extend(hst)

    # include public and private ipaddresses
    return hosts.extend([addr for addr in salt.utils.network.ip_addrs()
                         if not ipaddress.ip_address(addr).is_loopback])