Exemplo n.º 1
0
    def _wait_for_metadata_provisioned_if_needed(self, port_id):
        """Wait for metadata service to be provisioned.

        Wait until metadata service has been setup for this port in the chassis
        it resides. If metadata is disabled, this function will return right
        away.
        """
        if config.is_ovn_metadata_enabled() and self._sb_ovn:
            # Wait until metadata service has been setup for this port in the
            # chassis it resides.
            result = (
                self._sb_ovn.get_logical_port_chassis_and_datapath(port_id))
            if not result:
                LOG.warning("Logical port %s doesn't exist in OVN", port_id)
                return
            chassis, datapath = result
            if not chassis:
                LOG.warning("Logical port %s is not bound to a "
                            "chassis", port_id)
                return
            try:
                n_utils.wait_until_true(
                    lambda: datapath in self._sb_ovn.
                    get_chassis_metadata_networks(chassis),
                    timeout=METADATA_READY_WAIT_TIMEOUT,
                    exception=MetadataServiceReadyWaitTimeoutException)
            except MetadataServiceReadyWaitTimeoutException:
                # If we reach this point it means that metadata agent didn't
                # provision the datapath for this port on its chassis. Either
                # the agent is not running or it crashed. We'll complete the
                # provisioning block though.
                LOG.warning(
                    "Metadata service is not ready for port %s, check"
                    " networking-ovn-metadata-agent status/logs.", port_id)
Exemplo n.º 2
0
 def __init__(self, remote, schema):
     super(BaseOvnSbIdl, self).__init__(remote, schema)
     self.notify_handler = event.RowEventHandler()
     events = [ChassisAgentDeleteEvent(), ChassisGatewayAgentEvent()]
     if ovn_config.is_ovn_metadata_enabled():
         events.append(ChassisMetadataAgentEvent())
     self.notify_handler.watch_events(events)
Exemplo n.º 3
0
    def _sync_metadata_ports(self, ctx, db_ports):
        """Ensure metadata ports in all Neutron networks.

        This method will ensure that all networks have one and only one
        metadata port.
        """
        if not config.is_ovn_metadata_enabled():
            return
        LOG.debug('OVN sync metadata ports started')
        for net in self.core_plugin.get_networks(ctx):
            dhcp_ports = self.core_plugin.get_ports(
                ctx,
                filters=dict(network_id=[net['id']],
                             device_owner=[constants.DEVICE_OWNER_DHCP]))
            if not dhcp_ports:
                LOG.warning(
                    'Missing metadata port found in Neutron for '
                    'network %s', net['id'])
                if self.mode == SYNC_MODE_REPAIR:
                    try:
                        # Create the missing port in both Neutron and OVN.
                        LOG.warning(
                            'Creating missing metadadata port in '
                            'Neutron and OVN for network %s', net['id'])
                        self._ovn_client.create_metadata_port(ctx, net)
                    except n_exc.IpAddressGenerationFailure:
                        LOG.error(
                            'Could not allocate IP addresses for '
                            'metadata port in network %s', net['id'])
                        continue
            else:
                # Delete all but one DHCP ports. Only one is needed for
                # metadata.
                for port in dhcp_ports[1:]:
                    LOG.warning(
                        'Unnecessary DHCP port %s for network %s '
                        'found in Neutron', port['id'], net['id'])
                    if self.mode == SYNC_MODE_REPAIR:
                        LOG.warning(
                            'Deleting unnecessary DHCP port %s for '
                            'network %s', port['id'], net['id'])
                        self.core_plugin.delete_port(ctx, port['id'])
                    db_ports.pop(port['id'], None)
                port = dhcp_ports[0]
                if port['id'] in db_ports.keys():
                    LOG.warning(
                        'Metadata port %s for network %s found in '
                        'Neutron but not in OVN', port['id'], net['id'])
                    if self.mode == SYNC_MODE_REPAIR:
                        LOG.warning(
                            'Creating metadata port %s for network '
                            '%s in OVN', port['id'], net['id'])
                        self._create_port_in_ovn(ctx, port)
                    db_ports.pop(port['id'])

            if self.mode == SYNC_MODE_REPAIR:
                # Make sure that this port has an IP address in all the subnets
                self._ovn_client.update_metadata_port(ctx, net['id'])
        LOG.debug('OVN sync metadata ports finished')
