Ejemplo n.º 1
0
 def _create_listeners_flow(self):
     flows = []
     flows.append(
         database_tasks.ReloadLoadBalancer(
             name=constants.RELOAD_LB_AFTER_AMP_ASSOC_FULL_GRAPH,
             requires=constants.LOADBALANCER_ID,
             provides=constants.LOADBALANCER
         )
     )
     flows.append(
         network_tasks.CalculateDelta(
             requires=constants.LOADBALANCER, provides=constants.DELTAS
         )
     )
     flows.append(
         network_tasks.HandleNetworkDeltas(
             requires=constants.DELTAS, provides=constants.ADDED_PORTS
         )
     )
     flows.append(
         amphora_driver_tasks.AmphoraePostNetworkPlug(
             requires=(constants.LOADBALANCER, constants.ADDED_PORTS)
         )
     )
     flows.append(
         self.listener_flows.get_create_all_listeners_flow()
     )
     flows.append(
         database_tasks.MarkLBActiveInDB(
             mark_subobjects=True,
             requires=constants.LOADBALANCER
         )
     )
     return flows
Ejemplo n.º 2
0
    def get_delete_listener_flow(self, topology):
        """Flow to delete a listener"""

        delete_listener_flow = linear_flow.Flow(constants.DELETE_LISTENER_FLOW)
        delete_listener_flow.add(lifecycle_tasks.ListenerToErrorOnRevertTask(
            requires=constants.LISTENER))
        delete_listener_flow.add(vthunder_tasks.VthunderInstanceBusy(
            requires=a10constants.COMPUTE_BUSY))
        delete_listener_flow.add(a10_database_tasks.GetVThunderByLoadBalancer(
            requires=constants.LOADBALANCER,
            provides=a10constants.VTHUNDER))
        if topology == constants.TOPOLOGY_ACTIVE_STANDBY:
            delete_listener_flow.add(vthunder_tasks.GetMasterVThunder(
                name=a10constants.GET_MASTER_VTHUNDER,
                requires=a10constants.VTHUNDER,
                provides=a10constants.VTHUNDER))
        delete_listener_flow.add(self.handle_ssl_cert_flow(flow_type='delete'))
        delete_listener_flow.add(virtual_port_tasks.ListenerDelete(
            requires=[constants.LOADBALANCER, constants.LISTENER, a10constants.VTHUNDER]))
        delete_listener_flow.add(network_tasks.UpdateVIPForDelete(
            requires=constants.LOADBALANCER))
        delete_listener_flow.add(database_tasks.DeleteListenerInDB(
            requires=constants.LISTENER))
        delete_listener_flow.add(database_tasks.DecrementListenerQuota(
            requires=constants.LISTENER))
        delete_listener_flow.add(database_tasks.MarkLBActiveInDB(
            requires=constants.LOADBALANCER))
        delete_listener_flow.add(vthunder_tasks.WriteMemory(
            requires=a10constants.VTHUNDER))
        delete_listener_flow.add(a10_database_tasks.SetThunderUpdatedAt(
            requires=a10constants.VTHUNDER))
        return delete_listener_flow
 def get_update_load_balancer_flow(self):
     """Creates a flow to update a load balancer.
     :returns: The flow for update a load balancer
     """
     update_LB_flow = linear_flow.Flow(constants.UPDATE_LOADBALANCER_FLOW)
     update_LB_flow.add(
         lifecycle_tasks.LoadBalancerToErrorOnRevertTask(
             requires=constants.LOADBALANCER))
     update_LB_flow.add(
         a10_database_tasks.GetVThunderByLoadBalancer(
             requires=constants.LOADBALANCER,
             provides=a10constants.VTHUNDER))
     update_LB_flow.add(
         a10_database_tasks.MarkVThunderStatusInDB(
             name="set load balancer status PENDING_UPDATE",
             requires=a10constants.VTHUNDER,
             inject={"status": constants.PENDING_UPDATE}))
     update_LB_flow.add(
         network_tasks.ApplyQos(requires=(constants.LOADBALANCER,
                                          constants.UPDATE_DICT)))
     # update_LB_flow.add(amphora_driver_tasks.ListenersUpdate(
     #    requires=[constants.LOADBALANCER, constants.LISTENERS]))
     update_LB_flow.add(
         virtual_server_tasks.UpdateVirtualServerTask(
             requires=(constants.LOADBALANCER, a10constants.VTHUNDER)))
     update_LB_flow.add(
         database_tasks.UpdateLoadbalancerInDB(
             requires=[constants.LOADBALANCER, constants.UPDATE_DICT]))
     update_LB_flow.add(
         database_tasks.MarkLBActiveInDB(requires=constants.LOADBALANCER))
     return update_LB_flow
    def get_delete_listener_flow(self):
        """Flow to delete a listener"""

        delete_listener_flow = linear_flow.Flow(constants.DELETE_LISTENER_FLOW)
        delete_listener_flow.add(
            lifecycle_tasks.ListenerToErrorOnRevertTask(
                requires=constants.LISTENER))
        delete_listener_flow.add(
            a10_database_tasks.GetVThunderByLoadBalancer(
                requires=constants.LOADBALANCER,
                provides=a10constants.VTHUNDER))
        delete_listener_flow.add(self.handle_ssl_cert_flow(flow_type='delete'))
        delete_listener_flow.add(
            virtual_port_tasks.ListenerDelete(requires=[
                constants.LOADBALANCER, constants.LISTENER,
                a10constants.VTHUNDER
            ]))
        delete_listener_flow.add(
            network_tasks.UpdateVIPForDelete(requires=constants.LOADBALANCER))
        delete_listener_flow.add(
            database_tasks.DeleteListenerInDB(requires=constants.LISTENER))
        delete_listener_flow.add(
            database_tasks.DecrementListenerQuota(requires=constants.LISTENER))
        delete_listener_flow.add(
            database_tasks.MarkLBActiveInDB(requires=constants.LOADBALANCER))
        delete_listener_flow.add(
            vthunder_tasks.WriteMemory(requires=a10constants.VTHUNDER))
        return delete_listener_flow
