def get_create_load_balancer_flow(self, topology, listeners=None):
        """Creates a conditional graph flow that allocates a loadbalancer to

        two spare amphorae.
        :raises InvalidTopology: Invalid topology specified
        :return: The graph flow for creating a loadbalancer.
        """
        f_name = constants.CREATE_LOADBALANCER_FLOW
        lb_create_flow = linear_flow.Flow(f_name)

        lb_create_flow.add(
            lifecycle_tasks.LoadBalancerIDToErrorOnRevertTask(
                requires=constants.LOADBALANCER_ID))

        if topology == constants.TOPOLOGY_ACTIVE_STANDBY:
            lb_create_flow.add(*self._create_active_standby_topology())
        elif topology == constants.TOPOLOGY_SINGLE:
            lb_create_flow.add(*self._create_single_topology())
        else:
            LOG.error(
                _LE("Unknown topology: %s.  Unable to build load "
                    "balancer."), topology)
            raise exceptions.InvalidTopology(topology=topology)

        post_amp_prefix = constants.POST_LB_AMP_ASSOCIATION_SUBFLOW
        lb_create_flow.add(
            self.get_post_lb_amp_association_flow(post_amp_prefix, topology))

        if listeners:
            lb_create_flow.add(*self._create_listeners_flow())

        return lb_create_flow
    def get_create_load_balancer_flow(self, topology, listeners=None):
        """Flow to create a load balancer"""

        f_name = constants.CREATE_LOADBALANCER_FLOW
        lb_create_flow = linear_flow.Flow(f_name)
        lb_create_flow.add(
            lifecycle_tasks.LoadBalancerIDToErrorOnRevertTask(
                requires=constants.LOADBALANCER_ID))

        # Attaching vThunder to LB in database
        if topology == constants.TOPOLOGY_ACTIVE_STANDBY:
            lb_create_flow.add(*self._create_active_standby_topology())
            LOG.info("TOPOLOGY ===" + str(topology))
        elif topology == constants.TOPOLOGY_SINGLE:
            lb_create_flow.add(*self._create_single_topology())
            LOG.info("TOPOLOGY ===" + str(topology))
        else:
            LOG.error("Unknown topology: %s.  Unable to build load balancer.",
                      topology)
            raise exceptions.InvalidTopology(topology=topology)

        # IMP: Now creating vThunder config here
        post_amp_prefix = constants.POST_LB_AMP_ASSOCIATION_SUBFLOW
        lb_create_flow.add(
            self.get_post_lb_vthunder_association_flow(
                post_amp_prefix, topology, mark_active=(not listeners)))
        lb_create_flow.add(
            virtual_server_tasks.CreateVirtualServerTask(
                requires=(constants.LOADBALANCER, a10constants.VTHUNDER)))
        lb_create_flow.add(
            vthunder_tasks.WriteMemory(requires=a10constants.VTHUNDER))
        return lb_create_flow
    def get_create_rack_vthunder_load_balancer_flow(self,
                                                    vthunder_conf,
                                                    topology,
                                                    listeners=None):
        """Creates a linear flow to create rack vthunder

        :return: The linear flow for creating a loadbalancer.
        """
        f_name = constants.CREATE_LOADBALANCER_FLOW
        lb_create_flow = linear_flow.Flow(f_name)

        lb_create_flow.add(
            lifecycle_tasks.LoadBalancerIDToErrorOnRevertTask(
                requires=constants.LOADBALANCER_ID))

        lb_create_flow.add(
            self.vthunder_flows.get_rack_vthunder_for_lb_subflow(
                vthunder_conf=vthunder_conf,
                prefix=constants.ROLE_STANDALONE,
                role=constants.ROLE_STANDALONE))
        post_amp_prefix = constants.POST_LB_AMP_ASSOCIATION_SUBFLOW
        lb_create_flow.add(
            self.get_post_lb_rack_vthunder_association_flow(
                post_amp_prefix, topology, mark_active=(not listeners)))

        lb_create_flow.add(
            virtual_server_tasks.CreateVirtualServerTask(
                requires=(constants.LOADBALANCER, a10constants.VTHUNDER),
                provides=a10constants.STATUS))

        return lb_create_flow
    def get_create_rack_vthunder_load_balancer_flow(self,
                                                    vthunder_conf,
                                                    topology,
                                                    listeners=None):
        """Flow to create rack load balancer"""

        f_name = constants.CREATE_LOADBALANCER_FLOW
        lb_create_flow = linear_flow.Flow(f_name)

        lb_create_flow.add(
            lifecycle_tasks.LoadBalancerIDToErrorOnRevertTask(
                requires=constants.LOADBALANCER_ID))
        lb_create_flow.add(
            database_tasks.ReloadLoadBalancer(
                requires=constants.LOADBALANCER_ID,
                provides=constants.LOADBALANCER))
        lb_create_flow.add(
            a10_database_tasks.CheckExistingProjectToThunderMappedEntries(
                inject={a10constants.VTHUNDER_CONFIG: vthunder_conf},
                requires=(constants.LOADBALANCER,
                          a10constants.VTHUNDER_CONFIG),
                provides=a10constants.VTHUNDER_CONFIG))
        lb_create_flow.add(
            a10_database_tasks.CheckExistingThunderToProjectMappedEntries(
                requires=(constants.LOADBALANCER,
                          a10constants.VTHUNDER_CONFIG)))
        lb_create_flow.add(
            self.vthunder_flows.get_rack_vthunder_for_lb_subflow(
                vthunder_conf=a10constants.VTHUNDER_CONFIG,
                prefix=constants.ROLE_STANDALONE,
                role=constants.ROLE_STANDALONE))
        post_amp_prefix = constants.POST_LB_AMP_ASSOCIATION_SUBFLOW
        lb_create_flow.add(
            self.get_post_lb_rack_vthunder_association_flow(
                post_amp_prefix, topology, mark_active=(not listeners)))
        lb_create_flow.add(
            a10_database_tasks.GetFlavorData(
                rebind={a10constants.LB_RESOURCE: constants.LOADBALANCER},
                provides=constants.FLAVOR_DATA))
        lb_create_flow.add(
            nat_pool_tasks.NatPoolCreate(requires=(constants.LOADBALANCER,
                                                   a10constants.VTHUNDER,
                                                   constants.FLAVOR_DATA)))
        lb_create_flow.add(
            virtual_server_tasks.CreateVirtualServerTask(
                requires=(constants.LOADBALANCER, a10constants.VTHUNDER,
                          constants.FLAVOR_DATA),
                provides=a10constants.STATUS))
        lb_create_flow.add(
            vthunder_tasks.WriteMemory(requires=a10constants.VTHUNDER))
        lb_create_flow.add(
            a10_database_tasks.SetThunderUpdatedAt(
                requires=a10constants.VTHUNDER))
        return lb_create_flow
    def get_create_load_balancer_flow(self, topology, listeners=None):
        """Creates a conditional graph flow that allocates a loadbalancer to

        two spare amphorae.
        :raises InvalidTopology: Invalid topology specified
        :return: The graph flow for creating a loadbalancer.
        """
        f_name = constants.CREATE_LOADBALANCER_FLOW
        lb_create_flow = linear_flow.Flow(f_name)

        lb_create_flow.add(lifecycle_tasks.LoadBalancerIDToErrorOnRevertTask(
            requires=constants.LOADBALANCER_ID))

        # allocate VIP
        lb_create_flow.add(database_tasks.ReloadLoadBalancer(
            name=constants.RELOAD_LB_BEFOR_ALLOCATE_VIP,
            requires=constants.LOADBALANCER_ID,
            provides=constants.LOADBALANCER
        ))
        lb_create_flow.add(network_tasks.AllocateVIP(
            requires=constants.LOADBALANCER,
            provides=constants.VIP))
        lb_create_flow.add(database_tasks.UpdateVIPAfterAllocation(
            requires=(constants.LOADBALANCER_ID, constants.VIP),
            provides=constants.LOADBALANCER))
        lb_create_flow.add(network_tasks.UpdateVIPSecurityGroup(
            requires=constants.LOADBALANCER))
        lb_create_flow.add(network_tasks.GetSubnetFromVIP(
            requires=constants.LOADBALANCER,
            provides=constants.SUBNET))

        if topology == constants.TOPOLOGY_ACTIVE_STANDBY:
            lb_create_flow.add(*self._create_active_standby_topology())
        elif topology == constants.TOPOLOGY_SINGLE:
            lb_create_flow.add(*self._create_single_topology())
        else:
            LOG.error("Unknown topology: %s.  Unable to build load balancer.",
                      topology)
            raise exceptions.InvalidTopology(topology=topology)

        post_amp_prefix = constants.POST_LB_AMP_ASSOCIATION_SUBFLOW
        lb_create_flow.add(
            self.get_post_lb_amp_association_flow(
                post_amp_prefix, topology, mark_active=(not listeners)))

        if listeners:
            lb_create_flow.add(*self._create_listeners_flow())

        return lb_create_flow
    def test_LoadBalancerIDToErrorOnRevertTask(
            self, mock_loadbalancer_prov_status_error):

        loadbalancer_id_to_error_on_revert = (
            lifecycle_tasks.LoadBalancerIDToErrorOnRevertTask())

        # Execute
        loadbalancer_id_to_error_on_revert.execute(self.LOADBALANCER_ID)

        self.assertFalse(mock_loadbalancer_prov_status_error.called)

        # Revert
        loadbalancer_id_to_error_on_revert.revert(self.LOADBALANCER_ID)

        mock_loadbalancer_prov_status_error.assert_called_once_with(
            self.LOADBALANCER_ID)