コード例 #1
0
ファイル: listener.py プロジェクト: selvakumarnms/octavia
    def _validate_listener(self, lock_session, listener_dict):
        """Validate listener for wrong protocol or duplicate listeners

        Update the load balancer db when provisioning status changes.
        """
        if (listener_dict and listener_dict.get('insert_headers') and list(
                set(listener_dict['insert_headers'].keys()) -
                set(constants.SUPPORTED_HTTP_HEADERS))):
            raise exceptions.InvalidOption(
                value=listener_dict.get('insert_headers'),
                option='insert_headers')

        try:
            sni_containers = listener_dict.pop('sni_containers', [])
            db_listener = self.repositories.listener.create(
                lock_session, **listener_dict)
            if sni_containers:
                for container in sni_containers:
                    sni_dict = {
                        'listener_id': db_listener.id,
                        'tls_container_id': container.get('tls_container_id')
                    }
                    self.repositories.sni.create(lock_session, **sni_dict)
                db_listener = self.repositories.listener.get(lock_session,
                                                             id=db_listener.id)
            return db_listener
        except odb_exceptions.DBDuplicateEntry as de:
            if ['id'] == de.columns:
                raise exceptions.IDAlreadyExists()
            elif set(['load_balancer_id', 'protocol_port']) == set(de.columns):
                raise exceptions.DuplicateListenerEntry(
                    port=listener_dict.get('protocol_port'))
        except odb_exceptions.DBError:
            raise exceptions.InvalidOption(value=listener_dict.get('protocol'),
                                           option='protocol')
コード例 #2
0
ファイル: listener.py プロジェクト: paperandsoap/octavia
    def _validate_listener(self, session, listener_dict):
        """Validate listener for wrong protocol or duplicate listeners

        Update the load balancer db when provisioning status changes.
        """
        lb_repo = self.repositories.load_balancer
        if (listener_dict
            and listener_dict.get('insert_headers')
            and list(set(listener_dict['insert_headers'].keys()) -
                     set(constants.SUPPORTED_HTTP_HEADERS))):
            raise exceptions.InvalidOption(
                value=listener_dict.get('insert_headers'),
                option='insert_headers')

        try:
            sni_containers = listener_dict.pop('sni_containers', [])
            db_listener = self.repositories.listener.create(
                session, **listener_dict)
            if sni_containers:
                for container in sni_containers:
                    sni_dict = {'listener_id': db_listener.id,
                                'tls_container_id': container.get(
                                    'tls_container_id')}
                    self.repositories.sni.create(session, **sni_dict)
                db_listener = self.repositories.listener.get(session,
                                                             id=db_listener.id)
        except odb_exceptions.DBDuplicateEntry as de:
            # Setting LB back to active because this is just a validation
            # failure
            lb_repo.update(session, self.load_balancer_id,
                           provisioning_status=constants.ACTIVE)
            if ['id'] == de.columns:
                raise exceptions.IDAlreadyExists()
            elif set(['load_balancer_id', 'protocol_port']) == set(de.columns):
                raise exceptions.DuplicateListenerEntry(
                    port=listener_dict.get('protocol_port'))
        except odb_exceptions.DBError:
            # Setting LB back to active because this is just a validation
            # failure
            lb_repo.update(session, self.load_balancer_id,
                           provisioning_status=constants.ACTIVE)
            raise exceptions.InvalidOption(value=listener_dict.get('protocol'),
                                           option='protocol')
        try:
            LOG.info(_LI("Sending Creation of Listener %s to handler"),
                     db_listener.id)
            self.handler.create(db_listener)
        except Exception:
            with excutils.save_and_reraise_exception(reraise=False):
                self.repositories.listener.update(
                    session, db_listener.id,
                    provisioning_status=constants.ERROR)
        db_listener = self._get_db_listener(session, db_listener.id)
        return self._convert_db_to_type(db_listener,
                                        listener_types.ListenerResponse)
