Ejemplo n.º 1
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:
         for port in ports:
             try:
                 sock = salt.utils.network.get_socket(addr, socket.SOCK_STREAM)
                 sock.settimeout(float(__opts__['ssh_scan_timeout']))
                 sock.connect((str(addr), port))
                 sock.shutdown(socket.SHUT_RDWR)
                 sock.close()
                 ret[addr] = {'host': addr, 'port': port}
             except socket.error:
                 pass
     return ret
Ejemplo n.º 2
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:
         for port in ports:
             try:
                 sock = salt.utils.network.get_socket(
                     addr, socket.SOCK_STREAM)
                 sock.settimeout(float(__opts__['ssh_scan_timeout']))
                 sock.connect((str(addr), port))
                 sock.shutdown(socket.SHUT_RDWR)
                 sock.close()
                 ret[addr] = {'host': addr, 'port': port}
             except socket.error:
                 pass
     return ret
Ejemplo n.º 3
0
def is_loopback(ip_addr):
    '''
    Check if the given IP address is a loopback address

    .. versionadded:: 2014.7.0
    .. versionchanged:: Beryllium
        IPv6 support

    CLI Example::

        salt '*' network.is_loopback 127.0.0.1
    '''
    return ipaddress.ip_address(ip_addr).is_loopback
Ejemplo n.º 4
0
def is_private(ip_addr):
    '''
    Check if the given IP address is a private address

    .. versionadded:: 2014.7.0
    .. versionchanged:: Beryllium
        IPv6 support

    CLI Example::

        salt '*' network.is_private 10.0.0.3
    '''
    return ipaddress.ip_address(ip_addr).is_private
Ejemplo n.º 5
0
def reverse_ip(ip_addr):
    '''
    Returns the reversed IP address

    .. versionchanged:: Beryllium
        IPv6 support

    CLI Example:

    .. code-block:: bash

        salt '*' network.reverse_ip 172.17.0.4
    '''
    return ipaddress.ip_address(ip_addr).reverse_pointer
Ejemplo n.º 6
0
def ensure(name, cidr, overlay, mtu=1420):
    '''
    Ensure that a bridge (named <name>) is configured for containers.

    Under the covers we will make sure that
      - The bridge exists
      - The MTU is set
      - The correct network is added to the bridge
      - iptables is set up for MASQUERADE for egress

    cidr:
        The cidr range in the form of 10.244.x.0/24
    mtu:
        The MTU to set on the interface
    '''
    ret = {'name': name, 'changes': {}, 'result': False, 'comment': ''}

    # This is a little hacky.  I should probably import a real library for this
    # but this'll work for now.
    try:
        cidr_network = ipaddr.ip_interface(cidr)
    except Exception:
        raise salt.exceptions.SaltInvocationError(
            'Invalid CIDR \'{0}\''.format(cidr))

    if cidr_network.version == 4:
        for net in overlay:
            iptables_rule = {
                'table': 'nat',
                'chain': 'POSTROUTING',
                'rule': '-j MASQUERADE \! -d {0} -s {0}'.format(net)
            }
    else:
        iptables_rule = None

    def bridge_exists(name):
        'Determine if a bridge exists already.'
        out = __salt__['cmd.run_stdout']('brctl show {0}'.format(name))
        for line in out.splitlines():
            # get rid of first line
            if line.startswith('bridge name'):
                continue
            # get rid of ^\n's
            vals = line.split()
            if not vals:
                continue
            if len(vals) > 1:
                return True
        return False

    def get_ip_addr_details(name):
        'For the given interface, get address details.'
        out = __salt__['cmd.run']('ip addr show dev {0}'.format(name))
        ret = { 'networks': [] }
        for line in out.splitlines():
            match = re.match(
                r'^\d*:\s+([\w.\-]+)(?:@)?([\w.\-]+)?:\s+<(.+)>.*mtu (\d+)',
                line)
            if match:
                iface, parent, attrs, mtu = match.groups()
                if 'UP' in attrs.split(','):
                    ret['up'] = True
                else:
                    ret['up'] = False
                if parent:
                    ret['parent'] = parent
                ret['mtu'] = int(mtu)
                continue
            cols = line.split()
            if len(cols) > 2 and cols[0] == 'inet':
                ret['networks'].append(cols[1])
        return ret


    def get_current_state():
        'Helper that returns a dict of current bridge state.'
        ret = {}
        ret['name'] = name
        ret['exists'] = bridge_exists(name)
        if ret['exists']:
            ret['details'] = get_ip_addr_details(name)
        else:
            ret['details'] = {}
        # This module function is strange and returns True if the rule exists.
        # If not, it returns a string with the error from the call to iptables.
        if iptables_rule:
            ret['iptables_rule_exists'] = \
              __salt__['iptables.check'](**iptables_rule) == True
        else:
            ret['iptables_rule_exists'] = True
        return ret

    desired_network = '{0}/{1}'.format(
        str(ipaddr.ip_address(cidr_network.network.network_address._ip + 1)),
        str(cidr_network.network.prefixlen))

    current_state = get_current_state()

    if (current_state['exists']
        and current_state['details']['mtu'] == mtu
        and desired_network in current_state['details']['networks']
        and current_state['details']['up']
        and current_state['iptables_rule_exists']):
        ret['result'] = True
        ret['comment'] = 'System already in the correct state'
        return ret

    # The state of the system does need to be changed. Check if we're running
    # in ``test=true`` mode.
    if __opts__['test'] == True:
        ret['comment'] = 'The state of "{0}" will be changed.'.format(name)
        ret['changes'] = {
            'old': current_state,
            'new': 'Create and configure bridge'
        }

        # Return ``None`` when running with ``test=true``.
        ret['result'] = None

        return ret

    # Finally, make the actual change and return the result.
    if not current_state['exists']:
        __salt__['cmd.run']('brctl addbr {0}'.format(name))
    new_state = get_current_state()
    if new_state['details']['mtu'] != mtu:
        __salt__['cmd.run'](
            'ip link set dev {0} mtu {1}'.format(name, str(mtu)))
    new_state = get_current_state()
    if desired_network not in new_state['details']['networks']:
        __salt__['cmd.run'](
            'ip addr flush dev {0}'.format(name))
        __salt__['cmd.run'](
            'ip addr add {0} dev {1}'.format(desired_network, name))
    new_state = get_current_state()
    if not new_state['details']['up']:
        __salt__['cmd.run'](
            'ip link set dev {0} up'.format(name))
    new_state = get_current_state()
    if iptables_rule and not new_state['iptables_rule_exists']:
        __salt__['iptables.append'](**iptables_rule)
    new_state = get_current_state()

    ret['comment'] = 'The state of "{0}" was changed!'.format(name)

    ret['changes'] = {
        'old': current_state,
        'new': new_state,
    }

    ret['result'] = True

    return ret