Ejemplo n.º 5
0
    def get_create_amphora_for_lb_flow(self):
        """Creates a flow to create an amphora for a load balancer.

        This flow is used when there are no spare amphora available
        for a new load balancer.  It builds an amphora and allocates
        for the specific load balancer.

        :returns: The The flow for creating the amphora
        """
        create_amp_for_lb_flow = linear_flow.Flow(
            constants.CREATE_AMPHORA_FOR_LB_FLOW)
        create_amp_for_lb_flow.add(
            database_tasks.CreateAmphoraInDB(provides=constants.AMPHORA_ID))
        if self.REST_AMPHORA_DRIVER:
            create_amp_for_lb_flow.add(
                cert_task.GenerateServerPEMTask(provides=constants.SERVER_PEM))
            create_amp_for_lb_flow.add(
                compute_tasks.CertComputeCreate(
                    requires=(constants.AMPHORA_ID, constants.SERVER_PEM),
                    provides=constants.COMPUTE_ID))
        else:
            create_amp_for_lb_flow.add(
                compute_tasks.ComputeCreate(requires=constants.AMPHORA_ID,
                                            provides=constants.COMPUTE_ID))
        create_amp_for_lb_flow.add(
            database_tasks.UpdateAmphoraComputeId(
                requires=(constants.AMPHORA_ID, constants.COMPUTE_ID)))
        create_amp_for_lb_flow.add(
            database_tasks.MarkAmphoraBootingInDB(
                requires=(constants.AMPHORA_ID, constants.COMPUTE_ID)))
        wait_flow = linear_flow.Flow(
            constants.WAIT_FOR_AMPHORA,
            retry=retry.Times(CONF.controller_worker.amp_active_retries))
        wait_flow.add(
            compute_tasks.ComputeWait(requires=constants.COMPUTE_ID,
                                      provides=constants.COMPUTE_OBJ))
        wait_flow.add(
            database_tasks.UpdateAmphoraInfo(requires=(constants.AMPHORA_ID,
                                                       constants.COMPUTE_OBJ),
                                             provides=constants.AMPHORA))
        create_amp_for_lb_flow.add(wait_flow)
        create_amp_for_lb_flow.add(
            amphora_driver_tasks.AmphoraFinalize(requires=constants.AMPHORA))
        create_amp_for_lb_flow.add(
            database_tasks.MarkAmphoraAllocatedInDB(
                requires=(constants.AMPHORA, constants.LOADBALANCER_ID)))
        create_amp_for_lb_flow.add(
            database_tasks.ReloadAmphora(requires=constants.AMPHORA_ID,
                                         provides=constants.AMPHORA))
        create_amp_for_lb_flow.add(
            database_tasks.ReloadLoadBalancer(
                name=constants.RELOAD_LB_AFTER_AMP_ASSOC,
                requires=constants.LOADBALANCER_ID,
                provides=constants.LOADBALANCER))
        new_LB_net_subflow = self._lb_flows.get_new_LB_networking_subflow()
        create_amp_for_lb_flow.add(new_LB_net_subflow)
        create_amp_for_lb_flow.add(
            database_tasks.MarkLBActiveInDB(requires=constants.LOADBALANCER))

        return create_amp_for_lb_flow