コード例 #3
0
ファイル: listener.py プロジェクト: problemv/octavia
    def _validate_listener(self, session, lb_id, listener_dict):
        """Validate listener for wrong protocol or duplicate listeners

        Update the load balancer db when provisioning status changes.
        """
        lb_repo = self.repositories.load_balancer
        if (listener_dict and listener_dict.get('insert_headers') and list(
                set(listener_dict['insert_headers'].keys()) -
                set(constants.SUPPORTED_HTTP_HEADERS))):
            raise exceptions.InvalidOption(
                value=listener_dict.get('insert_headers'),
                option='insert_headers')

        try:
            sni_containers = listener_dict.pop('sni_containers', [])
            db_listener = self.repositories.listener.create(
                session, **listener_dict)
            if sni_containers:
                for container in sni_containers:
                    sni_dict = {
                        'listener_id': db_listener.id,
                        'tls_container_id': container.get('tls_container_id')
                    }
                    self.repositories.sni.create(session, **sni_dict)
                db_listener = self.repositories.listener.get(session,
                                                             id=db_listener.id)
            return db_listener
        except odb_exceptions.DBDuplicateEntry as de:
            # Setting LB back to active because this is just a validation
            # failure
            lb_repo.update(session,
                           lb_id,
                           provisioning_status=constants.ACTIVE)
            column_list = ['load_balancer_id', 'protocol_port']
            constraint_list = ['uq_listener_load_balancer_id_protocol_port']
            if ['id'] == de.columns:
                raise exceptions.IDAlreadyExists()
            elif (set(column_list) == set(de.columns)
                  or set(constraint_list) == set(de.columns)):
                raise exceptions.DuplicateListenerEntry(
                    port=listener_dict.get('protocol_port'))
        except odb_exceptions.DBError:
            # Setting LB back to active because this is just a validation
            # failure
            lb_repo.update(session,
                           lb_id,
                           provisioning_status=constants.ACTIVE)
            raise exceptions.InvalidOption(value=listener_dict.get('protocol'),
                                           option='protocol')
コード例 #4
0
    def _validate_create_listener(self, lock_session, listener_dict):
        """Validate listener for wrong protocol or duplicate listeners

        Update the load balancer db when provisioning status changes.
        """
        listener_protocol = listener_dict.get('protocol')

        if listener_dict and listener_dict.get('insert_headers'):
            self._validate_insert_headers(
                listener_dict['insert_headers'].keys(), listener_protocol)

        # Check for UDP compatibility
        if (listener_protocol == constants.PROTOCOL_UDP
                and self._is_tls_or_insert_header(listener_dict)):
            raise exceptions.ValidationException(
                detail=_("%s protocol listener does not support TLS or header "
                         "insertion.") % constants.PROTOCOL_UDP)

        # Check for TLS disabled
        if (not CONF.api_settings.allow_tls_terminated_listeners
                and listener_protocol == constants.PROTOCOL_TERMINATED_HTTPS):
            raise exceptions.DisabledOption(
                value=constants.PROTOCOL_TERMINATED_HTTPS, option='protocol')

        # Check for certs when not TERMINATED_HTTPS
        if (listener_protocol != constants.PROTOCOL_TERMINATED_HTTPS
                and self._has_tls_container_refs(listener_dict)):
            raise exceptions.ValidationException(
                detail=_(
                    "Certificate container references are only allowed on "
                    "%s protocol listeners.") %
                constants.PROTOCOL_TERMINATED_HTTPS)

        # Make sure a base certificate exists if specifying a client ca
        if (listener_dict.get('client_ca_tls_certificate_id')
                and not (listener_dict.get('tls_certificate_id')
                         or listener_dict.get('sni_containers'))):
            raise exceptions.ValidationException(detail=_(
                "An SNI or default certificate container reference must "
                "be provided with a client CA container reference."))

        # Make sure a certificate container is specified for TERMINATED_HTTPS
        if (listener_protocol == constants.PROTOCOL_TERMINATED_HTTPS
                and not (listener_dict.get('tls_certificate_id')
                         or listener_dict.get('sni_containers'))):
            raise exceptions.ValidationException(
                detail=_(
                    "An SNI or default certificate container reference must "
                    "be provided for %s protocol listeners.") %
                constants.PROTOCOL_TERMINATED_HTTPS)

        # Make sure we have a client CA cert if they enable client auth
        if (listener_dict.get('client_authentication') !=
                constants.CLIENT_AUTH_NONE
                and not listener_dict.get('client_ca_tls_certificate_id')):
            raise exceptions.ValidationException(
                detail=_(
                    "Client authentication setting %s requires a client CA "
                    "container reference.") %
                listener_dict.get('client_authentication'))

        # Make sure we have a client CA if they specify a CRL
        if (listener_dict.get('client_crl_container_id')
                and not listener_dict.get('client_ca_tls_certificate_id')):
            raise exceptions.ValidationException(
                detail=_("A client authentication CA reference is required to "
                         "specify a client authentication revocation list."))

        # Validate the TLS containers
        sni_containers = listener_dict.pop('sni_containers', [])
        tls_refs = [sni['tls_container_id'] for sni in sni_containers]
        if listener_dict.get('tls_certificate_id'):
            tls_refs.append(listener_dict.get('tls_certificate_id'))
        self._validate_tls_refs(tls_refs)

        # Validate the client CA cert and optional client CRL
        if listener_dict.get('client_ca_tls_certificate_id'):
            self._validate_client_ca_and_crl_refs(
                listener_dict.get('client_ca_tls_certificate_id'),
                listener_dict.get('client_crl_container_id', None))

        try:
            db_listener = self.repositories.listener.create(
                lock_session, **listener_dict)
            if sni_containers:
                for container in sni_containers:
                    sni_dict = {
                        'listener_id': db_listener.id,
                        'tls_container_id': container.get('tls_container_id')
                    }
                    self.repositories.sni.create(lock_session, **sni_dict)
                db_listener = self.repositories.listener.get(lock_session,
                                                             id=db_listener.id)
            return db_listener
        except odb_exceptions.DBDuplicateEntry as de:
            column_list = ['load_balancer_id', 'protocol_port']
            constraint_list = ['uq_listener_load_balancer_id_protocol_port']
            if ['id'] == de.columns:
                raise exceptions.IDAlreadyExists()
            elif (set(column_list) == set(de.columns)
                  or set(constraint_list) == set(de.columns)):
                raise exceptions.DuplicateListenerEntry(
                    port=listener_dict.get('protocol_port'))
        except odb_exceptions.DBError:
            raise exceptions.InvalidOption(value=listener_dict.get('protocol'),
                                           option='protocol')
