Пример #1
0
    def put(self, id, listener_):
        """Updates a listener on a load balancer."""
        listener = listener_.listener
        context = pecan_request.context.get('octavia_context')
        db_listener = self._get_db_listener(context.session,
                                            id,
                                            show_deleted=False)
        load_balancer_id = db_listener.load_balancer_id

        project_id, provider = self._get_lb_project_id_provider(
            context.session, load_balancer_id)

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

        self._validate_listener_PUT(listener, db_listener)

        self._set_default_on_none(listener)

        if listener.default_pool_id:
            self._validate_pool(context.session, load_balancer_id,
                                listener.default_pool_id, db_listener.protocol)

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

        with db_api.get_lock_session() as lock_session:
            self._test_lb_and_listener_statuses(lock_session,
                                                load_balancer_id,
                                                id=id)

            # Prepare the data for the driver data model
            listener_dict = listener.to_dict(render_unsets=False)
            listener_dict['id'] = id

            provider_listener_dict = (
                driver_utils.listener_dict_to_provider_dict(listener_dict))

            # Also prepare the baseline object data
            old_provider_listener = (
                driver_utils.db_listener_to_provider_listener(db_listener,
                                                              for_delete=True))

            # Dispatch to the driver
            LOG.info("Sending update Listener %s to provider %s", id,
                     driver.name)
            driver_utils.call_provider(
                driver.name, driver.listener_update, old_provider_listener,
                driver_dm.Listener.from_dict(provider_listener_dict))

            # Update the database to reflect what the driver just accepted
            self.repositories.listener.update(
                lock_session, id, **listener.to_dict(render_unsets=False))

        # Force SQL alchemy to query the DB, otherwise we get inconsistent
        # results
        context.session.expire_all()
        db_listener = self._get_db_listener(context.session, id)
        result = self._convert_db_to_type(db_listener,
                                          listener_types.ListenerResponse)
        return listener_types.ListenerRootResponse(listener=result)
Пример #2
0
 def test_listener_dict_to_provider_dict(self, mock_load_cert, mock_secret):
     mock_secret.side_effect = [
         'ca cert', 'X509 CRL FILE', 'X509 POOL CA CERT FILE',
         'X509 POOL CRL FILE'
     ]
     cert1 = data_models.TLSContainer(certificate='cert 1')
     cert2 = data_models.TLSContainer(certificate='cert 2')
     cert3 = data_models.TLSContainer(certificate='cert 3')
     listener_certs = {'tls_cert': cert1, 'sni_certs': [cert2, cert3]}
     pool_cert = data_models.TLSContainer(certificate='pool cert')
     pool_certs = {'tls_cert': pool_cert, 'sni_certs': []}
     mock_load_cert.side_effect = [listener_certs, pool_certs]
     # The reason to do this, as before the logic arrives the test func,
     # there are two data sources, one is from db_dict, the other is from
     # the api layer model_dict, actually, they are different and contain
     # different fields. That's why the test_listener1_dict from sample data
     # just contain the client_ca_tls_certificate_id for client certificate,
     # not any other related fields. So we need to delete them.
     expect_prov = copy.deepcopy(self.sample_data.provider_listener1_dict)
     expect_pool_prov = copy.deepcopy(self.sample_data.provider_pool1_dict)
     expect_prov['default_pool'] = expect_pool_prov
     provider_listener = utils.listener_dict_to_provider_dict(
         self.sample_data.test_listener1_dict)
     # TODO(johnsom) Remove this once the listener ACLs patch merges
     # https://review.opendev.org/#/c/659626/
     del expect_prov['allowed_cidrs']
     self.assertEqual(expect_prov, provider_listener)