Ejemplo n.º 6
0
    def get_create_load_balancer_flow(self):
        """Creates a flow to create a load balancer.

        :returns: The flow for creating a load balancer
        """

        # Note this flow is a bit strange in how it handles building
        # Amphora if there are no spares.  TaskFlow has a spec for
        # a conditional flow that would make this cleaner once implemented.
        # https://review.openstack.org/#/c/98946/

        create_LB_flow = linear_flow.Flow(constants.CREATE_LOADBALANCER_FLOW)

        create_LB_flow.add(database_tasks.MapLoadbalancerToAmphora(
            requires=constants.LOADBALANCER_ID,
            provides=constants.AMPHORA_ID))
        create_LB_flow.add(database_tasks.ReloadAmphora(
            requires=constants.AMPHORA_ID,
            provides=constants.AMPHORA))
        create_LB_flow.add(database_tasks.ReloadLoadBalancer(
            name=constants.RELOAD_LB_AFTER_AMP_ASSOC,
            requires=constants.LOADBALANCER_ID,
            provides=constants.LOADBALANCER))
        new_LB_net_subflow = self.get_new_LB_networking_subflow()
        create_LB_flow.add(new_LB_net_subflow)
        create_LB_flow.add(database_tasks.MarkLBActiveInDB(
            requires=constants.LOADBALANCER))

        return create_LB_flow
    def get_post_lb_vthunder_association_flow(self,
                                              prefix,
                                              topology,
                                              mark_active=True):
        """Flow to manage networking after lb creation"""

        sf_name = prefix + '-' + constants.POST_LB_AMP_ASSOCIATION_SUBFLOW
        post_create_lb_flow = linear_flow.Flow(sf_name)
        post_create_lb_flow.add(
            database_tasks.ReloadLoadBalancer(
                name=sf_name + '-' + constants.RELOAD_LB_AFTER_AMP_ASSOC,
                requires=constants.LOADBALANCER_ID,
                provides=constants.LOADBALANCER))
        # IMP: here we will inject network flow
        new_LB_net_subflow = self.get_new_lb_networking_subflow(topology)
        post_create_lb_flow.add(new_LB_net_subflow)

        if topology == constants.TOPOLOGY_ACTIVE_STANDBY:
            vrrp_subflow = self.vthunder_flows.get_vrrp_subflow(prefix)
            post_create_lb_flow.add(vrrp_subflow)

        post_create_lb_flow.add(
            database_tasks.UpdateLoadbalancerInDB(
                requires=[constants.LOADBALANCER, constants.UPDATE_DICT]))
        if mark_active:
            post_create_lb_flow.add(
                database_tasks.MarkLBActiveInDB(
                    name=sf_name + '-' + constants.MARK_LB_ACTIVE_INDB,
                    requires=constants.LOADBALANCER))
        return post_create_lb_flow
Ejemplo n.º 8
0
    def get_create_load_balancer_graph_flows(self, topology, prefix):
        allocate_amphorae_flow = self.get_create_load_balancer_flow(topology)
        f_name = constants.CREATE_LOADBALANCER_GRAPH_FLOW
        lb_create_graph_flow = linear_flow.Flow(f_name)
        lb_create_graph_flow.add(
            self.get_post_lb_amp_association_flow(prefix, topology))
        lb_create_graph_flow.add(
            database_tasks.ReloadLoadBalancer(
                name=constants.RELOAD_LB_AFTER_AMP_ASSOC_FULL_GRAPH,
                requires=constants.LOADBALANCER_ID,
                provides=constants.LOADBALANCER))
        lb_create_graph_flow.add(
            network_tasks.CalculateDelta(requires=constants.LOADBALANCER,
                                         provides=constants.DELTAS))
        lb_create_graph_flow.add(
            network_tasks.HandleNetworkDeltas(requires=constants.DELTAS,
                                              provides=constants.ADDED_PORTS))
        lb_create_graph_flow.add(
            amphora_driver_tasks.AmphoraePostNetworkPlug(
                requires=(constants.LOADBALANCER, constants.ADDED_PORTS)))
        lb_create_graph_flow.add(
            self.listener_flows.get_create_all_listeners_flow())

        lb_create_graph_flow.add(
            database_tasks.MarkLBActiveInDB(mark_listeners=True,
                                            requires=constants.LOADBALANCER))
        return allocate_amphorae_flow, lb_create_graph_flow
    def get_post_lb_rack_vthunder_association_flow(self,
                                                   prefix,
                                                   topology,
                                                   mark_active=True):
        """Flow to manage networking after rack lb creation"""

        sf_name = prefix + '-' + constants.POST_LB_AMP_ASSOCIATION_SUBFLOW
        post_create_lb_flow = linear_flow.Flow(sf_name)
        post_create_lb_flow.add(
            vthunder_tasks.SetupDeviceNetworkMap(
                requires=a10constants.VTHUNDER,
                provides=a10constants.VTHUNDER))
        post_create_lb_flow.add(
            database_tasks.ReloadLoadBalancer(
                name=sf_name + '-' + constants.RELOAD_LB_AFTER_AMP_ASSOC,
                requires=constants.LOADBALANCER_ID,
                provides=constants.LOADBALANCER))
        post_create_lb_flow.add(
            database_tasks.UpdateLoadbalancerInDB(
                requires=[constants.LOADBALANCER, constants.UPDATE_DICT]))
        post_create_lb_flow.add(self.handle_vrid_for_loadbalancer_subflow())
        if CONF.a10_global.network_type == 'vlan':
            post_create_lb_flow.add(
                vthunder_tasks.TagInterfaceForLB(
                    requires=[constants.LOADBALANCER, a10constants.VTHUNDER]))
        if mark_active:
            post_create_lb_flow.add(
                database_tasks.MarkLBActiveInDB(
                    name=sf_name + '-' + constants.MARK_LB_ACTIVE_INDB,
                    requires=constants.LOADBALANCER))
        return post_create_lb_flow
    def get_delete_rack_listener_flow(self):
        """Create a flow to delete a rack listener

        :returns: The flow for deleting a rack listener
        """
        delete_listener_flow = linear_flow.Flow(constants.DELETE_LISTENER_FLOW)
        delete_listener_flow.add(
            lifecycle_tasks.ListenerToErrorOnRevertTask(
                requires=constants.LISTENER))
        delete_listener_flow.add(
            a10_database_tasks.GetVThunderByLoadBalancer(
                requires=constants.LOADBALANCER,
                provides=a10constants.VTHUNDER))
        delete_listener_flow.add(
            virtual_port_tasks.ListenerDelete(requires=[
                constants.LOADBALANCER, constants.LISTENER,
                a10constants.VTHUNDER
            ]))
        delete_listener_flow.add(
            database_tasks.DeleteListenerInDB(requires=constants.LISTENER))
        delete_listener_flow.add(
            database_tasks.DecrementListenerQuota(requires=constants.LISTENER))
        delete_listener_flow.add(
            database_tasks.MarkLBActiveInDB(requires=constants.LOADBALANCER))

        return delete_listener_flow
