def update_port(self, context, id, port):
        delete_security_groups = self._check_update_deletes_security_groups(
            port)
        has_security_groups = self._check_update_has_security_groups(port)
        with context.session.begin(subtransactions=True):
            ret_port = super(PortSecurityTestPlugin,
                             self).update_port(context, id, port)
            # copy values over - but not fixed_ips
            port['port'].pop('fixed_ips', None)
            ret_port.update(port['port'])

            # populate port_security setting
            if psec.PORTSECURITY not in ret_port:
                ret_port[psec.PORTSECURITY] = self._get_port_security_binding(
                    context, id)
            has_ip = self._ip_on_port(ret_port)
            # checks if security groups were updated adding/modifying
            # security groups, port security is set and port has ip
            if (has_security_groups
                    and (not ret_port[psec.PORTSECURITY] or not has_ip)):
                raise psec.PortSecurityAndIPRequiredForSecurityGroups()

            # Port security/IP was updated off. Need to check that no security
            # groups are on port.
            if ret_port[psec.PORTSECURITY] is not True or not has_ip:
                if has_security_groups:
                    raise psec.PortSecurityAndIPRequiredForSecurityGroups()

                # get security groups on port
                filters = {'port_id': [id]}
                security_groups = (super(
                    PortSecurityTestPlugin,
                    self)._get_port_security_group_bindings(context, filters))
                if security_groups and not delete_security_groups:
                    raise psec.PortSecurityPortHasSecurityGroup()

            if (delete_security_groups or has_security_groups):
                # delete the port binding and read it with the new rules.
                self._delete_port_security_group_bindings(context, id)
                sgids = self._get_security_groups_on_port(context, port)
                # process port create sec groups needs port id
                port['id'] = id
                self._process_port_create_security_group(
                    context, ret_port, sgids)

            if psec.PORTSECURITY in port['port']:
                self._process_port_port_security_update(
                    context, port['port'], ret_port)

        return ret_port
Ejemplo n.º 2
0
    def update_port(self, context, id, port):
        LOG.debug(
            "MidonetPluginV2.update_port called: id=%(id)s "
            "port=%(port)r", {
                'id': id,
                'port': port
            })

        with context.session.begin(subtransactions=True):

            # update the port DB
            original_port = super(MidonetPluginV2, self).get_port(context, id)
            p = super(MidonetPluginV2, self).update_port(context, id, port)
            c_utils.check_update_port(original_port, p)
            self.extension_manager.process_update_port(context, port['port'],
                                                       p)

            has_sg = self._check_update_has_security_groups(port)
            delete_sg = self._check_update_deletes_security_groups(port)

            if delete_sg or has_sg:
                # delete the port binding and read it with the new rules.
                self._delete_port_security_group_bindings(context, id)
                sg_ids = self._get_security_groups_on_port(context, port)
                self._process_port_create_security_group(context, p, sg_ids)
            self._update_extra_dhcp_opts_on_port(context, id, port, p)

            self._process_portbindings_create_and_update(
                context, port['port'], p)
            self._process_mido_portbindings_create_and_update(
                context, port['port'], p)
            self.update_address_pairs_on_port(context, id, port, original_port,
                                              p)

            self._process_port_port_security_update(context, port['port'], p)

            port_psec = p.get(psec.PORTSECURITY)
            if port_psec is False:
                if p.get(ext_sg.SECURITYGROUPS):
                    raise psec.PortSecurityPortHasSecurityGroup()
                if p.get(addr_pair.ADDRESS_PAIRS):
                    raise addr_pair.AddressPairAndPortSecurityRequired()
            # NOTE(yamamoto): Retrieve the db object to get the correct
            # revision
            context.session.flush()
            context.session.expire_all()
            p = self.get_port(context, id)
            self.client.update_port_precommit(context, id, p)

        # Set status along admin_state_up to update.
        if p['admin_state_up']:
            update_status = n_const.PORT_STATUS_ACTIVE
        else:
            update_status = n_const.PORT_STATUS_DOWN

        try:
            self.client.update_port_postcommit(id, p)
            data = {'port': {'status': update_status}}
            new_port = super(MidonetPluginV2,
                             self).update_port(context, id, data)
            # prevent binding:profile information from lacking
            p['status'] = new_port['status']
            if 'revision_number' in new_port:
                p['revision_number'] = new_port['revision_number']
        except Exception as ex:
            with excutils.save_and_reraise_exception():
                LOG.error(
                    _LE("Failed to update a port %(port_id)s in "
                        "MidoNet: %(err)s"), {
                            "port_id": id,
                            "err": ex
                        })
                try:
                    data = {'port': {'status': n_const.PORT_STATUS_ERROR}}
                    super(MidonetPluginV2, self).update_port(context, id, data)
                except Exception:
                    LOG.exception(_LE("Failed to update port status %s"), id)

        LOG.debug("MidonetPluginV2.update_port exiting: p=%r", p)
        return p