Пример #3
0
    def put(self, id, listener_):
        """Updates a listener on a load balancer."""
        listener = listener_.listener
        context = pecan.request.context.get('octavia_context')
        db_listener = self._get_db_listener(context.session, id,
                                            show_deleted=False)
        load_balancer_id = db_listener.load_balancer_id

        project_id, provider = self._get_lb_project_id_provider(
            context.session, load_balancer_id)

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

        self._validate_listener_PUT(listener, db_listener)

        self._set_default_on_none(listener)

        if listener.default_pool_id:
            self._validate_pool(context.session, load_balancer_id,
                                listener.default_pool_id, db_listener.protocol)

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

        with db_api.get_lock_session() as lock_session:
            self._test_lb_and_listener_statuses(lock_session,
                                                load_balancer_id, id=id)

            # Prepare the data for the driver data model
            listener_dict = listener.to_dict(render_unsets=False)
            listener_dict['id'] = id
            provider_listener_dict = (
                driver_utils.listener_dict_to_provider_dict(listener_dict))

            # Also prepare the baseline object data
            old_provider_llistener = (
                driver_utils.db_listener_to_provider_listener(db_listener))

            # Dispatch to the driver
            LOG.info("Sending update Listener %s to provider %s", id,
                     driver.name)
            driver_utils.call_provider(
                driver.name, driver.listener_update,
                old_provider_llistener,
                driver_dm.Listener.from_dict(provider_listener_dict))

            # Update the database to reflect what the driver just accepted
            self.repositories.listener.update(
                lock_session, id, **listener.to_dict(render_unsets=False))

        # Force SQL alchemy to query the DB, otherwise we get inconsistent
        # results
        context.session.expire_all()
        db_listener = self._get_db_listener(context.session, id)
        result = self._convert_db_to_type(db_listener,
                                          listener_types.ListenerResponse)
        return listener_types.ListenerRootResponse(listener=result)
Пример #4
0
 def test_listener_dict_to_provider_dict(self, mock_load_cert):
     cert1 = data_models.TLSContainer(certificate='cert 1')
     cert2 = data_models.TLSContainer(certificate='cert 2')
     cert3 = data_models.TLSContainer(certificate='cert 3')
     mock_load_cert.return_value = {
         'tls_cert': cert1,
         'sni_certs': [cert2, cert3]
     }
     provider_listener = utils.listener_dict_to_provider_dict(
         self.sample_data.test_listener1_dict)
     self.assertEqual(self.sample_data.provider_listener1_dict,
                      provider_listener)
Пример #5
0
    def test_listener_dict_to_provider_dict_load_cert_error_for_delete(
            self, mock_load_cert, mock_secret):
        mock_secret.side_effect = ['ca cert', 'X509 CRL FILE',
                                   'X509 POOL CA CERT FILE',
                                   'X509 POOL CRL FILE']
        mock_load_cert.side_effect = [Exception]

        # Test load_cert exception for_delete == True path
        expect_prov = copy.deepcopy(self.sample_data.provider_listener1_dict)
        expect_pool_prov = copy.deepcopy(self.sample_data.provider_pool1_dict)
        del expect_pool_prov['tls_container_data']
        expect_prov['default_pool'] = expect_pool_prov
        del expect_prov['default_tls_container_data']
        del expect_prov['sni_container_data']
        provider_listener = utils.listener_dict_to_provider_dict(
            self.sample_data.test_listener1_dict, for_delete=True)
        self.assertEqual(expect_prov, provider_listener)
Пример #6
0
    def test_listener_dict_to_provider_dict_load_cert_error_for_delete(
            self, mock_load_cert, mock_secret):
        mock_secret.side_effect = [
            'ca cert', 'X509 CRL FILE', 'X509 POOL CA CERT FILE',
            'X509 POOL CRL FILE'
        ]
        mock_load_cert.side_effect = [Exception]

        # Test load_cert exception for_delete == True path
        expect_prov = copy.deepcopy(self.sample_data.provider_listener1_dict)
        expect_pool_prov = copy.deepcopy(self.sample_data.provider_pool1_dict)
        del expect_pool_prov['tls_container_data']
        # TODO(johnsom) Remove when versions and ciphers are implemented
        expect_pool_prov.pop(lib_constants.TLS_VERSIONS)
        expect_prov.pop(lib_constants.TLS_VERSIONS)
        expect_prov['default_pool'] = expect_pool_prov
        del expect_prov['default_tls_container_data']
        del expect_prov['sni_container_data']
        provider_listener = utils.listener_dict_to_provider_dict(
            self.sample_data.test_listener1_dict, for_delete=True)
        self.assertEqual(expect_prov, provider_listener)
