Example #1
0
    def get_delete_pool_flow_internal(self, name):
        """Create a flow to delete a pool, etc.

        :returns: The flow for deleting a pool
        """
        delete_pool_flow = linear_flow.Flow(constants.DELETE_POOL_FLOW)
        # health monitor should cascade
        # members should cascade
        delete_pool_flow.add(database_tasks.MarkPoolPendingDeleteInDB(
            name='mark_pool_pending_delete_in_db_' + name,
            requires=constants.POOL,
            rebind={constants.POOL: name}))
        delete_pool_flow.add(database_tasks.CountPoolChildrenForQuota(
            name='count_pool_children_for_quota_' + name,
            requires=constants.POOL,
            provides=constants.POOL_CHILD_COUNT,
            rebind={constants.POOL: name}))
        delete_pool_flow.add(model_tasks.DeleteModelObject(
            name='delete_model_object_' + name,
            rebind={constants.OBJECT: name}))
        delete_pool_flow.add(database_tasks.DeletePoolInDB(
            name='delete_pool_in_db_' + name,
            requires=constants.POOL,
            rebind={constants.POOL: name}))
        delete_pool_flow.add(database_tasks.DecrementPoolQuota(
            name='decrement_pool_quota_' + name,
            requires=[constants.POOL, constants.POOL_CHILD_COUNT],
            rebind={constants.POOL: name}))

        return delete_pool_flow
Example #2
0
    def get_delete_pool_flow(self):
        """Create a flow to delete a pool

        :returns: The flow for deleting a pool
        """
        delete_pool_flow = linear_flow.Flow(constants.DELETE_POOL_FLOW)
        delete_pool_flow.add(lifecycle_tasks.PoolToErrorOnRevertTask(
            requires=[constants.POOL,
                      constants.LISTENERS,
                      constants.LOADBALANCER]))
        delete_pool_flow.add(database_tasks.MarkPoolPendingDeleteInDB(
            requires=constants.POOL))
        delete_pool_flow.add(database_tasks.CountPoolChildrenForQuota(
            requires=constants.POOL, provides=constants.POOL_CHILD_COUNT))
        delete_pool_flow.add(model_tasks.DeleteModelObject(
            rebind={constants.OBJECT: constants.POOL}))
        delete_pool_flow.add(amphora_driver_tasks.ListenersUpdate(
            requires=[constants.LOADBALANCER, constants.LISTENERS]))
        delete_pool_flow.add(database_tasks.DeletePoolInDB(
            requires=constants.POOL))
        delete_pool_flow.add(database_tasks.DecrementPoolQuota(
            requires=[constants.POOL, constants.POOL_CHILD_COUNT]))
        delete_pool_flow.add(database_tasks.MarkLBAndListenersActiveInDB(
            requires=[constants.LOADBALANCER, constants.LISTENERS]))

        return delete_pool_flow
