Пример #1
0
    def test_existing_resource_of_many(self):
        sms = {}
        for resource_id in ['5678', 'ABCD', 'EFGH']:
            r = event.Resource(
                tenant_id=self.tenant_id,
                id=resource_id,
                driver=router.Router.RESOURCE_NAME,
            )
            msg = event.Event(
                resource=r,
                crud=event.CREATE,
                body={'key': 'value'},
            )
            # First time creates...
            sm1 = self.trm.get_state_machines(msg, self.ctx)[0]
            sms[resource_id] = sm1

        # Second time should return the same objects...
        r = event.Resource(
            id='5678',
            tenant_id=self.tenant_id,
            driver=router.Router.RESOURCE_NAME,
        )
        msg = event.Event(
            resource=r,
            crud=event.CREATE,
            body={'key': 'value'},
        )
        sm2 = self.trm.get_state_machines(msg, self.ctx)[0]
        self.assertIs(sm2, sms['5678'])
Пример #2
0
    def setUp(self):
        super(TestWildcardMessages, self).setUp()

        self.tenant_id_1 = 'a8f964d4-6631-11e5-a79f-525400cfc32a'
        self.tenant_id_2 = 'ef1a6e90-6631-11e5-83cb-525400cfc326'
        self.w._should_process_message = mock.MagicMock(return_value=self.msg)

        # Create some tenants
        for msg in [
                event.Event(
                    resource=event.Resource(
                        driver=router.Router.RESOURCE_NAME,
                        id='ABCD',
                        tenant_id=self.tenant_id_1,
                    ),
                    crud=event.CREATE,
                    body={'key': 'value'},
                ),
                event.Event(
                    resource=event.Resource(driver=router.Router.RESOURCE_NAME,
                                            id='EFGH',
                                            tenant_id=self.tenant_id_2),
                    crud=event.CREATE,
                    body={'key': 'value'},
                )
        ]:
            self.w.handle_message(msg.resource.tenant_id, msg)
Пример #3
0
 def test__should_process_no_router_id(self, fake_hash):
     fake_ring_manager = fake_hash.HashRingManager()
     fake_ring_manager.ring.get_hosts.return_value = [self.w.host]
     self.w.hash_ring_mgr = fake_ring_manager
     self.fake_cache.get_by_tenant.return_value = (
         '9846d012-3c75-11e5-b476-8321b3ff1a1d')
     r = event.Resource(
         driver=router.Router.RESOURCE_NAME,
         id=None,
         tenant_id='fake_tenant_id',
     )
     expected_r = event.Resource(
         driver=router.Router.RESOURCE_NAME,
         id='9846d012-3c75-11e5-b476-8321b3ff1a1d',
         tenant_id='fake_tenant_id',
     )
     msg = event.Event(
         resource=r,
         crud=event.CREATE,
         body={'key': 'value'},
     )
     expected = event.Event(
         resource=expected_r,
         crud=event.CREATE,
         body={'key': 'value'},
     )
     self.assertEqual(expected,
                      self.w._should_process_message(self.target, msg))
Пример #4
0
    def pre_populate_hook():
        """Fetch the existing LBs from neutron then and returns list back
        to populate to be distributed to workers.

        Wait for neutron to return the list of the existing LBs.
        Pause up to max_sleep seconds between each attempt and ignore
        neutron client exceptions.

        """
        nap_time = 1

        neutron_client = neutron.Neutron(cfg.CONF)

        while True:
            try:
                resources = []
                for lb in neutron_client.get_loadbalancers():
                    resources.append(
                        event.Resource(driver=LoadBalancer.RESOURCE_NAME,
                                       id=lb.id,
                                       tenant_id=lb.tenant_id))

                return resources
            except (q_exceptions.Unauthorized, q_exceptions.Forbidden) as err:
                LOG.warning(_LW('PrePopulateWorkers thread failed: %s'), err)
                return
            except Exception as err:
                LOG.warning(
                    _LW('Could not fetch loadbalancers from neutron: %s'), err)
                LOG.warning(_LW('sleeping %s seconds before retrying'),
                            nap_time)
                time.sleep(nap_time)
                nap_time = min(nap_time * 2,
                               cfg.CONF.astara_appliance.max_sleep)
