예제 #1
0
파일: plugin.py 프로젝트: Juniper/neutron
    def create_network(self, context, network):
        net_data = network['network']
        segments = self._process_provider_create(net_data)
        tenant_id = self._get_tenant_id_for_create(context, net_data)

        session = context.session
        with session.begin(subtransactions=True):
            self._ensure_default_security_group(context, tenant_id)
            result = super(Ml2Plugin, self).create_network(context, network)
            network_id = result['id']
            self._process_l3_create(context, result, net_data)
            # REVISIT(rkukura): Consider moving all segment management
            # to TypeManager.
            if segments:
                for segment in segments:
                    self.type_manager.reserve_provider_segment(session,
                                                               segment)
                    db.add_network_segment(session, network_id, segment)
            else:
                segment = self.type_manager.allocate_tenant_segment(session)
                db.add_network_segment(session, network_id, segment)
            self._extend_network_dict_provider(context, result)
            mech_context = driver_context.NetworkContext(self, context,
                                                         result)
            self.mechanism_manager.create_network_precommit(mech_context)

        try:
            self.mechanism_manager.create_network_postcommit(mech_context)
        except ml2_exc.MechanismDriverError:
            with excutils.save_and_reraise_exception():
                LOG.error(_("mechanism_manager.create_network_postcommit "
                            "failed, deleting network '%s'"), result['id'])
                self.delete_network(context, result['id'])
        return result
예제 #2
0
    def _sync_base(self):
        ctx = context.get_admin_context()
        # Sync Networks
        for network in self.core_plugin.get_networks(ctx):
            mech_context = driver_context.NetworkContext(self.core_plugin, ctx,
                                                         network)
            try:
                self.driver.create_network_postcommit(mech_context)
            except Exception:
                LOG.warn(_LW("Create network postcommit failed for "
                             "network %s"), network['id'])

        # Sync Subnets
        for subnet in self.core_plugin.get_subnets(ctx):
            mech_context = driver_context.SubnetContext(self.core_plugin, ctx,
                                                        subnet)
            try:
                self.driver.create_subnet_postcommit(mech_context)
            except Exception:
                LOG.warn(_LW("Create subnet postcommit failed for"
                             " subnet %s"), subnet['id'])

        # Sync Ports (compute/gateway/dhcp)
        for port in self.core_plugin.get_ports(ctx):
            _, binding = l2_db.get_locked_port_and_binding(ctx.session,
                                                           port['id'])
            network = self.core_plugin.get_network(ctx, port['network_id'])
            mech_context = driver_context.PortContext(self.core_plugin, ctx,
                                                      port, network, binding,
                                                      [])
            try:
                self.driver.create_port_postcommit(mech_context)
            except Exception:
                LOG.warn(_LW("Create port postcommit failed for"
                             " port %s"), port['id'])
예제 #3
0
파일: plugin.py 프로젝트: kakawxy/neutron-1
    def delete_network(self, context, id):
        # REVISIT(rkukura) The super(Ml2Plugin, self).delete_network()
        # function is not used because it auto-deletes ports and
        # subnets from the DB without invoking the derived class's
        # delete_port() or delete_subnet(), preventing mechanism
        # drivers from being called. This approach should be revisited
        # when the API layer is reworked during icehouse.

        session = context.session
        while True:
            with session.begin(subtransactions=True):
                filter = {'network_id': [id]}

                # Get ports to auto-delete.
                ports = self.get_ports(context, filters=filter)
                only_auto_del = all(p['device_owner'] in
                                    db_base_plugin_v2.AUTO_DELETE_PORT_OWNERS
                                    for p in ports)
                if not only_auto_del:
                    raise exc.NetworkInUse(net_id=id)

                # Get subnets to auto-delete.
                subnets = self.get_subnets(context, filters=filter)

                if not ports or subnets:
                    network = self.get_network(context, id)
                    mech_context = driver_context.NetworkContext(
                        self, context, network)
                    self.mechanism_manager.delete_network_precommit(
                        mech_context)

                    record = self._get_network(context, id)
                    context.session.delete(record)

                    for segment in mech_context.network_segments:
                        self.type_manager.release_segment(session, segment)

                    # The segment records are deleted via cascade from the
                    # network record, so explicit removal is not necessary.
                    break

            for port in ports:
                self.delete_port(context, port['id'])

            for subnet in subnets:
                self.delete_subnet(context, subnet['id'])

        try:
            self.mechanism_manager.delete_network_postcommit(mech_context)
        except ml2_exc.MechanismDriverError:
            # TODO(apech) - One or more mechanism driver failed to
            # delete the network.  Ideally we'd notify the caller of
            # the fact that an error occurred.
            pass
        self.notifier.network_delete(context, id)
