def _config_net_topology(self, conf):
        all_nics = [(nic, dom_name)
                    for dom_name, dom in conf['domains'].items()
                    for nic in dom['nics']]
        nics_by_net = {}
        for nic, dom in all_nics:
            nics_by_net.setdefault(nic['net'], []).append((nic, dom))

        with utils.RollbackContext() as rollback:
            for net_name, net_spec in conf.get('nets', {}).items():
                try:
                    subnet = net_spec['gw']
                    if subnet_lease.is_leasable_subnet(subnet):
                        raise RuntimeError(
                            '%s subnet can only be dynamically allocated' %
                            (subnet, ))
                except KeyError:
                    subnet = subnet_lease.acquire(self.paths.uuid())
                    rollback.prependDefer(subnet_lease.release, subnet)
                    net_spec['gw'] = subnet

                allocated_ips = set([1])

                # Check all allocated IPs
                for nic, dom in nics_by_net[net_name]:
                    if 'ip' not in nic:
                        continue

                    if not _ip_in_subnet(subnet, nic['ip']):
                        raise RuntimeError(
                            "%s:nic%d's IP [%s] is outside the subnet [%s]",
                            dom,
                            dom['nics'].index(nic),
                            nic['ip'],
                            subnet,
                        )

                    index = int(nic['ip'].split('.'))[3]
                    allocated_ips.add(index)
                    nic['ip'] = _create_ip(subnet, index)

                # Allocate IPs for domains without assigned IPs
                for nic, _ in nics_by_net[net_name]:
                    if 'ip' in nic:
                        continue

                    next_vacancy = set(set(range(1, 255))
                                       ^ allocated_ips).pop()
                    allocated_ips.add(next_vacancy)
                    nic['ip'] = _create_ip(subnet, next_vacancy)

                # Here we will store the domain images:
                logging.info('Creating bridge...')
                if 'mapping' not in net_spec:
                    net_spec['mapping'] = {}
                net_spec['mapping'].update(
                    {dom: nic['ip']
                     for nic, dom in nics_by_net[net_name]}, )
                net_spec['name'] = net_name
            rollback.clear()
Example #2
0
    def _register_preallocated_ips(self, conf):
        """
        Parse all the domains in the given conf and preallocate all their ips
        into the networks mappings, raising exception on duplicated ips or ips
        out of the allowed ranges

        See Also:
            :mod:`lago.subnet_lease`

        Args:
            conf (dict): Configuration spec to parse

        Returns:
            None

        Raises:
            RuntimeError: if there are any duplicated ips or any ip out of the
                allowed range
        """
        for dom_name, dom_spec in conf.get('domains', {}).items():
            for idx, nic in enumerate(dom_spec.get('nics', [])):
                if 'ip' not in nic:
                    continue

                net = conf['nets'][nic['net']]
                if subnet_lease.is_leasable_subnet(net['gw']):
                    nic['ip'] = _create_ip(
                        net['gw'], int(nic['ip'].split('.')[-1])
                    )

                dom_name = dom_spec['name']
                if not _ip_in_subnet(net['gw'], nic['ip']):
                    raise RuntimeError(
                        "%s:nic%d's IP [%s] is outside the subnet [%s]" % (
                            dom_name,
                            dom_spec['nics'].index(nic),
                            nic['ip'],
                            net['gw'],
                        ),
                    )

                if nic['ip'] in net['mapping'].values():
                    conflict_list = [
                        name
                        for name, ip in net['mapping'].items()
                        if ip == net['ip']
                    ]
                    raise RuntimeError(
                        'IP %s was to several domains: %s %s' % (
                            nic['ip'],
                            dom_name,
                            ' '.join(conflict_list),
                        ),
                    )

                self._add_nic_to_mapping(net, dom_spec, nic)