Ejemplo n.º 11
0
    def get_update_load_balancer_flow(self):
        """Creates a flow to update a load balancer.

        :returns: The flow for update a load balancer
        """
        update_LB_flow = linear_flow.Flow(constants.UPDATE_LOADBALANCER_FLOW)
        update_LB_flow.add(
            lifecycle_tasks.LoadBalancerToErrorOnRevertTask(
                requires=constants.LOADBALANCER))
        update_LB_flow.add(
            model_tasks.UpdateAttributes(
                rebind={constants.OBJECT: constants.LOADBALANCER},
                requires=[constants.UPDATE_DICT]))
        update_LB_flow.add(
            network_tasks.ApplyQos(requires=(constants.LOADBALANCER,
                                             constants.UPDATE_DICT)))
        update_LB_flow.add(
            amphora_driver_tasks.ListenersUpdate(
                requires=[constants.LOADBALANCER, constants.LISTENERS]))
        update_LB_flow.add(
            database_tasks.UpdateLoadbalancerInDB(
                requires=[constants.LOADBALANCER, constants.UPDATE_DICT]))
        update_LB_flow.add(
            database_tasks.MarkLBActiveInDB(requires=constants.LOADBALANCER))

        return update_LB_flow
    def get_post_lb_amp_association_flow(self, prefix, topology,
                                         mark_active=True):
        """Reload the loadbalancer and create networking subflows for

        created/allocated amphorae.
        :return: Post amphorae association subflow
        """

        # Note: If any task in this flow failed, the created amphorae will be
        #  left ''incorrectly'' allocated to the loadbalancer. Likely,
        # the get_new_LB_networking_subflow is the most prune to failure
        # shall deallocate the amphora from its loadbalancer and put it in a
        # READY state.

        sf_name = prefix + '-' + constants.POST_LB_AMP_ASSOCIATION_SUBFLOW
        post_create_LB_flow = linear_flow.Flow(sf_name)
        post_create_LB_flow.add(
            database_tasks.ReloadLoadBalancer(
                name=sf_name + '-' + constants.RELOAD_LB_AFTER_AMP_ASSOC,
                requires=constants.LOADBALANCER_ID,
                provides=constants.LOADBALANCER))

        if topology == constants.TOPOLOGY_ACTIVE_STANDBY:
            vrrp_subflow = self.amp_flows.get_vrrp_subflow(prefix)
            post_create_LB_flow.add(vrrp_subflow)

        post_create_LB_flow.add(database_tasks.UpdateLoadbalancerInDB(
            requires=[constants.LOADBALANCER, constants.UPDATE_DICT]))
        if mark_active:
            post_create_LB_flow.add(database_tasks.MarkLBActiveInDB(
                name=sf_name + '-' + constants.MARK_LB_ACTIVE_INDB,
                requires=constants.LOADBALANCER))
        return post_create_LB_flow
    def get_update_load_balancer_flow(self):
        """Flow to update load balancer."""

        update_LB_flow = linear_flow.Flow(constants.UPDATE_LOADBALANCER_FLOW)
        update_LB_flow.add(
            lifecycle_tasks.LoadBalancerToErrorOnRevertTask(
                requires=constants.LOADBALANCER))
        update_LB_flow.add(
            a10_database_tasks.GetVThunderByLoadBalancer(
                requires=constants.LOADBALANCER,
                provides=a10constants.VTHUNDER))
        update_LB_flow.add(
            a10_database_tasks.MarkVThunderStatusInDB(
                requires=a10constants.VTHUNDER,
                inject={"status": constants.PENDING_UPDATE}))
        update_LB_flow.add(
            vthunder_tasks.SetupDeviceNetworkMap(
                requires=a10constants.VTHUNDER,
                provides=a10constants.VTHUNDER))
        update_LB_flow.add(
            network_tasks.ApplyQos(requires=(constants.LOADBALANCER,
                                             constants.UPDATE_DICT)))
        # update_LB_flow.add(amphora_driver_tasks.ListenersUpdate(
        #    requires=[constants.LOADBALANCER, constants.LISTENERS]))
        # post_create_lb_flow.add(handle_vrid_for_loadbalancer_subflow())
        update_LB_flow.add(self.handle_vrid_for_loadbalancer_subflow())
        update_LB_flow.add(
            a10_database_tasks.GetFlavorData(
                rebind={a10constants.LB_RESOURCE: constants.LOADBALANCER},
                provides=constants.FLAVOR_DATA))
        update_LB_flow.add(
            virtual_server_tasks.UpdateVirtualServerTask(
                requires=(constants.LOADBALANCER, a10constants.VTHUNDER,
                          constants.FLAVOR_DATA)))
        update_LB_flow.add(
            database_tasks.UpdateLoadbalancerInDB(
                requires=[constants.LOADBALANCER, constants.UPDATE_DICT]))
        if CONF.a10_global.network_type == 'vlan':
            update_LB_flow.add(
                vthunder_tasks.TagInterfaceForLB(
                    requires=[constants.LOADBALANCER, a10constants.VTHUNDER]))
        update_LB_flow.add(
            database_tasks.MarkLBActiveInDB(requires=constants.LOADBALANCER))
        update_LB_flow.add(
            vthunder_tasks.WriteMemory(requires=a10constants.VTHUNDER))
        update_LB_flow.add(
            a10_database_tasks.MarkVThunderStatusInDB(
                name="pending_update_to_active",
                requires=a10constants.VTHUNDER,
                inject={"status": constants.ACTIVE}))
        update_LB_flow.add(
            a10_database_tasks.SetThunderUpdatedAt(
                requires=a10constants.VTHUNDER))
        return update_LB_flow
