Forum Discussion

stucky101_88485's avatar
stucky101_88485
Icon for Nimbostratus rankNimbostratus
Feb 26, 2013

Cannot add 3rd irule to vip due to priority error even if priorities are different

Gurus

 

I posted this on the pycontrol group already but it's probably more of an icontrol so I'm posting it here again.

 

https://devcentral.f5.com/community/group/aft/2166035/asg/4

 

For those not subscribed to the pycontrol group I'm pasting this in here again. Sorry for cross-post.

 

****************************************************************

 

I'm trying to use it to dynamically add a maintenance irule and then remove it again based on a ruby script that's out on devcentral.

 

However, I'm running into a wall finally and it smells like a bug or massively misleading API error to me.

 

I know that icontrol is stricter than the gui and won't let me add 2 irules with the same priority except I can prove to you that it does anyway whereas I cannot add a 3rd iRule

 

if 2 exist already no matter what the priorities are.

 

Case in point. I have a test vs with no irules. I can use my pycontrol script to add a redirect rule no problem.

 

***********************

 

SCENARIO 1 (works when it shouldn't) :

 

[stucky@vito pycontrol]$ ./maintenance.py blablabla

 

The iRule 'api_maintenance' already existed but got refreshed.

 

 

Successfully added iRule 'api_maintenance' to virtual server '/Common/test'

 

The irule is set to priority 1 :

 

[root@stglbltm01:Active:Standalone] config tmsh show ltm rule api_maintenance

 

 

---------------------------------------------

 

Ltm::Rule Event: api_maintenance:HTTP_REQUEST

 

---------------------------------------------

 

Priority 1

 

Executions

 

Now as per docs I should not be able do this again if another rule with pri 1 already exists. To test let's remove this rule again and manually add the test rule with pri 1.

 

[root@stglbltm01:Active:Standalone] config tmsh list ltm virtual test

 

ltm virtual test {

 

destination ip:http

 

ip-protocol tcp

 

mask 255.255.255.255

 

profiles {

 

http { }

 

tcp { }

 

}

 

rules {

 

test_hipri

 

}

 

[root@stglbltm01:Active:Standalone] config tmsh show ltm rule test_hipri

 

 

----------------------------------------

 

Ltm::Rule Event: test_hipri:HTTP_REQUEST

 

----------------------------------------

 

Priority 1

 

Executions

 

 

Ok now let's try to use pycontrol to add the maintenance rule again:

 

[stucky@vito pycontrol]$ ./maintenance.py blablabla

 

 

The iRule 'api_maintenance' already existed but got refreshed.

 

 

Successfully added iRule 'api_maintenance' to virtual server '/Common/test'

 

 

Let's confirm we have both rules associated with the vs:

 

[root@stglbltm01:Active:Standalone] config tmsh list ltm virtual test

 

ltm virtual test {

 

destination ip:http

 

ip-protocol tcp

 

mask 255.255.255.255

 

profiles {

 

http { }

 

tcp { }

 

}

 

rules {

 

test_hipri

 

api_maintenance

 

}

 

Now I don't mind if something works that shouldn't as much as I do when something doesn't work that should !

 

**************************

 

SCENARIO 2 (Doesn't work when it really should !!)

 

Let's add 2 irules to this vs both with DIFFERENT priorities (other than 1 for sure !):

 

[root@stglbltm01:Active:Standalone] config tmsh list ltm virtual test

 

ltm virtual test {

 

destination ip:http

 

ip-protocol tcp

 

mask 255.255.255.255

 

profiles {

 

http { }

 

tcp { }

 

}

 

rules {

 

log_persistence_cookie

 

filter_http_methods

 

}

 

 

We have pri 800 and pri 10.

 

[root@stglbltm01:Active:Standalone] config tmsh show ltm rule log_persistence_cookie

 

 

----------------------------------------------------

 

Ltm::Rule Event: log_persistence_cookie:HTTP_REQUEST

 

----------------------------------------------------

 

Priority 800

 

Executions

 

 

[root@stglbltm01:Active:Standalone] config tmsh show ltm rule filter_http_methods

 

 

-------------------------------------------------

 

Ltm::Rule Event: filter_http_methods:HTTP_REQUEST

 

-------------------------------------------------

 

Priority 10

 

Executions

 

 

According to the docs I should have no problem adding a 3rd irule with priority 1 here via pycontrol so let's try :

 

[stucky@vito pycontrol]$ ./maintenance.py blablab

 

The iRule 'api_maintenance' already existed but got refreshed.

 

 

No handlers could be found for logger "suds.client"

 

Server raised fault: 'Exception caught in LocalLB::urn:iControl:LocalLB/VirtualServer::add_rule()

 

Exception: Common::OperationFailed

 

primary_error_code : 17237537 (0x01070621)

 

secondary_error_code : 0

 

error_string : 01070621:3: Rule priorities for virtual server (/Common/test) must be unique.'

 

 

This totally hoses me cause I cannot finish my maintenance script testing now. It's all moot if I can't get this rule added/removed on the fly.

 

Please tell me I'm doing something wrong !

 

Keep up the great forum !

 

thx

 

12 Replies

  • Brent

     

    I do understand the importance of priorities and I didn't mean to say they are arbitrary in general. I just felt that the P100 passed to the method was "arbitrary" considering that it had absolutely no impact on the actual priority.

     

    The only thing it achieves is let me append the rule to begin with. Any number over 4 does the same thing.

     

    The other statement you made is interesting.

     

     

     

    My expectation would be that if you set priority 100 on a virtual with 5 rules, that the priority 100 iRule would become p5 (0 - 4 already existing)

     

     

     

    Why would you expect that ? If I add a rule to a vip with a P100 and the rule itself has no priority set why would the API lower it to 5 ? Priorities are not dynamic.

     

    They are either 500 (default) or anything I set so I don't see how you came to your conclusion.

     

     

    As far as the other issue goes I still don't see how you achieve this without persisting the original rule list to disk. Once I enable a maint page it could be hours until I remove it again.

     

    If I save the original list in a var called rule_list then I will have lost it the moment the script has executed.

     

    If anything I'd imagine you save the original rules to a file and then have the script read it back whenever the maintenance is over.

     

     

    I agree that this could be important one day and I'm curious now how you plan to achieve this using your idea.

     

    Let's say you have a maint at 6pm that is scheduled till 10pm.

     

    The idea would be to run a script that saves the original rules and replace them with one maintenance rule.

     

    Then at 10pm you'd run it again to enable the original rules again but you'd have to read them back from somewhere, hence I thought you implied saving the entire config.

     

     

    Sorry but am I missing something here ?
  • Brent_West_7733's avatar
    Brent_West_7733
    Historic F5 Account
    The reason I thought that rule priorities might re-order is that is how certain other interfaces within iControl behave. Pool Members in GTM for example, re-order to be gapless.

     

     

    After testing...

     

     

     

    //Removed all rules for /Common/test

     

    //get_rule for /Common/test

     

     

    //add_rule for {'rule_name': 'rule_0' 'priority': '0'}

     

    //get_rule for /Common/test

     

    Rules for virtual /Common/test

     

    Rule Name: /Common/rule_0

     

    Rule Priority: 0 //What I expected

     

     

    //add_rule for {'rule_name': 'rule_0', 'priority': '0'}{'rule_name': 'rule_1', 'priority': '100'}{'rule_name': 'rule_2', 'priority': '200'}{'rule_name': 'rule_3', 'priority': '50'}{'rule_name': 'rule_2', 'priority': '400'}

     

    //get_rule for /Common/test

     

    Rules for virtual /Common/test

     

    Rule Name: /Common/rule_0

     

    Rule Priority: 0

     

    Rule Name: /Common/rule_1

     

    Rule Priority: 100 //Not what I expected

     

    Rule Name: /Common/rule_2

     

    Rule Priority: 200 //Again, not what I expected

     

    Rule Name: /Common/rule_3

     

    Rule Priority: 50 // This one is now in the proper processing order to fire before rule_1, rule_2, rule_4

     

    Rule Name: /Common/rule_4

     

    Rule Priority: 400

     

     

    //add_rule for {'rule_name': 'rule_5', 'priority': '1'}

     

    //get_rule for /Common/test

     

    Rules for virtual /Common/test

     

    Rule Name: /Common/rule_0

     

    Rule Priority: 0

     

    Rule Name: /Common/rule_1

     

    Rule Priority: 100

     

    Rule Name: /Common/rule_2

     

    Rule Priority: 200

     

    Rule Name: /Common/rule_3

     

    Rule Priority: 50

     

    Rule Name: /Common/rule_4

     

    Rule Priority: 400

     

    Rule Name: /Common/rule_5

     

    Rule Priority: 1 //Fires after rule_0, and before all other rules

     

     

    To answer your original question, this is why priorities are important when adding rules, since they are stateful, not gapless, and cannot be inserted to force an adjacent rule down, you must explicitly define the order you wish them to run in.

     

    When created by the GUI, they are applied in order 0,1,2,3,4,5 with no gaps. When you assign them via iControl, they are assigned with the priorities you specify.

     

    If you were to someday have a need to insert a rule in between 2 gapless rules, you would first need to remove the rule with the higher priority. And since this may impact the whole rule chain, you may need to remove them all in order to insert the new rule at the beginning of the list, change the rule priorities in your dictionary, and then re-add them.

     

     

    To answer your maintenance rule question, I didn't mean to say that you should permanently remove them, I only meant to say they you would need to remove them to re-prioritize them and add them back with your new rule, all within one run of the program. Once your maintenance was over you would simply 'remove_rule(virtualserver, rule_name)'