Beispiel #1
0
    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."))
Beispiel #2
0
    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."))
Beispiel #3
0
 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)
Beispiel #4
0
 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)
Beispiel #5
0
    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."))
Beispiel #6
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:
            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)
Beispiel #7
0
    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."))
Beispiel #8
0
    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)