Ejemplo n.º 14
0
    def get_update_load_balancer_flow(self):
        """Creates a flow to update a load balancer.

        :returns: The flow for update a load balancer
        """
        update_LB_flow = linear_flow.Flow(constants.UPDATE_LOADBALANCER_FLOW)
        update_LB_flow.add(controller_tasks.DisableEnableLB(
            requires=constants.LOADBALANCER))
        update_LB_flow.add(database_tasks.UpdateLoadbalancerInDB(
            requires=[constants.LOADBALANCER, constants.UPDATE_DICT]))
        update_LB_flow.add(database_tasks.MarkLBActiveInDB(
            requires=constants.LOADBALANCER))

        return update_LB_flow
Ejemplo n.º 15
0
    def get_delete_listener_flow(self):
        """Create a flow to delete a listener

        :returns: The flow for deleting a listener
        """
        delete_listener_flow = linear_flow.Flow(constants.DELETE_LISTENER_FLOW)
        delete_listener_flow.add(amphora_driver_tasks.ListenerDelete(
            requires=[constants.LOADBALANCER, constants.LISTENER]))
        delete_listener_flow.add(network_tasks.UpdateVIP(
            requires=constants.LOADBALANCER))
        delete_listener_flow.add(database_tasks.DeleteListenerInDB(
            requires=constants.LISTENER))
        delete_listener_flow.add(database_tasks.MarkLBActiveInDB(
            requires=constants.LOADBALANCER))

        return delete_listener_flow
Ejemplo n.º 16
0
    def test_mark_LB_active_in_db(self, mock_generate_uuid, mock_LOG,
                                  mock_get_session,
                                  mock_loadbalancer_repo_update,
                                  mock_listener_repo_update,
                                  mock_amphora_repo_update,
                                  mock_amphora_repo_delete):

        mark_loadbalancer_active = database_tasks.MarkLBActiveInDB()
        mark_loadbalancer_active.execute(self.loadbalancer_mock)

        repo.LoadBalancerRepository.update.assert_called_once_with(
            'TEST', LB_ID, provisioning_status=constants.ACTIVE)

        # Test the revert

        mock_loadbalancer_repo_update.reset_mock()
        mark_loadbalancer_active.revert(self.loadbalancer_mock)

        repo.LoadBalancerRepository.update.assert_called_once_with(
            'TEST', LB_ID, provisioning_status=constants.ERROR)
