]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
undocument "update", and document conversions to new syntax
authorAlan T. DeKok <aland@freeradius.org>
Sun, 24 Jul 2022 13:54:48 +0000 (09:54 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Sun, 24 Jul 2022 13:54:48 +0000 (09:54 -0400)
doc/antora/modules/reference/pages/unlang/edit.adoc
doc/antora/modules/reference/pages/unlang/index.adoc
doc/antora/modules/reference/pages/unlang/update.adoc

index af752bf2c243d9c47fe89619404630c754578a1f..d385e4348001f3e6d84ab9e5af2dcbbe791725f5 100644 (file)
@@ -137,6 +137,9 @@ to the `update` section.  However, for "in-place" lists, _the only
 operator which is permitted is `=`.  The server *will not start* if
 any other operator is used._
 
+NOTE: If the right-hand side of an assignment is a list, then _only_
+operator allowed inside of the right-hand side list is `=`.
+
 If the _<rhs>_ is an "in-place" list, then all of the
 xref:xlat/index.adoc[dynamic expansions] are valid, just as are
 xref:reference:unlang/attr.adoc[attribute references].
index 525438056f78373b62993c693120202fadacb785..50f918897f62a2c05dadf00f1dc678c9b83b9588 100644 (file)
@@ -67,22 +67,22 @@ if ((&User-Name == "bob") && (&Calling-Station-Id == "00:01:03:04:05")) {
 }
 ----
 
-== Update Statements
+== Editing Attribures and lists.
 
-xref:unlang/update.adoc[update] statements are used to edit attributes and
-lists of attributes.
+xref:unlang/edit.adoc[attribute editing] statements are used to edit
+attributes and lists of attributes.  The old-style
+xref:unlang/update.adoc[update] sections are deprecated, and no longer
+supported.
 
 Most request packets will result in reply packets that contain
-additional information for the requestor.  The `update` section allows
+additional information for the requestor.  Attribute editing allows
 policies to add attributes to requests, replies, or to other places.
 
 .Example
 [source,unlang]
 ----
-update reply {
-       &Session-Timeout := 3600
-       &Framed-IP-Address := 192.0.2.4
-}
+&reply.Session-Timeout := 3600
+&reply.Framed-IP-Address := 192.0.2.4
 ----
 
 == Dynamic Expansions
@@ -98,9 +98,7 @@ attributes, databases, and scripts.
 .Example
 [source,unlang]
 ----
-update reply {
-       &Framed-IP-Address := "%{sql:SELECT static_ip from table WHERE user = '%{User-Name}'}"
-}
+&reply.Framed-IP-Address := "%{sql:SELECT static_ip from table WHERE user = '%{User-Name}'}"
 ----
 
 == Data Types
@@ -114,10 +112,10 @@ error.
 .Example
 [source,unlang]
 ----
-update reply {
-       &Framed-IP-Address := 192.0.2.4
-       &Session-Timeout := 5
-       &Reply-Message := "hello"
+&reply += {
+       &Framed-IP-Address = 192.0.2.4
+       &Session-Timeout = 5
+       &Reply-Message = "hello"
 }
 ----
 
@@ -144,10 +142,10 @@ and values for those variables.  Those values do not change when the
 server is running.
 
 In contrast, `unlang` performs run-time processing of requests.
-Conditional statements such as xref:unlang/if.adoc[if] are evaluated for every
-packet that is received.  Attribute editing statements such as
-xref:unlang/update.adoc[update] can be used to edit attribute contents or lists
-of attributes.
+Conditional statements such as xref:unlang/if.adoc[if] are evaluated
+for every packet that is received.  Attribute
+xref:unlang/edit.adoc[editing] statements such as can be used to edit
+attribute contents or lists of attributes.
 
 .Example
 [source,unlang]
@@ -158,15 +156,11 @@ of attributes.
 # attribute has value "bob"
 
 if (&User-Name == "bob") {
-    # keyword "update"
-
     # followed by instructions to add the Reply-Message
     # attribute to the "reply" list, with contents
     # "Hello, bob"
 
-    update reply {
-        Reply-Message := "Hello, bob"
-    }
+    &reply.Reply-Message := "Hello, bob"
 }
 ----
 
index b4f779a483fc04e4436dd6d4ea90e119f7586e94..915c2ef95425b5634fa2b5f22b446a50f367ae6a 100644 (file)
 = The update Statement
 
-.Syntax
-[source,unlang]
-----
-update [ <list> ] {
-       <server-attribute> <op> <value>
-       ...
-}
-----
+The `update` statement is deprecated.  It may work, but it will be
+removed in a future release.  The `update` statement does not support
+the data types of `group` and `struct`.
+
+All new configuration should use the new xref:unlang/edit.adoc[edit]
+syntax.  It is more flexible and more powerful than `update` sections.
 
-The `update` statement adds attributes to, or edits the attributes in,
-the named _<list>_.
+This page exists only document how the old-style `update` sections can
+be converted to the new syntax.
 
-The `update` statement consists of the following syntax elements:
+The most important conceptual change is that the
+xref:unlang/edit.adoc[edit] syntax separates list assignments from
+value assignments.  Where the `update` sections always modified a list
+by adding or deleting attributes, the new syntax allows for list
+updates _or_ updates to an attributes value.  Be careful not to get
+the two uses mixed up, otherwise the result will not be what you
+expect.
 
-_<list>_: The attribute list which will be updated.  The list is
-usually `request`, `reply`, or `control`.
-+
-If the _<list>_ qualifier is omitted, then each entry inside of the
-`update` section *must* be prefixed with a list name.  For example,
-`&request.User-Name ...`
+The second conceptual change is that attribute creation is separate
+from applying attributes to a list.  For example, the `+=` operator
+used to both create an attribute, and then append that attribute to a
+list.  The new edit syntax separates attribute creation from list
+modification.
 
-_<server-attribute>_:: The server attribute which is assigned the
-_<value>_.
+== Conversions
 
-_<op>_:: The operator such as `=`, `:=`, etc.
+There are a larger number of operators using for both the old `update`
+section and the xref:unlang/edit.adoc[edit] syntax.  We explain in
+detail how the configuration can be converted from one form to another.
 
-_<value>_:: The value which is assigned to the attribute.  If the field
-is a double-quoted string, it undergoes xref:xlat/index.adoc[string
-expansion], and the resulting value is assigned to the attribute.
+=== Appending to a list: +=
 
-The update process is atomic, in that either all of the attributes are
-modified, or none of them are modified.  If the `update` fails for any
-reason, then all of the results are discarded, and the `update` does
-not affect any server attributes.
+The following example creates four attributes, and appends them to the
+`request` list.
 
-.Example
 [source,unlang]
 ----
-update reply {
-   &Reply-Message := "Hello!"
-   &Framed-IP-Address := 192.0.2.4
+update request {
+       &User-Name += "foo"
+       &Filter-Id += "bar"
+       &NAS-IP-Address += 127.0.0.1
+       &NAS-Port += 5
 }
 ----
 
-== Lists
+This example should be converted to the following syntax:
 
-The _<list>_ field sets the attribute list that will be updated.  If
-the _<list>_ qualifier is omitted, then each entry inside of the
-`update` section *must* be prefixed with a list name.  For example,
-`&request.User-Name ...`
+[source,unlang]
+----
+&request += {
+       &User-Name = "foo"
+       &Filter-Id = "bar"
+       &NAS-IP-Address = 127.0.0.1
+       &NAS-Por = 5
+}
+----
 
-Please see the xref:unlang/list.adoc[list] page for valid list names.
+This configuration can be interpreted as "edit the `&request` list,
+but appending (`+=`) another list to it.  The list being appended
+contains four attributes".
 
-== Server Attributes
+Note that the operators on the right-hand side list are all `=`.  The
+`=` operator is used here because we are simply _creating_ the
+right-hand side list, not _modifying_ it.
 
-The _<server-attribute>_ field is an attribute name, such as
-`&Reply-Message`.  The attribute name may also be prefixed with a
-_<list>_ qualifier, which overrides the _<list>_ given at the start
-of the `update` section.
+=== Over-writing attributes in a list: :=
 
-NOTE: In version 3, the leading `&` was optional.  In version 4, the
-leading `&` is required.
+The following example over-writes the values for two attributes in the
+`request` list.
 
-== Editing Operators
+[source,unlang]
+----
+update request {
+       &User-Name := "foo"
+       &Filter-Id := "bar"
+}
+----
+
+The simplest conversion here is to keep the `:=` operator, and to just
+assign the attributes in place, with a list qualifier.
+
+[source,unlang]
+----
+&request.User-Name := "foo"
+&request.Filter-Id := "bar"
+----
 
-The `<op>` field is used to define how the attribute is processed.
-Different operators allow attributes to be added, deleted, or
-replaced, as defined below.
+=== Conditionally Over-writing attributes in a list: =
 
-.Editing Operators
-[options="header"]
-[cols="10%,90%"]
-|=====
-| Operator | Description
-| =        | Add the attribute to the list, if and only if an attribute of
-the same name is not already present in that list.
-| :=       | Add the attribute to the list. If any attribute of the same
-name is already present in that list, its value is replaced with the
-value of the current attribute.
-| +=       | Add the attribute to the tail of the list, even if attributes
-of the same name are already present in the list.
-| ^=       | Add the attribute to the head of the list, even if attributes
-of the same name are already present in the list.
-| -=       | Remove all attributes from the list that match _<value>_.
-| !*       | Delete all occurances of the attribute, no matter what the value.
-|=====
+The following example conditionally over-writes the values for two attributes in the
+`request` list.
 
-.Example
 [source,unlang]
 ----
-update reply {
-   &Session-timeout := 86400
+update request {
+       &User-Name = "foo"
+       &Filter-Id = "bar"
 }
 ----
 
-.Example
+The simplest conversion here is to keep the `=` operator, and to just
+assign the attributes in place, with a list qualifier.
+
 [source,unlang]
 ----
-update reply {
-   &Reply-Message += "Rejected: Also, realm does not end with ac.uk"
-}
+&request.User-Name = "foo"
+&request.Filter-Id = "bar"
 ----
 
-== Values
+=== Removing Attributes from a list: !*
 
-The _<value>_ field is the value which is assigned to the
-_<server-attribute>_.  The interpretation of the _<value>_ field
-depends on the data type of the contents.  For example, if the string
-`"192.0.2.1"` is assigned to an attribute of the `string` data type,
-then the result is an ASCII string containing that value.  However, if
-the same string is assigned to an attribute of the `ipaddr` data type,
-then the result is a 32-bit IPv4 address, with binary value `0xc0000201`.
+The following example removes all `&User-Name` attributes from the `request` list.
 
-.Example
 [source,unlang]
 ----
-update reply {
-   &Session-Timeout <= 3600
+update request {
+       &User-Name !* ANY
 }
 ----
 
+The conversion is to use the `-=` operator:
+
+[source,unlang]
+----
+&request -= &User-Name
+----
+
+== More Complex Conversions
+
+It is extremely difficult to document every possible conversion when
+using a mix of operators in an `update` section.  The above examples
+should be sufficient for most common cases.
+
+Our recommendation is that if an `update` section contains multiple
+different operators, it should be split into multiple assignments.
+That is, do not try to convert the entire `update` section as-is.
+Instead, separate the `update` section into multiple `update`
+sections, one for each operator.  Then, convert each `update` section
+individually.
+
+Another option is to write down in plain English what operations you
+wish to perform.  Then, look at the new documentation to see how those
+operations match to the new syntax.
+
+In most cases, the operations are little more than "add attributes to
+list", or "delete attributes from list".  Those operations are simple
+to perform in the new syntax.
+
+== Issues with the Old Operators
+
+The operators in the `update` sections were really _list_ operators,
+and not _value_ operators.  For example, `+=` was "add attribute to
+list", and not "add value to attribute".  This mixup was the source of
+a significant amount of confusion when people first tried to use
+FreeRADIUS.
+
+In addition, using `+=` to manipulate lists meant that it was
+impossible to use that operator for adding values.  The follow-on
+effect was that math had to be done using the `%{expr:...}` expansion,
+which was confusing and difficult to document.  Changing the syntax
+allowed the separation of list assignments from value modifications,
+which meant that xref:unlang/expression.adoc[expressions] became
+became simpler.
+
+
 // Copyright (C) 2021 Network RADIUS SAS.  Licenced under CC-by-NC 4.0.
 // Development of this documentation was sponsored by Network RADIUS SAS.