Forum Discussion
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
- crosson_16669
Nimbostratus
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- crosson_16669
Nimbostratus
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.
- crosson_16669
Nimbostratus
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. - crosson_16669
Nimbostratus
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 examplesmember = {: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_Historic F5 Accountcrosson,
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 - crosson_16669
Nimbostratus
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 - crosson_16669
Nimbostratus
Does anyone happen to know the equivalent python format for set_monitor_state?
Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com