F5-LTM-REST - Enable, Disable, or Force Offline Member
Octopus.Script exported 06/10/2020 by gvanderberg belongs to 'F5' category.
F5-LTM-REST - 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?
If checked, the deployment won't continue until current connections on the node = 0
Kill connections when <=
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.
Max. Wait Time (seconds)
Maximum wait time (in seconds) before killing connections and moving on. Defaults to 5 minutes
LTM Status
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
Name of F5 pool
LTM Member IP
IP Address of F5 pool member. Default will auto discover the ip address of Tentacle.
LTM Host name
The DNS name or IP address of the F5 LTM device.
LTM username
Credential used to access F5 REST API
LTM password
Credential used to access F5 REST API
Script body
# Based on the F5 template by spuder.
# This template has been translated to use REST instead of the iControl SOAP commandlets.
# https://www.powershellgallery.com/packages/F5-LTM/1.4.297
# https://devcentral.f5.com/s/articles/powershell-module-for-the-f5-ltm-rest-api
Import-Module -Name F5-LTM
function WaitFor-ConnectionCount()
{
param(
$pool_name,
$member,
[int]$MaxWaitTime = 300, #defaults to 5 minutes
$ConnectionCount = 0
)
$member_addr = $member
Write-Host "Waiting for current connections to drop to "$ConnectionCount
$cur_connections = 100;
$elapsed = [System.Diagnostics.Stopwatch]::StartNew();
while ( $cur_connections -gt $ConnectionCount -and $elapsed.ElapsedMilliseconds -lt ($MaxWaitTime * 1000))
{
$MemberStatisticsA = Get-PoolMemberStats -PoolName $pool_name -Address $member_addr
$MemberStatisticEntry = $MemberStatisticsA.'serverside.curConns'
$cur_connections = $MemberStatisticEntry.Value;
Write-Host "Current Connections: $cur_connections"
Start-Sleep -s 5
}
}
$Pool = $OctopusParameters['F5LTM.PoolName'].trim();
If ([string]::IsNullOrWhiteSpace($OctopusParameters['F5LTM.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['F5LTM.MemberIP']
}
$Member = $ip
Write-Host "Member is $Member"
# Gets the hostname of the current machine being deployed.
$curhost = hostname
$hostname = $OctopusParameters['F5LTM.HostName']
$username = $OctopusParameters['F5LTM.Username']
$password = ConvertTo-SecureString $OctopusParameters['F5LTM.Password'] -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential ($username, $password)
Write-host "Currently deploying to $curhost"
If (($OctopusParameters['F5LTM.EnableOrDisable'] -ne "Enabled") -and ($OctopusParameters['F5LTM.WaitForConnections'] -eq "True"))
{
New-F5Session -LTMName $hostname -LTMCredentials $credential
Write-Host "Setting $Member to $($OctopusParameters['F5LTM.EnableOrDisable']) in $Pool pool";
Disable-PoolMember -PoolName $Pool -Address $Member
Write-Host "Waiting for connections to drain before deploying. This could take a while...."
WaitFor-ConnectionCount -pool_name $Pool -member $Member -MaxWaitTime $OctopusParameters['F5LTM.MaxWaitTime'] -ConnectionCount $OctopusParameters['F5LTM.ConnectionCount']
if ($OctopusParameters['F5LTM.EnableOrDisable'] -eq "Disabled")
{
Write-Host "Setting $Member to Offline in $Pool pool";
Disable-PoolMember -PoolName $Pool -Address $Member -Force
}
}
Else
{
New-F5Session -LTMName $hostname -LTMCredentials $credential
Write-host "Setting $Member to $($OctopusParameters['F5LTM.EnableOrDisable']) in $Pool pool."
if ($OctopusParameters['F5LTM.EnableOrDisable'] -eq "Disabled")
{
Disable-PoolMember -PoolName $Pool -Address $Member -Force
}
Else
{
Enable-PoolMember -PoolName $Pool -Address $Member
}
}To use this template in Octopus Deploy, copy the JSON below and paste it into the Library → Step templates → Import dialog.
Show JSON{
"Id": "4703dd4c-9f2d-471d-b15a-c1e345378695",
"Name": "F5-LTM-REST - Enable, Disable, or Force Offline Member",
"Description": "F5-LTM-REST - Enable, Disable, or Force Offline Member with optional wait for connections to drop",
"Version": 1,
"ExportedAt": "2020-06-10T10:23:31.760Z",
"ActionType": "Octopus.Script",
"Author": "gvanderberg",
"Packages": [],
"Parameters": [
{
"Id": "5ed914ec-ff22-436d-ac37-1ccc5216372e",
"Name": "F5LTM.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": "d3b82f88-87d5-4aec-be2a-4a0b3408b8db",
"Name": "F5LTM.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"
}
},
{
"Id": "2207ca51-ce9c-4498-8394-e0553fbcf54c",
"Name": "F5LTM.MaxWaitTime",
"Label": "Max. Wait Time (seconds)",
"HelpText": "Maximum wait time (in seconds) before killing connections and moving on. Defaults to 5 minutes",
"DefaultValue": "300",
"DisplaySettings": {
"Octopus.ControlType": "SingleLineText"
}
},
{
"Id": "7f503c0b-0050-4685-a9d8-7dbc42199ac0",
"Name": "F5LTM.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": "e49bb08a-c72b-4bae-95ea-bb2c4c808657",
"Name": "F5LTM.PoolName",
"Label": "LTM Pool name",
"HelpText": "Name of F5 pool",
"DefaultValue": "",
"DisplaySettings": {
"Octopus.ControlType": "SingleLineText"
}
},
{
"Id": "50225d2a-503c-443e-85ca-8a42cba25ea3",
"Name": "F5LTM.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": "559c46da-55be-4bb7-88fd-0d17b09455c5",
"Name": "F5LTM.HostName",
"Label": "LTM Host name",
"HelpText": "The DNS name or IP address of the F5 LTM device.",
"DefaultValue": "",
"DisplaySettings": {
"Octopus.ControlType": "SingleLineText"
}
},
{
"Id": "25f4bb72-26df-4c97-8b4b-fbac72aa2655",
"Name": "F5LTM.Username",
"Label": "LTM username",
"HelpText": "Credential used to access F5 REST API",
"DefaultValue": "",
"DisplaySettings": {
"Octopus.ControlType": "SingleLineText"
}
},
{
"Id": "4973c257-489f-4c1c-8c30-721e3ff11ccc",
"Name": "F5LTM.Password",
"Label": "LTM password",
"HelpText": "Credential used to access F5 REST API",
"DefaultValue": "",
"DisplaySettings": {
"Octopus.ControlType": "Sensitive"
}
}
],
"Properties": {
"Octopus.Action.Script.ScriptSource": "Inline",
"Octopus.Action.Script.Syntax": "PowerShell",
"Octopus.Action.Script.ScriptBody": "# Based on the F5 template by spuder.\n# This template has been translated to use REST instead of the iControl SOAP commandlets.\n# https://www.powershellgallery.com/packages/F5-LTM/1.4.297\n# https://devcentral.f5.com/s/articles/powershell-module-for-the-f5-ltm-rest-api\nImport-Module -Name F5-LTM\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 $member_addr = $member\n\n Write-Host \"Waiting for current connections to drop to \"$ConnectionCount\n\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-PoolMemberStats -PoolName $pool_name -Address $member_addr\n $MemberStatisticEntry = $MemberStatisticsA.'serverside.curConns'\n $cur_connections = $MemberStatisticEntry.Value; \n\n Write-Host \"Current Connections: $cur_connections\"\n\n Start-Sleep -s 5\n }\n}\n\n$Pool = $OctopusParameters['F5LTM.PoolName'].trim();\n\nIf ([string]::IsNullOrWhiteSpace($OctopusParameters['F5LTM.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['F5LTM.MemberIP']\n}\n\n$Member = $ip\n\nWrite-Host \"Member is $Member\"\n\n# Gets the hostname of the current machine being deployed.\n$curhost = hostname\n$hostname = $OctopusParameters['F5LTM.HostName']\n$username = $OctopusParameters['F5LTM.Username']\n$password = ConvertTo-SecureString $OctopusParameters['F5LTM.Password'] -AsPlainText -Force\n$credential = New-Object System.Management.Automation.PSCredential ($username, $password)\n\nWrite-host \"Currently deploying to $curhost\"\n\nIf (($OctopusParameters['F5LTM.EnableOrDisable'] -ne \"Enabled\") -and ($OctopusParameters['F5LTM.WaitForConnections'] -eq \"True\"))\n{\n New-F5Session -LTMName $hostname -LTMCredentials $credential\n\n Write-Host \"Setting $Member to $($OctopusParameters['F5LTM.EnableOrDisable']) in $Pool pool\";\n\n Disable-PoolMember -PoolName $Pool -Address $Member\n\n Write-Host \"Waiting for connections to drain before deploying. This could take a while....\"\n\n WaitFor-ConnectionCount -pool_name $Pool -member $Member -MaxWaitTime $OctopusParameters['F5LTM.MaxWaitTime'] -ConnectionCount $OctopusParameters['F5LTM.ConnectionCount']\n\n if ($OctopusParameters['F5LTM.EnableOrDisable'] -eq \"Disabled\") \n {\n Write-Host \"Setting $Member to Offline in $Pool pool\";\n\n Disable-PoolMember -PoolName $Pool -Address $Member -Force\n }\n}\nElse\n{\n New-F5Session -LTMName $hostname -LTMCredentials $credential\n\n Write-host \"Setting $Member to $($OctopusParameters['F5LTM.EnableOrDisable']) in $Pool pool.\"\n\n if ($OctopusParameters['F5LTM.EnableOrDisable'] -eq \"Disabled\") \n {\n Disable-PoolMember -PoolName $Pool -Address $Member -Force\n } \n Else\n {\n Enable-PoolMember -PoolName $Pool -Address $Member\n }\n}"
},
"Category": "F5",
"HistoryUrl": "https://github.com/OctopusDeploy/Library/commits/master/step-templates/f5-ltm-rest-enable-disable-member.json",
"Website": "/step-templates/4703dd4c-9f2d-471d-b15a-c1e345378695",
"Logo": "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",
"$Meta": {
"Type": "ActionTemplate"
}
}Provided under the Apache License version 2.0.