Forum Discussion

benhaw01_9110's avatar
benhaw01_9110
Icon for Nimbostratus rankNimbostratus
May 03, 2011

No effect when using remove_wideip_pool and add_wideip_pool

Hello.

 

 

I'm using iControl against a v9.4.7 Build330.0 Hotfix HF2 GTM. I am trying to set the ratio of pool members in a wideIP. To be clear, PoolMember's set_ratio method won't do what I want, because I'm trying to set the ratio on the pool within the WideIP, not the ratio of members in a pool.

 

 

At a high level, I'm doing:

 

 

set_active_partition('Partition_1')

 

get_wideip_pool('wideip_name')

 

{get the pool definition from this response based on input parameters}

 

remove_wideip_pool('wideip_name', pooldef from previous step)

 

{set new ratio value on pooldef object}

 

add_wideip_pool('wideip_name', modified pooldef)

 

 

When I run the script, I find that it runs without error, but there is no effect reflected in the GUI, and subsequent runs show that iControl returns the old values as if they were never updated. The user that I'm logging in with has the Administrator role. Running it with only the "remove" request also shows no effect. The pool is not removed.

 

 

I'm attaching the code snippet in question as well as the input and output SOAP. I can attach the entire script if necessary. Am I doing something wrong (i.e. do I need to invoke some kind of "commit" or "update" method after sending these requests)? Does this GTM version have a bug? Does the output SOAP look like a successful response?

 

 

 

Perl code snippet:

 

 

Set the session to the appropriate Partition

 

$soapResponse = $ManagementPartition->set_active_partition(

 

SOAP::Data->name('active_partition' => 'Partition_1'),

 

);

 

&checkResponse($soapResponse);

 

 

 

$soapResponse = $GlobalPoolMember->get_wideip_pool

 

(

 

SOAP::Data->name('wide_ips' => [$sWip]),

 

);

 

&checkResponse($soapResponse);

 

my $poolList = $soapResponse->result->[0];

 

 

Search for the requested pool object from the response

 

my $poolObj;

 

my $found=0;

 

foreach my $pool (@$poolList) {

 

my $name = $pool->{'pool_name'};

 

 

if ($name =~ m/^$sPool$/) {

 

This is the pool we want.

 

$poolObj = $pool;

 

$found++;

 

last;

 

}

 

}

 

die ("Requested pool $sPool not found in $sWip.") unless $found;

 

 

Check to make sure we actually need to do something.

 

die ("Requested pool $sPool ($sWip) ratio is already set to $sRatio. Exiting.") if ($poolObj->{'ratio'} =~ /^$sRatio$/);

 

 

Now for the scary part.

 

Remove the pool...

 

$soapResponse = $GlobalPoolMember->remove_wideip_pool

 

(

 

SOAP::Data->name('wide_ips' => [$sWip]),

 

SOAP::Data->name('wideip_pools' => $poolObj),

 

);

 

&checkResponse($soapResponse);

 

 

Edit our pool object with the new settings

 

$poolObj->{'ratio'} = $sRatio;

 

 

Re-add it with the appropriate settings.

 

$soapResponse = $GlobalPoolMember->add_wideip_pool

 

(

 

SOAP::Data->name('wide_ips' => [$sWip]),

 

SOAP::Data->name('wideip_pools' => $poolObj),

 

);

 

&checkResponse($soapResponse);

 

 

 

Excerpts from the SOAP requests sent for remove_wideip_pool and add_wideip_pool:

 

 

(attached)

 

 

 

The output from remove_wideip_pool and add_wideip_pool:

 

 

 

(attached)

 

 

/e:envelope

 

  • This is a very common mistake when dealing with the loosely typed languages like Perl and Python.

    Your problem is that the second parameter for the remove_wideip_pool() and add_wideip_pool() methods are a 2-d array and you are passing in a scalar value. The method signatures are

    GlobalLB.WideIP.add_wideip_pool(
      in String [] wide_ips,
      in GlobalLB__WideIP__WideIPPool [] [] wideip_pools
    )
    GlobalLB.WideIP.remove_wideip_pool(
      in String [] wide_ips,
      in GlobalLB__WideIP__WideIPPool [] [] wideip_pools
    )

    The methods are designed to allow you to work on multiple wideips in a single call. And for each wideip, you have a list of pools you can add/remove.

    You are calling the methods as if they were like:

    GlobalLB.WideIP.add_wideip_pool(
      in String [] wide_ips,
      in GlobalLB__WideIP__WideIPPool wideip_pools
    )
    GlobalLB.WideIP.remove_wideip_pool(
      in String [] wide_ips,
    
      in GlobalLB__WideIP__WideIPPool wideip_pools
    )

    On the server, we iterate through each of the wide_ips in the first parameter and then extract the list from the second parameter's associated 1-degree index. In your case, the second parameter isn't an array so it's treated as an array of size zero so it's essentially a no-op on the server. The same as if you passed in an empty size array.

    You are going to have to create a 2-D array something like this:

     Now for the scary part.
     Remove the pool...
    my $oldPoolObj = $poolObj;
    my @oldPoolObjA;
    push @oldPoolObjA, $oldPoolObj;
    my @oldPoolObjAofA;
    push @oldPoolObjAofA, [@oldPoolObjA];
    $soapResponse = $GlobalPoolMember->remove_wideip_pool
    (
        SOAP::Data->name('wide_ips' => [$sWip]),
        SOAP::Data->name('wideip_pools' => [@oldPoolObjAofA]),
    );
    &checkResponse($soapResponse);
     Edit our pool object with the new settings
    $poolObj->{'ratio'} = $sRatio;
    my @newPoolObjA;
    push @newPoolObjA, $poolObj;
    my @newPoolObjAofA;
    push @newPoolObjAofA, [@newPoolObjA];
     Re-add it with the appropriate settings.
    $soapResponse = $GlobalPoolMember->add_wideip_pool
    (
        SOAP::Data->name('wide_ips' => [$sWip]),
        SOAP::Data->name('wideip_pools' => [@newPoolObjAofA]),
    );
    &checkResponse($soapResponse);

    In the trace, you should now see the wideip_pools parameter as a 2-d array.

    This hasn't been tested, but I think it'll get you where you want to go. Let me know if you are still stuck after this.

    -Joe

  • Fantastic. Changing this:

     

     

    SOAP::Data->name('wideip_pools' => $poolObj),

     

     

    to this:

     

     

    SOAP::Data->name('wideip_pools' => [[$poolObj]]),

     

     

    works great.

     

     

    Thank you for explaining how the device handles the request on the server side. It was helpful in understanding why this is necessary.

     

  • Sweet, I didn't realize you could double bracket a scalar to turn it into a 2-d array. Learn something new everyday!

     

     

    -Joe