Disable Multiple Pools Members At Once

Making a single rest call, has anyone been able to disable multiple pool members? I’m running into a problem where I want to only disable 2 of the 4 members, but every time I use the PATCH or PUT method, it wipes out the members that are not referenced in the JSON data. I should mention that I’m also using the latest version of iControlRest.

Example:

URL: https://myf5.foobar.com/mgmt/tm/ltm/pool/testpool/

Method: PATCH

Current Pool Members: member1,member2,member3,member4

Data:

{
"members":[
 {"name":"member1:80","state": "user-up", "session": "user-disabled"},
 {"name":"member2:80","state": "user-up", "session": "user-disabled"}
]
}

Expected Result: Half of the pool members will be disabled (1 and 2), while the other half are enabled (3 and 4)

Actual Result: Pool members 3 and 4 are wiped out and only 1 and 2 are showing as part of the pool.

Hi, I think this is an expected behavior and you may have to request json more than once. [ ]

iControl® REST User Guide - Page 47… “In other words, the PUT method overwrites any existing properties of thecollection. Therefore, if you use the PUT method to modify one member object of an LTM pool that originally had three members, the request reduces the collection to just the single member.”

Currently, members in a pool are all in the pool object and not by themselves in a sub-collection. Because of this, you’ll want to read in the current pool definition, then send the whole thing back in with the edits you want to make. What you have to realize is that you’re patching the whole Pool to this new state. I believe F5 in version 12 was going to change pool members to a sub-collection which would allow you to patch a member individually. I have not found a way around this yet.

Currently, members in a pool are all in the pool object and not by themselves in a sub-collection. Because of this, you’ll want to read in the current pool definition, then send the whole thing back in with the edits you want to make. What you have to realize is that you’re patching the whole Pool to this new state. I believe F5 in version 12 was going to change pool members to a sub-collection which would allow you to patch a member individually. I have not found a way around this yet.

Okay, this is a very rough attempt, but it mostly gets the job done. The below script requires three parameters:

* pool name
* enable or disable
* a comma-delimited list of pool members defined by IP:port

So for example:

./update-pool.sh test-pool disable 10.10.10.10:80,10.10.10.11:80

So based on the entered list of pool members, the script will loop through the existing pool members and create a new update string, then launch a cURL to update the pool. As it stands, if the (existing) pool member isn’t listed in the argument it’ll be marked up. To get around that you’d need to enumerate the current status of all of the pool existing pool members, and I didn’t want to do that. I also didn’t parameterize the server host/IP so there’s two places in the below script where you have to change that.

!/bin/bash

if [ -z "$1" ]
then
     bad arguments - quit
    echo "Syntax: update-pool.sh   "
else
     build member list from arguments
    args=($(echo $3 |tr "," "\n"))

     set pool
    thispool=$1

     set enabled/disabled
    action=$2

     build pool list
    pool=($(curl -sk -u 'admin:password' -H "Content-Type: application/json" -X GET https://x.x.x.x/mgmt/tm/ltm/pool/${thispool}?expandSubcollections=true | sed 's/,/\'$'\n/g' | grep name | grep -v ${thispool} | awk -F"\"" '{ print $4 }'))

     establish the memberstring
    memberstring="{\"members\":["

     loop through the pool members to see if any are one of the arguments
    for i in "${pool[@]}"
    do
        notin=0

         loop through the argument member list
        for j in "${args[@]}"
        do
            if [ "$i" == "$j" ]
            then
                notin=1
            fi
        done

         if the argument member was in the pool - update the memberstring value
        if [ $notin -eq 1 ]
        then
            if [ "$action" == "disable" ]
            then
                memberstring="${memberstring}{\"name\":\"$i\",\"state\":\"user-up\",\"session\":\"user-disabled\"},"
            elif [ "$action" == "enable" ]
            then
                memberstring="${memberstring}{\"name\":\"$i\",\"state\":\"user-up\",\"session\":\"user-enabled\"},"
            fi
        else
            memberstring="${memberstring}{\"name\":\"$i\",\"state\":\"user-up\",\"session\":\"user-enabled\"},"
        fi

    done

     remove the last comma and add the end of the POST characters
    memberstring="${memberstring%?}]}"

     prints completed memberstring - enable for testing
     echo "executing: $memberstring"

     execute the cURL PATCH to update the pool
    curl -sk -u 'admin:password' -H "Content-Type: application/json" -X PATCH https://x.x.x.x/mgmt/tm/ltm/pool/${thispool} -d $memberstring

fi

Yes, in BIG-IP version 12.0, ltm pool members will become a sub-collection. Here’s an excerpt: { “items”: [ { “allowNat”: “yes”, “allowSnat”: “yes”, “fullPath”: “/Common/P1”, “generation”: 496, “ignorePersistedWeight”: “disabled”, “ipTosToClient”: “pass-through”, “ipTosToServer”: “pass-through”, “kind”: “tm:ltm:pool:poolstate”, “linkQosToClient”: “pass-through”, “linkQosToServer”: “pass-through”, “loadBalancingMode”: “round-robin”, “membersReference”: { “isSubcollection”: true, “link”: “https://localhost/mgmt/tm/ltm/pool/~Common~P1/members?ver=12.0.0” }, …

Yes, in BIG-IP version 12.0, ltm pool members will become a sub-collection. Here’s an excerpt: { “items”: [ { “allowNat”: “yes”, “allowSnat”: “yes”, “fullPath”: “/Common/P1”, “generation”: 496, “ignorePersistedWeight”: “disabled”, “ipTosToClient”: “pass-through”, “ipTosToServer”: “pass-through”, “kind”: “tm:ltm:pool:poolstate”, “linkQosToClient”: “pass-through”, “linkQosToServer”: “pass-through”, “loadBalancingMode”: “round-robin”, “membersReference”: { “isSubcollection”: true, “link”: “https://localhost/mgmt/tm/ltm/pool/~Common~P1/members?ver=12.0.0” }, …