Example #3
0
    def _register_preallocated_ips(self, conf):
        """
        Parse all the domains in the given conf and preallocate all their ips
        into the networks mappings, raising exception on duplicated ips or ips
        out of the allowed ranges

        See Also:
            :mod:`lago.subnet_lease`

        Args:
            conf (dict): Configuration spec to parse

        Returns:
            None

        Raises:
            RuntimeError: if there are any duplicated ips or any ip out of the
                allowed range
        """
        for dom_name, dom_spec in conf.get('domains', {}).items():
            for idx, nic in enumerate(dom_spec.get('nics', [])):
                if 'ip' not in nic:
                    continue

                net = conf['nets'][nic['net']]
                if subnet_lease.is_leasable_subnet(net['gw']):
                    nic['ip'] = _create_ip(
                        net['gw'], int(nic['ip'].split('.')[-1])
                    )

                dom_name = dom_spec['name']
                if not _ip_in_subnet(net['gw'], nic['ip']):
                    raise RuntimeError(
                        "%s:nic%d's IP [%s] is outside the subnet [%s]" % (
                            dom_name,
                            dom_spec['nics'].index(nic),
                            nic['ip'],
                            net['gw'],
                        ),
                    )

                if nic['ip'] in net['mapping'].values():
                    conflict_list = [
                        name for name, ip in net['mapping'].items()
                        if ip == net['ip']
                    ]
                    raise RuntimeError(
                        'IP %s was to several domains: %s %s' % (
                            nic['ip'],
                            dom_name,
                            ' '.join(conflict_list),
                        ),
                    )

                self._add_nic_to_mapping(net, dom_spec, nic)
Example #4
0
    def _check_predefined_subnets(conf):
        """
        Checks if all of the nets defined in the config are inside the allowed
        range, throws exception if not
        Args:
            conf (dict): Configuration spec where to get the nets definitions
                from
        Returns:
            None
        Raises:
            RuntimeError: If there are any subnets out of the allowed range
        """
        for net_spec in conf.get('nets', {}).itervalues():
            subnet = net_spec.get('gw')
            if subnet is None:
                continue

            if subnet_lease.is_leasable_subnet(subnet):
                raise RuntimeError(
                    '%s subnet can only be dynamically allocated' % (subnet)
                )
Example #5
0
    def _check_predefined_subnets(conf):
        """
        Checks if all of the nets defined in the config are inside the allowed
        range, throws exception if not

        Args:
            conf (dict): Configuration spec where to get the nets definitions
                from

        Returns:
            None

        Raises:
            RuntimeError: If there are any subnets out of the allowed range
        """
        for net_spec in conf.get('nets', {}).itervalues():
            subnet = net_spec.get('gw')
            if subnet is None:
                continue

            if subnet_lease.is_leasable_subnet(subnet):
                raise RuntimeError(
                    '%s subnet can only be dynamically allocated' % (subnet))
    def _config_net_topology(self, conf):
        all_nics = [
            (nic, dom_name)
            for dom_name, dom in conf['domains'].items()
            for nic in dom['nics']
        ]
        nics_by_net = {}
        for nic, dom in all_nics:
            nics_by_net.setdefault(
                nic['net'],
                []
            ).append((nic, dom))

        with utils.RollbackContext() as rollback:
            for net_name, net_spec in conf.get('nets', {}).items():
                try:
                    subnet = net_spec['gw']
                    if subnet_lease.is_leasable_subnet(subnet):
                        raise RuntimeError(
                            '%s subnet can only be dynamically allocated' % (
                                subnet,
                            )
                        )
                except KeyError:
                    subnet = subnet_lease.acquire(self.paths.uuid())
                    rollback.prependDefer(subnet_lease.release, subnet)
                    net_spec['gw'] = subnet

                allocated_ips = set([1])

                # Check all allocated IPs
                for nic, dom in nics_by_net[net_name]:
                    if 'ip' not in nic:
                        continue

                    if not _ip_in_subnet(subnet, nic['ip']):
                        raise RuntimeError(
                            "%s:nic%d's IP [%s] is outside the subnet [%s]",
                            dom,
                            dom['nics'].index(nic),
                            nic['ip'],
                            subnet,
                        )

                    index = int(nic['ip'].split('.'))[3]
                    allocated_ips.add(index)
                    nic['ip'] = _create_ip(subnet, index)

                # Allocate IPs for domains without assigned IPs
                for nic, _ in nics_by_net[net_name]:
                    if 'ip' in nic:
                        continue

                    next_vacancy = set(
                        set(range(1, 255)) ^ allocated_ips
                    ).pop()
                    allocated_ips.add(next_vacancy)
                    nic['ip'] = _create_ip(subnet, next_vacancy)

                # Here we will store the domain images:
                logging.info('Creating bridge...')
                if 'mapping' not in net_spec:
                    net_spec['mapping'] = {}
                net_spec['mapping'].update(
                    {
                        dom: nic['ip']
                        for nic, dom in nics_by_net[net_name]
                    },
                )
                net_spec['name'] = net_name
            rollback.clear()