Node properties expansion in directives

Table of Contents

Feature availability
Usage

It is possible to use properties defined on nodes to build Directive values. The resulting values will be computed during policy generation, and can therefore provide unique values for each node or be used in JavaScript expressions.

Properties on nodes are defined using Rudder's REST API, with the Update Node properties API call. More details in our API documentation.

Feature availability

This feature was introduced in Rudder 3.1.14, Rudder 3.2.7 and Rudder 4.0.0.

If you upgraded to 3.1.14 (or a later 3.1.x version) or 3.2.7 (or a later 3.2.x version) from a previous Rudder version, this feature is disabled by default in order to mitigate any risk of undesired side effects on existing installations. You can enable it in the Administration/Settings page, using the Enable node properties expansion in Directives switch.

Rudder installations from 4.0.0 onwards have this feature enabled by default.

Usage

In any directive text field, you can access properties defined on nodes using the following syntax:

${node.properties[property_name][key_one][key_two]}

where:

  • property_name is the name of the property defined via the API
  • key_one and key_two are keys in the JSON structure
  • the value obtained is the string representation, in compact mode, of the entire node property or sub-structure of the JSON value
  • if the key is not found, an error will be raised that will stop policy generation
  • spaces are authorized around separators ([,],|,}..)

Providing a default value

Most of the time, you will need to provide a default value to node properties expansion to avoid a policy generation error due to missing node properties. This is also a good case to allow a simple override mechanism for a parameter where only some nodes have a specific value.

You can also use other node properties, or other Rudder parameters as defaults, using the same syntax as above.

Some examples:

${node.properties[datacenter][id] | default = "LON2" }
${node.properties[datacenter][name] | default = """Co-location with "Hosting Company" in Paris (allows quotes)""" }
${node.properties[datacenter][id] | default = ${rudder.param.default_datacenter} }
${node.properties[netbios_name] | default = ${rudder.node.hostname} }
${node.properties[dns_suffix] | default = ${node.properties[datacenter][dns_suffix] | default = "${rudder.node.hostname}.example.com" }

#or even use cfengine variables in the default
${node.properties[my_override] | default = "${cfengine.key}"}

Forcing expansion on the node

In some cases, you will want to use a ${node.properties[key]} in a directive parameter, but you don’t want to expand it during policy generation on the Rudder server, but instead let the value be expanded during the agent run on the node. Typically if the value is to be used by a templating tool, or if the value is known only on the node.

For these cases, you can add the "node" option to the property expression:

${node.properties[datacenter][id] | node }

This will be rewritten during policy generation into:

${node.properties[datacenter][id]}

Which will be considered as a standard variable by the agent, which will replaced this expression by its value if it’s defined, or kept as is if it’s unknown.

The variable is content is read from /var/rudder/cfengine-community/inputs/properties.d/properties.json. You can find more information on node properties in the section called “Node properties”.