예제 #4
0
    def _sync_base(self):
        ctx = context.get_admin_context()
        # Sync Networks
        # Unroll to avoid unwanted additions during sync
        networks = [x for x in self.core_plugin.get_networks(ctx)]
        for network in networks:
            if (network['name'].startswith(
                    constants.HOST_SNAT_NETWORK_PREFIX) or
                    constants.APIC_SYNC_NETWORK == network['name']):
                continue

            mech_context = driver_context.NetworkContext(
                self.core_plugin, ctx, network)
            try:
                self.driver.create_network_postcommit(mech_context)
            except aexc.ReservedSynchronizationName as e:
                LOG.debug(e.message)
            except Exception as e:
                LOG.exception(e)

        # Sync Subnets
        subnets = [x for x in self.core_plugin.get_subnets(ctx)]
        for subnet in subnets:
            if constants.HOST_SNAT_POOL in subnet['name']:
                continue
            network = self.core_plugin.get_network(
                ctx, subnet['network_id'])
            mech_context = driver_context.SubnetContext(self.core_plugin, ctx,
                                                        subnet, network)
            try:
                self.driver.create_subnet_postcommit(mech_context)
            except Exception as e:
                LOG.exception(e)

        # Sync Ports (compute/gateway/dhcp)
        ports = [x for x in self.core_plugin.get_ports(ctx)]
        for port in ports:
            if constants.HOST_SNAT_POOL_PORT in port['name']:
                continue
            _, binding = l2_db.get_locked_port_and_binding(ctx.session,
                                                           port['id'])
            levels = l2_db.get_binding_levels(ctx.session, port['id'],
                                              binding.host)
            network = self.core_plugin.get_network(ctx, port['network_id'])
            mech_context = driver_context.PortContext(self.core_plugin, ctx,
                                                      port, network, binding,
                                                      levels)
            try:
                self.driver.create_port_postcommit(mech_context)
            except Exception as e:
                LOG.exception(e)
예제 #5
0
    def _sync_base(self):
        ctx = context.get_admin_context()
        # Sync Networks
        # Unroll to avoid unwanted additions during sync
        networks = [x for x in self.core_plugin.get_networks(ctx)]
        for network in networks:
            if constants.APIC_SYNC_NETWORK == network['name']:
                continue

            mech_context = driver_context.NetworkContext(
                self.core_plugin, ctx, network)
            try:
                self.driver.create_network_postcommit(mech_context)
            except aexc.ReservedSynchronizationName as e:
                LOG.debug(e.message)
            except Exception as e:
                LOG.warning(_LW("Create network postcommit failed for "
                                "network %(net_id)s: %(message)s"),
                            net_id=network['id'], message=e.message)
        # Sync Subnets
        subnets = [x for x in self.core_plugin.get_subnets(ctx)]
        for subnet in subnets:
            mech_context = driver_context.SubnetContext(self.core_plugin, ctx,
                                                        subnet)
            try:
                self.driver.create_subnet_postcommit(mech_context)
            except Exception as e:
                LOG.warning(_LW("Create subnet postcommit failed for "
                                "subnet %(sub_id)s: %(message)s"),
                            sub_id=subnet['id'], message=e.message)
        # Sync Ports (compute/gateway/dhcp)
        ports = [x for x in self.core_plugin.get_ports(ctx)]
        for port in ports:
            binding = l2_db.get_locked_port_and_binding(ctx.session,
                                                        port['id'])[1]
            levels = l2_db.get_binding_levels(ctx.session, port['id'],
                                              binding.host)
            network = self.core_plugin.get_network(ctx, port['network_id'])
            mech_context = driver_context.PortContext(self.core_plugin, ctx,
                                                      port, network, binding,
                                                      levels)
            try:
                self.driver.create_port_postcommit(mech_context)
            except Exception as e:
                LOG.warning(_LW("Create port postcommit failed for "
                                "port %(port_id)s: %(message)s"),
                            port_id=port['id'], message=e.message)
