Exemplo n.º 1
0
def find_bind_addrs(nr_of_addrs, addr_range):
    """
    Finds for the presence of address which can be bound to the sandbox given an address range, i.e.
    - Let's say 3 address aliases is required.
    - The address range is 192.168.128.0/24

    These addresses requires setup using ifconfig as such (macOS example):

    sudo ifconfig lo0 alias 192.168.128.1 255.255.255.255
    sudo ifconfig lo0 alias 192.168.128.2 255.255.255.255
    sudo ifconfig lo0 alias 192.168.128.3 255.255.255.255

    This command will check if 192.168.128.1, 192.168.128.2, and 192.168.128.3 can be bound. The check is done by
    binding a socket to each of these address using a test port.

    If the number of required address is not present, prompt the user for sudo password so that we can add the aliases.

    :param nr_of_addrs: number of address aliases required
    :param addr_range: the range of address which is available to core and agent to bind to.
                       The address is specified in the CIDR format, i.e. 192.168.128.0/24
    """

    addrs_to_bind = []
    addrs_unavailable = []
    for ip_addr in addr_range.hosts():
        if host.can_bind(ip_addr, BIND_TEST_PORT):
            addrs_to_bind.append(ip_addr)
        else:
            addrs_unavailable.append(ip_addr)

        if len(addrs_to_bind) >= nr_of_addrs:
            break

    if len(addrs_to_bind) < nr_of_addrs:
        nr_of_addr_setup = nr_of_addrs - len(addrs_to_bind)
        addr_aliases_commands = host.addr_alias_commands(addrs_unavailable[0:nr_of_addr_setup],
                                                         addr_range.version)
        if addr_aliases_commands:
            log = logging.getLogger(__name__)
            log.info('Network address aliases are required so that the sandbox can operate as a cluster of machines.'
                     '\nTo add the network aliases sudo privileges are required.')
            for command in addr_aliases_commands:
                try:
                    subprocess.check_call(command)
                    log.info(' '.join(command))
                except CalledProcessError:
                    commands_str = '\n'.join([' '.join(command) for command in addr_aliases_commands])
                    raise BindAddressNotFound('Not able to add the network address aliases. Please add them manually:'
                                              '\n\n{}'.format(commands_str))
            return find_bind_addrs(nr_of_addrs, addr_range)
        else:
            subnet_mask = host.get_subnet_mask(addr_range.version)
            addrs_formatted = ', '.join(['{}'.format(addr) for addr in addrs_unavailable[0:nr_of_addr_setup]])
            setup_instructions = 'Setup aliases for {} addresses with {} subnet mask'.format(addrs_formatted,
                                                                                             subnet_mask)
            raise BindAddressNotFound(setup_instructions)
    else:
        return addrs_to_bind
Exemplo n.º 2
0
    def test_failure(self):
        mock_socket = MagicMock()

        mock_bind = MagicMock(side_effect=OSError())
        mock_socket.bind = mock_bind

        mock_close = MagicMock()
        mock_socket.close = mock_close

        mock_create_socket = MagicMock(return_value=mock_socket)

        with patch('socket.socket', mock_create_socket):
            self.assertFalse(host.can_bind(self.addr_ipv6, self.port))

        mock_create_socket.assert_called_once_with(socket.AF_INET6,
                                                   socket.SOCK_STREAM)
        mock_bind.assert_called_once_with((self.addr_ipv6.exploded, self.port))
        mock_close.assert_called_once_with()
Exemplo n.º 3
0
    def test_success_ipv6(self):
        mock_socket = MagicMock()

        mock_bind = MagicMock()
        mock_socket.bind = mock_bind

        mock_close = MagicMock()
        mock_socket.close = mock_close

        mock_create_socket = MagicMock(return_value=mock_socket)

        with patch('socket.socket', mock_create_socket):
            self.assertTrue(host.can_bind(self.addr_ipv6, self.port))

        mock_create_socket.assert_called_once_with(socket.AF_INET6,
                                                   socket.SOCK_STREAM)
        mock_bind.assert_called_once_with((self.addr_ipv6.exploded, self.port))
        mock_close.assert_called_once_with()
Exemplo n.º 4
0
def find_bind_addrs(nr_of_addrs, addr_range):
    """
    Finds for the presence of address which can be bound to the sandbox given an address range, i.e.
    - Let's say 3 address aliases is required.
    - The address range is 192.168.128.0/24

    These addresses requires setup using ifconfig as such (MacOS example):

    sudo ifconfig lo0 alias 192.168.128.1 255.255.255.0
    sudo ifconfig lo0 alias 192.168.128.2 255.255.255.0
    sudo ifconfig lo0 alias 192.168.128.3 255.255.255.0

    This command will check if 192.168.128.1, 192.168.128.2, and 192.168.128.3 can be bound. The check is done by
    binding a socket to each of these address using a test port.

    If the number of required address is not present, provide the commands so the end user is able to copy-paste and
    execute these commands.

    :param nr_of_addrs: number of address aliases required
    :param addr_range: the range of address which is available to core and agent to bind to.
                       The address is specified in the CIDR format, i.e. 192.168.128.0/24
    """
    addrs_to_bind = []
    addrs_unavailable = []
    for ip_addr in addr_range.hosts():
        if host.can_bind(ip_addr, BIND_TEST_PORT):
            addrs_to_bind.append(ip_addr)
        else:
            addrs_unavailable.append(ip_addr)

        if len(addrs_to_bind) >= nr_of_addrs:
            break

    if len(addrs_to_bind) < nr_of_addrs:
        nr_of_addr_setup = nr_of_addrs - len(addrs_to_bind)
        setup_instructions = host.addr_alias_setup_instructions(
            addrs_unavailable[0:nr_of_addr_setup], addr_range.netmask)
        raise BindAddressNotFound(setup_instructions)
    else:
        return addrs_to_bind