Ejemplo n.º 17
0
    def get_update_load_balancer_flow(self):
        """Flow to update load balancer."""

        update_LB_flow = linear_flow.Flow(constants.UPDATE_LOADBALANCER_FLOW)
        update_LB_flow.add(
            lifecycle_tasks.LoadBalancerToErrorOnRevertTask(
                requires=constants.LOADBALANCER))
        update_LB_flow.add(
            a10_database_tasks.GetVThunderByLoadBalancer(
                requires=constants.LOADBALANCER,
                provides=a10constants.VTHUNDER))
        update_LB_flow.add(
            a10_database_tasks.MarkVThunderStatusInDB(
                requires=a10constants.VTHUNDER,
                inject={"status": constants.PENDING_UPDATE}))
        update_LB_flow.add(
            vthunder_tasks.SetupDeviceNetworkMap(
                requires=a10constants.VTHUNDER,
                provides=a10constants.VTHUNDER))
        update_LB_flow.add(
            network_tasks.ApplyQos(requires=(constants.LOADBALANCER,
                                             constants.UPDATE_DICT)))
        # update_LB_flow.add(amphora_driver_tasks.ListenersUpdate(
        #    requires=[constants.LOADBALANCER, constants.LISTENERS]))
        update_LB_flow.add(
            virtual_server_tasks.UpdateVirtualServerTask(
                requires=(constants.LOADBALANCER, a10constants.VTHUNDER)))
        update_LB_flow.add(
            database_tasks.UpdateLoadbalancerInDB(
                requires=[constants.LOADBALANCER, constants.UPDATE_DICT]))
        if CONF.a10_global.network_type == 'vlan':
            update_LB_flow.add(
                vthunder_tasks.TagInterfaceForLB(
                    requires=[constants.LOADBALANCER, a10constants.VTHUNDER]))
        update_LB_flow.add(
            database_tasks.MarkLBActiveInDB(requires=constants.LOADBALANCER))
        update_LB_flow.add(
            vthunder_tasks.WriteMemory(requires=a10constants.VTHUNDER))
        return update_LB_flow
    def get_post_lb_rack_vthunder_association_flow(self,
                                                   prefix,
                                                   topology,
                                                   mark_active=True):
        """Reload the loadbalancer and update loadbalancer in database."""

        sf_name = prefix + '-' + constants.POST_LB_AMP_ASSOCIATION_SUBFLOW
        post_create_lb_flow = linear_flow.Flow(sf_name)
        post_create_lb_flow.add(
            database_tasks.ReloadLoadBalancer(
                name=sf_name + '-' + constants.RELOAD_LB_AFTER_AMP_ASSOC,
                requires=constants.LOADBALANCER_ID,
                provides=constants.LOADBALANCER))

        post_create_lb_flow.add(
            database_tasks.UpdateLoadbalancerInDB(
                requires=[constants.LOADBALANCER, constants.UPDATE_DICT]))
        if mark_active:
            post_create_lb_flow.add(
                database_tasks.MarkLBActiveInDB(
                    name=sf_name + '-' + constants.MARK_LB_ACTIVE_INDB,
                    requires=constants.LOADBALANCER))
        return post_create_lb_flow
