Esempio n. 1
0
 def _subnet_create(self, context, subnet, clean_on_err=True):
     if subnet['enable_dhcp']:
         network_id = subnet['network_id']
         # Create port for DHCP service
         dhcp_port = {
             "name": "",
             "admin_state_up": True,
             "device_id": "",
             "device_owner": const.DEVICE_OWNER_DHCP,
             "network_id": network_id,
             "tenant_id": subnet["tenant_id"],
             "mac_address": attr.ATTR_NOT_SPECIFIED,
             "fixed_ips": [{
                 "subnet_id": subnet['id']
             }]
         }
         try:
             # This will end up calling handle_port_dhcp_access
             # down below as well as handle_port_metadata_access
             self.plugin.create_port(context, {'port': dhcp_port})
         except p_exc.PortConfigurationError as e:
             LOG.error(
                 _LE("Error while creating subnet %(cidr)s for "
                     "network %(network)s. Please, contact "
                     "administrator"), {
                         "cidr": subnet["cidr"],
                         "network": network_id
                     })
             db_base_plugin_v2.NeutronDbPluginV2.delete_port(
                 self.plugin, context, e.port_id)
             if clean_on_err:
                 self.plugin.delete_subnet(context, subnet['id'])
             raise n_exc.Conflict()
Esempio n. 2
0
    def _setup_existing_dhcp_port(self, network, device_id, dhcp_subnets):
        """Set up the existing DHCP port, if there is one."""

        # To avoid pylint thinking that port might be undefined after
        # the following loop...
        port = None

        # Look for an existing DHCP port for this network.
        for port in network.ports:
            port_device_id = getattr(port, 'device_id', None)
            if port_device_id == device_id:
                # If using gateway IPs on this port, we can skip the
                # following code, whose purpose is just to review and
                # update the Neutron-allocated IP addresses for the
                # port.
                if self.driver.use_gateway_ips:
                    return port
                # Otherwise break out, as we now have the DHCP port
                # whose subnets and addresses we need to review.
                break
        else:
            return None

        # Compare what the subnets should be against what is already
        # on the port.
        dhcp_enabled_subnet_ids = set(dhcp_subnets)
        port_subnet_ids = set(ip.subnet_id for ip in port.fixed_ips)

        # If those differ, we need to call update.
        if dhcp_enabled_subnet_ids != port_subnet_ids:
            # Collect the subnets and fixed IPs that the port already
            # has, for subnets that are still in the DHCP-enabled set.
            wanted_fixed_ips = []
            for fixed_ip in port.fixed_ips:
                if fixed_ip.subnet_id in dhcp_enabled_subnet_ids:
                    wanted_fixed_ips.append({
                        'subnet_id': fixed_ip.subnet_id,
                        'ip_address': fixed_ip.ip_address
                    })

            # Add subnet IDs for new DHCP-enabled subnets.
            wanted_fixed_ips.extend(
                dict(subnet_id=s)
                for s in dhcp_enabled_subnet_ids - port_subnet_ids)

            # Update the port to have the calculated subnets and fixed
            # IPs.  The Neutron server will allocate a fresh IP for
            # each subnet that doesn't already have one.
            port = self.plugin.update_dhcp_port(port.id, {
                'port': {
                    'network_id': network.id,
                    'fixed_ips': wanted_fixed_ips
                }
            })
            if not port:
                raise exceptions.Conflict()

        return port
Esempio n. 3
0
    def setup_dhcp_port(self, network):
        """Create/update DHCP port for the host if needed and return port."""

        # The ID that the DHCP port will have (or already has).
        device_id = self.get_device_id(network)

        # Get the set of DHCP-enabled subnets on this network.
        dhcp_subnets = {
            subnet.id: subnet
            for subnet in network.subnets if subnet.enable_dhcp
        }

        # There are 3 cases: either the DHCP port already exists (but
        # might need to be updated for a changed set of subnets); or
        # some other code has already prepared a 'reserved' DHCP port,
        # and we just need to adopt that; or we need to create a new
        # DHCP port.  Try each of those in turn until we have a DHCP
        # port.
        for setup_method in (self._setup_existing_dhcp_port,
                             self._setup_reserved_dhcp_port,
                             self._setup_new_dhcp_port):
            dhcp_port = setup_method(network, device_id, dhcp_subnets)
            if dhcp_port:
                break
        else:
            raise exceptions.Conflict()

        # Convert subnet_id to subnet dict
        fixed_ips = [
            dict(subnet_id=fixed_ip.subnet_id,
                 ip_address=fixed_ip.ip_address,
                 subnet=dhcp_subnets[fixed_ip.subnet_id])
            for fixed_ip in dhcp_port.fixed_ips
        ]

        ips = [
            DictModel(item) if isinstance(item, dict) else item
            for item in fixed_ips
        ]
        dhcp_port.fixed_ips = ips

        return dhcp_port