Пример #5
0
    def test__repopulate_sm_added(self, fake_repopulate):
        fake_ring = mock.Mock(get_hosts=mock.Mock())
        fake_hash = mock.Mock(ring=fake_ring)
        self.w.hash_ring_mgr = fake_hash

        rsc1 = event.Resource(
            driver='router',
            tenant_id='79f418c8-a849-11e5-9c36-df27538e1b7e',
            id='7f2a1d56-a849-11e5-a0ce-a74ef0b18fa1',
        )
        rsc2 = event.Resource(
            driver='router',
            tenant_id='8d55fdb4-a849-11e5-958f-0b870649546d',
            id='9005cd5a-a849-11e5-a434-27c4c7c70a8b',
        )
        rsc3 = event.Resource(
            driver='router',
            tenant_id='455549a4-a851-11e5-a060-df26a5877746',
            id='4a05c758-a851-11e5-bf9f-0387cfcb8f9b',
        )

        resources = [rsc1, rsc2, rsc3]

        # create initial, pre-rebalance state machines
        for r in resources[:-1]:
            for trm in self.w._get_trms(r.tenant_id):
                e = event.Event(resource=r, crud=None, body={})
                trm.get_state_machines(e, self.w._context)

        fake_hash.ring.get_hosts.side_effect = [
            self.fake_host, self.fake_host, self.fake_host
        ]
        fake_repopulate.return_value = resources

        # mock doesn't like to have its .name overwritten?
        class FakeWorker(object):
            name = self.w.proc_name

        tgt = [{'worker': FakeWorker()}]

        self.w.scheduler.dispatcher.pick_workers = mock.Mock(return_value=tgt)
        self.w._repopulate()
        post_rebalance_sms = self.w._get_all_state_machines()
        self.assertEqual(len(post_rebalance_sms), 3)
        rids = [r.id for r in resources]
        for sm in post_rebalance_sms:
            self.assertIn(sm.resource_id, rids)
Пример #6
0
    def router_deleted(self, ctxt, router_id):
        tenant_id = _get_tenant_id_for_message(ctxt)

        resource = event.Resource('router', router_id, tenant_id)

        crud = event.DELETE
        e = event.Event(resource, crud, None)
        self.notification_queue.put((e.resource.tenant_id, e))
Пример #7
0
 def test_delete_not_default_resource(self):
     r = event.Resource(id='1234',
                        tenant_id=self.tenant_id,
                        driver=router.Router.RESOURCE_NAME)
     self.trm._default_resource_id = 'abcd'
     self.trm.state_machines['1234'] = mock.Mock()
     self.trm._delete_resource(r)
     self.assertEqual('abcd', self.trm._default_resource_id)
Пример #8
0
 def test_delete_default_resource(self):
     r = event.Resource(id='1234',
                        tenant_id=self.tenant_id,
                        driver=router.Router.RESOURCE_NAME)
     self.trm._default_resource_id = '1234'
     self.trm.state_machines['1234'] = mock.Mock()
     self.trm._delete_resource(r)
     self.assertNotIn('1234', self.trm.state_machines)
     self.assertIs(None, self.trm._default_resource_id)
Пример #9
0
 def test_delete_resource(self):
     r = event.Resource(
         id='1234',
         tenant_id=self.tenant_id,
         driver=router.Router.RESOURCE_NAME,
     )
     self.trm.state_machines['1234'] = mock.Mock()
     self.trm._delete_resource(r)
     self.assertNotIn('1234', self.trm.state_machines)
     self.assertTrue(self.deleter.called)
Пример #10
0
 def test_process_notification_router_delete(self):
     payload = {'router_id': 'fake_router_id'}
     r = event.Resource(driver=router.Router.RESOURCE_NAME,
                        id='fake_router_id',
                        tenant_id='fake_tenant_id')
     e = event.Event(
         resource=r,
         crud=event.DELETE,
         body=payload,
     )
     self._test_notification('router.delete.end', payload, e)