Ejemplo n.º 19
0
    def get_failover_flow(self,
                          role=constants.ROLE_STANDALONE,
                          status=constants.AMPHORA_READY):
        """Creates a flow to failover a stale amphora

        :returns: The flow for amphora failover
        """

        failover_amphora_flow = linear_flow.Flow(
            constants.FAILOVER_AMPHORA_FLOW)

        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(
            database_tasks.MarkAmphoraPendingDeleteInDB(
                rebind={constants.AMPHORA: constants.FAILED_AMPHORA},
                requires=constants.AMPHORA))
        failover_amphora_flow.add(
            database_tasks.MarkAmphoraHealthBusy(
                rebind={constants.AMPHORA: constants.FAILED_AMPHORA},
                requires=constants.AMPHORA))
        failover_amphora_flow.add(
            compute_tasks.ComputeDelete(
                rebind={constants.AMPHORA: constants.FAILED_AMPHORA},
                requires=constants.AMPHORA))
        failover_amphora_flow.add(
            network_tasks.WaitForPortDetach(
                rebind={constants.AMPHORA: constants.FAILED_AMPHORA},
                requires=constants.AMPHORA))
        failover_amphora_flow.add(
            database_tasks.DisableAmphoraHealthMonitoring(
                rebind={constants.AMPHORA: constants.FAILED_AMPHORA},
                requires=constants.AMPHORA))
        failover_amphora_flow.add(
            database_tasks.MarkAmphoraDeletedInDB(
                rebind={constants.AMPHORA: constants.FAILED_AMPHORA},
                requires=constants.AMPHORA))

        # If this is an unallocated amp (spares pool), we're done
        if status != constants.AMPHORA_ALLOCATED:
            return failover_amphora_flow

        # Save failed amphora details for later
        failover_amphora_flow.add(
            database_tasks.GetAmphoraDetails(
                rebind={constants.AMPHORA: constants.FAILED_AMPHORA},
                requires=constants.AMPHORA,
                provides=constants.AMP_DATA))

        # Get a new amphora
        # Note: Role doesn't matter here.  We will update it later.
        get_amp_subflow = self.get_amphora_for_lb_subflow(
            prefix=constants.FAILOVER_AMPHORA_FLOW)
        failover_amphora_flow.add(get_amp_subflow)

        # Update the new amphora with the failed amphora details
        failover_amphora_flow.add(
            database_tasks.UpdateAmpFailoverDetails(
                requires=(constants.AMPHORA, constants.AMP_DATA)))

        # Update the data stored in the flow from the database
        failover_amphora_flow.add(
            database_tasks.ReloadLoadBalancer(
                requires=constants.LOADBALANCER_ID,
                provides=constants.LOADBALANCER))

        failover_amphora_flow.add(
            database_tasks.ReloadAmphora(requires=constants.AMPHORA_ID,
                                         provides=constants.AMPHORA))

        # Prepare to reconnect the network interface(s)
        failover_amphora_flow.add(
            network_tasks.GetAmphoraeNetworkConfigs(
                requires=constants.LOADBALANCER,
                provides=constants.AMPHORAE_NETWORK_CONFIG))
        failover_amphora_flow.add(
            database_tasks.GetListenersFromLoadbalancer(
                requires=constants.LOADBALANCER, provides=constants.LISTENERS))

        failover_amphora_flow.add(
            amphora_driver_tasks.ListenersUpdate(
                requires=(constants.LOADBALANCER, constants.LISTENERS)))

        # Plug the VIP ports into the new amphora
        failover_amphora_flow.add(
            network_tasks.PlugVIPPort(
                requires=(constants.AMPHORA,
                          constants.AMPHORAE_NETWORK_CONFIG)))
        failover_amphora_flow.add(
            amphora_driver_tasks.AmphoraPostVIPPlug(
                requires=(constants.AMPHORA, constants.LOADBALANCER,
                          constants.AMPHORAE_NETWORK_CONFIG)))

        # Plug the member networks into the new amphora
        failover_amphora_flow.add(
            network_tasks.CalculateDelta(requires=constants.LOADBALANCER,
                                         provides=constants.DELTAS))
        failover_amphora_flow.add(
            network_tasks.HandleNetworkDeltas(requires=constants.DELTAS,
                                              provides=constants.ADDED_PORTS))
        failover_amphora_flow.add(
            amphora_driver_tasks.AmphoraePostNetworkPlug(
                requires=(constants.LOADBALANCER, constants.ADDED_PORTS)))

        # Handle the amphora role and VRRP if necessary
        if role == constants.ROLE_MASTER:
            failover_amphora_flow.add(
                database_tasks.MarkAmphoraMasterInDB(
                    name=constants.MARK_AMP_MASTER_INDB,
                    requires=constants.AMPHORA))
            vrrp_subflow = self.get_vrrp_subflow(role)
            failover_amphora_flow.add(vrrp_subflow)
        elif role == constants.ROLE_BACKUP:
            failover_amphora_flow.add(
                database_tasks.MarkAmphoraBackupInDB(
                    name=constants.MARK_AMP_BACKUP_INDB,
                    requires=constants.AMPHORA))
            vrrp_subflow = self.get_vrrp_subflow(role)
            failover_amphora_flow.add(vrrp_subflow)
        elif role == constants.ROLE_STANDALONE:
            failover_amphora_flow.add(
                database_tasks.MarkAmphoraStandAloneInDB(
                    name=constants.MARK_AMP_STANDALONE_INDB,
                    requires=constants.AMPHORA))

        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