コード例 #5
0
ファイル: listener.py プロジェクト: jayofdoom/octavia
    def _validate_create_listener(self, lock_session, listener_dict):
        """Validate listener for wrong protocol or duplicate listeners

        Update the load balancer db when provisioning status changes.
        """
        listener_protocol = listener_dict.get('protocol')

        if listener_dict and listener_dict.get('insert_headers'):
            self._validate_insert_headers(
                listener_dict['insert_headers'].keys(), listener_protocol)

        # Check for UDP compatibility
        if (listener_protocol == constants.PROTOCOL_UDP and
                self._is_tls_or_insert_header(listener_dict)):
            raise exceptions.ValidationException(detail=_(
                "%s protocol listener does not support TLS or header "
                "insertion.") % constants.PROTOCOL_UDP)

        # Check for TLS disabled
        if (not CONF.api_settings.allow_tls_terminated_listeners and
                listener_protocol == constants.PROTOCOL_TERMINATED_HTTPS):
            raise exceptions.DisabledOption(
                value=constants.PROTOCOL_TERMINATED_HTTPS, option='protocol')

        # Check for certs when not TERMINATED_HTTPS
        if (listener_protocol != constants.PROTOCOL_TERMINATED_HTTPS and
                self._has_tls_container_refs(listener_dict)):
            raise exceptions.ValidationException(detail=_(
                "Certificate container references are only allowed on "
                "%s protocol listeners.") %
                constants.PROTOCOL_TERMINATED_HTTPS)

        # Make sure a base certificate exists if specifying a client ca
        if (listener_dict.get('client_ca_tls_certificate_id') and
            not (listener_dict.get('tls_certificate_id') or
                 listener_dict.get('sni_containers'))):
            raise exceptions.ValidationException(detail=_(
                "An SNI or default certificate container reference must "
                "be provided with a client CA container reference."))

        # Make sure a certificate container is specified for TERMINATED_HTTPS
        if (listener_protocol == constants.PROTOCOL_TERMINATED_HTTPS and
            not (listener_dict.get('tls_certificate_id') or
                 listener_dict.get('sni_containers'))):
            raise exceptions.ValidationException(detail=_(
                "An SNI or default certificate container reference must "
                "be provided for %s protocol listeners.") %
                constants.PROTOCOL_TERMINATED_HTTPS)

        # Make sure we have a client CA cert if they enable client auth
        if (listener_dict.get('client_authentication') !=
            constants.CLIENT_AUTH_NONE and not
                listener_dict.get('client_ca_tls_certificate_id')):
            raise exceptions.ValidationException(detail=_(
                "Client authentication setting %s requires a client CA "
                "container reference.") %
                listener_dict.get('client_authentication'))

        # Make sure we have a client CA if they specify a CRL
        if (listener_dict.get('client_crl_container_id') and
                not listener_dict.get('client_ca_tls_certificate_id')):
            raise exceptions.ValidationException(detail=_(
                "A client authentication CA reference is required to "
                "specify a client authentication revocation list."))

        # Validate the TLS containers
        sni_containers = listener_dict.pop('sni_containers', [])
        tls_refs = [sni['tls_container_id'] for sni in sni_containers]
        if listener_dict.get('tls_certificate_id'):
            tls_refs.append(listener_dict.get('tls_certificate_id'))
        self._validate_tls_refs(tls_refs)

        # Validate the client CA cert and optional client CRL
        if listener_dict.get('client_ca_tls_certificate_id'):
            self._validate_client_ca_and_crl_refs(
                listener_dict.get('client_ca_tls_certificate_id'),
                listener_dict.get('client_crl_container_id', None))

        # Validate that the L4 protocol (UDP or TCP) is not already used for
        # the specified protocol_port in this load balancer
        pcontext = pecan.request.context
        query_filter = {
            'project_id': listener_dict['project_id'],
            'load_balancer_id': listener_dict['load_balancer_id'],
            'protocol_port': listener_dict['protocol_port']
        }

        # Get listeners on the same load balancer that use the same
        # protocol port
        db_listeners = self.repositories.listener.get_all_API_list(
            lock_session, show_deleted=False,
            pagination_helper=pcontext.get(constants.PAGINATION_HELPER),
            **query_filter)[0]

        if db_listeners:
            l4_protocol = constants.L4_PROTOCOL_MAP[listener_protocol]

            # List supported protocols that share the same L4 protocol as our
            # new listener
            disallowed_protocols = [
                p
                for p in constants.L4_PROTOCOL_MAP
                if constants.L4_PROTOCOL_MAP[p] == l4_protocol
            ]

            for db_l in db_listeners:
                # Check if l4 protocol ports conflict
                if db_l.protocol in disallowed_protocols:
                    raise exceptions.DuplicateListenerEntry(
                        protocol=db_l.protocol,
                        port=listener_dict.get('protocol_port'))

        # Validate allowed CIDRs
        allowed_cidrs = listener_dict.get('allowed_cidrs', []) or []
        lb_id = listener_dict.get('load_balancer_id')
        vip_db = self.repositories.vip.get(
            lock_session, load_balancer_id=lb_id)
        vip_address = vip_db.ip_address
        self._validate_cidr_compatible_with_vip(vip_address, allowed_cidrs)

        try:
            db_listener = self.repositories.listener.create(
                lock_session, **listener_dict)
            if sni_containers:
                for container in sni_containers:
                    sni_dict = {'listener_id': db_listener.id,
                                'tls_container_id': container.get(
                                    'tls_container_id')}
                    self.repositories.sni.create(lock_session, **sni_dict)
                # DB listener needs to be refreshed
                db_listener = self.repositories.listener.get(
                    lock_session, id=db_listener.id)

            return db_listener
        except odb_exceptions.DBDuplicateEntry as de:
            column_list = ['load_balancer_id', 'protocol', 'protocol_port']
            constraint_list = ['uq_listener_load_balancer_id_protocol_port']
            if ['id'] == de.columns:
                raise exceptions.IDAlreadyExists()
            if (set(column_list) == set(de.columns) or
                    set(constraint_list) == set(de.columns)):
                raise exceptions.DuplicateListenerEntry(
                    protocol=listener_dict.get('protocol'),
                    port=listener_dict.get('protocol_port'))
        except odb_exceptions.DBError:
            raise exceptions.InvalidOption(value=listener_dict.get('protocol'),
                                           option='protocol')