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)
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)
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)
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)
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)
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)
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)