예제 #1
0
    def put(self, id, load_balancer):
        """Updates a load balancer."""
        load_balancer = load_balancer.loadbalancer
        context = pecan_request.context.get('octavia_context')
        db_lb = self._get_db_lb(context.session, id, show_deleted=False)

        self._auth_validate_action(context, db_lb.project_id,
                                   constants.RBAC_PUT)

        if not isinstance(load_balancer.vip_qos_policy_id, wtypes.UnsetType):
            network_driver = utils.get_network_driver()
            validate.qos_extension_enabled(network_driver)
            if load_balancer.vip_qos_policy_id is not None:
                if db_lb.vip.qos_policy_id != load_balancer.vip_qos_policy_id:
                    validate.qos_policy_exists(load_balancer.vip_qos_policy_id)

        # Load the driver early as it also provides validation
        driver = driver_factory.get_driver(db_lb.provider)

        with db_api.get_lock_session() as lock_session:
            self._test_lb_status(lock_session, id)

            # Prepare the data for the driver data model
            lb_dict = load_balancer.to_dict(render_unsets=False)
            lb_dict['id'] = id
            vip_dict = lb_dict.pop('vip', {})
            lb_dict = driver_utils.lb_dict_to_provider_dict(lb_dict)
            if 'qos_policy_id' in vip_dict:
                lb_dict['vip_qos_policy_id'] = vip_dict['qos_policy_id']

            # Also prepare the baseline object data
            old_provider_lb = (
                driver_utils.db_loadbalancer_to_provider_loadbalancer(
                    db_lb, for_delete=True))

            # Dispatch to the driver
            LOG.info("Sending update Load Balancer %s to provider "
                     "%s", id, driver.name)
            driver_utils.call_provider(
                driver.name, driver.loadbalancer_update,
                old_provider_lb,
                driver_dm.LoadBalancer.from_dict(lb_dict))

            db_lb_dict = load_balancer.to_dict(render_unsets=False)
            if 'vip' in db_lb_dict:
                db_vip_dict = db_lb_dict.pop('vip')
                self.repositories.vip.update(lock_session, id, **db_vip_dict)
            if db_lb_dict:
                self.repositories.load_balancer.update(lock_session, id,
                                                       **db_lb_dict)

        # Force SQL alchemy to query the DB, otherwise we get inconsistent
        # results
        context.session.expire_all()
        db_lb = self._get_db_lb(context.session, id)
        result = self._convert_db_to_type(db_lb, lb_types.LoadBalancerResponse)
        return lb_types.LoadBalancerRootResponse(loadbalancer=result)
예제 #2
0
    def put(self, id, load_balancer):
        """Updates a load balancer."""
        load_balancer = load_balancer.loadbalancer
        context = pecan.request.context.get('octavia_context')
        db_lb = self._get_db_lb(context.session, id, show_deleted=False)

        self._auth_validate_action(context, db_lb.project_id,
                                   constants.RBAC_PUT)

        if not isinstance(load_balancer.vip_qos_policy_id, wtypes.UnsetType):
            network_driver = utils.get_network_driver()
            validate.qos_extension_enabled(network_driver)
            if load_balancer.vip_qos_policy_id is not None:
                if db_lb.vip.qos_policy_id != load_balancer.vip_qos_policy_id:
                    validate.qos_policy_exists(load_balancer.vip_qos_policy_id)

        # Load the driver early as it also provides validation
        driver = driver_factory.get_driver(db_lb.provider)

        with db_api.get_lock_session() as lock_session:
            self._test_lb_status(lock_session, id)

            # Prepare the data for the driver data model
            lb_dict = load_balancer.to_dict(render_unsets=False)
            lb_dict['id'] = id
            vip_dict = lb_dict.pop('vip', {})
            lb_dict = driver_utils.lb_dict_to_provider_dict(lb_dict)
            if 'qos_policy_id' in vip_dict:
                lb_dict['vip_qos_policy_id'] = vip_dict['qos_policy_id']

            # Also prepare the baseline object data
            old_provider_lb = (
                driver_utils.db_loadbalancer_to_provider_loadbalancer(db_lb))

            # Dispatch to the driver
            LOG.info("Sending update Load Balancer %s to provider "
                     "%s", id, driver.name)
            driver_utils.call_provider(
                driver.name, driver.loadbalancer_update,
                old_provider_lb,
                driver_dm.LoadBalancer.from_dict(lb_dict))

            db_lb_dict = load_balancer.to_dict(render_unsets=False)
            if 'vip' in db_lb_dict:
                db_vip_dict = db_lb_dict.pop('vip')
                self.repositories.vip.update(lock_session, id, **db_vip_dict)
            if db_lb_dict:
                self.repositories.load_balancer.update(lock_session, id,
                                                       **db_lb_dict)

        # Force SQL alchemy to query the DB, otherwise we get inconsistent
        # results
        context.session.expire_all()
        db_lb = self._get_db_lb(context.session, id)
        result = self._convert_db_to_type(db_lb, lb_types.LoadBalancerResponse)
        return lb_types.LoadBalancerRootResponse(loadbalancer=result)
