F5 - Enable, Disable, or Force Offline Member with optional wait for connections to drop

Octopus.Script exported 2016-09-21 by spuder belongs to ‘F5’ category.

F5 - Enable, Disable, or Force Offline Member with optional wait for connections to drop

Parameters

When steps based on the template are included in a project’s deployment process, the parameters below can be set.

Wait on Connections?

WaitForConnections = False

If checked, the deployment won’t continue until current connections on the node = 0

Max. Wait Time (seconds)

MaxWaitTime = 300

Defaults to 5 minutes

LTM Status

EnableOrDisable = Disabled

State member will be put into (Enabled, Disabled, Offline)

  • Disabled continues to process persistent and active connections. It can accept new connections only if the connections belong to an existing persistence session.

  • Offline allows existing connections to time out, but no new connections are allowed.

LTM Pool name

PoolName = pl_DummyDeployWeb

Name of F5 pool

LTM Member IP

MemberIP =

IP Address of F5 pool member. Default will auto discover the ip address of Tentacle.

LTM Member port

MemberPort = 80

LTM Host name

HostName = 192.168.45.204

null

LTM username

Username

Credential used to access F5 Soap API

LTM password

Password

Credential used to access F5 Soap API

Kill connections when <=

ConnectionCount = 0

The default is to wait until there are no connections left on the node. If you don’t want to wait for zero connections before deploying, you can put a value here and when that number of connections is reached the deployment will happen killing the rest of the connected sessions.

Script body

Steps based on this template will execute the following PowerShell script.

#Load the F5 powershell iControl snapin
#https://help.octopus.com/t/the-windows-powershell-snap-in-webadministration-is-not-installed-on-this-computer/4290
Add-PSSnapin iControlSnapin;

function WaitFor-ConnectionCount() 
{ 
    param(
        $pool_name, 
        $member,
        [int]$MaxWaitTime = 300, #defaults to 5 minutes
        $ConnectionCount = 0
    )
    $vals = $member.Split( (, ':'));
    $member_addr = $vals[0];
    $member_port = $vals[1];

    Write-Host "Waiting for current connections to drop to "$OctopusParameters['ConnectionCount']

    $MemberDef = New-Object -TypeName iControl.CommonIPPortDefinition;
    $MemberDef.address = $member_addr;
    $MemberDef.port = $member_port;
    $MemberDefAofA = New-Object -TypeName "iControl.CommonIPPortDefinition[][]" 1,1
    $MemberDefAofA[0][0] = $MemberDef;
    $cur_connections = 100;
    $elapsed = [System.Diagnostics.Stopwatch]::StartNew();

    while ( $cur_connections -gt $ConnectionCount -and $elapsed.ElapsedMilliseconds -lt ($MaxWaitTime * 1000))
    {
        $MemberStatisticsA = (Get-F5.iControl).LocalLBPoolMember.get_statistics( (, $pool_name), $MemberDefAofA);
        $MemberStatisticEntry = $MemberStatisticsA[0].statistics[0];
        $Statistics = $MemberStatisticEntry.statistics;
        foreach ($Statistic in $Statistics)
        {
            $type = $Statistic.type;
            $value = $Statistic.value;
            if ( $type -eq "STATISTIC_SERVER_SIDE_CURRENT_CONNECTIONS" )
            {
                # just use the low value.  Odds are there aren't over 2^32 current connections.
                # If your site is this big, you'll have to convert this to a 64 bit number.
                $cur_connections = $value.low; 
                Write-Host "Current Connections: $cur_connections"
            }
        }
        Start-Sleep -s 5
    }
}

$Pool = $OctopusParameters['PoolName'].trim();

If ([string]::IsNullOrWhiteSpace($OctopusParameters['MemberIP'])) {
    Write-Host "No IP Adress was provided on the 'LTM Member IP`, using [System.Net.Dns]::GetHostAddresses to resolve it"
    $ip = $([System.Net.Dns]::GetHostAddresses("$($OctopusParameters['Octopus.Machine.Hostname'])") | Where {$_.AddressFamily -ne 'InterNetworkV6'}).IpAddressToString
    if ($ip -is [array]) {
      Write-Host "Found multiple ipv4 addresses, using first address $($ip[0])"
      $ip = $ip[0]
    }
} Else {
    $ip = $OctopusParameters['MemberIP']
}

$Member = $ip+":"+$OctopusParameters['MemberPort']
Write-Host "Member is $Member"

# Gets the hostname of the current machine being deployed.
$curhost = hostname

Write-host "Currently deploying to $curhost"