Пример #11
0
    def process_notification(tenant_id, event_type, payload):
        """Process an incoming notification event

        This gets called from the notifications layer to determine whether
        this driver should process an incoming notification event. It is
        responsible for translating an incoming notificatino to an Event
        object appropriate for this driver.

        :param tenant_id: str The UUID tenant_id for the incoming event
        :param event_type: str event type, for example loadbalancer.create.end
        :param payload: The payload body of the incoming event

        :returns: A populated Event objet if it should process, or None if not
        """
        if event_type.startswith('loadbalancerstatus.update'):
            # these are generated when we sync state
            return
        lb_id = (payload.get('loadbalancer', {}).get('id')
                 or payload.get('listener', {}).get('loadbalancer_id')
                 or payload.get('loadbalancer_id'))

        update_notifications = [
            'listener.create.start',
            'pool.create.start',
            'member.create.end',
            'member.delete.end',
        ]

        # some events do not contain a lb id.
        if not lb_id and event_type not in update_notifications:
            return

        if event_type == 'loadbalancer.create.end':
            crud = event.CREATE
        elif event_type == 'loadbalancer.delete.end':
            crud = event.DELETE
        elif event_type in update_notifications:
            crud = event.UPDATE
        else:
            crud = None

        if not crud:
            LOG.info('Could not determine CRUD for event: %s ', event_type)
            return

        resource = event.Resource(driver=LoadBalancer.RESOURCE_NAME,
                                  id=lb_id,
                                  tenant_id=tenant_id)
        e = event.Event(
            resource=resource,
            crud=crud,
            body=payload,
        )
        return e
Пример #12
0
 def test_process_notification_lb_delete(self):
     payload = {'loadbalancer': {'id': 'fake_lb_id'}}
     r = event.Resource(
         driver=loadbalancer.LoadBalancer.RESOURCE_NAME,
         id='fake_lb_id',
         tenant_id='fake_tenant_id')
     e = event.Event(
         resource=r,
         crud=event.DELETE,
         body=payload,
     )
     self._test_notification('loadbalancer.delete.end', payload, e)
Пример #13
0
 def test_process_notification_interesting_notifications(self):
     for notification in router._ROUTER_INTERESTING_NOTIFICATIONS:
         payload = {'router': {'id': 'fake_router_id'}}
         r = event.Resource(driver=router.Router.RESOURCE_NAME,
                            id='fake_router_id',
                            tenant_id='fake_tenant_id')
         e = event.Event(
             resource=r,
             crud=event.UPDATE,
             body=payload,
         )
         self._test_notification(notification, payload, e)
Пример #14
0
    def test_cluster_changed(self, fake_members, fake_start):
        fake_members.__get__ = mock.Mock(return_value=['foo', 'bar'])
        self.coordinator = coordination.RugCoordinator(self.queue)
        expected_rebalance_event = event.Event(
            resource=event.Resource('*', '*', '*'),
            crud=event.REBALANCE,
            body={'members': ['foo', 'bar']})

        self.coordinator.cluster_changed(event=None)
        expected = ('*', expected_rebalance_event)
        res = self.queue.get()
        self.assertEqual(res, expected)
Пример #15
0
 def test__should_process_command_debug_config(self):
     for cmd in [commands.WORKERS_DEBUG, commands.CONFIG_RELOAD]:
         r = event.Resource(
             tenant_id=self.tenant_id,
             id=self.router_id,
             driver='router',
         )
         msg = event.Event(
             resource=r,
             crud=event.COMMAND,
             body={'command': cmd},
         )
         self.assertTrue(self.w._should_process_command(msg))
Пример #16
0
 def test_get_state_machine_no_resoruce_id(self):
     r = event.Resource(
         tenant_id=self.tenant_id,
         id=None,
         driver=router.Router.RESOURCE_NAME,
     )
     msg = event.Event(
         resource=r,
         crud=event.CREATE,
         body={'key': 'value'},
     )
     self.assertRaises(tenant.InvalidIncomingMessage,
                       self.trm.get_state_machines, msg, self.ctx)
Пример #17
0
 def test__should_process_no_router_id_no_router_found(self):
     self.fake_cache.get_by_tenant.return_value = None
     r = event.Resource(
         driver=router.Router.RESOURCE_NAME,
         id=None,
         tenant_id='fake_tenant_id',
     )
     msg = event.Event(
         resource=r,
         crud=event.CREATE,
         body={'key': 'value'},
     )
     self.assertFalse(self.w._should_process_message(self.target, msg))
Пример #18
0
    def info(self, ctxt, publisher_id, event_type, payload, metadata):
        tenant_id = _get_tenant_id_for_message(ctxt, payload)
        crud = event.UPDATE
        e = None
        events = []
        if event_type.startswith('astara.command'):
            LOG.debug('received a command: %r', payload)
            crud = event.COMMAND
            if payload.get('command') == commands.POLL:
                r = event.Resource(driver='*', id='*', tenant_id='*')
                e = event.Event(resource=r, crud=event.POLL, body={})
                self.notification_queue.put(('*', e))
                return
            else:
                # If the message does not specify a tenant, send it to everyone
                tenant_id = payload.get('tenant_id', '*')
                router_id = payload.get('router_id')
                resource = event.Resource(driver='*',
                                          id=router_id,
                                          tenant_id=tenant_id)
                events.append(event.Event(resource, crud, payload))
        else:

            for driver in drivers.enabled_drivers():
                driver_event = driver.process_notification(
                    tenant_id, event_type, payload)
                if driver_event:
                    events.append(driver_event)

        if not events:
            LOG.debug('Could not construct any events from %s /w payload: %s',
                      event_type, payload)
            return

        LOG.debug('Generated %s events from %s /w payload: %s', len(events),
                  event_type, payload)

        for e in events:
            self.notification_queue.put((e.resource.tenant_id, e))
