diff --git a/f5lbaasdriver/v2/bigip/driver_v2.py b/f5lbaasdriver/v2/bigip/driver_v2.py index 040a71ac8..62e0560da 100644 --- a/f5lbaasdriver/v2/bigip/driver_v2.py +++ b/f5lbaasdriver/v2/bigip/driver_v2.py @@ -152,11 +152,11 @@ def __init__(self, driver): self.api_dict = None self.loadbalancer = None - def _call_rpc(self, context, entity, rpc_method): + def _call_rpc(self, context, entity, rpc_method, **kwargs): '''Perform operations common to create and delete for managers.''' try: - agent_host, service = self._setup_crud(context, entity) + agent_host, service = self._setup_crud(context, entity, **kwargs) rpc_callable = getattr(self.driver.agent_rpc, rpc_method) rpc_callable(context, self.api_dict, service, agent_host) except (lbaas_agentschedulerv2.NoEligibleLbaasAgent, @@ -166,7 +166,7 @@ def _call_rpc(self, context, entity, rpc_method): LOG.error("Exception: %s: %s" % (rpc_method, e)) raise e - def _setup_crud(self, context, entity): + def _setup_crud(self, context, entity, **kwargs): '''Setup CRUD operations for managers to make calls to agent. :param context: auth context for performing CRUD operation @@ -176,12 +176,13 @@ def _setup_crud(self, context, entity): ''' if entity.attached_to_loadbalancer() and self.loadbalancer: - (agent, service) = self._schedule_agent_create_service(context) + (agent, service) = self._schedule_agent_create_service( + context, entity, **kwargs) return agent['host'], service raise F5NoAttachedLoadbalancerException() - def _schedule_agent_create_service(self, context): + def _schedule_agent_create_service(self, context, entity=None, **kwargs): '''Schedule agent and build service--used for most managers. :param context: auth context for performing crud operation @@ -195,9 +196,93 @@ def _schedule_agent_create_service(self, context): self.driver.env ) service = self.driver.service_builder.build( - context, self.loadbalancer, agent) + context, self.loadbalancer, agent, **kwargs) return agent, service + def _append_listeners(self, context, service, listener): + + if not listener: + return + + def get_db_listener(): + if cfg.CONF.f5_driver_perf_mode == 3: + return listener + else: + return self.driver.plugin.db.get_listener( + context, listener.id) + + db_listener = get_db_listener() + listener_dict = db_listener.to_dict( + loadbalancer=False, + default_pool=False, + l7_policies=False + ) + + # Listener may have l7policies or default pool + listener_dict['l7_policies'] = \ + [{'id': l7_policy.id} for l7_policy in listener.l7_policies] + if listener.default_pool: + listener_dict['default_pool_id'] = listener.default_pool.id + service['listeners'] = [listener_dict] + + def _append_pools_monitors(self, context, service, pool): + + if not pool: + service['pools'] = [] + return + + def get_db_pool(): + if cfg.CONF.f5_driver_perf_mode == 3: + return pool + else: + return self.driver.plugin.db.get_pool( + context, pool.id) + + db_pool = get_db_pool() + + pool_dict = db_pool.to_dict( + healthmonitor=False, + listener=False, + listeners=False, + loadbalancer=False, + l7_policies=False, + members=False, + session_persistence=False + ) + + pool_dict['members'] = [{'id': member.id} for member in pool.members] + pool_dict['l7_policies'] = [ + {'id': l7_policy.id} for l7_policy in pool.l7_policies] + + if pool.session_persistence: + pool_dict['session_persistence'] = ( + pool.session_persistence.to_api_dict() + ) + + service['pools'] = [pool_dict] + + # Place an empty member list as the initial value. + # Append_members() can be called later to change this value. + service['members'] = [] + + if not pool.healthmonitor: + return + + def get_db_healthmonitor(): + if cfg.CONF.f5_driver_perf_mode == 3: + return pool.healthmonitor + else: + return self.driver.plugin.db.get_healthmonitor( + context, + pool.healthmonitor.id + ) + + healthmonitor = get_db_healthmonitor() + healthmonitor_dict = healthmonitor.to_dict(pool=False) + healthmonitor_dict['pool_id'] = pool.id + + service['healthmonitors'] = [healthmonitor_dict] + class LoadBalancerManager(EntityManager): """LoadBalancerManager class handles Neutron LBaaS CRUD.""" @@ -353,7 +438,21 @@ def create(self, context, listener): self.loadbalancer = listener.loadbalancer self.api_dict = listener.to_dict( loadbalancer=False, default_pool=False) - self._call_rpc(context, listener, 'create_listener') + + def append_listeners(context, loadbalancer, service): + self._append_listeners(context, service, listener) + + if cfg.CONF.f5_driver_perf_mode in (2, 3): + # Listener does not have default pool or l7policies. + self._call_rpc( + context, listener, 'create_listener', + append_listeners=append_listeners, + append_pools_monitors=lambda *args: None, + append_members=lambda *args: None, + append_l7policies_rules=lambda *args: None + ) + else: + self._call_rpc(context, listener, 'create_listener') @log_helpers.log_method_call def update(self, context, old_listener, listener): @@ -382,7 +481,22 @@ def delete(self, context, listener): self.loadbalancer = listener.loadbalancer self.api_dict = listener.to_dict( loadbalancer=False, default_pool=False) - self._call_rpc(context, listener, 'delete_listener') + + def append_listeners(context, loadbalancer, service): + self._append_listeners(context, service, listener) + + if cfg.CONF.f5_driver_perf_mode in (2, 3): + # L7policy should already be deleted. + # Needn't modify pool. + self._call_rpc( + context, listener, 'delete_listener', + append_listeners=append_listeners, + append_pools_monitors=lambda *args: None, + append_members=lambda *args: None, + append_l7policies_rules=lambda *args: None + ) + else: + self._call_rpc(context, listener, 'delete_listener') class PoolManager(EntityManager): @@ -407,7 +521,26 @@ def create(self, context, pool): self.loadbalancer = pool.loadbalancer self.api_dict = self._get_pool_dict(pool) - self._call_rpc(context, pool, 'create_pool') + + def append_listeners(context, loadbalancer, service): + self._append_listeners(context, service, pool.listener) + + def append_pools_monitors(context, loadbalancer, service): + self._append_pools_monitors(context, service, pool) + + if cfg.CONF.f5_driver_perf_mode in (2, 3): + # Pool and l7plicies ??? + # Pool may be associated with listener, maybe not. + # Pool has no members + # Listener may have l7policies. Utilize default behavior. + self._call_rpc( + context, pool, 'create_pool', + append_listeners=append_listeners, + append_pools_monitors=append_pools_monitors, + append_members=lambda *args: None + ) + else: + self._call_rpc(context, pool, 'create_pool') @log_helpers.log_method_call def update(self, context, old_pool, pool): @@ -434,7 +567,23 @@ def delete(self, context, pool): self.loadbalancer = pool.loadbalancer self.api_dict = self._get_pool_dict(pool) - self._call_rpc(context, pool, 'delete_pool') + + def append_listeners(context, loadbalancer, service): + self._append_listeners(context, service, pool.listener) + + def append_pools_monitors(context, loadbalancer, service): + self._append_pools_monitors(context, service, pool) + + if cfg.CONF.f5_driver_perf_mode in (2, 3): + # Pool may be associated with a listener + # Utilize default behavior to load member, l7policy and rule + self._call_rpc( + context, pool, 'delete_pool', + append_listeners=append_listeners, + append_pools_monitors=append_pools_monitors + ) + else: + self._call_rpc(context, pool, 'delete_pool') class MemberManager(EntityManager): @@ -466,7 +615,20 @@ def create(self, context, member): portbindings.HOST_ID: agent_host}}) LOG.debug('the port created here is: %s' % p) self.api_dict = member.to_dict(pool=False) - self._call_rpc(context, member, 'create_member') + + def append_pools_monitors(context, loadbalancer, service): + self._append_pools_monitors(context, service, member.pool) + + if cfg.CONF.f5_driver_perf_mode in (2, 3): + # Utilize default behavior to append all members + self._call_rpc( + context, member, 'create_member', + append_listeners=lambda *args: None, + append_pools_monitors=append_pools_monitors, + append_l7policies_rules=lambda *args: None + ) + else: + self._call_rpc(context, member, 'create_member') if self.driver.unlegacy_setting_placeholder_driver_side: LOG.debug('running un-legacy way for member create p2:') @@ -504,7 +666,19 @@ def delete(self, context, member): self.loadbalancer = member.pool.loadbalancer driver = self.driver try: - agent_host, service = self._setup_crud(context, member) + def append_pools_monitors(context, loadbalancer, service): + self._append_pools_monitors(context, service, member.pool) + + if cfg.CONF.f5_driver_perf_mode in (2, 3): + # Utilize default behavior to append all members + agent_host, service = self._setup_crud( + context, member, + append_listeners=lambda *args: None, + append_pools_monitors=append_pools_monitors, + append_l7policies_rules=lambda *args: None + ) + else: + agent_host, service = self._setup_crud(context, member) driver.agent_rpc.delete_member( context, member.to_dict(pool=False), service, agent_host) @@ -522,7 +696,20 @@ def create(self, context, health_monitor): self.loadbalancer = health_monitor.pool.loadbalancer self.api_dict = health_monitor.to_dict(pool=False) - self._call_rpc(context, health_monitor, 'create_health_monitor') + + def append_pools_monitors(context, loadbalancer, service): + self._append_pools_monitors(context, service, health_monitor.pool) + + if cfg.CONF.f5_driver_perf_mode in (2, 3): + # Utilize default behavior to append all members + self._call_rpc( + context, health_monitor, 'create_health_monitor', + append_listeners=lambda *args: None, + append_pools_monitors=append_pools_monitors, + append_l7policies_rules=lambda *args: None + ) + else: + self._call_rpc(context, health_monitor, 'create_health_monitor') @log_helpers.log_method_call def update(self, context, old_health_monitor, health_monitor): @@ -549,7 +736,20 @@ def delete(self, context, health_monitor): self.loadbalancer = health_monitor.pool.loadbalancer self.api_dict = health_monitor.to_dict(pool=False) - self._call_rpc(context, health_monitor, 'delete_health_monitor') + + def append_pools_monitors(context, loadbalancer, service): + self._append_pools_monitors(context, service, health_monitor.pool) + + if cfg.CONF.f5_driver_perf_mode in (2, 3): + # Utilize default behavior to append all members + self._call_rpc( + context, health_monitor, 'delete_health_monitor', + append_listeners=lambda *args: None, + append_pools_monitors=append_pools_monitors, + append_l7policies_rules=lambda *args: None + ) + else: + self._call_rpc(context, health_monitor, 'delete_health_monitor') class L7PolicyManager(EntityManager): @@ -561,7 +761,25 @@ def create(self, context, policy): self.loadbalancer = policy.listener.loadbalancer self.api_dict = policy.to_dict(listener=False, rules=False) - self._call_rpc(context, policy, 'create_l7policy') + + def append_listeners(context, loadbalancer, service): + self._append_listeners(context, service, policy.listener) + + def append_pools_monitors(context, loadbalancer, service): + self._append_pools_monitors( + context, service, policy.listener.default_pool) + + if cfg.CONF.f5_driver_perf_mode in (2, 3): + # Utilize default behavior to load policies and rules + # Listener may have default pool + # Utilize default behavior to load members + self._call_rpc( + context, policy, 'create_l7policy', + append_listeners=append_listeners, + append_pools_monitors=append_pools_monitors + ) + else: + self._call_rpc(context, policy, 'create_l7policy') @log_helpers.log_method_call def update(self, context, old_policy, policy): @@ -588,7 +806,25 @@ def delete(self, context, policy): self.loadbalancer = policy.listener.loadbalancer self.api_dict = policy.to_dict(listener=False, rules=False) - self._call_rpc(context, policy, 'delete_l7policy') + + def append_listeners(context, loadbalancer, service): + self._append_listeners(context, service, policy.listener) + + def append_pools_monitors(context, loadbalancer, service): + self._append_pools_monitors( + context, service, policy.listener.default_pool) + + if cfg.CONF.f5_driver_perf_mode in (2, 3): + # Utilize default behavior to load policies and rules + # Listener may have default pool + # Utilize default behavior to load members + self._call_rpc( + context, policy, 'delete_l7policy', + append_listeners=append_listeners, + append_pools_monitors=append_pools_monitors + ) + else: + self._call_rpc(context, policy, 'delete_l7policy') class L7RuleManager(EntityManager): @@ -600,7 +836,25 @@ def create(self, context, rule): self.loadbalancer = rule.policy.listener.loadbalancer self.api_dict = rule.to_dict(policy=False) - self._call_rpc(context, rule, 'create_l7rule') + + def append_listeners(context, loadbalancer, service): + self._append_listeners(context, service, rule.policy.listener) + + def append_pools_monitors(context, loadbalancer, service): + self._append_pools_monitors( + context, service, rule.policy.listener.default_pool) + + if cfg.CONF.f5_driver_perf_mode in (2, 3): + # Utilize default behavior to load policies and rules + # Listener may have default pool + # Utilize default behavior to load members + self._call_rpc( + context, rule, 'create_l7rule', + append_listeners=append_listeners, + append_pools_monitors=append_pools_monitors + ) + else: + self._call_rpc(context, rule, 'create_l7rule') @log_helpers.log_method_call def update(self, context, old_rule, rule): @@ -627,4 +881,22 @@ def delete(self, context, rule): self.loadbalancer = rule.policy.listener.loadbalancer self.api_dict = rule.to_dict(policy=False) - self._call_rpc(context, rule, 'delete_l7rule') + + def append_listeners(context, loadbalancer, service): + self._append_listeners(context, service, rule.policy.listener) + + def append_pools_monitors(context, loadbalancer, service): + self._append_pools_monitors( + context, service, rule.policy.listener.default_pool) + + if cfg.CONF.f5_driver_perf_mode in (2, 3): + # Utilize default behavior to load policies and rules + # Listener may have default pool + # Utilize default behavior to load members + self._call_rpc( + context, rule, 'delete_l7rule', + append_listeners=append_listeners, + append_pools_monitors=append_pools_monitors + ) + else: + self._call_rpc(context, rule, 'delete_l7rule') diff --git a/f5lbaasdriver/v2/bigip/service_builder.py b/f5lbaasdriver/v2/bigip/service_builder.py index a3fc5a055..b67d33244 100644 --- a/f5lbaasdriver/v2/bigip/service_builder.py +++ b/f5lbaasdriver/v2/bigip/service_builder.py @@ -53,7 +53,7 @@ def __init__(self, driver): self.disconnected_service = DisconnectedService() self.q_client = q_client.F5NetworksNeutronClient(self.plugin) - def build(self, context, loadbalancer, agent): + def build(self, context, loadbalancer, agent, **kwargs): """Get full service definition from loadbalancer ID.""" # Invalidate cache if it is too old if ((datetime.datetime.now() - self.last_cache_update).seconds > @@ -146,24 +146,45 @@ def build(self, context, loadbalancer, agent): ) # Get listeners and pools. - service['listeners'] = self._get_listeners(context, loadbalancer) + append_listeners = kwargs.get( + "append_listeners", self._append_listeners) + append_pools_monitors = kwargs.get( + "append_pools_monitors", self._append_pools_monitors) + append_members = kwargs.get("append_members", self._append_members) + append_l7policies_rules = kwargs.get( + "append_l7policies_rules", self._append_l7policies_rules) + + append_listeners(context, loadbalancer, service) + append_pools_monitors(context, loadbalancer, service) + append_members( + context, loadbalancer, service, network_map, subnet_map) + append_l7policies_rules(context, loadbalancer, service) - service['pools'], service['healthmonitors'] = \ - self._get_pools_and_healthmonitors(context, loadbalancer) + return service - service['members'] = self._get_members( - context, loadbalancer, service['pools'], - subnet_map, network_map) + @log_helpers.log_method_call + def _append_listeners(self, context, loadbalancer, service): + service['listeners'] = self._get_listeners(context, loadbalancer) - service['subnets'] = subnet_map - service['networks'] = network_map + @log_helpers.log_method_call + def _append_pools_monitors(self, context, loadbalancer, service): + service['pools'], service['healthmonitors'] = \ + self._get_pools_and_healthmonitors(context, loadbalancer) - service['l7policies'] = self._get_l7policies( - context, loadbalancer, service['listeners']) - service['l7policy_rules'] = self._get_l7policy_rules( - context, loadbalancer, service['l7policies']) + @log_helpers.log_method_call + def _append_members(self, context, loadbalancer, service, + network_map, subnet_map): + service['members'] = self._get_members( + context, loadbalancer, service['pools'], subnet_map, network_map) + service['subnets'] = subnet_map + service['networks'] = network_map - return service + @log_helpers.log_method_call + def _append_l7policies_rules(self, context, loadbalancer, service): + service['l7policies'] = self._get_l7policies( + context, loadbalancer, service['listeners']) + service['l7policy_rules'] = self._get_l7policy_rules( + context, loadbalancer, service['l7policies']) @log_helpers.log_method_call def _get_extended_member(self, context, member):