If (($OctopusParameters['EnableOrDisable'] -ne "Enabled") -and ($OctopusParameters['WaitForConnections'] -eq "True"))
{
    Initialize-F5.iControl -HostName $OctopusParameters['HostName'] -Username $OctopusParameters['Username'] -Password $OctopusParameters['Password']
    Write-Host "Setting $curhost to $($OctopusParameters['EnableOrDisable']) in $Pool pool";
    Set-F5.LTMPoolMemberState -Pool $Pool -Member $Member -state $OctopusParameters['EnableOrDisable'];
    Write-Host "Waiting for connections to drain before deploying.  This could take a while...."
    WaitFor-ConnectionCount -pool_name $Pool -member $Member -MaxWaitTime $OctopusParameters['MaxWaitTime'] -ConnectionCount $OctopusParameters['ConnectionCount']
    if ($OctopusParameters['EnableOrDisable'] -eq "Disabled") 
    {
        Write-Host "Setting $curhost to Offline in $Pool pool";
        # We've now waited the desired amount, go ahead and force offline and move on with deployment
        Set-F5.LTMPoolMemberState -Pool $Pool -Member $Member -state Offline;
    }
}
Else
{
    Initialize-F5.iControl -HostName $OctopusParameters['HostName'] -Username $OctopusParameters['Username'] -Password $OctopusParameters['Password']
    Write-host "Setting $curhost to $($OctopusParameters['EnableOrDisable']) in $Pool pool."
    Set-F5.LTMPoolMemberState -Pool $Pool -Member $Member -state $OctopusParameters['EnableOrDisable'];
}

Provided under the Apache License version 2.0.

Report an issue

To use this template in Octopus Deploy, copy the JSON below and paste it into the Library → Step templates → Import dialog.

