Skip to content

Commit

Permalink
Failover should cause LB to be Immutable
Browse files Browse the repository at this point in the history
Change-Id: I31c71c1a626f49a32a51ecfbe75356a66d5f8604
  • Loading branch information
rm-you committed Jun 30, 2017
1 parent a7bdf03 commit 8baf0ca
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 1 deletion.
6 changes: 6 additions & 0 deletions octavia/controller/worker/flows/amphora_flows.py
Expand Up @@ -292,6 +292,10 @@ def get_failover_flow(self, role=constants.ROLE_STANDALONE,
failover_amphora_flow.add(lifecycle_tasks.AmphoraToErrorOnRevertTask(
rebind={constants.AMPHORA: constants.FAILED_AMPHORA},
requires=constants.AMPHORA))
if status == constants.AMPHORA_ALLOCATED:
failover_amphora_flow.add(
database_tasks.TestLBStatusSetPendingInDB(
requires=constants.LOADBALANCER_ID))

# Delete the old amphora
failover_amphora_flow.add(
Expand Down Expand Up @@ -392,6 +396,8 @@ def get_failover_flow(self, role=constants.ROLE_STANDALONE,

failover_amphora_flow.add(amphora_driver_tasks.ListenersStart(
requires=(constants.LOADBALANCER, constants.LISTENERS)))
failover_amphora_flow.add(database_tasks.MarkLBActiveInDB(
requires=[constants.LOADBALANCER]))

return failover_amphora_flow

Expand Down
18 changes: 18 additions & 0 deletions octavia/controller/worker/tasks/database_tasks.py
Expand Up @@ -891,6 +891,24 @@ def execute(self, amphora):
cert_busy=False)


class TestLBStatusSetPendingInDB(BaseDatabaseTask):
"""Test the LB's status to get a lock, and set it to PENDING_UPDATE
"""

def execute(self, loadbalancer_id):
LOG.debug("Attempting to get a lock for loadbalancer %s to set "
"PENDING_UPDATE status", loadbalancer_id)
self.loadbalancer_repo.test_and_set_provisioning_status(
db_apis.get_session(), loadbalancer_id,
status=constants.PENDING_UPDATE, raise_exception=True)
LOG.debug("Set loadbalancer %s to PENDING_UPDATE", loadbalancer_id)

def revert(self, loadbalancer_id):
LOG.debug("Marking loadbalancer %s ERROR", loadbalancer_id)
self.task_utils.mark_loadbalancer_prov_status_error(loadbalancer_id)


class MarkLBActiveInDB(BaseDatabaseTask):
"""Mark the load balancer active in the DB.
Expand Down
7 changes: 6 additions & 1 deletion octavia/db/repositories.py
Expand Up @@ -638,7 +638,8 @@ def create_load_balancer_tree(self, session, lock_session, lb_dict):
class LoadBalancerRepository(BaseRepository):
model_class = models.LoadBalancer

def test_and_set_provisioning_status(self, session, id, status):
def test_and_set_provisioning_status(self, session, id, status,
raise_exception=False):
"""Tests and sets a load balancer and provisioning status.
Puts a lock on the load balancer table to check the status of a
Expand All @@ -649,6 +650,7 @@ def test_and_set_provisioning_status(self, session, id, status):
:param session: A Sql Alchemy database session.
:param id: id of Load Balancer
:param status: Status to set Load Balancer if check passes.
:param raise_exception: If True, raise ImmutableObject on failure
:returns: bool
"""
with session.begin(subtransactions=True):
Expand All @@ -660,6 +662,9 @@ def test_and_set_provisioning_status(self, session, id, status):
if is_delete else consts.MUTABLE_STATUSES
)
if lb.provisioning_status not in acceptable_statuses:
if raise_exception:
raise exceptions.ImmutableObject(
resource='Load Balancer', id=id)
return False
lb.provisioning_status = status
session.add(lb)
Expand Down
14 changes: 14 additions & 0 deletions octavia/tests/functional/db/test_repositories.py
Expand Up @@ -2706,6 +2706,20 @@ def test_test_and_set_provisioning_status_immutable(self):
lb = self.lb_repo.get(self.session, id=lb_id)
self.assertEqual(constants.PENDING_CREATE, lb.provisioning_status)

def test_test_and_set_provisioning_status_immutable_raise(self):
lb_id = uuidutils.generate_uuid()
self.lb_repo.create(self.session, id=lb_id,
provisioning_status=constants.PENDING_CREATE,
operating_status=constants.OFFLINE,
enabled=True)
self.assertRaises(exceptions.ImmutableObject,
self.lb_repo.test_and_set_provisioning_status,
self.session, lb_id,
status=constants.PENDING_UPDATE,
raise_exception=True)
lb = self.lb_repo.get(self.session, id=lb_id)
self.assertEqual(constants.PENDING_CREATE, lb.provisioning_status)

def test_test_and_set_provisioning_status_mutable(self):
lb_id = uuidutils.generate_uuid()
self.lb_repo.create(self.session, id=lb_id,
Expand Down
24 changes: 24 additions & 0 deletions octavia/tests/unit/controller/worker/tasks/test_database_tasks.py
Expand Up @@ -1063,6 +1063,30 @@ def test_update_amphora_cert_busy_to_false(self,
AMP_ID,
cert_busy=False)

@mock.patch('octavia.db.repositories.LoadBalancerRepository'
'.test_and_set_provisioning_status')
def test_test_lb_status_set_pending_in_db(self,
mock_loadbalancer_repo_test,
mock_generate_uuid,
mock_LOG,
mock_get_session,
mock_loadbalancer_repo_update,
mock_listener_repo_update,
mock_amphora_repo_update,
mock_amphora_repo_delete):
test_lb_pending = database_tasks.TestLBStatusSetPendingInDB()
test_lb_pending.execute(LB_ID)
mock_loadbalancer_repo_test.assert_called_once_with(
'TEST', LB_ID, status=constants.PENDING_UPDATE,
raise_exception=True)

# Test the revert
test_lb_pending.revert(LB_ID)
mock_loadbalancer_repo_update.assert_called_once_with(
'TEST',
id=LB_ID,
provisioning_status=constants.ERROR)

def test_mark_LB_active_in_db(self,
mock_generate_uuid,
mock_LOG,
Expand Down

0 comments on commit 8baf0ca

Please sign in to comment.