Ejemplo n.º 20
0
    def get_failover_flow(self,
                          role=constants.ROLE_STANDALONE,
                          status=constants.AMPHORA_READY):
        """Creates a flow to failover a stale amphora

        :returns: The flow for amphora failover
        """

        failover_amphora_flow = linear_flow.Flow(
            constants.FAILOVER_AMPHORA_FLOW)

        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))

        # Note: It seems intuitive to boot an amphora prior to deleting
        #       the old amphora, however this is a complicated issue.
        #       If the target host (due to anit-affinity) is resource
        #       constrained, this will fail where a post-delete will
        #       succeed. Since this is async with the API it would result
        #       in the LB ending in ERROR though the amps are still alive.
        #       Consider in the future making this a complicated
        #       try-on-failure-retry flow, or move upgrade failovers to be
        #       synchronous with the API. For now spares pool and act/stdby
        #       will mitigate most of this delay.

        # Delete the old amphora
        failover_amphora_flow.add(
            database_tasks.MarkAmphoraPendingDeleteInDB(
                rebind={constants.AMPHORA: constants.FAILED_AMPHORA},
                requires=constants.AMPHORA))
        failover_amphora_flow.add(
            database_tasks.MarkAmphoraHealthBusy(
                rebind={constants.AMPHORA: constants.FAILED_AMPHORA},
                requires=constants.AMPHORA))
        failover_amphora_flow.add(
            compute_tasks.ComputeDelete(
                rebind={constants.AMPHORA: constants.FAILED_AMPHORA},
                requires=constants.AMPHORA))
        failover_amphora_flow.add(
            network_tasks.WaitForPortDetach(
                rebind={constants.AMPHORA: constants.FAILED_AMPHORA},
                requires=constants.AMPHORA))
        failover_amphora_flow.add(
            database_tasks.DisableAmphoraHealthMonitoring(
                rebind={constants.AMPHORA: constants.FAILED_AMPHORA},
                requires=constants.AMPHORA))
        failover_amphora_flow.add(
            database_tasks.MarkAmphoraDeletedInDB(
                rebind={constants.AMPHORA: constants.FAILED_AMPHORA},
                requires=constants.AMPHORA))

        # If this is an unallocated amp (spares pool), we're done
        if status != constants.AMPHORA_ALLOCATED:
            return failover_amphora_flow

        # Save failed amphora details for later
        failover_amphora_flow.add(
            database_tasks.GetAmphoraDetails(
                rebind={constants.AMPHORA: constants.FAILED_AMPHORA},
                requires=constants.AMPHORA,
                provides=constants.AMP_DATA))

        # Get a new amphora
        # Note: Role doesn't matter here.  We will update it later.
        get_amp_subflow = self.get_amphora_for_lb_subflow(
            prefix=constants.FAILOVER_AMPHORA_FLOW)
        failover_amphora_flow.add(get_amp_subflow)

        # Update the new amphora with the failed amphora details
        failover_amphora_flow.add(
            database_tasks.UpdateAmpFailoverDetails(
                requires=(constants.AMPHORA, constants.AMP_DATA)))

        # Update the data stored in the flow from the database
        failover_amphora_flow.add(
            database_tasks.ReloadLoadBalancer(
                requires=constants.LOADBALANCER_ID,
                provides=constants.LOADBALANCER))

        failover_amphora_flow.add(
            database_tasks.ReloadAmphora(requires=constants.AMPHORA_ID,
                                         provides=constants.AMPHORA))

        # Prepare to reconnect the network interface(s)
        failover_amphora_flow.add(
            network_tasks.GetAmphoraeNetworkConfigs(
                requires=constants.LOADBALANCER,
                provides=constants.AMPHORAE_NETWORK_CONFIG))
        failover_amphora_flow.add(
            database_tasks.GetListenersFromLoadbalancer(
                requires=constants.LOADBALANCER, provides=constants.LISTENERS))

        failover_amphora_flow.add(
            amphora_driver_tasks.ListenersUpdate(
                requires=(constants.LOADBALANCER, constants.LISTENERS)))

        # Plug the VIP ports into the new amphora
        failover_amphora_flow.add(
            network_tasks.PlugVIPPort(
                requires=(constants.AMPHORA,
                          constants.AMPHORAE_NETWORK_CONFIG)))
        failover_amphora_flow.add(
            amphora_driver_tasks.AmphoraPostVIPPlug(
                requires=(constants.AMPHORA, constants.LOADBALANCER,
                          constants.AMPHORAE_NETWORK_CONFIG)))

        # Plug the member networks into the new amphora
        failover_amphora_flow.add(
            network_tasks.CalculateDelta(requires=constants.LOADBALANCER,
                                         provides=constants.DELTAS))
        failover_amphora_flow.add(
            network_tasks.HandleNetworkDeltas(requires=constants.DELTAS,
                                              provides=constants.ADDED_PORTS))
        failover_amphora_flow.add(
            amphora_driver_tasks.AmphoraePostNetworkPlug(
                requires=(constants.LOADBALANCER, constants.ADDED_PORTS)))

        # Handle the amphora role and VRRP if necessary
        if role == constants.ROLE_MASTER:
            failover_amphora_flow.add(
                database_tasks.MarkAmphoraMasterInDB(
                    name=constants.MARK_AMP_MASTER_INDB,
                    requires=constants.AMPHORA))
            vrrp_subflow = self.get_vrrp_subflow(role)
            failover_amphora_flow.add(vrrp_subflow)
        elif role == constants.ROLE_BACKUP:
            failover_amphora_flow.add(
                database_tasks.MarkAmphoraBackupInDB(
                    name=constants.MARK_AMP_BACKUP_INDB,
                    requires=constants.AMPHORA))
            vrrp_subflow = self.get_vrrp_subflow(role)
            failover_amphora_flow.add(vrrp_subflow)
        elif role == constants.ROLE_STANDALONE:
            failover_amphora_flow.add(
                database_tasks.MarkAmphoraStandAloneInDB(
                    name=constants.MARK_AMP_STANDALONE_INDB,
                    requires=constants.AMPHORA))

        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