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.  -list     Changes the return value to always be a list even if only one 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)? (-list)?  ('--')?  CLASS_OBJ  (PATTERN)?

   DESCRIPTION
       Returns the names of the class elements.

       class 'get' (-nocase)? (-list)? ('--')?	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 | -list)?	('--')?
       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.  -list	Changes the return value to always be a list, even if just one
       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						      2020-06-23					     iRule(1)