Example #3
0
    def get_delete_pool_rack_flow(self, members, health_mon, store):
        """Create a flow to delete a pool rack

        :returns: The flow for deleting a pool
        """
        delete_pool_flow = linear_flow.Flow(constants.DELETE_POOL_FLOW)
        delete_pool_flow.add(lifecycle_tasks.PoolToErrorOnRevertTask(
            requires=[constants.POOL,
                      constants.LISTENERS,
                      constants.LOADBALANCER]))
        delete_pool_flow.add(database_tasks.MarkPoolPendingDeleteInDB(
            requires=constants.POOL))
        delete_pool_flow.add(database_tasks.CountPoolChildrenForQuota(
            requires=constants.POOL, provides=constants.POOL_CHILD_COUNT))
        delete_pool_flow.add(model_tasks.DeleteModelObject(
            rebind={constants.OBJECT: constants.POOL}))
        # Get VThunder details from database
        delete_pool_flow.add(a10_database_tasks.GetVThunderByLoadBalancer(
            requires=constants.LOADBALANCER,
            provides=a10constants.VTHUNDER))
        delete_pool_flow.add(virtual_port_tasks.ListenerUpdateForPool(
            requires=[constants.LOADBALANCER, constants.LISTENER, a10constants.VTHUNDER]))
        delete_pool_flow.add(persist_tasks.DeleteSessionPersistence(
            requires=[a10constants.VTHUNDER, constants.POOL]))
        delete_pool_flow.add(vthunder_tasks.SetupDeviceNetworkMap(
            requires=a10constants.VTHUNDER,
            provides=a10constants.VTHUNDER))

        # Device Flavor
        delete_pool_flow.add(a10_database_tasks.GetFlavorData(
            rebind={a10constants.LB_RESOURCE: constants.LOADBALANCER},
            provides=constants.FLAVOR))
        delete_pool_flow.add(vthunder_tasks.GetVthunderConfByFlavor(
            requires=(constants.LOADBALANCER, a10constants.VTHUNDER_CONFIG,
                      a10constants.DEVICE_CONFIG_DICT),
            rebind={constants.FLAVOR_DATA: constants.FLAVOR},
            provides=(a10constants.VTHUNDER_CONFIG, a10constants.USE_DEVICE_FLAVOR)))
        delete_pool_flow.add(a10_network_tasks.GetPoolsOnThunder(
            requires=[a10constants.VTHUNDER, a10constants.USE_DEVICE_FLAVOR],
            provides=a10constants.POOLS))

        # Delete pool children
        delete_pool_flow.add(self._get_delete_health_monitor_vthunder_subflow(health_mon))
        delete_pool_flow.add(self._get_delete_member_vthunder_subflow(members, store))
        delete_pool_flow.add(service_group_tasks.PoolDelete(
            requires=[constants.POOL, a10constants.VTHUNDER]))
        delete_pool_flow.add(database_tasks.DeletePoolInDB(
            requires=constants.POOL))
        delete_pool_flow.add(database_tasks.DecrementPoolQuota(
            requires=[constants.POOL, constants.POOL_CHILD_COUNT]))
        delete_pool_flow.add(database_tasks.MarkLBAndListenersActiveInDB(
            requires=[constants.LOADBALANCER, constants.LISTENERS]))
        delete_pool_flow.add(vthunder_tasks.WriteMemory(
            requires=a10constants.VTHUNDER))
        delete_pool_flow.add(a10_database_tasks.SetThunderUpdatedAt(
            requires=a10constants.VTHUNDER))

        return delete_pool_flow
Example #4
0
    def get_cascade_delete_pool_internal_flow(
            self, pool_name, members, pool_listener_name, health_mon):
        """Create a flow to delete a pool, etc.
        :returns: The flow for deleting a pool
        """
        store = {}
        delete_pool_flow = linear_flow.Flow(constants.DELETE_POOL_FLOW)
        # health monitor should cascade
        # members should cascade
        delete_pool_flow.add(database_tasks.MarkPoolPendingDeleteInDB(
            name='mark_pool_pending_delete_in_db_' + pool_name,
            requires=constants.POOL,
            rebind={constants.POOL: pool_name}))
        delete_pool_flow.add(database_tasks.CountPoolChildrenForQuota(
            name='count_pool_children_for_quota_' + pool_name,
            requires=constants.POOL,
            provides=constants.POOL_CHILD_COUNT,
            rebind={constants.POOL: pool_name}))
        delete_pool_flow.add(virtual_port_tasks.ListenerUpdateForPool(
            name='listener_update_for_pool_' + pool_name,
            requires=[constants.LOADBALANCER, constants.LISTENER, a10constants.VTHUNDER],
            rebind={constants.LISTENER: pool_listener_name}))
        delete_pool_flow.add(persist_tasks.DeleteSessionPersistence(
            name='delete_session_persistence_' + pool_name,
            requires=[a10constants.VTHUNDER, constants.POOL],
            rebind={constants.POOL: pool_name}))
        delete_pool_flow.add(model_tasks.DeleteModelObject(
            name='delete_model_object_' + pool_name,
            rebind={constants.OBJECT: pool_name}))
        delete_pool_flow.add(a10_network_tasks.GetPoolsOnThunder(
            name='get_pools_on_thunder_' + pool_name,
            requires=[a10constants.VTHUNDER, a10constants.USE_DEVICE_FLAVOR],
            provides=a10constants.POOLS))
        # Delete pool children
        delete_pool_flow.add(self._get_delete_health_monitor_vthunder_subflow(health_mon, True))
        delete_pool_flow.add(self._get_delete_member_vthunder_subflow(members, store, pool_name))
        delete_pool_flow.add(service_group_tasks.PoolDelete(
            name='pool_delete_' + pool_name,
            requires=[constants.POOL, a10constants.VTHUNDER],
            rebind={constants.POOL: pool_name}))
        delete_pool_flow.add(database_tasks.DeletePoolInDB(
            name='delete_pool_in_db_' + pool_name,
            requires=constants.POOL,
            rebind={constants.POOL: pool_name}))
        delete_pool_flow.add(database_tasks.DecrementPoolQuota(
            name='decrement_pool_quota_' + pool_name,
            requires=[constants.POOL, constants.POOL_CHILD_COUNT],
            rebind={constants.POOL: pool_name}))

        return (delete_pool_flow, store)