Esempio n. 4
0
    def setup_dhcp_port(self, network):
        """Create/update DHCP port for the host if needed and return port."""

        device_id = self.get_device_id(network)
        subnets = {}
        dhcp_enabled_subnet_ids = []
        for subnet in network.subnets:
            if subnet.enable_dhcp:
                dhcp_enabled_subnet_ids.append(subnet.id)
                subnets[subnet.id] = subnet

        dhcp_port = None
        for port in network.ports:
            port_device_id = getattr(port, 'device_id', None)
            if port_device_id == device_id:
                port_fixed_ips = []
                ips_needs_removal = False
                for fixed_ip in port.fixed_ips:
                    if fixed_ip.subnet_id in dhcp_enabled_subnet_ids:
                        port_fixed_ips.append({
                            'subnet_id': fixed_ip.subnet_id,
                            'ip_address': fixed_ip.ip_address
                        })
                        dhcp_enabled_subnet_ids.remove(fixed_ip.subnet_id)
                    else:
                        ips_needs_removal = True

                # If there are dhcp_enabled_subnet_ids here that means that
                # we need to add those to the port and call update.
                if dhcp_enabled_subnet_ids or ips_needs_removal:
                    port_fixed_ips.extend(
                        [dict(subnet_id=s) for s in dhcp_enabled_subnet_ids])
                    dhcp_port = self.plugin.update_dhcp_port(
                        port.id, {
                            'port': {
                                'network_id': network.id,
                                'fixed_ips': port_fixed_ips
                            }
                        })
                    if not dhcp_port:
                        raise exceptions.Conflict()
                else:
                    dhcp_port = port
                # break since we found port that matches device_id
                break

        # check for a reserved DHCP port
        if dhcp_port is None:
            LOG.debug(
                'DHCP port %(device_id)s on network %(network_id)s'
                ' does not yet exist. Checking for a reserved port.', {
                    'device_id': device_id,
                    'network_id': network.id
                })
            for port in network.ports:
                port_device_id = getattr(port, 'device_id', None)
                if port_device_id == constants.DEVICE_ID_RESERVED_DHCP_PORT:
                    dhcp_port = self.plugin.update_dhcp_port(
                        port.id, {
                            'port': {
                                'network_id': network.id,
                                'device_id': device_id
                            }
                        })
                    if dhcp_port:
                        break

        # DHCP port has not yet been created.
        if dhcp_port is None:
            LOG.debug(
                'DHCP port %(device_id)s on network %(network_id)s'
                ' does not yet exist.', {
                    'device_id': device_id,
                    'network_id': network.id
                })
            port_dict = dict(
                name='',
                admin_state_up=True,
                device_id=device_id,
                network_id=network.id,
                tenant_id=network.tenant_id,
                fixed_ips=[dict(subnet_id=s) for s in dhcp_enabled_subnet_ids])
            dhcp_port = self.plugin.create_dhcp_port({'port': port_dict})

        if not dhcp_port:
            raise exceptions.Conflict()

        # Convert subnet_id to subnet dict
        fixed_ips = [
            dict(subnet_id=fixed_ip.subnet_id,
                 ip_address=fixed_ip.ip_address,
                 subnet=subnets[fixed_ip.subnet_id])
            for fixed_ip in dhcp_port.fixed_ips
        ]

        ips = [
            DictModel(item) if isinstance(item, dict) else item
            for item in fixed_ips
        ]
        dhcp_port.fixed_ips = ips

        return dhcp_port
Esempio n. 5
0
    def setup_dhcp_port(self, network):
        """Create/update DHCP port for the host if needed and return port."""

        device_id = self.get_device_id(network)
        subnets = {}
        dhcp_enabled_subnet_ids = []
        for subnet in network.subnets:
            if subnet.enable_dhcp:
                dhcp_enabled_subnet_ids.append(subnet.id)
                subnets[subnet.id] = subnet

        dhcp_port = None
        for port in network.ports:
            port_device_id = getattr(port, 'device_id', None)
            if port_device_id == device_id:
                if self.driver.bridged():
                    port_fixed_ips = []
                    for fixed_ip in port.fixed_ips:
                        port_fixed_ips.append({'subnet_id': fixed_ip.subnet_id,
                                               'ip_address': fixed_ip.ip_address})
                        if fixed_ip.subnet_id in dhcp_enabled_subnet_ids:
                            dhcp_enabled_subnet_ids.remove(fixed_ip.subnet_id)

                    # If there are dhcp_enabled_subnet_ids here that means that
                    # we need to add those to the port and call update.
                    if dhcp_enabled_subnet_ids:
                        port_fixed_ips.extend(
                            [dict(subnet_id=s) for s in dhcp_enabled_subnet_ids])
                        dhcp_port = self.plugin.update_dhcp_port(
                            port.id, {'port': {'fixed_ips': port_fixed_ips}})
                        if not dhcp_port:
                            raise exceptions.Conflict()
                    else:
                        dhcp_port = port
                else:
                    # When the DHCP port and VM TAP interfaces are not
                    # bridged, we don't allocate a unique IP address
                    # for the DHCP port.
                    LOG.debug("port.fixed_ips = %s" % port.fixed_ips)
                    dhcp_port = port
                # break since we found port that matches device_id
                break

        # DHCP port has not yet been created.
        if dhcp_port is None:
            LOG.debug(_('DHCP port %(device_id)s on network %(network_id)s'
                        ' does not yet exist.'), {'device_id': device_id,
                                                  'network_id': network.id})

            # When the DHCP port and VM TAP interfaces are not
            # bridged, we don't allocate a unique IP address for the
            # DHCP port.
            port_fixed_ips = []
            if self.driver.bridged():
                port_fixed_ips=[dict(subnet_id=s) for s in dhcp_enabled_subnet_ids]

            port_dict = dict(
                name='',
                admin_state_up=True,
                device_id=device_id,
                network_id=network.id,
                tenant_id=network.tenant_id,
                fixed_ips=port_fixed_ips)
            dhcp_port = self.plugin.create_dhcp_port({'port': port_dict})

        if not dhcp_port:
            raise exceptions.Conflict()

        # Convert subnet_id to subnet dict
        fixed_ips = [dict(subnet_id=fixed_ip.subnet_id,
                          ip_address=fixed_ip.ip_address,
                          subnet=subnets[fixed_ip.subnet_id])
                     for fixed_ip in dhcp_port.fixed_ips]

        ips = [DictModel(item) if isinstance(item, dict) else item
               for item in fixed_ips]
        dhcp_port.fixed_ips = ips

        return dhcp_port