Пример #7
0
 def test_listener_dict_to_provider_dict(self, mock_load_cert, mock_secret):
     mock_secret.side_effect = ['ca cert', 'X509 CRL FILE',
                                'X509 POOL CA CERT FILE',
                                'X509 POOL CRL FILE']
     cert1 = data_models.TLSContainer(certificate='cert 1')
     cert2 = data_models.TLSContainer(certificate='cert 2')
     cert3 = data_models.TLSContainer(certificate='cert 3')
     listener_certs = {'tls_cert': cert1, 'sni_certs': [cert2, cert3]}
     pool_cert = data_models.TLSContainer(certificate='pool cert')
     pool_certs = {'tls_cert': pool_cert, 'sni_certs': []}
     mock_load_cert.side_effect = [listener_certs, pool_certs]
     # The reason to do this, as before the logic arrives the test func,
     # there are two data sources, one is from db_dict, the other is from
     # the api layer model_dict, actually, they are different and contain
     # different fields. That's why the test_listener1_dict from sample data
     # just contain the client_ca_tls_certificate_id for client certificate,
     # not any other related fields. So we need to delete them.
     expect_prov = copy.deepcopy(self.sample_data.provider_listener1_dict)
     expect_pool_prov = copy.deepcopy(self.sample_data.provider_pool1_dict)
     expect_prov['default_pool'] = expect_pool_prov
     provider_listener = utils.listener_dict_to_provider_dict(
         self.sample_data.test_listener1_dict)
     self.assertEqual(expect_prov, provider_listener)
Пример #8
0
    def put(self, id, listener_):
        """Updates a listener on a load balancer."""
        listener = listener_.listener
        context = pecan.request.context.get('octavia_context')
        db_listener = self._get_db_listener(context.session, id,
                                            show_deleted=False)
        load_balancer_id = db_listener.load_balancer_id

        project_id, provider = self._get_lb_project_id_provider(
            context.session, load_balancer_id)

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

        # TODO(rm_work): Do we need something like this? What do we do on an
        # empty body for a PUT?
        if not listener:
            raise exceptions.ValidationException(
                detail='No listener object supplied.')

        if (db_listener.protocol == constants.PROTOCOL_UDP and
                self._is_tls_or_insert_header(listener)):
            raise exceptions.ValidationException(detail=_(
                "%s protocol listener does not support TLS or header "
                "insertion.") % constants.PROTOCOL_UDP)

        if listener.default_pool_id:
            self._validate_pool(context.session, load_balancer_id,
                                listener.default_pool_id, db_listener.protocol)

        sni_containers = listener.sni_container_refs or []
        tls_refs = [sni for sni in sni_containers]
        if listener.default_tls_container_ref:
            tls_refs.append(listener.default_tls_container_ref)
        self._validate_tls_refs(tls_refs)

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

        with db_api.get_lock_session() as lock_session:
            self._test_lb_and_listener_statuses(lock_session,
                                                load_balancer_id, id=id)

            # Prepare the data for the driver data model
            listener_dict = listener.to_dict(render_unsets=False)
            listener_dict['id'] = id
            provider_listener_dict = (
                driver_utils.listener_dict_to_provider_dict(listener_dict))

            # Also prepare the baseline object data
            old_provider_llistener = (
                driver_utils.db_listener_to_provider_listener(db_listener))

            # Dispatch to the driver
            LOG.info("Sending update Listener %s to provider %s", id,
                     driver.name)
            driver_utils.call_provider(
                driver.name, driver.listener_update,
                old_provider_llistener,
                driver_dm.Listener.from_dict(provider_listener_dict))

            # Update the database to reflect what the driver just accepted
            self.repositories.listener.update(
                lock_session, id, **listener.to_dict(render_unsets=False))

        # Force SQL alchemy to query the DB, otherwise we get inconsistent
        # results
        context.session.expire_all()
        db_listener = self._get_db_listener(context.session, id)
        result = self._convert_db_to_type(db_listener,
                                          listener_types.ListenerResponse)
        return listener_types.ListenerRootResponse(listener=result)