def get_create_member_flow(self, topology): """Create a flow to create a member :returns: The flow for creating a member """ create_member_flow = linear_flow.Flow(constants.CREATE_MEMBER_FLOW) create_member_flow.add( lifecycle_tasks.MemberToErrorOnRevertTask(requires=[ constants.MEMBER, constants.LISTENERS, constants.LOADBALANCER, constants.POOL ])) create_member_flow.add( database_tasks.MarkMemberPendingCreateInDB( requires=constants.MEMBER)) create_member_flow.add( a10_database_tasks.GetVThunderByLoadBalancer( requires=constants.LOADBALANCER, provides=a10constants.VTHUNDER)) create_member_flow.add( a10_database_tasks.GetLoadBalancerListByProjectID( requires=a10constants.VTHUNDER, provides=a10constants.LOADBALANCERS_LIST)) create_member_flow.add( database_tasks.GetAmphoraeFromLoadbalancer( requires=constants.LOADBALANCER, provides=constants.AMPHORA)) create_member_flow.add( a10_network_tasks.CalculateDelta( requires=(constants.LOADBALANCER, a10constants.LOADBALANCERS_LIST), provides=constants.DELTAS)) create_member_flow.add( a10_network_tasks.HandleNetworkDeltas( requires=constants.DELTAS, provides=constants.ADDED_PORTS)) # managing interface additions here create_member_flow.add( vthunder_tasks.AmphoraePostMemberNetworkPlug( requires=(constants.LOADBALANCER, constants.ADDED_PORTS, a10constants.VTHUNDER))) create_member_flow.add( vthunder_tasks.VThunderComputeConnectivityWait( requires=(a10constants.VTHUNDER, constants.AMPHORA))) create_member_flow.add( vthunder_tasks.EnableInterfaceForMembers(requires=[ constants.ADDED_PORTS, constants.LOADBALANCER, a10constants.VTHUNDER ])) create_member_flow.add(self.handle_vrid_for_member_subflow()) # configure member flow for HA if topology == constants.TOPOLOGY_ACTIVE_STANDBY: create_member_flow.add( a10_database_tasks.GetBackupVThunderByLoadBalancer( name="get_backup_vThunder", requires=constants.LOADBALANCER, provides=a10constants.BACKUP_VTHUNDER)) create_member_flow.add( vthunder_tasks.AmphoraePostMemberNetworkPlug( name="backup_amphora_network_plug", requires=[constants.ADDED_PORTS, constants.LOADBALANCER], rebind={ a10constants.VTHUNDER: a10constants.BACKUP_VTHUNDER })) create_member_flow.add( vthunder_tasks.VThunderComputeConnectivityWait( name="backup_compute_conn_wait", requires=constants.AMPHORA, rebind={ a10constants.VTHUNDER: a10constants.BACKUP_VTHUNDER })) create_member_flow.add( vthunder_tasks.EnableInterfaceForMembers( name="backup_enable_interface", requires=[constants.ADDED_PORTS, constants.LOADBALANCER], rebind={ a10constants.VTHUNDER: a10constants.BACKUP_VTHUNDER })) create_member_flow.add( a10_database_tasks.CountMembersWithIP( requires=constants.MEMBER, provides=a10constants.MEMBER_COUNT_IP)) create_member_flow.add( a10_database_tasks.GetFlavorData( rebind={a10constants.LB_RESOURCE: constants.LOADBALANCER}, provides=constants.FLAVOR)) create_member_flow.add(self.get_create_member_snat_pool_subflow()) create_member_flow.add( server_tasks.MemberCreate(requires=(constants.MEMBER, a10constants.VTHUNDER, constants.POOL, a10constants.MEMBER_COUNT_IP, constants.FLAVOR))) create_member_flow.add( database_tasks.MarkMemberActiveInDB(requires=constants.MEMBER)) create_member_flow.add( database_tasks.MarkPoolActiveInDB(requires=constants.POOL)) create_member_flow.add( database_tasks.MarkLBAndListenersActiveInDB( requires=(constants.LOADBALANCER, constants.LISTENERS))) create_member_flow.add( vthunder_tasks.WriteMemory(requires=a10constants.VTHUNDER)) create_member_flow.add( a10_database_tasks.SetThunderUpdatedAt( requires=a10constants.VTHUNDER)) return create_member_flow
def get_failover_flow(self, role=constants.ROLE_STANDALONE, load_balancer=None): """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)) # 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.MarkAmphoraDeletedInDB( rebind={constants.AMPHORA: constants.FAILED_AMPHORA}, requires=constants.AMPHORA)) # If this is an unallocated amp (spares pool), we're done if not load_balancer: failover_amphora_flow.add( database_tasks.DisableAmphoraHealthMonitoring( rebind={constants.AMPHORA: constants.FAILED_AMPHORA}, requires=constants.AMPHORA)) 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( database_tasks.GetAmphoraeFromLoadbalancer( requires=constants.LOADBALANCER, provides=constants.AMPHORAE)) # Plug the VIP ports into the new amphora # The reason for moving these steps here is the udp listeners want to # do some kernel configuration before Listener update for forbidding # failure during rebuild 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))) # Listeners update needs to be run on all amphora to update # their peer configurations. So parallelize this with an # unordered subflow. update_amps_subflow = unordered_flow.Flow( constants.UPDATE_AMPS_SUBFLOW) timeout_dict = { constants.CONN_MAX_RETRIES: CONF.haproxy_amphora.active_connection_max_retries, constants.CONN_RETRY_INTERVAL: CONF.haproxy_amphora.active_connection_rety_interval } # Setup parallel flows for each amp. We don't know the new amp # details at flow creation time, so setup a subflow for each # amp on the LB, they let the task index into a list of amps # to find the amphora it should work on. amp_index = 0 for amp in load_balancer.amphorae: if amp.status == constants.DELETED: continue update_amps_subflow.add( amphora_driver_tasks.AmpListenersUpdate( name=constants.AMP_LISTENER_UPDATE + '-' + str(amp_index), requires=(constants.LISTENERS, constants.AMPHORAE), inject={ constants.AMPHORA_INDEX: amp_index, constants.TIMEOUT_DICT: timeout_dict })) amp_index += 1 failover_amphora_flow.add(update_amps_subflow) # Plug the member networks into the new amphora failover_amphora_flow.add( network_tasks.CalculateAmphoraDelta( requires=(constants.LOADBALANCER, constants.AMPHORA), provides=constants.DELTA)) failover_amphora_flow.add( network_tasks.HandleNetworkDelta(requires=(constants.AMPHORA, constants.DELTA), provides=constants.ADDED_PORTS)) failover_amphora_flow.add( amphora_driver_tasks.AmphoraePostNetworkPlug( requires=(constants.LOADBALANCER, constants.ADDED_PORTS))) failover_amphora_flow.add( database_tasks.ReloadLoadBalancer( name='octavia-failover-LB-reload-2', requires=constants.LOADBALANCER_ID, provides=constants.LOADBALANCER)) # 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, constants.AMPHORA))) failover_amphora_flow.add( database_tasks.DisableAmphoraHealthMonitoring( rebind={constants.AMPHORA: constants.FAILED_AMPHORA}, requires=constants.AMPHORA)) return failover_amphora_flow
def get_create_member_flow(self, topology): """Create a flow to create a member :returns: The flow for creating a member """ create_member_flow = linear_flow.Flow(constants.CREATE_MEMBER_FLOW) create_member_flow.add(lifecycle_tasks.MemberToErrorOnRevertTask( requires=[constants.MEMBER, constants.LISTENERS, constants.LOADBALANCER, constants.POOL])) create_member_flow.add(vthunder_tasks.VthunderInstanceBusy( requires=a10constants.COMPUTE_BUSY)) create_member_flow.add(database_tasks.MarkMemberPendingCreateInDB( requires=constants.MEMBER)) create_member_flow.add(a10_database_tasks.GetVThunderByLoadBalancer( requires=constants.LOADBALANCER, provides=a10constants.VTHUNDER)) create_member_flow.add(a10_database_tasks.GetLoadBalancerListByProjectID( requires=a10constants.VTHUNDER, provides=a10constants.LOADBALANCERS_LIST)) create_member_flow.add(database_tasks.GetAmphoraeFromLoadbalancer( requires=constants.LOADBALANCER, provides=constants.AMPHORA)) create_member_flow.add(a10_network_tasks.CalculateDelta( requires=(constants.LOADBALANCER, a10constants.LOADBALANCERS_LIST), provides=constants.DELTAS)) create_member_flow.add(a10_network_tasks.HandleNetworkDeltas( requires=constants.DELTAS, provides=constants.ADDED_PORTS)) # managing interface additions here if topology == constants.TOPOLOGY_SINGLE: create_member_flow.add( vthunder_tasks.AmphoraePostMemberNetworkPlug( requires=( constants.LOADBALANCER, constants.ADDED_PORTS, a10constants.VTHUNDER))) create_member_flow.add(vthunder_tasks.VThunderComputeConnectivityWait( name=a10constants.VTHUNDER_CONNECTIVITY_WAIT, requires=(a10constants.VTHUNDER, constants.AMPHORA))) create_member_flow.add( vthunder_tasks.EnableInterfaceForMembers( requires=[ constants.ADDED_PORTS, constants.LOADBALANCER, a10constants.VTHUNDER])) # configure member flow for HA if topology == constants.TOPOLOGY_ACTIVE_STANDBY: create_member_flow.add( a10_database_tasks.GetBackupVThunderByLoadBalancer( name="get_backup_vThunder", requires=(constants.LOADBALANCER, a10constants.VTHUNDER), provides=a10constants.BACKUP_VTHUNDER)) create_member_flow.add(vthunder_tasks.VThunderComputeConnectivityWait( name="backup_compute_conn_wait_before_probe_device", requires=constants.AMPHORA, rebind={a10constants.VTHUNDER: a10constants.BACKUP_VTHUNDER})) create_member_flow.add(vthunder_tasks.VCSSyncWait( name="vcs_sync_wait_before_probe_device", requires=a10constants.VTHUNDER)) create_member_flow.add( vthunder_tasks.AmphoraePostMemberNetworkPlug( requires=( constants.LOADBALANCER, constants.ADDED_PORTS, a10constants.VTHUNDER))) create_member_flow.add( vthunder_tasks.AmphoraePostMemberNetworkPlug( name="backup_amphora_network_plug", requires=[ constants.ADDED_PORTS, constants.LOADBALANCER], rebind={ a10constants.VTHUNDER: a10constants.BACKUP_VTHUNDER})) create_member_flow.add(vthunder_tasks.VThunderComputeConnectivityWait( name=a10constants.MASTER_CONNECTIVITY_WAIT, requires=(a10constants.VTHUNDER, constants.AMPHORA))) create_member_flow.add(vthunder_tasks.VThunderComputeConnectivityWait( name=a10constants.BACKUP_CONNECTIVITY_WAIT, requires=constants.AMPHORA, rebind={a10constants.VTHUNDER: a10constants.BACKUP_VTHUNDER})) create_member_flow.add(vthunder_tasks.VCSSyncWait( name="backup-plug-wait-vcs-ready", requires=a10constants.VTHUNDER)) create_member_flow.add(vthunder_tasks.GetMasterVThunder( name=a10constants.GET_MASTER_VTHUNDER, requires=a10constants.VTHUNDER, provides=a10constants.VTHUNDER)) create_member_flow.add(a10_database_tasks.GetBackupVThunderByLoadBalancer( name="get_backup_vThunder_after_get_master", requires=(constants.LOADBALANCER, a10constants.VTHUNDER), provides=a10constants.BACKUP_VTHUNDER)) create_member_flow.add( vthunder_tasks.EnableInterfaceForMembers( name=a10constants.ENABLE_MASTER_VTHUNDER_INTERFACE, requires=[ constants.ADDED_PORTS, constants.LOADBALANCER, a10constants.VTHUNDER])) create_member_flow.add(vthunder_tasks.AmphoraePostMemberNetworkPlug( name="amphorae-post-member-network-plug-for-master", requires=(constants.LOADBALANCER, constants.ADDED_PORTS, a10constants.VTHUNDER))) create_member_flow.add( vthunder_tasks.VThunderComputeConnectivityWait( name=a10constants.CONNECTIVITY_WAIT_FOR_MASTER_VTHUNDER, requires=(a10constants.VTHUNDER, constants.AMPHORA))) create_member_flow.add( vthunder_tasks.VThunderComputeConnectivityWait( name=a10constants.CONNECTIVITY_WAIT_FOR_BACKUP_VTHUNDER, rebind={ a10constants.VTHUNDER: a10constants.BACKUP_VTHUNDER}, requires=constants.AMPHORA)) create_member_flow.add(vthunder_tasks.VCSSyncWait( name="member_enable_interface_vcs_sync_wait", requires=a10constants.VTHUNDER)) create_member_flow.add(vthunder_tasks.GetMasterVThunder( name=a10constants.GET_VTHUNDER_MASTER, requires=a10constants.VTHUNDER, provides=a10constants.VTHUNDER)) create_member_flow.add( vthunder_tasks.EnableInterfaceForMembers( requires=[ constants.ADDED_PORTS, constants.LOADBALANCER, a10constants.VTHUNDER])) create_member_flow.add(self.handle_vrid_for_member_subflow()) create_member_flow.add(a10_database_tasks.CountMembersWithIP( requires=constants.MEMBER, provides=a10constants.MEMBER_COUNT_IP )) create_member_flow.add(vthunder_tasks.AllowLoadbalancerForwardWithAnySource( name=a10constants.ALLOW_NO_SNAT, requires=(constants.MEMBER, constants.AMPHORA))) create_member_flow.add(a10_database_tasks.GetFlavorData( rebind={a10constants.LB_RESOURCE: constants.LOADBALANCER}, provides=constants.FLAVOR)) create_member_flow.add(self.get_create_member_snat_pool_subflow()) create_member_flow.add(server_tasks.MemberCreate( requires=(constants.MEMBER, a10constants.VTHUNDER, constants.POOL, a10constants.MEMBER_COUNT_IP, constants.FLAVOR))) create_member_flow.add(database_tasks.MarkMemberActiveInDB( requires=constants.MEMBER)) create_member_flow.add(database_tasks.MarkPoolActiveInDB( requires=constants.POOL)) create_member_flow.add(database_tasks. MarkLBAndListenersActiveInDB( requires=(constants.LOADBALANCER, constants.LISTENERS))) create_member_flow.add(vthunder_tasks.WriteMemory( requires=a10constants.VTHUNDER)) create_member_flow.add(a10_database_tasks.SetThunderUpdatedAt( requires=a10constants.VTHUNDER)) return create_member_flow
def get_delete_member_flow(self): """Flow to delete a member on VThunder :returns: The flow for deleting a member """ delete_member_flow = linear_flow.Flow(constants.DELETE_MEMBER_FLOW) delete_member_flow.add( lifecycle_tasks.MemberToErrorOnRevertTask(requires=[ constants.MEMBER, constants.LISTENERS, constants.LOADBALANCER, constants.POOL ])) delete_member_flow.add( database_tasks.MarkMemberPendingDeleteInDB( requires=constants.MEMBER)) delete_member_flow.add( model_tasks.DeleteModelObject( rebind={constants.OBJECT: constants.MEMBER})) delete_member_flow.add( database_tasks.GetAmphoraeFromLoadbalancer( requires=constants.LOADBALANCER, provides=constants.AMPHORA)) delete_member_flow.add( a10_database_tasks.GetVThunderByLoadBalancer( requires=constants.LOADBALANCER, provides=a10constants.VTHUNDER)) delete_member_flow.add( a10_database_tasks.CountMembersWithIP( requires=constants.MEMBER, provides=a10constants.MEMBER_COUNT_IP)) delete_member_flow.add( a10_database_tasks.CountMembersWithIPPortProtocol( requires=(constants.MEMBER, constants.POOL), provides=a10constants.MEMBER_COUNT_IP_PORT_PROTOCOL)) delete_member_flow.add( a10_database_tasks.GetFlavorData( rebind={a10constants.LB_RESOURCE: constants.LOADBALANCER}, provides=constants.FLAVOR)) delete_member_flow.add( database_tasks.DeleteMemberInDB(requires=constants.MEMBER)) delete_member_flow.add( a10_database_tasks.GetLoadBalancerListByProjectID( requires=a10constants.VTHUNDER, provides=a10constants.LOADBALANCERS_LIST)) delete_member_flow.add( a10_network_tasks.CalculateDelta( requires=(constants.LOADBALANCER, a10constants.LOADBALANCERS_LIST), provides=constants.DELTAS)) delete_member_flow.add( a10_network_tasks.HandleNetworkDeltas( requires=constants.DELTAS, provides=constants.ADDED_PORTS)) delete_member_flow.add( vthunder_tasks.AmphoraePostNetworkUnplug( requires=(constants.LOADBALANCER, constants.ADDED_PORTS, a10constants.VTHUNDER))) delete_member_flow.add( vthunder_tasks.VThunderComputeConnectivityWait( requires=(a10constants.VTHUNDER, constants.AMPHORA))) delete_member_flow.add( server_tasks.MemberFindNatPool(requires=[ constants.MEMBER, a10constants.VTHUNDER, constants.POOL, constants.FLAVOR ], provides=a10constants.NAT_FLAVOR)) delete_member_flow.add( a10_database_tasks.GetNatPoolEntry( requires=[constants.MEMBER, a10constants.NAT_FLAVOR], provides=a10constants.NAT_POOL)) delete_member_flow.add( a10_network_tasks.ReleaseSubnetAddressForMember(requires=[ constants.MEMBER, a10constants.NAT_FLAVOR, a10constants.NAT_POOL ])) delete_member_flow.add( a10_database_tasks.DeleteNatPoolEntry( requires=a10constants.NAT_POOL)) delete_member_flow.add( server_tasks.MemberDelete( requires=(constants.MEMBER, a10constants.VTHUNDER, constants.POOL, a10constants.MEMBER_COUNT_IP, a10constants.MEMBER_COUNT_IP_PORT_PROTOCOL))) delete_member_flow.add(self.get_delete_member_vrid_subflow()) delete_member_flow.add( database_tasks.DecrementMemberQuota(requires=constants.MEMBER)) delete_member_flow.add( database_tasks.MarkPoolActiveInDB(requires=constants.POOL)) delete_member_flow.add( database_tasks.MarkLBAndListenersActiveInDB( requires=[constants.LOADBALANCER, constants.LISTENERS])) delete_member_flow.add( vthunder_tasks.WriteMemory(requires=a10constants.VTHUNDER)) delete_member_flow.add( a10_database_tasks.SetThunderUpdatedAt( requires=a10constants.VTHUNDER)) return delete_member_flow
def get_delete_member_flow(self, topology): """Flow to delete a member on VThunder :returns: The flow for deleting a member """ delete_member_flow = linear_flow.Flow(constants.DELETE_MEMBER_FLOW) delete_member_flow.add(lifecycle_tasks.MemberToErrorOnRevertTask( requires=[constants.MEMBER, constants.LISTENERS, constants.LOADBALANCER, constants.POOL])) delete_member_flow.add(vthunder_tasks.VthunderInstanceBusy( requires=a10constants.COMPUTE_BUSY)) delete_member_flow.add(database_tasks.MarkMemberPendingDeleteInDB( requires=constants.MEMBER)) delete_member_flow.add(model_tasks. DeleteModelObject(rebind={constants.OBJECT: constants.MEMBER})) delete_member_flow.add(database_tasks.GetAmphoraeFromLoadbalancer( requires=constants.LOADBALANCER, provides=constants.AMPHORA)) delete_member_flow.add(a10_database_tasks.GetVThunderByLoadBalancer( requires=constants.LOADBALANCER, provides=a10constants.VTHUNDER)) delete_member_flow.add(a10_database_tasks.CountMembersWithIP( requires=constants.MEMBER, provides=a10constants.MEMBER_COUNT_IP)) delete_member_flow.add( a10_database_tasks.CountMembersWithIPPortProtocol( requires=( constants.MEMBER, constants.POOL), provides=a10constants.MEMBER_COUNT_IP_PORT_PROTOCOL)) delete_member_flow.add(a10_database_tasks.GetFlavorData( rebind={a10constants.LB_RESOURCE: constants.LOADBALANCER}, provides=constants.FLAVOR)) delete_member_flow.add(a10_database_tasks.GetLoadBalancerListByProjectID( requires=a10constants.VTHUNDER, provides=a10constants.LOADBALANCERS_LIST)) delete_member_flow.add(a10_network_tasks.CalculateDelta( requires=(constants.LOADBALANCER, a10constants.LOADBALANCERS_LIST), provides=constants.DELTAS)) delete_member_flow.add(a10_network_tasks.HandleNetworkDeltas( requires=constants.DELTAS, provides=constants.ADDED_PORTS)) delete_member_flow.add( vthunder_tasks.AmphoraePostNetworkUnplug( requires=( constants.LOADBALANCER, constants.ADDED_PORTS, a10constants.VTHUNDER))) delete_member_flow.add(vthunder_tasks.VThunderComputeConnectivityWait( name=a10constants.VTHUNDER_CONNECTIVITY_WAIT, requires=(a10constants.VTHUNDER, constants.AMPHORA))) if topology == constants.TOPOLOGY_ACTIVE_STANDBY: delete_member_flow.add( a10_database_tasks.GetBackupVThunderByLoadBalancer( name=a10constants.GET_BACKUP_VTHUNDER_BY_LB, requires=(constants.LOADBALANCER, a10constants.VTHUNDER), provides=a10constants.BACKUP_VTHUNDER)) delete_member_flow.add( vthunder_tasks.VThunderComputeConnectivityWait( name=a10constants.BACKUP_CONNECTIVITY_WAIT + "-before-unplug", requires=constants.AMPHORA, rebind={a10constants.VTHUNDER: a10constants.BACKUP_VTHUNDER})) delete_member_flow.add( vthunder_tasks.AmphoraePostNetworkUnplug( name=a10constants.AMPHORA_POST_NETWORK_UNPLUG_FOR_BACKUP_VTHUNDER, requires=(constants.LOADBALANCER, constants.ADDED_PORTS), rebind={a10constants.VTHUNDER: a10constants.BACKUP_VTHUNDER})) delete_member_flow.add( vthunder_tasks.VThunderComputeConnectivityWait( name=a10constants.BACKUP_CONNECTIVITY_WAIT, requires=constants.AMPHORA, rebind={a10constants.VTHUNDER: a10constants.BACKUP_VTHUNDER})) delete_member_flow.add(vthunder_tasks.VCSSyncWait( name='member-unplug-' + a10constants.VCS_SYNC_WAIT, requires=a10constants.VTHUNDER)) delete_member_flow.add(vthunder_tasks.GetMasterVThunder( name=a10constants.GET_VTHUNDER_MASTER, requires=a10constants.VTHUNDER, provides=a10constants.VTHUNDER)) delete_member_flow.add(server_tasks.MemberFindNatPool( requires=[constants.MEMBER, a10constants.VTHUNDER, constants.POOL, constants.FLAVOR], provides=a10constants.NAT_FLAVOR)) delete_member_flow.add(a10_database_tasks.GetNatPoolEntry( requires=[constants.MEMBER, a10constants.NAT_FLAVOR], provides=a10constants.NAT_POOL)) delete_member_flow.add(a10_network_tasks.ReleaseSubnetAddressForMember( requires=[constants.MEMBER, a10constants.NAT_FLAVOR, a10constants.NAT_POOL])) delete_member_flow.add(a10_database_tasks.DeleteNatPoolEntry( requires=a10constants.NAT_POOL)) delete_member_flow.add( server_tasks.MemberDelete( requires=( constants.MEMBER, a10constants.VTHUNDER, constants.POOL, a10constants.MEMBER_COUNT_IP, a10constants.MEMBER_COUNT_IP_PORT_PROTOCOL))) delete_member_flow.add(self.get_delete_member_vrid_subflow()) delete_member_flow.add(database_tasks.DeleteMemberInDB( requires=constants.MEMBER)) delete_member_flow.add(database_tasks.DecrementMemberQuota( requires=constants.MEMBER)) delete_member_flow.add(database_tasks.MarkPoolActiveInDB( requires=constants.POOL)) delete_member_flow.add(database_tasks.MarkLBAndListenersActiveInDB( requires=[constants.LOADBALANCER, constants.LISTENERS])) delete_member_flow.add(vthunder_tasks.WriteMemory( requires=a10constants.VTHUNDER)) delete_member_flow.add(a10_database_tasks.SetThunderUpdatedAt( requires=a10constants.VTHUNDER)) return delete_member_flow
def get_new_lb_networking_subflow(self, topology): """Subflow to setup networking for amphora""" new_LB_net_subflow = linear_flow.Flow( constants.LOADBALANCER_NETWORKING_SUBFLOW) new_LB_net_subflow.add( a10_network_tasks.PlugVIP(requires=constants.LOADBALANCER, provides=constants.AMPS_DATA)) new_LB_net_subflow.add( a10_network_tasks.ApplyQos(requires=(constants.LOADBALANCER, constants.AMPS_DATA, constants.UPDATE_DICT))) new_LB_net_subflow.add( database_tasks.UpdateAmphoraeVIPData(requires=constants.AMPS_DATA)) new_LB_net_subflow.add( database_tasks.ReloadLoadBalancer( name=constants.RELOAD_LB_AFTER_PLUG_VIP, requires=constants.LOADBALANCER_ID, provides=constants.LOADBALANCER)) new_LB_net_subflow.add( a10_network_tasks.GetAmphoraeNetworkConfigs( requires=constants.LOADBALANCER, provides=constants.AMPHORAE_NETWORK_CONFIG)) new_LB_net_subflow.add( database_tasks.GetAmphoraeFromLoadbalancer( requires=constants.LOADBALANCER, provides=constants.AMPHORA)) new_LB_net_subflow.add( vthunder_tasks.VThunderComputeConnectivityWait( name=a10constants.MASTER_CONNECTIVITY_WAIT, requires=(a10constants.VTHUNDER, constants.AMPHORA))) new_LB_net_subflow.add( vthunder_tasks.EnableInterface(requires=a10constants.VTHUNDER)) new_LB_net_subflow.add( a10_database_tasks.MarkVThunderStatusInDB( name=a10constants.MARK_VTHUNDER_MASTER_ACTIVE_IN_DB, requires=a10constants.VTHUNDER, inject={a10constants.STATUS: constants.ACTIVE})) if topology == constants.TOPOLOGY_ACTIVE_STANDBY: new_LB_net_subflow.add( vthunder_tasks.CreateHealthMonitorOnVThunder( name=a10constants.CREATE_HEALTH_MONITOR_ON_VTHUNDER_MASTER, requires=a10constants.VTHUNDER)) new_LB_net_subflow.add( a10_database_tasks.GetBackupVThunderByLoadBalancer( name=a10constants.GET_BACKUP_VTHUNDER_BY_LB, requires=constants.LOADBALANCER, provides=a10constants.BACKUP_VTHUNDER)) new_LB_net_subflow.add( vthunder_tasks.VThunderComputeConnectivityWait( name=a10constants.BACKUP_CONNECTIVITY_WAIT, rebind={ a10constants.VTHUNDER: a10constants.BACKUP_VTHUNDER }, requires=constants.AMPHORA)) new_LB_net_subflow.add( vthunder_tasks.EnableInterface( name=a10constants.BACKUP_ENABLE_INTERFACE, rebind={ a10constants.VTHUNDER: a10constants.BACKUP_VTHUNDER })) new_LB_net_subflow.add( a10_database_tasks.MarkVThunderStatusInDB( name=a10constants.MARK_VTHUNDER_BACKUP_ACTIVE_IN_DB, rebind={ a10constants.VTHUNDER: a10constants.BACKUP_VTHUNDER }, inject={a10constants.STATUS: constants.ACTIVE})) return new_LB_net_subflow
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_network_tasks.CalculateDelta( requires=(constants.LOADBALANCER, a10constants.LOADBALANCERS_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, 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 get_extension_flow(self, distributor): """Extend a amphora for load balancer. :returns: The flow for loadbalancer extension """ extension_flow = linear_flow.Flow( constants.EXTENSION_LOADBALANCER_FLOW) get_amp_subflow = self.get_amphora_for_lb_subflow( prefix=constants.EXTENSION_LOADBALANCER_FLOW, role=constants.ROLE_ACTIVE) extension_flow.add(get_amp_subflow) # Update the data stored in the flow from the database extension_flow.add( database_tasks.ReloadLoadBalancer( name='first', requires=constants.LOADBALANCER_ID, provides=constants.LOADBALANCER)) extension_flow.add( network_tasks.PlugAmphoraVIP(requires=(constants.AMPHORA, constants.LOADBALANCER), provides=constants.AMPS_DATA)) extension_flow.add( database_tasks.UpdateAmphoraVIPData(requires=constants.AMPS_DATA)) # Update the data stored in the flow from the database extension_flow.add( database_tasks.ReloadLoadBalancer( name='second', requires=constants.LOADBALANCER_ID, provides=constants.LOADBALANCER)) extension_flow.add( database_tasks.ReloadAmphora(requires=constants.AMPHORA_ID, provides=constants.AMPHORA)) # Prepare to reconnect the network interface(s) extension_flow.add( network_tasks.GetAmphoraeNetworkConfigs( requires=constants.LOADBALANCER, provides=constants.AMPHORAE_NETWORK_CONFIG)) extension_flow.add( database_tasks.GetListenersFromLoadbalancer( requires=constants.LOADBALANCER, provides=constants.LISTENERS)) extension_flow.add( database_tasks.GetAmphoraeFromLoadbalancer( requires=constants.LOADBALANCER, provides=constants.AMPHORAE)) extension_flow.add( amphora_driver_tasks.AmphoraPostVIPPlug( requires=(constants.AMPHORA, constants.LOADBALANCER, constants.AMPHORAE_NETWORK_CONFIG))) timeout_dict = { constants.CONN_MAX_RETRIES: CONF.haproxy_amphora.active_connection_max_retries, constants.CONN_RETRY_INTERVAL: CONF.haproxy_amphora.active_connection_rety_interval } extension_flow.add( amphora_driver_tasks.AmpsListenersUpdate( name=constants.AMP_LISTENER_UPDATE, requires=(constants.LISTENERS, constants.LOADBALANCER), inject=({ constants.TIMEOUT_DICT: timeout_dict }))) # Plug the member networks into the new amphora extension_flow.add( network_tasks.CalculateAmphoraDelta( requires=(constants.LOADBALANCER, constants.AMPHORA), provides=constants.DELTA)) extension_flow.add( network_tasks.HandleNetworkDelta(requires=(constants.AMPHORA, constants.DELTA), provides=constants.ADDED_PORTS)) extension_flow.add( amphora_driver_tasks.AmphoraePostNetworkPlug( requires=(constants.LOADBALANCER, constants.ADDED_PORTS))) extension_flow.add( database_tasks.ReloadLoadBalancer( name='octavia-extension-LB-reload-2', requires=constants.LOADBALANCER_ID, provides=constants.LOADBALANCER)) extension_flow.add( self.get_distributor_flows('octavia-extension-distributor-flow', distributor)) extension_flow.add( amphora_driver_tasks.ListenersStart( requires=(constants.LOADBALANCER, constants.LISTENERS, constants.AMPHORA))) return extension_flow
def get_delete_load_balancer_flow(self, lb, deleteCompute, cascade): """Flow to delete load balancer""" store = {} delete_LB_flow = linear_flow.Flow(constants.DELETE_LOADBALANCER_FLOW) delete_LB_flow.add( lifecycle_tasks.LoadBalancerToErrorOnRevertTask( requires=constants.LOADBALANCER)) delete_LB_flow.add( a10_database_tasks.GetVThunderByLoadBalancer( requires=constants.LOADBALANCER, provides=a10constants.VTHUNDER)) delete_LB_flow.add( a10_database_tasks.MarkVThunderStatusInDB( requires=a10constants.VTHUNDER, inject={"status": constants.PENDING_DELETE})) delete_LB_flow.add( vthunder_tasks.SetupDeviceNetworkMap( requires=a10constants.VTHUNDER, provides=a10constants.VTHUNDER)) delete_LB_flow.add( compute_tasks.NovaServerGroupDelete( requires=constants.SERVER_GROUP_ID)) delete_LB_flow.add( database_tasks.MarkLBAmphoraeHealthBusy( requires=constants.LOADBALANCER)) if cascade: (pools_listeners_delete, store) = self._get_cascade_delete_pools_listeners_flow(lb) delete_LB_flow.add(pools_listeners_delete) delete_LB_flow.add( a10_database_tasks.GetFlavorData( rebind={a10constants.LB_RESOURCE: constants.LOADBALANCER}, provides=constants.FLAVOR_DATA)) delete_LB_flow.add( a10_database_tasks.CountLoadbalancersWithFlavor( requires=(constants.LOADBALANCER, a10constants.VTHUNDER), provides=a10constants.LB_COUNT)) delete_LB_flow.add(self.get_delete_lb_vrid_subflow()) if CONF.a10_global.network_type == 'vlan': delete_LB_flow.add( vthunder_tasks.DeleteInterfaceTagIfNotInUseForLB( requires=[constants.LOADBALANCER, a10constants.VTHUNDER])) # delete_LB_flow.add(listeners_delete) # delete_LB_flow.add(network_tasks.UnplugVIP( # requires=constants.LOADBALANCER)) delete_LB_flow.add( database_tasks.GetAmphoraeFromLoadbalancer( requires=constants.LOADBALANCER, provides=constants.AMPHORA)) delete_LB_flow.add( a10_database_tasks.GetLoadBalancerListByProjectID( requires=a10constants.VTHUNDER, provides=a10constants.LOADBALANCERS_LIST)) if not deleteCompute: delete_LB_flow.add( a10_network_tasks.CalculateDelta( requires=(constants.LOADBALANCER, a10constants.LOADBALANCERS_LIST), provides=constants.DELTAS)) delete_LB_flow.add( a10_network_tasks.HandleNetworkDeltas( requires=constants.DELTAS, provides=constants.ADDED_PORTS)) delete_LB_flow.add( vthunder_tasks.AmphoraePostNetworkUnplug( name=a10constants.AMPHORA_POST_NETWORK_UNPLUG, requires=(constants.LOADBALANCER, constants.ADDED_PORTS, a10constants.VTHUNDER))) delete_LB_flow.add( vthunder_tasks.VThunderComputeConnectivityWait( name=a10constants.VTHUNDER_CONNECTIVITY_WAIT, requires=(a10constants.VTHUNDER, constants.AMPHORA))) delete_LB_flow.add( virtual_server_tasks.DeleteVirtualServerTask( requires=(constants.LOADBALANCER, a10constants.VTHUNDER))) delete_LB_flow.add( nat_pool_tasks.NatPoolDelete(requires=(constants.LOADBALANCER, a10constants.VTHUNDER, a10constants.LB_COUNT, constants.FLAVOR_DATA))) if deleteCompute: delete_LB_flow.add( compute_tasks.DeleteAmphoraeOnLoadBalancer( requires=constants.LOADBALANCER)) delete_LB_flow.add( a10_database_tasks.MarkVThunderStatusInDB( name=a10constants.MARK_VTHUNDER_MASTER_DELETED_IN_DB, requires=a10constants.VTHUNDER, inject={"status": constants.DELETED})) delete_LB_flow.add( database_tasks.MarkLBAmphoraeDeletedInDB( requires=constants.LOADBALANCER)) delete_LB_flow.add( database_tasks.DisableLBAmphoraeHealthMonitoring( requires=constants.LOADBALANCER)) delete_LB_flow.add( database_tasks.MarkLBDeletedInDB(requires=constants.LOADBALANCER)) delete_LB_flow.add( database_tasks.DecrementLoadBalancerQuota( requires=constants.LOADBALANCER)) if not deleteCompute: delete_LB_flow.add( vthunder_tasks.WriteMemory(requires=a10constants.VTHUNDER)) delete_LB_flow.add( a10_database_tasks.SetThunderUpdatedAt( name=a10constants.SET_THUNDER_UPDATE_AT, requires=a10constants.VTHUNDER)) delete_LB_flow.add( a10_database_tasks.GetBackupVThunderByLoadBalancer( requires=constants.LOADBALANCER, provides=a10constants.BACKUP_VTHUNDER)) delete_LB_flow.add( a10_database_tasks.MarkVThunderStatusInDB( name=a10constants.MARK_VTHUNDER_BACKUP_DELETED_IN_DB, rebind={a10constants.VTHUNDER: a10constants.BACKUP_VTHUNDER}, inject={"status": constants.DELETED})) delete_LB_flow.add( a10_database_tasks.SetThunderUpdatedAt( name=a10constants.SET_THUNDER_BACKUP_UPDATE_AT, rebind={a10constants.VTHUNDER: a10constants.BACKUP_VTHUNDER})) return (delete_LB_flow, store)