Пример #19
0
 def test_no_update_deleted_resource(self):
     r = event.Resource(
         tenant_id='1234',
         id='5678',
         driver=router.Router.RESOURCE_NAME,
     )
     self.trm._default_resource_id = 'abcd'
     self.trm.state_machines['5678'] = mock.Mock()
     self.trm._delete_resource(r)
     self.assertEqual(self.trm.state_machines.values(), [])
     r = event.Resource(
         tenant_id='1234',
         id='5678',
         driver=router.Router.RESOURCE_NAME,
     )
     msg = event.Event(
         resource=r,
         crud=event.CREATE,
         body={'key': 'value'},
     )
     sms = self.trm.get_state_machines(msg, self.ctx)
     self.assertEqual(sms, [])
     self.assertIn('5678', self.trm.state_machines.deleted)
Пример #20
0
    def setUp(self):
        super(TestRebalance, self).setUp()
        self.fake_host = 'fake_host'
        self.w.host = 'fake_host'
        self.resource_id = '56232034-a852-11e5-854e-035a3632659f'
        self.tenant_id = '601128de-a852-11e5-a09d-cf6fa26e6e6b'

        self.resource = event.Resource('router', self.resource_id,
                                       self.tenant_id)
        self.msg = event.Event(
            resource=self.resource,
            crud=None,
            body={'key': 'value'},
        )
Пример #21
0
    def setUp(self):
        super(TestCreatingResource, self).setUp()
        self.tenant_id = '98dd9c41-d3ac-4fd6-8927-567afa0b8fc3'
        self.router_id = 'ac194fc5-f317-412e-8611-fb290629f624'
        self.hostname = 'astara'

        self.resource = event.Resource(router.Router.RESOURCE_NAME,
                                       self.router_id, self.tenant_id)

        self.msg = event.Event(
            resource=self.resource,
            crud=event.CREATE,
            body={'key': 'value'},
        )
        self.w._should_process_message = mock.MagicMock(return_value=self.msg)
Пример #22
0
 def test_deleter_callback(self):
     r = event.Resource(
         tenant_id='1234',
         id='5678',
         driver=router.Router.RESOURCE_NAME,
     )
     msg = event.Event(
         resource=r,
         crud=event.CREATE,
         body={'key': 'value'},
     )
     sm = self.trm.get_state_machines(msg, self.ctx)[0]
     self.assertIn('5678', self.trm.state_machines)
     sm._do_delete()
     self.assertNotIn('5678', self.trm.state_machines)
     self.assertTrue(self.trm.state_machines.has_been_deleted('5678'))
Пример #23
0
 def test_new_resource(self):
     r = event.Resource(
         tenant_id=self.tenant_id,
         id='5678',
         driver=router.Router.RESOURCE_NAME,
     )
     msg = event.Event(
         resource=r,
         crud=event.CREATE,
         body={'key': 'value'},
     )
     self.fake_load_resource.return_value = fakes.fake_driver(
         resource_id='5678')
     sm = self.trm.get_state_machines(msg, self.ctx)[0]
     self.assertEqual(sm.resource_id, '5678')
     self.assertIn('5678', self.trm.state_machines)
Пример #24
0
 def test_resource_cache_miss(self):
     r = event.Resource(
         tenant_id='fake_tenant_id',
         id='fake_fetched_resource_id',
         driver=router.Router.RESOURCE_NAME,
     )
     msg = event.Event(
         resource=r,
         crud=event.UPDATE,
         body={},
     )
     res = self.resource_cache.get_by_tenant(
         resource=r, worker_context=self.worker_context, message=msg)
     self.assertEqual(res, 'fake_fetched_resource_id')
     self.w._context.neutron.get_router_for_tenant.assert_called_with(
         'fake_tenant_id')
