Ejemplo n.º 1
0
 def create(self, context, loadbalancer):
     super(LoadBalancerManager, self).create(context, loadbalancer)
     agent = self.driver.loadbalancer_scheduler.schedule(
         self.driver.plugin, context, loadbalancer,
         self.driver.device_driver)
     if not agent:
         raise lbaas_agentschedulerv2.NoEligibleLbaasAgent(
             loadbalancer_id=loadbalancer.id)
     self.driver.agent_rpc.create_loadbalancer(
         context, loadbalancer, agent['host'], self.driver.device_driver)
Ejemplo n.º 2
0
def test_mgr__call_rpc_no_eligible_agent_exception(mock_log,
                                                   happy_path_driver):
    mock_driver, mock_ctx = happy_path_driver
    pol_mgr = dv2.L7PolicyManager(mock_driver)
    pol_mgr._setup_crud = mock.MagicMock(
        name='mock_setup_crud',
        side_effect=lbaas_agentschedulerv2.NoEligibleLbaasAgent(
            loadbalancer_id='test_lb'))
    fake_pol = FakePolicy(id='test_lb')
    pol_mgr.delete(mock_ctx, fake_pol)
    assert mock_log.error.call_args == mock.call(
        'Exception: delete_l7policy: No eligible agent found for '
        'loadbalancer test_lb.')
Ejemplo n.º 3
0
def test_lbmgr_delete_no_eligible_agent_exception(mock_log):
    mock_driver = mock.MagicMock(name='mock_driver')
    mock_driver.agent_rpc.delete_loadbalancer.side_effect = \
        lbaas_agentschedulerv2.NoEligibleLbaasAgent(loadbalancer_id='test_lb')
    lb_mgr = dv2.LoadBalancerManager(mock_driver)
    mock_ctx = mock.MagicMock(name='mock_context')
    fake_lb = FakeLB(id='test_lb')
    lb_mgr.delete(mock_ctx, fake_lb)
    assert mock_log.error.call_args == mock.call(
        'Exception: loadbalancer delete: No eligible agent found for '
        'loadbalancer test_lb.')
    assert mock_driver.plugin.db.delete_loadbalancer.call_args == \
        mock.call(mock_ctx, 'test_lb')
Ejemplo n.º 4
0
def test_lbmgr_update_no_eligible_agent_exception(mock_log):
    mock_driver = mock.MagicMock(name='mock_driver')
    mock_driver.agent_rpc.update_loadbalancer.side_effect = \
        lbaas_agentschedulerv2.NoEligibleLbaasAgent(loadbalancer_id='new_lb')
    lb_mgr = dv2.LoadBalancerManager(mock_driver)
    mock_ctx = mock.MagicMock(name='mock_context')
    old_lb = FakeLB(id='old_lb')
    new_lb = FakeLB(id='new_lb')
    lb_mgr.update(mock_ctx, old_lb, new_lb)
    assert mock_log.error.call_args == mock.call(
        'Exception: loadbalancer update: No eligible agent found for '
        'loadbalancer new_lb.')
    assert mock_driver._handle_driver_error.call_args == \
        mock.call(mock_ctx, models.LoadBalancer, 'new_lb', 'ERROR')
Ejemplo n.º 5
0
    def schedule(self, plugin, context, loadbalancer_id, env=None):
        """Schedule the loadbalancer to an active loadbalancer agent.

        If there is no enabled agent hosting it.
        """

        with context.session.begin(subtransactions=True):
            loadbalancer = plugin.db.get_loadbalancer(context, loadbalancer_id)
            # If the loadbalancer is hosted on an active agent
            # already, return that agent or one in its env
            lbaas_agent = self.get_lbaas_agent_hosting_loadbalancer(
                plugin,
                context,
                loadbalancer.id,
                env
            )

            if lbaas_agent:
                lbaas_agent = lbaas_agent['agent']
                LOG.debug(' Assigning task to agent %s.'
                          % (lbaas_agent['id']))
                return lbaas_agent

            # There is no existing loadbalancer agent binding.
            # Find all active agent candidates in this env.
            # We use environment_prefix to find F5® agents
            # rather then map to the agent binary name.
            candidates = self.get_agents_in_env(
                context,
                plugin,
                env,
                active=True
            )

            LOG.debug("candidate agents: %s", candidates)
            if len(candidates) == 0:
                LOG.error('No f5 lbaas agents are active for env %s' % env)
                raise lbaas_agentschedulerv2.NoActiveLbaasAgent(
                    loadbalancer_id=loadbalancer.id)

            # We have active candidates to choose from.
            # Qualify them by tenant affinity and then capacity.
            chosen_agent = None
            agents_by_group = defaultdict(list)
            capacity_by_group = {}

            for candidate in candidates:
                # Organize agents by their environment group
                # and collect each group's max capacity.
                ac = self.deserialize_agent_configurations(
                    candidate['configurations']
                )
                gn = 1
                if 'environment_group_number' in ac:
                    gn = ac['environment_group_number']
                agents_by_group[gn].append(candidate)

                # populate each group's capacity
                group_capacity = self.get_capacity(ac)
                if gn not in capacity_by_group:
                    capacity_by_group[gn] = group_capacity
                else:
                    if group_capacity > capacity_by_group[gn]:
                        capacity_by_group[gn] = group_capacity

                # Do we already have this tenant assigned to this
                # agent candidate? If we do and it has capacity
                # then assign this loadbalancer to this agent.
                assigned_lbs = plugin.db.list_loadbalancers_on_lbaas_agent(
                    context, candidate['id'])
                for assigned_lb in assigned_lbs:
                    if loadbalancer.tenant_id == assigned_lb.tenant_id:
                        chosen_agent = candidate
                        break

                if chosen_agent:
                    # Does the agent which had tenants assigned
                    # to it still have capacity?
                    if group_capacity >= 1.0:
                        chosen_agent = None
                    else:
                        break

            # If we don't have an agent with capacity associated
            # with our tenant_id, let's pick an agent based on
            # the group with the lowest capacity score.
            if not chosen_agent:
                # lets get an agent from the group with the
                # lowest capacity score
                lowest_utilization = 1.0
                selected_group = 1
                for group, capacity in capacity_by_group.items():
                    if capacity < lowest_utilization:
                        lowest_utilization = capacity
                        selected_group = group

                LOG.debug('%s group %s scheduled with capacity %s'
                          % (env, selected_group, lowest_utilization))
                if lowest_utilization < 1.0:
                    # Choose a agent in the env group for this
                    # tenant at random.
                    chosen_agent = random.choice(
                        agents_by_group[selected_group]
                    )

            # If there are no agents with available capacity, raise exception
            if not chosen_agent:
                LOG.warn('No capacity left on any agents in env: %s' % env)
                LOG.warn('Group capacity in environment %s were %s.'
                         % (env, capacity_by_group))
                raise lbaas_agentschedulerv2.NoEligibleLbaasAgent(
                    loadbalancer_id=loadbalancer.id)

            binding = agent_scheduler.LoadbalancerAgentBinding()
            binding.agent = chosen_agent
            binding.loadbalancer_id = loadbalancer.id
            context.session.add(binding)

            LOG.debug(('Loadbalancer %(loadbalancer_id)s is scheduled to '
                       'lbaas agent %(agent_id)s'),
                      {'loadbalancer_id': loadbalancer.id,
                       'agent_id': chosen_agent['id']})

            return chosen_agent