Example #5
0
    def get_delete_pool_flow(self, members, health_mon, store, topology):
        """Create a flow to delete a pool

        :returns: The flow for deleting a pool
        """
        delete_pool_flow = linear_flow.Flow(constants.DELETE_POOL_FLOW)
        delete_pool_flow.add(
            lifecycle_tasks.PoolToErrorOnRevertTask(requires=[
                constants.POOL, constants.LISTENERS, constants.LOADBALANCER
            ]))
        delete_pool_flow.add(
            vthunder_tasks.VthunderInstanceBusy(
                requires=a10constants.COMPUTE_BUSY))

        delete_pool_flow.add(
            database_tasks.MarkPoolPendingDeleteInDB(requires=constants.POOL))
        delete_pool_flow.add(
            database_tasks.CountPoolChildrenForQuota(
                requires=constants.POOL, provides=constants.POOL_CHILD_COUNT))
        delete_pool_flow.add(
            model_tasks.DeleteModelObject(
                rebind={constants.OBJECT: constants.POOL}))
        # Get VThunder details from database
        delete_pool_flow.add(
            a10_database_tasks.GetVThunderByLoadBalancer(
                requires=constants.LOADBALANCER,
                provides=a10constants.VTHUNDER))
        if topology == constants.TOPOLOGY_ACTIVE_STANDBY:
            delete_pool_flow.add(
                vthunder_tasks.GetMasterVThunder(
                    name=a10constants.GET_MASTER_VTHUNDER,
                    requires=a10constants.VTHUNDER,
                    provides=a10constants.VTHUNDER))
        delete_pool_flow.add(
            virtual_port_tasks.ListenerUpdateForPool(requires=[
                constants.LOADBALANCER, constants.LISTENER,
                a10constants.VTHUNDER
            ]))
        delete_pool_flow.add(
            persist_tasks.DeleteSessionPersistence(
                requires=[a10constants.VTHUNDER, constants.POOL]))
        # Delete pool children
        delete_pool_flow.add(
            self._get_delete_health_monitor_vthunder_subflow(health_mon))
        delete_pool_flow.add(
            self._get_delete_member_vthunder_subflow(members, store))
        delete_pool_flow.add(
            service_group_tasks.PoolDelete(
                requires=[constants.POOL, a10constants.VTHUNDER]))
        delete_pool_flow.add(
            database_tasks.DeletePoolInDB(requires=constants.POOL))
        # Interface delete.
        delete_pool_flow.add(
            a10_database_tasks.GetLoadBalancerListByProjectID(
                requires=a10constants.VTHUNDER,
                provides=a10constants.LOADBALANCERS_LIST))
        delete_pool_flow.add(
            a10_database_tasks.GetMemberListByProjectID(
                requires=a10constants.VTHUNDER,
                provides=a10constants.MEMBER_LIST))
        delete_pool_flow.add(
            a10_network_tasks.CalculateDelta(
                requires=(constants.LOADBALANCER,
                          a10constants.LOADBALANCERS_LIST,
                          a10constants.MEMBER_LIST),
                provides=constants.DELTAS))
        delete_pool_flow.add(
            a10_network_tasks.HandleNetworkDeltas(
                requires=constants.DELTAS, provides=constants.ADDED_PORTS))
        delete_pool_flow.add(
            vthunder_tasks.AmphoraePostNetworkUnplug(
                requires=(constants.LOADBALANCER, constants.ADDED_PORTS,
                          a10constants.VTHUNDER)))
        delete_pool_flow.add(
            database_tasks.GetAmphoraeFromLoadbalancer(
                requires=constants.LOADBALANCER_ID,
                provides=constants.AMPHORA))
        delete_pool_flow.add(
            vthunder_tasks.VThunderComputeConnectivityWait(
                requires=(a10constants.VTHUNDER, constants.AMPHORA)))
        delete_pool_flow.add(
            database_tasks.DecrementPoolQuota(
                requires=[constants.POOL, constants.POOL_CHILD_COUNT]))
        delete_pool_flow.add(
            database_tasks.MarkLBAndListenersActiveInDB(
                requires=[constants.LOADBALANCER, constants.LISTENERS]))
        delete_pool_flow.add(
            vthunder_tasks.WriteMemory(requires=a10constants.VTHUNDER))
        delete_pool_flow.add(
            a10_database_tasks.SetThunderUpdatedAt(
                requires=a10constants.VTHUNDER))

        return delete_pool_flow
    def test_decrement_pool_quota_pool_children(self, mock_check_quota_met,
                                                mock_decrement_quota):
        pool_child_count = {'HM': 1, 'member': 2}
        project_id = uuidutils.generate_uuid()
        test_object = mock.MagicMock()
        test_object.project_id = project_id
        task = database_tasks.DecrementPoolQuota()
        mock_session = mock.MagicMock()

        with mock.patch('octavia.db.api.'
                        'get_session') as mock_get_session_local:
            mock_get_session_local.return_value = mock_session

            task.execute(test_object, pool_child_count)

            calls = [
                mock.call(mock_session, data_models.Pool, project_id),
                mock.call(mock_session, data_models.HealthMonitor, project_id),
                mock.call(mock_session,
                          data_models.Member,
                          project_id,
                          quantity=2)
            ]

            mock_decrement_quota.assert_has_calls(calls)

            mock_session.commit.assert_called_once_with()

        # revert
        mock_session.reset_mock()
        with mock.patch('octavia.db.api.'
                        'get_session') as mock_get_session_local:
            mock_lock_session = mock.MagicMock()
            mock_get_session_local.side_effect = [
                mock_session, mock_lock_session, mock_lock_session,
                mock_lock_session, mock_lock_session
            ]

            task.revert(test_object, pool_child_count, None)

            calls = [
                mock.call(mock_session, mock_lock_session, data_models.Pool,
                          project_id),
                mock.call(mock_session, mock_lock_session,
                          data_models.HealthMonitor, project_id),
                mock.call(mock_session, mock_lock_session, data_models.Member,
                          project_id),
                mock.call(mock_session, mock_lock_session, data_models.Member,
                          project_id)
            ]

            mock_check_quota_met.assert_has_calls(calls)

            self.assertEqual(4, mock_lock_session.commit.call_count)

        # revert with health monitor quota exception
        mock_session.reset_mock()
        mock_check_quota_met.side_effect = [
            None, Exception('fail'), None, None
        ]
        with mock.patch('octavia.db.api.'
                        'get_session') as mock_get_session_local:
            mock_lock_session = mock.MagicMock()
            mock_get_session_local.side_effect = [
                mock_session, mock_lock_session, mock_lock_session,
                mock_lock_session, mock_lock_session
            ]

            task.revert(test_object, pool_child_count, None)

            calls = [
                mock.call(mock_session, mock_lock_session, data_models.Pool,
                          project_id),
                mock.call(mock_session, mock_lock_session,
                          data_models.HealthMonitor, project_id),
                mock.call(mock_session, mock_lock_session, data_models.Member,
                          project_id),
                mock.call(mock_session, mock_lock_session, data_models.Member,
                          project_id)
            ]

            mock_check_quota_met.assert_has_calls(calls)

            self.assertEqual(3, mock_lock_session.commit.call_count)
            self.assertEqual(1, mock_lock_session.rollback.call_count)

        # revert with member quota exception
        mock_session.reset_mock()
        mock_check_quota_met.side_effect = [
            None, None, None, Exception('fail')
        ]
        with mock.patch('octavia.db.api.'
                        'get_session') as mock_get_session_local:
            mock_lock_session = mock.MagicMock()
            mock_get_session_local.side_effect = [
                mock_session, mock_lock_session, mock_lock_session,
                mock_lock_session, mock_lock_session
            ]

            task.revert(test_object, pool_child_count, None)

            calls = [
                mock.call(mock_session, mock_lock_session, data_models.Pool,
                          project_id),
                mock.call(mock_session, mock_lock_session,
                          data_models.HealthMonitor, project_id),
                mock.call(mock_session, mock_lock_session, data_models.Member,
                          project_id),
                mock.call(mock_session, mock_lock_session, data_models.Member,
                          project_id)
            ]

            mock_check_quota_met.assert_has_calls(calls)

            self.assertEqual(3, mock_lock_session.commit.call_count)
            self.assertEqual(1, mock_lock_session.rollback.call_count)
 def test_decrement_pool_quota(self):
     task = database_tasks.DecrementPoolQuota()
     data_model = data_models.Pool
     self._test_decrement_quota(task, data_model)