Exemplo n.º 4
0
 def from_server(cls, connection_string, schema_name):
     _check_and_set_ssl_files(schema_name)
     helper = idlutils.get_schema_helper(connection_string, schema_name)
     helper.register_table('Chassis')
     if ovn_config.is_ovn_metadata_enabled():
         helper.register_table('Port_Binding')
         helper.register_table('Datapath_Binding')
     return cls(connection_string, helper)
Exemplo n.º 5
0
    def _wait_for_metadata_provisioned_if_needed(self, port_id):
        """Wait for metadata service to be provisioned.

        Wait until metadata service has been setup for this port in the chassis
        it resides. If metadata is disabled or DHCP is not enabled for its
        subnets, this function will return right away.
        """
        if config.is_ovn_metadata_enabled() and self._sb_ovn:
            # Wait until metadata service has been setup for this port in the
            # chassis it resides.
            result = (
                self._sb_ovn.get_logical_port_chassis_and_datapath(port_id))
            if not result:
                LOG.warning("Logical port %s doesn't exist in OVN", port_id)
                return
            chassis, datapath = result
            if not chassis:
                LOG.warning("Logical port %s is not bound to a "
                            "chassis", port_id)
                return

            # Check if the port belongs to some IPv4 subnet with DHCP enabled.
            context = n_context.get_admin_context()
            port = self._plugin.get_port(context, port_id)
            port_subnet_ids = set(ip['subnet_id'] for ip in port['fixed_ips']
                                  if n_utils.get_ip_version(ip['ip_address'])
                                  == const.IP_VERSION_4)
            if not port_subnet_ids:
                # The port doesn't belong to any IPv4 subnet
                return

            subnets = self._plugin.get_subnets(
                context,
                filters=dict(network_id=[port['network_id']],
                             ip_version=[4],
                             enable_dhcp=True))

            subnet_ids = set(s['id'] for s in subnets
                             if s['id'] in port_subnet_ids)
            if not subnet_ids:
                return

            try:
                n_utils.wait_until_true(
                    lambda: datapath in self._sb_ovn.
                    get_chassis_metadata_networks(chassis),
                    timeout=METADATA_READY_WAIT_TIMEOUT,
                    exception=MetadataServiceReadyWaitTimeoutException)
            except MetadataServiceReadyWaitTimeoutException:
                # If we reach this point it means that metadata agent didn't
                # provision the datapath for this port on its chassis. Either
                # the agent is not running or it crashed. We'll complete the
                # provisioning block though.
                LOG.warning(
                    "Metadata service is not ready for port %s, check"
                    " networking-ovn-metadata-agent status/logs.", port_id)
Exemplo n.º 6
0
 def from_server(cls, connection_string, schema_name, driver):
     _check_and_set_ssl_files(schema_name)
     helper = idlutils.get_schema_helper(connection_string, schema_name)
     helper.register_table('Chassis')
     helper.register_table('Encap')
     if ovn_config.is_ovn_metadata_enabled():
         helper.register_table('Port_Binding')
         helper.register_table('Datapath_Binding')
     _idl = cls(driver, connection_string, helper)
     _idl.set_lock(_idl.event_lock_name)
     return _idl
Exemplo n.º 7
0
    def check_metadata_ports(self):
        # If OVN metadata is disabled do not run this task again
        if not ovn_conf.is_ovn_metadata_enabled():
            raise periodics.NeverAgain()

        # Make sure that only one worker is executing this
        if not self.has_lock:
            return

        admin_context = n_context.get_admin_context()
        for n in self._ovn_client._plugin.get_networks(admin_context):
            self._ovn_client.create_metadata_port(admin_context, n)

        raise periodics.NeverAgain()