Node properties

Node properties can be found in the "properties" tab of each node in Rudder.

Node properties can be modified using Rudder's API, see http://www.rudder-project.org/rudder-api-doc/#api-Nodes-updateNodeProperties

Properties can also be defined on the node itself, to override locally properties.

Each property is a key=value pair. The value can be a string or a well-formatted JSON data structure.

Some examples: datacenter=Paris datacenter= { "id": "FRA1", "name": "Colo 1, Paris", "location": "Paris, France", "dns_suffix": "paris.example.com" }

Using properties

You can use node properties almost everywhere in Rudder:

  • in directive parameters
  • in the technique editor
  • in your own techniques and generic methods

To use a property, simply use the variable node.properties with the variable call syntax.

Example with a property named datacenter:

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

Before Rudder 3.1.14 and 3.2.7, node properties could not be used in JavaScript expressions (see following section), since they are evaluated during policy generation and node properties were only made available to agents at runtime. Since Rudder 3.1.14, 3.2.7 and 4.0.0 and later, you can enable a feature switch in "Administration/Settings" to enable node properties expansion in directive parameters. More details are available at the section called “Node properties expansion in directives”.

In a mustache template, use:

{{{vars.node.properties.datacenter}}}

Local override

The agent searches for optionnal properties files /var/rudder/local/properties.d/*.json, and will override existing properties.

As a result, if you have node properties defined server side as "sysctls_postgresql":{"kernel.shmall":"903330","kernel.shmmax":"3700041320"} and "vm":{"vm.dirty_ratio":"10"}

and a local property file /var/rudder/local/properties.d/postgresql_config.json as

{
  "properties":
  {
    "sysctls_postgresql": {
      "kernel.shmmax":"5368709120"
    }
  }

}

The resulting properties will be:

"sysctls_postgresql":{"kernel.shmmax":"5368709120"} and "vm":{"vm.dirty_ratio":"10"}

sysctls_postgresql has been overriden by local property, and vm has been left untouched. Note that it is an override, as the semantic of merging is not deterministic with literal values, and it does not allow to unset values. If you need to merge, please refer to the next paragraph.

Merging properties

If you want to merge server defined properties with local defined properties, rather than override them, you will need to use the generic method variable_dict_merge_tolerant to define which variables you need to merge, and define the local variables in a different namespace than properties.

For instance, if you have defined in the node properties the following properties

"sysctls_postgresql":{"kernel.shmall":"903330","kernel.shmmax":"3700041320"}

and you wish to merge these values on a node with locally defined variable, to change the value of kernel.shmmax and set the value of kernel.shmmni, you can define the file /var/rudder/local/properties.d/postgresql_config.json with the following content

{
    "local_properties":
    {
        "sysctls_postgresql": {
            "kernel.shmmax":"5368709120",
            "kernel.shmmni":"4096"
        }
    }

}

and use the generic method variable_dict_merge_tolerant to merge node.properties[sysctls_postgresql] and node.local_properties[sysctls_postgresql], and set the result in merged_properties.sysctls_postgresql (for instance): variable_dict_merge_tolerant("merged_properties", "sysctls_postgresql", "node.properties[sysctls_postgresql]", "node.local_properties[sysctls_postgresql]")

As a result, merged_properties.sysctls_postgresql will contain

---

"sysctls_postgresql": { "kernel.shmall":"903330", "kernel.shmmax":"5368709120", "kernel.shmmni":"4096" }

---

Under the hood

On the server, one or more properties files are written for each node in the /var/rudder/share/<uuid>/rules/cfengine-community/properties.d/ directory. This directory is then copied to each node by the agent with all other promise files.

In the agent, properties are made available in the node.<namespace> container that contains the values. Those values are read from /var/rudder/cfengine-community/inputs/properties/*.json. All files are taken in order and override the previous ones - the last one wins.

The agent searches for optionnal properties files /var/rudder/local/properties.d/*.json, and will define variables or override existing properties.

Each file must contain at least 2 levels of JSON content, the first level is the namespace level and the second level is the key level.

The namespace name must be an ASCII name that doesn’t start with _ and must match the following regex: [a-zA-Z0-9][a-zA-Z0-9_]*

For example:

{
  "properties":
  {
    "datacenter": "Paris",
    "environment": "production",
    "customer": "Normation"
  }
}

The merge is a first level merge done at the namespace level. This means that:

  • a key in a namespace is fully overridden by the same key in the same namespace in a later file.
  • a key in a namespace is never overriden by the same key in a different namespace
  • a key that is overriden never retains original data even if it is a data container itself

The result key is available in the node.<namespace> data variable. A usage example:

${node.properties[datacenter]}

To get the original data (for debug only) there is the properties.property_<fileid> variable. A usage example:

${properties.property__var_rudder_cfengine_community_inputs_properties_d_properties_json[properties][datacenter]}