def _validate_port_and_fill_or_validate_subnet(load_balancer): port = validate.port_exists(port_id=load_balancer.vip_port_id) validate.check_port_in_use(port) load_balancer.vip_network_id = port.network_id # validate the request vip port whether applied the qos_policy and # store the port_qos_policy to loadbalancer obj if possible. The # default behavior is that if 'vip_qos_policy_id' is specified in the # request, it will override the qos_policy applied on vip_port. port_qos_policy_id = port.qos_policy_id if (port_qos_policy_id and isinstance(load_balancer.vip_qos_policy_id, wtypes.UnsetType)): load_balancer.vip_qos_policy_id = port_qos_policy_id # Identify the subnet for this port if load_balancer.vip_subnet_id: validate.subnet_exists(subnet_id=load_balancer.vip_subnet_id) else: if load_balancer.vip_address: for port_fixed_ip in port.fixed_ips: if port_fixed_ip.ip_address == load_balancer.vip_address: load_balancer.vip_subnet_id = port_fixed_ip.subnet_id break if not load_balancer.vip_subnet_id: raise exceptions.ValidationException(detail=_( "Specified VIP address not found on the " "specified VIP port.")) elif len(port.fixed_ips) == 1: load_balancer.vip_subnet_id = port.fixed_ips[0].subnet_id else: raise exceptions.ValidationException(detail=_( "VIP port's subnet could not be determined. Please " "specify either a VIP subnet or address."))
def _validate_port_and_fill_or_validate_subnet(load_balancer): port = validate.port_exists(port_id=load_balancer.vip_port_id) validate.check_port_in_use(port) load_balancer.vip_network_id = port.network_id # validate the request vip port whether applied the qos_policy and # store the port_qos_policy to loadbalancer obj if possible. The # default behavior is that if 'vip_qos_policy_id' is specified in the # request, it will override the qos_policy applied on vip_port. port_qos_policy_id = port.qos_policy_id if (port_qos_policy_id and isinstance(load_balancer.vip_qos_policy_id, wtypes.UnsetType)): load_balancer.vip_qos_policy_id = port_qos_policy_id # Identify the subnet for this port if load_balancer.vip_subnet_id: validate.subnet_exists(subnet_id=load_balancer.vip_subnet_id) else: if load_balancer.vip_address: for port_fixed_ip in port.fixed_ips: if port_fixed_ip.ip_address == load_balancer.vip_address: load_balancer.vip_subnet_id = port_fixed_ip.subnet_id break if not load_balancer.vip_subnet_id: raise exceptions.ValidationException( detail=_("Specified VIP address not found on the " "specified VIP port.")) elif len(port.fixed_ips) == 1: load_balancer.vip_subnet_id = port.fixed_ips[0].subnet_id else: raise exceptions.ValidationException(detail=_( "VIP port's subnet could not be determined. Please " "specify either a VIP subnet or address."))
def test_port_exists_with_valid_port(self): port_id = uuidutils.generate_uuid() port = network_models.Port(id=port_id) with mock.patch( 'octavia.common.utils.get_network_driver') as net_mock: net_mock.return_value.get_port.return_value = port self.assertEqual(validate.port_exists(port_id), port)
def _validate_port_and_fill_or_validate_subnet(load_balancer, context=None): port = validate.port_exists(port_id=load_balancer.vip_port_id, context=context) validate.check_port_in_use(port) load_balancer.vip_network_id = port.network_id # validate the request vip port whether applied the qos_policy and # store the port_qos_policy to loadbalancer obj if possible. The # default behavior is that if 'vip_qos_policy_id' is specified in the # request, it will override the qos_policy applied on vip_port. port_qos_policy_id = port.qos_policy_id if (port_qos_policy_id and isinstance(load_balancer.vip_qos_policy_id, wtypes.UnsetType)): load_balancer.vip_qos_policy_id = port_qos_policy_id if load_balancer.vip_subnet_id: # If we were provided a subnet_id, validate it exists and that # there is a fixed_ip on the port that matches the provided subnet validate.subnet_exists(subnet_id=load_balancer.vip_subnet_id, context=context) for port_fixed_ip in port.fixed_ips: if port_fixed_ip.subnet_id == load_balancer.vip_subnet_id: load_balancer.vip_address = port_fixed_ip.ip_address break # Just pick the first address found in the subnet if not load_balancer.vip_address: raise exceptions.ValidationException(detail=_( "No VIP address found on the specified VIP port within " "the specified subnet.")) elif load_balancer.vip_address: normalized_lb_ip = ipaddress.ip_address( load_balancer.vip_address).compressed for port_fixed_ip in port.fixed_ips: normalized_port_ip = ipaddress.ip_address( port_fixed_ip.ip_address).compressed if normalized_port_ip == normalized_lb_ip: load_balancer.vip_subnet_id = port_fixed_ip.subnet_id break if not load_balancer.vip_subnet_id: raise exceptions.ValidationException(detail=_( "Specified VIP address not found on the " "specified VIP port.")) elif len(port.fixed_ips) == 1: # User provided only a port, get the subnet and address from it load_balancer.vip_subnet_id = port.fixed_ips[0].subnet_id load_balancer.vip_address = port.fixed_ips[0].ip_address else: raise exceptions.ValidationException(detail=_( "VIP port's subnet could not be determined. Please " "specify either a VIP subnet or address."))
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: port = validate.port_exists(port_id=load_balancer.vip_port_id) load_balancer.vip_network_id = port.network_id # 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 validate.network_allowed_by_config(load_balancer.vip_network_id)
def _validate_port_and_fill_or_validate_subnet(load_balancer): port = validate.port_exists(port_id=load_balancer.vip_port_id) load_balancer.vip_network_id = port.network_id # Identify the subnet for this port if load_balancer.vip_subnet_id: validate.subnet_exists(subnet_id=load_balancer.vip_subnet_id) else: if load_balancer.vip_address: for port_fixed_ip in port.fixed_ips: if port_fixed_ip.ip_address == load_balancer.vip_address: load_balancer.vip_subnet_id = port_fixed_ip.subnet_id break if not load_balancer.vip_subnet_id: raise exceptions.ValidationException( detail=_("Specified VIP address not found on the " "specified VIP port.")) elif len(port.fixed_ips) == 1: load_balancer.vip_subnet_id = port.fixed_ips[0].subnet_id else: raise exceptions.ValidationException(detail=_( "VIP port's subnet could not be determined. Please " "specify either a VIP subnet or address."))
def post(self, load_balancer): """Creates a load balancer.""" load_balancer = load_balancer.loadbalancer context = pecan.request.context.get('octavia_context') project_id = context.project_id if context.is_admin or CONF.auth_strategy == constants.NOAUTH: if load_balancer.project_id: project_id = load_balancer.project_id if not project_id: raise exceptions.ValidationException(detail=_( "Missing project ID in request where one is required.")) load_balancer.project_id = project_id if not (load_balancer.vip_port_id or load_balancer.vip_network_id or load_balancer.vip_subnet_id): raise exceptions.ValidationException(detail=_( "VIP must contain one of: port_id, network_id, subnet_id.")) # Validate the port id if load_balancer.vip_port_id: port = validate.port_exists(port_id=load_balancer.vip_port_id) load_balancer.vip_network_id = port.network_id # 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 lock_session = db_api.get_session(autocommit=False) if self.repositories.check_quota_met(context.session, lock_session, data_models.LoadBalancer, load_balancer.project_id): lock_session.rollback() raise exceptions.QuotaException # TODO(blogan): lb graph, look at v1 code try: lb_dict = db_prepare.create_load_balancer( load_balancer.to_dict(render_unsets=True)) vip_dict = lb_dict.pop('vip', {}) db_lb = self.repositories.create_load_balancer_and_vip( lock_session, lb_dict, vip_dict) lock_session.commit() except odb_exceptions.DBDuplicateEntry: lock_session.rollback() raise exceptions.IDAlreadyExists() except Exception: with excutils.save_and_reraise_exception(): lock_session.rollback() # Handler will be responsible for sending to controller try: LOG.info(_LI("Sending created Load Balancer %s to the handler"), db_lb.id) self.handler.create(db_lb) except Exception: with excutils.save_and_reraise_exception(reraise=False): self.repositories.load_balancer.update( context.session, db_lb.id, provisioning_status=constants.ERROR) result = self._convert_db_to_type(db_lb, lb_types.LoadBalancerResponse) return lb_types.LoadBalancerRootResponse(loadbalancer=result)