{
  "Id": "6775501d-cafb-493e-ba67-ec95c9500562",
  "Name": "F5 - Enable, Disable, or Force Offline Member with optional wait for connections to drop",
  "Description": "F5 - Enable, Disable, or Force Offline Member with optional wait for connections to drop",
  "Version": 36,
  "ExportedAt": "2016-09-21T17:50:00.631+00:00",
  "ActionType": "Octopus.Script",
  "Author": "spuder",
  "Parameters": [
    {
      "Id": "c27ab1f7-5303-48fe-a8e5-80aa638a054f",
      "Name": "WaitForConnections",
      "Label": "Wait on Connections?",
      "HelpText": "If checked, the deployment won't continue until current connections on the node = 0",
      "DefaultValue": "False",
      "DisplaySettings": {
        "Octopus.ControlType": "Checkbox"
      }
    },
    {
      "Id": "becfb740-d954-4250-9818-4c561f210ec5",
      "Name": "MaxWaitTime",
      "Label": "Max. Wait Time (seconds)",
      "HelpText": "Defaults to 5 minutes",
      "DefaultValue": "300",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "9a0e97c0-d972-4707-b477-c1903090f508",
      "Name": "EnableOrDisable",
      "Label": "LTM Status",
      "HelpText": "State member will be put into (Enabled, Disabled, Offline)  \n\n- **Disabled** continues to process persistent and active connections. It can accept new connections only if the connections belong to an existing persistence session.  \n\n- **Offline** allows existing connections to time out, but no new connections are allowed.",
      "DefaultValue": "Disabled",
      "DisplaySettings": {
        "Octopus.ControlType": "Select",
        "Octopus.SelectOptions": "Enabled|Enable\nDisabled|Disable\nOffline|Forced Offline"
      }
    },
    {
      "Id": "7e1b8bc0-b950-4394-9e92-3a00ce3fce3a",
      "Name": "PoolName",
      "Label": "LTM Pool name",
      "HelpText": "Name of F5 pool",
      "DefaultValue": "pl_DummyDeployWeb",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "adf16144-16be-437a-ac81-199ca1de1e0e",
      "Name": "MemberIP",
      "Label": "LTM Member IP",
      "HelpText": "IP Address of F5 pool member. Default will auto discover the ip address of Tentacle.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "a37006fa-b34e-4f17-b16a-e7e82981b002",
      "Name": "MemberPort",
      "Label": "LTM Member port",
      "HelpText": "",
      "DefaultValue": "80",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "df633633-bf98-45d3-86cf-335b97902dca",
      "Name": "HostName",
      "Label": "LTM Host name",
      "HelpText": null,
      "DefaultValue": "192.168.45.204",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "3d43e5a4-4527-4b7c-bf88-319818f0d498",
      "Name": "Username",
      "Label": "LTM username",
      "HelpText": "Credential used to access F5 Soap API",
      "DefaultValue": null,
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "a3349f60-5cdf-4ab4-9213-a74843149643",
      "Name": "Password",
      "Label": "LTM password",
      "HelpText": "Credential used to access F5 Soap API",
      "DefaultValue": null,
      "DisplaySettings": {
        "Octopus.ControlType": "Sensitive"
      }
    },
    {
      "Id": "0ea7a048-0aa3-4387-a4cc-11e6cd8df6cb",
      "Name": "ConnectionCount",
      "Label": "Kill connections when <=",
      "HelpText": "The default is to wait until there are no connections left on the node.  If you don't want to wait for zero connections before deploying, you can put a value here and when that number of connections is reached the deployment will happen killing the rest of the connected sessions.",
      "DefaultValue": "0",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    }
  ],
  "Properties": {
    "Octopus.Action.Script.ScriptBody": "#Load the F5 powershell iControl snapin\n#https://help.octopus.com/t/the-windows-powershell-snap-in-webadministration-is-not-installed-on-this-computer/4290\nAdd-PSSnapin iControlSnapin;\n\nfunction WaitFor-ConnectionCount() \n{ \n    param(\n        $pool_name, \n        $member,\n        [int]$MaxWaitTime = 300, #defaults to 5 minutes\n        $ConnectionCount = 0\n    )\n    $vals = $member.Split( (, ':'));\n    $member_addr = $vals[0];\n    $member_port = $vals[1];\n\n    Write-Host \"Waiting for current connections to drop to \"$OctopusParameters['ConnectionCount']\n\n    $MemberDef = New-Object -TypeName iControl.CommonIPPortDefinition;\n    $MemberDef.address = $member_addr;\n    $MemberDef.port = $member_port;\n    $MemberDefAofA = New-Object -TypeName \"iControl.CommonIPPortDefinition[][]\" 1,1\n    $MemberDefAofA[0][0] = $MemberDef;\n    $cur_connections = 100;\n    $elapsed = [System.Diagnostics.Stopwatch]::StartNew();\n\n    while ( $cur_connections -gt $ConnectionCount -and $elapsed.ElapsedMilliseconds -lt ($MaxWaitTime * 1000))\n    {\n        $MemberStatisticsA = (Get-F5.iControl).LocalLBPoolMember.get_statistics( (, $pool_name), $MemberDefAofA);\n        $MemberStatisticEntry = $MemberStatisticsA[0].statistics[0];\n        $Statistics = $MemberStatisticEntry.statistics;\n        foreach ($Statistic in $Statistics)\n        {\n            $type = $Statistic.type;\n            $value = $Statistic.value;\n            if ( $type -eq \"STATISTIC_SERVER_SIDE_CURRENT_CONNECTIONS\" )\n            {\n                # just use the low value.  Odds are there aren't over 2^32 current connections.\n                # If your site is this big, you'll have to convert this to a 64 bit number.\n                $cur_connections = $value.low; \n                Write-Host \"Current Connections: $cur_connections\"\n            }\n        }\n        Start-Sleep -s 5\n    }\n}\n\n$Pool = $OctopusParameters['PoolName'].trim();\n\nIf ([string]::IsNullOrWhiteSpace($OctopusParameters['MemberIP'])) {\n    Write-Host \"No IP Adress was provided on the 'LTM Member IP`, using [System.Net.Dns]::GetHostAddresses to resolve it\"\n    $ip = $([System.Net.Dns]::GetHostAddresses(\"$($OctopusParameters['Octopus.Machine.Hostname'])\") | Where {$_.AddressFamily -ne 'InterNetworkV6'}).IpAddressToString\n    if ($ip -is [array]) {\n      Write-Host \"Found multiple ipv4 addresses, using first address $($ip[0])\"\n      $ip = $ip[0]\n    }\n} Else {\n    $ip = $OctopusParameters['MemberIP']\n}\n\n$Member = $ip+\":\"+$OctopusParameters['MemberPort']\nWrite-Host \"Member is $Member\"\n\n# Gets the hostname of the current machine being deployed.\n$curhost = hostname\n\nWrite-host \"Currently deploying to $curhost\"\n\nIf (($OctopusParameters['EnableOrDisable'] -ne \"Enabled\") -and ($OctopusParameters['WaitForConnections'] -eq \"True\"))\n{\n    Initialize-F5.iControl -HostName $OctopusParameters['HostName'] -Username $OctopusParameters['Username'] -Password $OctopusParameters['Password']\n    Write-Host \"Setting $curhost to $($OctopusParameters['EnableOrDisable']) in $Pool pool\";\n    Set-F5.LTMPoolMemberState -Pool $Pool -Member $Member -state $OctopusParameters['EnableOrDisable'];\n    Write-Host \"Waiting for connections to drain before deploying.  This could take a while....\"\n    WaitFor-ConnectionCount -pool_name $Pool -member $Member -MaxWaitTime $OctopusParameters['MaxWaitTime'] -ConnectionCount $OctopusParameters['ConnectionCount']\n    if ($OctopusParameters['EnableOrDisable'] -eq \"Disabled\") \n    {\n        Write-Host \"Setting $curhost to Offline in $Pool pool\";\n        # We've now waited the desired amount, go ahead and force offline and move on with deployment\n        Set-F5.LTMPoolMemberState -Pool $Pool -Member $Member -state Offline;\n    }\n}\nElse\n{\n    Initialize-F5.iControl -HostName $OctopusParameters['HostName'] -Username $OctopusParameters['Username'] -Password $OctopusParameters['Password']\n    Write-host \"Setting $curhost to $($OctopusParameters['EnableOrDisable']) in $Pool pool.\"\n    Set-F5.LTMPoolMemberState -Pool $Pool -Member $Member -state $OctopusParameters['EnableOrDisable'];\n}\n",
    "Octopus.Action.Script.Syntax": "PowerShell",
    "Octopus.Action.Script.ScriptSource": "Inline",
    "Octopus.Action.RunOnServer": "false",
    "Octopus.Action.Script.ScriptFileName": null,
    "Octopus.Action.Package.FeedId": null,
    "Octopus.Action.Package.PackageId": null
  },
  "Category": "F5",
  "HistoryUrl": "https://github.com/OctopusDeploy/Library/commits/master/step-templates//opt/buildagent/work/75443764cd38076d/step-templates/f5-enable-disable-member.json",
  "Website": "/step-templates/6775501d-cafb-493e-ba67-ec95c9500562",
  "Logo": "iVBORw0KGgoAAAANSUhEUgAAAMkAAADICAIAAADN+FL3AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAHYFJREFUeNrsnQd4FNUWx3fKzvaa3RQCBELv0hFpIkgTyBMEEQsoCFhAqoBPFGmCCiioCIJPBBR5iuBDpAgIiIhgA5QOISEJKZvsZvtOeXcInWyyszszu7Pc/7fffgvZMnPnN+eec++55yIMw8igoAQQCpsACrIFBdmCgoJsQUG2oCBbUFCQLSjIFhRkCwoKsgUF2YKCbEFBQbagIFtQkC0oKMgWFGQLCrIFBQXZgoJsQUG2oKAgW1CQLSjIFhQUZAsqRoTf7Q3AMEwgwDjddImDtpdShTa62M54fYzLQ+ZeZigavEGGIAiG4WmpiIJAlAosyYIadKjJiOo0iFaN4DjECLJ1RTQDAPIfPx3445j7h/2Bv8/KSDKS70OUSmXHVop7WxJN6skb1kF1WkjV1Za5K+pBMAyVX+T96VfP1j2eHw5ECFMlDarTqvvcr+7XHaCGGvSQrbhFKnDmgvu73c4Vn9MOZxQ6hRpV9c89qezSFktOhGzFhSjK/9cJ57pNrm+2yXz+mGhlo14/aqg640G8ShLw3iBbEoQqN9/x8RfOTzYI2utF1Nx6rWHSKO2AXohOA9mShsjzWbYpc3y//CmRVke0j2cAyFCTAbIVu/L//nfx5Hn+U2ck2PaIuvf9xjcmYlYzZCvGqDr0R+HkudT5LKlfA/UjfYwvj8YSLZCt6Cvw9+nC5/9Nnr0YT1dC1bOL+c2XUbMRshWlUQWPt2jcTM/3e+LTQ0FR07yXtY/2jY9YUkpseQ8cLnhmiszlie/wCq+fnrh6MZZshWyJZa4mzPJs2SW7S4TIjDPG6Z4eLGkDJgG2fD8dLhg+mfF6ZXeZ8LRU6+dL8KopkC0BRJK28TNdm3bK7lohiGneFO1jGZAtPkXlF+Y/PJq8eEl210vVo1PC+7MRQg7Z4qMfPPhbwZBxDEVCsK72j9WSk7auRvU6KUW9MXhMpZ/+N3/Q8xCsW7yDrLzczoMCp89DuxV2QMgUjp/p+Xqb4KetVmJJVmAG2BdWswzHyYs5bA6q308XO6i8ghid7UYQ87uvaTJ6QLa4elhUwYgp3h8OCHFJ8NppRGM2L5RoVE9eLx21mJDg4T0TIAN/n3au/9a19htZ7PkMhqlj9M89CdkK2WCRVEGfEb5/TvB2Yiqlol1z4p6GxD2NiOaNMGM4KaDevYeKxr5G20pi7bLpxz1tmDgSshVaVzhyqmf7Xh7OR6lQdm2v7t9d1fU+REHw4OjkXC567t/+347F2pUzLZimfbQfZKvirpAuGDPd+/2PEVop1YOd1P26Ke5rhapVfNtU0r5gWelHa2Ux1j2a335FM+ghyFYQ0UzBsAnePQfD/gKseqpu2EDQxKhe2AU2nh37i8bPZELIu1f17Kzq1oF2exiXmy51sQvUnC7aXkoX2689O8AdFfe+V1TZYpiiF2a4vw1z2B2454bxI1W9uyAYJtJAQOalwjGvBI6drPhtid+sULRoXNF50zS7HLLARhUV04XF1OUCMjcfPFO5BVRePngGYQ0H6/XWNM3gfpCtW+RYvNK+8OMwPohazPqxw7RDMxC52EPVjNdXNP6NCmbNsepVUvb9F4lgjpkJBKicy2RWLnkpj8rKDZy7SF7IJjOzmVJXsCg4eccaed10yNa1Lmbbj8B/50xVgkn/4jDNo31Dd6oCZy74j58C3ROC44heh6elymulRTJ/wlC0c+UXJXOWljs8YZj0rH7scAFMPEPl5pPnLgbOZrKonc8C5wXIKzsGNMGYsudL1KCDbMnIrJycjgMRmttPq/p2M82aiIWcmUkV2myT5nh33TFgRsgVrZqqenRS9+kadiZxbudB5J3p1AiScvAbPEWk1YjApSNPnw+cAo9ztMNpmjUppuYco8AW4/NfatWHsTs5mSvz/KkgEuQQfRYU5Q8YDW7xCr8XVfXorHt2COsecenF/EdPXu47XHbHvUE0a5D07SoZVJlDLP5PAneYE1hEi8aW5W9iiQmcepCisa9XAhZ749OerbvBAzChGzFE9VDXUMICMju34KkJsvKMrrJre4jUjTtX5N9zrd3k3bmfQz/Yq4v18yWcwALyHTji++kwBzv05z9FL8643PNJELQyFcZoTIAEsS1daCv3r8r7IVtR6hOpvIKcdhnAWoRmr+TGac9rhw9CUM4xV9FLM91ffx/eQWIpiZrH+muH9L8TaICdbdxM9+YdQSPEvRsQFJY0E99uMUzB8EkhgoWoVdbVi3TPDA4DrDK7Ff4NkJvveGdFzr0ZJbOX0CWOm/8EYsNgYAFpBvSOEbDowqK7y99ybdwWOH4qpLcqCMt/3la2axFmy3q9bJJMhAqQpcvXOdds1Ax6CESUmMXk2vCd8+MvKviEul+3GDEYnj2/KNs1x6KdaC9Sn0iXOnOa9WJCS4oyzZ8KuqTwBzhy83Pb9he5HeWN6iRvXR0jbJXMe9+746fkH9ZGd5mQSDa8aNT0EMHSjXkiwul9xukSvx01j8TQnHHg9IXAmfPOT/4b//6WZ9te7/5fQ4oKe3Y2TB0T4d1Gi88Wjqn/FUO5oOTZTPBcPHMRlV8Y12yBoP2l10I6FIvZ9OZUJGIzzjjdIjeisn0rLGaqHTEBkszKLQuebONnxTNbjlXrGVdIy1ZNr7+E8VFpg3aJzZaq7wMxZLQuZF1P9vfuO0TlXI5PtphAwDF/WUi+cJN6qr78xFmMyAUjQIfYo3MMOVunblkLZH9reXyOQbg3bgvRhdc//xTCU1BDl4rqbynatUCDJOOD6Nh35BiqViIqJaJWgWcUPGtUgqYGBf4+ffM/XV9vNUx/DrMmxBdbFF386sJQ3ohVTVb16MTXz4ocJ6oe7Bj01tqyu3jK3PJaHUf1WvZh0KNG3ZVnPWrQIQbwWoclmNh/WkyYyYjotVxvOf+f/9zaHIxt0mzrp4viii33zv2MJ6TuSfNoPx5zR2lxfXll53bB/uTd/XMQn4ikbSUhLR8i5JjFjJqNWIIRtSaA11gieFhRqxlLsmBVklCl4laQGP+xE3ccxkGqqBggGy9sMTL71LkhvlfT/0E+f1lEXx6vU0Nes1qweM27/1CkP+Bnc1DBIxDk78DU4SmJeLUqWLWUK6gpaZv9zreVLl5lnDUxTtjyHf6TLLKH5MU3roenpfL402KOb2kG9g5qtH48yAjv+TH20gB4nDhb8dtKP/va8PIYRKuOhzjRNn1BqH1KpzY8N7dovjyCaP7VM6hLsGlH7ASPMpp2fvpVPIxBUHkF5MlzIb6ZaFyP52YUq09UtG4WrHIk4w94dh2QxZJKlnwicv0BQdhyreYwk4WnV+fZbonFluqhoEOmvoO/MaXOmGJL5vb4j56QOFsM41i5ngNbfKeCiBQnoqi69/3B/ujZtlcWe3IsWyNttsiLOYzHF6rHotOgfO9sI874FnATg2VaM4GA+7vdMciWZ8secGwSZsu9lUOzYhYz7zlG4sSJ6gG9gkaI+36li4pjkC0ZQ982ai8xttiaVaH/vFHPd+sxYswnKgjVA/cF+6P/9+PseaGxWL7bLWJnzfP4FrvNcyaH6re8b8TFzgQIHw2pOrdDtUG7csPEkeDBUBRb6yG/kLpcyAbOmZfIzGzgMJAXL4mfBXRdznWbjFNGS5It7yFuu8yxfSLfLrbx1bFsP4ui7ANB2NUcGCrDMHZaCTzj2NXX+LV/4hi7nzn4H/bN6JXPsh8HsV7Ja4uCdIg9K3clMYydlkmyyJrcMUZTbCfPZgbOXGDX4J/JDJw4S2XnitQr2kroYgdq0kuPLdcXm7ixlZrEM1oqpW7kEF6+Ktj1RrRq1QMdIvlmzGTAWjVVtGp647fyCnx/HPf98od3988AOEEvuffAYXWfrlJji2E8O38q52KoVewdnJKIJVtBbIVZE1DwnGzFwT8luJGz8t6WvJddAK2h7tkFPGQzxgXOZ3n3HPTuPuD96YgQJX3d3+6UHltUYbHsjhDXuv595b0tZHEkZee2An47gsjTq4OH7ulBoOt0b97h+uLbUNfehWi3duxjXVLhlwDxGSf6j5RTFBSvlhJPYIFLouzWQZyfAl2n7qmByVs/Td71uX7Ss1j1Kvz0LgFSnOrAfLLl2bVfDG9dLLEV5+8Q0bIJXiVJ5COR165hGDs8Zc+X5vdex+vWjPwLfaJM/vDK1vZ9d7QKjtyavCYJeX8+kj/4hZKZi8uJEEXxVMq3mDimyeiRvH1Nwvuz8CBJY6H2MD//JiW2GLIcS1vBIFAMimEY775D+YOeKxj8gu/nI+V2iKpeXaLcJ6Ooum+35B1r9eOeZsdWwrt59v4qJbbowuJyw3WpgOX7/XjBkBcLho7zHfw92HuI5o3E7xDLJ4yQGyaOTNq8Ut6gdhgfZ3MJhR9h5i1OJC/llUOu6PtmMRRFZd84EqasbA54Bi1JU8CNBQ8QzLIvPN6yB1VU7N68s9LqyzK2Uk2vmLofiCb1k7Z84lz1pf3t5YzXx6WV2NNH+C7ELxhbpzPLYSv4WlbG56fdHt6XI1P5RbkdBwrTVLi6bzdZjAnBcd2zjxGtmhYOm3hbRadKGqqoBJcKW4Ez5SSa0vlFJfM/pItK2HLqLhdT6mJr+ZdV9He5FR1aJ657j+cT4lKZnZOUHVrxPrPOlxQtGidu+rjwqYnsouoQ2yknT+jhIf7YKm98L3DyLHgEveeECCFJodhS9e4qi2HJa1ZL/HpZweMvhZhFA+yWZHx5/1nOs2CoWimEvyWMZSDU0Y4QKxVmMSeuf18R2ixI4PhpybDFFHLOhkMUQtgtQfbUVLZrHms7A5R/OQ066+qF8iaVL2+h7HaJsMUwTBgXVYBC+4wwfaKyU1uZRATu2IQlb1QaA1I5+RJhiw5nVy2EIPg/IZoWopkUHdvIpCN5enXTm5XsZ1POph6xyVZ4RVPZvDz+2eJ/SBBLTZbXS5dJSpqMB9XB13yzl8zjlQZbYQ7yYvxn6wtRGlj9rx4IgsikJtMbEypa++knJcJWmAZBALslAFuah3vKJChUqzG/9Upw3yGu2RKk0j/f/hZeN11eu4ZMmlK0bqro0Lr8C4+gUmErrC5DCnargsXTkpD2qQFBrjwmDbbCdEeEsFv8ooXIYqq4dxhSPXAfnla1nDNTKaTBVpjrPIVI8+DV5yaaN5ZHloUXdSE4rh1WzuQ9KnzRcr7YQsPJ7WcEGIviNaCTeod49Sz6d7+zi5A3rC0Rttg0QO4ppjQT41dF1Sse2MIsZkXrZrdfeJ1GMmyhVu6lWgXpE3mzWyBCjJtFSsout89Z4VWShf5R3nJslC2auc5xm0ZghJif4a9LJE+dy67fFfglmMWEWsxsae6y6sjJiXhqElYlGTUbpDKmquzYxn7rJhIYrzVmhWVLns7d5xUiH4bXi824PRR4lJeuLbuyXhxPS5XXrSmvXwuvXUNepyZeo2ps7vsqb1gXUSlvnufBq0uHLbxBLc5XToBpBzEvLSAv8M8Z8JBdK5uL6DREs4ZE0/pEswaKVk2jshtFkGgRw2unBY6eFDNO5I+tGlU5f0aIGnbCDwlWRFupy7f/V9+1Df3w9OqK9i2V7Vsq7m0h/tYBt5uumtVvYUv4dDT+2EqycLdbArCFxVCXRJ67CB6uNRvZKg+N6io7tFJ2aE20boaqlOIfzM1bDCMmAyLHJcMWotGAw2VXaHFgy8+/8ccwWQyKYQLHToJH6bK1wO9Rdm2vebSvslNbMUMBzHqjeIJKlJIW/N3liIxo1Yxbgwfi3G6Vf9Yer2fLrsInxud1HuRYtpa2O8T5XVSvvRE2tm0uKbbA3dCd293AablmyCcU62zd6DEvZNvnLs1p3a9k7lIRCLt5VRUINSTGlqINR7vl5j/1UQQ3gmcz5vWBjjKn/cP2d1fRbiGrAN/kLeA8lVsSjy15nZrRZwuXGFvXA0zHOytyOwx0rtnICJPyfz2zDUtLRUQJJvhkCxwxpzQ6RojbVC5Jtq5e/UJb8fQF+QNGk5nZ/OPruxo56Z54WCQPj9+v0zzWn0NTeqDdKkf+I0fzeg/jfdcWuvjqQmpha2oKxxan4w5xV1iOgyqSZ6usiyx8dqrjo7U8fieVV3jl5kPxWmmSZEteq4ZMEeqqQ9rh5D0VApHHA1tX+GLsc5baF6/kMSxl4632LUQz7XxH7CiiyQg5CdgfuO4E8OlvSXC9VzA5Fn7s5LKHTQUKnD7POlvDBop28PyPBrFZjqE7AXzv68SOdAtQCiCKKp7xju/345E6Wx5v2V44RIvGEmaLaN6IwzkLsP8vEl9syQKkbfwbEY4zsxWsaBrRa8VMzeCfLVSjDr1ONQPZCsVVOnexlMt2p3fKd+QoeDa89LSYhy3IDInp1bGh2i0B5joEKWFCEFhKNLeHcXzwGW0vDfvj3h9/YXduH9hH8mwpO7QJsSYgbeO/ChSi4JktRcc2Kfs2pPy8UdG+ZfRGJZxh7yVLlzh8B39TdGojck1NYWZ2MVQ/dngob6RKBGCL11KX2icHWFcvxFMSERQ1z5+GRCP16prtORjeBz079slISrRtEwVmC1ySoRmhjAVwKi0svt3SjX7cOGvi9ZwwPC3VMHlUtNjyhxstur/diZmMRON6ccIWajJoQtjAki4WwG7xZFp0o4capz13W/qe9ulBROtmUWGLys2nuO/xRGbnevceMr/7mvjDfgJmOxn/PbbS8xFiQyxe+kTtUwMM056/8/hBz2iaMzlaGYhhzGG71v8PMxhEm0MUiS3UbFT17FzJvShAJerIS/SqH+ljnDkhWMIxUb+WbuRjUWGLnSXjFAFQlGvDFtNb06IyVyHs/WeYMLKSxioq5p+tyOyWOuNB84JpFa9FM0wYIdqM763txW361f3VVsbhVHW7Lyp3grBsyeulE/dUNExPFRTxz1YEW4mo+nQ1L5xR6YIOgG/C0jfE376P0yACcM5KFixjSwdGKc9b8F+1fDC7QrtVwlA032yF78sbJo4MscIv0aiu4eUxol4rDOVU0rdk5rsyt0/Vq3O0AlvB2cKqJmuG9AsOF03zPcSFqsK3W5zWwGmHPUK0bCLapZLXq4WGbJI9uw64N36f8O6MKC5OEeOHTa+9VEHKHnW5MHbslmc7h2xPBEPNb00XLYs69FiPKnHYpswl6tZSdu8oi57EYAs4QObZE4M2RC7PGzREMr7lWvsNJ9Mlr11DO6S/OJcq9B32Sma9RxfYLJ8skEVVIhlMzZD+yiCTcbyHiqgl/MoLVF6B66utnD6iHz8CtQq+37uqR6cQB9ZLl69zb9hifHUsVq3KXcGWDEESVsxH5OVkv9BON78/hVeNqCBb6YefcVrFhSUYzZVtcBLpRTLoTLMnh3Twq78qmb1EXrO67pnBoQ5rFNtdX2y2TZ9f/Poi4KXxuNmWeI4eqtOYXn2xPPeZ55X7WLI1ko+T57O8e37mZlS6d1Q/ImD6imney1gIpVxcX24pefUd8CJh2ewQB0udy9cWjpiCN6htnP6i4YVhjNd36b4B/hNnJMYW2zM+OeDOKo+8p8RgiZYIgyPnqg2cL/+sifKGdYRoNN3zT6ofeqDyY163yTZ5joxhNIMfkjcI6UhA4EJ7fIlffaRo1hDVqoEvoe59f5V9G2zjZtL5RRJjC1zyxM0rrw85omaj9pnBmsF9ee5+5TiWGlExT+/eX/x/neB2ZmqV9bNFoSfchjrMMXyQobLcGIZh7ItWFk99E7wiGtcNtYOmKNAV6sexmaiur75z/+8HNj+MohGCSPpmhe31RTw4JyL7d1iCybr2ParQJq9VHa9TU6AiQYp7GrqzciL5Bsf7n1o+msft1KwJieveKxg6LnDyHB8thRomjdI990TFTUS7PbZJczz/+6Fs8CVxw7IQdxvxHzulHX7VJ3Nv2Gr9Ykng6Anf4b8Ube8BgTaq1zAkGeFqsygMrClaN1X36iKvmy5c9anIN7PwbNtLch8cAd1x4sYV6oj3lsKqpljXLdE//2TFTeQ/euJyv2fKwAIOVuLXyxFNqIOrVF4+lnLVMaVdbv/xU861G+X1rxYWJZo2jDy1TjIVhbg51906mN97PaIMd5p2b9wWToNq1QmLX7N+tljeIJzNAYDN0I9/JnnnWmWF206DSNbx4WeX+48gT52/5u9PITg5fARxfe0QiN/xRAty08ph2mZHIpjeiGe22Lgho0fK/q8sq97SPNovPMjYga5wl30rO7dN2ro64cM57M7koSV7odYE3aihyT+uN4wfUfHcDjBX+QPH2Od9ILu2gbKqXzftYxnceo8m9b3X6rIihBy1mg2vT3As/c9Vj3PbHlQTKVuIEJtZxpwYhiqwkecvkpmXyKwcKq8A/JO2ldAOJ7D8rPEPMqBl+eRt1QORJqiAXwE0gE6HvJBNFxWzOVhlwy4EAYwclmwF7gHRsrG8Xq2KE3vAlfId/K304/Xenftvhp5oUjdx06owNtEtHPOKefYkNMHk//t0mc0LnM2Up1d3b/mBdd5CCE5jnS1gmcVPVrlZ9sUrHQs/Lr/faNog6duV0S8CAKj69S/7W8t8v/xxeyxWq3rytjXhLclkfP68nk+Y50+/XpQP+O+l760KnM1KWPpG5Gcd/cocZGZ24ajp8oZ1wK2D10oD9w1es1qMrF/1//WPZ8c+1YOdogaVP+Dessv5nw3lLsTAUpOSt64Ou60QBZG8fW3ph58VjZqu6NKWzikgz503znlZP+FZfgaDYqFP9B05mj9g9I2OCcfxGlXl6dWw6ql41RTwGk9jX/A+ylqp3brqmrRrrhnSDxCGatSitUngfJZ703bXuk2gBy/fP9NpqvyyGdHycUhsd+tna2nw2sKx4m/5Dv+V/8gYWQV5ggiCGvXsdjqJFtRsRC0mPDkRTTCiei1qNKBmA5ZgQvQ6hPtOjpWydY14jGhYV96oDtG8EWtia9dA1Sp+G4EqtvsOHAEutu/g7+TZzIoc/8SElO8+Bc+x7OXGkC8fOHoyL2NkRJtlAP4MOoAgajGjJj2q17Hk6TSIDjxrQXiPqJUACESpRJQEolAgCrlMoXCu+rJ02ZpwRqGqpcjr12b386mVBl7jVZKBY86pABjtcgOG/MdO+X8/Bjwq8tzFkPyYtNTk7WuiuApXknEilXM554EhMpdHJlGhKLtXWYKJNagAaP0VoEFHU+YXUxTjCwCeaLuDBnFrdh5daOPsIDeonbx5pUDuQTyzJbuS8pHb4wk6iJNxl0vVo5Nl2VxZbO79ceeNFnMHZDKk7FyLVU2GJN0m7fBHLMvflApYstgdOyXJknkflK74HCJVFjgnLJyhzuguraOO6XF5/5Gj+Y++wH9NVGlxVaNq4sYVWIJRes5nLB8c0bJJ6pEt8vQady1Y6n7dU3avlyJYMmnMJ1KU7ZUFrnWb7y6sUNQ8b4pGrEVEdytbZQ7YhezCF2YE/vrnbuBK83Bv48yXRNiaFbJ1Q65vttvGz5RRdLxSxWYFrlksT68eB+civRwbusRRPGWu+/sf4w0rBDVMflY/5nEJjTLEG1tXu8jzWYXDJwTOZcfHZdAMfsj4yosi17qFbAUXwwDrVTx5Lu0ole4FIOrXNH8wl9PegJAt8Qjz//m348M1HtBLSuhccEz39CDt8EF4atzOQMRPTjNVWORYtNL5+ebrWeQx2uJatWHyaO1j/SUx3wzZusmK+QPefYdKZi4u29ItlloaUXW+Vz9xBNGknoQ2bIdslefsX7zk+W63femnDMf6s7xLXquGbsxQVZ+uYqatQrZEGbMotvsP/+navMu980eZyyvOj6IJRs3gvqpuHYiGdRC+01MhWzHJmb00cOyke8c+99Y9bIoYj+eOonj9dE1GT1WnNuxakphPCoVsCemZBUi6xEGeyQz8cyZwPtN/5GjgQjYTSjEwFEVMOqJuLTZ3vkl9ee2aeLUUVK+9S7woyFbYlo1mKEpG0eyGtCDevN44CIIQcrZ3wzB2lWkcbVsM2YKSnqAZh4JsQUG2oKAgW1CQLSjIFhQUZAsKsgUF2YKCgmxBQbagIFtQUJAtKMgWFGQLCgqyBQXZgoJsQUFBtqAgW1CQLSgoyBYUZAsKsgUFBdmCgmxBQbagoMLT/wUYANXydK6gFDnzAAAAAElFTkSuQmCC",
  "$Meta": {
    "Type": "ActionTemplate"
  }
}

History

Page updated on Wednesday, September 21, 2016