Forum Discussion

Guilherme's avatar
Guilherme
Icon for Nimbostratus rankNimbostratus
Feb 18, 2020

Help with irule structure

Hi sirs,

I just wrote a rule that reads a specific HTTP header and saves it to USER_COD and if it has an empty value or PRINT value it should forward the connection to a certain pool, if the this value is a specific number (can be like 1-999), this number should be compared against numbers that are inside the datagroups and if there is a match the connection will be forwarded to the correct pool, if no value is available in the datagroups to compare against, the default pool will be chosen. Unfortunately I am not a great expert in programming (as you guys can see) and during the tests I got several errors in variables reading, I believe that error is related to the irule structure when try to save the value (when receiving PRINT or empty) and when the value is compared to the datagroup, I really need a help with the experts guys that live here hehe

when RULE_INIT {
# 0 - log off
# 1 - log on
set static::debug_user_cod 0
}
when HTTP_REQUEST {
#	checks if the USER_COD is empty or PRINT
if {[HTTP::header value "USER_COD"] equals "" or "PRINT" }  {
# 	save it on USER_COD_NULL
	set USER_COD_NULL [HTTP::header value "USER_COD"]
#	forward to pool_default
	pool POOL_DEFAULT
#	show log
	if { $static::debug_user_cod } { log local0. "src: [IP::client_addr] get USER_COD: $USER_COD - send it to default pool" }
#	If USER_COD contains numbers save it on USER_COD to compare with DGs
} else { set USER_COD [HTTP::header value "USER_COD"] }
#	show log	
if { $static::debug_user_cod } {
	set HTTP_DEBUG_COD "src: [IP::client_addr] URL -> [HTTP::host][HTTP::uri]"
	log local0. "----------------------------------------"
	log local0. "$HTTP_DEBUG_COD (REQUEST)"
	log local0. "Value get on USER_COD: $USER_COD"
	log local0. "----------------------------------------"
	}
#	Compare the number saved on USER_COD with DGs to forward for the specific pool
if { $USER_COD == $DG_01 } {
	pool POOL_DG_01
} elseif { $USER_COD == $DG_02 } {
	pool POOL_DG_02
} elseif { $USER_COD == $DG_03 } {
	pool POOL_DG_03
} elseif { $USER_COD == $DG_04 } {
	pool POOL_DG_04
} elseif { $USER_COD == $DG_05 } {
	pool POOL_DG_05
} elseif { $USER_COD == $DG_06 } {
	pool POOL_DG_06
} elseif { $USER_COD == $DG_07 } {
	pool POOL_DG_07
#	If no values match forward it to default one
} else { pool POOL_DEFAULT }
}
when SERVER_CONNECTED {
    if { $static::debug_user_cod } { 
	log local0. "----------------------------------------"
	log local0. "src: [IP::local_addr] - Dst Member: [IP::remote_addr] - USER_COD: $USER_COD"
	log local0. "----------------------------------------"
}
}

Erros that I got during the tests (a lot of them):

 TCL error: /Common/test_log <HTTP_REQUEST> - invalid command name "894"    while executing "$USER_COD"

test_log <HTTP_REQUEST> - can't read "USER_COD": no such variable   while executing "if {[HTTP::header value "USER_COD"] equals "" or "PRINT" }"") }

Looking for a help from you guys... and thanks for everyone who is available to read my post.

5 Replies

  • Hi

    Try something like this...

    when RULE_INIT {
    # 0 - log off
    # 1 - log on
    set static::debug_user_cod 0
    }
     
    when HTTP_REQUEST {
     
        if { $static::debug_user_cod } {
         set USER_COD [HTTP::header value "USER_COD"]
        }
    	
    	#Switch through the values of header USER_COD. If a value matches then send to appropiate pool
    	#if no value matches,including value PRINT or a null value then send to default pool
    	
    	
    	switch -glob [string tolower [HTTP::header value "USER_COD"]] {
    		"dg_01"		{pool POOL_DG_01}
    		"dg_02"		{pool POOL_DG_02}
    		"dg_03"		{pool POOL_DG_03}
    		"dg_04"		{pool POOL_DG_04}
    		"dg_05"		{pool POOL_DG_05}
    		"dg_06"		{pool POOL_DG_06}
    		"dg_07"		{pool POOL_DG_07}
    		default 	{pool POOL_DEFAULT
    		            if { $static::debug_user_cod } {
    		            	log local0. "----------------------------------------"
    	                    log local0. "src: [IP::client_addr] URL -> [HTTP::host][HTTP::uri] (REQUEST)"
    	                    log local0. "Value get on USER_COD: $USER_COD"
    	                    log local0. "----------------------------------------"
    		                } 
    		            }
            }
    }
     
    when SERVER_CONNECTED {
        if { $static::debug_user_cod } { 
    	log local0. "----------------------------------------"
    	log local0. "src: [IP::local_addr] - Dst Member: [IP::remote_addr] - USER_COD: $USER_COD"
    	log local0. "----------------------------------------"
    }
    }
    • Guilherme's avatar
      Guilherme
      Icon for Nimbostratus rankNimbostratus

      Hi iaine,

      Thank you! I cant test right now but I still with a doubt.. how can I insert the empty value into to the datagroup ? There is some situations that header comes empty or with PRINT value and It must be send to a specific pool, may I use the default condition ?

  • Hi

     

    If the header value is null then this should get picked up by the default logic at the end of the code and sent to the default_pool.

     

    The code is written so that is there is a match on a dg_## value in the header then the request will get sent to the corresponding pool. All other requests (ie non-matching) will get sent to the default_pool

    • Guilherme's avatar
      Guilherme
      Icon for Nimbostratus rankNimbostratus

      OK I got you! Im wondering how the switch will call values in the datagroup, it doesnt need to use the "class" match command ?

  • hi

     

    so if you wanted to use a data group, then the code would look something like...

       when HTTP_REQUEST {
          set app_pool [class match -value -- [HTTP::header value "USER_COD"] eq cod_value]
          if {$app_pool ne ""} {
             pool $app_pool
          } else {
             pool default_pool
          }
       }

    ...where cod_value is the name of the data group

     

    ltm data-group internal /Common/cod_value {

      records {

        DG_01 {

          data Pool_01

        }

      }

      type string

    }