예제 #3
0
    def _validate_vip_request_object(self, load_balancer, context=None):
        allowed_network_objects = []
        if CONF.networking.allow_vip_port_id:
            allowed_network_objects.append('vip_port_id')
        if CONF.networking.allow_vip_network_id:
            allowed_network_objects.append('vip_network_id')
        if CONF.networking.allow_vip_subnet_id:
            allowed_network_objects.append('vip_subnet_id')

        msg = _("use of %(object)s is disallowed by this deployment's "
                "configuration.")
        if (load_balancer.vip_port_id and
                not CONF.networking.allow_vip_port_id):
            raise exceptions.ValidationException(
                detail=msg % {'object': 'vip_port_id'})
        if (load_balancer.vip_network_id and
                not CONF.networking.allow_vip_network_id):
            raise exceptions.ValidationException(
                detail=msg % {'object': 'vip_network_id'})
        if (load_balancer.vip_subnet_id and
                not CONF.networking.allow_vip_subnet_id):
            raise exceptions.ValidationException(
                detail=msg % {'object': 'vip_subnet_id'})

        if not (load_balancer.vip_port_id or
                load_balancer.vip_network_id or
                load_balancer.vip_subnet_id):
            raise exceptions.VIPValidationException(
                objects=', '.join(allowed_network_objects))

        # Validate the port id
        if load_balancer.vip_port_id:
            self._validate_port_and_fill_or_validate_subnet(load_balancer,
                                                            context=context)
        # If no port id, validate the network id (and subnet if provided)
        elif load_balancer.vip_network_id:
            self._validate_network_and_fill_or_validate_subnet(load_balancer,
                                                               context=context)
        # Validate just the subnet id
        elif load_balancer.vip_subnet_id:
            subnet = validate.subnet_exists(
                subnet_id=load_balancer.vip_subnet_id)
            load_balancer.vip_network_id = subnet.network_id
        if load_balancer.vip_qos_policy_id:
            validate.qos_policy_exists(
                qos_policy_id=load_balancer.vip_qos_policy_id)
