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?

F5LTM.WaitForConnections = False

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

Kill connections when <=

F5LTM.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.

Max. Wait Time (seconds)

F5LTM.MaxWaitTime = 300

Maximum wait time (in seconds) before killing connections and moving on. Defaults to 5 minutes

LTM Status

F5LTM.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

F5LTM.PoolName

Name of F5 pool

LTM Member IP

F5LTM.MemberIP

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

LTM Host name

F5LTM.HostName

The DNS name or IP address of the F5 LTM device.

LTM username

F5LTM.Username

Credential used to access F5 REST API

LTM password

F5LTM.Password

Credential used to access F5 REST API

Script body

Steps based on this template will execute the following PowerShell script.
Show script
# 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"
  }
}

History »