Skip to content

Commit 35d3fe3

Browse files
authored
Merge pull request #1231 from Niklaus-xie/24-add-purge-driver-0121-only-try
[OPENSTACK-2966] add purge interface in driver
2 parents 4d58954 + 9f3b5f1 commit 35d3fe3

3 files changed

Lines changed: 124 additions & 0 deletions

File tree

f5lbaasdriver/v2/bigip/agent_rpc.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,18 @@ def rebuild_loadbalancer(self, context, loadbalancer, service, host):
118118
),
119119
topic=topic)
120120

121+
@log_helpers.log_method_call
122+
def purge_loadbalancer(self, context, loadbalancer, service, host):
123+
topic = '%s.%s' % (self.topic, host)
124+
return self.cast(
125+
context,
126+
self.make_msg(
127+
'purge_loadbalancer',
128+
loadbalancer=loadbalancer,
129+
service=service
130+
),
131+
topic=topic)
132+
121133
@log_helpers.log_method_call
122134
def delete_loadbalancer(self, context, loadbalancer, service, host):
123135
topic = '%s.%s' % (self.topic, host)

f5lbaasdriver/v2/bigip/device_scheduler.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ class LbaasDeviceDisappeared(nexception.Conflict):
5757
"is disappeared.")
5858

5959

60+
class LbaasDeviceNotUsable(lbaas_agentschedulerv2.NoEligibleLbaasAgent):
61+
message = ("Device %(device_id)s is not usable, "
62+
"Please check device status first. Purge unsuccessful. ")
63+
64+
6065
class LbaasDeviceDisabled(nexception.Conflict):
6166
message = ("Device %(device_id)s for loadbalancer %(loadbalancer_id)s "
6267
"is disabled.")

f5lbaasdriver/v2/bigip/driver_v2.py

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,64 @@ def _schedule_agent_and_device(self, context, loadbalancer,
367367

368368
return agent, device
369369

370+
# use separate schedule as the schedule becomes more complicated;
371+
# it may reschedule agent; but use device even if admin_state_down
372+
def _schedule_agent_and_device_4_purge(
373+
self, context, loadbalancer, device_id_passed=None
374+
):
375+
'''Schedule agent and device only used for purge'''
376+
377+
LAB = agent_scheduler.LoadbalancerAgentBinding
378+
379+
# If LB is already hosted on an agent, return this agent and device
380+
result = self.driver.plugin.db.get_agent_hosting_loadbalancer(
381+
context, loadbalancer.id)
382+
383+
if result:
384+
agent = result["agent"]
385+
if not agent["alive"] or not agent["admin_state_up"]:
386+
# Agent is not alive or is disabled. Attempt to
387+
# reschedule this loadbalancer to a new agent.
388+
LOG.info("Reschedule loadbalancer %s", loadbalancer.id)
389+
agent = self.driver.agent_scheduler.schedule(
390+
self.driver.plugin,
391+
context,
392+
loadbalancer,
393+
self.driver.env
394+
)
395+
# Update binding table
396+
with context.session.begin(subtransactions=True):
397+
query = context.session.query(LAB)
398+
binding = query.get(loadbalancer.id)
399+
binding.agent_id = agent["id"]
400+
LOG.info("Loadbalancer %s is rescheduled to agent %s",
401+
loadbalancer.id, agent.id)
402+
403+
# Load device info and return
404+
if device_id_passed:
405+
LOG.warn("using passed device %s to purge", device_id_passed) # noqa
406+
device_id = device_id_passed
407+
else:
408+
device_id = result["device_id"]
409+
410+
device = self.driver.device_scheduler.load_device(
411+
context, device_id
412+
)
413+
414+
# skipped checking admin_state_up based on discussion
415+
if device:
416+
LOG.debug("using device %s here for purge", device_id)
417+
return agent, device
418+
else:
419+
raise device_scheduler.LbaasDeviceNotUsable(
420+
device_id=device_id
421+
)
422+
else:
423+
raise Exception(
424+
"No binding information for loadbalancer %s",
425+
loadbalancer.id
426+
)
427+
370428
def _create_service(self, context, loadbalancer, agent,
371429
entity=None, **kwargs):
372430
'''build service--used for most managers.
@@ -644,6 +702,55 @@ def refresh(self, context, body):
644702
self._handle_entity_error(context, loadbalancer.id)
645703
raise e
646704

705+
@log_helpers.log_method_call
706+
def purge(self, context, body):
707+
"""Purge a loadbalancer from device without touching DB data."""
708+
709+
lbext = body["loadbalancerext"]
710+
loadbalancer = lbext["loadbalancer"]
711+
712+
self._log_entity(loadbalancer)
713+
driver = self.driver
714+
715+
device_id_passed = None
716+
717+
try:
718+
if lbext.get("device", None):
719+
device_id_passed = lbext["device"]
720+
LOG.warning('device passed from args. Trying to use it!')
721+
722+
agent, device = self._schedule_agent_and_device_4_purge(
723+
context, loadbalancer, device_id_passed=device_id_passed
724+
)
725+
726+
service = self._create_service(context, loadbalancer, agent)
727+
service["device"] = device
728+
729+
agent_host = agent['host']
730+
self._allocate_acl_groups(context, service)
731+
732+
driver.agent_rpc.purge_loadbalancer(
733+
context, loadbalancer.to_api_dict(), service, agent_host
734+
)
735+
736+
except device_scheduler.LbaasDeviceNotUsable:
737+
LOG.error("device_id for the lb is not usable")
738+
LOG.error("Pls check its status. Purge unsuccessful here.")
739+
# update its status to active here although it's not purged
740+
self.driver.plugin.db.update_status(
741+
context, models.LoadBalancer,
742+
loadbalancer.id, plugin_constants.ACTIVE
743+
)
744+
raise
745+
746+
except Exception as e:
747+
LOG.error("Exception: loadbalancer purge: %s" % e.message)
748+
self.driver.plugin.db.update_status(
749+
context, models.LoadBalancer,
750+
loadbalancer.id, plugin_constants.ERROR
751+
)
752+
raise e
753+
647754
def _allocate_acl_groups(self, context, service):
648755

649756
# for compatibility with pipeline test only.

0 commit comments

Comments
 (0)