ltm rule command classΒΆ

iRule(1)		      BIG-IP TMSH Manual		      iRule(1)



class
       Advanced access of classes.

SYNOPSIS
       class 'match' (((CLASS_SEARCH_OPTION)  ('-all'))#)?  ('--')?  ITEM
       CLASS_OPERATOR  CLASS_OBJ

   DESCRIPTION
       class match attempts to match the provided  to an element in
        by applying the  to the .

       The return value depends on the option specified. If no option was
       specified, the return value is 1 for a match and 0 for a no-match.

       This command form is equivalent to the current iRule command:
	   matchclass   

       Example:
	   class match [HTTP::uri] ends_with image_class read as, does the URI
       end with an element from image_class.

       Example:
	   class match [IP::client_addr] equals client_ip_class read as, does
       the client IP address exist in the client_ip_class.

       class 'search'  (((CLASS_SEARCH_OPTION)	('-all'))#)?  ('--')?
       CLASS_OBJ  CLASS_OPERATOR  ITEM

   DESCRIPTION
       class search attempts to match the provided  to an element in
        by applying the to the  element.

       The return value depends on the option specified. If no option was
       specified, the return value is 1 for a match and 0 for a no-match.

       This command form is equivalent to the current iRule command:
	   matchclass   

       Example:
	   class search blocked_paths starts_with [HTTP::uri] read as, does
       blocked_paths contain an element that starts with the URI.

       class match & class search difference: Notice that there are
       differences between the two forms: - The order in which you specify
        and .  - The item on which the operator is applied for
       operations other than equals.

       The table below describes the semantics of the different operators when
       used in each of the commands. See also the example below for a code
       snippet depicting the differences:

       operator      class match
       class search equals	return a value indicating  has an
       element that is equal to 		   return a value indicating
        has an element that is equal to  starts_with      return
       a value indicating there is a  element that matches the start of
       	    return a value indicating  value matches the start
       of a  element ends_with	return a value indicating there is a
        element that matches the end of 	 return a value
       indicating  value matches the end of a  element contains
       return a value indicating  value contains a  element
       return a value indicating there is a  element that contains
       

       class match & class search optional arguments: The  for both
       of the above forms of the class command can be: -index	 Changes the
       return value to be the index of the matching class element.  -name
       Changes the return value to be the name of the matching class element.
       -value	 Changes the return value to be the value of the matching
       class element.  -element  Changes the return value to be a list of the
       name and value of the matching class element.  -all	If used with
       -index, -name, -value, -element, changes the return value to all of the
       matching class elements.  (added in v11.0) --	    Terminates option
       processing (useful if the  or  begins with a hyphen).

       The  for both of the above forms can be: equals, starts_with,
       ends_with, contains

       class 'lookup'  ITEM  CLASS_OBJ

   DESCRIPTION
       Equivalent to: class match -value  equals 

       class 'element' (-name | -value)?  ('--')?  INDEX  CLASS_OBJ

   DESCRIPTION
       Returns a list containing the name and value of the element found at
        in .

       Note: class indexes are not guaranteed to be consistent and may change
       when a datagroup is modified. This could happen if the event execution
       becomes suspended or across executions of different events.

       The  for this command can be:
	   -name   Changes the return value to be the name of the class
       element at the index.
	   -value  Changes the return value to be the value of the class
       element at the index.
	   --	   Terminates option processing.

       class 'type'  CLASS_OBJ

   DESCRIPTION
       Returns the type of the , currently only string, IP, or value.

       class 'exists'  CLASS_OBJ

   DESCRIPTION
       Returns 1 or 0 depending on whether a class named  actually
       exists.

       class 'size'  CLASS_OBJ

   DESCRIPTION
       Returns the number of elements currently found in .

       class 'names'  (-nocase)?  ('--')?  CLASS_OBJ  (PATTERN)?

   DESCRIPTION
       Returns the names of the class elements.

       class 'get' (-nocase)?  ('--')?	CLASS_OBJ  (PATTERN)?

   DESCRIPTION
       Returns a list containing the names or a list of the name and value
       currently found in .  An optional  may be specified to
       restrict the list to names that match the Tcl glob pattern.
       Additionally, the switch -nocase may be specified to enable case-
       insensitive pattern matching.  This command provides a way to access
       the class as a Tcl list similar to previously access the global
       variable named the same as the list.

       Note: Use class get only if you want to manage a class as a list. If
       you are looking for an element within the class, class search and class
       match are far more efficient. This is particularly important when using
       large classes.

       class 'startsearch'  CLASS_OBJ

   DESCRIPTION
       Returns a  to be used with each of the following commands.

       class ('anymore' | 'donesearch' | 'nextelement')  (-name | -value |
       -index | -element)?  ('--')?  CLASS_OBJ	(CLASS_SEARCH_ID)?

   DESCRIPTION
       Subcommand nextelement returns a list containing the name and value of
       the next element in the current search.

       -index	    Changes the return value to be the index of the next class
       element.  -name	      Changes the return value to be the name of the
       next class element.  -value	 Changes the return value to be the
       value of the next class element.  --	      Terminates option
       processing.

       Subcommand anymore returns 1 or 0 depending on whether there are more
       elements to iterate on in the .

       Subcommand donesearch terminates the search. After using this command,
       executing 'class anymore' or 'class nextelement' will cause a runtime
       error. To exit a loop early, use break . Once done with the search and
       outside any loop referencing the search id, use 'class donesearch' to
       clean up the memory associated with the search.

DESCRIPTION
       The class command, implemented in v10.0.0, allows you to query data
       groups and data group properties.

       These commands work for both internal (defined in the bigip.conf) and
       external (custom file) data groups. Internal data groups were not able
       to make use of the name/value pairing with the := separator until
       version 10.1. As of 10.1 all classes support the name/value pairing.

       The class command deprecates the findclass and matchclass commands as
       it offers better functionality and performance than the older commands.

       Note -
	   You should not use a $:: or :: prefix on the datagroup name when
       using the class command (or in any datagroup reference on 9.4.4 or
       later).

	   In v9.4.4 - 10, using $::datagroup_name will work but demote the virtual server from running on all TMMs. For details, see the CMP compatibility page.

	   In v11, using $::datagroup_name will result in a TCL runtime error and a reset being sent to the client!

       Note -
	   Starting in v11, any data-groups that are configured in a partition
       other than Common must be referenced by
       /Partition_Name/Data-Group_Name, even by iRules configured in that
       partition. Data-groups referenced only by name are implicitly presumed
       to be /Common/Data-Group_Name.

       Note -
	   When using the equals operator on IP classes, or when using the
       starts_with or ends_with operators, if multiple possible matches are
       found in the class, then the longest match is always chosen. This is
       not true when using the contains operator. See the example below for
       more details.

RETURN VALUE
VALID DURING
       CLASS_FUNCTION, GLOBAL_GTM, INFORMATIONAL_COMMAND

EXAMPLES
	# External Class Format (v10):
	# class namevalue {
	#   "name1" := "value",
	#   "name2" := "value",
	# }

	# Internal Class Format (v10.1):
	# class namevalue {
	#    {
	#	"name1" { "value1" }
	#	"name2" { "value2" }
	#    }
	# }

	# Internal Class Format (v11.0):
	# ltm data-group internal name_value_dg {
	#     records {
	#	  name1 {
	#	      data value1
	#	  }
	#	  name2 {
	#	      data "value2 with spaces"
	#	  }
	#     }
	#    type string
	# }

	#
	# The example below demonstrates the differences between class match and class search when applied to a data group using different keys and operations (note that no option was specified, so the return value shown in the tables below is the operation result code). The iRule first gets the contents of the data group being queried and then performs the various operations using both forms. When a match occurs, the matching data group key is shown as well.
	when RULE_INIT {

	    log local0.info "dg_test_class: [class get dg_test_class]"
	    foreach val {p://a.b p://a.b/x p://a.b/x/y p://a.b/x/y/z } {
		log local0.info "+[string repeat - 15]|[string repeat - 15]|[string repeat - 15]|[string repeat - 15]+"
		log local0.info "[format |%-15s|%15s|%15s|%15s| value operation {class match} {class search}]"
		foreach oper {equals starts_with ends_with contains} {
		    set rc_match "[class match -name $val $oper dg_test_class]:[class match $val $oper dg_test_class]"
		    set rc_search "[class search -name dg_test_class $oper $val]:[class search dg_test_class $oper $val]"
		    log local0.info "[format |%-15s|%15s|%15s|%15s| $val $oper $rc_match $rc_search ]"
		}
		log local0.info "+[string repeat - 15]|[string repeat - 15]|[string repeat - 15]|[string repeat - 15]+"
	    }
	}

	# Below is the resulting log output (note the line prefix was stripped for brevity):
	# "/Common/rl_test_dg : dg_test_class: {p://a.b/x/y a_b_x_y} {p://y.y/x y_y_x} {p://u.v/w u_v_w}"
	# "/Common/rl_test_dg : +---------------|---------------|---------------|---------------+"
	# "/Common/rl_test_dg : |value	   |	  operation|	class match|   class search|"
	# "/Common/rl_test_dg : |p://a.b	   |	     equals|		 :0|		 :0|"
	# "/Common/rl_test_dg : |p://a.b	   |	starts_with|		 :0|  p://a.b/x/y:1|"
	# "/Common/rl_test_dg : |p://a.b	   |	  ends_with|		 :0|		 :0|"
	# "/Common/rl_test_dg : |p://a.b	   |	   contains|		 :0|  p://a.b/x/y:1|"
	# "/Common/rl_test_dg : +---------------|---------------|---------------|---------------+"
	# "/Common/rl_test_dg : +---------------|---------------|---------------|---------------+"
	# "/Common/rl_test_dg : |value	   |	  operation|	class match|   class search|"
	# "/Common/rl_test_dg : |p://a.b/x	   |	     equals|		 :0|		 :0|"
	# "/Common/rl_test_dg : |p://a.b/x	   |	starts_with|		 :0|  p://a.b/x/y:1|"
	# "/Common/rl_test_dg : |p://a.b/x	   |	  ends_with|		 :0|		 :0|"
	# "/Common/rl_test_dg : |p://a.b/x	   |	   contains|		 :0|  p://a.b/x/y:1|"
	# "/Common/rl_test_dg : +---------------|---------------|---------------|---------------+"
	# "/Common/rl_test_dg : +---------------|---------------|---------------|---------------+"
	# "/Common/rl_test_dg : |value	   |	  operation|	class match|   class search|"
	# "/Common/rl_test_dg : |p://a.b/x/y    |	     equals|  p://a.b/x/y:1|  p://a.b/x/y:1|"
	# "/Common/rl_test_dg : |p://a.b/x/y    |	starts_with|  p://a.b/x/y:1|  p://a.b/x/y:1|"
	# "/Common/rl_test_dg : |p://a.b/x/y    |	  ends_with|  p://a.b/x/y:1|  p://a.b/x/y:1|"
	# "/Common/rl_test_dg : |p://a.b/x/y    |	   contains|  p://a.b/x/y:1|  p://a.b/x/y:1|"
	# "/Common/rl_test_dg : +---------------|---------------|---------------|---------------+"
	# "/Common/rl_test_dg : +---------------|---------------|---------------|---------------+"
	# "/Common/rl_test_dg : |value	   |	  operation|	class match|   class search|"
	# "/Common/rl_test_dg : |p://a.b/x/y/z  |	     equals|		 :0|		 :0|"
	# "/Common/rl_test_dg : |p://a.b/x/y/z  |	starts_with|  p://a.b/x/y:1|		 :0|"
	# "/Common/rl_test_dg : |p://a.b/x/y/z  |	  ends_with|		 :0|		 :0|"
	# "/Common/rl_test_dg : |p://a.b/x/y/z  |	   contains|  p://a.b/x/y:1|		 :0|"
	# "/Common/rl_test_dg : +---------------|---------------|---------------|---------------+"

	# This example disables compression based on source IP's in an address type datagroup named localusers_dg
	when HTTP_REQUEST {
	    if { [class match [IP::client_addr] equals "localusers_dg" ] } {
		COMPRESS::disable
	    }
	}

	# This v10 example chooses a pool based on the URI requested:
	# /config/app_class.dat:
	# "/trxdef/" := "trx_pool",
	# "/aaa/" := "aaa_pool",
	# "/abscon/" := "abs_pool",

	# class app_class {
	#    type string
	#    filename app_class.dat
	# }
	rule appl_director {
	   when HTTP_REQUEST {
	      set app_pool [class match -value -- [HTTP::uri] starts_with app_class]
	      if {$app_pool ne ""} {
		 pool $app_pool
	      } else {
		 pool default_pool
	      }
	   }
	}

	# This example chooses a pool based on the time of day:
	# /config/daily_schedule.dat:
	# 0 := early_morning_pool,
	# 7 := morning_rush,
	# 10 := midday_pool,
	# 15 := afternoon_rush,
	# 18 := evening_pool,

	# class daily_schedule {
	#    type value
	#    filename daily_schedule.dat
	# }

	rule daily_director {

	   # Initialize a variable to track the closest hour match
	   # as we loop through the datagroup elements.
	   # We want to find the lowest hour in the datagroup that is
	   # greater or equal to the current hour.
	   #
	   # Note: The order of datagroup elements is not guaranteed
	   # so we must loop through all elements to find the best match.

	   when HTTP_REQUEST {

	      # Get the hour of day
	      set hour_now [clock format [clock seconds] -format {%H}]

	      # Save a search ID for the daily_schedule datagroup
	      set id [class startsearch daily_schedule]

	      # Initialize a variable to track the closest hour match
	      # By setting this to higher than the highest hour of the day,
	      # any match in the datagroup will override this default value.
	      set best_match 24

	      # Loop through the datagroup
	      while { [class anymore daily_schedule $id] } {

		 # Save the current element's key and value to a TCL list
		 set x [class nextelement daily_schedule $id]

		 # Save the current datagroup element's hour field (the first list element)
		 # to a variable so we don't rerun the lindex several times
		 set hour_class [lindex $x 0]

		 # Check if the current hour is greater than the the current element key
		 if {$hour_now >= $hour_class && $hour_class < $best_match} {

		    # Save the currently matched hour to see if it's the best match
		    set best_match $hour_class

		    # Save the value as the pool name
		    set pool [lindex $x 1]
		 }
	      }
	      # Assign the best match's corresponding pool
	      pool $pool
	   }
	}

	# This example demostrates how to loop through each element in a datagroup using 'class startsearch' and exit the loop once a match is found. Cleanup of internal structures is done using 'class donesearch':
	when RULE_INIT {

	   # Save a class name to search through
	   set class_name numbers_class

	   # Save a search ID for the datagroup
	   set id [class startsearch $class_name]

	   # Loop through the class row by row
	   while {[class anymore $class_name $id]}{
	      set element [class nextelement $class_name $id]
	      log local0. "\[class nextelement $class_name $id\]: $element"

	      # Perform some operation against the current datagroup key and/or value

	      # Check if the element's key is greater than 2
	      if {[lindex $element 1] > 2}{

		 # Exit the loop if the logic check is true
		 log local0. "Found key greater than 2, breaking out of loop"
		 break
	      }
	   }
	   # Clean up the search
	   class donesearch $class_name $id
	}

	# This example extracts an base64 encoded image from a class to send in an HTTP response when load balancing failed:
	# /config/img.txt:
	# "img" := "R0lGODlhEgAeANUAABAREz9CSEBBQz0+QB8hJCIkJ5eZnGJlaXN2egQJDwUKEDo+Q0VJTgE
	#	    DBQULEQUKDwMGCTo+Qk1RVUtPU0pOUk9TV1RYXFZaXlxgZFtfYy0vMRcYGTEzNR8gIW5xdG1
	#	    wc2lsb2hrbklLTXh7fnV4e3R3enN2eXF0d4SHiqCipJeZmwQKDwULEDU6PktQVFtfYjI4PHN
	#	    2eAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAEgAeAEA
	#	    G20CRcEgsDjFIZGa5fDmTSId0Sq2yroqsdsvVnr5fk9gUK8fAX4Z6zW6vu3Duak6v2+mIfH7
	#	    E7/P1eSGsDjFIZGa5fDmTSId0Sq2yroqsdsvVnr5fk9gUK8fAX4Z6zW6vu3Duak6v2+CggMd
	#	    IIWHHYOCsDjFIZGa5fDmTSId0Sq2yroqsdsvVnr5fk9gUK8fAX4Z6zW6vu3Duak6v2+FY2NG
	#	    hsSkJIbjsDjFIZGa5fDmTSId0Sq2yroqsdsvVnr5fk9gUK8fAX4Z6zW6vu3Duak6v2+o0RmJ
	#	    gEAC2bnQsDjFIZGa5fDmTSId0Sq2yroqsdsvVnr5fk9gUK8fAX4Z6zW6vu3Duak6v2+CZmFU
	#	    uEA6kpqUsDjFIZGa5fDmTSId0Sq2yroqsdsvVnr5fk9gUK8fAX4Z6zW6vu3Duak6v2+OVyxc
	#	    ExAKrrCvsDjFIZGa5fDmTSId0Sq2yroqsdsvVnr5fk9gUK8fAX4Z6zW6vu3Duak6v2+W3auK
	#	    7a2dSm7vL2+vCXBwSTExcTCwR/KygYCHs0eKgLLygfW19jZ1xfc3CgcFt/hHN3cFOfo6eroA
	#	    e3tJwU7vL2+L8PIF7u0w+Pn6+/lV/lSruEBooGBgQYJxEio0yBChlgcQI0qcGPGORTsJMmrc
	#	    yFFjEA7vL2+A7",

	# class img {
	#    type string
	#    filename "/config/img.txt"
	# }

	rule LBFailedResponse {
	   when LB_FAILED {
	      HTTP::respond 200 content [b64decode [class element -value 0 img]] "Content-Type" "image/png"
	   }
	}


	# Using the -all flag added in v11.0 to return details on multiple matches (for class match or class search):
	#
	# Show the full contents of the string_dg datagroup retrieved as a TCL list:
	  log local0. "[class get string_dg] "
	# Log output: {abc value1} {abcd value2} {abcde value3} {123 value4}

	# Use -all with no other options to return a count of the number of matching names in the datagroup:
	  log local0. "[class search -all string_dg starts_with "abc"]"
	# Log output: 3

	# Use -all with the -index option to return the index of matching names in the datagroup:
	  log local0. "[class search -all -index string_dg starts_with "abc"]"
	# Log output: 0 1 2

	# Use -all with the -index option to return the index of matching names in the datagroup:
	  log local0. "[class search -all -index string_dg starts_with "abc"]"
	# Log output: 0 1 2

	# Use -all with the -element option to return the name and value of matching names in the datagroup:
	  log local0. "[class search -all -element string_dg starts_with "abc"]"
	# Log output: {abc value1} {abcd value2} {abcde value3}

	# Use -all with the -name option to return the name of matching names in the datagroup:
	log local0. "[class search -all -name string_dg starts_with "abc"]"
	# Log output: abc abcd abcde

	# Use -all with the -value option to return the value of matching names in the datagroup:
	log local0. "[class search -all -value string_dg starts_with "abc"]"
	# Log output: value1 value2 value3

	# Examples showing longest-match selection (v11.x syntax):
	ltm data-group internal /Common/addr_list {
	    records {
		10.0.0.0/8 {
		    data bignet
		}
		10.0.0.0/24 {
		    data littlenet
		}
	    }
	    type ip
	}
	ltm data-group internal /Common/string_list {
	    records {
		left {
		    data first
		}
		lefter {
		    data second
		}
	    }
	    type string
	}

	log local0. "match of 10.0.0.128 is [class match -value 10.0.0.128 equals addr_list]"
	log local0. "match of lefterest is [class match -value lefterest starts_with string_list]"
	# will log:
	# Rule /Common/classes : match of 10.0.0.128 is littlenet
	# Rule /Common/classes : match of lefterest is second
	# In each case, the longest match was used (10.0.0.0/24 had a longer match than 10.0.0.0/8, and "lefter" had a longer match than "left").

HINTS
SEE ALSO
       https://devcentral.f5.com/wiki/iRules.GenericHostToUriMapping.ashx -
       This iRule shows how to map a portion of the host header to a specified
       Uri.
       https://devcentral.f5.com/wiki/iRules.Google-Authenticator-iRule-For-Two-Factor-Auth-With-LDAP.ashx
       - This iRule adds two-factor authentication to a virtual server by
       combining an LDAP account with a Google Authenticator token
       https://devcentral.f5.com/wiki/iRules.Google-Authenticator-Token-Verification-iRule-For-APM.ashx
       - This iRule adds token authentication capabilities for Google
       Authenticator to APM.
       https://devcentral.f5.com/wiki/iRules.LTMImageHosting.ashx - Host
       Images on LTM in External Class
       https://devcentral.f5.com/wiki/iRules.MS-Exchange-Active-Sync-Multi-Device-Auth.ashx
       - Utilizes the Exchange extended attributes to store multiple devices
       per client, (i.e. iPhone, iPad, etc.) to validate the device as
       approved for the assigned user.
       https://devcentral.f5.com/wiki/iRules.ProxyPassV10.ashx - iRule (for
       LTM v10/v11) to replace the functionality of Apache Webserver ProxyPass
       and ProxyPassReverse functions allowing for a different server and
       client view of your web application(s).
       https://devcentral.f5.com/wiki/iRules.Route_Domain_Snat_and_Nat_Implementation.ashx
       - This iRule Provides Snat and Nat capabilities across route domains
       https://devcentral.f5.com/wiki/iRules.TLS-ServerNameIndication.ashx -
       Server Name Indication (TLS SNI) allows dynamic selection of clientssl
       profiles and pools
       
       - This Solution will act as a Web Form Application protection layer
       against malicious entities such as automated bots.
       https://devcentral.f5.com/wiki/iRules.virtual_server_connection_rate_limit_with_tables.ashx
       - Limit the rate of connections to a virtual server to prevent
       overloading of pool members

       For examples on v10 and v11 data group formats, see Jason Rahm's
       articles:
       https://devcentral.f5.com/Tutorials/TechTips/tabid/63/articleType/ArticleView/articleId/1086448/iRules-Data-Group-Formatting-Rules.aspx
       https://devcentral.f5.com/Tutorials/TechTips/tabid/63/articleType/ArticleView/articleId/1086510/v11-iRules-Data-Group-Updates.aspx

       Note that datagroups are not currently synced between GTMs, although if
       synced between LTMs on GTM/LTM servers they will be accessible.

       Note that if you wish to create datagroups on a standalone GTM, you
       will need to contact support.

CHANGE LOG
       @BIGIP-11.1.0 --First introduced to GTM.  @BIGIP-10.0.0 --First
       introduced the command.



BIG-IP				  2017-01-31			      iRule(1)