예제 #6
0
    def delete_network(self, context, id):
        session = context.session
        with session.begin(subtransactions=True):
            network = self.get_network(context, id)
            mech_context = driver_context.NetworkContext(
                self, context, network)
            self.mechanism_manager.delete_network_precommit(mech_context)
            super(Ml2Plugin, self).delete_network(context, id)
            for segment in mech_context.network_segments:
                self.type_manager.release_segment(session, segment)
            # The segment records are deleted via cascade from the
            # network record, so explicit removal is not necessary.

        try:
            self.mechanism_manager.delete_network_postcommit(mech_context)
        except ml2_exc.MechanismDriverError:
            # TODO(apech) - One or more mechanism driver failed to
            # delete the network.  Ideally we'd notify the caller of
            # the fact that an error occurred.
            pass
        self.notifier.network_delete(context, id)
예제 #7
0
파일: plugin.py 프로젝트: Juniper/neutron
    def update_network(self, context, id, network):
        provider._raise_if_updates_provider_attributes(network['network'])

        session = context.session
        with session.begin(subtransactions=True):
            original_network = super(Ml2Plugin, self).get_network(context, id)
            updated_network = super(Ml2Plugin, self).update_network(context,
                                                                    id,
                                                                    network)
            self._process_l3_update(context, updated_network,
                                    network['network'])
            self._extend_network_dict_provider(context, updated_network)
            mech_context = driver_context.NetworkContext(
                self, context, updated_network,
                original_network=original_network)
            self.mechanism_manager.update_network_precommit(mech_context)

        # TODO(apech) - handle errors raised by update_network, potentially
        # by re-calling update_network with the previous attributes. For
        # now the error is propogated to the caller, which is expected to
        # either undo/retry the operation or delete the resource.
        self.mechanism_manager.update_network_postcommit(mech_context)
        return updated_network
예제 #8
0
파일: plugin.py 프로젝트: Juniper/neutron
    def delete_network(self, context, id):
        # REVISIT(rkukura) The super(Ml2Plugin, self).delete_network()
        # function is not used because it auto-deletes ports and
        # subnets from the DB without invoking the derived class's
        # delete_port() or delete_subnet(), preventing mechanism
        # drivers from being called. This approach should be revisited
        # when the API layer is reworked during icehouse.

        LOG.debug(_("Deleting network %s"), id)
        session = context.session
        while True:
            try:
                with session.begin(subtransactions=True):
                    # Get ports to auto-delete.
                    ports = (session.query(models_v2.Port).
                             enable_eagerloads(False).
                             filter_by(network_id=id).
                             with_lockmode('update').all())
                    LOG.debug(_("Ports to auto-delete: %s"), ports)
                    only_auto_del = all(p.device_owner
                                        in db_base_plugin_v2.
                                        AUTO_DELETE_PORT_OWNERS
                                        for p in ports)
                    if not only_auto_del:
                        LOG.debug(_("Tenant-owned ports exist"))
                        raise exc.NetworkInUse(net_id=id)

                    # Get subnets to auto-delete.
                    subnets = (session.query(models_v2.Subnet).
                               enable_eagerloads(False).
                               filter_by(network_id=id).
                               with_lockmode('update').all())
                    LOG.debug(_("Subnets to auto-delete: %s"), subnets)

                    if not (ports or subnets):
                        network = self.get_network(context, id)
                        mech_context = driver_context.NetworkContext(self,
                                                                     context,
                                                                     network)
                        self.mechanism_manager.delete_network_precommit(
                            mech_context)

                        record = self._get_network(context, id)
                        LOG.debug(_("Deleting network record %s"), record)
                        session.delete(record)

                        for segment in mech_context.network_segments:
                            self.type_manager.release_segment(session, segment)

                        # The segment records are deleted via cascade from the
                        # network record, so explicit removal is not necessary.
                        LOG.debug(_("Committing transaction"))
                        break
            except os_db.exception.DBError as e:
                if isinstance(e.inner_exception, sql_exc.IntegrityError):
                    msg = _("A concurrent port creation has occurred")
                    LOG.warning(msg)
                    continue
                else:
                    raise

            for port in ports:
                try:
                    self.delete_port(context, port.id)
                except Exception:
                    LOG.exception(_("Exception auto-deleting port %s"),
                                  port.id)
                    raise

            for subnet in subnets:
                try:
                    self.delete_subnet(context, subnet.id)
                except Exception:
                    LOG.exception(_("Exception auto-deleting subnet %s"),
                                  subnet.id)
                    raise

        try:
            self.mechanism_manager.delete_network_postcommit(mech_context)
        except ml2_exc.MechanismDriverError:
            # TODO(apech) - One or more mechanism driver failed to
            # delete the network.  Ideally we'd notify the caller of
            # the fact that an error occurred.
            LOG.error(_("mechanism_manager.delete_network_postcommit failed"))
        self.notifier.network_delete(context, id)
