Forum Discussion

crosson_16669's avatar
crosson_16669
Icon for Nimbostratus rankNimbostratus
Dec 19, 2012

Confusion on changing a pool member state

 

I can display states, nodes, and virtual servers just fine. Attached screenshot is my lazy attempt at diving into only the surface of the iControl api. For the most part I found the API documentation pretty good and useful for finding which methods to call.

 

 

The problem comes when trying to make changes to objects. For example I'd like to use the ltm["LocalLB.PoolMember"].set_monitor_state() method to force nodes offline or online. However it is not obvious what arguments set_monitor_state expects.

 

I have tried variations of the following.

 

member_state = {"member" => {"address" => "172.16.20.65", "port" => 0}, "monitor_state" => "STATE_DISABLED"}

 

member_state = {"member" => {"address" => "172.16.20.65", "port" => 0}, "monitor_state" => 0}

 

member_state = {:member => {:address => "172.16.20.65", :port => 0}, :monitor_state => 0}

 

 

Passing that into the set_monitor_state

 

@ltm["LocalLB.PoolMember"].set_monitor_state("tmp_test_pool", member_state)

 

 

I cannot figure out how it wants the data arranged. Can anyone give me any hints or pointers??

 

8 Replies

  • Hmm I couldn't add the screenshot. Here is an example of being able to make calls and pull data off the LTM.

     

     

    require 'rubygems'

     

    require 'highline/import'

     

    require 'f5-icontrol'

     

     

    @password = ask("Password: ") {|q| q.echo = false}

     

    @username = "somedude"

     

    @poolname = "tmp_test_pool"

     

    @host = "ltm01.whatever.com"

     

     

    @ltm = F5::IControl.new(@host, @username, @password, ["LocalLB.PoolMember"]).get_interfaces

     

     

    while true

     

    string = ""

     

    ltm["LocalLB.PoolMember"].get_monitor_status(poolname).first.each do |member|

     

    status = member.monitor_status

     

    address = member.member.address

     

    port = member.member.port

     

    string << "%s:%d %20s\n" % [address, port, status]

     

    end

     

    system('clear')

     

    puts string

     

    sleep 1

     

    end

     

  • I think you are munging two data types together in your member_state hash. Instead, try something like this:

     

    member = {:address => "172.16.20.65", :port => 0}

     

    monitor_state = "STATE_DISABLED"

     

     

    your next issue is likely due to the fact that the set_monitor_state method wants you to pass in an array of pool names and an array of arrays for the member

     

    set_member_monitor_state(

     

    in String [] pool_names,

     

    in Common__AddressPort [] [] members,

     

    in EnabledState [] [] monitor_states

     

    );

     

     

    that's what the "[]" and "[] []" mean in the method definition.

     

     

    so you would need something like this (if you just wanted to mess around with a single pool and single pool member in the pool)

     

    @ltm["LocalLB.PoolMember"].set_monitor_state(["tmp_test_pool"],[ member],[[monitor_state]])

     

     

    also, if you are using v11.x you should be doing all this in the LocalLB::Pool with set_member_monitor_state

     

  • that's what the "[]" and "[] []" mean in the method definition.

     

     

    I thought of that. The reason I didn't do this, and the reason I got confused, is because get_monitor_status also requires string [] but if you see my example above I did not have to pass it in as an array. I was able to simply use "poolname" and not ["poolname"]

     

     

     

    member = {:address => "172.16.20.65", :port => 0}

     

    monitor_state = "STATE_DISABLED"

     

     

     

    This is a good point. I will try this.

     

     

    also, if you are using v11.x you should be doing all this in the LocalLB::Pool with set_member_monitor_state

     

     

    We standardize on 10.2.3 still. :)

     

     

    Thanks for the help Andy. I'll update you with the status. It may be a few weeks, after the holidays, when I can look at this again.

     

     

     

  • Had a long vacation but will be back in action in a few days. I'll try the monitor_state assignment as you mentioned above to see if it works.
  • I have tried all the variations you gave above plus some alterations of it. I get the following.

     
    
    XSD::ValueSpaceError: {urn:iControl}Common.EnabledState: cannot accept ''
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/wsdl/xmlSchema/simpleType.rb:66:in `check_restriction'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/wsdl/xmlSchema/simpleType.rb:23:in `check_lexical_format'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/mapping/wsdlencodedregistry.rb:125:in `simpleobj2soap'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/mapping/wsdlencodedregistry.rb:118:in `obj2typesoap'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/mapping/wsdlencodedregistry.rb:44:in `obj2soap'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/mapping/mapping.rb:127:in `_obj2soap'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/mapping/wsdlencodedregistry.rb:210:in `elements2soap'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/mapping/wsdlencodedregistry.rb:206:in `each'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/mapping/wsdlencodedregistry.rb:206:in `elements2soap'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/mapping/wsdlencodedregistry.rb:167:in `struct2soap'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/mapping/wsdlencodedregistry.rb:134:in `complexobj2soap'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/mapping/wsdlencodedregistry.rb:120:in `obj2typesoap'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/mapping/wsdlencodedregistry.rb:44:in `obj2soap'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/mapping/mapping.rb:127:in `_obj2soap'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/mapping/wsdlencodedregistry.rb:179:in `array2soap'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/mapping/wsdlencodedregistry.rb:178:in `each'
    ... 14 levels...
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/mapping/wsdlencodedregistry.rb:206:in `elements2soap'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/mapping/wsdlencodedregistry.rb:167:in `struct2soap'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/mapping/wsdlencodedregistry.rb:134:in `complexobj2soap'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/mapping/wsdlencodedregistry.rb:120:in `obj2typesoap'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/mapping/wsdlencodedregistry.rb:44:in `obj2soap'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/mapping/mapping.rb:127:in `_obj2soap'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/mapping/mapping.rb:47:in `obj2soap'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/mapping/mapping.rb:360:in `protect_threadvars'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/mapping/mapping.rb:43:in `obj2soap'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/rpc/proxy.rb:394:in `request_rpc_enc'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/rpc/proxy.rb:376:in `request_rpc'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/rpc/proxy.rb:338:in `request_body'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/rpc/proxy.rb:123:in `call'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/rpc/driver.rb:178:in `call'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/rpc/driver.rb:232:in `set_monitor_state'
    from (irb):135>> 
    
    

    I know that the argument expects two arguments since if I pass 1 or 3 it fails asking for two. So I tried the following examples

    
    member = {:port=>0, :address=>"172.16.20.65"}
    monitor_state = "STATE_DISABLE"
    @ltm["LocalLB.PoolMember"].set_monitor_state(@poolname, [member, monitor_state])
    @ltm["LocalLB.PoolMember"].set_monitor_state([@poolname], [member, monitor_state])
    @ltm["LocalLB.PoolMember"].set_monitor_state(@poolname, [[member], [monitor_state]])
    

    I get the same error on all of them

    The API asks for a struct so I took it to the next extreme via the following.

    
    Struct.new("Member", :address, :port)
    Struct.new("Member_status", :member, :status)
    m = Struct::Member.new("172.16.20.65", 0)
    ms = Struct::Member_status.new(m, 0)
    
    @ltm["LocalLB.PoolMember"].set_monitor_state(@poolname, ms)
    

    API Says it expects a MemberMonitorState which is a struct of IpPortDefinition and EnabledState. IpPortDefinition is a struct of a string, Address, and long, port. The EnabledState looks like simply a 0 or 1.

    https://devcentral.f5.com/wiki/iControl.LocalLB__PoolMember__set_monitor_state.ashx

    Anyhow I get the same errors

    XSD::ValueSpaceError: {urn:iControl}Common.EnabledState: cannot accept ''

  • George_Watkins_'s avatar
    George_Watkins_
    Historic F5 Account
    crosson,

    Give this a shot:

    
    bigip = F5::IControl.new('test-ltm-01', 'admin', 'admin', ['LocalLB.PoolMember']).get_interfaces
    member = { 'address' => '10.84.3.50', 'port' => 80 }
    bigip['LocalLB.PoolMember'].set_monitor_state ['test-ubuntu-lucid'], [ [ { 'member' => member, 'monitor_state' => 'STATE_DISABLED' } ] ]
    bigip['LocalLB.PoolMember'].set_monitor_state ['test-ubuntu-lucid'], [ [ { 'member' => member, 'monitor_state' => 'STATE_ENABLED' } ] ]
    

    Best regards,

    George
  • Pycontrol looks quite a bit more matured than the ruby gem. For now I've gone ahead and made my own wrapper for pool member manipulation. Feel free to use.

     

     

    https://github.com/crosson/util_scripts/blob/master/Pool.rb
  • Does anyone happen to know the equivalent python format for set_monitor_state?