Пример #25
0
 def test_resource_cache_hit(self):
     self.resource_cache._tenant_resources = {
         router.Router.RESOURCE_NAME: {
             'fake_tenant_id': 'fake_cached_resource_id',
         }
     }
     r = event.Resource(
         tenant_id='fake_tenant_id',
         id='fake_resource_id',
         driver=router.Router.RESOURCE_NAME,
     )
     msg = event.Event(resource=r, crud=event.UPDATE, body={})
     res = self.resource_cache.get_by_tenant(
         resource=r, worker_context=self.worker_context, message=msg)
     self.assertEqual(res, 'fake_cached_resource_id')
     self.assertFalse(self.w._context.neutron.get_router_for_tenant.called)
Пример #26
0
 def test_notification_cmd_poll(self):
     event_type = 'astara.command'
     payload = {'command': commands.POLL}
     self.notifications_endpoint.info(ctxt=CTXT,
                                      publisher_id='network.astara',
                                      event_type=event_type,
                                      payload=payload,
                                      metadata={})
     expected_event = event.Event(
         resource=event.Resource(driver='*', id='*', tenant_id='*'),
         crud=event.POLL,
         body={},
     )
     tenant, e = self.queue.get()
     self.assertEqual('*', tenant)
     self.assertEqual(expected_event, e)
Пример #27
0
    def process_notification(tenant_id, event_type, payload):
        """Process an incoming notification event

        This gets called from the notifications layer to determine whether
        this driver should process an incoming notification event. It is
        responsible for translating an incoming notificatino to an Event
        object appropriate for this driver.

        :param tenant_id: str The UUID tenant_id for the incoming event
        :param event_type: str event type, for example router.create.end
        :param payload: The payload body of the incoming event

        :returns: A populated Event objet if it should process, or None if not
        """
        router_id = payload.get('router', {}).get('id')
        crud = event.UPDATE

        if event_type.startswith('routerstatus.update'):
            # We generate these events ourself, so ignore them.
            return

        if event_type == 'router.create.end':
            crud = event.CREATE
        elif event_type == 'router.delete.end':
            crud = event.DELETE
            router_id = payload.get('router_id')
        elif event_type in _ROUTER_INTERFACE_NOTIFICATIONS:
            crud = event.UPDATE
            router_id = payload.get('router.interface', {}).get('id')
        elif event_type in _ROUTER_INTERESTING_NOTIFICATIONS:
            crud = event.UPDATE
        elif cfg.CONF.router.ipsec_vpn and event_type in _VPN_NOTIFICATIONS:
            crud = event.UPDATE
        else:
            LOG.debug('Not processing event: %s' % event_type)
            return

        resource = event.Resource(driver=DRIVER_NAME,
                                  id=router_id,
                                  tenant_id=tenant_id)
        e = event.Event(
            resource=resource,
            crud=crud,
            body=payload,
        )
        return e
Пример #28
0
 def test_existing_resource(self):
     r = event.Resource(
         tenant_id=self.tenant_id,
         id='5678',
         driver=router.Router.RESOURCE_NAME,
     )
     msg = event.Event(
         resource=r,
         crud=event.CREATE,
         body={'key': 'value'},
     )
     # First time creates...
     sm1 = self.trm.get_state_machines(msg, self.ctx)[0]
     # Second time should return the same objects...
     sm2 = self.trm.get_state_machines(msg, self.ctx)[0]
     self.assertIs(sm1, sm2)
     self.assertIs(sm1._queue, sm2._queue)
Пример #29
0
def _health_inspector(scheduler):
    """Runs in the thread.
    """
    period = CONF.health_check_period
    while True:
        time.sleep(period)
        LOG.debug('waking up')
        r = event.Resource(
            id='*',
            tenant_id='*',
            driver='*',
        )
        e = event.Event(
            resource=r,
            crud=event.POLL,
            body={},
        )
        scheduler.handle_message('*', e)
Пример #30
0
 def test_resource_cache_delete(self):
     r = event.Resource(
         tenant_id='fake_tenant_id',
         id='fake_fetched_resource_id',
         driver=router.Router.RESOURCE_NAME,
     )
     msg = event.Event(
         resource=r,
         crud=event.UPDATE,
         body={},
     )
     self.resource_cache.get_by_tenant(resource=r,
                                       worker_context=self.worker_context,
                                       message=msg)
     self.assertEqual(
         self.resource_cache._tenant_resources[r.driver][r.tenant_id], r.id)
     self.resource_cache.delete(r)
     self.assertNotIn(r.tenant_id,
                      self.resource_cache._tenant_resources[r.driver])