예제 #9
0
 def filter_create_attributes_with_plugin(cls, network, plugin, dbcontext):
     context = driver_context.NetworkContext(plugin, dbcontext, network)
     cls.filter_create_attributes(network, context)
예제 #10
0
def delete_network(self, context, id):
    # REVISIT(rkukura) The super(Ml2Plugin, self).delete_network()
    # function is not used because it auto-deletes ports and
    # subnets from the DB without invoking the derived class's
    # delete_port() or delete_subnet(), preventing mechanism
    # drivers from being called. This approach should be revisited
    # when the API layer is reworked during icehouse.

    LOG.debug("Deleting network %s", id)
    session = context.session
    attempt = 0
    while True:
        attempt += 1
        LOG.info(i18n._LI("Attempt %(attempt)s to delete network %(net)s"), {
            'attempt': attempt,
            'net': id
        })
        if attempt > 100:
            raise InfiniteLoopError()
        try:
            # REVISIT: Serialize this operation with a semaphore
            # to prevent deadlock waiting to acquire a DB lock
            # held by another thread in the same process, leading
            # to 'lock wait timeout' errors.
            #
            # Process L3 first, since, depending on the L3 plugin, it may
            # involve sending RPC notifications, and/or calling delete_port
            # on this plugin.
            # Additionally, a rollback may not be enough to undo the
            # deletion of a floating IP with certain L3 backends.
            self._process_l3_delete(context, id)
            # Using query().with_lockmode isn't necessary. Foreign-key
            # constraints prevent deletion if concurrent creation happens.
            with session.begin(subtransactions=True):
                # Get ports to auto-delete.
                ports = (session.query(
                    models_v2.Port).enable_eagerloads(False).filter_by(
                        network_id=id).all())
                LOG.debug("Ports to auto-delete: %s", ports)
                only_auto_del = all(
                    p.device_owner in db_base_plugin_v2.AUTO_DELETE_PORT_OWNERS
                    for p in ports)
                if not only_auto_del:
                    LOG.debug("Tenant-owned ports exist")
                    raise exc.NetworkInUse(net_id=id)

                # Get subnets to auto-delete.
                subnets = (session.query(
                    models_v2.Subnet).enable_eagerloads(False).filter_by(
                        network_id=id).all())
                LOG.debug("Subnets to auto-delete: %s", subnets)

                if not (ports or subnets):
                    network = self.get_network(context, id)
                    mech_context = driver_context.NetworkContext(
                        self, context, network)
                    self.mechanism_manager.delete_network_precommit(
                        mech_context)

                    self.type_manager.release_network_segments(session, id)
                    record = self._get_network(context, id)
                    LOG.debug("Deleting network record %s", record)
                    session.delete(record)

                    # The segment records are deleted via cascade from the
                    # network record, so explicit removal is not necessary.
                    LOG.debug("Committing transaction")
                    break

                port_ids = [port.id for port in ports]
                subnet_ids = [subnet.id for subnet in subnets]
        except os_db_exception.DBError as e:
            with excutils.save_and_reraise_exception() as ctxt:
                if isinstance(e.inner_exception, sql_exc.IntegrityError):
                    ctxt.reraise = False
                    LOG.warning(
                        i18n._LW("A concurrent port creation has "
                                 "occurred"))
                    continue
        LOG.info(i18n._LI("Auto-deleting ports %(ports)s for network %(net)s"),
                 {
                     'ports': ports,
                     'net': id
                 })
        self._delete_ports(context, port_ids)
        LOG.info(
            i18n._LI("Auto-deleting subnets %(subnets)s for network "
                     "%(net)s"), {
                         'subnets': subnets,
                         'net': id
                     })
        self._delete_subnets(context, subnet_ids)

    try:
        self.mechanism_manager.delete_network_postcommit(mech_context)
    except ml2_exc.MechanismDriverError:
        # TODO(apech) - One or more mechanism driver failed to
        # delete the network.  Ideally we'd notify the caller of
        # the fact that an error occurred.
        LOG.error(
            i18n._LE("mechanism_manager.delete_network_postcommit"
                     " failed"))
    self.notifier.network_delete(context, id)