예제 #4
0
    def _validate_vip_request_object(self, load_balancer):
        allowed_network_objects = []
        if CONF.networking.allow_vip_port_id:
            allowed_network_objects.append('vip_port_id')
        if CONF.networking.allow_vip_network_id:
            allowed_network_objects.append('vip_network_id')
        if CONF.networking.allow_vip_subnet_id:
            allowed_network_objects.append('vip_subnet_id')

        msg = _("use of %(object)s is disallowed by this deployment's "
                "configuration.")
        if (load_balancer.vip_port_id and
                not CONF.networking.allow_vip_port_id):
            raise exceptions.ValidationException(
                detail=msg % {'object': 'vip_port_id'})
        if (load_balancer.vip_network_id and
                not CONF.networking.allow_vip_network_id):
            raise exceptions.ValidationException(
                detail=msg % {'object': 'vip_network_id'})
        if (load_balancer.vip_subnet_id and
                not CONF.networking.allow_vip_subnet_id):
            raise exceptions.ValidationException(
                detail=msg % {'object': 'vip_subnet_id'})

        if not (load_balancer.vip_port_id or
                load_balancer.vip_network_id or
                load_balancer.vip_subnet_id):
            raise exceptions.VIPValidationException(
                objects=', '.join(allowed_network_objects))

        # Validate the port id
        if load_balancer.vip_port_id:
            self._validate_port_and_fill_or_validate_subnet(load_balancer)
        # If no port id, validate the network id (and subnet if provided)
        elif load_balancer.vip_network_id:
            self._validate_network_and_fill_or_validate_subnet(load_balancer)
        # Validate just the subnet id
        elif load_balancer.vip_subnet_id:
            subnet = validate.subnet_exists(
                subnet_id=load_balancer.vip_subnet_id)
            load_balancer.vip_network_id = subnet.network_id
        if load_balancer.vip_qos_policy_id:
            validate.qos_policy_exists(
                qos_policy_id=load_balancer.vip_qos_policy_id)
        validate.network_allowed_by_config(load_balancer.vip_network_id)
예제 #5
0
    def test_qos_policy_exists(self):
        qos_policy_id = uuidutils.generate_uuid()
        qos_policy = network_models.QosPolicy(id=qos_policy_id)
        with mock.patch('octavia.common.utils.get_network_driver') as net_mock:
            net_mock.return_value.get_qos_policy.return_value = qos_policy
            self.assertEqual(validate.qos_policy_exists(qos_policy_id),
                             qos_policy)

            net_mock.return_value.get_qos_policy.side_effect = Exception
            self.assertRaises(exceptions.InvalidSubresource,
                              validate.qos_policy_exists, qos_policy_id)
예제 #6
0
    def test_qos_policy_exists(self):
        qos_policy_id = uuidutils.generate_uuid()
        qos_policy = network_models.QosPolicy(id=qos_policy_id)
        with mock.patch(
                'octavia.common.utils.get_network_driver') as net_mock:
            net_mock.return_value.get_qos_policy.return_value = qos_policy
            self.assertEqual(
                validate.qos_policy_exists(qos_policy_id),
                qos_policy)

            net_mock.return_value.get_qos_policy.side_effect = Exception
            self.assertRaises(exceptions.InvalidSubresource,
                              validate.qos_policy_exists,
                              qos_policy_id)
예제 #7
0
    def put(self, id, load_balancer):
        """Updates a load balancer."""
        load_balancer = load_balancer.loadbalancer
        context = pecan.request.context.get('octavia_context')
        db_lb = self._get_db_lb(context.session, id)

        self._auth_validate_action(context, db_lb.project_id,
                                   constants.RBAC_PUT)

        if (load_balancer.vip_qos_policy_id and not isinstance(
                load_balancer.vip_qos_policy_id, wtypes.UnsetType) and
                db_lb.vip.qos_policy_id != load_balancer.vip_qos_policy_id):
            validate.qos_policy_exists(load_balancer.vip_qos_policy_id)
        self._test_lb_status(context.session, id)
        try:
            LOG.info("Sending updated Load Balancer %s to the handler", id)
            self.handler.update(db_lb, load_balancer)
        except Exception:
            with excutils.save_and_reraise_exception(reraise=False):
                self.repositories.load_balancer.update(
                    context.session, id, provisioning_status=constants.ERROR)
        db_lb = self._get_db_lb(context.session, id)
        result = self._convert_db_to_type(db_lb, lb_types.LoadBalancerResponse)
        return lb_types.LoadBalancerRootResponse(loadbalancer=result)